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.
Files changed (240) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +156 -0
  3. package/cli.js +122 -0
  4. package/package.json +47 -0
  5. package/templates/express/.claude/CLAUDE.md +114 -0
  6. package/templates/express/.claude/agents/arch-validator.md +85 -0
  7. package/templates/express/.claude/agents/db-optimizer.md +72 -0
  8. package/templates/express/.claude/agents/doc-gardener.md +67 -0
  9. package/templates/express/.claude/agents/garbage-collector.md +94 -0
  10. package/templates/express/.claude/agents/gate-checker.md +176 -0
  11. package/templates/express/.claude/agents/reviewer.md +84 -0
  12. package/templates/express/.claude/agents/security-auditor.md +82 -0
  13. package/templates/express/.claude/hooks/post-write.sh +93 -0
  14. package/templates/express/.claude/rules/api.md +149 -0
  15. package/templates/express/.claude/rules/architecture.md +78 -0
  16. package/templates/express/.claude/rules/database.md +104 -0
  17. package/templates/express/.claude/rules/jobs.md +81 -0
  18. package/templates/express/.claude/rules/security.md +92 -0
  19. package/templates/express/.claude/rules/testing.md +97 -0
  20. package/templates/express/.claude/settings.json +35 -0
  21. package/templates/express/.claude/skills/00-infra-setup/SKILL.md +479 -0
  22. package/templates/express/.claude/skills/01-write-roadmap/SKILL.md +72 -0
  23. package/templates/express/.claude/skills/02-write-spec/SKILL.md +119 -0
  24. package/templates/express/.claude/skills/03-write-plan/SKILL.md +124 -0
  25. package/templates/express/.claude/skills/04-build-layer/SKILL.md +216 -0
  26. package/templates/express/.claude/skills/05-validate-layer/SKILL.md +43 -0
  27. package/templates/express/.claude/skills/06-push-layer/SKILL.md +59 -0
  28. package/templates/express/.claude/skills/07-layer-check/SKILL.md +62 -0
  29. package/templates/express/.claude/skills/08-garbage-collect/SKILL.md +86 -0
  30. package/templates/express/.claude/skills/09-doc-garden/SKILL.md +64 -0
  31. package/templates/express/.claude/skills/10-db-optimize/SKILL.md +96 -0
  32. package/templates/express/.claude/skills/11-load-test/SKILL.md +77 -0
  33. package/templates/express/.dockerignore +43 -0
  34. package/templates/express/.env.example +42 -0
  35. package/templates/express/.github/CODEOWNERS +22 -0
  36. package/templates/express/.github/dependabot.yml +48 -0
  37. package/templates/express/.github/pull_request_template.md +58 -0
  38. package/templates/express/.github/workflows/ci.yml +278 -0
  39. package/templates/express/.github/workflows/load-test.yml +41 -0
  40. package/templates/express/.gitleaks.toml +18 -0
  41. package/templates/express/.lintstagedrc.json +3 -0
  42. package/templates/express/.nvmrc +1 -0
  43. package/templates/express/.prettierrc +8 -0
  44. package/templates/express/.sequelizerc +8 -0
  45. package/templates/express/AGENTS.md +94 -0
  46. package/templates/express/ARCHITECTURE.md +161 -0
  47. package/templates/express/Dockerfile +40 -0
  48. package/templates/express/Makefile +79 -0
  49. package/templates/express/QUICKSTART.md +131 -0
  50. package/templates/express/docker-compose.yml +114 -0
  51. package/templates/express/docs/PLANS.md +111 -0
  52. package/templates/express/docs/QUALITY_SCORE.md +66 -0
  53. package/templates/express/docs/design-docs/core-beliefs.md +89 -0
  54. package/templates/express/docs/design-docs/decisions/ADR-000-infrastructure.md +70 -0
  55. package/templates/express/docs/design-docs/decisions/ADR-001-observability.md +82 -0
  56. package/templates/express/docs/design-docs/decisions/index.md +23 -0
  57. package/templates/express/docs/design-docs/index.md +11 -0
  58. package/templates/express/docs/design-docs/observability.md +194 -0
  59. package/templates/express/docs/design-docs/team-workflow.md +64 -0
  60. package/templates/express/docs/exec-plans/active/.gitkeep +0 -0
  61. package/templates/express/docs/exec-plans/completed/.gitkeep +0 -0
  62. package/templates/express/docs/exec-plans/tech-debt-tracker.md +31 -0
  63. package/templates/express/docs/generated/.gitkeep +0 -0
  64. package/templates/express/docs/product-specs/ROADMAP.md +49 -0
  65. package/templates/express/docs/product-specs/draft/.gitkeep +0 -0
  66. package/templates/express/docs/product-specs/index.md +21 -0
  67. package/templates/express/docs/product-specs/ready/.gitkeep +0 -0
  68. package/templates/express/eslint.config.mjs +94 -0
  69. package/templates/express/gitignore +36 -0
  70. package/templates/express/infra/monitoring/alloy/config.alloy +59 -0
  71. package/templates/express/jest.config.ts +61 -0
  72. package/templates/express/package.json +45 -0
  73. package/templates/express/scripts/openapi.export.ts +77 -0
  74. package/templates/express/tests/architecture/isolation.test.ts +51 -0
  75. package/templates/express/tests/architecture/layers.test.ts +83 -0
  76. package/templates/express/tests/integration/health.test.ts +40 -0
  77. package/templates/express/tests/integration/isolation.test.template.ts +88 -0
  78. package/templates/express/tests/load/smoke.js +46 -0
  79. package/templates/express/tests/load/soak.js +45 -0
  80. package/templates/express/tests/load/stress.js +44 -0
  81. package/templates/express/tests/unit/utils/response.util.test.ts +53 -0
  82. package/templates/express/tsconfig.build.json +8 -0
  83. package/templates/express/tsconfig.json +20 -0
  84. package/templates/fastapi/.claude/CLAUDE.md +122 -0
  85. package/templates/fastapi/.claude/agents/arch-validator.md +64 -0
  86. package/templates/fastapi/.claude/agents/db-optimizer.md +59 -0
  87. package/templates/fastapi/.claude/agents/doc-gardener.md +55 -0
  88. package/templates/fastapi/.claude/agents/garbage-collector.md +74 -0
  89. package/templates/fastapi/.claude/agents/gate-checker.md +133 -0
  90. package/templates/fastapi/.claude/agents/reviewer.md +74 -0
  91. package/templates/fastapi/.claude/agents/security-auditor.md +69 -0
  92. package/templates/fastapi/.claude/hooks/post-write.sh +65 -0
  93. package/templates/fastapi/.claude/rules/api.md +119 -0
  94. package/templates/fastapi/.claude/rules/architecture.md +84 -0
  95. package/templates/fastapi/.claude/rules/database.md +153 -0
  96. package/templates/fastapi/.claude/rules/jobs.md +85 -0
  97. package/templates/fastapi/.claude/rules/security.md +102 -0
  98. package/templates/fastapi/.claude/rules/testing.md +207 -0
  99. package/templates/fastapi/.claude/settings.json +50 -0
  100. package/templates/fastapi/.claude/skills/00-infra-setup/SKILL.md +311 -0
  101. package/templates/fastapi/.claude/skills/01-write-roadmap/SKILL.md +61 -0
  102. package/templates/fastapi/.claude/skills/02-write-spec/SKILL.md +82 -0
  103. package/templates/fastapi/.claude/skills/03-write-plan/SKILL.md +83 -0
  104. package/templates/fastapi/.claude/skills/04-build-layer/SKILL.md +170 -0
  105. package/templates/fastapi/.claude/skills/05-validate-layer/SKILL.md +20 -0
  106. package/templates/fastapi/.claude/skills/06-push-layer/SKILL.md +31 -0
  107. package/templates/fastapi/.claude/skills/07-layer-check/SKILL.md +51 -0
  108. package/templates/fastapi/.claude/skills/08-garbage-collect/SKILL.md +47 -0
  109. package/templates/fastapi/.claude/skills/09-doc-garden/SKILL.md +9 -0
  110. package/templates/fastapi/.claude/skills/10-db-optimize/SKILL.md +53 -0
  111. package/templates/fastapi/.claude/skills/11-load-test/SKILL.md +81 -0
  112. package/templates/fastapi/.dockerignore +30 -0
  113. package/templates/fastapi/.github/dependabot.yml +24 -0
  114. package/templates/fastapi/AGENTS.md +87 -0
  115. package/templates/fastapi/ARCHITECTURE.md +141 -0
  116. package/templates/fastapi/Makefile +42 -0
  117. package/templates/fastapi/README.md +179 -0
  118. package/templates/fastapi/docs/PLANS.md +26 -0
  119. package/templates/fastapi/docs/QUALITY_SCORE.md +26 -0
  120. package/templates/fastapi/docs/design-docs/core-beliefs.md +46 -0
  121. package/templates/fastapi/docs/design-docs/decisions/ADR-000-infrastructure.md +79 -0
  122. package/templates/fastapi/docs/design-docs/decisions/index.md +7 -0
  123. package/templates/fastapi/docs/design-docs/index.md +9 -0
  124. package/templates/fastapi/docs/exec-plans/active/.gitkeep +0 -0
  125. package/templates/fastapi/docs/exec-plans/completed/.gitkeep +0 -0
  126. package/templates/fastapi/docs/exec-plans/tech-debt-tracker.md +19 -0
  127. package/templates/fastapi/docs/generated/.gitkeep +0 -0
  128. package/templates/fastapi/docs/product-specs/ROADMAP.md +49 -0
  129. package/templates/fastapi/docs/product-specs/draft/.gitkeep +0 -0
  130. package/templates/fastapi/docs/product-specs/index.md +18 -0
  131. package/templates/fastapi/docs/product-specs/ready/.gitkeep +0 -0
  132. package/templates/fastapi/gitignore +46 -0
  133. package/templates/fastapi/scripts/gate.sh +68 -0
  134. package/templates/nestjs/.claude/CLAUDE.md +121 -0
  135. package/templates/nestjs/.claude/agents/db-optimizer.md +51 -0
  136. package/templates/nestjs/.claude/agents/doc-gardener.md +45 -0
  137. package/templates/nestjs/.claude/agents/garbage-collector.md +50 -0
  138. package/templates/nestjs/.claude/agents/gate-checker.md +127 -0
  139. package/templates/nestjs/.claude/agents/reviewer.md +68 -0
  140. package/templates/nestjs/.claude/agents/security-auditor.md +72 -0
  141. package/templates/nestjs/.claude/hooks/post-write.sh +91 -0
  142. package/templates/nestjs/.claude/rules/api.md +87 -0
  143. package/templates/nestjs/.claude/rules/architecture.md +104 -0
  144. package/templates/nestjs/.claude/rules/database.md +111 -0
  145. package/templates/nestjs/.claude/rules/security.md +110 -0
  146. package/templates/nestjs/.claude/rules/testing.md +145 -0
  147. package/templates/nestjs/.claude/settings.json +33 -0
  148. package/templates/nestjs/.claude/skills/00-infra-setup/SKILL.md +222 -0
  149. package/templates/nestjs/.claude/skills/01-write-spec/SKILL.md +25 -0
  150. package/templates/nestjs/.claude/skills/02-write-plan/SKILL.md +18 -0
  151. package/templates/nestjs/.claude/skills/03-build-layer/SKILL.md +242 -0
  152. package/templates/nestjs/.claude/skills/04-validate-layer/SKILL.md +4 -0
  153. package/templates/nestjs/.claude/skills/05-push-layer/SKILL.md +6 -0
  154. package/templates/nestjs/.claude/skills/06-layer-check/SKILL.md +12 -0
  155. package/templates/nestjs/.claude/skills/07-garbage-collect/SKILL.md +2 -0
  156. package/templates/nestjs/.claude/skills/08-doc-garden/SKILL.md +4 -0
  157. package/templates/nestjs/.claude/skills/09-api-sync/SKILL.md +36 -0
  158. package/templates/nestjs/.claude/skills/10-load-test/SKILL.md +29 -0
  159. package/templates/nestjs/.env.example +11 -0
  160. package/templates/nestjs/AGENTS.md +88 -0
  161. package/templates/nestjs/ARCHITECTURE.md +192 -0
  162. package/templates/nestjs/docs/PLANS.md +22 -0
  163. package/templates/nestjs/docs/QUALITY_SCORE.md +27 -0
  164. package/templates/nestjs/docs/design-docs/core-beliefs.md +18 -0
  165. package/templates/nestjs/docs/design-docs/decisions/ADR-000-infrastructure.md +58 -0
  166. package/templates/nestjs/docs/design-docs/decisions/index.md +7 -0
  167. package/templates/nestjs/docs/design-docs/index.md +7 -0
  168. package/templates/nestjs/docs/exec-plans/active/.gitkeep +0 -0
  169. package/templates/nestjs/docs/exec-plans/completed/.gitkeep +0 -0
  170. package/templates/nestjs/docs/exec-plans/tech-debt-tracker.md +16 -0
  171. package/templates/nestjs/docs/generated/.gitkeep +0 -0
  172. package/templates/nestjs/docs/product-specs/draft/.gitkeep +0 -0
  173. package/templates/nestjs/docs/product-specs/index.md +7 -0
  174. package/templates/nestjs/docs/product-specs/ready/.gitkeep +0 -0
  175. package/templates/nestjs/gitignore +8 -0
  176. package/templates/nextjs/.claude/CLAUDE.md +139 -0
  177. package/templates/nextjs/.claude/agents/arch-validator.md +66 -0
  178. package/templates/nextjs/.claude/agents/contract-checker.md +78 -0
  179. package/templates/nextjs/.claude/agents/doc-gardener.md +52 -0
  180. package/templates/nextjs/.claude/agents/garbage-collector.md +61 -0
  181. package/templates/nextjs/.claude/agents/gate-checker.md +129 -0
  182. package/templates/nextjs/.claude/agents/perf-auditor.md +109 -0
  183. package/templates/nextjs/.claude/agents/reviewer.md +79 -0
  184. package/templates/nextjs/.claude/agents/security-auditor.md +50 -0
  185. package/templates/nextjs/.claude/hooks/post-write.sh +121 -0
  186. package/templates/nextjs/.claude/rules/api-contract.md +166 -0
  187. package/templates/nextjs/.claude/rules/architecture.md +99 -0
  188. package/templates/nextjs/.claude/rules/components.md +122 -0
  189. package/templates/nextjs/.claude/rules/security.md +122 -0
  190. package/templates/nextjs/.claude/rules/testing.md +187 -0
  191. package/templates/nextjs/.claude/scripts/infra-setup.sh +550 -0
  192. package/templates/nextjs/.claude/settings.json +33 -0
  193. package/templates/nextjs/.claude/skills/00-infra-setup/SKILL.md +471 -0
  194. package/templates/nextjs/.claude/skills/01-write-roadmap/SKILL.md +77 -0
  195. package/templates/nextjs/.claude/skills/02-write-spec/SKILL.md +78 -0
  196. package/templates/nextjs/.claude/skills/03-write-plan/SKILL.md +91 -0
  197. package/templates/nextjs/.claude/skills/04-build-layer/SKILL.md +141 -0
  198. package/templates/nextjs/.claude/skills/05-validate-layer/SKILL.md +13 -0
  199. package/templates/nextjs/.claude/skills/06-push-layer/SKILL.md +20 -0
  200. package/templates/nextjs/.claude/skills/07-layer-check/SKILL.md +28 -0
  201. package/templates/nextjs/.claude/skills/08-garbage-collect/SKILL.md +14 -0
  202. package/templates/nextjs/.claude/skills/09-doc-garden/SKILL.md +12 -0
  203. package/templates/nextjs/.claude/skills/10-api-sync/SKILL.md +50 -0
  204. package/templates/nextjs/.claude/skills/11-perf-budget/SKILL.md +51 -0
  205. package/templates/nextjs/.dockerignore +25 -0
  206. package/templates/nextjs/.gitattributes +10 -0
  207. package/templates/nextjs/.github/CODEOWNERS +24 -0
  208. package/templates/nextjs/.github/dependabot.yml +31 -0
  209. package/templates/nextjs/.github/pull_request_template.md +59 -0
  210. package/templates/nextjs/.github/workflows/ci.yml +143 -0
  211. package/templates/nextjs/.github/workflows/lighthouse.yml +54 -0
  212. package/templates/nextjs/.github/workflows/load-test.yml +54 -0
  213. package/templates/nextjs/.husky/pre-commit +1 -0
  214. package/templates/nextjs/.lintstagedrc.json +4 -0
  215. package/templates/nextjs/.mcp.json +8 -0
  216. package/templates/nextjs/.prettierignore +13 -0
  217. package/templates/nextjs/.prettierrc +9 -0
  218. package/templates/nextjs/AGENTS.md +88 -0
  219. package/templates/nextjs/ARCHITECTURE.md +165 -0
  220. package/templates/nextjs/Dockerfile +38 -0
  221. package/templates/nextjs/Makefile +50 -0
  222. package/templates/nextjs/QUICKSTART.md +128 -0
  223. package/templates/nextjs/docs/PLANS.md +23 -0
  224. package/templates/nextjs/docs/QUALITY_SCORE.md +27 -0
  225. package/templates/nextjs/docs/design-docs/core-beliefs.md +43 -0
  226. package/templates/nextjs/docs/design-docs/decisions/ADR-000-infrastructure.md +72 -0
  227. package/templates/nextjs/docs/design-docs/decisions/index.md +7 -0
  228. package/templates/nextjs/docs/design-docs/index.md +7 -0
  229. package/templates/nextjs/docs/design-docs/team-workflow.md +66 -0
  230. package/templates/nextjs/docs/exec-plans/active/.gitkeep +0 -0
  231. package/templates/nextjs/docs/exec-plans/completed/.gitkeep +0 -0
  232. package/templates/nextjs/docs/exec-plans/tech-debt-tracker.md +19 -0
  233. package/templates/nextjs/docs/generated/.gitkeep +0 -0
  234. package/templates/nextjs/docs/product-specs/ROADMAP.md +59 -0
  235. package/templates/nextjs/docs/product-specs/draft/.gitkeep +0 -0
  236. package/templates/nextjs/docs/product-specs/index.md +18 -0
  237. package/templates/nextjs/docs/product-specs/ready/.gitkeep +0 -0
  238. package/templates/nextjs/eslint.config.mjs +150 -0
  239. package/templates/nextjs/gitignore +35 -0
  240. package/templates/nextjs/lighthouserc.js +37 -0
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: 10-db-optimize
3
+ description: /db-optimize — Query Optimization Workflow
4
+ verified: 2026-06-04
5
+ libraries: [sequelize, pg]
6
+ source: https://sequelize.org/docs/v6/
7
+ staleness-threshold-days: 60
8
+ ---
9
+
10
+ # /db-optimize — Query Optimization Workflow
11
+
12
+ Triggered by: `/db-optimize [method-name or file]`
13
+
14
+ ---
15
+
16
+ ## Step 1 — Find the Slow Query
17
+ ```bash
18
+ # From logs (pino + your log aggregator)
19
+ # Or from pg_stat_statements:
20
+ psql $DATABASE_URL -c "
21
+ SELECT query, mean_exec_time::int, calls
22
+ FROM pg_stat_statements
23
+ WHERE mean_exec_time > 200
24
+ ORDER BY mean_exec_time DESC LIMIT 10;
25
+ "
26
+ ```
27
+
28
+ ## Step 2 — Run EXPLAIN ANALYZE
29
+ ```bash
30
+ # Replace with the actual query being executed
31
+ psql $DATABASE_URL << 'SQL'
32
+ EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
33
+ SELECT a.*, n.id as note_id, n.content
34
+ FROM applications a
35
+ LEFT JOIN notes n ON n.application_id = a.id
36
+ WHERE a.user_id = 'uuid-here' AND a.deleted_at IS NULL
37
+ ORDER BY a.created_at DESC LIMIT 21;
38
+ SQL
39
+ ```
40
+
41
+ ## Step 3 — Read the Output
42
+ | Output | Problem | Fix |
43
+ |---|---|---|
44
+ | `Seq Scan` on large table | Missing index | Add B-tree index on filter column |
45
+ | `Rows Removed >> returned` | Index too broad | Add partial index |
46
+ | `Nested Loop` with large outer | N+1 at DB level | Add composite index or use Hash Join |
47
+ | `Sort` without `Index Scan` | ORDER BY without index | Add index on sort column |
48
+
49
+ ## Step 4 — Add Index via Migration
50
+ ```bash
51
+ npx sequelize-cli migration:generate --name add-idx-{table}-{columns}
52
+ ```
53
+
54
+ ```javascript
55
+ // In the generated migration file:
56
+ module.exports = {
57
+ up: async (queryInterface) => {
58
+ await queryInterface.sequelize.query(
59
+ 'CREATE INDEX CONCURRENTLY idx_{table}_{col} ON {table}({col}) WHERE deleted_at IS NULL'
60
+ )
61
+ },
62
+ down: async (queryInterface) => {
63
+ await queryInterface.sequelize.query('DROP INDEX IF EXISTS idx_{table}_{col}')
64
+ },
65
+ }
66
+ ```
67
+
68
+ ```bash
69
+ npx sequelize-cli db:migrate
70
+ ```
71
+
72
+ ## Step 5 — Also Add to Model
73
+ ```typescript
74
+ // src/models/{Entity}.model.ts
75
+ @Table({
76
+ tableName: '{table}',
77
+ paranoid: true,
78
+ indexes: [
79
+ { fields: ['{col}'], where: { deleted_at: null }, name: 'idx_{table}_{col}' },
80
+ ],
81
+ })
82
+ ```
83
+
84
+ ## Step 6 — Verify
85
+ Re-run EXPLAIN ANALYZE — confirm `Index Scan` is used and execution time < 200ms.
86
+
87
+ ## Step 7 — Attach to Commit
88
+ ```bash
89
+ git add db/migrations/ src/models/
90
+ git commit -m "perf(db): add index idx_{table}_{col}
91
+
92
+ EXPLAIN ANALYZE before: {N}ms
93
+ EXPLAIN ANALYZE after: {M}ms
94
+
95
+ Query: [description]"
96
+ ```
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: 11-load-test
3
+ description: /load-test — k6 Performance Testing
4
+ verified: 2026-06-04
5
+ libraries: [k6]
6
+ source: https://grafana.com/docs/k6/latest/
7
+ staleness-threshold-days: 60
8
+ ---
9
+
10
+ # /load-test — k6 Performance Testing
11
+
12
+ Triggered by: `/load-test [smoke|stress|soak]`
13
+ Default: `smoke`
14
+
15
+ **The scripts already ship in the template** at `tests/load/{smoke,stress,soak}.js`
16
+ and run out of the box against `/health` (no feature needed). npm scripts wrap them.
17
+ k6 is a separate binary — install it first: `choco install k6` (Windows) / `brew install k6` (macOS).
18
+
19
+ ---
20
+
21
+ ## Run it
22
+
23
+ ```bash
24
+ # Local (server running on :3000)
25
+ npm run load:smoke
26
+ npm run load:stress
27
+ npm run load:soak
28
+
29
+ # Against a remote target (+ auth)
30
+ k6 run --env BASE_URL=https://staging.example.com --env AUTH_TOKEN=$TOKEN tests/load/smoke.js
31
+ ```
32
+
33
+ ## In CI (manual)
34
+
35
+ `.github/workflows/load-test.yml` runs **only** via `workflow_dispatch` — never on
36
+ push or PR. Trigger it from **GitHub → Actions → Load Test → Run workflow** and pass
37
+ `base_url`, `test` (smoke/stress/soak), and optional `auth_token`.
38
+
39
+ ## Profiles & thresholds
40
+
41
+ | Profile | Load | Thresholds |
42
+ |---|---|---|
43
+ | Smoke | 10 VUs / 30s | P95 < 500ms · err < 1% |
44
+ | Stress | ramp → 100 VUs | P95 < 1000ms · P99 < 2000ms · err < 5% |
45
+ | Soak | 20 VUs, sustained (`--env DURATION=2h`) | P95 < 800ms · err < 2% |
46
+
47
+ ---
48
+
49
+ ## Adapting a script to a real endpoint
50
+
51
+ Each shipped script hits `/health` and includes a **commented** authenticated
52
+ example. Uncomment and point it at your feature:
53
+
54
+ ```javascript
55
+ const headers = { Authorization: `Bearer ${__ENV.AUTH_TOKEN}`, 'Content-Type': 'application/json' }
56
+ const res = http.get(`${__ENV.BASE_URL}/api/v1/applications`, { headers })
57
+ check(res, {
58
+ 'status 200': (r) => r.status === 200,
59
+ 'has data field': (r) => r.json('data') !== undefined,
60
+ })
61
+ ```
62
+
63
+ ## Interpreting Results
64
+ | Metric | Healthy | Investigate |
65
+ |---|---|---|
66
+ | P95 latency | < 500ms | > 500ms |
67
+ | P99 latency | < 1000ms | > 1000ms |
68
+ | Error rate | < 1% | > 1% |
69
+ | Checks passed | > 99% | < 99% |
70
+
71
+ ## Attach Results to PR
72
+ ```
73
+ Load Test Results (smoke — 10 VUs, 30s):
74
+ P95: {N}ms ✅/❌
75
+ P99: {N}ms ✅/❌
76
+ Errors: {N}% ✅/❌
77
+ ```
@@ -0,0 +1,43 @@
1
+ # Build context hygiene — keep the Docker context small and free of secrets.
2
+ # Without this, `COPY . .` in the builder stage ships node_modules, .git, the
3
+ # .claude harness, docs, and tests into the image layers.
4
+
5
+ # Dependencies (reinstalled inside the image via npm ci)
6
+ node_modules/
7
+ npm-debug.log*
8
+
9
+ # Build output (rebuilt inside the image)
10
+ dist/
11
+ coverage/
12
+
13
+ # Version control + CI
14
+ .git/
15
+ .gitignore
16
+ .github/
17
+
18
+ # Agent harness (never needed at runtime)
19
+ .claude/
20
+
21
+ # Docs, specs, plans
22
+ docs/
23
+ *.md
24
+
25
+ # Local env + secrets — NEVER bake these into an image
26
+ .env
27
+ .env.*
28
+ !.env.example
29
+
30
+ # Editor / OS
31
+ .idea/
32
+ .vscode/
33
+ .DS_Store
34
+ Thumbs.db
35
+ *.swp
36
+
37
+ # Tests + load scripts
38
+ tests/
39
+ infra/
40
+
41
+ # Local compose overrides + k6 output
42
+ docker-compose.override.yml
43
+ k6-results/
@@ -0,0 +1,42 @@
1
+ # Environment
2
+ NODE_ENV=development
3
+
4
+ # Server
5
+ PORT=3000
6
+
7
+ # Database (PostgreSQL)
8
+ DATABASE_URL=postgresql://user:pass@localhost:5432/dbname
9
+ DATABASE_POOL_MAX=10
10
+ DATABASE_POOL_MIN=2
11
+
12
+ # Redis
13
+ REDIS_URL=redis://localhost:6379
14
+
15
+ # JWT
16
+ JWT_SECRET=
17
+ JWT_ACCESS_EXPIRY_SECONDS=900
18
+ JWT_REFRESH_EXPIRY_SECONDS=604800
19
+
20
+ # CORS
21
+ CORS_ORIGINS=http://localhost:3000
22
+
23
+ # Logging
24
+ LOG_LEVEL=info
25
+ SERVICE_NAME=your-service-name
26
+ APP_VERSION=0.0.1
27
+
28
+ # Observability (OpenTelemetry)
29
+ # OTLP/HTTP collector base URL for traces + metrics. The exporters append /v1/traces and
30
+ # /v1/metrics.
31
+ # IMPORTANT: BLANK by default ⇒ the SDK fully no-ops (the config/ helpers — logger, withSpan,
32
+ # metrics — still work). This is the correct default for tests, CI, and local-without-backend.
33
+ # To see signals in Grafana: start the LGTM stack and set this to http://localhost:4318
34
+ # (see docs/design-docs/observability.md).
35
+ OTEL_EXPORTER_OTLP_ENDPOINT=
36
+ OTEL_SERVICE_NAME=your-service-name
37
+ # Optional extra resource attributes (e.g. version, deployment env) — standard OTel var.
38
+ # OTEL_RESOURCE_ATTRIBUTES=service.version=0.0.1,deployment.environment=development
39
+ # How often metrics are flushed to the collector (ms).
40
+ OTEL_METRIC_EXPORT_INTERVAL_MS=10000
41
+ # Logs are NOT sent over OTLP — pino writes correlated JSON to stdout and Grafana Alloy ships
42
+ # it to Loki. See docs/design-docs/observability.md.
@@ -0,0 +1,22 @@
1
+ # CODEOWNERS — GitHub auto-requests these reviewers based on which files changed.
2
+ # Order matters: the LAST matching pattern wins.
3
+ #
4
+ # Replace the placeholder team slugs with your real GitHub teams/usernames, then
5
+ # enable "Require review from Code Owners" in branch protection
6
+ # (see docs/design-docs/team-workflow.md). Until then these are inert placeholders.
7
+
8
+ # Default — any engineer on the team can review
9
+ * @your-team/engineers
10
+
11
+ # Security-sensitive — leads must review
12
+ /.claude/hooks/ @your-team/leads
13
+ /src/providers/auth/ @your-team/leads
14
+ /src/config/ @your-team/leads
15
+
16
+ # Platform / infra — platform team owns build, containers, and CI
17
+ /Dockerfile @your-team/platform
18
+ /docker-compose.yml @your-team/platform
19
+ /.github/workflows/ @your-team/platform
20
+
21
+ # Database changes are irreversible in prod — leads must review
22
+ /db/migrations/ @your-team/leads
@@ -0,0 +1,48 @@
1
+ # Dependabot keeps the (deliberately unpinned) dependency tree from drifting
2
+ # silently. Because /infra-setup installs "latest LTS" with no lockfile in the
3
+ # template, every product needs an automated way to surface updates + CVEs once
4
+ # its lockfile exists. Grouped to keep PR noise low.
5
+ version: 2
6
+ updates:
7
+ # Application dependencies (npm). Active once a product's package-lock.json exists.
8
+ - package-ecosystem: npm
9
+ directory: /
10
+ schedule:
11
+ interval: weekly
12
+ day: monday
13
+ open-pull-requests-limit: 10
14
+ versioning-strategy: increase
15
+ groups:
16
+ # Peer-coupled set — must move together or the decorator layer breaks.
17
+ sequelize:
18
+ patterns:
19
+ - sequelize
20
+ - sequelize-typescript
21
+ - sequelize-cli
22
+ # OpenTelemetry shares a release line; bump as one unit.
23
+ opentelemetry:
24
+ patterns:
25
+ - '@opentelemetry/*'
26
+ types:
27
+ patterns:
28
+ - '@types/*'
29
+ update-types:
30
+ - minor
31
+ - patch
32
+ dev-minor-patch:
33
+ dependency-type: development
34
+ update-types:
35
+ - minor
36
+ - patch
37
+ labels:
38
+ - dependencies
39
+
40
+ # GitHub Actions — keep pinned action versions current (security-relevant).
41
+ - package-ecosystem: github-actions
42
+ directory: /
43
+ schedule:
44
+ interval: weekly
45
+ day: monday
46
+ labels:
47
+ - dependencies
48
+ - ci
@@ -0,0 +1,58 @@
1
+ <!--
2
+ PR title format: <type>(<scope>): <summary>
3
+ type ∈ feat | fix | chore | refactor | docs | test | perf
4
+ Example: feat(applications): add stage-transition endpoint
5
+ -->
6
+
7
+ ## What does this PR do?
8
+
9
+ <!-- One sentence. Link the spec it came from. -->
10
+
11
+ - Spec: `docs/product-specs/ready/SPEC-XXX.md`
12
+
13
+ ## Execution plan reference
14
+
15
+ <!-- Link the plan that drove this work. -->
16
+
17
+ - Plan: `docs/exec-plans/active/PLAN-XXX.md` (or completed/)
18
+ - Closes #
19
+
20
+ ## Layers touched (check each, confirm its rule holds)
21
+
22
+ - [ ] **Types** — zero imports from other layers; no logic
23
+ - [ ] **Config** — imports only from types/zod; `env.ts` Zod-validated
24
+ - [ ] **Models** — `paranoid: true`; UUIDv7 ids
25
+ - [ ] **Repo** — `Schema.parse(raw.toJSON())` on every result; ownership (`findByIdAndUser`); cursor pagination
26
+ - [ ] **Service** — no `express`/`Request`/`Response` imports; business logic only
27
+ - [ ] **Runtime** — order is auth → validate → service → respond; canonical envelope via `ok()`/`errorHandler`
28
+ - [ ] **Providers** — entered via explicit interface only
29
+ - [ ] **Utils** — zero domain imports; **100% test coverage**
30
+
31
+ ## Gate check (all green)
32
+
33
+ - [ ] `tsc --noEmit` — type-check passes
34
+ - [ ] `eslint src/ --max-warnings=0` — lint clean
35
+ - [ ] `jest` — all tests pass
36
+ - [ ] Coverage meets per-layer thresholds (utils 100 · services 90 · repo 80 · routes 75 · providers 70)
37
+ - [ ] Architecture tests pass (`jest tests/architecture/`)
38
+ - [ ] No file exceeds 400 lines
39
+
40
+ ## Security checklist
41
+
42
+ - [ ] No `console.*` in `src/` (use `logger`)
43
+ - [ ] No raw `process.env` outside `src/config/env.ts`
44
+ - [ ] Auth required on every protected endpoint (`requireAuth` first)
45
+ - [ ] `userId` scoped into every query (no cross-tenant leakage)
46
+ - [ ] Cross-user isolation test exists (User B → 404 on User A's resource)
47
+
48
+ ## ADR
49
+
50
+ - [ ] A non-obvious architectural decision was made → ADR written in `docs/design-docs/decisions/`
51
+ - [ ] No ADR needed (nothing non-obvious)
52
+
53
+ ## Breaking changes
54
+
55
+ - [ ] None
56
+ - [ ] Yes — documented below (API contract, DB migration, env var, or config change)
57
+
58
+ <!-- If breaking: describe the change, the migration path, and rollback steps. -->
@@ -0,0 +1,278 @@
1
+ name: CI
2
+
3
+ # The PR gate. Runs the same deterministic checks as `npm run gate`, plus
4
+ # security scanning, image build/scan, SBOM, and a performance-budget gate.
5
+ #
6
+ # Template-aware: a freshly-cloned template has no `src/` yet (it is generated by
7
+ # /infra-setup). The `guard` job detects that and lets source-dependent jobs skip
8
+ # cleanly, so the template's own pushes stay green while every product built from
9
+ # it inherits the full pipeline. Action versions are pinned; Dependabot keeps them
10
+ # current (see .github/dependabot.yml).
11
+
12
+ on:
13
+ push:
14
+ branches: [main]
15
+ pull_request:
16
+ branches: [main]
17
+
18
+ # Cancel superseded runs on the same ref to save minutes.
19
+ concurrency:
20
+ group: ci-${{ github.workflow }}-${{ github.ref }}
21
+ cancel-in-progress: true
22
+
23
+ permissions:
24
+ contents: read
25
+ security-events: write # upload Trivy SARIF to GitHub code scanning
26
+
27
+ jobs:
28
+ # ---------------------------------------------------------------------------
29
+ # Detect whether application code exists yet. All source-dependent jobs gate
30
+ # on `has_src` so the bare template doesn't fail CI before /infra-setup runs.
31
+ # ---------------------------------------------------------------------------
32
+ guard:
33
+ name: Detect project state
34
+ runs-on: ubuntu-latest
35
+ outputs:
36
+ has_src: ${{ steps.detect.outputs.has_src }}
37
+ steps:
38
+ - uses: actions/checkout@v4
39
+ - id: detect
40
+ run: |
41
+ if [ -n "$(find src -name '*.ts' 2>/dev/null | head -1)" ]; then
42
+ echo "has_src=true" >> "$GITHUB_OUTPUT"
43
+ echo "Application code detected — running the full pipeline."
44
+ else
45
+ echo "has_src=false" >> "$GITHUB_OUTPUT"
46
+ echo "No src/ yet (template state) — source-dependent jobs will skip."
47
+ fi
48
+
49
+ # ---------------------------------------------------------------------------
50
+ # Deterministic quality gate — mirrors `npm run gate` + coverage-enforced tests.
51
+ # ---------------------------------------------------------------------------
52
+ quality:
53
+ name: Lint · Typecheck · Test · Build
54
+ needs: guard
55
+ if: needs.guard.outputs.has_src == 'true'
56
+ runs-on: ubuntu-latest
57
+ services:
58
+ postgres:
59
+ image: postgres:16-alpine
60
+ env:
61
+ POSTGRES_USER: postgres
62
+ POSTGRES_PASSWORD: postgres
63
+ POSTGRES_DB: myapp_test
64
+ ports: ["5432:5432"]
65
+ options: >-
66
+ --health-cmd "pg_isready -U postgres"
67
+ --health-interval 10s --health-timeout 5s --health-retries 5
68
+ redis:
69
+ image: redis:7-alpine
70
+ ports: ["6379:6379"]
71
+ options: >-
72
+ --health-cmd "redis-cli ping"
73
+ --health-interval 10s --health-timeout 3s --health-retries 5
74
+ env:
75
+ NODE_ENV: test
76
+ DATABASE_URL: postgresql://postgres:postgres@localhost:5432/myapp_test
77
+ REDIS_URL: redis://localhost:6379
78
+ JWT_SECRET: ci-test-secret-not-a-real-key-min-32-chars
79
+ CORS_ORIGINS: http://localhost:3000
80
+ # Blank endpoint ⇒ OTel SDK is a clean no-op. Never start LGTM in CI.
81
+ OTEL_EXPORTER_OTLP_ENDPOINT: ""
82
+ steps:
83
+ - uses: actions/checkout@v4
84
+ - uses: actions/setup-node@v4
85
+ with:
86
+ node-version: "24"
87
+ cache: npm
88
+ - name: Install dependencies
89
+ run: |
90
+ if [ -f package-lock.json ]; then npm ci; else npm install; fi
91
+ - name: Typecheck
92
+ run: npm run typecheck
93
+ - name: Lint (0 warnings)
94
+ run: npm run lint
95
+ - name: Circular import check
96
+ run: npm run check:circular
97
+ - name: Test with coverage (thresholds enforced in jest.config.ts)
98
+ run: npm run test:coverage
99
+ - name: Build
100
+ run: npm run build
101
+ - name: OpenAPI contract is up to date
102
+ run: |
103
+ npm run openapi:export
104
+ # -N (intent-to-add) makes a never-committed contract count as a diff too, so this
105
+ # catches both drift AND "forgot to commit the generated contract" (plain `git diff`
106
+ # ignores untracked files and would pass silently).
107
+ git add -N docs/generated/openapi.json docs/generated/openapi.yaml 2>/dev/null || true
108
+ if ! git diff --exit-code -- docs/generated/openapi.json docs/generated/openapi.yaml; then
109
+ echo "::error::OpenAPI contract drifted or was never committed. Run 'npm run openapi:export' and commit docs/generated/openapi.*"
110
+ exit 1
111
+ fi
112
+ - name: Upload coverage
113
+ if: always()
114
+ uses: actions/upload-artifact@v4
115
+ with:
116
+ name: coverage
117
+ path: coverage/
118
+ if-no-files-found: ignore
119
+
120
+ # ---------------------------------------------------------------------------
121
+ # Secret scanning — runs ALWAYS (even on the bare template; secrets can land in
122
+ # any file, not just src/).
123
+ # ---------------------------------------------------------------------------
124
+ secret-scan:
125
+ name: Secret scan (gitleaks)
126
+ runs-on: ubuntu-latest
127
+ steps:
128
+ - uses: actions/checkout@v4
129
+ with:
130
+ fetch-depth: 0 # full history so gitleaks can scan every commit
131
+ # Run the gitleaks CLI from its official image rather than the marketplace
132
+ # action. The action calls the GitHub API (job summaries / usage checks) and
133
+ # crashes with an unhandled RequestError on any non-2xx response; the binary
134
+ # just scans git history and exits non-zero on findings — no token, no API,
135
+ # no action version to resolve. `git` subcommand needs the full history above.
136
+ - name: gitleaks
137
+ run: |
138
+ docker run --rm -v "$PWD:/repo" -w /repo \
139
+ ghcr.io/gitleaks/gitleaks:latest git \
140
+ --config .gitleaks.toml --redact --exit-code 1 .
141
+
142
+ # ---------------------------------------------------------------------------
143
+ # Dependency vulnerability audit (needs a lockfile to be meaningful).
144
+ # ---------------------------------------------------------------------------
145
+ audit:
146
+ name: Dependency audit
147
+ needs: guard
148
+ if: needs.guard.outputs.has_src == 'true'
149
+ runs-on: ubuntu-latest
150
+ steps:
151
+ - uses: actions/checkout@v4
152
+ - uses: actions/setup-node@v4
153
+ with:
154
+ node-version: "24"
155
+ cache: npm
156
+ - name: Install dependencies
157
+ run: |
158
+ if [ -f package-lock.json ]; then npm ci; else npm install; fi
159
+ - name: npm audit (fail on high+)
160
+ run: npm run audit
161
+
162
+ # ---------------------------------------------------------------------------
163
+ # Static analysis (CodeQL) — scans the app source for security issues and
164
+ # uploads findings to GitHub code scanning. JS/TS needs no build step.
165
+ # ---------------------------------------------------------------------------
166
+ codeql:
167
+ name: CodeQL (JS/TS)
168
+ needs: guard
169
+ if: needs.guard.outputs.has_src == 'true'
170
+ runs-on: ubuntu-latest
171
+ permissions:
172
+ contents: read
173
+ security-events: write
174
+ steps:
175
+ - uses: actions/checkout@v4
176
+ - uses: github/codeql-action/init@v3
177
+ with:
178
+ languages: javascript-typescript
179
+ - uses: github/codeql-action/analyze@v3
180
+
181
+ # ---------------------------------------------------------------------------
182
+ # Dependency review — blocks PRs that introduce vulnerable or disallowed-license
183
+ # dependencies. PR-only (it diffs the base vs head dependency manifests).
184
+ # ---------------------------------------------------------------------------
185
+ dependency-review:
186
+ name: Dependency review
187
+ if: github.event_name == 'pull_request'
188
+ runs-on: ubuntu-latest
189
+ steps:
190
+ - uses: actions/checkout@v4
191
+ - uses: actions/dependency-review-action@v4
192
+ with:
193
+ fail-on-severity: high
194
+
195
+ # ---------------------------------------------------------------------------
196
+ # Container build + image vulnerability scan + SBOM.
197
+ # ---------------------------------------------------------------------------
198
+ container:
199
+ name: Image build · Trivy scan · SBOM
200
+ needs: [guard, quality]
201
+ if: needs.guard.outputs.has_src == 'true'
202
+ runs-on: ubuntu-latest
203
+ steps:
204
+ - uses: actions/checkout@v4
205
+ - name: Build image
206
+ run: docker build -t harness-app:ci .
207
+ # Scanners run from their official Docker images (not marketplace actions) so there is
208
+ # no action-version to resolve/pin. `:latest` is intentional — you want the freshest
209
+ # vuln DB; a team that needs reproducibility can pin an image digest here.
210
+ - name: Trivy image scan (fail on CRITICAL/HIGH)
211
+ run: |
212
+ docker run --rm \
213
+ -v /var/run/docker.sock:/var/run/docker.sock \
214
+ -v "$PWD:/out" \
215
+ aquasec/trivy:latest image \
216
+ --severity CRITICAL,HIGH --ignore-unfixed \
217
+ --format sarif --output /out/trivy-results.sarif \
218
+ --exit-code 1 \
219
+ harness-app:ci
220
+ - name: Upload Trivy SARIF
221
+ if: always()
222
+ uses: github/codeql-action/upload-sarif@v3
223
+ with:
224
+ sarif_file: trivy-results.sarif
225
+ - name: Generate SBOM (SPDX) with Syft
226
+ if: always()
227
+ run: |
228
+ docker run --rm \
229
+ -v /var/run/docker.sock:/var/run/docker.sock \
230
+ -v "$PWD:/out" \
231
+ anchore/syft:latest \
232
+ scan harness-app:ci -o spdx-json=/out/sbom.spdx.json
233
+ - name: Upload SBOM
234
+ if: always()
235
+ uses: actions/upload-artifact@v4
236
+ with:
237
+ name: sbom
238
+ path: sbom.spdx.json
239
+ if-no-files-found: ignore
240
+
241
+ # ---------------------------------------------------------------------------
242
+ # Performance budget gate — boots the app + Postgres + Redis via compose and
243
+ # runs the k6 smoke test (p95 < 500ms, error rate < 1%; see tests/load/smoke.js).
244
+ # Push-only (post-merge) to keep PRs fast; the manual load-test.yml covers
245
+ # stress/soak against deployed environments.
246
+ # ---------------------------------------------------------------------------
247
+ perf-smoke:
248
+ name: Perf budget (k6 smoke)
249
+ needs: [guard, quality]
250
+ if: needs.guard.outputs.has_src == 'true' && github.event_name == 'push'
251
+ runs-on: ubuntu-latest
252
+ steps:
253
+ - uses: actions/checkout@v4
254
+ - name: Boot the stack
255
+ env:
256
+ # Blank ⇒ OTel SDK no-ops. Honors "never start the LGTM backend in CI".
257
+ OTEL_EXPORTER_OTLP_ENDPOINT: ""
258
+ run: |
259
+ # --wait blocks until postgres/redis are healthy so the app doesn't race the DB on boot.
260
+ docker compose up -d --wait postgres redis
261
+ # --no-deps so the lgtm/alloy observability backend is NOT started in CI.
262
+ docker compose up -d --no-deps --build app
263
+ # Wait for the app health endpoint.
264
+ for i in $(seq 1 30); do
265
+ if curl -fsS http://localhost:3000/health >/dev/null 2>&1; then echo "app up"; break; fi
266
+ sleep 2
267
+ done
268
+ - uses: grafana/setup-k6-action@v1
269
+ - name: k6 smoke (enforces thresholds)
270
+ env:
271
+ BASE_URL: http://localhost:3000
272
+ run: k6 run tests/load/smoke.js
273
+ - name: Dump app logs on failure
274
+ if: failure()
275
+ run: docker compose logs app
276
+ - name: Tear down
277
+ if: always()
278
+ run: docker compose down -v