9e2e4ec338
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5.9 KiB
5.9 KiB
Frontend — Status
What it is
React 18 + TypeScript + Vite SPA. In dev it runs on port 5173 and proxies /api/* to backend:8000. In prod it is served by nginx on port 80.
All API calls go through src/api/client.ts (single Axios instance, JWT injected via request interceptor from localStorage).
Routes
| Path | Component | Auth |
|---|---|---|
/login |
LoginPage |
Public |
/ |
DashboardPage |
Required |
/apps |
AppsPage |
Required |
/apps/documents |
DocumentsPage |
Required |
/apps/documents/settings/admin |
DocumentAdminSettingsPage |
Admin only |
/apps/ai/settings/admin |
AIAdminSettingsPage |
Admin only |
/admin |
AdminPage |
Admin only |
/profile |
ProfilePage |
Required |
PrivateRoute redirects to /login when no token. AdminRoute redirects to / when not admin.
Current functionality
Auth
- Login form (
POST /api/auth/login) stores JWT inlocalStorage - Logout clears token and redirects to
/login GET /api/users/meverifies token on protected routes
Apps page (/apps)
Cards for each installed app:
- Documents — link to
/apps/documents; admin gear icon →/apps/documents/settings/admin - AI Service — infrastructure card; admin gear icon →
/apps/ai/settings/admin; no Open button (no user-facing UI)
Documents page (/apps/documents)
Upload: PDF file input, 202 response, error display.
Filter bar:
- Search input (400ms debounce) — matches title, filename, tags, document_type
- Status dropdown (all / pending / processing / done / failed)
- Type dropdown (all / invoice / bill / receipt / order / expense / revenue / unknown)
- Sort selector (upload date / processed date / title / filename / file size / type / status)
- Asc/Desc toggle
- "Clear filters" button (appears when any filter is active)
Pagination: Prev/Next with "X–Y of Z" count. Only shown when total > per_page.
Document row (collapsed):
- Inline title editor (pencil icon, Enter to save, Esc to cancel; shows filename in italic when no title)
- Status badge (colour-coded)
- Document type label
- File size
- View button (opens PDF in new tab via blob URL — auth-gated)
- Download button
- Delete button (confirm dialog)
Document row (expanded):
- Tag editor — read mode shows chips + Edit button; edit mode has removable chips + input (Enter/comma to add) + Save/Cancel
- Extracted data table — all AI-extracted JSON fields (excludes
tags,suggested_categories) - Error message — shown if status=failed
- Categories — assigned chips with remove; dropdown to assign existing; AI-suggested chips with Accept / Create & Assign / Dismiss
- Status polling — auto-refetches every 3s while status is pending/processing; invalidates document list on done/failed
AI Admin Settings (/apps/ai/settings/admin)
- Provider selector (lmstudio / ollama / anthropic)
- Per-provider fields (base URL, model, API key)
- Test Connection button (
POST /api/settings/ai/test) - Save button
Document Admin Settings (/apps/documents/settings/admin)
- Upload Limits section only (max PDF size in MB)
- Save button
Admin page (/admin)
- User list with role and active status
- Inline role/status editing
Profile page (/profile)
- Display and edit personal information
API client (src/api/client.ts)
Key functions:
| Function | Description |
|---|---|
listDocuments(params) |
GET /documents — returns DocumentPage |
uploadDocument(file) |
POST /documents/upload |
deleteDocument(id) |
DELETE /documents/{id} |
downloadDocument(id, filename) |
Blob URL download |
viewDocument(id) |
Blob URL → window.open, auto-revoke after 60s |
getDocumentStatus(id) |
Poll endpoint |
listCategories() |
All categories for user |
createCategory(name) |
Create category |
assignCategory(docId, catId) |
Assign |
removeCategory(docId, catId) |
Remove |
updateDocumentTags(id, tags) |
PATCH /documents/{id}/tags |
updateDocumentTitle(id, title) |
PATCH /documents/{id}/title |
getAISettings() |
GET /settings/ai (masked) |
updateAISettings(data) |
PATCH /settings/ai |
testAIConnection() |
POST /settings/ai/test |
getDocumentLimits() |
GET /settings/documents/limits |
updateDocumentLimits(data) |
PATCH /settings/documents/limits |
State management
- TanStack Query — all server state;
queryKey: ["documents", params]for cache isolation per filter/page combination - No global store — local
useStatefor UI-only state (editing mode, filter params, etc.) - Token —
localStorage, read byuseAuthhook, injected by Axios interceptor
Known limitations / not implemented
- JWT in
localStorage— XSS risk; migrate tohttpOnlycookie when backend supports it - No toast / notification system — errors shown inline; success is silent
- No loading skeletons — "Loading…" text only
- No UI component library — raw inline styles throughout; shadcn/ui + Tailwind CSS adoption in progress
- No group/sharing UI — blocked on backend groups system
- No app permission UI — all apps visible to all authenticated users
Future work
- UI component library: shadcn/ui + Tailwind CSS confirmed
- Toast notification system (upload success, save feedback, errors)
- Loading skeletons
POST /queue/jobsintegration — show AI processing queue status / progress per document- Re-process document button (
POST /documents/{id}/reprocess— needs backend endpoint first) - Advanced filter: extracted data fields (vendor, due date, amount) — needs backend support
- Groups + document sharing UI — blocked on backend
- App permissions UI in Admin page
httpOnlycookie auth (requires backend change)- Bulk document operations (select multiple, bulk delete / bulk categorise)