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,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,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,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 .
|