The server's ReadTimeout (15s) was closing SSE connections shortly after
they were established, causing a rapid connect/disconnect loop. The handler
already disabled WriteTimeout but not ReadTimeout.
- Add source badges (assembly=teal, manual=blue) to BOM display rows
- Add info banner when assembly-sourced entries exist
- Change source input from text field to select dropdown
- Add merge response types to types.ts
Closes#47
Add file_count and files_total_size to item API responses, computed
via batch query on item_files table (no migration needed).
- Add BatchGetFileStats() to audit_queries.go (follows BatchCheckBOM pattern)
- Add file stats to ItemResponse, HandleListItems, HandleGetItem, HandleGetItemByUUID
- Add 'Files' column to ItemTable (default visible in vertical mode)
- Add has_files computed field to audit completeness scoring (weight 1 for manufactured)
Generated 2026-01-31, references HTML templates and 8 migrations
that are now outdated. Superseded by STATUS.md and SPECIFICATION.md.
API.md and silo-spec.md were already deleted in earlier commits.
Add BOM merge endpoint for syncing assembly-derived BOM entries from
FreeCAD's silo-mod plugin.
Merge rules:
- Added: entries in request but not in server BOM are auto-created
with source='assembly'
- Quantity changed: existing entries with different quantity are
auto-updated
- Unchanged: same part and quantity are skipped
- Unreferenced: assembly-sourced entries in server BOM but not in
request are flagged as warnings (never auto-deleted)
- Manual entries are silently ignored in unreferenced detection
Also emits SSE 'bom.merged' event on successful merge (#46).
Promote BOM source from metadata JSONB to a dedicated VARCHAR(20)
column with CHECK constraint ('manual' or 'assembly').
- Add migration 012_bom_source.sql (column, data migration, cleanup)
- Add Source field to Relationship and BOMEntry structs
- Update all SQL queries (GetBOM, GetWhereUsed, GetExpandedBOM, Create)
- Update API response/request types with source field
- Update CSV/ODS export to read e.Source instead of metadata
- Update CSV import to set source on relationship directly
- Update frontend types and BOMTab to use top-level source field
Closes#43
Adds a new read-only endpoint to resolve a Silo item UUID to its full
ItemResponse. Used by silo-mod to resolve FreeCAD document SiloUUID
properties to part numbers during BOM sync.
- Reuses existing ItemRepository.GetByID() (items.id is the stable UUID)
- Returns 404 for archived items
- Registered in viewer-accessible route group (no editor role required)
Implements #17, #18, #19, #20, #21
- Add CSS custom properties for density-dependent spacing (--d-* vars)
in theme.css with comfortable (default) and compact modes
- Create useDensity hook with localStorage persistence and DOM attribute sync
- Add FOUC prevention in main.tsx (sync density before first paint)
- Create shared PageFooter component merging stats + pagination
- Refactor AppShell to flex layout with density toggle button (COM/CMP)
- Consolidate inline pagination from ItemsPage/AuditPage into PageFooter
- Delete FooterStats.tsx (replaced by PageFooter)
- Replace all hardcoded padding/font/gap values in ItemTable, AuditTable,
ItemsToolbar, and AuditToolbar with var(--d-*) references
Comfortable mode is already tighter than the previous hardcoded values.
Compact mode reduces further for power-user density.
Add server-sent events at GET /api/events for live mutation
notifications. Add server mode (normal/read-only/degraded) exposed
via /health, /ready, and SSE server.state events.
New files:
- broker.go: SSE event hub with client management, non-blocking
fan-out, ring buffer history for Last-Event-ID replay, heartbeat
- servermode.go: mode state machine with periodic MinIO health
check and SIGUSR1 read-only toggle
- sse_handler.go: HTTP handler using http.Flusher and
ResponseController to disable WriteTimeout for long-lived SSE
- broker_test.go, servermode_test.go: 13 unit tests
Modified:
- handlers.go: Server struct gains broker/serverState fields,
Health/Ready include mode and sse_clients, write handlers
emit item.created/updated/deleted and revision.created events
- routes.go: register GET /api/events, add RequireWritable
middleware to all 8 editor-gated route groups
- middleware.go: RequireWritable returns 503 in read-only mode
- csv.go, ods.go: emit bulk item.created events after import
- storage.go: add Ping() method for health checks
- config.go: add ReadOnly field to ServerConfig
- main.go: create broker/state, start background goroutines,
SIGUSR1 handler, graceful shutdown sequence
Closes#38, closes#39
The /api/items/{pn}/projects endpoint returns Project objects
({id, code, name, created_at}), but MainTab typed them as string[].
React error #31 was thrown when trying to render the object as a
child node.
Change itemProjects state from string[] to Project[] and use
proj.code in all rendering and comparison logic.
Closes#33
- Mark Phase 4 (remove Go templates) as complete
- Update architecture: SPA serves at / via NotFound handler
- Update overview to past tense (migration is done)
- Update file/line counts (~40 files, ~7,600 lines)
- Mark backend changes 1-3 and 5 as implemented
- Reorganize remaining work section
Closes#30
- Remove silo-spec.md from doc table (deleted)
- Add CONFIGURATION.md, AUTH.md, AUTH_USER_GUIDE.md, frontend-spec.md to doc table
- Mark Configuration Reference as complete
- Fix audit_handlers.go filename (was handlers_audit.go)
- Update Appendix A file structure to match actual codebase
- Fix future migration numbering (012/013, since 011 is taken)
- Add file attachment endpoints to Appendix B
- Remove completed Documentation Overhaul from medium-term
Closes#28
- Replace all htmx references with React SPA
- Update endpoint count from 74 to 75 (6 occurrences)
- Update migration count from 10 to 11
- Update test file count from 1 to 9
- Fix comparison matrix web access entry
Closes#29
- Update migration count to 11, add 011_item_files.sql
- Update endpoint count from 74 to 75
- Replace htmx reference with React SPA
- Add file attachments as complete feature
- Update test file count from 1 to 9
- Update date to 2026-02-08
Closes#27
Remove maxWidth: 1400 and margin: 0 auto from AppShell main container.
Reduce padding from 2rem to 1rem so content fills available browser width.
Adjust height calc in ItemsPage and AuditPage from 80px to 64px offset
to account for reduced top padding.
Closes#16