Files
project-manager/docs/architecture.md
T
aneurinandClaude Sonnet 5 fb67b57807 Reorganize docs: simple README + organized docs/
Removed docs/stage-1-auth-api.md -- an early planning doc, badly out
of date (predates passwordless auth, statuses, the inbox, and
everything after).

README.md is now just: what this is, a pointer to docs/, an end-user
getting-started guide (Docker up, first-time login via the bundled
Mailpit catcher, adding a passkey), and provenance -- everything else
it used to carry moved out:

- docs/api.md -- the full REST API reference (auth, passkeys,
  projects, cards, statuses, error shape) + the curl walkthrough.
- docs/setup.md -- running without Docker, every environment
  variable, the test suite.
- docs/architecture.md -- backend file layout; points to
  web/README.md for the frontend, which already documented itself in
  enough depth to stand alone.
- docs/history.md -- the stage-by-stage feature log, with a new row
  for this session's refactoring work (which hadn't been logged yet).
- docs/README.md -- an index tying the above together.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 01:41:55 +01:00

2.3 KiB

Architecture

A REST API in PHP 8 (Slim 4) over a single SQLite file, plus a Vue 3 + TypeScript PWA frontend. Auth is a bearer JWT, obtained via a magic link or a passkey (see docs/api.md) — there's no session store or cookie.

Backend layout

public/index.php              Front controller
src/bootstrap.php             App wiring and route definitions
src/Support/Config.php        Environment-driven configuration
src/Support/Database.php      PDO/SQLite connection
src/Auth/JwtService.php       Issue/verify JWTs
src/Auth/AuthMiddleware.php   Bearer-token authentication
src/Auth/SessionPayload.php   Shared user + session JSON shape
src/Mail/                     Mailer interface, SMTP/mail()/log transports, EmailVerifier
src/Http/JsonErrorHandler.php Uniform JSON error envelope
src/Http/Controllers/        Request handlers (Auth, EmailVerification, Passkey, Project, Card, CardStatus)
src/Repository/              Database access (User, EmailVerification, Passkey, WebAuthnChallenge, Project, Card, CardStatus)
src/Support/Validator.php    Request-body validation helper
migrations/*.sql             Schema, applied by bin/migrate.php
Dockerfile                   Multi-stage: Node frontend build + PHP 8.3/Apache runtime
docker-compose.yml           Local stack: app (SPA + API) + Mailpit
docker/                      Apache vhost + container entrypoint
web/                         Vue 3 + TypeScript + Vite PWA frontend (dev on the host)

A ProjectScopedController base class centralizes "look up a project owned by the caller, or 404" for the controllers that need it (Project, Card, CardStatus). Every table a request can reach is scoped to the authenticated user one way or another — directly (owner_id/user_id) or via a project that is.

Frontend

The Vue/TypeScript PWA lives in web/ and is a separate concern with its own conventions (routing, state, styling, drag-and-drop). See web/README.md for all of that — this document only covers the backend.

Database

One SQLite file, migrated forward-only by bin/migrate.php from migrations/*.sql (each applied file is recorded in a schema_migrations table, so re-running is safe). See docs/setup.md for how to run migrations, and docs/history.md for how the schema and the rest of the app got here.