ADR-002: The API is its own application

Status: Accepted Date: 2026-10-10

Context

Teacher dashboards need live updates, AI calls need server-side control over what leaves the system, and tablet apps will need the same API later. Vercel functions limit body size and duration, and the data lives in the home cluster.

Decision

apps/api is a separate Fastify application, written as a modular monolith (one module per domain under src/modules/). Zod schemas in packages/contract define requests and responses for both web and API. Drizzle with plain SQL migrations will handle database access. A worker runs from the same image when background jobs arrive. This follows vgu-graduation ADR-002.

Alternatives considered

  • Next.js route handlers or server actions as the API: fewer deployables, but tied to Vercel's limits and unusable from future mobile apps.
  • Microservices: independent scaling nobody needs at this size.

Consequences

  • The web app's typecheck fails when an endpoint's shape changes.
  • One image to build and deploy.
  • Module boundaries are enforced by review, not by the runtime.