- 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
79 lines
2.6 KiB
Markdown
79 lines
2.6 KiB
Markdown
# 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 /health` → `200 {"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
|
|
|
|
```text
|
|
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.
|