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,143 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+
8
+ # Least-privilege default token. Jobs opt into more only where needed.
9
+ permissions:
10
+ contents: read
11
+
12
+ # Cancel superseded runs on the same ref.
13
+ concurrency:
14
+ group: ci-${{ github.ref }}
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ verify:
19
+ name: typecheck · lint · format · test · build
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+
24
+ # The bare template has no package.json (it's generated by /infra-setup).
25
+ # Skip the real steps until an app exists so this stays green on the harness itself.
26
+ - name: Detect app
27
+ id: app
28
+ run: |
29
+ if [ -f package.json ]; then
30
+ echo "exists=true" >> "$GITHUB_OUTPUT"
31
+ else
32
+ echo "exists=false" >> "$GITHUB_OUTPUT"
33
+ echo "::notice::No package.json yet (bare harness) — skipping verify steps. Run /infra-setup to scaffold the app."
34
+ fi
35
+
36
+ - uses: actions/setup-node@v4
37
+ if: steps.app.outputs.exists == 'true'
38
+ with:
39
+ node-version: 'lts/*'
40
+ cache: npm
41
+
42
+ - name: Install
43
+ if: steps.app.outputs.exists == 'true'
44
+ run: npm ci
45
+
46
+ - name: Type-check
47
+ if: steps.app.outputs.exists == 'true'
48
+ run: npm run typecheck
49
+
50
+ - name: Lint
51
+ if: steps.app.outputs.exists == 'true'
52
+ run: npm run lint
53
+
54
+ - name: Format check
55
+ if: steps.app.outputs.exists == 'true'
56
+ run: npm run format:check
57
+
58
+ - name: Test (coverage)
59
+ if: steps.app.outputs.exists == 'true'
60
+ run: npm run test:coverage
61
+
62
+ - name: Build
63
+ if: steps.app.outputs.exists == 'true'
64
+ env:
65
+ # env.ts validates this at build time; a dummy value is fine for CI build.
66
+ NEXT_PUBLIC_API_URL: http://localhost:8000
67
+ run: npm run build
68
+
69
+ # End-to-end browser tests (Playwright). Separate job so a flaky e2e never blocks
70
+ # the fast verify signal, and so the browser download is cached independently.
71
+ e2e:
72
+ name: e2e (Playwright)
73
+ runs-on: ubuntu-latest
74
+ steps:
75
+ - uses: actions/checkout@v4
76
+ - name: Detect app
77
+ id: app
78
+ run: |
79
+ if [ -f package.json ]; then echo "exists=true" >> "$GITHUB_OUTPUT";
80
+ else echo "exists=false" >> "$GITHUB_OUTPUT"; echo "::notice::No app yet — skipping e2e."; fi
81
+ - uses: actions/setup-node@v4
82
+ if: steps.app.outputs.exists == 'true'
83
+ with:
84
+ node-version: 'lts/*'
85
+ cache: npm
86
+ - name: Install
87
+ if: steps.app.outputs.exists == 'true'
88
+ run: npm ci
89
+ - name: Install Playwright browsers
90
+ if: steps.app.outputs.exists == 'true'
91
+ run: npx playwright install --with-deps chromium
92
+ - name: Run e2e
93
+ if: steps.app.outputs.exists == 'true'
94
+ env:
95
+ NEXT_PUBLIC_API_URL: http://localhost:8000
96
+ run: npm run test:e2e
97
+
98
+ # Dependency vulnerabilities + leaked secrets. Runs on the bare harness too
99
+ # (gitleaks scans history; audit no-ops without a lockfile).
100
+ security:
101
+ name: audit · secret-scan
102
+ runs-on: ubuntu-latest
103
+ steps:
104
+ - uses: actions/checkout@v4
105
+ with:
106
+ fetch-depth: 0 # gitleaks needs full history
107
+
108
+ - name: Detect app
109
+ id: app
110
+ run: |
111
+ if [ -f package-lock.json ]; then echo "lock=true" >> "$GITHUB_OUTPUT";
112
+ else echo "lock=false" >> "$GITHUB_OUTPUT"; echo "::notice::No lockfile yet — skipping npm audit."; fi
113
+
114
+ - uses: actions/setup-node@v4
115
+ if: steps.app.outputs.lock == 'true'
116
+ with:
117
+ node-version: 'lts/*'
118
+ cache: npm
119
+
120
+ - name: npm audit (high+)
121
+ if: steps.app.outputs.lock == 'true'
122
+ run: npm audit --audit-level=high
123
+
124
+ # Use the gitleaks CLI via Docker, NOT gitleaks-action — the action requires a
125
+ # paid license on GitHub Organizations; the CLI/image is free everywhere.
126
+ - name: Secret scan (gitleaks)
127
+ run: docker run --rm -v "${{ github.workspace }}:/repo" ghcr.io/gitleaks/gitleaks:latest detect --source=/repo --redact --verbose
128
+
129
+ # GitHub's dependency-review blocks PRs that introduce vulnerable/incompatible deps.
130
+ # PR-only (the action requires a base..head diff).
131
+ dependency-review:
132
+ name: dependency-review
133
+ if: github.event_name == 'pull_request'
134
+ runs-on: ubuntu-latest
135
+ permissions:
136
+ contents: read
137
+ pull-requests: write
138
+ steps:
139
+ - uses: actions/checkout@v4
140
+ - uses: actions/dependency-review-action@v4
141
+ with:
142
+ fail-on-severity: high
143
+ comment-summary-in-pr: on-failure
@@ -0,0 +1,54 @@
1
+ name: Lighthouse CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ concurrency:
13
+ group: lighthouse-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ jobs:
17
+ lighthouse:
18
+ name: Core Web Vitals budget
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+
23
+ # Skip until /infra-setup has generated the app.
24
+ - name: Detect app
25
+ id: app
26
+ run: |
27
+ if [ -f package.json ]; then
28
+ echo "exists=true" >> "$GITHUB_OUTPUT"
29
+ else
30
+ echo "exists=false" >> "$GITHUB_OUTPUT"
31
+ echo "::notice::No package.json yet (bare harness) — skipping Lighthouse."
32
+ fi
33
+
34
+ - uses: actions/setup-node@v4
35
+ if: steps.app.outputs.exists == 'true'
36
+ with:
37
+ node-version: 'lts/*'
38
+ cache: npm
39
+
40
+ - name: Install
41
+ if: steps.app.outputs.exists == 'true'
42
+ run: npm ci
43
+
44
+ - name: Build
45
+ if: steps.app.outputs.exists == 'true'
46
+ env:
47
+ NEXT_PUBLIC_API_URL: http://localhost:8000
48
+ run: npm run build
49
+
50
+ - name: Lighthouse CI
51
+ if: steps.app.outputs.exists == 'true'
52
+ env:
53
+ NEXT_PUBLIC_API_URL: http://localhost:8000
54
+ run: npx --yes @lhci/cli@latest autorun --config=lighthouserc.js
@@ -0,0 +1,54 @@
1
+ name: Load Test
2
+
3
+ # Manual only — never runs on push or PR. Trigger from the Actions tab
4
+ # (GitHub → Actions → Load Test → Run workflow) and point it at any reachable URL.
5
+ on:
6
+ workflow_dispatch:
7
+ inputs:
8
+ base_url:
9
+ description: 'Target base URL (e.g. https://staging.example.com)'
10
+ required: true
11
+ type: string
12
+ test:
13
+ description: 'Which test to run'
14
+ required: true
15
+ type: choice
16
+ default: smoke
17
+ options:
18
+ - smoke
19
+ - stress
20
+ - soak
21
+ auth_token:
22
+ description: 'Bearer token for authenticated endpoints (optional)'
23
+ required: false
24
+ type: string
25
+
26
+ permissions:
27
+ contents: read
28
+
29
+ jobs:
30
+ load-test:
31
+ name: k6 ${{ inputs.test }} → ${{ inputs.base_url }}
32
+ runs-on: ubuntu-latest
33
+ steps:
34
+ - name: Checkout
35
+ uses: actions/checkout@v4
36
+
37
+ # The k6 scripts are written by /infra-setup (tests/load/*.js). Fail loudly with
38
+ # a fix hint if they are missing, instead of a cryptic k6 "file not found".
39
+ - name: Verify load script exists
40
+ run: |
41
+ script="tests/load/${{ inputs.test }}.js"
42
+ if [ ! -f "$script" ]; then
43
+ echo "::error::$script not found. Run /infra-setup to scaffold tests/load/, or add the script."
44
+ exit 1
45
+ fi
46
+
47
+ - name: Install k6
48
+ uses: grafana/setup-k6-action@v1
49
+
50
+ - name: Run k6 ${{ inputs.test }}
51
+ env:
52
+ BASE_URL: ${{ inputs.base_url }}
53
+ AUTH_TOKEN: ${{ inputs.auth_token }}
54
+ run: k6 run tests/load/${{ inputs.test }}.js
@@ -0,0 +1 @@
1
+ npx lint-staged
@@ -0,0 +1,4 @@
1
+ {
2
+ "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
3
+ "*.{json,css,md,mjs}": ["prettier --write"]
4
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "context7": {
4
+ "command": "npx",
5
+ "args": ["-y", "@upstash/context7-mcp"]
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,13 @@
1
+ .next
2
+ out
3
+ node_modules
4
+ dist
5
+ coverage
6
+ playwright-report
7
+ test-results
8
+ package-lock.json
9
+ # Auto-generated by Next on every build — not prettier-clean, gitignored. Excluding it
10
+ # keeps `format:check` (gate + CI) green after a build regenerates it.
11
+ next-env.d.ts
12
+ # Generated — never format (READ ONLY, regenerated by /api-sync)
13
+ src/types/api.generated.ts
@@ -0,0 +1,9 @@
1
+ {
2
+ "semi": false,
3
+ "singleQuote": true,
4
+ "printWidth": 100,
5
+ "trailingComma": "es5",
6
+ "tabWidth": 2,
7
+ "useTabs": false,
8
+ "plugins": ["prettier-plugin-tailwindcss"]
9
+ }
@@ -0,0 +1,88 @@
1
+ # AGENTS.md — Navigation Map
2
+
3
+ Stack (latest LTS — no version pins): Next.js · React · TypeScript (strict) · Tailwind CSS · shadcn/ui · TanStack Query · Zustand · openapi-fetch · Vitest · Playwright
4
+
5
+ ---
6
+
7
+ ## 🗺️ Where Everything Lives
8
+
9
+ | What you need | Where |
10
+ |---|---|
11
+ | First 30 minutes / day-one guide | `QUICKSTART.md` |
12
+ | Layer rules + dependency diagram | `ARCHITECTURE.md` |
13
+ | Engineering constitution | `docs/design-docs/core-beliefs.md` |
14
+ | Active execution plan | `docs/exec-plans/active/` |
15
+ | Completed plans | `docs/exec-plans/completed/` |
16
+ | Product roadmap (feature areas → specs, dependency order) | `docs/product-specs/ROADMAP.md` |
17
+ | Product specs (draft) | `docs/product-specs/draft/` |
18
+ | Product specs (approved) | `docs/product-specs/ready/` |
19
+ | Architectural decisions | `docs/design-docs/decisions/` |
20
+ | Tech debt | `docs/exec-plans/tech-debt-tracker.md` |
21
+ | Domain health grades | `docs/QUALITY_SCORE.md` |
22
+ | API contract (generated) | `src/types/api.generated.ts` ← READ ONLY |
23
+ | Plan format | `docs/PLANS.md` |
24
+
25
+ ---
26
+
27
+ ## ⚡ Slash Commands
28
+
29
+ | Command | What it does |
30
+ |---|---|
31
+ | `/infra-setup` | Phase 0 — full Next.js scaffold (run once) |
32
+ | `/write-roadmap` | Brief + `openapi.json` → ordered frontend spec roadmap → `docs/product-specs/ROADMAP.md` |
33
+ | `/write-spec` | Write product spec → `docs/product-specs/draft/` |
34
+ | `/write-plan` | Turn READY spec into execution plan |
35
+ | `/build-layer` | Build next unchecked layer + run gate |
36
+ | `/validate-layer` | Gate check without building |
37
+ | `/push-layer` | Commit + push with conventional message |
38
+ | `/layer-check` | Ad-hoc architecture violation scan |
39
+ | `/garbage-collect` | End-of-feature cleanup |
40
+ | `/doc-garden` | Fix stale documentation |
41
+ | `/api-sync` | Regenerate `api.generated.ts` from OpenAPI spec file |
42
+ | `/perf-budget` | Run Lighthouse CI + bundle analysis |
43
+
44
+ ---
45
+
46
+ ## 🤖 Agents
47
+
48
+ | Agent | When to use |
49
+ |---|---|
50
+ | `gate-checker` | Auto-called by `/build-layer` — PASS/FAIL |
51
+ | `reviewer` | Before opening a PR |
52
+ | `arch-validator` | Deep import + layer scan |
53
+ | `security-auditor` | Before any auth/data-exposure PR |
54
+ | `perf-auditor` | Core Web Vitals + bundle size gatekeeper |
55
+ | `contract-checker` | Detect API contract drift |
56
+ | `doc-gardener` | Fix stale docs |
57
+ | `garbage-collector` | End-of-feature cleanup |
58
+
59
+ ---
60
+
61
+ ## ✅ Non-Negotiable Invariants
62
+
63
+ - No `console.log` in `src/` → use error boundaries or monitoring
64
+ - No `process.env` outside `src/lib/env.ts`
65
+ - No direct `fetch()` in components or pages → all API calls via hooks in `src/hooks/`
66
+ - No business logic in `app/` pages → pages are layout + data trigger only
67
+ - No hand-written types that duplicate `api.generated.ts`
68
+ - `api.generated.ts` is READ ONLY — regenerated by `/api-sync`, never edited manually
69
+ - Access tokens stored in memory only — never `localStorage`
70
+ - All images via `next/image` — never raw `<img>`
71
+ - Every `use client` must have a comment explaining why it needs client rendering
72
+ - No file > 400 lines → split into focused modules
73
+ - TypeScript strict — no `any`, no `as SomeType` on API response data
74
+
75
+ ---
76
+
77
+ ## 🔁 The Flow
78
+
79
+ ```
80
+ # Whole product (once, after the backend ships its openapi.json):
81
+ /write-roadmap → human reviews ROADMAP → pick the walking-skeleton spec
82
+
83
+ # Every feature (repeat down the roadmap, as backend specs ship):
84
+ /write-spec (roadmap-guided) → human marks READY → /write-plan
85
+ → /api-sync (ensure contract is current)
86
+ → /build-layer (repeats, gate-enforced)
87
+ → /garbage-collect → plan closed
88
+ ```
@@ -0,0 +1,165 @@
1
+ # ARCHITECTURE.md — Layered Architecture
2
+
3
+ Stack (latest LTS — no version pins): Next.js · React · TypeScript (strict) · Tailwind CSS · shadcn/ui · TanStack Query
4
+
5
+ ---
6
+
7
+ ## Dependency Layer Diagram
8
+
9
+ ```
10
+ ┌──────────────────────────────────────────────────────────────────┐
11
+ │ Utils (src/utils/) — stateless helpers, zero domain imports │
12
+ │ 100% test coverage required │
13
+ └─────────────────────────────┬────────────────────────────────────┘
14
+
15
+ ┌─────────────────────────────▼────────────────────────────────────┐
16
+ │ │
17
+ │ Types (src/types/) │
18
+ │ ├─ api.generated.ts ← READ ONLY — from /api-sync │
19
+ │ └─ domain.types.ts ← frontend-only types (no duplication) │
20
+ │ │
21
+ │ Lib (src/lib/) │
22
+ │ ├─ env.ts ← Zod-validated NEXT_PUBLIC_* env vars │
23
+ │ ├─ api-client.ts ← openapi-fetch instance (typed) │
24
+ │ └─ constants.ts │
25
+ │ │
26
+ │ Hooks (src/hooks/) ← "Repo" layer — ALL API calls live here │
27
+ │ ├─ use-applications.ts ← TanStack Query per domain │
28
+ │ └─ use-auth.ts │
29
+ │ │
30
+ │ Store (src/store/) ← Zustand — client-only UI state │
31
+ │ └─ Only state that does NOT belong on the server │
32
+ │ │
33
+ │ Features (src/features/) ← Feature-scoped modules │
34
+ │ ├─ applications/ ← components + feature hooks │
35
+ │ └─ auth/ │
36
+ │ │
37
+ │ Components (src/components/) ← Shared design system │
38
+ │ ├─ ui/ ← shadcn/ui (copy-owned — in your repo) │
39
+ │ └─ shared/ ← cross-feature shared components │
40
+ │ │
41
+ │ App (app/) ← Next.js App Router — routing only │
42
+ │ ├─ (auth)/ ← public auth routes │
43
+ │ ├─ (dashboard)/← protected routes (auth guard in layout) │
44
+ │ └─ api/ ← Next.js API routes (cookie auth only) │
45
+ │ │
46
+ └───────────────────────────────────────────────────────────────────┘
47
+ ```
48
+
49
+ ---
50
+
51
+ ## Layer Definitions
52
+
53
+ ### Types (`src/types/`)
54
+ - `api.generated.ts` — **NEVER edit this file**. Generated by `/api-sync` from the OpenAPI spec.
55
+ - `domain.types.ts` — Frontend-only types (UI state, component props, form inputs). Must NOT duplicate api.generated.ts.
56
+ - Zero imports from other layers.
57
+
58
+ ### Lib (`src/lib/`)
59
+ - `env.ts` — Zod-validated NEXT_PUBLIC_* env vars. `process.env` only here.
60
+ - `api-client.ts` — Single openapi-fetch client instance. Auth headers injected here.
61
+ - Imports: Types only.
62
+
63
+ ### Hooks (`src/hooks/`)
64
+ - **The only place API calls happen.** TanStack Query hooks per domain.
65
+ - Imports: Types, Lib
66
+ - Every hook wraps openapi-fetch via the api-client.
67
+ - Never call raw `fetch()` here — always through api-client.
68
+
69
+ ### Store (`src/store/`)
70
+ - Zustand for client-only state: sidebar open/closed, selected tab, modal state.
71
+ - **NOT** for server data (that lives in TanStack Query cache).
72
+ - Imports: Types only.
73
+
74
+ ### Features (`src/features/`)
75
+ - Feature-scoped components, forms, and feature-specific hooks.
76
+ - Imports: Types, Lib, Hooks, Store, Components, Utils.
77
+ - Never imports from `app/` (no routing concerns).
78
+
79
+ ### Components (`src/components/`)
80
+ - `ui/` — shadcn/ui components (yours to own and modify).
81
+ - `shared/` — cross-feature components (layout, nav, data tables).
82
+ - Imports: Types, Utils only. No hooks, no store.
83
+
84
+ ### App (`app/`)
85
+ - Next.js App Router pages and layouts — **routing only**.
86
+ - Pages render Feature components and trigger data fetches.
87
+ - Business logic lives in Features, not in pages.
88
+ - Imports: Features, Components only.
89
+
90
+ ### Utils (`src/utils/`)
91
+ - Pure, stateless TypeScript functions. Zero domain imports.
92
+ - 100% test coverage required.
93
+ - Examples: `formatDate.ts`, `cn.ts` (Tailwind class merger), `parseError.ts`
94
+
95
+ ---
96
+
97
+ ## Import Rules (ESLint enforces)
98
+
99
+ ```
100
+ Types → (nothing)
101
+ Lib → Types
102
+ Hooks → Types, Lib
103
+ Store → Types
104
+ Features → Types, Lib, Hooks, Store, Components, Utils
105
+ Components → Types, Utils
106
+ App → Features, Components
107
+ Utils → (nothing — stdlib only)
108
+ ```
109
+
110
+ **Forbidden:**
111
+ - `fetch()` in components, features, or pages (use hooks)
112
+ - `process.env` outside `src/lib/env.ts`
113
+ - Business logic in `app/` pages
114
+ - Editing `src/types/api.generated.ts` manually
115
+ - Storing access tokens in `localStorage` or `sessionStorage`
116
+ - `<img>` tags — use `next/image`
117
+
118
+ ---
119
+
120
+ ## Server Components vs Client Components
121
+
122
+ **Default: Server Component** (no directive needed)
123
+ - Pages that only render data
124
+ - Layout components
125
+ - Static content
126
+
127
+ **`'use client'` required when:**
128
+ - Using React hooks (`useState`, `useEffect`, `useRef`)
129
+ - Using browser APIs
130
+ - Using TanStack Query hooks (via `QueryClientProvider`)
131
+ - Using event handlers directly on interactive elements
132
+
133
+ **Rule:** Every `'use client'` directive must have a comment: `// Client: needs [reason]`
134
+
135
+ ---
136
+
137
+ ## Auth Token Strategy (matches backend)
138
+
139
+ The backend issues:
140
+ - **Access token** (JWT, 15 min) — sent as `Authorization: Bearer` header
141
+ - **Refresh token** (JWT, 7 days) — stored in `httpOnly` cookie by the backend
142
+
143
+ Frontend storage:
144
+ - Access token → React context/memory only. **Never localStorage.**
145
+ - Refresh token → Backend sets httpOnly cookie. Frontend never touches it.
146
+ - On 401 → call `/api/auth/refresh` → backend reads cookie, issues new access token.
147
+
148
+ ---
149
+
150
+ ## File Size Limit
151
+ - **400 lines max** per file
152
+ - Enforced by: PostToolUse hook + gate-checker
153
+
154
+ ---
155
+
156
+ ## Naming Conventions
157
+
158
+ | Layer | Pattern | Example |
159
+ |---|---|---|
160
+ | Hooks | `use-{domain}.ts` | `use-applications.ts` |
161
+ | Feature components | `{Domain}{Component}.tsx` | `ApplicationCard.tsx` |
162
+ | Shared components | `{Component}.tsx` | `DataTable.tsx` |
163
+ | Utils | `{name}.util.ts` | `format-date.util.ts` |
164
+ | Stores | `{domain}-store.ts` | `ui-store.ts` |
165
+ | Page | `page.tsx` | `app/(dashboard)/applications/page.tsx` |
@@ -0,0 +1,38 @@
1
+ # syntax=docker/dockerfile:1
2
+ # Multi-stage production image for the Next.js app.
3
+ # Requires `output: 'standalone'` in next.config.ts (the harness sets it).
4
+ # Result: a minimal image that runs as a non-root user with a healthcheck.
5
+ # Owned by the platform team (see .github/CODEOWNERS).
6
+
7
+ # ---- deps: reproducible install from the committed lockfile ----
8
+ FROM node:lts-bookworm-slim AS deps
9
+ WORKDIR /app
10
+ COPY package.json package-lock.json ./
11
+ RUN npm ci
12
+
13
+ # ---- builder: compile the app ----
14
+ FROM node:lts-bookworm-slim AS builder
15
+ WORKDIR /app
16
+ COPY --from=deps /app/node_modules ./node_modules
17
+ COPY . .
18
+ ENV NEXT_TELEMETRY_DISABLED=1
19
+ # NEXT_PUBLIC_* are inlined at build time. Override at build with --build-arg.
20
+ ARG NEXT_PUBLIC_API_URL=http://localhost:8000
21
+ ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
22
+ RUN npm run build
23
+
24
+ # ---- runner: copy only the standalone output, run as non-root ----
25
+ FROM node:lts-bookworm-slim AS runner
26
+ WORKDIR /app
27
+ ENV NODE_ENV=production
28
+ ENV NEXT_TELEMETRY_DISABLED=1
29
+ RUN mkdir .next && chown node:node .next
30
+ COPY --from=builder --chown=node:node /app/public ./public
31
+ COPY --from=builder --chown=node:node /app/.next/standalone ./
32
+ COPY --from=builder --chown=node:node /app/.next/static ./.next/static
33
+ USER node
34
+ EXPOSE 3000
35
+ ENV PORT=3000 HOSTNAME=0.0.0.0
36
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
37
+ CMD node -e "fetch('http://127.0.0.1:3000/').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
38
+ CMD ["node", "server.js"]
@@ -0,0 +1,50 @@
1
+ # Daily-driver targets — thin wrappers over the npm scripts so muscle memory works.
2
+ # Committed in the template (parked/restored by /infra-setup). Run `make help`.
3
+ # NOTE: recipes are TAB-indented (Make requirement).
4
+ .DEFAULT_GOAL := help
5
+ .PHONY: help setup dev build start lint format typecheck test coverage e2e gate api-sync analyze docker-build
6
+
7
+ help: ## List available targets
8
+ @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN{FS=":.*?## "}{printf " \033[36m%-14s\033[0m %s\n", $$1, $$2}'
9
+
10
+ setup: ## Phase 0 infra setup (run after the create-next-app scaffold step)
11
+ bash .claude/scripts/infra-setup.sh
12
+
13
+ dev: ## Run the dev server
14
+ npm run dev
15
+
16
+ build: ## Production build
17
+ npm run build
18
+
19
+ start: ## Start the production server
20
+ npm run start
21
+
22
+ lint: ## ESLint (flat config)
23
+ npm run lint
24
+
25
+ format: ## Prettier (write)
26
+ npm run format
27
+
28
+ typecheck: ## tsc --noEmit
29
+ npm run typecheck
30
+
31
+ test: ## Unit tests (watch)
32
+ npm run test
33
+
34
+ coverage: ## Unit tests + per-layer coverage gate
35
+ npm run test:coverage
36
+
37
+ e2e: ## Playwright end-to-end tests
38
+ npm run test:e2e
39
+
40
+ gate: ## Full layer gate (typecheck + lint + format:check + coverage)
41
+ npm run gate
42
+
43
+ api-sync: ## Regenerate API types from openapi.json
44
+ npm run api:sync
45
+
46
+ analyze: ## Bundle analysis
47
+ npm run analyze
48
+
49
+ docker-build: ## Build the production container image
50
+ docker build -t app:local .