Architecture Overview
High-Level Architecture
Section titled “High-Level Architecture”Browser → Cloudflare Access (auth) → Cloudflare Worker (Hono API + SPA) ↓ Cloudflare D1 (SQLite)The platform is a single-page application (React) served by a Cloudflare Worker (Hono). The Worker handles both static asset serving and API requests. All authentication happens at the edge via Cloudflare Access.
Project Structure
Section titled “Project Structure”dotcollective-tools/├── src/ # Frontend SPA (React + TypeScript)│ ├── components/│ │ ├── ui/ # shadcn/ui components│ │ ├── layout/ # App shell, sidebar, header│ │ ├── admin/ # Admin section (Executive only)│ │ ├── onboarding/ # Onboarding tool components│ │ └── scorecards/ # Scorecards tool components│ ├── routes/ # TanStack Router file-based routes│ ├── lib/ # Utilities, auth context, types│ └── hooks/ # TanStack Query hooks per tool├── worker/ # Hono API (Cloudflare Workers)│ ├── routes/ # API route handlers│ ├── middleware/ # Auth + permission middleware│ └── lib/ # CF Access JWT validation├── db/ # D1 schema and seed data├── docs/ # Starlight documentation site└── .claude/ # Claude Code configurationRequest Flow
Section titled “Request Flow”- User visits
app.dotcollective.com.au - Cloudflare Access intercepts, authenticates via Google Workspace
- Request reaches the Worker with a signed JWT in
Cf-Access-Jwt-Assertionheader - Auth middleware validates JWT, upserts user in D1
- Permission middleware checks tool-level access for the requested action
- Route handler processes request, scopes data by access level
- Response returned to the frontend
Key Design Decisions
Section titled “Key Design Decisions”- SPA over SSR: Internal tool with authenticated users - no SEO needed, simpler deployment
- Single Worker: One deployment serves both API and SPA via Wrangler
[assets]config - D1 over KV: Relational data (users, permissions, scorecards) benefits from SQL
- Cloudflare Access over custom OAuth: Eliminates auth code, session management, login UI
- shadcn/ui over component library: Owned components, full customisation, no version lock-in