@dewtech/dare-cli 3.3.0 → 3.4.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 (582) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +764 -764
  3. package/dist/__tests__/confidence.test.js +13 -13
  4. package/dist/__tests__/dag-converter.test.js +56 -56
  5. package/dist/__tests__/mcp-server/server.test.js +3 -16
  6. package/dist/__tests__/mcp-server/server.test.js.map +1 -1
  7. package/dist/__tests__/project-generator.test.js +2 -2
  8. package/dist/__tests__/project-generator.test.js.map +1 -1
  9. package/dist/__tests__/refine.test.js +49 -49
  10. package/dist/__tests__/reverse-collection.test.js +6 -6
  11. package/dist/__tests__/review.test.js +38 -38
  12. package/dist/__tests__/security-hardening.test.d.ts +2 -0
  13. package/dist/__tests__/security-hardening.test.d.ts.map +1 -0
  14. package/dist/__tests__/security-hardening.test.js +101 -0
  15. package/dist/__tests__/security-hardening.test.js.map +1 -0
  16. package/dist/__tests__/validate.test.js +65 -65
  17. package/dist/bin/dare.js +0 -0
  18. package/dist/commands/__tests__/init-validation.test.d.ts +2 -0
  19. package/dist/commands/__tests__/init-validation.test.d.ts.map +1 -0
  20. package/dist/commands/__tests__/init-validation.test.js +81 -0
  21. package/dist/commands/__tests__/init-validation.test.js.map +1 -0
  22. package/dist/commands/__tests__/init.integration.spec.js +6 -4
  23. package/dist/commands/__tests__/init.integration.spec.js.map +1 -1
  24. package/dist/commands/__tests__/init.spec.d.ts +2 -0
  25. package/dist/commands/__tests__/init.spec.d.ts.map +1 -0
  26. package/dist/commands/__tests__/init.spec.js +88 -0
  27. package/dist/commands/__tests__/init.spec.js.map +1 -0
  28. package/dist/commands/blueprint.js +122 -122
  29. package/dist/commands/design.js +20 -20
  30. package/dist/commands/init-validation.d.ts +22 -0
  31. package/dist/commands/init-validation.d.ts.map +1 -0
  32. package/dist/commands/init-validation.js +54 -0
  33. package/dist/commands/init-validation.js.map +1 -0
  34. package/dist/commands/init.d.ts.map +1 -1
  35. package/dist/commands/init.js +26 -10
  36. package/dist/commands/init.js.map +1 -1
  37. package/dist/graphrag/graph-rag.js +24 -24
  38. package/dist/mcp-server/__tests__/auth.test.d.ts +2 -0
  39. package/dist/mcp-server/__tests__/auth.test.d.ts.map +1 -0
  40. package/dist/mcp-server/__tests__/auth.test.js +72 -0
  41. package/dist/mcp-server/__tests__/auth.test.js.map +1 -0
  42. package/dist/mcp-server/__tests__/boot-config.test.d.ts +2 -0
  43. package/dist/mcp-server/__tests__/boot-config.test.d.ts.map +1 -0
  44. package/dist/mcp-server/__tests__/boot-config.test.js +29 -0
  45. package/dist/mcp-server/__tests__/boot-config.test.js.map +1 -0
  46. package/dist/mcp-server/__tests__/error-sanitize.test.d.ts +2 -0
  47. package/dist/mcp-server/__tests__/error-sanitize.test.d.ts.map +1 -0
  48. package/dist/mcp-server/__tests__/error-sanitize.test.js +66 -0
  49. package/dist/mcp-server/__tests__/error-sanitize.test.js.map +1 -0
  50. package/dist/mcp-server/__tests__/path-confinement.test.d.ts +2 -0
  51. package/dist/mcp-server/__tests__/path-confinement.test.d.ts.map +1 -0
  52. package/dist/mcp-server/__tests__/path-confinement.test.js +135 -0
  53. package/dist/mcp-server/__tests__/path-confinement.test.js.map +1 -0
  54. package/dist/mcp-server/bin/server.js +18 -6
  55. package/dist/mcp-server/bin/server.js.map +1 -1
  56. package/dist/mcp-server/boot-config.d.ts +6 -0
  57. package/dist/mcp-server/boot-config.d.ts.map +1 -0
  58. package/dist/mcp-server/boot-config.js +17 -0
  59. package/dist/mcp-server/boot-config.js.map +1 -0
  60. package/dist/mcp-server/middleware/auth.d.ts +10 -0
  61. package/dist/mcp-server/middleware/auth.d.ts.map +1 -0
  62. package/dist/mcp-server/middleware/auth.js +44 -0
  63. package/dist/mcp-server/middleware/auth.js.map +1 -0
  64. package/dist/mcp-server/middleware/cors.d.ts +6 -0
  65. package/dist/mcp-server/middleware/cors.d.ts.map +1 -0
  66. package/dist/mcp-server/middleware/cors.js +30 -0
  67. package/dist/mcp-server/middleware/cors.js.map +1 -0
  68. package/dist/mcp-server/middleware/error-handler.d.ts +11 -0
  69. package/dist/mcp-server/middleware/error-handler.d.ts.map +1 -0
  70. package/dist/mcp-server/middleware/error-handler.js +14 -0
  71. package/dist/mcp-server/middleware/error-handler.js.map +1 -0
  72. package/dist/mcp-server/server.d.ts +7 -2
  73. package/dist/mcp-server/server.d.ts.map +1 -1
  74. package/dist/mcp-server/server.js +185 -105
  75. package/dist/mcp-server/server.js.map +1 -1
  76. package/dist/skills/registry-mock.json +109 -109
  77. package/dist/skills/tests/manifest.spec.js +20 -20
  78. package/dist/stacks/__tests__/dna-emitter.spec.js +6 -6
  79. package/dist/stacks/dna-emitter.js +69 -69
  80. package/dist/stacks/ruby-rails-8/scaffold.js +15 -15
  81. package/dist/utils/project-generator.d.ts.map +1 -1
  82. package/dist/utils/project-generator.js +254 -252
  83. package/dist/utils/project-generator.js.map +1 -1
  84. package/dist/utils/stack-bootstrap.js +371 -371
  85. package/dist/utils/templates.js +394 -394
  86. package/dist/verification/__tests__/anti-tamper.test.js +13 -13
  87. package/package.json +96 -93
  88. package/templates/DARE-dag-example.yaml +280 -280
  89. package/templates/UPDATE-MANIFEST.json +68 -68
  90. package/templates/backend/node-nestjs/.env.example +9 -9
  91. package/templates/backend/node-nestjs/nest-cli.json +8 -8
  92. package/templates/backend/node-nestjs/package.json +50 -50
  93. package/templates/backend/node-nestjs/src/app.controller.ts +12 -12
  94. package/templates/backend/node-nestjs/src/app.module.ts +15 -15
  95. package/templates/backend/node-nestjs/src/app.service.ts +8 -8
  96. package/templates/backend/node-nestjs/src/main.ts +24 -24
  97. package/templates/backend/node-nestjs/tsconfig.json +21 -21
  98. package/templates/backend/php-laravel/.env.example +22 -22
  99. package/templates/backend/php-laravel/app/Http/Controllers/HealthController.php +15 -15
  100. package/templates/backend/php-laravel/composer.json +40 -40
  101. package/templates/backend/python-fastapi/.env.example +4 -4
  102. package/templates/backend/python-fastapi/app/api/router.py +8 -8
  103. package/templates/backend/python-fastapi/app/core/config.py +20 -20
  104. package/templates/backend/python-fastapi/main.py +35 -35
  105. package/templates/backend/python-fastapi/requirements.txt +13 -13
  106. package/templates/backend/rust-axum/.env.example +3 -3
  107. package/templates/backend/rust-axum/Cargo.toml +23 -23
  108. package/templates/backend/rust-axum/src/errors.rs +30 -30
  109. package/templates/backend/rust-axum/src/main.rs +32 -32
  110. package/templates/backend/rust-axum/src/routes.rs +6 -6
  111. package/templates/frontend/leptos-csr/.cargo/config.toml +2 -2
  112. package/templates/frontend/leptos-csr/Cargo.toml +16 -16
  113. package/templates/frontend/leptos-csr/Trunk.toml +10 -10
  114. package/templates/frontend/leptos-csr/index.html +11 -11
  115. package/templates/frontend/leptos-csr/src/lib.rs +20 -20
  116. package/templates/frontend/leptos-csr/style/main.scss +19 -19
  117. package/templates/frontend/leptos-fullstack/.cargo/config.toml +4 -4
  118. package/templates/frontend/leptos-fullstack/Cargo.toml +56 -56
  119. package/templates/frontend/leptos-fullstack/src/app.rs +49 -49
  120. package/templates/frontend/leptos-fullstack/src/lib.rs +9 -9
  121. package/templates/frontend/leptos-fullstack/src/main.rs +29 -29
  122. package/templates/frontend/leptos-fullstack/style/main.scss +19 -19
  123. package/templates/frontend/react/index.html +12 -12
  124. package/templates/frontend/react/package.json +35 -35
  125. package/templates/frontend/react/src/App.tsx +25 -25
  126. package/templates/frontend/react/src/main.tsx +9 -9
  127. package/templates/frontend/vue/package.json +32 -32
  128. package/templates/frontend/vue/src/App.vue +7 -7
  129. package/templates/frontend/vue/src/main.ts +10 -10
  130. package/templates/frontend/vue/src/router/index.ts +14 -14
  131. package/templates/frontend/vue/src/views/HomeView.vue +6 -6
  132. package/templates/hooks/pre-commit-dare-validate +24 -24
  133. package/templates/ide/antigravity/.agents/skills/dare-ax/SKILL.md +152 -152
  134. package/templates/ide/antigravity/.agents/skills/dare-bench/SKILL.md +21 -21
  135. package/templates/ide/antigravity/.agents/skills/dare-blueprint/SKILL.md +368 -368
  136. package/templates/ide/antigravity/.agents/skills/dare-bootstrap/SKILL.md +32 -32
  137. package/templates/ide/antigravity/.agents/skills/dare-bugfix-design/SKILL.md +76 -76
  138. package/templates/ide/antigravity/.agents/skills/dare-dag/SKILL.md +32 -32
  139. package/templates/ide/antigravity/.agents/skills/dare-dag-build/SKILL.md +154 -154
  140. package/templates/ide/antigravity/.agents/skills/dare-dag-run/SKILL.md +130 -130
  141. package/templates/ide/antigravity/.agents/skills/dare-dag-runner/SKILL.md +203 -203
  142. package/templates/ide/antigravity/.agents/skills/dare-design/SKILL.md +180 -180
  143. package/templates/ide/antigravity/.agents/skills/dare-discover/SKILL.md +33 -33
  144. package/templates/ide/antigravity/.agents/skills/dare-dna/SKILL.md +63 -63
  145. package/templates/ide/antigravity/.agents/skills/dare-docker/SKILL.md +315 -315
  146. package/templates/ide/antigravity/.agents/skills/dare-execute/SKILL.md +264 -264
  147. package/templates/ide/antigravity/.agents/skills/dare-feature-design/SKILL.md +74 -74
  148. package/templates/ide/antigravity/.agents/skills/dare-frontend-design/SKILL.md +192 -192
  149. package/templates/ide/antigravity/.agents/skills/dare-graph/SKILL.md +35 -35
  150. package/templates/ide/antigravity/.agents/skills/dare-info/SKILL.md +31 -31
  151. package/templates/ide/antigravity/.agents/skills/dare-init/SKILL.md +35 -35
  152. package/templates/ide/antigravity/.agents/skills/dare-laravel-api/SKILL.md +337 -337
  153. package/templates/ide/antigravity/.agents/skills/dare-layered-design/SKILL.md +166 -166
  154. package/templates/ide/antigravity/.agents/skills/dare-llm-integration/SKILL.md +217 -217
  155. package/templates/ide/antigravity/.agents/skills/dare-migrate/SKILL.md +61 -61
  156. package/templates/ide/antigravity/.agents/skills/dare-quality-telemetry/SKILL.md +187 -187
  157. package/templates/ide/antigravity/.agents/skills/dare-realtime/SKILL.md +217 -217
  158. package/templates/ide/antigravity/.agents/skills/dare-refine/SKILL.md +114 -114
  159. package/templates/ide/antigravity/.agents/skills/dare-reverse/SKILL.md +108 -108
  160. package/templates/ide/antigravity/.agents/skills/dare-review/SKILL.md +111 -111
  161. package/templates/ide/antigravity/.agents/skills/dare-rust-leptos/SKILL.md +263 -263
  162. package/templates/ide/antigravity/.agents/skills/dare-rust-workspace/SKILL.md +275 -275
  163. package/templates/ide/antigravity/.agents/skills/dare-security/SKILL.md +274 -274
  164. package/templates/ide/antigravity/.agents/skills/dare-skill/SKILL.md +35 -35
  165. package/templates/ide/antigravity/.agents/skills/dare-tasks/SKILL.md +265 -265
  166. package/templates/ide/antigravity/.agents/skills/dare-telemetry/SKILL.md +188 -188
  167. package/templates/ide/antigravity/.agents/skills/dare-update/SKILL.md +33 -33
  168. package/templates/ide/antigravity/.agents/skills/dare-validate/SKILL.md +33 -33
  169. package/templates/ide/antigravity/.agents/skills/dare-welcome/SKILL.md +30 -30
  170. package/templates/ide/antigravity/.agents/skills/skill-fastapi-api/SKILL.md +343 -343
  171. package/templates/ide/antigravity/.agents/skills/skill-go-gin-api/SKILL.md +377 -377
  172. package/templates/ide/antigravity/.agents/skills/skill-mcp-server/SKILL.md +382 -382
  173. package/templates/ide/antigravity/.agents/skills/skill-nestjs-api/SKILL.md +326 -326
  174. package/templates/ide/antigravity/.agents/skills/skill-rails-api/SKILL.md +393 -393
  175. package/templates/ide/antigravity/templates/BLUEPRINT-template.md +193 -193
  176. package/templates/ide/antigravity/templates/DESIGN-template.md +129 -129
  177. package/templates/ide/antigravity/templates/TASK-SPEC-template.md +141 -141
  178. package/templates/ide/antigravity/templates/TASKS-template.md +26 -26
  179. package/templates/ide/antigravity/templates/TELEMETRY-template.md +125 -125
  180. package/templates/ide/claude/.claude/commands/dare-ax.md +131 -131
  181. package/templates/ide/claude/.claude/commands/dare-bench.md +18 -18
  182. package/templates/ide/claude/.claude/commands/dare-blueprint.md +134 -134
  183. package/templates/ide/claude/.claude/commands/dare-bootstrap.md +27 -27
  184. package/templates/ide/claude/.claude/commands/dare-bugfix-design.md +119 -119
  185. package/templates/ide/claude/.claude/commands/dare-dag-build.md +151 -151
  186. package/templates/ide/claude/.claude/commands/dare-dag-run.md +109 -109
  187. package/templates/ide/claude/.claude/commands/dare-dag-runner.md +117 -117
  188. package/templates/ide/claude/.claude/commands/dare-dag-viz.md +197 -197
  189. package/templates/ide/claude/.claude/commands/dare-dag.md +27 -27
  190. package/templates/ide/claude/.claude/commands/dare-design.md +69 -69
  191. package/templates/ide/claude/.claude/commands/dare-discover.md +28 -28
  192. package/templates/ide/claude/.claude/commands/dare-dna.md +75 -75
  193. package/templates/ide/claude/.claude/commands/dare-docker.md +207 -207
  194. package/templates/ide/claude/.claude/commands/dare-execute.md +152 -152
  195. package/templates/ide/claude/.claude/commands/dare-feature-design.md +147 -147
  196. package/templates/ide/claude/.claude/commands/dare-frontend-design.md +149 -149
  197. package/templates/ide/claude/.claude/commands/dare-graph.md +30 -30
  198. package/templates/ide/claude/.claude/commands/dare-info.md +26 -26
  199. package/templates/ide/claude/.claude/commands/dare-init.md +30 -30
  200. package/templates/ide/claude/.claude/commands/dare-laravel-api.md +211 -211
  201. package/templates/ide/claude/.claude/commands/dare-layered-design.md +124 -124
  202. package/templates/ide/claude/.claude/commands/dare-llm-integration.md +148 -148
  203. package/templates/ide/claude/.claude/commands/dare-migrate.md +72 -72
  204. package/templates/ide/claude/.claude/commands/dare-quality-telemetry.md +166 -166
  205. package/templates/ide/claude/.claude/commands/dare-realtime.md +159 -159
  206. package/templates/ide/claude/.claude/commands/dare-refine.md +145 -145
  207. package/templates/ide/claude/.claude/commands/dare-reverse.md +139 -139
  208. package/templates/ide/claude/.claude/commands/dare-review.md +113 -113
  209. package/templates/ide/claude/.claude/commands/dare-rust-leptos.md +269 -269
  210. package/templates/ide/claude/.claude/commands/dare-rust-workspace.md +209 -209
  211. package/templates/ide/claude/.claude/commands/dare-security.md +232 -232
  212. package/templates/ide/claude/.claude/commands/dare-skill.md +30 -30
  213. package/templates/ide/claude/.claude/commands/dare-tasks.md +70 -70
  214. package/templates/ide/claude/.claude/commands/dare-telemetry.md +132 -132
  215. package/templates/ide/claude/.claude/commands/dare-update.md +28 -28
  216. package/templates/ide/claude/.claude/commands/dare-validate.md +28 -28
  217. package/templates/ide/claude/.claude/commands/dare-welcome.md +25 -25
  218. package/templates/ide/claude/.claude/commands/skill-fastapi-api.md +205 -205
  219. package/templates/ide/claude/.claude/commands/skill-go-gin-api.md +232 -232
  220. package/templates/ide/claude/.claude/commands/skill-mcp-server.md +228 -228
  221. package/templates/ide/claude/.claude/commands/skill-nestjs-api.md +210 -210
  222. package/templates/ide/claude/.claude/commands/skill-rails-api.md +236 -236
  223. package/templates/ide/claude/.claude/settings.example.json +35 -35
  224. package/templates/ide/claude/CLAUDE.md +146 -146
  225. package/templates/ide/claude/templates/BLUEPRINT-template.md +193 -193
  226. package/templates/ide/claude/templates/DESIGN-template.md +129 -129
  227. package/templates/ide/claude/templates/TASK-SPEC-template.md +141 -141
  228. package/templates/ide/claude/templates/TASKS-template.md +26 -26
  229. package/templates/ide/claude/templates/TELEMETRY-template.md +125 -125
  230. package/templates/ide/cursor/.cursor/commands/dare-bench.md +18 -18
  231. package/templates/ide/cursor/.cursor/commands/dare-blueprint.md +86 -86
  232. package/templates/ide/cursor/.cursor/commands/dare-bootstrap.md +27 -27
  233. package/templates/ide/cursor/.cursor/commands/dare-bugfix-design.md +64 -64
  234. package/templates/ide/cursor/.cursor/commands/dare-dag-run.md +110 -110
  235. package/templates/ide/cursor/.cursor/commands/dare-dag-viz.md +139 -139
  236. package/templates/ide/cursor/.cursor/commands/dare-dag.md +27 -27
  237. package/templates/ide/cursor/.cursor/commands/dare-design.md +35 -35
  238. package/templates/ide/cursor/.cursor/commands/dare-discover.md +28 -28
  239. package/templates/ide/cursor/.cursor/commands/dare-dna.md +75 -75
  240. package/templates/ide/cursor/.cursor/commands/dare-docker-compose.md +18 -18
  241. package/templates/ide/cursor/.cursor/commands/dare-dockerfile.md +17 -17
  242. package/templates/ide/cursor/.cursor/commands/dare-execute.md +19 -19
  243. package/templates/ide/cursor/.cursor/commands/dare-feature-design.md +64 -64
  244. package/templates/ide/cursor/.cursor/commands/dare-graph.md +30 -30
  245. package/templates/ide/cursor/.cursor/commands/dare-info.md +26 -26
  246. package/templates/ide/cursor/.cursor/commands/dare-init.md +30 -30
  247. package/templates/ide/cursor/.cursor/commands/dare-migrate.md +72 -72
  248. package/templates/ide/cursor/.cursor/commands/dare-refine.md +107 -107
  249. package/templates/ide/cursor/.cursor/commands/dare-reverse.md +139 -139
  250. package/templates/ide/cursor/.cursor/commands/dare-review.md +91 -91
  251. package/templates/ide/cursor/.cursor/commands/dare-skill.md +30 -30
  252. package/templates/ide/cursor/.cursor/commands/dare-tasks.md +184 -184
  253. package/templates/ide/cursor/.cursor/commands/dare-telemetry.md +42 -42
  254. package/templates/ide/cursor/.cursor/commands/dare-update.md +28 -28
  255. package/templates/ide/cursor/.cursor/commands/dare-validate.md +28 -28
  256. package/templates/ide/cursor/.cursor/commands/dare-welcome.md +25 -25
  257. package/templates/ide/cursor/.cursor/rules/skill-ax.mdc +263 -263
  258. package/templates/ide/cursor/.cursor/rules/skill-bugfix-design.mdc +51 -51
  259. package/templates/ide/cursor/.cursor/rules/skill-dag-build.mdc +173 -173
  260. package/templates/ide/cursor/.cursor/rules/skill-dag-run.mdc +134 -134
  261. package/templates/ide/cursor/.cursor/rules/skill-dag-runner.mdc +221 -221
  262. package/templates/ide/cursor/.cursor/rules/skill-dna.mdc +63 -63
  263. package/templates/ide/cursor/.cursor/rules/skill-docker.mdc +33 -33
  264. package/templates/ide/cursor/.cursor/rules/skill-fastapi-api.mdc +352 -352
  265. package/templates/ide/cursor/.cursor/rules/skill-feature-design.mdc +43 -43
  266. package/templates/ide/cursor/.cursor/rules/skill-frontend-design.mdc +244 -244
  267. package/templates/ide/cursor/.cursor/rules/skill-go-gin-api.mdc +371 -371
  268. package/templates/ide/cursor/.cursor/rules/skill-laravel-api.mdc +44 -44
  269. package/templates/ide/cursor/.cursor/rules/skill-layered-design.mdc +266 -266
  270. package/templates/ide/cursor/.cursor/rules/skill-llm-integration.mdc +295 -295
  271. package/templates/ide/cursor/.cursor/rules/skill-mcp-server.mdc +367 -367
  272. package/templates/ide/cursor/.cursor/rules/skill-migrate.mdc +58 -58
  273. package/templates/ide/cursor/.cursor/rules/skill-nestjs-api.mdc +346 -346
  274. package/templates/ide/cursor/.cursor/rules/skill-quality-telemetry.mdc +248 -248
  275. package/templates/ide/cursor/.cursor/rules/skill-rails-api.mdc +400 -400
  276. package/templates/ide/cursor/.cursor/rules/skill-realtime.mdc +262 -262
  277. package/templates/ide/cursor/.cursor/rules/skill-reverse.mdc +107 -107
  278. package/templates/ide/cursor/.cursor/rules/skill-rust-leptos.mdc +281 -281
  279. package/templates/ide/cursor/.cursor/rules/skill-rust-workspace.mdc +312 -312
  280. package/templates/ide/cursor/.cursor/rules/skill-security.mdc +245 -245
  281. package/templates/ide/cursor/.cursor/rules/skill-telemetry.mdc +156 -156
  282. package/templates/ide/cursor/templates/BLUEPRINT-template.md +193 -193
  283. package/templates/ide/cursor/templates/DESIGN-template.md +129 -129
  284. package/templates/ide/cursor/templates/TASK-SPEC-template.md +141 -141
  285. package/templates/ide/cursor/templates/TASKS-template.md +26 -26
  286. package/templates/ide/cursor/templates/TELEMETRY-template.md +125 -125
  287. package/templates/shared/docker-compose.yml +41 -41
  288. package/templates/stacks/go-gin/.dare/skills.yml +11 -11
  289. package/templates/stacks/go-gin/.env.example +24 -24
  290. package/templates/stacks/go-gin/.github/workflows/dare-ci.yml +42 -42
  291. package/templates/stacks/go-gin/README.md.tpl +38 -38
  292. package/templates/stacks/go-gin/cmd/server/main.go.tpl +78 -78
  293. package/templates/stacks/go-gin/db/migrations/0001_create_users.down.sql +2 -2
  294. package/templates/stacks/go-gin/db/migrations/0001_create_users.up.sql +12 -12
  295. package/templates/stacks/go-gin/db/queries/users.sql +23 -23
  296. package/templates/stacks/go-gin/gitignore +7 -7
  297. package/templates/stacks/go-gin/go.mod.tpl +17 -17
  298. package/templates/stacks/go-gin/internal/config/config.go +41 -41
  299. package/templates/stacks/go-gin/internal/db/postgres.go.tpl +25 -25
  300. package/templates/stacks/go-gin/internal/handler/auth_handler.go.tpl +72 -72
  301. package/templates/stacks/go-gin/internal/handler/users_handler.go.tpl +72 -72
  302. package/templates/stacks/go-gin/internal/handler/ws_handler.go +37 -37
  303. package/templates/stacks/go-gin/internal/llm/dummy.go +14 -14
  304. package/templates/stacks/go-gin/internal/llm/provider.go +8 -8
  305. package/templates/stacks/go-gin/internal/middleware/jwt.go.tpl +58 -58
  306. package/templates/stacks/go-gin/internal/middleware/rate_limit.go +55 -55
  307. package/templates/stacks/go-gin/internal/model/user.go +17 -17
  308. package/templates/stacks/go-gin/internal/repository/users_repository.go.tpl +79 -79
  309. package/templates/stacks/go-gin/internal/service/auth_service.go.tpl +55 -55
  310. package/templates/stacks/go-gin/internal/service/users_service.go.tpl +53 -53
  311. package/templates/stacks/go-gin/llms.txt.tpl +54 -54
  312. package/templates/stacks/go-gin/openapi.json.tpl +46 -46
  313. package/templates/stacks/go-gin/sqlc.yaml +14 -14
  314. package/templates/stacks/go-gin/tests/smoke_test.go.tpl +22 -22
  315. package/templates/stacks/go-stdlib/.dare/skills.yml +11 -11
  316. package/templates/stacks/go-stdlib/.env.example +24 -24
  317. package/templates/stacks/go-stdlib/.github/workflows/dare-ci.yml +42 -42
  318. package/templates/stacks/go-stdlib/README.md.tpl +41 -41
  319. package/templates/stacks/go-stdlib/cmd/server/main.go.tpl +82 -82
  320. package/templates/stacks/go-stdlib/db/migrations/0001_create_users.down.sql +2 -2
  321. package/templates/stacks/go-stdlib/db/migrations/0001_create_users.up.sql +12 -12
  322. package/templates/stacks/go-stdlib/db/queries/users.sql +23 -23
  323. package/templates/stacks/go-stdlib/gitignore +6 -6
  324. package/templates/stacks/go-stdlib/go.mod.tpl +15 -15
  325. package/templates/stacks/go-stdlib/internal/config/config.go +41 -41
  326. package/templates/stacks/go-stdlib/internal/db/postgres.go.tpl +24 -24
  327. package/templates/stacks/go-stdlib/internal/handler/auth_handler.go.tpl +71 -71
  328. package/templates/stacks/go-stdlib/internal/handler/users_handler.go.tpl +84 -84
  329. package/templates/stacks/go-stdlib/internal/handler/ws_handler.go +36 -36
  330. package/templates/stacks/go-stdlib/internal/httpx/json.go +32 -32
  331. package/templates/stacks/go-stdlib/internal/llm/dummy.go +14 -14
  332. package/templates/stacks/go-stdlib/internal/llm/provider.go +8 -8
  333. package/templates/stacks/go-stdlib/internal/middleware/chain.go +21 -21
  334. package/templates/stacks/go-stdlib/internal/middleware/cors.go +27 -27
  335. package/templates/stacks/go-stdlib/internal/middleware/jwt.go.tpl +51 -51
  336. package/templates/stacks/go-stdlib/internal/middleware/rate_limit.go +81 -81
  337. package/templates/stacks/go-stdlib/internal/model/user.go +17 -17
  338. package/templates/stacks/go-stdlib/internal/repository/users_repository.go.tpl +75 -75
  339. package/templates/stacks/go-stdlib/internal/service/auth_service.go.tpl +55 -55
  340. package/templates/stacks/go-stdlib/internal/service/users_service.go.tpl +53 -53
  341. package/templates/stacks/go-stdlib/llms.txt.tpl +60 -60
  342. package/templates/stacks/go-stdlib/openapi.json.tpl +46 -46
  343. package/templates/stacks/go-stdlib/sqlc.yaml +14 -14
  344. package/templates/stacks/go-stdlib/tests/smoke_test.go.tpl +45 -45
  345. package/templates/stacks/mcp-go/.dare/skills.yml +8 -8
  346. package/templates/stacks/mcp-go/.env.example +14 -14
  347. package/templates/stacks/mcp-go/.github/workflows/dare-ci.yml +42 -42
  348. package/templates/stacks/mcp-go/README.md.tpl +50 -50
  349. package/templates/stacks/mcp-go/cmd/server/main.go.tpl +62 -62
  350. package/templates/stacks/mcp-go/gitignore +6 -6
  351. package/templates/stacks/mcp-go/go.mod.tpl +9 -9
  352. package/templates/stacks/mcp-go/internal/prompts/summarize.go +9 -9
  353. package/templates/stacks/mcp-go/internal/server/server.go.tpl +80 -80
  354. package/templates/stacks/mcp-go/internal/tools/echo.go +15 -15
  355. package/templates/stacks/mcp-go/internal/transports/http.go.tpl +21 -21
  356. package/templates/stacks/mcp-go/internal/transports/sse.go.tpl +17 -17
  357. package/templates/stacks/mcp-go/internal/transports/stdio.go.tpl +14 -14
  358. package/templates/stacks/mcp-go/llms.txt.tpl +60 -60
  359. package/templates/stacks/mcp-go/openapi.json.tpl +31 -31
  360. package/templates/stacks/mcp-go/tests/echo_test.go.tpl +37 -37
  361. package/templates/stacks/mcp-node-ts/.dare/skills.yml +8 -8
  362. package/templates/stacks/mcp-node-ts/.env.example +16 -16
  363. package/templates/stacks/mcp-node-ts/.github/workflows/dare-ci.yml +54 -54
  364. package/templates/stacks/mcp-node-ts/README.md.hbs +49 -49
  365. package/templates/stacks/mcp-node-ts/gitignore +7 -7
  366. package/templates/stacks/mcp-node-ts/llms.txt.hbs +61 -61
  367. package/templates/stacks/mcp-node-ts/openapi.json.hbs +39 -39
  368. package/templates/stacks/mcp-node-ts/package.json.hbs +35 -35
  369. package/templates/stacks/mcp-node-ts/src/cli.ts.hbs +71 -71
  370. package/templates/stacks/mcp-node-ts/src/prompts/index.ts +36 -36
  371. package/templates/stacks/mcp-node-ts/src/server.ts.hbs +45 -45
  372. package/templates/stacks/mcp-node-ts/src/tools/echo.ts +23 -23
  373. package/templates/stacks/mcp-node-ts/src/tools/index.ts +18 -18
  374. package/templates/stacks/mcp-node-ts/src/transports/http.ts +68 -68
  375. package/templates/stacks/mcp-node-ts/src/transports/sse.ts +58 -58
  376. package/templates/stacks/mcp-node-ts/src/transports/stdio.ts +5 -5
  377. package/templates/stacks/mcp-node-ts/tests/echo.test.ts +50 -50
  378. package/templates/stacks/mcp-node-ts/tsconfig.json +17 -17
  379. package/templates/stacks/mcp-python/.dare/skills.yml +8 -8
  380. package/templates/stacks/mcp-python/.env.example +14 -14
  381. package/templates/stacks/mcp-python/.github/workflows/dare-ci.yml +42 -42
  382. package/templates/stacks/mcp-python/README.md.j2 +49 -49
  383. package/templates/stacks/mcp-python/gitignore +12 -12
  384. package/templates/stacks/mcp-python/llms.txt.j2 +56 -56
  385. package/templates/stacks/mcp-python/openapi.json.j2 +33 -33
  386. package/templates/stacks/mcp-python/pyproject.toml.j2 +37 -37
  387. package/templates/stacks/mcp-python/src/cli.py.j2 +68 -68
  388. package/templates/stacks/mcp-python/src/prompts/summarize.py +10 -10
  389. package/templates/stacks/mcp-python/src/server.py.j2 +28 -28
  390. package/templates/stacks/mcp-python/src/tools/echo.py +12 -12
  391. package/templates/stacks/mcp-python/src/transports/http.py +12 -12
  392. package/templates/stacks/mcp-python/src/transports/sse.py +13 -13
  393. package/templates/stacks/mcp-python/src/transports/stdio.py +6 -6
  394. package/templates/stacks/mcp-python/tests/test_echo.py +28 -28
  395. package/templates/stacks/mcp-rust/.dare/skills.yml +8 -8
  396. package/templates/stacks/mcp-rust/.env.example +14 -14
  397. package/templates/stacks/mcp-rust/.github/workflows/dare-ci.yml +38 -38
  398. package/templates/stacks/mcp-rust/Cargo.toml.tera +35 -35
  399. package/templates/stacks/mcp-rust/README.md.tera +50 -50
  400. package/templates/stacks/mcp-rust/gitignore +5 -5
  401. package/templates/stacks/mcp-rust/llms.txt.tera +60 -60
  402. package/templates/stacks/mcp-rust/openapi.json.tera +31 -31
  403. package/templates/stacks/mcp-rust/src/cli.rs.tera +33 -33
  404. package/templates/stacks/mcp-rust/src/lib.rs +6 -6
  405. package/templates/stacks/mcp-rust/src/main.rs.tera +30 -30
  406. package/templates/stacks/mcp-rust/src/prompts/mod.rs +1 -1
  407. package/templates/stacks/mcp-rust/src/prompts/summarize.rs +5 -5
  408. package/templates/stacks/mcp-rust/src/server.rs.tera +38 -38
  409. package/templates/stacks/mcp-rust/src/tools/echo.rs +18 -18
  410. package/templates/stacks/mcp-rust/src/tools/mod.rs +22 -22
  411. package/templates/stacks/mcp-rust/src/transports/http.rs +27 -27
  412. package/templates/stacks/mcp-rust/src/transports/mod.rs +3 -3
  413. package/templates/stacks/mcp-rust/src/transports/sse.rs +33 -33
  414. package/templates/stacks/mcp-rust/src/transports/stdio.rs +14 -14
  415. package/templates/stacks/mcp-rust/tests/echo_test.rs.tera +27 -27
  416. package/templates/stacks/node-nestjs/.dare/skills.yml +11 -11
  417. package/templates/stacks/node-nestjs/.env.example +21 -21
  418. package/templates/stacks/node-nestjs/.github/workflows/dare-ci.yml +54 -54
  419. package/templates/stacks/node-nestjs/README.md.hbs +35 -35
  420. package/templates/stacks/node-nestjs/gitignore +7 -7
  421. package/templates/stacks/node-nestjs/llms.txt.hbs +47 -47
  422. package/templates/stacks/node-nestjs/nest-cli.json +16 -16
  423. package/templates/stacks/node-nestjs/openapi.json.hbs +75 -75
  424. package/templates/stacks/node-nestjs/package.json.hbs +57 -57
  425. package/templates/stacks/node-nestjs/prisma/schema.prisma +25 -25
  426. package/templates/stacks/node-nestjs/prisma/seed.ts.hbs +25 -25
  427. package/templates/stacks/node-nestjs/src/app.module.ts +39 -39
  428. package/templates/stacks/node-nestjs/src/auth/auth.controller.ts +29 -29
  429. package/templates/stacks/node-nestjs/src/auth/auth.module.ts +25 -25
  430. package/templates/stacks/node-nestjs/src/auth/auth.service.ts +36 -36
  431. package/templates/stacks/node-nestjs/src/auth/dto/login-response.dto.ts +9 -9
  432. package/templates/stacks/node-nestjs/src/auth/dto/login.dto.ts +17 -17
  433. package/templates/stacks/node-nestjs/src/auth/jwt.strategy.ts +25 -25
  434. package/templates/stacks/node-nestjs/src/common/filters/problem-details.filter.ts +38 -38
  435. package/templates/stacks/node-nestjs/src/common/interceptors/json-response.interceptor.ts +13 -13
  436. package/templates/stacks/node-nestjs/src/main.ts.hbs +44 -44
  437. package/templates/stacks/node-nestjs/src/prisma/prisma.module.ts +9 -9
  438. package/templates/stacks/node-nestjs/src/prisma/prisma.service.ts +9 -9
  439. package/templates/stacks/node-nestjs/src/users/dto/create-user.dto.ts +22 -22
  440. package/templates/stacks/node-nestjs/src/users/dto/user.dto.ts +15 -15
  441. package/templates/stacks/node-nestjs/src/users/users.controller.ts +41 -41
  442. package/templates/stacks/node-nestjs/src/users/users.module.ts +11 -11
  443. package/templates/stacks/node-nestjs/src/users/users.repository.ts +38 -38
  444. package/templates/stacks/node-nestjs/src/users/users.service.ts +38 -38
  445. package/templates/stacks/node-nestjs/tsconfig.build.json +4 -4
  446. package/templates/stacks/node-nestjs/tsconfig.json +28 -28
  447. package/templates/stacks/php-laravel/.dare/skills.yml +11 -11
  448. package/templates/stacks/php-laravel/.env.example +41 -41
  449. package/templates/stacks/php-laravel/.github/workflows/dare-ci.yml +43 -43
  450. package/templates/stacks/php-laravel/README.md.hbs +36 -36
  451. package/templates/stacks/php-laravel/app/Http/Controllers/Api/AuthController.php +36 -36
  452. package/templates/stacks/php-laravel/app/Http/Controllers/Api/UsersController.php +33 -33
  453. package/templates/stacks/php-laravel/app/Http/Requests/CreateUserRequest.php +26 -26
  454. package/templates/stacks/php-laravel/app/Http/Requests/LoginRequest.php +34 -34
  455. package/templates/stacks/php-laravel/app/Llm/Contracts/LlmProvider.php +12 -12
  456. package/templates/stacks/php-laravel/app/Llm/Providers/DummyProvider.php +13 -13
  457. package/templates/stacks/php-laravel/app/Llm/Providers/OpenAiProvider.php +33 -33
  458. package/templates/stacks/php-laravel/app/Models/User.php +44 -44
  459. package/templates/stacks/php-laravel/app/Repositories/UsersRepository.php +32 -32
  460. package/templates/stacks/php-laravel/app/Services/AuthService.php +37 -37
  461. package/templates/stacks/php-laravel/app/Services/UsersService.php +57 -57
  462. package/templates/stacks/php-laravel/artisan +12 -12
  463. package/templates/stacks/php-laravel/bootstrap/app.php +29 -29
  464. package/templates/stacks/php-laravel/bootstrap/providers.php +5 -5
  465. package/templates/stacks/php-laravel/composer.json.hbs +58 -58
  466. package/templates/stacks/php-laravel/config/l5-swagger.php +41 -41
  467. package/templates/stacks/php-laravel/config/reverb.php +34 -34
  468. package/templates/stacks/php-laravel/config/sanctum.php +15 -15
  469. package/templates/stacks/php-laravel/database/migrations/2026_06_01_000001_create_users_table.php +27 -27
  470. package/templates/stacks/php-laravel/database/seeders/DatabaseSeeder.php +21 -21
  471. package/templates/stacks/php-laravel/gitignore +23 -23
  472. package/templates/stacks/php-laravel/llms.txt.hbs +53 -53
  473. package/templates/stacks/php-laravel/openapi.json.hbs +43 -43
  474. package/templates/stacks/php-laravel/phpstan.neon +9 -9
  475. package/templates/stacks/php-laravel/routes/api.php +13 -13
  476. package/templates/stacks/php-laravel/routes/channels.php +7 -7
  477. package/templates/stacks/php-laravel/tests/Feature/AuthTest.php +35 -35
  478. package/templates/stacks/php-laravel/tests/Feature/UsersTest.php +30 -30
  479. package/templates/stacks/php-laravel/tests/Pest.php +5 -5
  480. package/templates/stacks/python-fastapi/.dare/skills.yml +11 -11
  481. package/templates/stacks/python-fastapi/.env.example +21 -21
  482. package/templates/stacks/python-fastapi/.github/workflows/dare-ci.yml +43 -43
  483. package/templates/stacks/python-fastapi/README.md.j2 +35 -35
  484. package/templates/stacks/python-fastapi/alembic/env.py +46 -46
  485. package/templates/stacks/python-fastapi/alembic/script.py.mako +26 -26
  486. package/templates/stacks/python-fastapi/alembic/versions/0001_create_users.py.j2 +37 -37
  487. package/templates/stacks/python-fastapi/alembic.ini.j2 +39 -39
  488. package/templates/stacks/python-fastapi/app/core/config.py +24 -24
  489. package/templates/stacks/python-fastapi/app/core/security.py +34 -34
  490. package/templates/stacks/python-fastapi/app/db/session.py +22 -22
  491. package/templates/stacks/python-fastapi/app/main.py.j2 +36 -36
  492. package/templates/stacks/python-fastapi/app/models/__init__.py +3 -3
  493. package/templates/stacks/python-fastapi/app/models/user.py +30 -30
  494. package/templates/stacks/python-fastapi/app/repositories/user_repository.py +34 -34
  495. package/templates/stacks/python-fastapi/app/routers/auth.py +37 -37
  496. package/templates/stacks/python-fastapi/app/routers/users.py +46 -46
  497. package/templates/stacks/python-fastapi/app/schemas/user.py +56 -56
  498. package/templates/stacks/python-fastapi/app/services/auth_service.py +22 -22
  499. package/templates/stacks/python-fastapi/app/services/user_service.py +31 -31
  500. package/templates/stacks/python-fastapi/gitignore +12 -12
  501. package/templates/stacks/python-fastapi/llms.txt.j2 +53 -53
  502. package/templates/stacks/python-fastapi/openapi.json.j2 +43 -43
  503. package/templates/stacks/python-fastapi/pyproject.toml.j2 +45 -45
  504. package/templates/stacks/python-fastapi/tests/test_auth.py +22 -22
  505. package/templates/stacks/ruby-rails-8/.dare/skills.yml +50 -50
  506. package/templates/stacks/ruby-rails-8/.env.example +20 -20
  507. package/templates/stacks/ruby-rails-8/.github/workflows/dare-ci.yml +112 -112
  508. package/templates/stacks/ruby-rails-8/Gemfile.erb +61 -61
  509. package/templates/stacks/ruby-rails-8/app/channels/application_cable/channel.rb +11 -11
  510. package/templates/stacks/ruby-rails-8/app/channels/application_cable/connection.rb +34 -34
  511. package/templates/stacks/ruby-rails-8/app/channels/dare_updates_channel.rb +18 -18
  512. package/templates/stacks/ruby-rails-8/app/channels/user_updates_channel.rb +23 -23
  513. package/templates/stacks/ruby-rails-8/app/controllers/application_controller.rb +44 -44
  514. package/templates/stacks/ruby-rails-8/app/controllers/concerns/problem_details.rb +93 -93
  515. package/templates/stacks/ruby-rails-8/app/handlers/summarize_handler.rb +33 -33
  516. package/templates/stacks/ruby-rails-8/app/handlers/users_handler.rb +68 -68
  517. package/templates/stacks/ruby-rails-8/app/llm/cache/llm_cache.rb +44 -44
  518. package/templates/stacks/ruby-rails-8/app/llm/prompts/prompt_loader.rb +54 -54
  519. package/templates/stacks/ruby-rails-8/app/llm/prompts/summarize_v1.jinja2 +12 -12
  520. package/templates/stacks/ruby-rails-8/app/llm/providers/dummy_provider.rb +35 -35
  521. package/templates/stacks/ruby-rails-8/app/llm/providers/llm_provider.rb +67 -67
  522. package/templates/stacks/ruby-rails-8/app/llm/providers/openai_provider.rb +62 -62
  523. package/templates/stacks/ruby-rails-8/app/llm/rate_limit/token_bucket.rb +82 -82
  524. package/templates/stacks/ruby-rails-8/app/llm/validators/summarize_output_schema.json +21 -21
  525. package/templates/stacks/ruby-rails-8/app/llm/validators/validator.rb +52 -52
  526. package/templates/stacks/ruby-rails-8/app/models/user.rb +36 -36
  527. package/templates/stacks/ruby-rails-8/app/presenters/user_presenter.rb +48 -48
  528. package/templates/stacks/ruby-rails-8/app/repositories/document_repository.rb +57 -57
  529. package/templates/stacks/ruby-rails-8/app/repositories/user_repository.rb +73 -73
  530. package/templates/stacks/ruby-rails-8/app/services/create_user_service.rb +67 -67
  531. package/templates/stacks/ruby-rails-8/app/services/realtime_service.rb +53 -53
  532. package/templates/stacks/ruby-rails-8/app/services/summarize_document_service.rb +57 -57
  533. package/templates/stacks/ruby-rails-8/config/dare.yml +42 -42
  534. package/templates/stacks/ruby-rails-8/config/initializers/dare.rb +31 -31
  535. package/templates/stacks/ruby-rails-8/config/initializers/rack_attack.rb +64 -64
  536. package/templates/stacks/ruby-rails-8/config/initializers/rswag_api.rb +12 -12
  537. package/templates/stacks/ruby-rails-8/lib/tasks/dare.rake +159 -159
  538. package/templates/stacks/ruby-rails-8/llms.txt.erb +69 -69
  539. package/templates/stacks/ruby-rails-8/spec/api/summarize_spec.rb +56 -56
  540. package/templates/stacks/ruby-rails-8/spec/api/users_spec.rb +72 -72
  541. package/templates/stacks/ruby-rails-8/spec/channels/dare_updates_channel_spec.rb +61 -61
  542. package/templates/stacks/ruby-rails-8/spec/channels/user_updates_channel_spec.rb +56 -56
  543. package/templates/stacks/ruby-rails-8/spec/factories/users.rb +27 -27
  544. package/templates/stacks/ruby-rails-8/spec/handlers/users_handler_spec.rb +88 -88
  545. package/templates/stacks/ruby-rails-8/spec/rails_helper.rb +31 -31
  546. package/templates/stacks/ruby-rails-8/spec/services/create_user_service_spec.rb +88 -88
  547. package/templates/stacks/ruby-rails-8/spec/services/summarize_document_service_spec.rb +142 -142
  548. package/templates/stacks/ruby-rails-8/spec/swagger_helper.rb +73 -73
  549. package/templates/stacks/rust-axum/.dare/skills.yml +11 -11
  550. package/templates/stacks/rust-axum/.env.example +26 -26
  551. package/templates/stacks/rust-axum/.github/workflows/dare-ci.yml +40 -40
  552. package/templates/stacks/rust-axum/Cargo.toml.tera +53 -53
  553. package/templates/stacks/rust-axum/README.md.tera +37 -37
  554. package/templates/stacks/rust-axum/gitignore +5 -5
  555. package/templates/stacks/rust-axum/llms.txt.tera +54 -54
  556. package/templates/stacks/rust-axum/migrations/0001_create_users.sql +13 -13
  557. package/templates/stacks/rust-axum/openapi.json.tera +46 -46
  558. package/templates/stacks/rust-axum/src/config.rs +45 -45
  559. package/templates/stacks/rust-axum/src/errors.rs +48 -48
  560. package/templates/stacks/rust-axum/src/handlers/auth.rs +48 -48
  561. package/templates/stacks/rust-axum/src/handlers/mod.rs +3 -3
  562. package/templates/stacks/rust-axum/src/handlers/users.rs +81 -81
  563. package/templates/stacks/rust-axum/src/handlers/ws.rs +24 -24
  564. package/templates/stacks/rust-axum/src/lib.rs +19 -19
  565. package/templates/stacks/rust-axum/src/llm/mod.rs +1 -1
  566. package/templates/stacks/rust-axum/src/llm/provider.rs +48 -48
  567. package/templates/stacks/rust-axum/src/main.rs.tera +64 -64
  568. package/templates/stacks/rust-axum/src/middleware/auth.rs +20 -20
  569. package/templates/stacks/rust-axum/src/middleware/mod.rs +2 -2
  570. package/templates/stacks/rust-axum/src/middleware/rate_limit.rs +27 -27
  571. package/templates/stacks/rust-axum/src/models/mod.rs +1 -1
  572. package/templates/stacks/rust-axum/src/models/user.rs +13 -13
  573. package/templates/stacks/rust-axum/src/repositories/mod.rs +1 -1
  574. package/templates/stacks/rust-axum/src/repositories/user_repository.rs +62 -62
  575. package/templates/stacks/rust-axum/src/services/auth_service.rs +50 -50
  576. package/templates/stacks/rust-axum/src/services/mod.rs +2 -2
  577. package/templates/stacks/rust-axum/src/services/user_service.rs +53 -53
  578. package/templates/stacks/rust-axum/tests/integration_test.rs.tera +13 -13
  579. package/dist/commands/new.d.ts +0 -16
  580. package/dist/commands/new.d.ts.map +0 -1
  581. package/dist/commands/new.js +0 -104
  582. package/dist/commands/new.js.map +0 -1
@@ -1,36 +1,36 @@
1
- # frozen_string_literal: true
2
-
3
- # DARE v3.0 — User domain model
4
- # Convention (ADR-05): models are lean data objects — no callbacks, no fat model
5
- # Business logic lives in app/services/; data access in app/repositories/
6
-
7
- class User < ApplicationRecord
8
- # ── Validations ─────────────────────────────────────────────────────────
9
- validates :email, presence: true,
10
- uniqueness: { case_sensitive: false },
11
- format: { with: URI::MailTo::EMAIL_REGEXP }
12
- validates :name, presence: true, length: { minimum: 2, maximum: 100 }
13
-
14
- # ── Scopes ───────────────────────────────────────────────────────────────
15
- scope :active, -> { where(active: true) }
16
-
17
- # ── DARE: NO callbacks, NO fat model logic ───────────────────────────────
18
- # Use Services for: password hashing, welcome emails, event publishing, etc.
19
- # Use Repositories for: queries, bulk updates, custom SQL
20
- #
21
- # WRONG (fat model):
22
- # before_create :send_welcome_email
23
- # after_save :publish_event
24
- #
25
- # RIGHT (service):
26
- # Services::CreateUserService.new(...).execute(params)
27
-
28
- # ── Simple domain helpers (pure data concerns only) ──────────────────────
29
- def display_name
30
- name.presence || email.split("@").first
31
- end
32
-
33
- def can_view?(user_id)
34
- id == user_id.to_i || admin?
35
- end
36
- end
1
+ # frozen_string_literal: true
2
+
3
+ # DARE v3.0 — User domain model
4
+ # Convention (ADR-05): models are lean data objects — no callbacks, no fat model
5
+ # Business logic lives in app/services/; data access in app/repositories/
6
+
7
+ class User < ApplicationRecord
8
+ # ── Validations ─────────────────────────────────────────────────────────
9
+ validates :email, presence: true,
10
+ uniqueness: { case_sensitive: false },
11
+ format: { with: URI::MailTo::EMAIL_REGEXP }
12
+ validates :name, presence: true, length: { minimum: 2, maximum: 100 }
13
+
14
+ # ── Scopes ───────────────────────────────────────────────────────────────
15
+ scope :active, -> { where(active: true) }
16
+
17
+ # ── DARE: NO callbacks, NO fat model logic ───────────────────────────────
18
+ # Use Services for: password hashing, welcome emails, event publishing, etc.
19
+ # Use Repositories for: queries, bulk updates, custom SQL
20
+ #
21
+ # WRONG (fat model):
22
+ # before_create :send_welcome_email
23
+ # after_save :publish_event
24
+ #
25
+ # RIGHT (service):
26
+ # Services::CreateUserService.new(...).execute(params)
27
+
28
+ # ── Simple domain helpers (pure data concerns only) ──────────────────────
29
+ def display_name
30
+ name.presence || email.split("@").first
31
+ end
32
+
33
+ def can_view?(user_id)
34
+ id == user_id.to_i || admin?
35
+ end
36
+ end
@@ -1,48 +1,48 @@
1
- # frozen_string_literal: true
2
-
3
- # DARE v3.0 — UserPresenter
4
- # Convention (ADR-05): serialization concern isolated from model and controller
5
- # Returns plain Hash; handler renders JSON from it
6
-
7
- class UserPresenter
8
- def initialize(user)
9
- @user = user
10
- end
11
-
12
- # Full representation — used in show/create responses
13
- def as_json(*)
14
- {
15
- id: @user.id,
16
- email: @user.email,
17
- name: @user.name,
18
- active: @user.active?,
19
- created_at: @user.created_at&.iso8601,
20
- updated_at: @user.updated_at&.iso8601,
21
- }
22
- end
23
-
24
- def to_json(*)
25
- as_json.to_json
26
- end
27
-
28
- # Collection representation — used in index responses
29
- # Wraps an array of presenters into a standard envelope
30
- def self.collection(users, meta: {})
31
- {
32
- data: users.map { |u| new(u).as_json },
33
- meta: {
34
- count: users.size,
35
- **meta
36
- }
37
- }
38
- end
39
-
40
- # Minimal summary representation (e.g. for nested resources)
41
- def summary
42
- {
43
- id: @user.id,
44
- email: @user.email,
45
- name: @user.name
46
- }
47
- end
48
- end
1
+ # frozen_string_literal: true
2
+
3
+ # DARE v3.0 — UserPresenter
4
+ # Convention (ADR-05): serialization concern isolated from model and controller
5
+ # Returns plain Hash; handler renders JSON from it
6
+
7
+ class UserPresenter
8
+ def initialize(user)
9
+ @user = user
10
+ end
11
+
12
+ # Full representation — used in show/create responses
13
+ def as_json(*)
14
+ {
15
+ id: @user.id,
16
+ email: @user.email,
17
+ name: @user.name,
18
+ active: @user.active?,
19
+ created_at: @user.created_at&.iso8601,
20
+ updated_at: @user.updated_at&.iso8601,
21
+ }
22
+ end
23
+
24
+ def to_json(*)
25
+ as_json.to_json
26
+ end
27
+
28
+ # Collection representation — used in index responses
29
+ # Wraps an array of presenters into a standard envelope
30
+ def self.collection(users, meta: {})
31
+ {
32
+ data: users.map { |u| new(u).as_json },
33
+ meta: {
34
+ count: users.size,
35
+ **meta
36
+ }
37
+ }
38
+ end
39
+
40
+ # Minimal summary representation (e.g. for nested resources)
41
+ def summary
42
+ {
43
+ id: @user.id,
44
+ email: @user.email,
45
+ name: @user.name
46
+ }
47
+ end
48
+ end
@@ -1,57 +1,57 @@
1
- # frozen_string_literal: true
2
-
3
- # DARE v3.0 — DocumentRepository (interface + ActiveRecord implementation)
4
- # Convention (ADR-05): data access is isolated here — services never call AR directly
5
- # This enables easy mocking in unit tests and future DB swaps
6
-
7
- module Repositories
8
- class DocumentRepository
9
- # ── Query ──────────────────────────────────────────────────────────────
10
-
11
- def find(id)
12
- Document.find_by(id: id)
13
- end
14
-
15
- def find!(id)
16
- Document.find(id)
17
- rescue ActiveRecord::RecordNotFound
18
- raise ActiveRecord::RecordNotFound, "Document with id=#{id} was not found."
19
- end
20
-
21
- def all
22
- Document.order(created_at: :desc)
23
- end
24
-
25
- def by_user(user_id)
26
- Document.where(user_id: user_id).order(created_at: :desc)
27
- end
28
-
29
- # ── Persistence ────────────────────────────────────────────────────────
30
-
31
- # Builds a new Document (not persisted).
32
- def build(attrs = {})
33
- Document.new(attrs)
34
- end
35
-
36
- # Persist (create or update). Raises ActiveRecord::RecordInvalid on failure.
37
- def save!(document)
38
- document.save!
39
- document
40
- end
41
-
42
- # Update summary and timestamp after LLM processing.
43
- def update_summary!(document, summary)
44
- document.update!(summary: summary, summarized_at: Time.current)
45
- document
46
- end
47
-
48
- def update!(document, attributes)
49
- document.update!(attributes)
50
- document
51
- end
52
-
53
- def destroy!(document)
54
- document.destroy!
55
- end
56
- end
57
- end
1
+ # frozen_string_literal: true
2
+
3
+ # DARE v3.0 — DocumentRepository (interface + ActiveRecord implementation)
4
+ # Convention (ADR-05): data access is isolated here — services never call AR directly
5
+ # This enables easy mocking in unit tests and future DB swaps
6
+
7
+ module Repositories
8
+ class DocumentRepository
9
+ # ── Query ──────────────────────────────────────────────────────────────
10
+
11
+ def find(id)
12
+ Document.find_by(id: id)
13
+ end
14
+
15
+ def find!(id)
16
+ Document.find(id)
17
+ rescue ActiveRecord::RecordNotFound
18
+ raise ActiveRecord::RecordNotFound, "Document with id=#{id} was not found."
19
+ end
20
+
21
+ def all
22
+ Document.order(created_at: :desc)
23
+ end
24
+
25
+ def by_user(user_id)
26
+ Document.where(user_id: user_id).order(created_at: :desc)
27
+ end
28
+
29
+ # ── Persistence ────────────────────────────────────────────────────────
30
+
31
+ # Builds a new Document (not persisted).
32
+ def build(attrs = {})
33
+ Document.new(attrs)
34
+ end
35
+
36
+ # Persist (create or update). Raises ActiveRecord::RecordInvalid on failure.
37
+ def save!(document)
38
+ document.save!
39
+ document
40
+ end
41
+
42
+ # Update summary and timestamp after LLM processing.
43
+ def update_summary!(document, summary)
44
+ document.update!(summary: summary, summarized_at: Time.current)
45
+ document
46
+ end
47
+
48
+ def update!(document, attributes)
49
+ document.update!(attributes)
50
+ document
51
+ end
52
+
53
+ def destroy!(document)
54
+ document.destroy!
55
+ end
56
+ end
57
+ end
@@ -1,73 +1,73 @@
1
- # frozen_string_literal: true
2
-
3
- # DARE v3.0 — UserRepository
4
- # Convention (ADR-05): data access is isolated here — services never call AR directly
5
- # This enables easy mocking in unit tests and future DB swaps
6
-
7
- module Repositories
8
- class UserRepository
9
- # ── Query ──────────────────────────────────────────────────────────────
10
-
11
- def find(id)
12
- User.find_by(id: id)
13
- end
14
-
15
- def find!(id)
16
- User.find(id)
17
- rescue ActiveRecord::RecordNotFound
18
- raise ActiveRecord::RecordNotFound, "User with id=#{id} was not found."
19
- end
20
-
21
- def find_by_email(email)
22
- User.find_by(email: email.downcase.strip)
23
- end
24
-
25
- def all_active
26
- User.active.order(created_at: :desc)
27
- end
28
-
29
- def paginated(page: 1, per: 25)
30
- User.active
31
- .order(created_at: :desc)
32
- .offset((page.to_i - 1) * per.to_i)
33
- .limit(per.to_i)
34
- end
35
-
36
- def count
37
- User.count
38
- end
39
-
40
- # ── Persistence ────────────────────────────────────────────────────────
41
-
42
- # Builds a new User (not persisted). Let the service validate input first.
43
- def build(attributes = {})
44
- User.new(attributes)
45
- end
46
-
47
- # Persist (create or update). Raises ActiveRecord::RecordInvalid on failure.
48
- def save!(user)
49
- user.save!
50
- user
51
- end
52
-
53
- # Persist without raising. Returns false on failure.
54
- def save(user)
55
- user.save
56
- end
57
-
58
- def update!(user, attributes)
59
- user.update!(attributes)
60
- user
61
- end
62
-
63
- def destroy!(user)
64
- user.destroy!
65
- end
66
-
67
- # ── Bulk ───────────────────────────────────────────────────────────────
68
-
69
- def deactivate_all_inactive(since:)
70
- User.where("last_active_at < ?", since).update_all(active: false)
71
- end
72
- end
73
- end
1
+ # frozen_string_literal: true
2
+
3
+ # DARE v3.0 — UserRepository
4
+ # Convention (ADR-05): data access is isolated here — services never call AR directly
5
+ # This enables easy mocking in unit tests and future DB swaps
6
+
7
+ module Repositories
8
+ class UserRepository
9
+ # ── Query ──────────────────────────────────────────────────────────────
10
+
11
+ def find(id)
12
+ User.find_by(id: id)
13
+ end
14
+
15
+ def find!(id)
16
+ User.find(id)
17
+ rescue ActiveRecord::RecordNotFound
18
+ raise ActiveRecord::RecordNotFound, "User with id=#{id} was not found."
19
+ end
20
+
21
+ def find_by_email(email)
22
+ User.find_by(email: email.downcase.strip)
23
+ end
24
+
25
+ def all_active
26
+ User.active.order(created_at: :desc)
27
+ end
28
+
29
+ def paginated(page: 1, per: 25)
30
+ User.active
31
+ .order(created_at: :desc)
32
+ .offset((page.to_i - 1) * per.to_i)
33
+ .limit(per.to_i)
34
+ end
35
+
36
+ def count
37
+ User.count
38
+ end
39
+
40
+ # ── Persistence ────────────────────────────────────────────────────────
41
+
42
+ # Builds a new User (not persisted). Let the service validate input first.
43
+ def build(attributes = {})
44
+ User.new(attributes)
45
+ end
46
+
47
+ # Persist (create or update). Raises ActiveRecord::RecordInvalid on failure.
48
+ def save!(user)
49
+ user.save!
50
+ user
51
+ end
52
+
53
+ # Persist without raising. Returns false on failure.
54
+ def save(user)
55
+ user.save
56
+ end
57
+
58
+ def update!(user, attributes)
59
+ user.update!(attributes)
60
+ user
61
+ end
62
+
63
+ def destroy!(user)
64
+ user.destroy!
65
+ end
66
+
67
+ # ── Bulk ───────────────────────────────────────────────────────────────
68
+
69
+ def deactivate_all_inactive(since:)
70
+ User.where("last_active_at < ?", since).update_all(active: false)
71
+ end
72
+ end
73
+ end
@@ -1,67 +1,67 @@
1
- # frozen_string_literal: true
2
-
3
- # DARE v3.0 — CreateUserService
4
- # Convention (ADR-01): one service per operation; injected dependencies for testability
5
- #
6
- # Usage:
7
- # result = Services::CreateUserService.new(
8
- # user_repository: Repositories::UserRepository.new,
9
- # event_publisher: RealtimeService.instance
10
- # ).execute(email: "user@example.com", name: "Alice")
11
- #
12
- # Returns: User (persisted)
13
- # Raises: Services::CreateUserService::EmailTakenError
14
- # ActiveRecord::RecordInvalid (validation failure)
15
-
16
- module Services
17
- class CreateUserService
18
- # ── Domain errors ──────────────────────────────────────────────────────
19
- class EmailTakenError < StandardError
20
- def initialize(email)
21
- super("Email '#{email}' is already registered.")
22
- end
23
- end
24
-
25
- # ── Constructor ────────────────────────────────────────────────────────
26
- def initialize(user_repository:, event_publisher:)
27
- @user_repository = user_repository
28
- @event_publisher = event_publisher
29
- end
30
-
31
- # ── Main operation ─────────────────────────────────────────────────────
32
- def execute(email:, name:, password: nil, **extra_attrs)
33
- email = email.to_s.downcase.strip
34
-
35
- # Guard: check for duplicate email
36
- if @user_repository.find_by_email(email)
37
- raise EmailTakenError, email
38
- end
39
-
40
- # Build and persist
41
- user = @user_repository.build(
42
- email: email,
43
- name: name.to_s.strip,
44
- active: true,
45
- **extra_attrs
46
- )
47
-
48
- # Hash password if provided (example using has_secure_password)
49
- user.password = password if password.present?
50
-
51
- @user_repository.save!(user)
52
-
53
- # Publish real-time event
54
- @event_publisher.publish(
55
- type: "user.created",
56
- data: {
57
- user_id: user.id,
58
- email: user.email,
59
- name: user.name,
60
- timestamp: Time.now.to_i
61
- }
62
- )
63
-
64
- user
65
- end
66
- end
67
- end
1
+ # frozen_string_literal: true
2
+
3
+ # DARE v3.0 — CreateUserService
4
+ # Convention (ADR-01): one service per operation; injected dependencies for testability
5
+ #
6
+ # Usage:
7
+ # result = Services::CreateUserService.new(
8
+ # user_repository: Repositories::UserRepository.new,
9
+ # event_publisher: RealtimeService.instance
10
+ # ).execute(email: "user@example.com", name: "Alice")
11
+ #
12
+ # Returns: User (persisted)
13
+ # Raises: Services::CreateUserService::EmailTakenError
14
+ # ActiveRecord::RecordInvalid (validation failure)
15
+
16
+ module Services
17
+ class CreateUserService
18
+ # ── Domain errors ──────────────────────────────────────────────────────
19
+ class EmailTakenError < StandardError
20
+ def initialize(email)
21
+ super("Email '#{email}' is already registered.")
22
+ end
23
+ end
24
+
25
+ # ── Constructor ────────────────────────────────────────────────────────
26
+ def initialize(user_repository:, event_publisher:)
27
+ @user_repository = user_repository
28
+ @event_publisher = event_publisher
29
+ end
30
+
31
+ # ── Main operation ─────────────────────────────────────────────────────
32
+ def execute(email:, name:, password: nil, **extra_attrs)
33
+ email = email.to_s.downcase.strip
34
+
35
+ # Guard: check for duplicate email
36
+ if @user_repository.find_by_email(email)
37
+ raise EmailTakenError, email
38
+ end
39
+
40
+ # Build and persist
41
+ user = @user_repository.build(
42
+ email: email,
43
+ name: name.to_s.strip,
44
+ active: true,
45
+ **extra_attrs
46
+ )
47
+
48
+ # Hash password if provided (example using has_secure_password)
49
+ user.password = password if password.present?
50
+
51
+ @user_repository.save!(user)
52
+
53
+ # Publish real-time event
54
+ @event_publisher.publish(
55
+ type: "user.created",
56
+ data: {
57
+ user_id: user.id,
58
+ email: user.email,
59
+ name: user.name,
60
+ timestamp: Time.now.to_i
61
+ }
62
+ )
63
+
64
+ user
65
+ end
66
+ end
67
+ end
@@ -1,53 +1,53 @@
1
- # frozen_string_literal: true
2
-
3
- # DARE v3.0 — RealtimeService
4
- # Convention (ADR-03): centralized broadcaster — services call this, not channels directly
5
- # Singleton via .instance; injectable in tests via double
6
- #
7
- # Usage in a Service:
8
- # RealtimeService.instance.publish(
9
- # type: "user.created",
10
- # data: { user_id: 42, email: "user@example.com" }
11
- # )
12
- #
13
- # Frontend receives:
14
- # { type: "user.created", data: { ... }, timestamp: 1234567890 }
15
-
16
- class RealtimeService
17
- include Singleton
18
-
19
- # ── Public API ────────────────────────────────────────────────────────────
20
-
21
- # Broadcast to all subscribers of a channel stream.
22
- # channel_class: e.g. UserUpdatesChannel
23
- # target: e.g. user.id (matched against stream_for in the channel)
24
- # payload: Hash with :type and :data
25
- def broadcast_to(channel_class, target, type:, data: {})
26
- event = build_event(type: type, data: data)
27
- channel_class.broadcast_to(target, event)
28
- end
29
-
30
- # Generic publish: broadcasts to `dare_updates:<user_id>` for all active users.
31
- # Use for system-wide events.
32
- def publish(type:, data: {}, user_id: nil)
33
- event = build_event(type: type, data: data)
34
- stream = user_id ? "dare_updates:#{user_id}" : "dare_updates:global"
35
- ActionCable.server.broadcast(stream, event)
36
- end
37
-
38
- # Publish to a named stream directly (lower-level).
39
- def broadcast_to_stream(stream_name, type:, data: {})
40
- event = build_event(type: type, data: data)
41
- ActionCable.server.broadcast(stream_name, event)
42
- end
43
-
44
- private
45
-
46
- def build_event(type:, data: {})
47
- {
48
- type: type,
49
- data: data,
50
- timestamp: Time.now.to_i
51
- }
52
- end
53
- end
1
+ # frozen_string_literal: true
2
+
3
+ # DARE v3.0 — RealtimeService
4
+ # Convention (ADR-03): centralized broadcaster — services call this, not channels directly
5
+ # Singleton via .instance; injectable in tests via double
6
+ #
7
+ # Usage in a Service:
8
+ # RealtimeService.instance.publish(
9
+ # type: "user.created",
10
+ # data: { user_id: 42, email: "user@example.com" }
11
+ # )
12
+ #
13
+ # Frontend receives:
14
+ # { type: "user.created", data: { ... }, timestamp: 1234567890 }
15
+
16
+ class RealtimeService
17
+ include Singleton
18
+
19
+ # ── Public API ────────────────────────────────────────────────────────────
20
+
21
+ # Broadcast to all subscribers of a channel stream.
22
+ # channel_class: e.g. UserUpdatesChannel
23
+ # target: e.g. user.id (matched against stream_for in the channel)
24
+ # payload: Hash with :type and :data
25
+ def broadcast_to(channel_class, target, type:, data: {})
26
+ event = build_event(type: type, data: data)
27
+ channel_class.broadcast_to(target, event)
28
+ end
29
+
30
+ # Generic publish: broadcasts to `dare_updates:<user_id>` for all active users.
31
+ # Use for system-wide events.
32
+ def publish(type:, data: {}, user_id: nil)
33
+ event = build_event(type: type, data: data)
34
+ stream = user_id ? "dare_updates:#{user_id}" : "dare_updates:global"
35
+ ActionCable.server.broadcast(stream, event)
36
+ end
37
+
38
+ # Publish to a named stream directly (lower-level).
39
+ def broadcast_to_stream(stream_name, type:, data: {})
40
+ event = build_event(type: type, data: data)
41
+ ActionCable.server.broadcast(stream_name, event)
42
+ end
43
+
44
+ private
45
+
46
+ def build_event(type:, data: {})
47
+ {
48
+ type: type,
49
+ data: data,
50
+ timestamp: Time.now.to_i
51
+ }
52
+ end
53
+ end