# Phase 4: USB Manager & Label Printing - Context **Gathered:** 2026-04-10 **Status:** Ready for planning **Mode:** Auto-generated (autonomous mode) ## Phase Boundary USB peripherals are managed by a goroutine-per-device subsystem and any cataloged item can have a QR-coded label printed by the PRT Qutie without operator intervention after intake. This phase delivers the USB device manager with VID/PID enumeration, goroutine-per-device pattern, reconnect handling, QR code generation, label rendering, and PRT Qutie printer driver. ## Implementation Decisions ### Hardware Status - PRT Qutie printer, Treedix testers, FNIRSI FNB58 arrive 2026-04-13 (in 3 days) - Phase 4 builds code-complete implementation with mock USB device for testing - Integration tests use mock or skip gracefully - Real hardware validation is a human verification item ### USB Device Architecture (from RESEARCH/ARCHITECTURE) - Use `go.bug.st/serial` for USB serial communication - Single USB Manager owns all device connections - Goroutine-per-device model with command/event channels - VID/PID enumeration at startup and on hotplug (via periodic poll on macOS) - Reconnect handling on unplug/replug without path reconfiguration ### PRT Qutie Protocol - Protocol is unknown until hardware arrives — build a stub driver with command abstraction - Use a `PrinterDriver` interface so the PRT Qutie driver can be dropped in later - Implement bitmap label rendering using `image` package — output PNG/raw bitmap ### QR Code + Label Rendering - `github.com/skip2/go-qrcode` for QR generation (low error correction for compact labels) - Label contains: QR code (left), HW-ID (top right), name (middle), spec line (bottom) - 15mm wide at 203 DPI = ~120px label height - Font: use basicfont from x/image or embed a simple bitmap font ### Cable-Specific Label Template - Detect cable records (device_type contains "cable" or catalog tag) → use cable template - Cable template shows: USB version, max speed, max power, test date ### Integration with Existing Code - Add `internal/usb/` package for USB Manager - Add `internal/printer/` package for printer driver - Add `internal/labels/` package for QR + rendering - Extend chi router with POST /api/labels/:deviceID/print - Add SSE endpoint GET /api/usb/events for device connect/disconnect ### Infrastructure - No external services needed for Phase 4 - Mock USB device for tests - go.bug.st/serial supports macOS and Linux dev ## Existing Code Insights ### Reusable Assets from Phase 1-3 - `internal/netbox/client.go` — GetDevice to look up item for label - `internal/netbox/types.go` — Device, CustomFields - `internal/api/router.go` — chi router (add label + usb endpoints) - `internal/config/config.go` — viper config (add USB device paths) - `web/src/pages/DashboardPage.tsx` — add "Print Label" quick action ### Integration Points - Dashboard quick action: POST /api/labels/{deviceID}/print - Intake flow final step: auto-print after record creation - SSE GET /api/usb/events for frontend connect/disconnect notifications - USB Manager runs as goroutine, started from main.go ## Specific Ideas - Use a PrinterDriver interface: Connect(), Print(bitmap []byte) error, Disconnect() - Mock printer driver logs to stdout and saves PNG to /tmp for visual inspection - Label renderer produces a standard Go image.Image that the driver converts - For PRT Qutie stub: write raw bytes to serial port with TODO comment for real protocol ## Deferred Ideas - Treedix cable tester integration (Phase 5) - FNIRSI FNB58 (Phase 5) - Actual PRT Qutie protocol implementation (requires hardware + reverse engineering) - Print queue (unnecessary for single-user homelab)