FS Garage Utilisation (BE) Architecture
System Overview
PocketBase serves collections and custom JS hooks. Utilisation joins published allocations with external Timesheet API data to produce scorecard snapshots stored as JSON.
Architecture Diagram
graph TB
FrontendApp["Frontend<br/>base-fs-garage-fe"]
UtilisationHooks["pb_hooks<br/>utilisation + allocations"]
PublishedAllocations["allocations<br/>published weeks"]
TimesheetApi["External Timesheet API"]
UtilisationSnapshots["utilisation_snapshots<br/>scorecard JSON"]
FrontendApp -->|"GET scorecard / POST run"| UtilisationHooks
FrontendApp -->|"publish / copy-forward"| UtilisationHooks
PublishedAllocations -->|"planned hours input"| UtilisationHooks
TimesheetApi -->|"actual hours on run"| UtilisationHooks
UtilisationHooks -->|"writes computed snapshot"| UtilisationSnapshots
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
Collections
users/projectswith timesheet bridge IDsallocations- weekly planned hoursutilisation_snapshots- computed scorecard JSON
Hooks
Copy patterns from weekly_hook.pb.js (routerAdd, $app queries, JSON responses).
Planned utilisation hooks: allocations.pb.js, utilisation.pb.js, utilisation-calc.js.
Data Flow
- Publish allocations for a week
POST /api/utilisation/runpulls Timesheet actuals- BE computes snapshot (including
unloggedHours) - FE reads
GET /api/utilisation/scorecard(sparklines from prior snapshots)
Design Decisions
- Calc logic in BE hooks only - never push math to FE
- Do not store full timesheet as source of truth
pb_schema.jsonis stale; trustpb_migrations/- Local PocketBase only for development (ADR-005)
Technology Stack
| Layer | Technology |
|---|---|
| Runtime | PocketBase |
| DB | SQLite |
| Hooks | JavaScript pb_hooks |
| Templates | templates/ email templates |