diff --git a/frontend-spec.md b/frontend-spec.md index 6354d28..4e29629 100644 --- a/frontend-spec.md +++ b/frontend-spec.md @@ -1,10 +1,10 @@ # Silo Frontend Specification -Current as of 2026-02-06. Tracks the React + Vite + TypeScript frontend migration (epic #6). +Current as of 2026-02-08. Documents the React + Vite + TypeScript frontend (migration from Go templates is complete). ## Overview -The Silo web UI is being migrated from server-rendered Go templates with vanilla JavaScript (~7,000 lines across 7 templates) to a React single-page application. The Go API server remains unchanged — it serves JSON at `/api/*` and the React app consumes it. +The Silo web UI has been migrated from server-rendered Go templates to a React single-page application. The Go templates (~7,000 lines across 7 files) have been removed. The Go API server serves JSON at `/api/*` and the React SPA at `/`. **Stack**: React 19, React Router 7, Vite 6, TypeScript 5.7 **Theme**: Catppuccin Mocha (dark) via CSS custom properties @@ -19,22 +19,21 @@ The Silo web UI is being migrated from server-rendered Go templates with vanilla | 1 | #7 | Scaffold React + Vite + TS, shared layout, auth, API client | Code complete | | 2 | #8 | Migrate Items page with UI improvements | Code complete | | 3 | #9 | Migrate Projects, Schemas, Settings, Login pages | Code complete | -| 4 | #10 | Remove Go templates, Docker integration, cleanup | Not started | +| 4 | #10 | Remove Go templates, Docker integration, cleanup | Complete | ## Architecture ``` Browser - └── React SPA (served at /app/* during transition, / after Phase 4) + └── React SPA (served at /) ├── Vite dev server (development) → proxies /api/* to Go backend └── Static files in web/dist/ (production) → served by Go binary Go Server (silod) - ├── /api/* JSON REST API (unchanged) + ├── /api/* JSON REST API ├── /login, /logout Session auth endpoints (form POST) ├── /auth/oidc OIDC redirect flow - ├── /app/* React SPA static files (current transition) - └── /* Go template pages (removed in Phase 4) + └── /* React SPA (NotFound handler serves index.html for client-side routing) ``` ### Auth Flow @@ -101,7 +100,7 @@ web/ └── AuditPage.tsx Audit completeness (placeholder, expanded in Issue #5) ``` -**Total**: 32 source files, ~5,300 lines of TypeScript/TSX. +**Total**: ~40 source files, ~7,600 lines of TypeScript/TSX. ## Design System @@ -229,25 +228,17 @@ Basic table showing audit completeness data from `GET /api/audit/completeness`. **Import**: CSVImportResult, CSVImportError **Errors**: ErrorResponse -## Remaining Work +## Completed Work -### Issue #10: Remove Go Templates + Docker Integration +### Issue #10: Remove Go Templates + Docker Integration -- COMPLETE -The final phase completes the migration: +Completed in commit `50923cf`. All Go templates deleted, `web.go` handler removed, SPA serves at `/` via `NotFound` handler with `index.html` fallback. `build/package/Dockerfile` added. -**Remove Go templates**: Delete `internal/api/templates/` (7 HTML files), remove template loading code, remove web handler route group and CSRF middleware for web routes, remove `HandleIndex`, `HandleProjects`, `HandleSchemas`, `HandleSettings` handlers. - -**SPA serving**: Serve `web/dist/` at `/` with SPA fallback (non-API routes return `index.html`). Either `go:embed` for single-binary deployment or filesystem serving. `/api/*` routes must take precedence. Cache headers for Vite's hashed assets. - -**Docker**: Update `build/package/Dockerfile` to multi-stage — Stage 1: Node (`npm ci && npm run build`), Stage 2: Go build with `web/dist/`, Final: minimal Alpine image with single binary. - -**Makefile**: Existing `web-install`, `web-dev`, `web-build` targets need verification. `make build` should include the web build step. `make clean` should include `web/dist/`. - -**Acceptance criteria**: Single Docker image serves both API and React frontend. `make build` produces working binary. No Go template code remains. All pages accessible at React Router paths. +### Remaining Work ### Issue #5: Component Audit UI (future) -After migration completes, the Audit page will be expanded with completeness scoring, inline editing, tier filtering, and category breakdowns. This will be built natively in React using the patterns established in the migration. +The Audit page will be expanded with completeness scoring, inline editing, tier filtering, and category breakdowns. This will be built natively in React using the patterns established in the migration. ## Development @@ -572,11 +563,11 @@ The right sidebar is divided into three sections with `borderBottom: 1px solid v **Thumbnail**: A 4:3 aspect ratio placeholder box (`--ctp-crust` bg, `--ctp-surface0` border) with centered text "Generated from CAD file or upload manually". Clicking opens file picker filtered to images. If a thumbnail is uploaded, show it as an `` with `object-fit: cover`. -## Backend Changes Required +## Backend Changes -The following API additions are needed. These should be tracked as sub-tasks or a separate issue. +Items 1-3 and 5 below are implemented (migration `011_item_files.sql`, `internal/api/file_handlers.go`). Item 4 (hierarchical categories) remains open. -### 1. Presigned Upload URL +### 1. Presigned Upload URL -- IMPLEMENTED ``` POST /api/uploads/presign @@ -586,7 +577,7 @@ Response: { "object_key": "uploads/tmp/{uuid}/{filename}", "upload_url": "https: The Go handler generates a presigned PUT URL via the MinIO SDK. Objects are uploaded to a temporary prefix. On item creation, they're moved/linked to the item's permanent prefix. -### 2. File Association +### 2. File Association -- IMPLEMENTED ``` POST /api/items/{id}/files @@ -596,7 +587,7 @@ Response: { "file_id": "uuid", "filename": "...", "size": ..., "created_at": ".. Moves the object from the temp prefix to `items/{item_id}/files/{file_id}` and creates a row in a new `item_files` table. -### 3. Thumbnail +### 3. Thumbnail -- IMPLEMENTED ``` PUT /api/items/{id}/thumbnail @@ -606,7 +597,7 @@ Response: 204 Stores the thumbnail at `items/{item_id}/thumbnail.png` in MinIO. Updates `item.thumbnail_key` column. -### 4. Hierarchical Categories +### 4. Hierarchical Categories -- NOT IMPLEMENTED If schemas don't currently support a hierarchical category tree, one of these approaches: @@ -634,7 +625,7 @@ DELETE /api/categories/{id} → cascade check **Recommendation**: Option B is more flexible and keeps categories as a first-class entity. The three-tier picker doesn't need to be limited to exactly three levels — it can render as many columns as the deepest category path, but three is the practical default (Domain → Group → Subtype). -### 5. Database Schema Addition +### 5. Database Schema Addition -- IMPLEMENTED ```sql CREATE TABLE item_files (