Initial commit: LAAPC Print Service - Windows service with multi-tray printing, IPC queue management, PDF testing support, and self-installing CLI
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
# Harbor/Clipper Print Service - Implementation Plan
|
||||
|
||||
**TL;DR**: Build a persistent Windows service that monitors for new print capture files, immediately moves them to prevent overwrites, queues them for ordered processing, and sends multi-tray print jobs to laser printers with document-type-specific configurations.
|
||||
|
||||
**Recommended Approach**: C#/.NET 8+ Windows Service with FileSystemWatcher, print queue, and configurable document templates. C# is completely free (.NET SDK), has superior Windows printer APIs, and excellent service infrastructure.
|
||||
|
||||
---
|
||||
|
||||
## Steps
|
||||
|
||||
### Phase 1: Service Foundation (Parallel work possible after step 1)
|
||||
|
||||
1. **Create Windows Service project structure** using .NET 8+ Worker Service template
|
||||
|
||||
- Use `BackgroundService` base class for hosting
|
||||
- Configure as Windows Service with `Microsoft.Extensions.Hosting.WindowsServices`
|
||||
- Set up dependency injection, logging, and configuration (appsettings.json)
|
||||
2. **Implement file monitoring system** (*parallel with step 3*)
|
||||
|
||||
- `FileSystemWatcher` on Captures folder with `Created`, `Changed`, and `Renamed` events
|
||||
- Debounce logic to handle rapid file creation (buffer 100-200ms)
|
||||
- Immediate file move to processing queue folder with GUID-based naming to prevent collisions
|
||||
- Include original filename, timestamp, and metadata in queue
|
||||
3. **Design configuration system** (*parallel with step 2*)
|
||||
|
||||
- Document type definitions (invoice, order, delivery, etc.)
|
||||
- Per-document-type settings: printer name, tray sequence, content transformations
|
||||
- Global settings: queue folder paths, archive settings, retry policies
|
||||
- JSON schema for easy editing
|
||||
|
||||
### Phase 2: Command Interface & Queue Management
|
||||
|
||||
4. **Create CLI command handler** (*depends on 1*)
|
||||
|
||||
- Parse `-f <filepath> -t <doctype> -o <ordernumber>` arguments
|
||||
- Check if service is running via named pipe or TCP
|
||||
- If running: send command to service via IPC
|
||||
- If not running: log error or auto-start service
|
||||
- Return exit code immediately
|
||||
5. **Build print job queue** (*depends on 1*)
|
||||
|
||||
- Thread-safe queue with priority/ordering (FIFO by default, configurable)
|
||||
- Persistent queue state (survive service restart)
|
||||
- Job metadata: source file, document type, order number, timestamp, retry count
|
||||
- Status tracking: pending, processing, completed, failed
|
||||
6. **Implement IPC mechanism** (*depends on 4, 5*)
|
||||
|
||||
- Named pipe server listening for commands from CLI
|
||||
- Deserialize command → create job → enqueue
|
||||
- Return acknowledgment to caller
|
||||
|
||||
### Phase 3: Printer Integration
|
||||
|
||||
7. **Implement queue-based printer control** (*depends on 5*)
|
||||
|
||||
- Use `System.Drawing.Printing.PrintDocument` with Windows print queue
|
||||
- Multi-page document with dynamic `PageSettings.PaperSource` for tray selection
|
||||
- Per-printer tray mapping configuration (map logical tray numbers to physical `PaperSource` indexes)
|
||||
- Fallback handling when tray empty (configurable: fail job, use default tray, alert)
|
||||
- Optional: Print to PDF for testing/archiving
|
||||
8. **Build document processor with Graphics rendering** (*depends on 7*)
|
||||
|
||||
- Read queued capture file and parse text content
|
||||
- Apply document-type-specific transformations:
|
||||
- Line position adjustments using `Graphics.DrawString()` coordinates
|
||||
- Text removal/replacement via regex patterns
|
||||
- Font and formatting configuration per document type
|
||||
- Future: header/footer injection, graphics overlay, logo placement
|
||||
- Render each page with `Graphics` API for pixel-perfect control
|
||||
- Generate multi-page `PrintDocument` with correct tray sequence
|
||||
- Send to Windows print queue
|
||||
9. **Add printer routing logic** (*depends on 7, 8*)
|
||||
|
||||
- Map document types to printer(s) and tray sequences
|
||||
- Support multiple printer profiles per document type
|
||||
- Configuration: `{ "invoice": { "printer": "LaserJet-1", "trays": [3,4,1,2] } }`
|
||||
|
||||
### Phase 4: Reliability & Operations
|
||||
|
||||
10. **Implement error handling & retry** (*depends on 5, 8*)
|
||||
|
||||
- Printer offline detection → requeue with exponential backoff
|
||||
- File read errors → log and move to error folder
|
||||
- Max retry limit → move to dead letter queue
|
||||
- Detailed logging with correlation IDs
|
||||
11. **Add file lifecycle management** (*depends on 2*)
|
||||
|
||||
- Post-processing: delete or move to archive folder (configurable per document type)
|
||||
- Archive folder structure: organized by date, document type, or both
|
||||
- Retention policy support (future: auto-cleanup old archives)
|
||||
12. **Create service installer & deployment** (*depends on all previous*)
|
||||
|
||||
- MSI installer or PowerShell install script
|
||||
- Service registration with `sc.exe` or WiX toolset
|
||||
- Auto-start configuration
|
||||
- Uninstall/upgrade support
|
||||
|
||||
### Phase 5: Testing & Validation
|
||||
|
||||
13. **System testing** (*depends on 12*)
|
||||
|
||||
- Test rapid file creation (simulate Harbor/Clipper speed)
|
||||
- Verify no overwrites or missing files
|
||||
- Confirm correct print order
|
||||
- Test printer offline scenarios
|
||||
- Validate tray sequences for each document type
|
||||
14. **Integration with Harbor/Clipper** (*depends on 13*)
|
||||
|
||||
- Replace current Rust CLI calls with new CLI
|
||||
- Monitor production for 24-48 hours
|
||||
- Compare output quality and reliability
|
||||
- Performance tuning if needed
|
||||
|
||||
---
|
||||
|
||||
## Relevant Files
|
||||
|
||||
**To be created**:
|
||||
|
||||
- `PrintService/Program.cs` — Service host and startup configuration
|
||||
- `PrintService/Worker.cs` — Background service implementing FileSystemWatcher and queue processor
|
||||
- `PrintService/Models/PrintJob.cs` — Job data model
|
||||
- `PrintService/Models/DocumentConfig.cs` — Document type configuration schema
|
||||
- `PrintService/Services/FileMonitorService.cs` — File watching and immediate move logic
|
||||
- `PrintService/Services/PrintQueueService.cs` — Queue management and processing
|
||||
- `PrintService/Services/PrinterService.cs` — Queue-based printer control with tray commands
|
||||
- `PrintService/Services/DocumentProcessor.cs` — Text parsing and Graphics rendering
|
||||
- `PrintService/Services/IpcService.cs` — Named pipe listener for CLI commands
|
||||
- `PrintService/appsettings.json` — Configuration file for document types, printers, paths
|
||||
- `PrintServiceCLI/Program.cs` — Command-line tool for sending commands to service
|
||||
- `PrintService.sln` — Solution file
|
||||
|
||||
**Existing**:
|
||||
|
||||
- `Captures/` — Source folder for Harbor/Clipper output files (will be monitored)
|
||||
|
||||
---
|
||||
|
||||
## Verification
|
||||
|
||||
1. **Unit tests**: Queue ordering, configuration parsing, tray sequence generation
|
||||
2. **Integration test**: Create 50 files in 10 seconds → verify all printed in order with correct trays
|
||||
3. **Stress test**: 1000+ files → no overwrites, no missing files, proper ordering
|
||||
4. **Manual test**: Print each document type to each configured printer and verify tray usage
|
||||
5. **Production validation**: Monitor service for 48 hours, compare output count with Harbor/Clipper expected count
|
||||
6. **Error scenario testing**: Unplug printer mid-job → verify retry → reconnect → verify job completes
|
||||
|
||||
---
|
||||
|
||||
## Decisions
|
||||
|
||||
**Language**: C#/.NET 8+
|
||||
|
||||
- **Rationale**: Free, best Windows service/printer APIs, excellent tooling, easier printer control than Rust
|
||||
- **Alternative**: Could still use Rust with `windows-rs` crate, but printer control is more complex
|
||||
|
||||
**Architecture**: Service with IPC (Named Pipes)
|
||||
|
||||
- CLI tool sends commands → service processes asynchronously
|
||||
- Decouples Harbor/Clipper from processing delays
|
||||
|
||||
**File handling**: Immediate move with GUID renaming
|
||||
|
||||
- **Critical**: Prevents timestamp collision overwrites
|
||||
- Original metadata preserved in queue state
|
||||
|
||||
**Queue persistence**: JSON file or SQLite
|
||||
|
||||
- Survives service restart
|
||||
- Allows inspection/recovery
|
||||
|
||||
**Configuration**: JSON file (appsettings.json)
|
||||
|
||||
- Editable without recompilation
|
||||
- Per-document-type printer/tray/transformation settings
|
||||
|
||||
**Printer control**: PrintDocument with Windows print queue
|
||||
|
||||
- Per-page tray control via `PageSettings.PaperSource`
|
||||
- Content rendered using `Graphics.DrawString()` for positioning control
|
||||
- Jobs appear in Windows print queue (pausable, survives restarts)
|
||||
- Can print to PDF for testing
|
||||
|
||||
**Scope included**:
|
||||
|
||||
- Windows service with file monitoring
|
||||
- Command-line interface for Harbor/Clipper integration
|
||||
- Multi-tray printer control via Windows print queue
|
||||
- Configurable document routing
|
||||
- Archive/delete options
|
||||
- Error handling and retry logic
|
||||
- Content transformation with Graphics rendering (line positioning, text removal)
|
||||
|
||||
**Scope excluded** (future enhancements):
|
||||
|
||||
- GUI management console (use config file + logs for now)
|
||||
- Advanced document parsing/templating (start with regex transformations)
|
||||
- Web API or remote monitoring
|
||||
- Database storage (use file-based queue initially)
|
||||
- Automatic printer discovery
|
||||
- Print preview or validation UI
|
||||
|
||||
---
|
||||
|
||||
## Further Considerations
|
||||
|
||||
1. **Printer-specific tray mapping**: Need to identify your laser printer models and test `PaperSource` indexes. Do you know the printer makes/models?
|
||||
2. **Content transformation complexity**: You mentioned looping line items. For Phase 1, suggest simple regex-based transformations. If parsing becomes complex, consider a template engine (Scriban, Handlebars.NET) in Phase 2.
|
||||
3. **Testing environment**: Do you have a test laser printer or can we print to PDF initially to verify tray selection and content rendering work correctly?
|
||||
|
||||
---
|
||||
|
||||
## Benefits of Queue-Based Approach
|
||||
|
||||
- ✅ **Visibility**: Jobs appear in Windows print queue UI
|
||||
- ✅ **Resilience**: Queue survives service restarts
|
||||
- ✅ **Control**: Can pause/cancel jobs through Windows
|
||||
- ✅ **Testing**: Print to PDF for verification without paper waste
|
||||
- ✅ **Content Control**: `Graphics.DrawString()` gives pixel-perfect positioning for your line adjustments
|
||||
- ✅ **Debugging**: Easier to troubleshoot than raw printer commands
|
||||
Reference in New Issue
Block a user