create-rigel 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +156 -0
- package/cli.js +122 -0
- package/package.json +47 -0
- package/templates/express/.claude/CLAUDE.md +114 -0
- package/templates/express/.claude/agents/arch-validator.md +85 -0
- package/templates/express/.claude/agents/db-optimizer.md +72 -0
- package/templates/express/.claude/agents/doc-gardener.md +67 -0
- package/templates/express/.claude/agents/garbage-collector.md +94 -0
- package/templates/express/.claude/agents/gate-checker.md +176 -0
- package/templates/express/.claude/agents/reviewer.md +84 -0
- package/templates/express/.claude/agents/security-auditor.md +82 -0
- package/templates/express/.claude/hooks/post-write.sh +93 -0
- package/templates/express/.claude/rules/api.md +149 -0
- package/templates/express/.claude/rules/architecture.md +78 -0
- package/templates/express/.claude/rules/database.md +104 -0
- package/templates/express/.claude/rules/jobs.md +81 -0
- package/templates/express/.claude/rules/security.md +92 -0
- package/templates/express/.claude/rules/testing.md +97 -0
- package/templates/express/.claude/settings.json +35 -0
- package/templates/express/.claude/skills/00-infra-setup/SKILL.md +479 -0
- package/templates/express/.claude/skills/01-write-roadmap/SKILL.md +72 -0
- package/templates/express/.claude/skills/02-write-spec/SKILL.md +119 -0
- package/templates/express/.claude/skills/03-write-plan/SKILL.md +124 -0
- package/templates/express/.claude/skills/04-build-layer/SKILL.md +216 -0
- package/templates/express/.claude/skills/05-validate-layer/SKILL.md +43 -0
- package/templates/express/.claude/skills/06-push-layer/SKILL.md +59 -0
- package/templates/express/.claude/skills/07-layer-check/SKILL.md +62 -0
- package/templates/express/.claude/skills/08-garbage-collect/SKILL.md +86 -0
- package/templates/express/.claude/skills/09-doc-garden/SKILL.md +64 -0
- package/templates/express/.claude/skills/10-db-optimize/SKILL.md +96 -0
- package/templates/express/.claude/skills/11-load-test/SKILL.md +77 -0
- package/templates/express/.dockerignore +43 -0
- package/templates/express/.env.example +42 -0
- package/templates/express/.github/CODEOWNERS +22 -0
- package/templates/express/.github/dependabot.yml +48 -0
- package/templates/express/.github/pull_request_template.md +58 -0
- package/templates/express/.github/workflows/ci.yml +278 -0
- package/templates/express/.github/workflows/load-test.yml +41 -0
- package/templates/express/.gitleaks.toml +18 -0
- package/templates/express/.lintstagedrc.json +3 -0
- package/templates/express/.nvmrc +1 -0
- package/templates/express/.prettierrc +8 -0
- package/templates/express/.sequelizerc +8 -0
- package/templates/express/AGENTS.md +94 -0
- package/templates/express/ARCHITECTURE.md +161 -0
- package/templates/express/Dockerfile +40 -0
- package/templates/express/Makefile +79 -0
- package/templates/express/QUICKSTART.md +131 -0
- package/templates/express/docker-compose.yml +114 -0
- package/templates/express/docs/PLANS.md +111 -0
- package/templates/express/docs/QUALITY_SCORE.md +66 -0
- package/templates/express/docs/design-docs/core-beliefs.md +89 -0
- package/templates/express/docs/design-docs/decisions/ADR-000-infrastructure.md +70 -0
- package/templates/express/docs/design-docs/decisions/ADR-001-observability.md +82 -0
- package/templates/express/docs/design-docs/decisions/index.md +23 -0
- package/templates/express/docs/design-docs/index.md +11 -0
- package/templates/express/docs/design-docs/observability.md +194 -0
- package/templates/express/docs/design-docs/team-workflow.md +64 -0
- package/templates/express/docs/exec-plans/active/.gitkeep +0 -0
- package/templates/express/docs/exec-plans/completed/.gitkeep +0 -0
- package/templates/express/docs/exec-plans/tech-debt-tracker.md +31 -0
- package/templates/express/docs/generated/.gitkeep +0 -0
- package/templates/express/docs/product-specs/ROADMAP.md +49 -0
- package/templates/express/docs/product-specs/draft/.gitkeep +0 -0
- package/templates/express/docs/product-specs/index.md +21 -0
- package/templates/express/docs/product-specs/ready/.gitkeep +0 -0
- package/templates/express/eslint.config.mjs +94 -0
- package/templates/express/gitignore +36 -0
- package/templates/express/infra/monitoring/alloy/config.alloy +59 -0
- package/templates/express/jest.config.ts +61 -0
- package/templates/express/package.json +45 -0
- package/templates/express/scripts/openapi.export.ts +77 -0
- package/templates/express/tests/architecture/isolation.test.ts +51 -0
- package/templates/express/tests/architecture/layers.test.ts +83 -0
- package/templates/express/tests/integration/health.test.ts +40 -0
- package/templates/express/tests/integration/isolation.test.template.ts +88 -0
- package/templates/express/tests/load/smoke.js +46 -0
- package/templates/express/tests/load/soak.js +45 -0
- package/templates/express/tests/load/stress.js +44 -0
- package/templates/express/tests/unit/utils/response.util.test.ts +53 -0
- package/templates/express/tsconfig.build.json +8 -0
- package/templates/express/tsconfig.json +20 -0
- package/templates/fastapi/.claude/CLAUDE.md +122 -0
- package/templates/fastapi/.claude/agents/arch-validator.md +64 -0
- package/templates/fastapi/.claude/agents/db-optimizer.md +59 -0
- package/templates/fastapi/.claude/agents/doc-gardener.md +55 -0
- package/templates/fastapi/.claude/agents/garbage-collector.md +74 -0
- package/templates/fastapi/.claude/agents/gate-checker.md +133 -0
- package/templates/fastapi/.claude/agents/reviewer.md +74 -0
- package/templates/fastapi/.claude/agents/security-auditor.md +69 -0
- package/templates/fastapi/.claude/hooks/post-write.sh +65 -0
- package/templates/fastapi/.claude/rules/api.md +119 -0
- package/templates/fastapi/.claude/rules/architecture.md +84 -0
- package/templates/fastapi/.claude/rules/database.md +153 -0
- package/templates/fastapi/.claude/rules/jobs.md +85 -0
- package/templates/fastapi/.claude/rules/security.md +102 -0
- package/templates/fastapi/.claude/rules/testing.md +207 -0
- package/templates/fastapi/.claude/settings.json +50 -0
- package/templates/fastapi/.claude/skills/00-infra-setup/SKILL.md +311 -0
- package/templates/fastapi/.claude/skills/01-write-roadmap/SKILL.md +61 -0
- package/templates/fastapi/.claude/skills/02-write-spec/SKILL.md +82 -0
- package/templates/fastapi/.claude/skills/03-write-plan/SKILL.md +83 -0
- package/templates/fastapi/.claude/skills/04-build-layer/SKILL.md +170 -0
- package/templates/fastapi/.claude/skills/05-validate-layer/SKILL.md +20 -0
- package/templates/fastapi/.claude/skills/06-push-layer/SKILL.md +31 -0
- package/templates/fastapi/.claude/skills/07-layer-check/SKILL.md +51 -0
- package/templates/fastapi/.claude/skills/08-garbage-collect/SKILL.md +47 -0
- package/templates/fastapi/.claude/skills/09-doc-garden/SKILL.md +9 -0
- package/templates/fastapi/.claude/skills/10-db-optimize/SKILL.md +53 -0
- package/templates/fastapi/.claude/skills/11-load-test/SKILL.md +81 -0
- package/templates/fastapi/.dockerignore +30 -0
- package/templates/fastapi/.github/dependabot.yml +24 -0
- package/templates/fastapi/AGENTS.md +87 -0
- package/templates/fastapi/ARCHITECTURE.md +141 -0
- package/templates/fastapi/Makefile +42 -0
- package/templates/fastapi/README.md +179 -0
- package/templates/fastapi/docs/PLANS.md +26 -0
- package/templates/fastapi/docs/QUALITY_SCORE.md +26 -0
- package/templates/fastapi/docs/design-docs/core-beliefs.md +46 -0
- package/templates/fastapi/docs/design-docs/decisions/ADR-000-infrastructure.md +79 -0
- package/templates/fastapi/docs/design-docs/decisions/index.md +7 -0
- package/templates/fastapi/docs/design-docs/index.md +9 -0
- package/templates/fastapi/docs/exec-plans/active/.gitkeep +0 -0
- package/templates/fastapi/docs/exec-plans/completed/.gitkeep +0 -0
- package/templates/fastapi/docs/exec-plans/tech-debt-tracker.md +19 -0
- package/templates/fastapi/docs/generated/.gitkeep +0 -0
- package/templates/fastapi/docs/product-specs/ROADMAP.md +49 -0
- package/templates/fastapi/docs/product-specs/draft/.gitkeep +0 -0
- package/templates/fastapi/docs/product-specs/index.md +18 -0
- package/templates/fastapi/docs/product-specs/ready/.gitkeep +0 -0
- package/templates/fastapi/gitignore +46 -0
- package/templates/fastapi/scripts/gate.sh +68 -0
- package/templates/nestjs/.claude/CLAUDE.md +121 -0
- package/templates/nestjs/.claude/agents/db-optimizer.md +51 -0
- package/templates/nestjs/.claude/agents/doc-gardener.md +45 -0
- package/templates/nestjs/.claude/agents/garbage-collector.md +50 -0
- package/templates/nestjs/.claude/agents/gate-checker.md +127 -0
- package/templates/nestjs/.claude/agents/reviewer.md +68 -0
- package/templates/nestjs/.claude/agents/security-auditor.md +72 -0
- package/templates/nestjs/.claude/hooks/post-write.sh +91 -0
- package/templates/nestjs/.claude/rules/api.md +87 -0
- package/templates/nestjs/.claude/rules/architecture.md +104 -0
- package/templates/nestjs/.claude/rules/database.md +111 -0
- package/templates/nestjs/.claude/rules/security.md +110 -0
- package/templates/nestjs/.claude/rules/testing.md +145 -0
- package/templates/nestjs/.claude/settings.json +33 -0
- package/templates/nestjs/.claude/skills/00-infra-setup/SKILL.md +222 -0
- package/templates/nestjs/.claude/skills/01-write-spec/SKILL.md +25 -0
- package/templates/nestjs/.claude/skills/02-write-plan/SKILL.md +18 -0
- package/templates/nestjs/.claude/skills/03-build-layer/SKILL.md +242 -0
- package/templates/nestjs/.claude/skills/04-validate-layer/SKILL.md +4 -0
- package/templates/nestjs/.claude/skills/05-push-layer/SKILL.md +6 -0
- package/templates/nestjs/.claude/skills/06-layer-check/SKILL.md +12 -0
- package/templates/nestjs/.claude/skills/07-garbage-collect/SKILL.md +2 -0
- package/templates/nestjs/.claude/skills/08-doc-garden/SKILL.md +4 -0
- package/templates/nestjs/.claude/skills/09-api-sync/SKILL.md +36 -0
- package/templates/nestjs/.claude/skills/10-load-test/SKILL.md +29 -0
- package/templates/nestjs/.env.example +11 -0
- package/templates/nestjs/AGENTS.md +88 -0
- package/templates/nestjs/ARCHITECTURE.md +192 -0
- package/templates/nestjs/docs/PLANS.md +22 -0
- package/templates/nestjs/docs/QUALITY_SCORE.md +27 -0
- package/templates/nestjs/docs/design-docs/core-beliefs.md +18 -0
- package/templates/nestjs/docs/design-docs/decisions/ADR-000-infrastructure.md +58 -0
- package/templates/nestjs/docs/design-docs/decisions/index.md +7 -0
- package/templates/nestjs/docs/design-docs/index.md +7 -0
- package/templates/nestjs/docs/exec-plans/active/.gitkeep +0 -0
- package/templates/nestjs/docs/exec-plans/completed/.gitkeep +0 -0
- package/templates/nestjs/docs/exec-plans/tech-debt-tracker.md +16 -0
- package/templates/nestjs/docs/generated/.gitkeep +0 -0
- package/templates/nestjs/docs/product-specs/draft/.gitkeep +0 -0
- package/templates/nestjs/docs/product-specs/index.md +7 -0
- package/templates/nestjs/docs/product-specs/ready/.gitkeep +0 -0
- package/templates/nestjs/gitignore +8 -0
- package/templates/nextjs/.claude/CLAUDE.md +139 -0
- package/templates/nextjs/.claude/agents/arch-validator.md +66 -0
- package/templates/nextjs/.claude/agents/contract-checker.md +78 -0
- package/templates/nextjs/.claude/agents/doc-gardener.md +52 -0
- package/templates/nextjs/.claude/agents/garbage-collector.md +61 -0
- package/templates/nextjs/.claude/agents/gate-checker.md +129 -0
- package/templates/nextjs/.claude/agents/perf-auditor.md +109 -0
- package/templates/nextjs/.claude/agents/reviewer.md +79 -0
- package/templates/nextjs/.claude/agents/security-auditor.md +50 -0
- package/templates/nextjs/.claude/hooks/post-write.sh +121 -0
- package/templates/nextjs/.claude/rules/api-contract.md +166 -0
- package/templates/nextjs/.claude/rules/architecture.md +99 -0
- package/templates/nextjs/.claude/rules/components.md +122 -0
- package/templates/nextjs/.claude/rules/security.md +122 -0
- package/templates/nextjs/.claude/rules/testing.md +187 -0
- package/templates/nextjs/.claude/scripts/infra-setup.sh +550 -0
- package/templates/nextjs/.claude/settings.json +33 -0
- package/templates/nextjs/.claude/skills/00-infra-setup/SKILL.md +471 -0
- package/templates/nextjs/.claude/skills/01-write-roadmap/SKILL.md +77 -0
- package/templates/nextjs/.claude/skills/02-write-spec/SKILL.md +78 -0
- package/templates/nextjs/.claude/skills/03-write-plan/SKILL.md +91 -0
- package/templates/nextjs/.claude/skills/04-build-layer/SKILL.md +141 -0
- package/templates/nextjs/.claude/skills/05-validate-layer/SKILL.md +13 -0
- package/templates/nextjs/.claude/skills/06-push-layer/SKILL.md +20 -0
- package/templates/nextjs/.claude/skills/07-layer-check/SKILL.md +28 -0
- package/templates/nextjs/.claude/skills/08-garbage-collect/SKILL.md +14 -0
- package/templates/nextjs/.claude/skills/09-doc-garden/SKILL.md +12 -0
- package/templates/nextjs/.claude/skills/10-api-sync/SKILL.md +50 -0
- package/templates/nextjs/.claude/skills/11-perf-budget/SKILL.md +51 -0
- package/templates/nextjs/.dockerignore +25 -0
- package/templates/nextjs/.gitattributes +10 -0
- package/templates/nextjs/.github/CODEOWNERS +24 -0
- package/templates/nextjs/.github/dependabot.yml +31 -0
- package/templates/nextjs/.github/pull_request_template.md +59 -0
- package/templates/nextjs/.github/workflows/ci.yml +143 -0
- package/templates/nextjs/.github/workflows/lighthouse.yml +54 -0
- package/templates/nextjs/.github/workflows/load-test.yml +54 -0
- package/templates/nextjs/.husky/pre-commit +1 -0
- package/templates/nextjs/.lintstagedrc.json +4 -0
- package/templates/nextjs/.mcp.json +8 -0
- package/templates/nextjs/.prettierignore +13 -0
- package/templates/nextjs/.prettierrc +9 -0
- package/templates/nextjs/AGENTS.md +88 -0
- package/templates/nextjs/ARCHITECTURE.md +165 -0
- package/templates/nextjs/Dockerfile +38 -0
- package/templates/nextjs/Makefile +50 -0
- package/templates/nextjs/QUICKSTART.md +128 -0
- package/templates/nextjs/docs/PLANS.md +23 -0
- package/templates/nextjs/docs/QUALITY_SCORE.md +27 -0
- package/templates/nextjs/docs/design-docs/core-beliefs.md +43 -0
- package/templates/nextjs/docs/design-docs/decisions/ADR-000-infrastructure.md +72 -0
- package/templates/nextjs/docs/design-docs/decisions/index.md +7 -0
- package/templates/nextjs/docs/design-docs/index.md +7 -0
- package/templates/nextjs/docs/design-docs/team-workflow.md +66 -0
- package/templates/nextjs/docs/exec-plans/active/.gitkeep +0 -0
- package/templates/nextjs/docs/exec-plans/completed/.gitkeep +0 -0
- package/templates/nextjs/docs/exec-plans/tech-debt-tracker.md +19 -0
- package/templates/nextjs/docs/generated/.gitkeep +0 -0
- package/templates/nextjs/docs/product-specs/ROADMAP.md +59 -0
- package/templates/nextjs/docs/product-specs/draft/.gitkeep +0 -0
- package/templates/nextjs/docs/product-specs/index.md +18 -0
- package/templates/nextjs/docs/product-specs/ready/.gitkeep +0 -0
- package/templates/nextjs/eslint.config.mjs +150 -0
- package/templates/nextjs/gitignore +35 -0
- package/templates/nextjs/lighthouserc.js +37 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# /layer-check
|
|
2
|
+
```bash
|
|
3
|
+
npx tsc --noEmit 2>&1 | head -20
|
|
4
|
+
npx eslint src/ --max-warnings=0 2>&1 | head -20
|
|
5
|
+
grep -rn "console\." src/ --include="*.ts"
|
|
6
|
+
grep -rn "process\.env" src/ --include="*.ts" | grep -v "src/config/"
|
|
7
|
+
grep -rn "HttpException\b" src/ --include="*.service.ts"
|
|
8
|
+
grep -rn "@InjectModel" src/ --include="*.service.ts"
|
|
9
|
+
find src/ -name "*.ts" | xargs wc -l | sort -rn | awk '$1 > 400 { print "VIOLATION:", $2, $1 }'
|
|
10
|
+
npx jest --no-coverage 2>&1 | tail -5
|
|
11
|
+
```
|
|
12
|
+
Output: CLEAN or {N} violations.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# /api-sync — Export Live OpenAPI Spec
|
|
2
|
+
|
|
3
|
+
NestJS generates OpenAPI automatically from @ApiProperty decorators.
|
|
4
|
+
No static file needed. Export when backend is running:
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
# Backend must be running on port 3000
|
|
8
|
+
curl http://localhost:3000/api/docs-json -o openapi.json
|
|
9
|
+
|
|
10
|
+
# Or use the NestJS CLI plugin to generate at build time:
|
|
11
|
+
# Add to nest-cli.json:
|
|
12
|
+
# { "compilerOptions": { "plugins": ["@nestjs/swagger"] } }
|
|
13
|
+
# Then:
|
|
14
|
+
npx ts-node -e "
|
|
15
|
+
const { NestFactory } = require('@nestjs/core');
|
|
16
|
+
const { SwaggerModule, DocumentBuilder } = require('@nestjs/swagger');
|
|
17
|
+
const { AppModule } = require('./src/app.module');
|
|
18
|
+
async function generate() {
|
|
19
|
+
const app = await NestFactory.create(AppModule, { logger: false });
|
|
20
|
+
const config = new DocumentBuilder().setTitle('API').addBearerAuth().build();
|
|
21
|
+
const doc = SwaggerModule.createDocument(app, config);
|
|
22
|
+
require('fs').writeFileSync('openapi.json', JSON.stringify(doc, null, 2));
|
|
23
|
+
await app.close();
|
|
24
|
+
}
|
|
25
|
+
generate();
|
|
26
|
+
"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Then:
|
|
30
|
+
```bash
|
|
31
|
+
git add openapi.json
|
|
32
|
+
git commit -m "chore(api): export openapi spec"
|
|
33
|
+
git push origin main
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Frontend can now run /api-sync from their project using this file.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# /load-test [smoke|stress|soak]
|
|
2
|
+
|
|
3
|
+
```bash
|
|
4
|
+
k6 run --env BASE_URL=${BASE_URL:-http://localhost:3000} tests/load/smoke.js
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
Create tests/load/smoke.js:
|
|
8
|
+
```javascript
|
|
9
|
+
import http from 'k6/http'
|
|
10
|
+
import { check, sleep } from 'k6'
|
|
11
|
+
|
|
12
|
+
export const options = {
|
|
13
|
+
vus: 10, duration: '30s',
|
|
14
|
+
thresholds: { http_req_duration: ['p(95)<500'], http_req_failed: ['rate<0.01'] },
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default function () {
|
|
18
|
+
const res = http.get(`${__ENV.BASE_URL}/health`)
|
|
19
|
+
check(res, { 'health 200': (r) => r.status === 200 })
|
|
20
|
+
sleep(1)
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Results format for PR:
|
|
25
|
+
```
|
|
26
|
+
Load Test (smoke — 10 VUs, 30s):
|
|
27
|
+
P95: {N}ms ✅/❌ (target < 500ms)
|
|
28
|
+
Errors: {N}% ✅/❌ (target < 1%)
|
|
29
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
NODE_ENV=development
|
|
2
|
+
PORT=3000
|
|
3
|
+
DATABASE_URL=postgresql://app:app@localhost:5432/appdb
|
|
4
|
+
DATABASE_POOL_MAX=10
|
|
5
|
+
DATABASE_POOL_MIN=2
|
|
6
|
+
REDIS_URL=redis://localhost:6379
|
|
7
|
+
JWT_SECRET=
|
|
8
|
+
JWT_ACCESS_EXPIRY=15m
|
|
9
|
+
JWT_REFRESH_EXPIRY=7d
|
|
10
|
+
CORS_ORIGINS=http://localhost:3001
|
|
11
|
+
LOG_LEVEL=info
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# AGENTS.md — Navigation Map
|
|
2
|
+
|
|
3
|
+
Stack: NestJS 11 · Node 22 · TypeScript 5 strict · Sequelize 6 + sequelize-typescript · PostgreSQL · Redis · BullMQ · argon2 · @nestjs/swagger · nestjs-pino
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🗺️ Where Everything Lives
|
|
8
|
+
|
|
9
|
+
| What you need | Where |
|
|
10
|
+
|---|---|
|
|
11
|
+
| Layer rules + dependency diagram | `ARCHITECTURE.md` |
|
|
12
|
+
| Engineering constitution | `docs/design-docs/core-beliefs.md` |
|
|
13
|
+
| Active execution plan | `docs/exec-plans/active/` |
|
|
14
|
+
| Completed plans | `docs/exec-plans/completed/` |
|
|
15
|
+
| Product specs (draft) | `docs/product-specs/draft/` |
|
|
16
|
+
| Product specs (approved) | `docs/product-specs/ready/` |
|
|
17
|
+
| Architectural decisions | `docs/design-docs/decisions/` |
|
|
18
|
+
| Tech debt | `docs/exec-plans/tech-debt-tracker.md` |
|
|
19
|
+
| Domain health grades | `docs/QUALITY_SCORE.md` |
|
|
20
|
+
| Plan format | `docs/PLANS.md` |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## ⚡ Slash Commands
|
|
25
|
+
|
|
26
|
+
| Command | What it does |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `/infra-setup` | Phase 0 — full NestJS scaffold (run once) |
|
|
29
|
+
| `/write-spec` | Write product spec → `docs/product-specs/draft/` |
|
|
30
|
+
| `/write-plan` | Turn READY spec into execution plan |
|
|
31
|
+
| `/build-layer` | Build next unchecked layer + run gate |
|
|
32
|
+
| `/validate-layer` | Gate check without building |
|
|
33
|
+
| `/push-layer` | Commit + push with conventional message |
|
|
34
|
+
| `/layer-check` | Ad-hoc architecture violation scan |
|
|
35
|
+
| `/garbage-collect` | End-of-feature cleanup |
|
|
36
|
+
| `/doc-garden` | Fix stale documentation |
|
|
37
|
+
| `/api-sync` | Export live OpenAPI spec from running server |
|
|
38
|
+
| `/load-test` | Run k6 smoke / stress / soak |
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 🤖 Agents
|
|
43
|
+
|
|
44
|
+
| Agent | When |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `gate-checker` | Auto-called by `/build-layer` — PASS/FAIL per layer |
|
|
47
|
+
| `reviewer` | Before opening a PR |
|
|
48
|
+
| `arch-validator` | Deep layer compliance scan |
|
|
49
|
+
| `db-optimizer` | N+1, missing index, pagination audit |
|
|
50
|
+
| `security-auditor` | OWASP review — run before any auth PR |
|
|
51
|
+
| `doc-gardener` | Fix stale docs |
|
|
52
|
+
| `garbage-collector` | End-of-feature cleanup |
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## ✅ Non-Negotiable Invariants
|
|
57
|
+
|
|
58
|
+
- No `console.log` → use `Logger` from `@nestjs/common` or `nestjs-pino`
|
|
59
|
+
- No `process.env` → use `ConfigService` injected via NestJS DI
|
|
60
|
+
- No `HttpException` in services → use NestJS built-in exceptions (`NotFoundException` etc.)
|
|
61
|
+
- No business logic in controllers → delegate to service only
|
|
62
|
+
- No `@InjectModel()` in services → inject the repository class, not the model
|
|
63
|
+
- Every Sequelize `.toJSON()` result → `ZodSchema.parse()`
|
|
64
|
+
- Every list endpoint → cursor-based pagination
|
|
65
|
+
- Every `@Column` DTO field → has `@ApiProperty()` decorator
|
|
66
|
+
- No file > 400 lines
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 🔑 The NestJS Difference
|
|
71
|
+
|
|
72
|
+
**Auth is opt-out, not opt-in.** Global `JwtAuthGuard` protects all routes. Use `@Public()` to expose a route without auth. Never add auth guards per-route.
|
|
73
|
+
|
|
74
|
+
**Input validation is automatic.** Global `ValidationPipe` with `whitelist: true` runs `class-validator` on every DTO. No Zod on input.
|
|
75
|
+
|
|
76
|
+
**Output validation is Zod.** Sequelize `.toJSON()` is not guaranteed — Zod parse it in the repository.
|
|
77
|
+
|
|
78
|
+
**Swagger is live.** OpenAPI spec auto-generated at `/api/docs-json`. No separate file sync needed.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 🔁 The Flow
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
/write-spec → human marks READY → /write-plan
|
|
86
|
+
→ /build-layer (repeats per layer, gate-enforced)
|
|
87
|
+
→ /garbage-collect → plan closed
|
|
88
|
+
```
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# ARCHITECTURE.md — NestJS Layered Architecture
|
|
2
|
+
|
|
3
|
+
Stack: NestJS 11 · TypeScript 5 · Sequelize 6 + sequelize-typescript · PostgreSQL
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Module Dependency Diagram
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
11
|
+
│ Common (src/common/) │
|
|
12
|
+
│ ├─ Guards: JwtAuthGuard (global), RolesGuard │
|
|
13
|
+
│ ├─ Decorators: @CurrentUser(), @Public(), @Roles() │
|
|
14
|
+
│ ├─ Filters: AllExceptionsFilter (global) │
|
|
15
|
+
│ ├─ Interceptors: LoggingInterceptor (global) │
|
|
16
|
+
│ └─ DTOs: PaginationDto (shared cursor params) │
|
|
17
|
+
│ │
|
|
18
|
+
│ Config (src/config/) │
|
|
19
|
+
│ └─ ConfigModule with Joi validation — ConfigService everywhere │
|
|
20
|
+
│ │
|
|
21
|
+
│ Database (src/database/) │
|
|
22
|
+
│ └─ SequelizeModule.forRoot() — connection + pool config │
|
|
23
|
+
│ │
|
|
24
|
+
│ [Feature] Module (src/[feature]/) │
|
|
25
|
+
│ ├─ models/[feature].model.ts ← Sequelize model (schema) │
|
|
26
|
+
│ ├─ dto/ ← class-validator + @ApiProperty │
|
|
27
|
+
│ ├─ [feature].repository.ts ← @InjectModel + Zod parse │
|
|
28
|
+
│ ├─ [feature].service.ts ← business logic only │
|
|
29
|
+
│ ├─ [feature].controller.ts ← thin, Swagger decorators │
|
|
30
|
+
│ └─ [feature].module.ts ← wires everything │
|
|
31
|
+
│ │
|
|
32
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Layer Definitions
|
|
38
|
+
|
|
39
|
+
### Model (`src/[feature]/models/`)
|
|
40
|
+
|
|
41
|
+
- Sequelize-typescript class with `@Table`, `@Column` decorators
|
|
42
|
+
- Schema definition only — **no logic, no methods**
|
|
43
|
+
- `@Table({ paranoid: true })` on every model (soft delete)
|
|
44
|
+
- `@Default(() => newId())` on every `id` column (UUIDv7)
|
|
45
|
+
- Indexes defined in `@Table({ indexes: [] })`
|
|
46
|
+
- Imports: Types only
|
|
47
|
+
|
|
48
|
+
### DTOs (`src/[feature]/dto/`)
|
|
49
|
+
|
|
50
|
+
- `class-validator` + `class-transformer` decorated classes
|
|
51
|
+
- Every field has `@ApiProperty()` for Swagger
|
|
52
|
+
- Input DTOs: `Create*Dto`, `Update*Dto`
|
|
53
|
+
- Response DTOs: `*ResponseDto` (controls what is serialised)
|
|
54
|
+
- **No logic** — only property definitions and validation decorators
|
|
55
|
+
|
|
56
|
+
### Repository (`src/[feature]/[feature].repository.ts`)
|
|
57
|
+
|
|
58
|
+
- `@Injectable()` class with `@InjectModel(Model)` in constructor
|
|
59
|
+
- **Only place DB queries happen**
|
|
60
|
+
- Every `.toJSON()` result passed through `ZodSchema.parse()`
|
|
61
|
+
- Cursor-based pagination on all list methods
|
|
62
|
+
- Ownership enforced in every `WHERE` clause (`userId` filter)
|
|
63
|
+
- Exports only typed domain objects — never raw Sequelize instances
|
|
64
|
+
|
|
65
|
+
### Service (`src/[feature]/[feature].service.ts`)
|
|
66
|
+
|
|
67
|
+
- `@Injectable()` class — business logic only
|
|
68
|
+
- Injects repository class (not the model directly)
|
|
69
|
+
- **No HTTP types** — no `Request`, `Response`, `@nestjs/common` HTTP imports
|
|
70
|
+
- **No `HttpException`** — uses NestJS built-in semantic exceptions:
|
|
71
|
+
- `NotFoundException`, `ConflictException`, `UnauthorizedException`, `ForbiddenException`, `BadRequestException`
|
|
72
|
+
- Multi-step operations wrapped in `sequelize.transaction()`
|
|
73
|
+
|
|
74
|
+
### Controller (`src/[feature]/[feature].controller.ts`)
|
|
75
|
+
|
|
76
|
+
- `@Controller()` class — routing and serialisation only
|
|
77
|
+
- **Zero business logic** — each handler is a one-liner delegating to service
|
|
78
|
+
- Required Swagger decorators on every class and route:
|
|
79
|
+
- `@ApiTags()`, `@ApiBearerAuth()`, `@ApiOperation()`, `@ApiResponse()`
|
|
80
|
+
- `@UseGuards()` only if route-level guard needed (not for JWT — that's global)
|
|
81
|
+
- `@Roles('ADMIN')` for admin-only routes
|
|
82
|
+
|
|
83
|
+
### Module (`src/[feature]/[feature].module.ts`)
|
|
84
|
+
|
|
85
|
+
- Wires: `SequelizeModule.forFeature([Model])`, repository, service, controller
|
|
86
|
+
- Exports services that other modules need
|
|
87
|
+
- Imported in `AppModule` (or parent module)
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Import Rules (ESLint enforces)
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
Model → Types only
|
|
95
|
+
DTOs → Types only (class-validator, swagger decorators)
|
|
96
|
+
Repository → Model, Config, Types, Zod
|
|
97
|
+
Service → Repository, Config, Types — NO HTTP imports
|
|
98
|
+
Controller → Service, DTOs, Common decorators
|
|
99
|
+
Module → All of the above
|
|
100
|
+
Common → Config, Types only
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Forbidden:**
|
|
104
|
+
|
|
105
|
+
- `process.env` anywhere (use `ConfigService`)
|
|
106
|
+
- `console.log` anywhere (use `Logger` or `nestjs-pino`)
|
|
107
|
+
- `HttpException` in services (use built-in semantic exceptions)
|
|
108
|
+
- Business logic in controllers
|
|
109
|
+
- `@InjectModel()` in services (inject repository instead)
|
|
110
|
+
- Raw Sequelize instance returned from repository (always `.toJSON()` + Zod)
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Auth Model — Opt-Out, Not Opt-In
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
// main.ts — JWT guard applied GLOBALLY
|
|
118
|
+
app.useGlobalGuards(new JwtAuthGuard(reflector))
|
|
119
|
+
|
|
120
|
+
// Public routes use @Public() decorator
|
|
121
|
+
@Public()
|
|
122
|
+
@Post('login')
|
|
123
|
+
login(@Body() dto: LoginDto) { ... }
|
|
124
|
+
|
|
125
|
+
// Protected routes need NO guard decoration — they're protected by default
|
|
126
|
+
@Get('profile')
|
|
127
|
+
getProfile(@CurrentUser() user: JwtPayload) { ... }
|
|
128
|
+
|
|
129
|
+
// Admin routes add @Roles()
|
|
130
|
+
@Roles('ADMIN')
|
|
131
|
+
@Delete(':id')
|
|
132
|
+
delete(@Param('id') id: string) { ... }
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Validation Model
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
HTTP Request
|
|
141
|
+
│
|
|
142
|
+
▼ Global ValidationPipe (whitelist: true, transform: true)
|
|
143
|
+
│ → class-validator validates DTO
|
|
144
|
+
│ → strips unknown fields
|
|
145
|
+
│ → transforms types (string → number etc.)
|
|
146
|
+
▼
|
|
147
|
+
Controller → Service → Repository
|
|
148
|
+
│
|
|
149
|
+
▼ Sequelize query
|
|
150
|
+
│
|
|
151
|
+
▼ .toJSON()
|
|
152
|
+
│
|
|
153
|
+
▼ ZodSchema.parse() ← output validation boundary
|
|
154
|
+
│
|
|
155
|
+
TypedResult
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## NestJS Exception Map
|
|
161
|
+
|
|
162
|
+
| NestJS Exception | HTTP Status | When to use |
|
|
163
|
+
| ------------------------------ | ----------- | ------------------------------------------------------- |
|
|
164
|
+
| `NotFoundException` | 404 | Resource not found |
|
|
165
|
+
| `ConflictException` | 409 | Duplicate, invalid state transition |
|
|
166
|
+
| `UnauthorizedException` | 401 | Invalid credentials, expired token |
|
|
167
|
+
| `ForbiddenException` | 403 | Insufficient permissions |
|
|
168
|
+
| `BadRequestException` | 400 | Invalid input (caught before service by ValidationPipe) |
|
|
169
|
+
| `InternalServerErrorException` | 500 | Unexpected failure |
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## File Size Limit
|
|
174
|
+
|
|
175
|
+
**400 lines maximum** per file. Enforced by PostToolUse hook + gate-checker.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Naming Conventions
|
|
180
|
+
|
|
181
|
+
| Thing | Pattern | Example |
|
|
182
|
+
| ------------ | --------------------- | --------------------------------- |
|
|
183
|
+
| Model | `*.model.ts` | `application.model.ts` |
|
|
184
|
+
| Repository | `*.repository.ts` | `application.repository.ts` |
|
|
185
|
+
| Service | `*.service.ts` | `application.service.ts` |
|
|
186
|
+
| Controller | `*.controller.ts` | `application.controller.ts` |
|
|
187
|
+
| Module | `*.module.ts` | `application.module.ts` |
|
|
188
|
+
| Create DTO | `create-*.dto.ts` | `create-application.dto.ts` |
|
|
189
|
+
| Update DTO | `update-*.dto.ts` | `update-application.dto.ts` |
|
|
190
|
+
| Response DTO | `*-response.dto.ts` | `application-response.dto.ts` |
|
|
191
|
+
| Zod schemas | `*Schema` | `ApplicationSchema` |
|
|
192
|
+
| Migration | `YYYYMMDDHHMMSS-*.js` | `20260508-create-applications.js` |
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# PLANS.md — Execution Plan Format
|
|
2
|
+
|
|
3
|
+
## Lifecycle
|
|
4
|
+
/write-plan → docs/exec-plans/active/PLAN-XXX.md
|
|
5
|
+
→ /build-layer (each NestJS layer: Model → Migration → DTOs → Repository → Service → Controller → Module → Tests)
|
|
6
|
+
→ /garbage-collect → docs/exec-plans/completed/
|
|
7
|
+
|
|
8
|
+
Plans are NEVER deleted.
|
|
9
|
+
|
|
10
|
+
## NestJS Layer Order (per feature)
|
|
11
|
+
1. Model (sequelize-typescript class)
|
|
12
|
+
2. Migration (sequelize-cli)
|
|
13
|
+
3. DTOs (class-validator + @ApiProperty)
|
|
14
|
+
4. Repository (@InjectModel + Zod parse)
|
|
15
|
+
5. Service (@Injectable, NestJS exceptions)
|
|
16
|
+
6. Controller (@Controller, Swagger decorators)
|
|
17
|
+
7. Module (SequelizeModule.forFeature, wire everything)
|
|
18
|
+
8. Tests (jest unit + supertest e2e)
|
|
19
|
+
|
|
20
|
+
## Escalation Rule
|
|
21
|
+
Escalate only for: ambiguous requirements, security decisions with no pattern, architecture change needed.
|
|
22
|
+
Never escalate for: TypeScript errors, linter failures, test failures.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# QUALITY_SCORE.md — Domain Health Grades
|
|
2
|
+
|
|
3
|
+
Updated by /garbage-collect after every feature.
|
|
4
|
+
|
|
5
|
+
## Grading
|
|
6
|
+
| Grade | Meaning |
|
|
7
|
+
|---|---|
|
|
8
|
+
| A | All invariants met, ≥ 90% service coverage, zero debt |
|
|
9
|
+
| B | Minor issues, ≥ 80% coverage, low-priority debt logged |
|
|
10
|
+
| C | Layer violation OR < 80% OR unresolved medium debt |
|
|
11
|
+
| D | Multiple violations, active bugs |
|
|
12
|
+
|
|
13
|
+
## Architecture Health
|
|
14
|
+
| Check | Status |
|
|
15
|
+
|---|---|
|
|
16
|
+
| No cross-layer imports | — |
|
|
17
|
+
| No files > 400 lines | — |
|
|
18
|
+
| No process.env outside config | — |
|
|
19
|
+
| No console.log in src | — |
|
|
20
|
+
| No HttpException in services | — |
|
|
21
|
+
| No @InjectModel in services | — |
|
|
22
|
+
| Zod parse on all .toJSON() in repos | — |
|
|
23
|
+
|
|
24
|
+
## Domain Grades
|
|
25
|
+
| Domain | Grade | Coverage | Last Updated |
|
|
26
|
+
|---|---|---|---|
|
|
27
|
+
| *(none yet)* | — | — | — |
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Core Beliefs — The Engineering Constitution
|
|
2
|
+
|
|
3
|
+
1. **The Repo Is Reality** — if not committed, it doesn't exist
|
|
4
|
+
2. **Enforce Mechanically** — linter rules + hooks > documentation
|
|
5
|
+
3. **Agents Execute, Humans Steer** — escalate only when judgment is needed
|
|
6
|
+
4. **Layers Protect Concerns** — controllers delegate, services have no HTTP, repos have no logic
|
|
7
|
+
5. **External Data Is Adversarial** — Zod parse every .toJSON() at the repo boundary
|
|
8
|
+
6. **Gate Before Commit** — TypeScript + ESLint + tests before every push
|
|
9
|
+
7. **Observability Is Not Optional** — structured logs on every service boundary
|
|
10
|
+
8. **Small, Boring, Legible** — 400-line limit, NestJS idioms, no premature abstraction
|
|
11
|
+
9. **Technical Debt Is a High-Interest Loan** — log it immediately, pay daily
|
|
12
|
+
10. **The Fix Is Never Try Harder** — repeated failure = missing rule, tool, or abstraction
|
|
13
|
+
|
|
14
|
+
## NestJS-Specific Beliefs
|
|
15
|
+
- Auth is opt-out (global guard) — not opt-in
|
|
16
|
+
- ValidationPipe is the input contract — not manual Zod on inputs
|
|
17
|
+
- Swagger is auto-generated — no separate file sync needed
|
|
18
|
+
- Inject repositories into services — not models directly
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# ADR-000 — Infrastructure & Stack Choices
|
|
2
|
+
|
|
3
|
+
**Status:** ACCEPTED
|
|
4
|
+
**Date:** *(fill when /infra-setup is run)*
|
|
5
|
+
**Plan:** Phase 0
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Decisions
|
|
10
|
+
|
|
11
|
+
### Framework: NestJS 11
|
|
12
|
+
- Modular architecture with IoC container built-in
|
|
13
|
+
- TypeScript-first with full decorator support
|
|
14
|
+
- Global guards, pipes, filters, interceptors
|
|
15
|
+
- v11 stable — v12 (ESM + Vitest) targeting Q3 2026, not stable yet
|
|
16
|
+
|
|
17
|
+
### ORM: Sequelize 6 + sequelize-typescript + @nestjs/sequelize
|
|
18
|
+
- Team standard across projects
|
|
19
|
+
- @nestjs/sequelize provides SequelizeModule.forRoot + @InjectModel DI
|
|
20
|
+
- sequelize-typescript provides TypeScript decorator model definitions
|
|
21
|
+
- sequelize-cli for migrations
|
|
22
|
+
- Alternatives considered: Prisma (better DX), TypeORM (NestJS native) — Sequelize chosen for consistency
|
|
23
|
+
|
|
24
|
+
### Auth: @nestjs/passport + passport-jwt + @nestjs/jwt
|
|
25
|
+
- NestJS official pattern — JwtStrategy + JwtAuthGuard
|
|
26
|
+
- Global guard (APP_GUARD) — every route protected by default
|
|
27
|
+
- @Public() decorator for opt-out
|
|
28
|
+
- argon2 for password hashing (GPU-resistant, beats bcrypt)
|
|
29
|
+
|
|
30
|
+
### Validation: class-validator + class-transformer (input), Zod (output)
|
|
31
|
+
- class-validator: NestJS native, integrates with ValidationPipe and Swagger
|
|
32
|
+
- Zod: output validation on Sequelize .toJSON() at repository boundary
|
|
33
|
+
- Two-layer approach: structured validation in, typed safety out
|
|
34
|
+
|
|
35
|
+
### Config: @nestjs/config + Joi
|
|
36
|
+
- ConfigModule with Joi schema — process.exit on invalid config at startup
|
|
37
|
+
- ConfigService injected everywhere — no process.env in application code
|
|
38
|
+
|
|
39
|
+
### Logging: nestjs-pino
|
|
40
|
+
- Structured JSON logging via pino
|
|
41
|
+
- NestJS lifecycle integration
|
|
42
|
+
- Replaces default NestJS logger
|
|
43
|
+
|
|
44
|
+
### API Docs: @nestjs/swagger
|
|
45
|
+
- Auto-generated OpenAPI spec from DTOs and decorators
|
|
46
|
+
- Live at /api/docs — no static file sync needed
|
|
47
|
+
- Frontend exports via: curl http://localhost:3000/api/docs-json -o openapi.json
|
|
48
|
+
|
|
49
|
+
### Queue: @nestjs/bullmq
|
|
50
|
+
- Official NestJS BullMQ integration
|
|
51
|
+
- Redis-backed, most mature queue in Node ecosystem
|
|
52
|
+
|
|
53
|
+
### Rate Limiting: @nestjs/throttler
|
|
54
|
+
- Official NestJS rate limiting
|
|
55
|
+
- Applied per-controller or per-route with @Throttle()
|
|
56
|
+
|
|
57
|
+
### Health: @nestjs/terminus
|
|
58
|
+
- Official health checks — /health (liveness) + /ready (DB + Redis)
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Technical Debt Tracker
|
|
2
|
+
|
|
3
|
+
## Severity
|
|
4
|
+
| P0 | Security/data integrity — fix immediately |
|
|
5
|
+
| P1 | Blocks features — within 2 sprints |
|
|
6
|
+
| P2 | Degrades quality — within quarter |
|
|
7
|
+
| P3 | Code smell — when in area |
|
|
8
|
+
|
|
9
|
+
## Open Debt
|
|
10
|
+
| ID | Severity | Area | Description | Created By | Date |
|
|
11
|
+
|---|---|---|---|---|---|
|
|
12
|
+
| *(none yet)* | — | — | — | — | — |
|
|
13
|
+
|
|
14
|
+
## Resolved Debt
|
|
15
|
+
| ID | Description | Resolved By | Date |
|
|
16
|
+
|---|---|---|---|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|