Files
headquarter/openspec/changes/archive/2026-05-14-frontend-foundation/design.md
T
alex 78aaddb2b5
CI / Web CI (push) Failing after 12s
CI / API CI (push) Failing after 1m1s
docs(openspec): add OpenSpec changes for FN-005, FN-006, FN-008, FN-009, FN-010
- 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
2026-05-14 17:35:20 +02:00

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

  1. Should we use a pre-built OIDC client library or implement PKCE manually?
  2. Do we need refresh token rotation or are short-lived access tokens sufficient?
  3. Should the API client auto-retry on 401 or redirect immediately?