Usage guide
pnpm workflow
App Router + Drizzle

Guide

Use the project confidently once the app is live.

This page is the hand-off surface for developers and product teams. It explains which routes matter, which commands are worth memorizing, and where to extend the project without turning the codebase into ceremony.

Clear entry points

See the exact pages and runtime routes you can hand to teammates once the app is deployed.

Small command surface

Use a short pnpm command surface for local dev, smoke tests, migrations, and observability checks.

Shallow structure

Keep extension work predictable by growing features inside a stable folder layout.

Complete request flow

Trace continuity survives from the route adapter down to the Drizzle query layer.

GET
/Everyone

Overview page that introduces the stack, architecture, and sample feature flow.

GET
/guideDevelopers

Onboarding page for commands, routes, extension points, and project structure.

GET
/operationsOperators

Runbook page for health checks, metrics, logs, traces, and Tempo usage.

GET
/api/healthLoad balancers / probes

Health JSON with app name, active database mode, and tracing configuration.

GET
/metricsPrometheus / SRE

Metrics exposition for route counters, process metrics, and database timings.

POST
/api/subscribersFeature smoke tests

Real sample workflow using Zod validation, Drizzle persistence, and tracing.

Layout
Project structure
You can add features without pulling business logic into route files.
  • src/appRoute entrypoints, page composition, and thin HTTP adapters only.
  • src/featuresBusiness rules, validation contracts, and repositories grouped by domain.
  • src/serverEnv parsing, observability, db wiring, and generic HTTP utilities.
  • src/componentsReusable UI primitives and client components that stay close to the app.
  • drizzleGenerated SQL migrations kept outside src for cleaner runtime code.
  • opsLocal Grafana and Tempo provisioning for observability smoke tests.
Principles
How to extend it safely
These rules keep the project production-ready without pushing it into enterprise ceremony.
  • Keep App Router files thin: parse the request, call a feature service, return a stable response.
  • Create spans at route, service, and repository boundaries so tracing stays useful without exploding cardinality.
  • Log with request and trace IDs by default so production incidents can be correlated quickly.
  • Prefer one shallow server layer for infra concerns instead of enterprise-style abstractions for every file.
Commands
Daily workflow
These are the commands worth learning if you use the repo every day.
  • pnpm checkRun linting, type checks, and unit tests in one pass.
  • pnpm e2eMigrate the local database, build the app, and run Playwright.
  • pnpm observability:upBoot Grafana and Tempo locally with ready-to-use provisioning.
  • pnpm observability:testStart the stack, run the app, and verify spans reach Tempo.
  • pnpm db:migrateApply committed migrations to the configured database.
  • pnpm devStart the local development server with the current configuration.
Request path
What happens during a request
The sample subscriber feature is the reference path for new domain features.

Entry point

A browser or API client loads a page or posts JSON to a route handler.

Route adapter

The App Router file parses input, starts the route span, and delegates immediately.

Service boundary

A feature service applies rules and emits a business-level span with stable names.

Repository and DB

A repository performs the Drizzle query and records database timing in child spans.

Observability trail

Logs, metrics, and traces are emitted together so the request can be reconstructed later.