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,87 @@
1
+ # AGENTS.md — Navigation Map
2
+
3
+ Stack: Python 3.14 · FastAPI 0.115 · SQLAlchemy 2 (async) · PostgreSQL · Redis · Celery · uv
4
+
5
+ ---
6
+
7
+ ## 🗺️ Where Everything Lives
8
+
9
+ | What you need | Where |
10
+ |---|---|
11
+ | Daily-driver commands | `Makefile` (`make bootstrap/dev/lint/test/gate/migrate/openapi`) |
12
+ | Runnable gate (same checks as gate-checker) | `scripts/gate.sh` (`make gate`) |
13
+ | Layer rules + dependency diagram | `ARCHITECTURE.md` |
14
+ | Engineering constitution (the WHY) | `docs/design-docs/core-beliefs.md` |
15
+ | Active execution plan | `docs/exec-plans/active/` |
16
+ | Completed plans (history) | `docs/exec-plans/completed/` |
17
+ | Product roadmap (epics → specs, dependency order) | `docs/product-specs/ROADMAP.md` |
18
+ | Product specs (draft) | `docs/product-specs/draft/` |
19
+ | Product specs (approved) | `docs/product-specs/ready/` |
20
+ | Architectural decisions (ADRs) | `docs/design-docs/decisions/` |
21
+ | Known tech debt | `docs/exec-plans/tech-debt-tracker.md` |
22
+ | Domain health grades | `docs/QUALITY_SCORE.md` |
23
+ | Plan format + lifecycle | `docs/PLANS.md` |
24
+ | Generated DB schema | `docs/generated/db-schema.md` |
25
+
26
+ ---
27
+
28
+ ## ⚡ Slash Commands
29
+
30
+ | Command | What it does |
31
+ |---|---|
32
+ | `/infra-setup` | Phase 0 — full infra scaffold (run once) |
33
+ | `/write-roadmap` | Turn a product brief into an ordered spec roadmap → `docs/product-specs/ROADMAP.md` |
34
+ | `/write-spec` | Write a product spec → `docs/product-specs/draft/` |
35
+ | `/write-plan` | Turn a READY spec into an execution plan |
36
+ | `/build-layer` | Build next unchecked layer from active plan + run gate |
37
+ | `/validate-layer` | Run gate check on current layer without building |
38
+ | `/push-layer` | Commit + push current layer with conventional message |
39
+ | `/layer-check` | Ad-hoc architecture violation scan |
40
+ | `/garbage-collect` | End-of-feature cleanup pass |
41
+ | `/doc-garden` | Scan + fix stale documentation |
42
+ | `/db-optimize` | EXPLAIN ANALYZE workflow for slow queries |
43
+ | `/load-test` | Run k6 smoke / stress / soak test |
44
+
45
+ ---
46
+
47
+ ## 🤖 Agents
48
+
49
+ | Agent | When to use |
50
+ |---|---|
51
+ | `gate-checker` | Called automatically by `/build-layer` — PASS/FAIL per layer |
52
+ | `reviewer` | Before opening a PR — full harness review |
53
+ | `arch-validator` | Deep import + layer compliance scan |
54
+ | `db-optimizer` | N+1, missing index, pagination audit on repo layer |
55
+ | `security-auditor` | OWASP Top 10 review — run before any auth/payment PR |
56
+ | `doc-gardener` | Use the `/doc-garden` skill |
57
+ | `garbage-collector` | Use the `/garbage-collect` skill |
58
+
59
+ ---
60
+
61
+ ## ✅ Non-Negotiable Invariants
62
+
63
+ - No `print()` → use `logger` from `src/providers/logger.py`
64
+ - No `os.environ` outside `src/config/settings.py`
65
+ - No raw dict cast on SQLAlchemy results → `Model.model_validate(row.__dict__)` only
66
+ - No file > 400 lines → split into focused modules
67
+ - No cross-layer imports → enforced by `ruff` + structural tests
68
+ - Every DB query result → `PydanticSchema.model_validate()`
69
+ - Every list endpoint → cursor-based pagination
70
+ - Every protected route → `Depends(require_auth)` as first dependency
71
+ - Every external call → `tenacity` retry + timeout
72
+ - All tests pass before `/push-layer`
73
+ - `raise HTTPException` only in runtime layer — never in service layer
74
+
75
+ ---
76
+
77
+ ## 🔁 The Flow
78
+
79
+ ```
80
+ # Whole product (run once at the start):
81
+ /write-roadmap → human reviews ROADMAP → pick the walking-skeleton spec
82
+
83
+ # Every feature (repeat down the roadmap):
84
+ /write-spec (roadmap-guided) → human marks READY → /write-plan
85
+ → /build-layer (repeats, gate-enforced)
86
+ → /garbage-collect → plan closed
87
+ ```
@@ -0,0 +1,141 @@
1
+ # ARCHITECTURE.md — Layered Architecture
2
+
3
+ Stack: Python 3.14 · FastAPI 0.115 · SQLAlchemy 2 (async) · Alembic · PostgreSQL · Redis · Celery
4
+
5
+ ---
6
+
7
+ ## Dependency Layer Diagram
8
+
9
+ ```
10
+ ┌──────────────────────────────────────────────────────────┐
11
+ │ Utils — stateless helpers, zero domain imports │
12
+ │ 100% test coverage required │
13
+ └───────────────────────┬──────────────────────────────────┘
14
+ │ (imported by all layers below)
15
+ ┌───────────────────────▼──────────────────────────────────┐
16
+ │ │
17
+ │ Types ──► Config ──► Models ──► Repo │
18
+ │ │ │
19
+ │ ▼ │
20
+ │ Service │
21
+ │ │ │
22
+ │ ▼ │
23
+ │ Runtime { Routers · Workers } │
24
+ │ │
25
+ │ Providers (auth, logger, db session, redis, telemetry) │
26
+ │ └─ enter domain via FastAPI Depends() only │
27
+ │ │
28
+ └───────────────────────────────────────────────────────────┘
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Layer Definitions
34
+
35
+ ### Types (`src/types/`)
36
+ - Pure Pydantic `BaseModel` schemas, enums, TypedDicts
37
+ - **Zero imports** from other layers
38
+ - **Zero logic** — only field definitions and validators
39
+ - Examples: `ApplicationStage`, `CreateApplicationInput`, `PageResult[T]`
40
+
41
+ ### Config (`src/config/`)
42
+ - `pydantic-settings` `BaseSettings` — typed, validated on startup
43
+ - Imports: **Types only**
44
+ - `settings.py` raises `ValidationError` on bad env → process never starts
45
+ - Examples: `settings.py`, `constants.py`, `timeouts.py`
46
+
47
+ ### Models (`src/models/`)
48
+ - SQLAlchemy 2 ORM model classes — schema only, no logic
49
+ - Imports: **Types, Config**
50
+ - All models: `__mapper_args__` soft delete pattern, `uuid7()` default on id
51
+ - Indexes defined in model `__table_args__`
52
+ - Examples: `user.py`, `application.py`
53
+
54
+ ### Repo (`src/repo/`)
55
+ - Async DB access **and** outbound external-API gateways (`*_gateway.py`, httpx + tenacity). All output validated with Pydantic.
56
+ - This is the home for "external APIs go via Repo" — services never make inline HTTP calls.
57
+ - Imports: **Types, Config, Models**
58
+ - **Every** query/response result: `Schema.model_validate(row.__dict__)`
59
+ - All list methods: cursor-based pagination (`WHERE created_at < :cursor`)
60
+ - Ownership enforced: `WHERE id = :id AND user_id = :user_id`
61
+ - Examples: `user_repo.py`, `application_repo.py`
62
+
63
+ ### Service (`src/services/`)
64
+ - Business logic and use-case orchestration
65
+ - Imports: **Types, Config, Repo**
66
+ - **No** `Request`, `HTTPException`, `fastapi` imports
67
+ - **No** inline HTTP calls — external APIs go via Repo
68
+ - `raise DomainError(...)` — never `raise HTTPException`
69
+ - Examples: `application_service.py`, `auth_service.py`
70
+
71
+ ### Runtime (`src/runtime/`)
72
+ - FastAPI routers, Celery workers, CLI entry points
73
+ - Imports: **Types, Config, Repo, Service**
74
+ - Routes: `Depends(require_auth)` first, then validate, then service, then respond
75
+ - Thin layer — zero business logic
76
+ - Maps `DomainError` → `HTTPException` in exception handlers
77
+ - Examples: `routers/v1/applications.py`, `workers/reminder_worker.py`
78
+
79
+ ### Providers (`src/providers/`)
80
+ - Cross-cutting: logger, db session factory, redis, auth, telemetry
81
+ - Injected via FastAPI `Depends()` — never imported directly by Service
82
+ - Examples: `logger.py`, `database.py`, `auth/jwt.py`
83
+
84
+ ### Utils (`src/utils/`)
85
+ - Stateless helpers — **zero domain imports**
86
+ - **100% test coverage** required
87
+ - Examples: `retry.py`, `pagination.py`, `uuid_util.py`
88
+
89
+ ---
90
+
91
+ ## Allowed Imports (strict — ruff enforces)
92
+
93
+ ```
94
+ Types → (nothing)
95
+ Config → Types
96
+ Models → Types, Config
97
+ Repo → Types, Config, Models
98
+ Service → Types, Config, Repo
99
+ Runtime → Types, Config, Repo, Service
100
+ Utils → (nothing)
101
+ Providers → Types, Config only
102
+ ```
103
+
104
+ **Forbidden:**
105
+ - Service importing `fastapi`, `HTTPException`, or anything from Runtime
106
+ - Repo containing business logic (if/else beyond null checks)
107
+ - Utils importing any domain layer
108
+ - Circular imports of any kind
109
+ - `os.environ` outside `src/config/settings.py`
110
+
111
+ ---
112
+
113
+ ## File Size Limit
114
+ - **400 lines maximum** per file
115
+ - Enforced by: PostToolUse hook + gate-checker agent
116
+
117
+ ---
118
+
119
+ ## Naming Conventions
120
+
121
+ | Layer | Pattern | Example |
122
+ |---|---|---|
123
+ | Types | `*_schema.py` or `*_types.py` | `application_schema.py` |
124
+ | Config | `settings.py`, `constants.py` | `settings.py` |
125
+ | Models | `*.py` in `models/` | `application.py` |
126
+ | Repo | `*_repo.py` | `application_repo.py` |
127
+ | Service | `*_service.py` | `application_service.py` |
128
+ | Router | `*.py` in `routers/v1/` | `applications.py` |
129
+ | Worker | `*_worker.py` | `reminder_worker.py` |
130
+ | Utils | `*_util.py` | `retry_util.py` |
131
+ | Pydantic schemas | `PascalCase` | `ApplicationResponse` |
132
+
133
+ ---
134
+
135
+ ## Mechanical Enforcement Stack
136
+
137
+ 1. **ruff rules** — `no-os-environ`, `no-cross-layer-import`, `no-print`
138
+ 2. **PostToolUse hooks** — fire on every file write (size, print, os.environ)
139
+ 3. **Structural tests** — `tests/architecture/test_layers.py` — fails CI on violations
140
+ 4. **gate-checker agent** — PASS required before every commit
141
+ 5. **mypy** — strict type checking on every CI run
@@ -0,0 +1,42 @@
1
+ # Makefile — single-command developer experience for the FastAPI harness.
2
+ # Every command in the docs goes through a target here so humans and agents
3
+ # run the exact same thing. Generated/maintained alongside /infra-setup.
4
+
5
+ .PHONY: bootstrap dev lint format typecheck test gate migrate openapi up down lgtm
6
+
7
+ bootstrap: ## one-command setup: sync deps + install git hooks
8
+ uv sync && uv run pre-commit install
9
+
10
+ dev: ## run the API with autoreload
11
+ uv run uvicorn src.runtime.main:app --reload
12
+
13
+ lint: ## ruff lint
14
+ uv run ruff check src/ tests/
15
+
16
+ format: ## ruff format (writes)
17
+ uv run ruff format src/ tests/
18
+
19
+ typecheck: ## mypy strict
20
+ uv run mypy src/
21
+
22
+ test: ## full test suite + coverage
23
+ uv run pytest
24
+
25
+ gate: ## deterministic gate — same checks the gate-checker agent runs
26
+ bash scripts/gate.sh
27
+
28
+ migrate: ## apply migrations
29
+ uv run alembic upgrade head
30
+
31
+ openapi: ## export OpenAPI spec to openapi.json (loads .env if present so settings validate)
32
+ set -a; [ -f .env ] && . ./.env; set +a; \
33
+ uv run python -c "import json,sys; from src.runtime.main import app; json.dump(app.openapi(), sys.stdout)" > openapi.json
34
+
35
+ up: ## start local stack (app + postgres + redis)
36
+ docker compose up -d
37
+
38
+ down: ## stop local stack
39
+ docker compose down
40
+
41
+ lgtm: ## start local observability stack (Grafana/Loki/Tempo/Prometheus)
42
+ docker compose -f infra/monitoring/docker-compose.lgtm.yml up -d
@@ -0,0 +1,179 @@
1
+ # FastAPI Agent Template
2
+
3
+ Production-ready FastAPI template with layered architecture, SQLAlchemy 2 async, OpenTelemetry, and full agent harness for spec → plan → build → test → deploy workflow.
4
+
5
+ ---
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ # Initialize new project
11
+ /infra-setup
12
+
13
+ # Plan a whole product (run before /write-spec)
14
+ /write-roadmap # → docs/product-specs/ROADMAP.md (brief → ordered, dependency-aware specs)
15
+
16
+ # Build a feature
17
+ /write-spec # → docs/product-specs/draft/ (roadmap-guided)
18
+ /write-plan # → docs/exec-plans/active/
19
+ /build-layer # → auto-build + gate + commit + push (one layer at a time)
20
+
21
+ # Quality gates
22
+ /validate-layer # Run gate without building
23
+ /layer-check # Ad-hoc architecture violation scan
24
+ /db-optimize # N+1 query detection, missing indexes
25
+ /load-test smoke # k6 performance test
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Stack
31
+
32
+ | Category | Packages |
33
+ |---|---|
34
+ | **Runtime** | Python 3.14, FastAPI 0.115, uvicorn[standard] 0.32 |
35
+ | **ORM** | SQLAlchemy 2 (async), Alembic, asyncpg |
36
+ | **Auth** | PyJWT[crypto] 2.9, pwdlib[argon2] 0.2, argon2-cffi |
37
+ | **Queue** | Celery 5, Redis 5 |
38
+ | **Logging** | structlog 24 |
39
+ | **Tracing** | opentelemetry-sdk, opentelemetry-instrumentation-fastapi, prometheus-fastapi-instrumentator |
40
+ | **Validation** | pydantic 2, pydantic-settings 2, email-validator |
41
+ | **HTTP Client** | httpx, tenacity |
42
+ | **Rate Limit** | slowapi, limits (Redis store) |
43
+ | **Testing** | pytest 8, pytest-asyncio, pytest-cov, httpx AsyncClient, factory-boy, faker |
44
+ | **Security** | bandit |
45
+ | **Tooling** | uv, ruff, mypy, pre-commit |
46
+
47
+ ---
48
+
49
+ ## ✅ Key Features
50
+
51
+ - **Layered architecture** enforced by ruff + AST structural tests
52
+ - **Pydantic v2 validation** at every DB boundary (`model_validate` required)
53
+ - **Structured JSON logging** with PII redaction (structlog)
54
+ - **OpenTelemetry** instrumentation (FastAPI + SQLAlchemy)
55
+ - **Rate limiting** with Redis store (3 tiers: auth, public, user)
56
+ - **Cursor pagination** with opaque base64url tokens (no leaking impl details)
57
+ - **Response envelopes** standardized: `{ ok, data, meta }` success, `{ ok: false, error, meta }` errors
58
+ - **Security headers** middleware (7 headers: CSP, HSTS, X-Frame-Options, etc.)
59
+ - **GDPR deletion** utility (anonymize PII, hard-delete sensitive, keep audit)
60
+ - **Audit logging** utility (who, what, resource, timestamp)
61
+ - **Cross-user isolation** tests (404 not 403 — don't leak resource existence)
62
+ - **k6 load tests** (smoke + stress with P95/P99 budgets enforced in CI)
63
+ - **schemathesis** OpenAPI contract/fuzz tests against `/openapi.json`
64
+ - **Multi-stage Dockerfile** + `.dockerignore` (non-root user, HEALTHCHECK)
65
+ - **GitHub Actions CI** — parallel jobs: quality (ruff + mypy), test (pytest + schemathesis), security (bandit + pip-audit + gitleaks), image (Trivy scan + SBOM)
66
+ - **Dependabot** (uv + GitHub Actions + Docker)
67
+ - **Makefile** single-command DX (`make bootstrap/dev/lint/test/gate/migrate/openapi`) + runnable `scripts/gate.sh`
68
+ - **Agent-first workflow** (spec → plan → build loop with auto-gating)
69
+
70
+ ---
71
+
72
+ ## Why `>=` Version Bounds?
73
+
74
+ All dependencies use `>=` (no upper bounds):
75
+
76
+ ```toml
77
+ fastapi = ">=0.115"
78
+ pydantic = ">=2.0"
79
+ ```
80
+
81
+ **Reasoning:**
82
+
83
+ - `uv.lock` pins exact versions for reproducible builds (lock file does the pinning)
84
+ - Upper bounds cause **dependency hell** in libraries (if lib A pins `pydantic<3` and lib B pins `pydantic<2.5`, they're incompatible)
85
+ - Security updates apply immediately via `uv sync --upgrade` (no waiting for maintainer to bump upper bound)
86
+ - Dependabot raises weekly PRs that bump `uv.lock` and re-run the full CI gate, so updates are reviewed, not blind
87
+ - Lockfile-first dependency management (pin the lock, range the manifest) is standard modern practice
88
+
89
+ This is the same strategy as Rust (Cargo.toml) and modern Python packaging (PEP 440 discourages upper bounds).
90
+
91
+ ---
92
+
93
+ ## Architecture Layers
94
+
95
+ ```
96
+ src/
97
+ ├── types/ # Domain exceptions, common types (no imports allowed)
98
+ ├── config/ # Settings, constants, timeouts (pydantic-settings)
99
+ ├── models/ # SQLAlchemy models (ORM only)
100
+ ├── repo/ # DB queries, cursor pagination, ownership filters
101
+ ├── services/ # Business logic (raise DomainError, never HTTPException)
102
+ ├── utils/ # Pure functions (no domain imports)
103
+ ├── providers/ # External integrations (DB, Redis, auth, logger, telemetry)
104
+ └── runtime/ # FastAPI routers, middleware, exception handlers
105
+ ```
106
+
107
+ **Enforced by:**
108
+
109
+ - ruff import rules
110
+ - `tests/architecture/test_layers.py` (AST-based structural tests)
111
+ - post-write hook (catches `print()`, `os.environ`, HTTPException in services)
112
+
113
+ ---
114
+
115
+ ## Project Files
116
+
117
+ | File | Purpose |
118
+ |---|---|
119
+ | `ARCHITECTURE.md` | Layer rules + dependency graph |
120
+ | `AGENTS.md` | Navigation map for agents (which files do what) |
121
+ | `.claude/CLAUDE.md` | Agent entry point (read first on every session) |
122
+ | `.claude/rules/*.md` | Path-scoped rules (auto-injected based on file being edited) |
123
+ | `.claude/skills/*.md` | Slash commands (`/infra-setup`, `/build-layer`, etc.) |
124
+ | `docs/product-specs/ROADMAP.md` | Whole-product spec roadmap (epics, dependency order, walking skeleton) |
125
+ | `docs/exec-plans/active/` | Current execution plan (checked boxes = done) |
126
+ | `docs/design-docs/decisions/` | ADRs (Architecture Decision Records) |
127
+ | `docs/product-specs/ready/` | Approved specs ready for implementation |
128
+
129
+ ---
130
+
131
+ ## OpenAPI → Frontend Sync
132
+
133
+ FastAPI auto-generates OpenAPI spec at `GET /openapi.json`. To sync with frontend:
134
+
135
+ ```bash
136
+ # 1. Export the OpenAPI spec (no running server needed)
137
+ make openapi # → openapi.json (app.openapi() dumped to file)
138
+
139
+ # 2. In frontend repo
140
+ /api-sync # generates TypeScript types from openapi.json
141
+ ```
142
+
143
+ This keeps frontend types in sync with backend contract.
144
+
145
+ ---
146
+
147
+ ## Celery vs arq
148
+
149
+ Template uses **Celery 5** by default. Trade-offs:
150
+
151
+ | Feature | Celery | arq |
152
+ |---|---|---|
153
+ | **Async support** | Sync-first (requires `asyncio.run()` wrapper) | Native async |
154
+ | **Scheduling** | Beat (cron-like) | None (use external scheduler) |
155
+ | **Workflows** | Chain, chord, group primitives | Manual composition |
156
+ | **Ecosystem** | Large (flower, django-celery, etc.) | Small (Pydantic team only) |
157
+ | **Type safety** | Manual | Built-in (Pydantic v2) |
158
+
159
+ **When to use arq:** If you don't need beat scheduling or chord/chain and want native async + type safety, consider arq.
160
+
161
+ **Decision documented in:** `docs/design-docs/decisions/ADR-000-infrastructure.md` (scaffolded by `/infra-setup`)
162
+
163
+ ---
164
+
165
+ ## License
166
+
167
+ MIT (or your org's standard license)
168
+
169
+ ---
170
+
171
+ ## Contributing
172
+
173
+ This is a template repository. To update:
174
+
175
+ 1. Edit `.claude/skills/*.md` (skill scaffolds)
176
+ 2. Edit `.claude/rules/*.md` (path-scoped rules)
177
+ 3. Edit `CLAUDE.md`, `ARCHITECTURE.md`, `AGENTS.md` (agent context)
178
+ 4. Update `Verified:` headers on skills when libraries change
179
+ 5. Run staleness detection: if `Verified:` date > 60 days, fetch current docs via `ctx7`
@@ -0,0 +1,26 @@
1
+ # PLANS.md — Execution Plan Format
2
+
3
+ ## Roadmap → Specs (the altitude above plans)
4
+ /write-roadmap creates → docs/product-specs/ROADMAP.md (epics → dependency-ordered specs).
5
+ The roadmap plans the SET of specs for a whole product; /write-spec then authors each one.
6
+ A single spec may span MULTIPLE plans — slice a big spec into shippable milestones, each its own
7
+ PLAN-XXX. The spec's `**Plan:**` field then lists them all (e.g. `PLAN-003, PLAN-007`).
8
+
9
+ ## Lifecycle
10
+ /write-plan creates → docs/exec-plans/active/PLAN-XXX.md [IN_PROGRESS]
11
+ → layers built one by one, checkboxes ticked
12
+ → /garbage-collect closes → docs/exec-plans/completed/ [COMPLETE]
13
+
14
+ Plans are NEVER deleted. They are the project memory.
15
+
16
+ ## Plan Template
17
+ See any file in docs/exec-plans/ for the full template.
18
+
19
+ ## Escalation Rule
20
+ Escalate to human only when judgment is required:
21
+ - Ambiguous acceptance criteria
22
+ - Conflicting requirements
23
+ - Security decision with no established pattern
24
+ - Performance budget impossible without architecture change
25
+
26
+ Never escalate for: linter failures, test failures, technical unknowns — fix those.
@@ -0,0 +1,26 @@
1
+ # QUALITY_SCORE.md — Domain Health Grades
2
+
3
+ Updated by /garbage-collect after every feature.
4
+
5
+ ## Grading Rubric
6
+ | Grade | Meaning |
7
+ |---|---|
8
+ | A | All invariants met, ≥ 90% coverage, zero known debt |
9
+ | B | Minor issues, ≥ 80% coverage, low-priority debt logged |
10
+ | C | Layer violation OR < 80% coverage OR unresolved medium debt |
11
+ | D | Multiple violations, < 70% coverage, active bugs |
12
+ | F | Blocking issues, data integrity risk, security concern |
13
+
14
+ ## Architecture Health
15
+ | Check | Status |
16
+ |---|---|
17
+ | No circular imports | — |
18
+ | No files > 400 lines | — |
19
+ | No os.environ outside config | — |
20
+ | No print() in src/ | — |
21
+ | Utils: 100% test coverage | — |
22
+
23
+ ## Domain Grades
24
+ | Domain | Grade | Coverage | Last Updated | Notes |
25
+ |---|---|---|---|---|
26
+ | *(no domains yet)* | — | — | — | — |
@@ -0,0 +1,46 @@
1
+ # Core Beliefs — The Engineering Constitution
2
+
3
+ Rules without reasons get bent under pressure.
4
+ This document explains the WHY behind every constraint in this harness.
5
+
6
+ ---
7
+
8
+ ## 1. The Repo Is Reality
9
+ If a decision isn't written here, it doesn't exist. Verbal agreements and Slack messages are invisible to agents and future engineers.
10
+ **Consequence:** Every decision → ADR. Every product → ROADMAP.md. Every intent → spec. Every plan → PLAN-XXX.md.
11
+
12
+ ## 2. Enforce Mechanically, Not Aspirationally
13
+ A ruff rule that blocks CI is worth ten documentation paragraphs. Agents respond to linter output.
14
+ **Consequence:** Every constraint is a ruff rule, a structural test, or a hook — not just a doc.
15
+
16
+ ## 3. Agents Execute. Humans Steer.
17
+ Human attention is the scarcest resource. Optimize everything around preserving it.
18
+ **Consequence:** Maximum agent autonomy. Escalate only when judgment is needed.
19
+
20
+ ## 4. Layers Protect Business Logic
21
+ Service layer is pure business logic. No HTTP, no FastAPI, no ORM models. It receives an injected `AsyncSession` and orchestrates repos — testable against a real test session, no web-layer mocks.
22
+ **Consequence:** `raise HTTPException` only in runtime. Services raise `DomainError`. ORM models and `session.add` live only in the repo layer.
23
+
24
+ ## 5. External Data Is Adversarial Until Validated
25
+ SQLAlchemy row `__dict__` is untyped. Pydantic `model_validate()` is the gate.
26
+ **Consequence:** `Schema.model_validate(row.__dict__)` at every repo boundary. No raw dicts.
27
+
28
+ ## 6. Observability Is Not Optional
29
+ Structured logs + traces are the only way to reproduce production bugs autonomously.
30
+ **Consequence:** structlog on every service boundary. OTel spans on every DB query.
31
+
32
+ ## 7. Gate Before Commit — Always
33
+ Every layer gated before commit. Auto-fix enabled — no reason to leave violations in.
34
+ **Consequence:** gate-checker runs after every layer. PASS required before push.
35
+
36
+ ## 8. Small, Boring, Legible
37
+ 400 lines max. Well-known libraries. No premature abstraction.
38
+ **Consequence:** uv, FastAPI, SQLAlchemy — widely used, well-documented, excellent agent training data.
39
+
40
+ ## 9. Technical Debt Is a High-Interest Loan
41
+ Log debt immediately. Pay it in small daily amounts.
42
+ **Consequence:** tech-debt-tracker.md updated after every feature. Garbage collect after every plan.
43
+
44
+ ## 10. The Fix Is Never "Try Harder"
45
+ Repeated failures indicate a missing capability — tool, constraint, or abstraction.
46
+ **Consequence:** Diagnose → build the capability → solve permanently.
@@ -0,0 +1,79 @@
1
+ # ADR-000 — Infrastructure & Stack Choices
2
+
3
+ **Status:** ACCEPTED
4
+ **Date:** *(fill when /infra-setup is run)*
5
+ **Plan:** Phase 0
6
+
7
+ ---
8
+
9
+ ## Context
10
+ Starting a new Python backend project. Stack choices made here are expensive to change.
11
+
12
+ ---
13
+
14
+ ## Decisions
15
+
16
+ ### Runtime: Python 3.14 + FastAPI 0.115
17
+ - Python 3.14 is the latest stable (released Oct 2025) — improved performance, better typing
18
+ - FastAPI: async-native, auto OpenAPI, Pydantic v2 integration, best-in-class DX
19
+ - Alternatives rejected: Flask (no async-native), Django (too opinionated for API-only)
20
+
21
+ ### ORM: SQLAlchemy 2 (async) + Alembic
22
+ - SQLAlchemy 2 has proper async support (not bolted on)
23
+ - `asyncpg` driver — fastest async PostgreSQL driver available
24
+ - Alembic is SQLAlchemy's own migration tool — tight integration
25
+ - Alternatives rejected: Tortoise ORM (less mature), SQLModel (thin wrapper, less control)
26
+
27
+ ### Validation: Pydantic v2
28
+ - FastAPI's native schema layer — zero friction integration
29
+ - v2 is 5-17x faster than v1 (Rust core)
30
+ - Used at every external data boundary via `model_validate()`
31
+
32
+ ### Auth: PyJWT[crypto] + pwdlib[argon2]
33
+ - PyJWT: FastAPI's official recommendation, actively maintained, RS256/HS256 support
34
+ - pwdlib (`PasswordHash.recommended()` → argon2id): created by the FastAPI Users maintainer, Python 3.13+ compatible
35
+ - argon2id: OWASP-recommended, winner of the Password Hashing Competition — GPU-resistant
36
+ - Alternatives rejected:
37
+ - python-jose (abandoned — last release 2023, open CVEs)
38
+ - passlib (BROKEN on Python 3.13+ — `crypt` module removed in 3.13)
39
+ - bcrypt directly (GPU-vulnerable vs argon2id)
40
+
41
+ ### Queue: Celery 5 + Redis
42
+ - Most mature Python task queue — battle-tested at scale
43
+ - Redis broker: same Redis instance used for caching and rate limiting
44
+ - Alternatives considered: dramatiq (simpler but less ecosystem), RQ (less features)
45
+
46
+ ### Logging: structlog 24
47
+ - Structured JSON logging — equivalent of pino for Python
48
+ - Built-in context binding, redaction, async support
49
+ - Alternatives rejected: loguru (less structured), standard logging (no structured output)
50
+
51
+ ### Rate Limiting: slowapi + limits (Redis store)
52
+ - slowapi: FastAPI-native rate limiting via Depends()
53
+ - Redis store: distributed — works across multiple uvicorn workers
54
+ - Alternatives: custom middleware (more work, same result)
55
+
56
+ ### Package Manager: uv
57
+ - 10-100x faster than pip
58
+ - Manages Python version + virtualenv + dependencies in one tool
59
+ - Replaces: pip, pip-tools, pyenv, virtualenv
60
+ - Lockfile (`uv.lock`) committed for reproducible installs
61
+
62
+ ### Linter/Formatter: ruff
63
+ - Replaces: flake8 + black + isort + pyupgrade in one tool
64
+ - Written in Rust — 10-100x faster than alternatives
65
+ - Single config in `pyproject.toml`
66
+
67
+ ### PgBouncer
68
+ - NOT in application code — infrastructure concern
69
+ - Uncomment in `docker-compose.yml` when concurrent users > 50
70
+ - App connects to PgBouncer (port 6432), PgBouncer connects to PostgreSQL
71
+
72
+ ---
73
+
74
+ ## Consequences
75
+ - FastAPI async: all DB calls must be `await session.execute(...)` — no sync ORM calls
76
+ - SQLAlchemy async: sessions are NOT thread-safe — inject via `Depends(get_session)`, never share
77
+ - Celery: sync tasks (Celery is sync by default) — use `asyncio.run()` inside tasks for async calls
78
+ - PyJWT: stateless tokens — revocation requires a Redis denylist check on every verify
79
+ - argon2id (pwdlib): intentionally slow — login endpoint will be slower than bcrypt (~200ms vs ~100ms)
@@ -0,0 +1,7 @@
1
+ # ADR Index
2
+
3
+ | ID | Title | Status | Date | Plan |
4
+ |---|---|---|---|---|
5
+ | ADR-000 | Infrastructure & Stack Choices | ACCEPTED | *(fill on /infra-setup)* | — |
6
+
7
+ Add a row here after every new ADR.
@@ -0,0 +1,9 @@
1
+ # Design Docs Index
2
+
3
+ | Document | Purpose |
4
+ |---|---|
5
+ | core-beliefs.md | Engineering constitution — WHY every rule exists |
6
+ | decisions/index.md | ADR registry |
7
+ | decisions/ADR-000-infrastructure.md | Stack choices and rationale |
8
+
9
+ Add a row here when creating a new design doc or ADR.
@@ -0,0 +1,19 @@
1
+ # Technical Debt Tracker
2
+
3
+ ## Severity
4
+ | Level | Fix by |
5
+ |---|---|
6
+ | P0 | Immediately — security/data integrity |
7
+ | P1 | Within 2 sprints — blocks features |
8
+ | P2 | Within quarter — degrades quality |
9
+ | P3 | When in area — code smell |
10
+
11
+ ## Open Debt
12
+ | ID | Severity | Area | Description | Created By | Date |
13
+ |---|---|---|---|---|---|
14
+ | *(none yet)* | — | — | — | — | — |
15
+
16
+ ## Resolved Debt
17
+ | ID | Description | Resolved By | Date |
18
+ |---|---|---|---|
19
+ | *(none yet)* | — | — | — |
File without changes