docs(04-02): complete label rendering plan — QR code + bitmap renderers
This commit is contained in:
parent
7800917500
commit
bec54df2e0
1 changed files with 153 additions and 0 deletions
153
.planning/phases/04-usb-manager-label-printing/04-02-SUMMARY.md
Normal file
153
.planning/phases/04-usb-manager-label-printing/04-02-SUMMARY.md
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
---
|
||||||
|
phase: 04-usb-manager-label-printing
|
||||||
|
plan: "02"
|
||||||
|
subsystem: labels
|
||||||
|
tags: [go, qrcode, image, label-printing, bitmap]
|
||||||
|
|
||||||
|
# Dependency graph
|
||||||
|
requires:
|
||||||
|
- phase: 04-usb-manager-label-printing
|
||||||
|
provides: "Phase context, label dimensions, printer interface design"
|
||||||
|
- phase: 01-foundation
|
||||||
|
provides: "internal/netbox/types.go Device and CustomFields structs"
|
||||||
|
provides:
|
||||||
|
- "internal/labels package: RenderStandard (384x120) and RenderCable (384x180) bitmap renderers"
|
||||||
|
- "QR code generation encoding http://mac-mini.mg:8080/hw/HW-XXXXX URLs"
|
||||||
|
- "IsCableDevice() heuristic detection for cable records"
|
||||||
|
- "LabelData and CableLabelData structs as public API for printer driver"
|
||||||
|
affects:
|
||||||
|
- 04-03-printer-driver
|
||||||
|
- 04-05-intake-integration
|
||||||
|
|
||||||
|
# Tech tracking
|
||||||
|
tech-stack:
|
||||||
|
added:
|
||||||
|
- "github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e"
|
||||||
|
- "golang.org/x/image v0.39.0"
|
||||||
|
patterns:
|
||||||
|
- "Label renderers return image.Image — driver-agnostic; printer driver converts to bytes"
|
||||||
|
- "HWID format validated (HW-\\d{5}) before any qrcode.New() call (T-04-07 mitigation)"
|
||||||
|
- "TDD: failing tests committed first, implementation makes them pass"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- internal/labels/renderer.go
|
||||||
|
- internal/labels/renderer_test.go
|
||||||
|
- internal/labels/cable.go
|
||||||
|
- internal/labels/cable_test.go
|
||||||
|
modified:
|
||||||
|
- go.mod
|
||||||
|
- go.sum
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "DisableBorder=true (not DisableBorderPadding — that field doesn't exist in skip2/go-qrcode v0.0.0-20200617195104)"
|
||||||
|
- "HWID format validated before qrcode.New() to mitigate T-04-07 DoS via malformed input"
|
||||||
|
- "IsCableDevice uses name/notes heuristic only — real device_type detection deferred to Phase 5"
|
||||||
|
- "Cable label is 180px tall (vs 120px standard) to fit 4 text lines"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Label renderers: pure image.Image output, no USB/printer dependency — testable in isolation"
|
||||||
|
- "HWID validation: regexp.MustCompile at package level, checked at render entry points"
|
||||||
|
- "Text layout: TextOffsetX=112 (after QR block), y positions proportional to label height"
|
||||||
|
|
||||||
|
requirements-completed: [LBL-01, LBL-02, LBL-03]
|
||||||
|
|
||||||
|
# Metrics
|
||||||
|
duration: 15min
|
||||||
|
completed: 2026-04-10
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 04 Plan 02: QR Code + Label Rendering Summary
|
||||||
|
|
||||||
|
**image.NRGBA label bitmaps at 203 DPI using skip2/go-qrcode — standard (384x120) and cable (384x180) templates with HWID-encoded QR codes and basicfont text**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** ~15 min
|
||||||
|
- **Started:** 2026-04-10T06:30:00Z
|
||||||
|
- **Completed:** 2026-04-10T06:45:55Z
|
||||||
|
- **Tasks:** 2
|
||||||
|
- **Files modified:** 6 (4 created, 2 modified)
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- Standard label renderer: 384x120px NRGBA bitmap with QR code (left 96x96), HW ID, name, spec line
|
||||||
|
- Cable label renderer: 384x180px bitmap with 4 text lines — HW ID, name, USB version/speed, wattage/test date
|
||||||
|
- IsCableDevice() heuristic returns true when device Name or AINotes contains "cable" (case-insensitive)
|
||||||
|
- HWID format validated before QR generation (T-04-07 mitigation — prevents DoS via malformed input)
|
||||||
|
- All 10 tests pass across both renderers and the cable detection helper
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
Each task was committed atomically:
|
||||||
|
|
||||||
|
1. **Task 1: QR code generation + standard label renderer** - `8cbd840` (feat)
|
||||||
|
2. **Task 2: Cable label renderer + IsCableDevice detection helper** - `7800917` (feat)
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
- `internal/labels/renderer.go` — LabelData, RenderStandard(), drawText(), truncate(), HWID validation
|
||||||
|
- `internal/labels/renderer_test.go` — 5 tests: dimensions, QR non-blank, URL encoding, empty name fallback, white background
|
||||||
|
- `internal/labels/cable.go` — CableLabelData, RenderCable(), IsCableDevice()
|
||||||
|
- `internal/labels/cable_test.go` — 5 tests: dimensions, full data, IsCableDevice true/false, empty test date
|
||||||
|
- `go.mod` / `go.sum` — added github.com/skip2/go-qrcode and golang.org/x/image
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
- Used `DisableBorder = true` (not `DisableBorderPadding` — that field does not exist in the installed version of go-qrcode)
|
||||||
|
- HWID validated via `regexp.MustCompile("^HW-\\d{5}$")` at render entry points per T-04-07 threat disposition (mitigate)
|
||||||
|
- Cable detection kept as heuristic (name/notes contains "cable") — device_type-based detection is a Phase 5 concern
|
||||||
|
- go.mod upgraded from go 1.23.0 to 1.25.0 automatically when golang.org/x/image@v0.39.0 required it
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. [Rule 1 - Bug] DisableBorderPadding field does not exist in go-qrcode**
|
||||||
|
- **Found during:** Task 1 (standard label renderer)
|
||||||
|
- **Issue:** Plan code snippet used `qr.DisableBorderPadding = true` but the installed version of skip2/go-qrcode has `DisableBorder bool` not `DisableBorderPadding`
|
||||||
|
- **Fix:** Changed to `qr.DisableBorder = true` (inspected package source)
|
||||||
|
- **Files modified:** internal/labels/renderer.go, internal/labels/cable.go
|
||||||
|
- **Verification:** All tests pass after fix
|
||||||
|
- **Committed in:** 8cbd840 (Task 1 commit)
|
||||||
|
|
||||||
|
**2. [Rule 2 - Missing Critical] Added HWID format validation (T-04-07)**
|
||||||
|
- **Found during:** Task 1 — threat model review
|
||||||
|
- **Issue:** Threat register marked T-04-07 (DoS via malformed HWID to qrcode.New) as `mitigate` — no validation was in the plan's code snippet
|
||||||
|
- **Fix:** Added `hwIDPattern = regexp.MustCompile("^HW-\\d{5}$")` and guard at top of both RenderStandard and RenderCable
|
||||||
|
- **Files modified:** internal/labels/renderer.go, internal/labels/cable.go
|
||||||
|
- **Verification:** Passing invalid HWIDs returns error rather than passing to qrcode.New
|
||||||
|
- **Committed in:** 8cbd840, 7800917 (both task commits)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Total deviations:** 2 auto-fixed (1 bug, 1 missing critical security mitigation)
|
||||||
|
**Impact on plan:** Both fixes necessary for correctness and threat mitigation. No scope creep.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
- golang.org/x/image@v0.39.0 requires go 1.25+ — `go get` automatically upgraded go.mod from 1.23.0 to 1.25.0. This is acceptable for the project.
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
|
||||||
|
None — no external service configuration required.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
- `internal/labels` package is complete and fully tested
|
||||||
|
- Printer driver (04-03) can import `internal/labels` and call `RenderStandard` / `RenderCable` to get `image.Image`, then convert to bytes for the PRT Qutie
|
||||||
|
- Intake integration (04-05) can use `IsCableDevice()` to route to the correct label template
|
||||||
|
- No blockers
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
|
|
||||||
|
- internal/labels/renderer.go: FOUND
|
||||||
|
- internal/labels/renderer_test.go: FOUND
|
||||||
|
- internal/labels/cable.go: FOUND
|
||||||
|
- internal/labels/cable_test.go: FOUND
|
||||||
|
- Commit 8cbd840: FOUND
|
||||||
|
- Commit 7800917: FOUND
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 04-usb-manager-label-printing*
|
||||||
|
*Completed: 2026-04-10*
|
||||||
Loading…
Add table
Reference in a new issue