Express + TypeScript reference implementation for FFMS REST modules. Copy .cursor/rules/ffms-backend-express.mdc, ffms-api-stack.mdc, and ffms-api-engineering.mdc as the authority.
src/app.ts—createApp(env)for server + Vitest/Supertest (no listen).src/features/<name>/—*.routes.ts,*.controller.ts,*.service.ts,*.repository.ts,*.schemas.ts.src/db/— Drizzle client +schema/(align migrations withdocs/schema/ffms_postgresql.sql).
Reference modules:
| Module | Route | Notes |
|---|---|---|
| health | GET /api/v1/health |
No database. |
| contributions | GET /api/v1/contributions |
D2 list by memberId + optional cycleYear / cycleMonth; requires DATABASE_URL. |
cp .env.example .env
npm install
npm run devHooks and config live only under this package (fms-api/.husky, lint-staged.config.mjs).
preparerunsnode scripts/husky-prepare.mjs, which finds the git root and runshuskypointing atfms-api/.huskywhen this repo is a monorepo with a parent.git, or at.huskywhenfms-apiis the repository root..husky/pre-commit→lint-staged(ESLint + Prettier on staged files here)..husky/pre-push→npm run typecheck,npm test, andnpm run build.
Run npm install from fms-api/ after clone so hooks install. In CI, set HUSKY=0 (and/or CI=true) to skip the install step.
npm test # Vitest once (used in pre-push)
npm run test:watch- Unit: Zod schemas, health service/controller, contributions service/controller (
src/**/*.test.ts). - HTTP integration:
createApp+ Supertest (src/create-app.http.test.ts) — nolisten(), perffms-api-stack.mdc.
Repository integration tests against real Postgres are optional (see engineering rules); not included here.
Errors use a stable code string where possible:
{ "code": "VALIDATION_FAILED", "message": "…" }import request from "supertest";
import { createApp } from "./app";
import { loadEnv } from "./config/env";
import { initDb } from "./db";
const env = loadEnv();
initDb(env.DATABASE_URL);
const app = createApp(env);
const res = await request(app).get("/api/v1/health").expect(200);Add Vitest + supertest per .cursor/rules/ffms-api-stack.mdc for CI.