FS Garage Utilisation (FE) Architecture
System Overview
Next.js App Router FE for FS Garage. Utilisation module displays BE-computed utilisation snapshots and manages allocations UI without duplicating scorecard math on the client.
Architecture Diagram
graph TB
subgraph FE["Frontend: base-fs-garage-fe"]
AuthMiddleware["1. middleware.js<br/>auth check"]
UtilizationPages["2. /utilization pages"]
LibHelpers["3. lib helpers<br/>PocketBase + timesheet"]
UiComponents["4. UI components<br/>shadcn / Radix"]
end
subgraph BE["Backend: fs-garage-base"]
PocketBaseServer["PocketBase :8091<br/>auth + collections"]
UtilisationHooks["pb_hooks<br/>utilisation / allocations"]
end
TimesheetApi["External Timesheet API"]
AuthMiddleware -->|"runs before page loads"| UtilizationPages
UtilizationPages -->|"uses helpers to fetch data"| LibHelpers
UtilizationPages -->|"renders UI with"| UiComponents
LibHelpers -->|"auth + CRUD"| PocketBaseServer
LibHelpers -->|"custom scorecard / allocation APIs"| UtilisationHooks
UtilisationHooks -->|"pulls actual hours"| TimesheetApi
How to read this diagram
Arrows mean flow / dependency / "talks to", not button clicks. Each arrow label says what happens on that step.
Core Components
Routes (app/(auth)/)
Auth-gated App Router routes. Utilisation lives at /utilization with header-only shell (no sidebar).
Data layer (lib/, hooks/)
PocketBase client for auth/CRUD/custom routes. Scorecard JSON is displayed as returned from BE.
UI
Utilisation uses Tailwind + shadcn/ui + Radix. Other Garage modules may use Mantine - follow the nearest existing screen pattern.
Data Flow
sequenceDiagram
participant User
participant Frontend as Utilisation Frontend
participant PocketBaseHooks as PocketBase hooks
participant TimesheetApi as Timesheet API
User->>Frontend: Open /utilization
Frontend->>PocketBaseHooks: GET /api/utilisation/scorecard
PocketBaseHooks-->>Frontend: snapshot JSON + sparklines
Frontend-->>User: Render scorecard
User->>Frontend: Run Now
Frontend->>PocketBaseHooks: POST /api/utilisation/run
PocketBaseHooks->>TimesheetApi: Pull actuals
PocketBaseHooks-->>Frontend: Upserted snapshot
Design Decisions
BE-computed snapshots
Context: Avoid FE/BE metric drift.
Decision: FE never recomputes utilisation maths; it renders snapshot JSON.
Header-only shell
Context: Match FS Garage UX.
Decision: No sidebar for Utilisation; 5th header icon after Timesheet.
Technology Stack
| Layer | Technology |
|---|---|
| Framework | Next.js App Router |
| Language | JavaScript |
| UI | Tailwind, shadcn/ui, Radix, Chart.js / AG Grid as used |
| Deploy | OpenNext Cloudflare |
| Default branch | dev |