221 lines
9.8 KiB
Markdown
221 lines
9.8 KiB
Markdown
# 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
|