Files
mercadodevida/specs/F-001-scaffold/DESIGN.md
rikrdo 1d4eebca54 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
2026-08-14 21:46:54 +02:00

2.6 KiB

DESIGN — F-001 Scaffold modular monolith skeleton

Affected modules

  • New: project/ application skeleton (no business modules yet, only exemplar health module).

Modules touched

  • src/modules/health (exemplar module proving the layout and boundary rule)
  • src/shared (error envelope helper)
  • src/infrastructure/http (Fastify server bootstrap)
  • src/app (composition root)

Modules NOT touched

  • Everything else. No business modules exist yet. No harness files outside work/artifacts/ and specs/.

New interfaces

  • health module public API: registerHealthRoutes(app: FastifyInstance): Promise<void> exported only from src/modules/health/index.ts.
  • Boundary checker script: node scripts/check-module-boundaries.mjs src → exit 0 ok / exit 1 violation.

API changes

  • Adds GET /health200 {"status":"ok"}.

Database changes

  • None.

Events

  • None.

External integrations

  • None.

Cache changes

  • None.

Security considerations

  • Fastify default JSON error handler replaced with an envelope that never leaks stack traces.
  • No dependencies beyond Fastify + toolchain.

Layout

project/
├── package.json
├── tsconfig.json
├── eslint.config.mjs
├── vitest.config.ts
├── .gitignore
├── scripts/
│   └── check-module-boundaries.mjs
└── src/
    ├── app/
    │   └── build-app.ts            # composition root: wires modules
    ├── infrastructure/
    │   └── http/
    │       └── server.ts           # listen entrypoint
    ├── modules/
    │   └── health/
    │       ├── index.ts            # public API
    │       ├── api/
    │       │   └── health.routes.ts
    │       └── tests/
    │           └── health.test.ts
    └── shared/
        └── errors.ts

Boundary rules enforced by the checker

  1. Files inside src/modules/<mod>/ may only import: own subtree (relative), src/shared/... (relative or alias-free path), Node builtins, and npm packages.
  2. Any relative import escaping src/modules/<mod>/ toward another module or toward src/app/src/infrastructure is a violation.
  3. Files outside modules (src/app, src/infrastructure) may import a module only via its index.ts (direct deep import = violation).

Toolchain

  • TypeScript strict, Fastify 5, Vitest, ESLint (flat config) + Prettier, tsc build to dist/.

Migration strategy

  • None (greenfield).

Rollback strategy

  • Delete project/ content added by this ticket; no other system depends on it yet.