c9f874b7f4
docs(05-02): complete NetBox CreateCable + TestHandler plan
...
- SUMMARY.md: 2 tasks, 2 commits, threat mitigations T-05-03/04/05 applied
- Deviation: go-netbox Cable model required url/display fields in test mock
2026-04-10 07:16:50 +00:00
1764c7b06a
feat(05-02): add TestHandler with 3 cable-test endpoints + router wiring
...
- TestHandler: POST /api/test/cable, GET /api/test/events, GET /api/test/recent
- POST /api/test/cable: DisallowUnknownFields (T-05-03), creates NetBox cable,
auto-prints with 1s rate limit (T-05-05), prepends to 20-item ring buffer
- GET /api/test/events: SSE, 30s keepalive, exits on context cancel (T-05-04)
- GET /api/test/recent: thread-safe ring buffer, returns [] when empty
- AttachStream() wires StreamingTesterDriver channel to SSE broadcaster
- Router: three /api/test/* routes added to NewRouter signature
- main.go: constructs TestHandler, wires USB Manager event loop stub
- All handler tests pass race-clean (7 test cases)
2026-04-10 07:15:30 +00:00
7908d40af3
feat(05-02): add CreateCable method and CableRecord type to netbox client
...
- CableRecord type added to types.go (ID, HWID, Label, TestData, CatalogStatus)
- CreateCable(ctx, label, assetTag, testDataJSON) uses DcimCablesCreate
- Sets test_data and catalog_status custom fields; hw_id if assetTag non-empty
- Rejects empty label with sentinel error message
- Unit tests use httptest.NewUnstartedServer (201 success, 422 error, empty label)
2026-04-10 07:12:00 +00:00
db287c238f
docs(05-01): complete TesterDriver interface + mock drivers plan
...
- TesterDriver, StreamingTesterDriver interfaces defined
- 4 mock drivers: MockUSBDriver, MockDPDriver, MockHDMIDriver, MockFNB58Driver
- KnownDevices extended with 4 RoleCableTester placeholder entries
- All tests pass, race detector clean
2026-04-10 07:08:46 +00:00
11aea60aee
feat(05-01): TesterDriver interface, 4 mock drivers, KnownDevices tester entries
...
- TesterDriver interface: Connect/Read/Disconnect
- StreamingTesterDriver interface: embeds TesterDriver, adds Stream()
- TestResult struct: CableType, versions, speed, power, continuity, eMarker, resistance
- LiveReading struct: Voltage, CurrentAmps, PowerWatts, PDProtocol, Timestamp
- MockUSBDriver: deterministic USB 3.2 Gen 2 result, ErrNotConnected guard
- MockDPDriver: deterministic DP 1.4 result
- MockHDMIDriver: deterministic HDMI 2.1 result
- MockFNB58Driver: 3 LiveReading samples at 100ms, context-cancelled via Disconnect()
- KnownDevices: 4 RoleCableTester placeholder entries (dead0:0001-0004)
2026-04-10 07:07:27 +00:00
384ffac870
test(05-01): add failing tests for TesterDriver, mock drivers, FNB58 streaming
2026-04-10 07:06:23 +00:00
984f67834f
docs(05): create phase 5 plans — tester drivers, backend endpoints, cable test UI
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 07:04:57 +00:00
468f8930d1
docs(05): auto-generated context (cable test phase)
2026-04-10 07:00:24 +00:00
ac190abafe
docs(phase-4): complete phase execution
2026-04-10 06:59:45 +00:00
93d26ebf55
docs(04): phase 4 verification + human UAT (hardware blocked)
2026-04-10 06:59:45 +00:00
36f7e92cf2
Merge branch 'worktree-agent-a3099381'
2026-04-10 06:58:42 +00:00
de807ba931
docs(04-05): complete frontend USB status bar and print label plan
2026-04-10 06:58:21 +00:00
47f351b40a
docs(04-04): complete intake auto-print integration plan
2026-04-10 06:58:16 +00:00
f9b1b3ff29
feat(04-04): integrate auto-print into intake handler
...
- Add IntakePrinter interface to intake.go (optional, nil-safe)
- Add printer field to IntakeHandler, update NewIntakeHandler signature
- Add PrintSkipped bool to IntakeResponse (json: print_skipped)
- Auto-print label after NetBox record creation using labels.RenderStandard + printer.ImageToRawBitmap
- Printer errors are non-fatal: logged and surfaced via print_skipped=true
- Update main.go to pass mockDriver as IntakePrinter
- Add 4 new tests covering success, ErrNoDevice, nil printer, and non-fatal error
- All 10 intake tests pass (6 existing + 4 new)
2026-04-10 06:57:27 +00:00
4d2d35e277
docs(04-03): complete printer driver + HTTP endpoints plan — MockDriver, SSE, rate limiter
2026-04-10 06:53:59 +00:00
9f57cbdf6c
feat(04-03): LabelHandler, USBEventsHandler, router wiring, main.go USB+printer init
...
- LabelHandler: POST /api/labels/:deviceID/print with 1/s rate limit (T-04-09)
- USBEventsHandler: GET /api/usb/events SSE stream, exits on context cancel (T-04-11)
- router.go: two new parameters + routes wired
- main.go: USB Manager started with ctx, MockDriver connected, handlers passed to router
2026-04-10 06:52:52 +00:00
dd381eefa3
test(04-03): add failing handler tests for label print and USB SSE (TDD RED)
2026-04-10 06:50:51 +00:00
1156eff896
feat(04-03): PrinterDriver interface, MockDriver, PrtQutieDriver stub
...
- PrinterDriver interface: Connect/Print(bitmap,w,h)/Disconnect
- ImageToRawBitmap(): 1-bit packed row-major converter from image.Image
- MockDriver: saves PNG to SaveDir (/tmp default) for visual inspection
- PrtQutieDriver: stub returns ErrNoDevice — safe before hardware arrives
- ErrNoDevice, ErrNotConnected, ErrEmptyBitmap sentinel errors
2026-04-10 06:50:12 +00:00
b223b54a87
test(04-03): add failing printer driver tests (TDD RED)
2026-04-10 06:49:31 +00:00
2d6765077c
Merge commit 'bec54df'
2026-04-10 06:47:55 +00:00
bec54df2e0
docs(04-02): complete label rendering plan — QR code + bitmap renderers
2026-04-10 06:47:13 +00:00
63b66f7a94
docs(04-01): complete USB manager plan — goroutine-per-device, VID/PID enumeration
...
- 10/10 tests pass with -race flag
- goroutine count stable across 5 replug cycles
- T-04-01 read buffer cap mitigated
- Known stubs: VID/PID placeholder pending hardware 2026-04-13
2026-04-10 06:46:07 +00:00
7800917500
feat(04-02): cable label renderer and IsCableDevice detection
...
- Add CableLabelData struct and RenderCable() producing 384x180 bitmap
- Cable template: HW ID, name, USB version/speed, wattage/test date
- IsCableDevice() detects cable records by name or AINotes heuristic
- T-04-07 mitigation applied: HWID format validated in RenderCable too
- All 5 cable tests pass (10 total in package)
2026-04-10 06:45:48 +00:00
82eaf6bed7
feat(04-01): USB Manager goroutine-per-device, poll loop, reconnect, leak-safe teardown
...
- Manager with injectable enumerateFunc and serialOpener for test isolation
- goroutine-per-device model: deviceLoop owns one serial port per device
- context+done-channel teardown: inner read goroutine exits on ctx.Done()
- Read buffer capped at 4096 bytes (T-04-01 threat mitigation)
- Poll loop reconciles prev/current snapshots for connect/disconnect events
- ErrDeviceNotConnected returned by Send() when device absent
- All 5 manager tests pass with -race flag; goroutine count stable across 5 replug cycles
- mockPort test helper blocks Read until Close() unblocks it (realistic behavior)
2026-04-10 06:45:26 +00:00
8cbd840cba
feat(04-02): standard label renderer with QR code generation
...
- Add internal/labels package with LabelData struct and RenderStandard()
- QR encodes http://mac-mini.mg:8080/hw/HW-XXXXX (LBL-01)
- Label is 384x120px NRGBA, white background, basicfont text
- T-04-07 mitigation: validate HWID format before qrcode.New()
- Install github.com/skip2/go-qrcode and golang.org/x/image
- All 5 renderer tests pass
2026-04-10 06:44:11 +00:00
f5b1d3156c
feat(04-01): USB device types, KnownDevices registry, VID/PID enumeration
...
- DeviceSpec, DeviceRole, DeviceState, DeviceEvent, Command types
- KnownDevices registry with PRT Qutie placeholder (0525:a4a7)
- enumerateConnected() with system_profiler JSON parsing + injectable test seams
- ParseVIDPID() helper with error on malformed input
- All 5 device_test.go tests pass
- go.bug.st/serial v1.6.4 added to go.mod
2026-04-10 06:43:43 +00:00
77bf4ebfd6
docs(04): create phase 4 plans — USB manager, label printing, SSE, intake integration
...
5 plans across 3 waves covering USB-01 through USB-04 and LBL-01 through LBL-05.
Mock drivers and goroutine-leak harness tests enable full TDD before hardware arrives.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 06:41:26 +00:00
6a8a4658a7
docs(04): auto-generated context (hardware phase)
2026-04-10 06:34:02 +00:00
ecb0c99f7b
docs(phase-3): complete phase execution
2026-04-10 06:33:14 +00:00
1fe46db050
docs(03): phase 3 verification + human UAT (3 gaps deferred for review)
2026-04-10 06:33:09 +00:00
021c82875e
fix(03): resolve TypeScript type mismatches from merged plans
2026-04-10 06:27:11 +00:00
e2ac3b10aa
chore: merge 03-04 worktree (intake UI) — resolved router/api/AppShell conflicts
2026-04-10 06:25:29 +00:00
8c7563af9a
chore: merge 03-03 worktree (dashboard+detail) — resolved router/api/AppShell conflicts
2026-04-10 06:24:20 +00:00
83e1725cd9
docs(03-05): complete PWA manifest + service worker + QR scanner plan
2026-04-10 06:23:01 +00:00
7fc7705c84
docs(03-04): complete intake wizard UI plan summary
2026-04-10 06:22:46 +00:00
d0ad1fb219
docs(03-03): complete dashboard + item detail plan summary
2026-04-10 06:22:35 +00:00
75c91a5941
feat(03-05): QR scanner page with @zxing/browser and router wiring
...
- web/src/pages/ScanPage.tsx: camera QR scanner with volt reticle overlay
- extractHWID() parses both URL format and bare HW-XXXXX patterns
- rear camera preference (back/rear/environment label matching)
- debounce via lastScanned state prevents duplicate navigation
- graceful camera permission denied error state
- web/src/router.tsx: lazy-loads ScanPage with Suspense fallback spinner
- web/src/lib/api.ts: typed fetch wrappers (fetchInventory, fetchInventoryItem)
- web/src/components/layout/AppShell.tsx: minimal page wrapper (stub for plan 03-03)
2026-04-10 06:22:14 +00:00
95a50f4abd
feat(03-05): PWA manifest, service worker, icons, and registration hook
...
- web/public/manifest.json with display=standalone, theme_color=#faff69, 192+512 icons
- web/public/sw.js with app-shell cache strategy (API calls network-only)
- web/public/icons/icon-192.png and icon-512.png generated via gen-icons.cjs
- web/scripts/gen-icons.cjs pure-Node.js PNG icon generator (black canvas, volt H monogram)
- web/src/hooks/usePWA.ts registers service worker on app load
- web/index.html: added theme-color meta tag
- web/src/App.tsx: calls usePWA() hook
2026-04-10 06:22:05 +00:00
5909025677
feat(03-04): intake wizard UI — AIResultReview, ConfirmForm, IntakePage, router wiring
...
- AIResultReview: confidence meter (green/yellow/red), manufacturer/model/category/tags, editable name input, ai_notes card
- ConfirmForm: confirm/start-over action buttons with submitting spinner state
- AppShell: top-nav layout wrapper with HWLab logo and Inventory/Add Item nav links
- IntakePage: three-step wizard (upload → submitting → review) wired to submitIntake()
- router.tsx: lazy-loads IntakePage for /intake, Suspense+Spinner fallback
- Analyze button disabled during submitting (T-03-13 DoS mitigation)
2026-04-10 06:21:53 +00:00
19c2bb7d05
feat(03-03): DashboardPage, ItemDetailPage, FilterBar, and router wiring
...
- web/src/components/inventory/FilterBar.tsx: search + status dropdown + grid/list toggle
- web/src/pages/DashboardPage.tsx: / route with grid/list view, filters, loading/error/empty states
- web/src/pages/ItemDetailPage.tsx: /item/$id route, two-column desktop, single-column mobile
- web/src/router.tsx: lazy-load DashboardPage + ItemDetailPage, keep intake/scan stubs
2026-04-10 06:21:48 +00:00
1867846a9f
feat(03-03): API client, TanStack Query hooks, layout shell, inventory item components
...
- web/src/lib/api.ts: typed fetch wrappers for GET /api/inventory and GET /api/inventory/:id
- web/src/hooks/useInventory.ts: useInventory + useInventoryItem TanStack Query hooks
- web/src/components/inventory/StatusBadge.tsx: catalog_status → Badge variant mapping
- web/src/components/inventory/ItemCard.tsx: grid card with photo, HW ID, name, status, NetBox link
- web/src/components/inventory/ItemRow.tsx: list-mode row with status color indicator
- web/src/components/layout/TopBar.tsx: sticky nav with HWLab volt brand, Add Item + Scan buttons
- web/src/components/layout/AppShell.tsx: TopBar + main content wrapper
2026-04-10 06:21:43 +00:00
709876d3a0
feat(03-04): add intake Zustand store, api.ts submitIntake, DropZone, PhotoPreview
...
- useIntakeStore: step tracking, photos (max 3), aiResult, editedName, error
- submitIntake(): multipart FormData POST /api/intake with IntakeResponse type
- DropZone: react-dropzone with camera capture, volt hover state, slot counter
- PhotoPreview: thumbnail grid with X remove button per photo
2026-04-10 06:20:35 +00:00
86d0a949c5
Merge commit 'a892ae1c38cf308a9652370e0c7c2e22a6d9283c'
2026-04-10 06:18:11 +00:00
f151b96f88
docs(03-01): complete frontend scaffold plan — Vite+React+ClickHouse design system
2026-04-10 06:17:42 +00:00
d38f93dd67
feat(03-01): bootstrap React+TS frontend with ClickHouse design system
...
- Vite 5 + React 18 + TypeScript 5 + Tailwind 3 scaffold in web/
- ClickHouse design tokens (volt, forest, canvas, charcoal, near-black) in tailwind.config.ts
- TanStack Router v1 with placeholder routes for /, /item/$id, /intake, /scan
- TanStack Query v5 QueryClientProvider + Zustand uiStore
- shadcn/ui Button (neon/forest/secondary/outline/ghost), Card, Badge with ClickHouse variants
- Vite proxy: /api -> http://localhost:8080
- Makefile: added frontend and dev-frontend targets
- Fixed: @typescript-eslint v8 for ESLint v9 compatibility; @types/node for vite.config.ts
2026-04-10 06:16:46 +00:00
a892ae1c38
docs(03-02): complete inventory endpoints plan summary
2026-04-10 06:16:09 +00:00
743611f488
feat(03-02): wire GET /api/inventory and GET /api/inventory/{id} routes
...
- NewRouter signature extended to accept *handlers.InventoryHandler
- GET /inventory and GET /inventory/{id} registered in /api route group
- main.go constructs handlers.NewInventoryHandler(nbClient) and passes to NewRouter
2026-04-10 06:15:12 +00:00
b0b6153b24
feat(03-02): InventoryHandler with list+detail endpoints and 7 unit tests
...
- InventoryNetBoxClient interface (ListDevices + GetDevice) for testability
- ListInventory returns 200 JSON array (limit=200, 502 on NetBox error)
- GetInventoryItem returns 200/404/400/502 based on ID validity and NetBox response
- deviceToResponse maps netbox.Device to InventoryItemResponse (nil PhotoURLs → [])
- 7 TDD tests: empty list, 2-item list, NetBox error, found, not found, invalid ID, server error
2026-04-10 06:14:43 +00:00
206d6886aa
docs(03): mark phase 3 plans autonomous for overnight execution
2026-04-10 06:12:46 +00:00
1a9931f900
docs(03): create phase 3 plans — dashboard, intake UI, PWA (5 plans, 2 waves)
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 06:12:02 +00:00