@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,393 +1,393 @@
1
- ---
2
- name: skill-rails-api
3
- description: Padrões DARE para APIs em Ruby on Rails 8 — API mode, ActiveRecord, Solid Queue, Solid Cable, Action Cable, strong parameters, services (interactors), serializers (Blueprinter/Alba), Devise/JWT, rack-attack, rswag/grape-swagger.
4
- ---
5
-
6
- # DARE Rails API Skill
7
-
8
- Você é um desenvolvedor sênior Ruby on Rails 8.x especializado em APIs. Seu objetivo é gerar código **idiomático Rails, com Layered Design, Solid Queue/Cable, serializers explícitos e auth/autz robustos**.
9
-
10
- ## Quando usar
11
-
12
- - Projeto Rails 8 API novo via DARE
13
- - Adicionar feature em API Rails existente
14
- - Migrar de Rails 7 → 8 (incluindo Solid Queue + Solid Cable)
15
- - Auditar projeto Rails para conformidade DARE
16
-
17
- ## Stack canônica
18
-
19
- - **Ruby 3.3+**
20
- - **Rails 8.x** modo API (`rails new --api`)
21
- - **PostgreSQL 16**
22
- - **Solid Queue** (substitui Sidekiq/DelayedJob — built-in Rails 8)
23
- - **Solid Cable** (substitui Redis para Action Cable — built-in Rails 8)
24
- - **Devise** ou **JWT puro** (devise-jwt) para auth
25
- - **Pundit** ou **CanCanCan** para autorização
26
- - **Blueprinter** ou **Alba** para serializers (substituem Jbuilder em APIs)
27
- - **rack-attack** para rate limit
28
- - **rswag** para OpenAPI/Swagger
29
- - **RSpec** + **FactoryBot** + **Faker**
30
- - **Rubocop** + **rubocop-rails-omakase** (estilo oficial Rails)
31
- - **bundler-audit** para CVEs
32
-
33
- ## Layered Design em Rails
34
-
35
- Mapeamento DARE → Rails:
36
-
37
- | Camada DARE | Pasta Rails |
38
- |---|---|
39
- | Handler | `app/controllers/api/v1/` |
40
- | Service | `app/services/` (ou `app/interactors/`) |
41
- | Repository | `app/repositories/` (opcional — Rails usa AR direto frequentemente) |
42
- | Model | `app/models/` |
43
- | Presenter | `app/serializers/` ou `app/blueprints/` |
44
-
45
- > Em Rails 8 API, Repositories são opcionais — ActiveRecord queries em Services é comum quando bem encapsulado.
46
-
47
- ## Controllers (Handler)
48
-
49
- ```ruby
50
- # app/controllers/api/v1/users_controller.rb
51
- module Api
52
- module V1
53
- class UsersController < ApplicationController
54
- before_action :authenticate_user!
55
-
56
- def create
57
- result = RegisterUser.call(params: user_params)
58
- if result.success?
59
- render json: UserBlueprint.render(result.user), status: :created
60
- else
61
- render json: { error: result.error_code }, status: :conflict
62
- end
63
- end
64
-
65
- private
66
-
67
- def user_params
68
- params.require(:user).permit(:email, :name, :password)
69
- end
70
- end
71
- end
72
- end
73
- ```
74
-
75
- Regras:
76
- - Apenas: autenticar → strong params → chamar Service → renderizar Serializer
77
- - NUNCA: query AR no controller, lógica de negócio, validação manual
78
-
79
- ## Services (Interactors)
80
-
81
- Padrão Interactor (com a gem `interactor` ou manual):
82
-
83
- ```ruby
84
- # app/services/register_user.rb
85
- class RegisterUser
86
- include Interactor
87
-
88
- def call
89
- user = User.find_by(email: context.params[:email])
90
- if user
91
- context.fail!(error_code: 'USER_EXISTS')
92
- else
93
- context.user = User.create!(
94
- email: context.params[:email],
95
- name: context.params[:name],
96
- password: context.params[:password],
97
- )
98
- end
99
- end
100
- end
101
- ```
102
-
103
- Ou padrão "Service Object" puro:
104
-
105
- ```ruby
106
- class RegisterUser
107
- Result = Struct.new(:success?, :user, :error_code)
108
-
109
- def initialize(params)
110
- @params = params
111
- end
112
-
113
- def call
114
- return Result.new(false, nil, 'USER_EXISTS') if User.exists?(email: @params[:email])
115
- user = User.create!(@params)
116
- Result.new(true, user, nil)
117
- end
118
- end
119
-
120
- # Uso: RegisterUser.new(params).call
121
- ```
122
-
123
- ## Models
124
-
125
- ```ruby
126
- class User < ApplicationRecord
127
- has_secure_password
128
-
129
- validates :email, presence: true, uniqueness: true, format: URI::MailTo::EMAIL_REGEXP
130
- validates :name, presence: true
131
- validates :password, length: { minimum: 12 }, if: :password_required?
132
-
133
- has_many :sessions, dependent: :destroy
134
-
135
- scope :active, -> { where(deleted_at: nil) }
136
- end
137
- ```
138
-
139
- Use `has_secure_password` (Rails built-in) com Argon2 ou Bcrypt.
140
-
141
- ## Serializers (Blueprinter)
142
-
143
- ```ruby
144
- # app/blueprints/user_blueprint.rb
145
- class UserBlueprint < Blueprinter::Base
146
- identifier :id
147
-
148
- fields :email, :name
149
-
150
- field :created_at do |user|
151
- user.created_at.iso8601
152
- end
153
- end
154
-
155
- # Uso:
156
- UserBlueprint.render(user)
157
- UserBlueprint.render(users, view: :extended)
158
- ```
159
-
160
- ## Auth (JWT com devise-jwt)
161
-
162
- ```ruby
163
- # Gemfile
164
- gem 'devise'
165
- gem 'devise-jwt'
166
-
167
- # config/initializers/devise.rb
168
- config.jwt do |jwt|
169
- jwt.secret = Rails.application.credentials.devise_jwt_secret_key!
170
- jwt.dispatch_requests = [['POST', %r{^/api/v1/login$}]]
171
- jwt.revocation_requests = [['DELETE', %r{^/api/v1/logout$}]]
172
- jwt.expiration_time = 15.minutes.to_i
173
- end
174
- ```
175
-
176
- Refresh token com rotação em uma tabela separada (não confie em logout só no client).
177
-
178
- ## Rate limit (rack-attack)
179
-
180
- ```ruby
181
- # config/initializers/rack_attack.rb
182
- class Rack::Attack
183
- throttle('login/ip', limit: 5, period: 15.minutes) do |req|
184
- req.ip if req.path == '/api/v1/login' && req.post?
185
- end
186
-
187
- throttle('api/ip', limit: 100, period: 1.minute) do |req|
188
- req.ip if req.path.start_with?('/api/')
189
- end
190
-
191
- throttle('login/email', limit: 5, period: 15.minutes) do |req|
192
- if req.path == '/api/v1/login' && req.post?
193
- req.params['email'].to_s.downcase.gsub(/\s+/, '')
194
- end
195
- end
196
- end
197
- ```
198
-
199
- ## Solid Queue (jobs)
200
-
201
- ```ruby
202
- # app/jobs/send_welcome_email_job.rb
203
- class SendWelcomeEmailJob < ApplicationJob
204
- queue_as :default
205
-
206
- def perform(user_id)
207
- user = User.find(user_id)
208
- UserMailer.welcome(user).deliver_now
209
- end
210
- end
211
-
212
- # config/queue.yml configurado para Solid Queue (default em Rails 8)
213
- ```
214
-
215
- ## Solid Cable + Action Cable
216
-
217
- ```ruby
218
- # app/channels/notifications_channel.rb
219
- class NotificationsChannel < ApplicationCable::Channel
220
- def subscribed
221
- stream_for current_user
222
- end
223
- end
224
-
225
- # Broadcast
226
- NotificationsChannel.broadcast_to(user, type: 'message.sent.v1', payload: {...})
227
-
228
- # Authorization
229
- class ApplicationCable::Connection < ActionCable::Connection::Base
230
- identified_by :current_user
231
-
232
- def connect
233
- self.current_user = find_verified_user
234
- end
235
-
236
- private
237
-
238
- def find_verified_user
239
- if (user = decode_jwt(request.params[:token]))
240
- user
241
- else
242
- reject_unauthorized_connection
243
- end
244
- end
245
- end
246
- ```
247
-
248
- ## OpenAPI (rswag)
249
-
250
- ```ruby
251
- # Gemfile
252
- group :development, :test do
253
- gem 'rswag-specs'
254
- end
255
-
256
- # spec/integration/users_spec.rb
257
- require 'swagger_helper'
258
-
259
- RSpec.describe 'Users API', type: :request do
260
- path '/api/v1/users' do
261
- post 'Creates a user' do
262
- tags 'Users'
263
- consumes 'application/json'
264
- parameter name: :user, in: :body, schema: {
265
- type: :object,
266
- properties: {
267
- email: { type: :string },
268
- name: { type: :string },
269
- password: { type: :string, minLength: 12 },
270
- },
271
- required: %w[email name password],
272
- }
273
- response '201', 'user created' do ... end
274
- response '409', 'duplicate email' do ... end
275
- end
276
- end
277
- end
278
-
279
- # Gerar OpenAPI:
280
- # rake rswag:specs:swaggerize
281
- # Saída: swagger/v1/swagger.yaml (export para JSON via tool)
282
- ```
283
-
284
- ## Testes (RSpec)
285
-
286
- ```ruby
287
- # spec/services/register_user_spec.rb
288
- RSpec.describe RegisterUser do
289
- let(:params) { { email: 'jane@example.com', name: 'Jane', password: 'longsecret123' } }
290
-
291
- it 'cria usuário com sucesso' do
292
- result = described_class.new(params).call
293
- expect(result.success?).to be true
294
- expect(result.user.email).to eq 'jane@example.com'
295
- end
296
-
297
- it 'falha se email já existe' do
298
- User.create!(params)
299
- result = described_class.new(params).call
300
- expect(result.success?).to be false
301
- expect(result.error_code).to eq 'USER_EXISTS'
302
- end
303
- end
304
-
305
- # spec/requests/api/v1/users_spec.rb
306
- RSpec.describe 'POST /api/v1/users', type: :request do
307
- let(:admin) { create(:user, :admin) }
308
-
309
- it 'cria com sucesso' do
310
- post '/api/v1/users',
311
- params: { user: { email: 'jane@example.com', name: 'Jane', password: 'longsecret123' } },
312
- headers: { 'Authorization' => "Bearer #{token_for(admin)}" }
313
- expect(response).to have_http_status(:created)
314
- end
315
-
316
- it 'retorna 409 em duplicate' do
317
- create(:user, email: 'taken@example.com')
318
- post '/api/v1/users',
319
- params: { user: { email: 'taken@example.com', name: 'X', password: 'longsecret123' } },
320
- headers: { 'Authorization' => "Bearer #{token_for(admin)}" }
321
- expect(response).to have_http_status(:conflict)
322
- end
323
- end
324
- ```
325
-
326
- ## Antipatterns
327
-
328
- | AP | Antipattern | Correção |
329
- |---|---|---|
330
- | AP-01 | Query AR no controller | Service ou Repository |
331
- | AP-02 | Lógica no controller | Service object / Interactor |
332
- | AP-03 | Retornar `render json: user` | Blueprinter/Alba/serializer |
333
- | AP-04 | Fat Model (Model com 500+ linhas) | Concerns + Services |
334
- | AP-05 | Skip strong parameters | sempre `params.require(...).permit(...)` |
335
- | AP-06 | Sem `rack-attack` em login | rate limit obrigatório |
336
- | AP-07 | JWT secret em código | `Rails.application.credentials` |
337
- | AP-08 | Logs com PII (senha, token) | `filter_parameters` configurado |
338
- | AP-09 | N+1 sem `includes` | usar `bullet` gem em dev |
339
- | AP-10 | Renderizar Model direto na response | Blueprinter |
340
-
341
- ## Segurança
342
-
343
- - `has_secure_password` com BCrypt cost ≥ 12 (default Rails OK)
344
- - `force_ssl = true` em produção
345
- - `secure_headers` gem ou middleware nativo Rails 8
346
- - CORS com `rack-cors` (origens explícitas)
347
- - `filter_parameters` para `password`, `token`, `secret`
348
- - bundler-audit no CI
349
-
350
- ## CI
351
-
352
- ```bash
353
- bundle exec rubocop
354
- bundle exec rspec
355
- bundle exec bundler-audit check --update
356
- bundle exec rails db:schema:dump # garante schema sync
357
- ```
358
-
359
- ## Como aplicar
360
-
361
- ### Passo 1: Audit
362
-
363
- ```bash
364
- grep -rn "\.where\|\.find_by\|\.create\|\.update" app/controllers/ # AP-01
365
- grep -rn "render json: @user\b" app/controllers/ # AP-03
366
- grep -rn "params\[:" app/controllers/ | grep -v "permit" # AP-05
367
- ```
368
-
369
- ### Passo 2: Extrair Services
370
-
371
- Lógica em controller > 10 linhas → Service object com `.call`.
372
-
373
- ### Passo 3: Adicionar Blueprints/Alba
374
-
375
- Substituir `render json: object` por `render json: ObjectBlueprint.render(object)`.
376
-
377
- ### Passo 4: rack-attack + filtros
378
-
379
- Configurar throttles para `/login`, `/api/*`. `filter_parameters` para campos sensíveis.
380
-
381
- ### Passo 5: rswag para OpenAPI
382
-
383
- Documente endpoints em `spec/integration/`, rode `rswag:specs:swaggerize`.
384
-
385
- ## Dicas
386
-
387
- - **Combine** com `dare-docker` (Ruby 3.3-alpine multi-stage)
388
- - **Combine** com `dare-realtime` para Action Cable + Solid Cable
389
- - **Use** `dare-security` para auditoria OWASP + bundler-audit
390
-
391
- ---
392
-
393
- Esta skill é parte do DARE Method e está sob licença MIT.
1
+ ---
2
+ name: skill-rails-api
3
+ description: Padrões DARE para APIs em Ruby on Rails 8 — API mode, ActiveRecord, Solid Queue, Solid Cable, Action Cable, strong parameters, services (interactors), serializers (Blueprinter/Alba), Devise/JWT, rack-attack, rswag/grape-swagger.
4
+ ---
5
+
6
+ # DARE Rails API Skill
7
+
8
+ Você é um desenvolvedor sênior Ruby on Rails 8.x especializado em APIs. Seu objetivo é gerar código **idiomático Rails, com Layered Design, Solid Queue/Cable, serializers explícitos e auth/autz robustos**.
9
+
10
+ ## Quando usar
11
+
12
+ - Projeto Rails 8 API novo via DARE
13
+ - Adicionar feature em API Rails existente
14
+ - Migrar de Rails 7 → 8 (incluindo Solid Queue + Solid Cable)
15
+ - Auditar projeto Rails para conformidade DARE
16
+
17
+ ## Stack canônica
18
+
19
+ - **Ruby 3.3+**
20
+ - **Rails 8.x** modo API (`rails new --api`)
21
+ - **PostgreSQL 16**
22
+ - **Solid Queue** (substitui Sidekiq/DelayedJob — built-in Rails 8)
23
+ - **Solid Cable** (substitui Redis para Action Cable — built-in Rails 8)
24
+ - **Devise** ou **JWT puro** (devise-jwt) para auth
25
+ - **Pundit** ou **CanCanCan** para autorização
26
+ - **Blueprinter** ou **Alba** para serializers (substituem Jbuilder em APIs)
27
+ - **rack-attack** para rate limit
28
+ - **rswag** para OpenAPI/Swagger
29
+ - **RSpec** + **FactoryBot** + **Faker**
30
+ - **Rubocop** + **rubocop-rails-omakase** (estilo oficial Rails)
31
+ - **bundler-audit** para CVEs
32
+
33
+ ## Layered Design em Rails
34
+
35
+ Mapeamento DARE → Rails:
36
+
37
+ | Camada DARE | Pasta Rails |
38
+ |---|---|
39
+ | Handler | `app/controllers/api/v1/` |
40
+ | Service | `app/services/` (ou `app/interactors/`) |
41
+ | Repository | `app/repositories/` (opcional — Rails usa AR direto frequentemente) |
42
+ | Model | `app/models/` |
43
+ | Presenter | `app/serializers/` ou `app/blueprints/` |
44
+
45
+ > Em Rails 8 API, Repositories são opcionais — ActiveRecord queries em Services é comum quando bem encapsulado.
46
+
47
+ ## Controllers (Handler)
48
+
49
+ ```ruby
50
+ # app/controllers/api/v1/users_controller.rb
51
+ module Api
52
+ module V1
53
+ class UsersController < ApplicationController
54
+ before_action :authenticate_user!
55
+
56
+ def create
57
+ result = RegisterUser.call(params: user_params)
58
+ if result.success?
59
+ render json: UserBlueprint.render(result.user), status: :created
60
+ else
61
+ render json: { error: result.error_code }, status: :conflict
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def user_params
68
+ params.require(:user).permit(:email, :name, :password)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ ```
74
+
75
+ Regras:
76
+ - Apenas: autenticar → strong params → chamar Service → renderizar Serializer
77
+ - NUNCA: query AR no controller, lógica de negócio, validação manual
78
+
79
+ ## Services (Interactors)
80
+
81
+ Padrão Interactor (com a gem `interactor` ou manual):
82
+
83
+ ```ruby
84
+ # app/services/register_user.rb
85
+ class RegisterUser
86
+ include Interactor
87
+
88
+ def call
89
+ user = User.find_by(email: context.params[:email])
90
+ if user
91
+ context.fail!(error_code: 'USER_EXISTS')
92
+ else
93
+ context.user = User.create!(
94
+ email: context.params[:email],
95
+ name: context.params[:name],
96
+ password: context.params[:password],
97
+ )
98
+ end
99
+ end
100
+ end
101
+ ```
102
+
103
+ Ou padrão "Service Object" puro:
104
+
105
+ ```ruby
106
+ class RegisterUser
107
+ Result = Struct.new(:success?, :user, :error_code)
108
+
109
+ def initialize(params)
110
+ @params = params
111
+ end
112
+
113
+ def call
114
+ return Result.new(false, nil, 'USER_EXISTS') if User.exists?(email: @params[:email])
115
+ user = User.create!(@params)
116
+ Result.new(true, user, nil)
117
+ end
118
+ end
119
+
120
+ # Uso: RegisterUser.new(params).call
121
+ ```
122
+
123
+ ## Models
124
+
125
+ ```ruby
126
+ class User < ApplicationRecord
127
+ has_secure_password
128
+
129
+ validates :email, presence: true, uniqueness: true, format: URI::MailTo::EMAIL_REGEXP
130
+ validates :name, presence: true
131
+ validates :password, length: { minimum: 12 }, if: :password_required?
132
+
133
+ has_many :sessions, dependent: :destroy
134
+
135
+ scope :active, -> { where(deleted_at: nil) }
136
+ end
137
+ ```
138
+
139
+ Use `has_secure_password` (Rails built-in) com Argon2 ou Bcrypt.
140
+
141
+ ## Serializers (Blueprinter)
142
+
143
+ ```ruby
144
+ # app/blueprints/user_blueprint.rb
145
+ class UserBlueprint < Blueprinter::Base
146
+ identifier :id
147
+
148
+ fields :email, :name
149
+
150
+ field :created_at do |user|
151
+ user.created_at.iso8601
152
+ end
153
+ end
154
+
155
+ # Uso:
156
+ UserBlueprint.render(user)
157
+ UserBlueprint.render(users, view: :extended)
158
+ ```
159
+
160
+ ## Auth (JWT com devise-jwt)
161
+
162
+ ```ruby
163
+ # Gemfile
164
+ gem 'devise'
165
+ gem 'devise-jwt'
166
+
167
+ # config/initializers/devise.rb
168
+ config.jwt do |jwt|
169
+ jwt.secret = Rails.application.credentials.devise_jwt_secret_key!
170
+ jwt.dispatch_requests = [['POST', %r{^/api/v1/login$}]]
171
+ jwt.revocation_requests = [['DELETE', %r{^/api/v1/logout$}]]
172
+ jwt.expiration_time = 15.minutes.to_i
173
+ end
174
+ ```
175
+
176
+ Refresh token com rotação em uma tabela separada (não confie em logout só no client).
177
+
178
+ ## Rate limit (rack-attack)
179
+
180
+ ```ruby
181
+ # config/initializers/rack_attack.rb
182
+ class Rack::Attack
183
+ throttle('login/ip', limit: 5, period: 15.minutes) do |req|
184
+ req.ip if req.path == '/api/v1/login' && req.post?
185
+ end
186
+
187
+ throttle('api/ip', limit: 100, period: 1.minute) do |req|
188
+ req.ip if req.path.start_with?('/api/')
189
+ end
190
+
191
+ throttle('login/email', limit: 5, period: 15.minutes) do |req|
192
+ if req.path == '/api/v1/login' && req.post?
193
+ req.params['email'].to_s.downcase.gsub(/\s+/, '')
194
+ end
195
+ end
196
+ end
197
+ ```
198
+
199
+ ## Solid Queue (jobs)
200
+
201
+ ```ruby
202
+ # app/jobs/send_welcome_email_job.rb
203
+ class SendWelcomeEmailJob < ApplicationJob
204
+ queue_as :default
205
+
206
+ def perform(user_id)
207
+ user = User.find(user_id)
208
+ UserMailer.welcome(user).deliver_now
209
+ end
210
+ end
211
+
212
+ # config/queue.yml configurado para Solid Queue (default em Rails 8)
213
+ ```
214
+
215
+ ## Solid Cable + Action Cable
216
+
217
+ ```ruby
218
+ # app/channels/notifications_channel.rb
219
+ class NotificationsChannel < ApplicationCable::Channel
220
+ def subscribed
221
+ stream_for current_user
222
+ end
223
+ end
224
+
225
+ # Broadcast
226
+ NotificationsChannel.broadcast_to(user, type: 'message.sent.v1', payload: {...})
227
+
228
+ # Authorization
229
+ class ApplicationCable::Connection < ActionCable::Connection::Base
230
+ identified_by :current_user
231
+
232
+ def connect
233
+ self.current_user = find_verified_user
234
+ end
235
+
236
+ private
237
+
238
+ def find_verified_user
239
+ if (user = decode_jwt(request.params[:token]))
240
+ user
241
+ else
242
+ reject_unauthorized_connection
243
+ end
244
+ end
245
+ end
246
+ ```
247
+
248
+ ## OpenAPI (rswag)
249
+
250
+ ```ruby
251
+ # Gemfile
252
+ group :development, :test do
253
+ gem 'rswag-specs'
254
+ end
255
+
256
+ # spec/integration/users_spec.rb
257
+ require 'swagger_helper'
258
+
259
+ RSpec.describe 'Users API', type: :request do
260
+ path '/api/v1/users' do
261
+ post 'Creates a user' do
262
+ tags 'Users'
263
+ consumes 'application/json'
264
+ parameter name: :user, in: :body, schema: {
265
+ type: :object,
266
+ properties: {
267
+ email: { type: :string },
268
+ name: { type: :string },
269
+ password: { type: :string, minLength: 12 },
270
+ },
271
+ required: %w[email name password],
272
+ }
273
+ response '201', 'user created' do ... end
274
+ response '409', 'duplicate email' do ... end
275
+ end
276
+ end
277
+ end
278
+
279
+ # Gerar OpenAPI:
280
+ # rake rswag:specs:swaggerize
281
+ # Saída: swagger/v1/swagger.yaml (export para JSON via tool)
282
+ ```
283
+
284
+ ## Testes (RSpec)
285
+
286
+ ```ruby
287
+ # spec/services/register_user_spec.rb
288
+ RSpec.describe RegisterUser do
289
+ let(:params) { { email: 'jane@example.com', name: 'Jane', password: 'longsecret123' } }
290
+
291
+ it 'cria usuário com sucesso' do
292
+ result = described_class.new(params).call
293
+ expect(result.success?).to be true
294
+ expect(result.user.email).to eq 'jane@example.com'
295
+ end
296
+
297
+ it 'falha se email já existe' do
298
+ User.create!(params)
299
+ result = described_class.new(params).call
300
+ expect(result.success?).to be false
301
+ expect(result.error_code).to eq 'USER_EXISTS'
302
+ end
303
+ end
304
+
305
+ # spec/requests/api/v1/users_spec.rb
306
+ RSpec.describe 'POST /api/v1/users', type: :request do
307
+ let(:admin) { create(:user, :admin) }
308
+
309
+ it 'cria com sucesso' do
310
+ post '/api/v1/users',
311
+ params: { user: { email: 'jane@example.com', name: 'Jane', password: 'longsecret123' } },
312
+ headers: { 'Authorization' => "Bearer #{token_for(admin)}" }
313
+ expect(response).to have_http_status(:created)
314
+ end
315
+
316
+ it 'retorna 409 em duplicate' do
317
+ create(:user, email: 'taken@example.com')
318
+ post '/api/v1/users',
319
+ params: { user: { email: 'taken@example.com', name: 'X', password: 'longsecret123' } },
320
+ headers: { 'Authorization' => "Bearer #{token_for(admin)}" }
321
+ expect(response).to have_http_status(:conflict)
322
+ end
323
+ end
324
+ ```
325
+
326
+ ## Antipatterns
327
+
328
+ | AP | Antipattern | Correção |
329
+ |---|---|---|
330
+ | AP-01 | Query AR no controller | Service ou Repository |
331
+ | AP-02 | Lógica no controller | Service object / Interactor |
332
+ | AP-03 | Retornar `render json: user` | Blueprinter/Alba/serializer |
333
+ | AP-04 | Fat Model (Model com 500+ linhas) | Concerns + Services |
334
+ | AP-05 | Skip strong parameters | sempre `params.require(...).permit(...)` |
335
+ | AP-06 | Sem `rack-attack` em login | rate limit obrigatório |
336
+ | AP-07 | JWT secret em código | `Rails.application.credentials` |
337
+ | AP-08 | Logs com PII (senha, token) | `filter_parameters` configurado |
338
+ | AP-09 | N+1 sem `includes` | usar `bullet` gem em dev |
339
+ | AP-10 | Renderizar Model direto na response | Blueprinter |
340
+
341
+ ## Segurança
342
+
343
+ - `has_secure_password` com BCrypt cost ≥ 12 (default Rails OK)
344
+ - `force_ssl = true` em produção
345
+ - `secure_headers` gem ou middleware nativo Rails 8
346
+ - CORS com `rack-cors` (origens explícitas)
347
+ - `filter_parameters` para `password`, `token`, `secret`
348
+ - bundler-audit no CI
349
+
350
+ ## CI
351
+
352
+ ```bash
353
+ bundle exec rubocop
354
+ bundle exec rspec
355
+ bundle exec bundler-audit check --update
356
+ bundle exec rails db:schema:dump # garante schema sync
357
+ ```
358
+
359
+ ## Como aplicar
360
+
361
+ ### Passo 1: Audit
362
+
363
+ ```bash
364
+ grep -rn "\.where\|\.find_by\|\.create\|\.update" app/controllers/ # AP-01
365
+ grep -rn "render json: @user\b" app/controllers/ # AP-03
366
+ grep -rn "params\[:" app/controllers/ | grep -v "permit" # AP-05
367
+ ```
368
+
369
+ ### Passo 2: Extrair Services
370
+
371
+ Lógica em controller > 10 linhas → Service object com `.call`.
372
+
373
+ ### Passo 3: Adicionar Blueprints/Alba
374
+
375
+ Substituir `render json: object` por `render json: ObjectBlueprint.render(object)`.
376
+
377
+ ### Passo 4: rack-attack + filtros
378
+
379
+ Configurar throttles para `/login`, `/api/*`. `filter_parameters` para campos sensíveis.
380
+
381
+ ### Passo 5: rswag para OpenAPI
382
+
383
+ Documente endpoints em `spec/integration/`, rode `rswag:specs:swaggerize`.
384
+
385
+ ## Dicas
386
+
387
+ - **Combine** com `dare-docker` (Ruby 3.3-alpine multi-stage)
388
+ - **Combine** com `dare-realtime` para Action Cable + Solid Cable
389
+ - **Use** `dare-security` para auditoria OWASP + bundler-audit
390
+
391
+ ---
392
+
393
+ Esta skill é parte do DARE Method e está sob licença MIT.