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

6.8 KiB
Raw Blame History

Units of Work — CMS Frontend

Overview

The CMS frontend is decomposed into 7 sequential units (Unit 06). Each unit builds on the previous; dependencies flow strictly forward. All units together produce a single deployable SPA + updated backend API.

graph LR
    U0["Unit 0\nBackend Prerequisites"]
    U1["Unit 1\nProject Scaffold"]
    U2["Unit 2\nAuth Pages"]
    U3["Unit 3\nLayout & Nav"]
    U4["Unit 4\nDashboard"]
    U5["Unit 5\nUser Management"]
    U6["Unit 6\nRemaining Pages"]

    U0 --> U1 --> U2 --> U3 --> U4 --> U5 --> U6

    style U0 fill:#4CAF50,stroke:#2E7D32,color:#fff
    style U1 fill:#FFC107,stroke:#F57F17,color:#000
    style U2 fill:#FF5722,stroke:#BF360C,color:#fff
    style U3 fill:#9C27B0,stroke:#4A148C,color:#fff
    style U4 fill:#2196F3,stroke:#0D47A1,color:#fff
    style U5 fill:#009688,stroke:#004D40,color:#fff
    style U6 fill:#607D8B,stroke:#263238,color:#fff

Unit 0 — Backend Prerequisites

Type: Backend (.NET) — blocking prerequisite for all frontend units Priority: Must complete before Unit 1

Deliverables

  • ServiceCollectionExtensions.cs — add AddCorsFrontendPolicy() reading Cors:AllowedOrigins[] from config
  • Program.cs — add app.UseCors("FrontendPolicy") before UseAuthentication
  • AuthController.cs — update Login, Refresh, Revoke to use httpOnly cookie
  • RefreshTokenRequest.csremove (no backward compatibility needed; refresh now uses httpOnly cookie)
  • TokenResponse.cs — add Name property (display name from UserName or Email)
  • appsettings.json — add Cors section (production placeholder)
  • appsettings.Development.json — add Cors:AllowedOrigins: ["http://localhost:5173"]
  • Tests — update AuthController tests for cookie-based flow

Key Decisions

  • Cookie name: refreshToken, Path: /api/v1/auth, HttpOnly, Secure, SameSite=Strict
  • CORS: AllowCredentials() required for cookie flow
  • name field in TokenResponse maps from user.UserName ?? user.Email

Unit 1 — Project Scaffold & Infrastructure

Type: Frontend — foundation for all subsequent units Depends on: Unit 0 (API must be reachable with CORS)

Deliverables

frontend/
├── src/
│   ├── api/
│   │   ├── client.ts          # ApiClient: fetch + auth header + 401 interceptor
│   │   └── types.ts           # Shared TS interfaces (User, AuthResponse, etc.)
│   ├── auth/
│   │   ├── AuthContext.tsx    # AuthProvider: in-memory token + user state
│   │   └── useAuth.ts         # useAuth hook
│   ├── components/
│   │   ├── layout/
│   │   │   └── ThemeProvider.tsx
│   │   └── error/
│   │       └── ErrorBoundary.tsx
│   ├── main.tsx               # Entry: QueryClientProvider + AuthProvider + RouterProvider
│   └── app.tsx                # App root
├── .env.example               # VITE_API_BASE_URL=http://localhost:5000
├── .env                       # gitignored
├── vite.config.ts
├── tailwind.config.ts         # Primary color #ac0000
├── tsconfig.json
└── package.json               # pnpm workspace

Key Decisions

  • TanStack Router file-based routing initialized (empty route tree)
  • shadcn/ui configured with #ac0000 primary
  • ApiClient created; AuthContext wired up; QueryClient configured

Unit 2 — Authentication Pages

Type: Frontend — public + session management Depends on: Unit 1 (ApiClient, AuthContext)

Deliverables

frontend/src/
├── auth/
│   ├── ProtectedRoute.tsx     # Redirects unauthenticated → /login
│   ├── RoleGuard.tsx          # Redirects wrong role → /403
│   └── InitGuard.tsx          # Redirects uninitialized → /setup
├── api/
│   └── useSetup.ts            # useSetupStatus, useCreateOwner
└── routes/
    ├── __root.tsx             # Root route: InitGuard + global ErrorBoundary
    ├── login.tsx              # LoginPage
    ├── setup.tsx              # SetupPage
    └── invite.complete.tsx    # InviteCompletePage

Key Decisions

  • react-hook-form + zod for all forms; password schema enforces exact backend rules
  • InitGuard in __root.tsx blocks all routes until setup status confirmed
  • ProtectedRoute uses beforeLoad in TanStack Router

Unit 3 — Layout & Navigation

Type: Frontend — authenticated shell Depends on: Unit 2 (ProtectedRoute, RoleGuard, AuthContext)

Deliverables

frontend/src/
├── components/layout/
│   ├── AppLayout.tsx          # Shell: Sidebar + <Outlet />
│   └── Sidebar.tsx            # Role-filtered nav, logout, theme toggle
└── routes/
    └── _authenticated.tsx     # Authenticated layout route wrapping all protected pages

Key Decisions

  • _authenticated.tsx is a TanStack Router layout route — all child routes inherit ProtectedRoute
  • Sidebar filters nav items by user.role from AuthContext
  • Responsive: hamburger menu on mobile

Unit 4 — Dashboard

Type: Frontend — first authenticated page Depends on: Unit 3 (AppLayout, AuthContext)

Deliverables

frontend/src/
├── api/
│   └── useAvailability.ts     # useAvailabilityStatus (staleTime: 30s)
├── components/shared/
│   └── AvailabilityStatusBadge.tsx
└── routes/
    └── index.tsx              # DashboardPage: welcome + availability widget

Unit 5 — User Management

Type: Frontend — Owner/Admin feature Depends on: Unit 3 (AppLayout, RoleGuard), Unit 4 (patterns established)

Deliverables

frontend/src/
├── api/
│   ├── useUsers.ts            # useUsers, useInviteUser
│   └── useInvitation.ts       # useValidateInvitation, useCompleteSetup
├── components/users/
│   └── InviteUserDialog.tsx   # Two-step: invite form → share link
└── routes/
    └── users.tsx              # UsersPage: user table + invite dialog

Unit 6 — Remaining Pages & Documentation

Type: Frontend + Documentation Depends on: Unit 3 (AppLayout, RoleGuard)

Deliverables

frontend/src/routes/
├── profile.tsx               # ProfilePage: read-only user info
├── settings.tsx              # SettingsPage: Owner-only, availability + placeholders
├── cms.tsx                   # CmsPage: Owner-only placeholder
├── 403.tsx                   # AccessDeniedPage
└── $404.tsx                  # NotFoundPage

Documentation:

  • README.md — add Frontend Development section:
    • Prerequisites (Node.js, pnpm)
    • pnpm install in frontend/
    • .env setup (copy .env.example)
    • pnpm dev to start dev server
    • pnpm build for production build
    • Security headers note for production deployment