Files
slp-modular-cms/aidlc-docs/features/cms-frontend/inception/application-design/application-design.md
T

6.4 KiB
Raw Blame History

Application Design — CMS Frontend

Overview

This document consolidates the complete application design for the CMS frontend feature. It covers both the backend prerequisite changes (Unit 0) and the full frontend React SPA (Units 16).

Tech decisions confirmed by user:

  • State management: React Context (auth) + TanStack Query (server state)
  • HTTP client: TanStack Query (server state) using native fetch via ApiClient wrapper
  • Form validation: react-hook-form + zod
  • Routing: TanStack Router — file-based (src/routes/)
  • Auth token storage: Access token in-memory (React context), refresh token in httpOnly cookie
  • Cookie: refreshToken, path /api/v1/auth, HttpOnly, Secure, SameSite=Strict
  • CORS origins: Configured via appsettings.json → Cors:AllowedOrigins[] (dotnet-appsettings pattern)
  • User data in context: Full user object { id, email, name, role, isActive }
  • Error boundaries: Global + per-page

Architecture at a Glance

graph LR
    subgraph FE["Frontend (frontend/)"]
        direction TB
        Infra["Infrastructure\nApiClient · AuthContext · RouterConfig"]
        Guards["Guards\nProtectedRoute · RoleGuard · InitGuard"]
        Layout["Layout\nAppLayout · Sidebar · ThemeProvider"]
        Hooks["TanStack Query Hooks\nuseAvailability · useUsers · useInvitation · useSetup"]
        Pages["Pages\nLogin · Setup · InviteComplete\nDashboard · Users · Profile\nSettings · CMS · 403 · 404"]
    end

    subgraph BE["Backend (src/)"]
        direction TB
        CORS["CORS Policy\n(ServiceCollectionExtensions)"]
        AuthCtrl["AuthController\n(httpOnly cookie)"]
        AuthSvc["AuthService"]
    end

    Pages --> Hooks
    Pages --> Infra
    Layout --> Infra
    Guards --> Infra
    Hooks --> Infra
    Infra -->|HTTP + cookie| AuthCtrl
    AuthCtrl --> AuthSvc

    style Infra fill:#FFC107,stroke:#F57F17,color:#000
    style Guards fill:#FF5722,stroke:#BF360C,color:#fff
    style Layout fill:#9C27B0,stroke:#4A148C,color:#fff
    style Hooks fill:#009688,stroke:#004D40,color:#fff
    style Pages fill:#2196F3,stroke:#0D47A1,color:#fff
    style CORS fill:#4CAF50,stroke:#2E7D32,color:#fff
    style AuthCtrl fill:#4CAF50,stroke:#2E7D32,color:#fff
    style AuthSvc fill:#FFC107,stroke:#F57F17,color:#000

Unit Decomposition Summary

Unit Name Primary Components
0 Backend Prerequisites CorsPolicy, AuthController (cookie), appsettings updates
1 Project Scaffold ApiClient, AuthContext, RouterConfig, ThemeProvider, ErrorBoundary, .env
2 Auth Pages LoginPage, SetupPage, InviteCompletePage, ProtectedRoute, RoleGuard, InitGuard
3 Layout & Navigation AppLayout, Sidebar
4 Dashboard DashboardPage, AvailabilityStatusBadge, useAvailabilityStatus
5 User Management UsersPage, InviteUserDialog, useUsers, useInviteUser, useValidateInvitation, useCompleteSetup
6 Remaining Pages ProfilePage, SettingsPage, CmsPage, NotFoundPage, AccessDeniedPage, README.md

Project Structure

frontend/
├── src/
│   ├── api/
│   │   ├── client.ts              # ApiClient (fetch wrapper, 401 interceptor)
│   │   ├── types.ts               # Shared TypeScript interfaces
│   │   ├── useAvailability.ts     # TanStack Query hooks
│   │   ├── useUsers.ts
│   │   ├── useInvitation.ts
│   │   └── useSetup.ts
│   ├── auth/
│   │   ├── AuthContext.tsx        # AuthContext + AuthProvider
│   │   ├── useAuth.ts             # useAuth hook
│   │   ├── ProtectedRoute.tsx
│   │   ├── RoleGuard.tsx
│   │   └── InitGuard.tsx
│   ├── components/
│   │   ├── layout/
│   │   │   ├── AppLayout.tsx
│   │   │   ├── Sidebar.tsx
│   │   │   └── ThemeProvider.tsx
│   │   ├── users/
│   │   │   └── InviteUserDialog.tsx
│   │   ├── shared/
│   │   │   └── AvailabilityStatusBadge.tsx
│   │   └── error/
│   │       └── ErrorBoundary.tsx
│   ├── routes/                    # TanStack Router file-based routes
│   │   ├── __root.tsx             # Root route (InitGuard, ErrorBoundary)
│   │   ├── index.tsx              # /  → DashboardPage
│   │   ├── login.tsx              # /login
│   │   ├── setup.tsx              # /setup
│   │   ├── invite.complete.tsx    # /invite/complete
│   │   ├── users.tsx              # /users  (Owner/Admin)
│   │   ├── profile.tsx            # /profile
│   │   ├── settings.tsx           # /settings  (Owner)
│   │   ├── cms.tsx                # /cms  (Owner)
│   │   ├── 403.tsx                # /403
│   │   └── $404.tsx               # catch-all
│   ├── routeTree.gen.ts           # Generated by TanStack Router CLI
│   ├── main.tsx                   # App entry point
│   └── app.tsx                    # QueryClientProvider + AuthProvider + RouterProvider
├── .env.example                   # Template for VITE_API_BASE_URL
├── .env                           # gitignored — developer local override
├── package.json
├── pnpm-lock.yaml
├── tsconfig.json
├── vite.config.ts
└── tailwind.config.ts

Security Design Summary

Concern Design Decision
Access token storage In-memory only (React state in AuthContext)
Refresh token storage httpOnly cookie — set/cleared by backend
CORS Named policy "FrontendPolicy" with specific origins + AllowCredentials()
Role enforcement RoleGuard (routing) + Sidebar (UX) + backend (authoritative)
HTTP calls Centralised through ApiClient only
Form validation zod schemas matching backend password rules
Error handling Global + per-page ErrorBoundary; generic user-facing error messages

Artifacts Index

Artifact Path
Component definitions inception/application-design/components.md
Method signatures inception/application-design/component-methods.md
Service layer inception/application-design/services.md
Dependency diagram inception/application-design/component-dependency.md
This document inception/application-design/application-design.md