feat(F-001): scaffold modular monolith skeleton with boundary checker

- TypeScript + Fastify skeleton under project/ (src/modules, shared, infrastructure, app)
- scripts/check-module-boundaries.mjs enforcing module public-API rules (tested with fixtures)
- GET /health endpoint, error envelope without stack leakage
- specs/F-001-scaffold (SPEC/DESIGN/TASKS/TESTS), spec/tech.md dependency justification
- 30-ticket MercadoDeVida roadmap in backlog/features.json, spec/roadmap.md
- All gates approved: reviewer, security, qa; verify.sh green
This commit is contained in:
rikrdo
2026-08-14 21:46:54 +02:00
commit 1d4eebca54
76 changed files with 9430 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
import Fastify, { type FastifyInstance } from 'fastify';
import type { FastifyError, FastifyReply, FastifyRequest } from 'fastify';
import { registerHealthRoutes } from '../modules/health/index.js';
import { errorEnvelope } from '../shared/errors.js';
function notFoundHandler(_request: FastifyRequest, reply: FastifyReply): void {
void reply.code(404).send(errorEnvelope(404, 'Not Found'));
}
function errorHandler(error: FastifyError, _request: FastifyRequest, reply: FastifyReply): void {
const statusCode =
error.statusCode !== undefined && error.statusCode >= 400 ? error.statusCode : 500;
const message = statusCode >= 500 ? 'Internal Server Error' : error.message;
void reply.code(statusCode).send(errorEnvelope(statusCode, message));
}
/**
* Composition root. The only place allowed to wire modules together.
*/
export async function buildApp(): Promise<FastifyInstance> {
const app = Fastify({ logger: false });
app.setErrorHandler(errorHandler);
app.setNotFoundHandler(notFoundHandler);
await app.register(async (instance) => {
await registerHealthRoutes(instance);
});
return app;
}