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
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
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
Rewrite CreateItemPane from single-column scrolling form to a
two-column CSS Grid layout (1fr 280px):
Left column (scrollable form):
- Identity section: Type select, Description input, CategoryPicker
- Sourcing section: Sourcing Type, Standard Cost, Sourcing Link
- Details section: Long Description textarea, Projects TagInput
- Category Properties: dynamic fields from schema (2-column sub-grid)
- Section headers with uppercase labels and horizontal dividers
Right column (sidebar):
- Metadata: auto-assigned revision ('A'), created by (current user)
- Attachments: FileDropZone with presigned upload integration
- Thumbnail: 4:3 preview box, click to upload image
Submission flow:
1. POST /api/items with form data
2. Associate uploaded attachments via POST /api/items/{pn}/files
3. Set thumbnail via PUT /api/items/{pn}/thumbnail
4. File failures are non-blocking (item already created)
Integrates: CategoryPicker (#13), TagInput (#11), FileDropZone (#14),
useFileUpload presigned upload hook (#12)
Closes#15
New files:
- web/src/hooks/useFileUpload.ts: presigned upload hook that gets
a presigned PUT URL from POST /api/uploads/presign then uploads
via XMLHttpRequest for progress tracking
- web/src/components/items/FileDropZone.tsx: drag-and-drop file
upload zone with file list, type-colored badges (CAD/PDF/IMG),
progress bars, and remove buttons
Features:
- Dashed border drop zone with drag-over visual feedback
- Click to browse or drag files to add
- File type detection by extension with colored badges
- Upload progress bar (2px mauve) during active uploads
- Error state display per file
- Configurable accepted file types via accept prop
Closes#14
Replace the flat <select> dropdown for category selection in
CreateItemPane with a searchable, scrollable CategoryPicker component.
New files:
- web/src/hooks/useCategories.ts: fetches and caches category enum
values from GET /api/schemas/kindred-rd, extracts the category
segment values map
- web/src/components/items/CategoryPicker.tsx: scrollable list with
search input filtering by code and description, selected item
highlighted with mauve, breadcrumb showing current selection
Modified:
- web/src/components/items/CreateItemPane.tsx: replaced <select>
with <CategoryPicker>, uses useCategories hook instead of
fetching full schema inline
Closes#13
Build the full Audit page replacing the minimal stub with:
Phase 1 - Audit Overview:
- useAudit hook with server-side filtering by project, category,
tier (mapped to min_score/max_score), sort, and pagination
- AuditSummaryBar: horizontal stacked bar with tier counts, colored
segments (critical/low/partial/good/complete), clickable to filter
- AuditToolbar: project and category dropdowns, sort selector,
layout toggle
- AuditTable: sortable table with score badge (colored by tier),
part number, description, category, sourcing type, missing count
- SplitPanel integration (reused from items) with persistent layout
Phase 2 - Inline Edit Panel:
- AuditDetailPanel: split-panel detail view with field-by-field
breakdown from GET /api/audit/completeness/{pn}
- Fields grouped into Required, Procurement, Category Properties,
and Computed sections
- Color-coded left border per field: green if filled, red if empty
- Critical fields (weight >= 3) marked with asterisk
- Inline editing with debounced auto-save on blur (500ms)
- Item-level fields saved via PUT /api/items/{pn}
- Property fields saved via PUT with merged properties + new revision
- Score progress bar updates live after each save
- Computed fields (has_bom) shown read-only
All components use inline CSS with Catppuccin Mocha theme variables,
matching the existing frontend patterns.
Closes#5
Phase 1 of frontend migration (epic #6, issue #7).
Project setup (web/):
- React 19, React Router 7, Vite 6, TypeScript 5.7
- Catppuccin Mocha theme CSS variables matching existing Go templates
- Vite dev proxy to Go backend at :8080 for /api/*, /login, /logout,
/auth/*, /health, /ready
Shared infrastructure:
- api/client.ts: typed fetch wrapper (get/post/put/del) with 401
redirect and credentials:include for session cookies
- api/types.ts: TypeScript interfaces for all API response types
(User, Item, Project, Schema, Revision, BOMEntry, Audit, Error)
- context/AuthContext.tsx: AuthProvider calling GET /api/auth/me
- hooks/useAuth.ts: useAuth() hook exposing user/loading/logout
UI shell:
- AppShell.tsx: header nav matching current Go template navbar
(Items, Projects, Schemas, Audit, Settings) with role badges
(admin=mauve, editor=blue, viewer=teal) and active tab highlighting
- LoginPage: redirects to Go-served /login during transition
- Placeholder pages: Items, Projects, Schemas fetch from API and
display data in tables; Audit shows summary stats; Settings shows
current user profile
Go server changes:
- routes.go: serve web/dist/ at /app/* with SPA index.html fallback
(only activates when web/dist/ directory exists)
- .gitignore: web/node_modules/, web/dist/
- Makefile: web-install, web-dev, web-build targets