batchCooking/apps/api/src/app.ts
Nicolas 1d03effc77 API: endpoints foyer/profil (nom, régime, allergènes) (step 2/6)
- GET/PATCH /house/current — renomme le foyer de l'utilisateur connecté.
  PATCH avec houseId null -> 404 HOUSE_NOT_FOUND.
- PATCH /profile/diet { dietId: number | null } — régime du profil ;
  null l'efface (étape skippable du parcours). dietId invalide ->
  404 DIET_NOT_FOUND.
- GET/PATCH /profile/allergies — allergènes/intolérances, liste d'IDs ;
  PATCH remplace l'ensemble complet (pas une fusion, cohérent avec un
  multi-select). ID invalide -> 404 ALLERGY_NOT_FOUND.
- 3 nouveaux ErrorCode (4041-4043) + libellés fr.
- Extraction de toSafeProfile() dans src/lib/safe-profile.ts —
  auparavant dupliqué dans auth.service.ts et require-auth.ts,
  profile.service.ts le réutilise aussi.
- Tests Mocha (28 passing) + Cucumber (15 scenarios) — même convention
  que le reste, doc README.

Deuxième commit de la feature profil/foyer/régime/allergènes —
composants front partagés dans le commit suivant.
2026-08-16 23:18:46 +02:00

57 lines
2.5 KiB
TypeScript

import { errorHandlerService } from "@batch-cooking/error-tools";
import { ExpressServer, createErrorMiddleware } from "@batch-cooking/express-tools";
import { ErrorCode } from "@batch-cooking/shared";
import type { Express, Request, Response } from "express";
import { env } from "./config/env.js";
import { authRouter } from "./modules/auth/auth.routes.js";
import { houseRouter } from "./modules/house/house.routes.js";
import { planningRouter } from "./modules/planning/planning.routes.js";
import { profileRouter } from "./modules/profile/profile.routes.js";
import { referenceRouter } from "./modules/reference/reference.routes.js";
/**
* Builds the API's `ExpressServer`: standard middleware, routes, and the
* final error handler, in that order. Returns the `ExpressServer` wrapper
* (not just the raw Express app) so `server.ts` can call `.listen()` on
* it — {@link createApp} below is the thinner entry point that exposes
* just the raw `Express` instance, for test tooling (supertest) that
* expects one.
*/
export function createServer(): ExpressServer {
const server = new ExpressServer();
server.setupCore({ corsOrigin: env.CORS_ORIGIN });
server.addRoute("get", "/health", (_req: Request, res: Response) => {
res.status(200).json({ status: "ok" });
});
server.mountRouter("/auth", authRouter);
server.mountRouter("/house", houseRouter);
server.mountRouter("/planning", planningRouter);
server.mountRouter("/profile", profileRouter);
server.mountRouter("/reference", referenceRouter);
// No route matched — same shape as every other error response, via the
// shared ErrorCode contract, so clients never special-case 404s.
server.addMiddleware((_req: Request, res: Response) => {
res.status(404).json({ code: ErrorCode.NOT_FOUND, message: "Not found" });
});
// Final error-handling middleware: every thrown/`next(err)`-ed error in
// the app ends up here. All the "what status/body does this error map
// to" logic lives in ErrorHandlerService, from @batch-cooking/error-tools
// — this stays a thin adapter.
server.setErrorHandler(createErrorMiddleware(errorHandlerService));
return server;
}
/**
* Builds a fresh Express application instance (no shared mutable state
* between calls — used both indirectly by the real server entrypoint
* (`server.ts`, via {@link createServer}) and directly by tests, which
* each get their own app via supertest).
*/
export function createApp(): Express {
return createServer().instance;
}