- Add frontend-foundation change (FN-005) with 46 tasks - Add deployment-config change (FN-006) with 27 tasks - Add runfusion-poc/opencode-poc change (FN-008) with 25 tasks - Add config-secrets change (FN-009) with 31 tasks - Add codeserver-spawn change (FN-010) with 38 tasks - Include project specsheet and configuration - Archive completed deployment-config change
3.2 KiB
Context
The frontend is currently a static scaffold (FN-002) with no routing, auth, or API integration. The backend has complete domain models, CRUD routers, and auth dependencies (FN-004, FN-011). This design bridges the gap by establishing the frontend architecture needed for all user-facing features.
Current frontend state:
- Single App.tsx with static HTML
- No routing, state management, or API client
- No auth integration
- Tests only verify static rendering
Goals / Non-Goals
Goals:
- Deliver a functional auth flow (login/logout via Authentik OIDC)
- Provide a responsive dashboard shell with navigation
- Enable project CRUD operations from the UI
- Establish typed API client patterns
- Set up environment-based configuration
Non-Goals:
- Full tool spawn UI (deferred to FN-010/FN-008)
- Config/secrets management UI (deferred to FN-009)
- Repository connection UI (deferred to future task)
- Real-time updates or WebSockets
- Mobile-optimized responsive design (basic responsiveness only)
Decisions
1. React Router v7 for routing
- Rationale: Industry standard, integrates well with React 19, supports nested routes and loaders
- Alternative: TanStack Router - more type-safe but steeper learning curve, overkill for MVP
2. TanStack Query (React Query) for server state
- Rationale: Standard for API caching, background refetching, and optimistic updates
- Alternative: SWR - similar but TanStack Query has better TypeScript support and devtools
3. Zustand for client state
- Rationale: Lightweight, TypeScript-friendly, minimal boilerplate vs Redux
- Alternative: Context API - sufficient for auth but Zustand scales better for future features
4. HTTP client: fetch API with thin wrapper
- Rationale: No extra dependency needed, native fetch is sufficient
- Alternative: Axios - adds bundle size, fetch handles our use cases
5. Auth: OIDC Authorization Code flow with PKCE
- Rationale: Secure, recommended by OAuth 2.1, Authentik supports it
- Implementation: redirect to Authentik authorize endpoint, callback handles code exchange
6. Component library: Headless UI + Tailwind CSS
- Rationale: Unstyled primitives give full control, Tailwind is already in Vite scaffold
- Alternative: Material UI - opinionated, harder to customize
Risks / Trade-offs
[Risk] Auth token storage in browser → Mitigation: Use httpOnly cookies (set by backend callback) or secure storage. Never localStorage. Implement CSRF protection.
[Risk] OIDC library bundle size → Mitigation: Use lightweight oauth4webapi or implement PKCE manually (~2KB vs 50KB+ for oidc-client-ts)
[Risk] CORS complexity between web and API → Mitigation: Configure CORS in FastAPI to allow web origin. Use same-origin deployment in production (Traefik routes both).
[Risk] Test complexity with auth flows → Mitigation: Mock auth context in tests, test components in isolation. E2E tests deferred post-MVP.
Migration Plan
No migration needed - this is additive to the scaffold.
Open Questions
- Should we use a pre-built OIDC client library or implement PKCE manually?
- Do we need refresh token rotation or are short-lived access tokens sufficient?
- Should the API client auto-retry on 401 or redirect immediately?