fix architecture and write new tests

This commit is contained in:
root
2026-06-10 00:40:19 -04:00
parent 560da1cadf
commit 80a597bc10
377 changed files with 84020 additions and 1337 deletions
+13 -14
View File
@@ -89,7 +89,7 @@ apps/dashboard/
src/hooks/
useTeam.ts team management data/actions
src/lib/
api.ts fetch wrapper and auth token handling
api.ts cookie-aware API fetch wrapper
preferences.ts language/theme persistence scoped per employee
dashboardPaths.ts normalizes basePath-aware routes
urls.ts resolves marketplace/admin app links
@@ -102,7 +102,7 @@ Most dashboard screens are client components.
That is a deliberate fit for the app because the dashboard relies heavily on:
- local auth state from `localStorage`
- HttpOnly session-cookie authentication
- cookie and embedded-host redirects
- optimistic UI updates
- direct REST fetches after mount
@@ -117,23 +117,22 @@ The root `src/app/layout.tsx` is still server-rendered enough to:
## Auth and Session Model
The dashboard uses employee JWTs issued by the API.
The dashboard uses API-issued employee sessions stored in an HttpOnly cookie.
### Login flow
`src/app/sign-in/[[...sign-in]]/SignInPageClient.tsx`:
1. submits credentials to `POST /auth/employee/login`
2. stores the returned token in `localStorage` under `employee_token`
3. stores the employee profile in `localStorage` under `employee_profile`
4. mirrors the token into the `employee_token` cookie
5. redirects to the requested dashboard path
2. receives an HttpOnly `employee_session` cookie from the API
3. stores only non-sensitive employee profile/preferences client-side
4. redirects to the requested dashboard path
The sign-in page also supports:
- language and theme query params
- embedded usage through `postMessage`
- redirect handoff to the admin app when an admin token is returned instead of an employee token
- redirect handoff to the admin app after the API sets the admin HttpOnly session cookie
### Protected-route middleware
@@ -142,7 +141,7 @@ The sign-in page also supports:
Important behavior:
- public dashboard routes are limited to sign-in and forgot-password flows
- all other `/dashboard/*` routes require the `employee_token` cookie
- all other `/dashboard/*` routes require the `employee_session` cookie
- unauthenticated users are redirected either to the marketplace root or to `/dashboard/sign-in`, depending on host context
- duplicate `/dashboard/dashboard` paths are normalized back to `/dashboard`
@@ -222,7 +221,7 @@ It handles:
- current theme: `light`, `dark`
- full in-app copy dictionaries
- persistence to cookies and `localStorage`
- per-employee scoped preferences using the decoded JWT subject
- per-employee scoped preferences using non-sensitive cached profile metadata
`src/lib/preferences.ts` is the key utility here. It stores both:
@@ -239,8 +238,8 @@ The dashboard centralizes API access in `src/lib/api.ts`.
Browser fetch behavior:
- reads the JWT from `localStorage`
- injects `Authorization: Bearer <token>` when present
- never reads authentication tokens from `localStorage`
- sends authenticated requests with the HttpOnly session cookie
- defaults JSON requests to `Content-Type: application/json`
- preserves `FormData` for file uploads
- includes credentials for cookie-aware flows
@@ -253,7 +252,7 @@ Browser base URL:
### `apiFetchServer`
Server-side helper for routes/components that already have a token and need `cache: 'no-store'`.
Server-side helper for routes/components that explicitly receive a trusted server-side token and need `cache: 'no-store'`. Browser code should use HttpOnly cookies instead.
### Pattern used across pages
@@ -647,7 +646,7 @@ Examples in the code:
It also coordinates with sibling apps:
- `marketplaceUrl` links staff back to the public marketplace domain
- `adminUrl` supports token handoff into the admin interface
- `adminUrl` supports cookie-based handoff into the admin interface
- host-aware URL rewriting allows the same app to function under external domains, internal Docker hostnames, and proxied environments
## API Dependency Summary