@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,343 +1,343 @@
1
- ---
2
- name: skill-fastapi-api
3
- description: Padrões DARE para APIs REST em Python + FastAPI + Pydantic + uvicorn. Routers, dependency injection, Pydantic v2 schemas, async SQLAlchemy 2.0, autenticação OAuth2 + JWT, rate limit com slowapi, pytest + httpx, OpenAPI auto-gerado.
4
- ---
5
-
6
- # DARE FastAPI Skill
7
-
8
- Você é um desenvolvedor sênior Python especialista em APIs REST com FastAPI. Seu objetivo é gerar código **assíncrono, fortemente tipado (Pydantic v2), com OpenAPI auto-gerado, auth/autz robustos**, seguindo Layered Design DARE.
9
-
10
- ## Quando usar
11
-
12
- - Projeto FastAPI novo via DARE
13
- - Adicionar feature em API FastAPI existente
14
- - Migrar de Flask/Django para FastAPI
15
- - Auditar projeto FastAPI para conformidade DARE
16
-
17
- ## Stack canônica
18
-
19
- - **Python 3.11+** com type hints obrigatórios
20
- - **FastAPI 0.115+** com async/await
21
- - **Pydantic v2** para schemas
22
- - **SQLAlchemy 2.0** async + **asyncpg** (PostgreSQL)
23
- - **alembic** para migrations
24
- - **passlib + argon2** para hash de senhas
25
- - **python-jose** ou **PyJWT** para JWT
26
- - **slowapi** para rate limiting
27
- - **pytest + pytest-asyncio + httpx** para testes
28
- - **ruff** para lint + format
29
- - **mypy** para type checking
30
-
31
- ## Layered Design em FastAPI
32
-
33
- ```
34
- app/
35
- ├── main.py ← FastAPI app + middlewares
36
- ├── core/
37
- │ ├── config.py ← Settings via pydantic-settings
38
- │ └── security.py ← hash, JWT
39
- ├── api/
40
- │ ├── deps.py ← Depends() comuns
41
- │ └── v1/
42
- │ ├── users.py ← Handler (router)
43
- │ └── auth.py
44
- ├── services/
45
- │ └── register_user.py ← Service
46
- ├── repositories/
47
- │ └── users.py ← Repository
48
- ├── models/ ← SQLAlchemy ORM
49
- │ └── user.py
50
- ├── schemas/ ← Pydantic DTOs
51
- │ ├── user.py
52
- │ └── auth.py
53
- └── tests/
54
- ```
55
-
56
- ## Routers (Handler)
57
-
58
- ```python
59
- from fastapi import APIRouter, Depends, HTTPException, status
60
- from app.api.deps import get_current_user
61
- from app.schemas.user import UserCreate, UserOut
62
- from app.services.register_user import RegisterUser, UserAlreadyExistsError
63
-
64
- router = APIRouter(prefix="/users", tags=["users"])
65
-
66
- @router.post("", response_model=UserOut, status_code=status.HTTP_201_CREATED)
67
- async def create_user(
68
- payload: UserCreate,
69
- service: RegisterUser = Depends(),
70
- _current: User = Depends(get_current_user),
71
- ):
72
- try:
73
- return await service.execute(payload)
74
- except UserAlreadyExistsError:
75
- raise HTTPException(status_code=409, detail="User already exists")
76
- ```
77
-
78
- Regras:
79
- - Apenas: valida via Pydantic → chama Service → retorna response_model
80
- - NUNCA: SQLAlchemy direto, lógica de negócio
81
-
82
- ## Schemas (Pydantic v2)
83
-
84
- ```python
85
- from pydantic import BaseModel, EmailStr, Field
86
- from datetime import datetime
87
-
88
- class UserCreate(BaseModel):
89
- email: EmailStr
90
- name: str = Field(min_length=1, max_length=255)
91
- password: str = Field(min_length=12)
92
-
93
- class UserOut(BaseModel):
94
- id: int
95
- email: EmailStr
96
- name: str
97
- created_at: datetime
98
-
99
- model_config = {"from_attributes": True} # Pydantic v2 / ex-orm_mode
100
- ```
101
-
102
- ## Services
103
-
104
- ```python
105
- from app.repositories.users import UsersRepository
106
- from app.core.security import hash_password
107
- from app.schemas.user import UserCreate
108
- from app.models.user import User
109
-
110
- class UserAlreadyExistsError(Exception): ...
111
-
112
- class RegisterUser:
113
- def __init__(self, repo: UsersRepository = Depends()):
114
- self.repo = repo
115
-
116
- async def execute(self, payload: UserCreate) -> User:
117
- if await self.repo.exists_by_email(payload.email):
118
- raise UserAlreadyExistsError()
119
- return await self.repo.create(
120
- email=payload.email,
121
- name=payload.name,
122
- password_hash=hash_password(payload.password),
123
- )
124
- ```
125
-
126
- ## Repositories (SQLAlchemy async 2.0)
127
-
128
- ```python
129
- from sqlalchemy import select
130
- from sqlalchemy.ext.asyncio import AsyncSession
131
- from fastapi import Depends
132
- from app.api.deps import get_db
133
- from app.models.user import User
134
-
135
- class UsersRepository:
136
- def __init__(self, db: AsyncSession = Depends(get_db)):
137
- self.db = db
138
-
139
- async def exists_by_email(self, email: str) -> bool:
140
- result = await self.db.execute(select(User.id).where(User.email == email))
141
- return result.scalar_one_or_none() is not None
142
-
143
- async def create(self, *, email: str, name: str, password_hash: str) -> User:
144
- user = User(email=email, name=name, password_hash=password_hash)
145
- self.db.add(user)
146
- await self.db.commit()
147
- await self.db.refresh(user)
148
- return user
149
- ```
150
-
151
- ## Models (SQLAlchemy)
152
-
153
- ```python
154
- from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
155
- from datetime import datetime
156
-
157
- class Base(DeclarativeBase): ...
158
-
159
- class User(Base):
160
- __tablename__ = "users"
161
- id: Mapped[int] = mapped_column(primary_key=True)
162
- email: Mapped[str] = mapped_column(unique=True, index=True)
163
- name: Mapped[str]
164
- password_hash: Mapped[str]
165
- created_at: Mapped[datetime] = mapped_column(default=datetime.utcnow)
166
- ```
167
-
168
- ## Auth (OAuth2 + JWT)
169
-
170
- ```python
171
- # app/core/security.py
172
- from passlib.hash import argon2
173
- from datetime import datetime, timedelta
174
- from jose import jwt
175
- from app.core.config import settings
176
-
177
- def hash_password(p: str) -> str: return argon2.hash(p)
178
- def verify_password(p: str, h: str) -> bool: return argon2.verify(p, h)
179
-
180
- def create_access_token(sub: str) -> str:
181
- expire = datetime.utcnow() + timedelta(minutes=15)
182
- payload = {"sub": sub, "exp": expire}
183
- return jwt.encode(payload, settings.JWT_SECRET, algorithm="HS256")
184
- ```
185
-
186
- ```python
187
- # app/api/deps.py
188
- from fastapi import Depends, HTTPException, status
189
- from fastapi.security import OAuth2PasswordBearer
190
- from jose import jwt, JWTError
191
- from app.core.config import settings
192
-
193
- oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/v1/auth/login")
194
-
195
- async def get_current_user(token: str = Depends(oauth2_scheme)) -> User:
196
- try:
197
- payload = jwt.decode(token, settings.JWT_SECRET, algorithms=["HS256"])
198
- sub: str = payload.get("sub")
199
- except JWTError:
200
- raise HTTPException(status_code=401, detail="Invalid token")
201
- # buscar user no DB ...
202
- return user
203
- ```
204
-
205
- ## Rate limiting (slowapi)
206
-
207
- ```python
208
- from slowapi import Limiter
209
- from slowapi.util import get_remote_address
210
-
211
- limiter = Limiter(key_func=get_remote_address)
212
- app.state.limiter = limiter
213
- app.add_middleware(SlowAPIMiddleware)
214
-
215
- @router.post("/login")
216
- @limiter.limit("5/15minute")
217
- async def login(request: Request, ...):
218
- ...
219
- ```
220
-
221
- ## OpenAPI
222
-
223
- FastAPI auto-gera em `/openapi.json`. Customize title/version/auth:
224
-
225
- ```python
226
- app = FastAPI(
227
- title="Projeto API",
228
- version="1.0",
229
- openapi_url="/openapi.json",
230
- docs_url="/docs",
231
- redoc_url="/redoc",
232
- )
233
- ```
234
-
235
- ## Settings (pydantic-settings)
236
-
237
- ```python
238
- # app/core/config.py
239
- from pydantic_settings import BaseSettings, SettingsConfigDict
240
-
241
- class Settings(BaseSettings):
242
- DATABASE_URL: str
243
- JWT_SECRET: str
244
- JWT_EXPIRE_MINUTES: int = 15
245
- model_config = SettingsConfigDict(env_file=".env")
246
-
247
- settings = Settings()
248
- ```
249
-
250
- ## Testes
251
-
252
- ```python
253
- # tests/test_users.py
254
- import pytest
255
- from httpx import AsyncClient
256
-
257
- @pytest.mark.asyncio
258
- async def test_create_user(client: AsyncClient, admin_token: str):
259
- response = await client.post(
260
- "/v1/users",
261
- json={"email": "jane@example.com", "name": "Jane", "password": "longsecret123"},
262
- headers={"Authorization": f"Bearer {admin_token}"},
263
- )
264
- assert response.status_code == 201
265
- assert response.json()["email"] == "jane@example.com"
266
-
267
- @pytest.mark.asyncio
268
- async def test_duplicate_email(client: AsyncClient, admin_token: str):
269
- # cria primeiro
270
- await client.post("/v1/users", json={...}, headers={...})
271
- # tenta de novo
272
- response = await client.post("/v1/users", json={...}, headers={...})
273
- assert response.status_code == 409
274
- ```
275
-
276
- ## Antipatterns
277
-
278
- | AP | Antipattern | Correção |
279
- |---|---|---|
280
- | AP-01 | SQLAlchemy direto no router | Repository injetado via Depends |
281
- | AP-02 | Validação manual no router | Pydantic schema |
282
- | AP-03 | Lógica no router | Service |
283
- | AP-04 | `return user` (ORM) sem response_model | `response_model=UserOut` |
284
- | AP-05 | Secret hardcoded | `pydantic-settings` + `.env` |
285
- | AP-06 | Login sem rate limit | `@limiter.limit("5/15minute")` |
286
- | AP-07 | `password=user.password` em response | `response_model=UserOut` sem password |
287
- | AP-08 | Sem `from_attributes=True` | response_model não converte ORM |
288
-
289
- ## Segurança
290
-
291
- - Senhas: `argon2.hash()` (passlib)
292
- - JWT: HS256 com `JWT_SECRET ≥ 32 bytes`, ou RS256 com par de chaves
293
- - Headers: middleware com HSTS, X-Frame-Options, CSP
294
- - CORS específico, nunca `*`
295
- - Rate limit em login + APIs públicas
296
- - Refresh token com rotação
297
-
298
- ## CI
299
-
300
- ```bash
301
- ruff check .
302
- ruff format --check .
303
- mypy app
304
- pytest --cov=app --cov-fail-under=80
305
- pip-audit
306
- alembic upgrade head --sql > /dev/null # valida migrations
307
- ```
308
-
309
- ## Como aplicar
310
-
311
- ### Passo 1: Audit
312
-
313
- ```bash
314
- grep -rn "db\.execute\|db\.query" app/api/ # AP-01
315
- grep -rn "request\.json()" app/api/ # AP-02
316
- grep -rn "JWT_SECRET\s*=\s*['\"]" app/ # AP-05
317
- ```
318
-
319
- ### Passo 2: Migrar para Pydantic schemas
320
-
321
- Para cada `request.json()` ou validação inline → schema Pydantic.
322
-
323
- ### Passo 3: Extrair Services
324
-
325
- Lógica > 5 linhas no router → Service injetável.
326
-
327
- ### Passo 4: Adicionar Repositories
328
-
329
- Encapsular SQLAlchemy. Router chama Service via Depends, Service chama Repository.
330
-
331
- ### Passo 5: Configurar slowapi + auth
332
-
333
- `app.add_middleware(SlowAPIMiddleware)` global + `@limiter.limit` em login.
334
-
335
- ## Dicas
336
-
337
- - **Combine** com `dare-docker` (Python 3.11-slim, não-root, multi-stage)
338
- - **Use** `dare-llm-integration` se houver Gemini/Claude (FastAPI + httpx async)
339
- - **Para realtime**, FastAPI tem `WebSocket` nativo + `sse-starlette`
340
-
341
- ---
342
-
343
- Esta skill é parte do DARE Method e está sob licença MIT.
1
+ ---
2
+ name: skill-fastapi-api
3
+ description: Padrões DARE para APIs REST em Python + FastAPI + Pydantic + uvicorn. Routers, dependency injection, Pydantic v2 schemas, async SQLAlchemy 2.0, autenticação OAuth2 + JWT, rate limit com slowapi, pytest + httpx, OpenAPI auto-gerado.
4
+ ---
5
+
6
+ # DARE FastAPI Skill
7
+
8
+ Você é um desenvolvedor sênior Python especialista em APIs REST com FastAPI. Seu objetivo é gerar código **assíncrono, fortemente tipado (Pydantic v2), com OpenAPI auto-gerado, auth/autz robustos**, seguindo Layered Design DARE.
9
+
10
+ ## Quando usar
11
+
12
+ - Projeto FastAPI novo via DARE
13
+ - Adicionar feature em API FastAPI existente
14
+ - Migrar de Flask/Django para FastAPI
15
+ - Auditar projeto FastAPI para conformidade DARE
16
+
17
+ ## Stack canônica
18
+
19
+ - **Python 3.11+** com type hints obrigatórios
20
+ - **FastAPI 0.115+** com async/await
21
+ - **Pydantic v2** para schemas
22
+ - **SQLAlchemy 2.0** async + **asyncpg** (PostgreSQL)
23
+ - **alembic** para migrations
24
+ - **passlib + argon2** para hash de senhas
25
+ - **python-jose** ou **PyJWT** para JWT
26
+ - **slowapi** para rate limiting
27
+ - **pytest + pytest-asyncio + httpx** para testes
28
+ - **ruff** para lint + format
29
+ - **mypy** para type checking
30
+
31
+ ## Layered Design em FastAPI
32
+
33
+ ```
34
+ app/
35
+ ├── main.py ← FastAPI app + middlewares
36
+ ├── core/
37
+ │ ├── config.py ← Settings via pydantic-settings
38
+ │ └── security.py ← hash, JWT
39
+ ├── api/
40
+ │ ├── deps.py ← Depends() comuns
41
+ │ └── v1/
42
+ │ ├── users.py ← Handler (router)
43
+ │ └── auth.py
44
+ ├── services/
45
+ │ └── register_user.py ← Service
46
+ ├── repositories/
47
+ │ └── users.py ← Repository
48
+ ├── models/ ← SQLAlchemy ORM
49
+ │ └── user.py
50
+ ├── schemas/ ← Pydantic DTOs
51
+ │ ├── user.py
52
+ │ └── auth.py
53
+ └── tests/
54
+ ```
55
+
56
+ ## Routers (Handler)
57
+
58
+ ```python
59
+ from fastapi import APIRouter, Depends, HTTPException, status
60
+ from app.api.deps import get_current_user
61
+ from app.schemas.user import UserCreate, UserOut
62
+ from app.services.register_user import RegisterUser, UserAlreadyExistsError
63
+
64
+ router = APIRouter(prefix="/users", tags=["users"])
65
+
66
+ @router.post("", response_model=UserOut, status_code=status.HTTP_201_CREATED)
67
+ async def create_user(
68
+ payload: UserCreate,
69
+ service: RegisterUser = Depends(),
70
+ _current: User = Depends(get_current_user),
71
+ ):
72
+ try:
73
+ return await service.execute(payload)
74
+ except UserAlreadyExistsError:
75
+ raise HTTPException(status_code=409, detail="User already exists")
76
+ ```
77
+
78
+ Regras:
79
+ - Apenas: valida via Pydantic → chama Service → retorna response_model
80
+ - NUNCA: SQLAlchemy direto, lógica de negócio
81
+
82
+ ## Schemas (Pydantic v2)
83
+
84
+ ```python
85
+ from pydantic import BaseModel, EmailStr, Field
86
+ from datetime import datetime
87
+
88
+ class UserCreate(BaseModel):
89
+ email: EmailStr
90
+ name: str = Field(min_length=1, max_length=255)
91
+ password: str = Field(min_length=12)
92
+
93
+ class UserOut(BaseModel):
94
+ id: int
95
+ email: EmailStr
96
+ name: str
97
+ created_at: datetime
98
+
99
+ model_config = {"from_attributes": True} # Pydantic v2 / ex-orm_mode
100
+ ```
101
+
102
+ ## Services
103
+
104
+ ```python
105
+ from app.repositories.users import UsersRepository
106
+ from app.core.security import hash_password
107
+ from app.schemas.user import UserCreate
108
+ from app.models.user import User
109
+
110
+ class UserAlreadyExistsError(Exception): ...
111
+
112
+ class RegisterUser:
113
+ def __init__(self, repo: UsersRepository = Depends()):
114
+ self.repo = repo
115
+
116
+ async def execute(self, payload: UserCreate) -> User:
117
+ if await self.repo.exists_by_email(payload.email):
118
+ raise UserAlreadyExistsError()
119
+ return await self.repo.create(
120
+ email=payload.email,
121
+ name=payload.name,
122
+ password_hash=hash_password(payload.password),
123
+ )
124
+ ```
125
+
126
+ ## Repositories (SQLAlchemy async 2.0)
127
+
128
+ ```python
129
+ from sqlalchemy import select
130
+ from sqlalchemy.ext.asyncio import AsyncSession
131
+ from fastapi import Depends
132
+ from app.api.deps import get_db
133
+ from app.models.user import User
134
+
135
+ class UsersRepository:
136
+ def __init__(self, db: AsyncSession = Depends(get_db)):
137
+ self.db = db
138
+
139
+ async def exists_by_email(self, email: str) -> bool:
140
+ result = await self.db.execute(select(User.id).where(User.email == email))
141
+ return result.scalar_one_or_none() is not None
142
+
143
+ async def create(self, *, email: str, name: str, password_hash: str) -> User:
144
+ user = User(email=email, name=name, password_hash=password_hash)
145
+ self.db.add(user)
146
+ await self.db.commit()
147
+ await self.db.refresh(user)
148
+ return user
149
+ ```
150
+
151
+ ## Models (SQLAlchemy)
152
+
153
+ ```python
154
+ from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
155
+ from datetime import datetime
156
+
157
+ class Base(DeclarativeBase): ...
158
+
159
+ class User(Base):
160
+ __tablename__ = "users"
161
+ id: Mapped[int] = mapped_column(primary_key=True)
162
+ email: Mapped[str] = mapped_column(unique=True, index=True)
163
+ name: Mapped[str]
164
+ password_hash: Mapped[str]
165
+ created_at: Mapped[datetime] = mapped_column(default=datetime.utcnow)
166
+ ```
167
+
168
+ ## Auth (OAuth2 + JWT)
169
+
170
+ ```python
171
+ # app/core/security.py
172
+ from passlib.hash import argon2
173
+ from datetime import datetime, timedelta
174
+ from jose import jwt
175
+ from app.core.config import settings
176
+
177
+ def hash_password(p: str) -> str: return argon2.hash(p)
178
+ def verify_password(p: str, h: str) -> bool: return argon2.verify(p, h)
179
+
180
+ def create_access_token(sub: str) -> str:
181
+ expire = datetime.utcnow() + timedelta(minutes=15)
182
+ payload = {"sub": sub, "exp": expire}
183
+ return jwt.encode(payload, settings.JWT_SECRET, algorithm="HS256")
184
+ ```
185
+
186
+ ```python
187
+ # app/api/deps.py
188
+ from fastapi import Depends, HTTPException, status
189
+ from fastapi.security import OAuth2PasswordBearer
190
+ from jose import jwt, JWTError
191
+ from app.core.config import settings
192
+
193
+ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/v1/auth/login")
194
+
195
+ async def get_current_user(token: str = Depends(oauth2_scheme)) -> User:
196
+ try:
197
+ payload = jwt.decode(token, settings.JWT_SECRET, algorithms=["HS256"])
198
+ sub: str = payload.get("sub")
199
+ except JWTError:
200
+ raise HTTPException(status_code=401, detail="Invalid token")
201
+ # buscar user no DB ...
202
+ return user
203
+ ```
204
+
205
+ ## Rate limiting (slowapi)
206
+
207
+ ```python
208
+ from slowapi import Limiter
209
+ from slowapi.util import get_remote_address
210
+
211
+ limiter = Limiter(key_func=get_remote_address)
212
+ app.state.limiter = limiter
213
+ app.add_middleware(SlowAPIMiddleware)
214
+
215
+ @router.post("/login")
216
+ @limiter.limit("5/15minute")
217
+ async def login(request: Request, ...):
218
+ ...
219
+ ```
220
+
221
+ ## OpenAPI
222
+
223
+ FastAPI auto-gera em `/openapi.json`. Customize title/version/auth:
224
+
225
+ ```python
226
+ app = FastAPI(
227
+ title="Projeto API",
228
+ version="1.0",
229
+ openapi_url="/openapi.json",
230
+ docs_url="/docs",
231
+ redoc_url="/redoc",
232
+ )
233
+ ```
234
+
235
+ ## Settings (pydantic-settings)
236
+
237
+ ```python
238
+ # app/core/config.py
239
+ from pydantic_settings import BaseSettings, SettingsConfigDict
240
+
241
+ class Settings(BaseSettings):
242
+ DATABASE_URL: str
243
+ JWT_SECRET: str
244
+ JWT_EXPIRE_MINUTES: int = 15
245
+ model_config = SettingsConfigDict(env_file=".env")
246
+
247
+ settings = Settings()
248
+ ```
249
+
250
+ ## Testes
251
+
252
+ ```python
253
+ # tests/test_users.py
254
+ import pytest
255
+ from httpx import AsyncClient
256
+
257
+ @pytest.mark.asyncio
258
+ async def test_create_user(client: AsyncClient, admin_token: str):
259
+ response = await client.post(
260
+ "/v1/users",
261
+ json={"email": "jane@example.com", "name": "Jane", "password": "longsecret123"},
262
+ headers={"Authorization": f"Bearer {admin_token}"},
263
+ )
264
+ assert response.status_code == 201
265
+ assert response.json()["email"] == "jane@example.com"
266
+
267
+ @pytest.mark.asyncio
268
+ async def test_duplicate_email(client: AsyncClient, admin_token: str):
269
+ # cria primeiro
270
+ await client.post("/v1/users", json={...}, headers={...})
271
+ # tenta de novo
272
+ response = await client.post("/v1/users", json={...}, headers={...})
273
+ assert response.status_code == 409
274
+ ```
275
+
276
+ ## Antipatterns
277
+
278
+ | AP | Antipattern | Correção |
279
+ |---|---|---|
280
+ | AP-01 | SQLAlchemy direto no router | Repository injetado via Depends |
281
+ | AP-02 | Validação manual no router | Pydantic schema |
282
+ | AP-03 | Lógica no router | Service |
283
+ | AP-04 | `return user` (ORM) sem response_model | `response_model=UserOut` |
284
+ | AP-05 | Secret hardcoded | `pydantic-settings` + `.env` |
285
+ | AP-06 | Login sem rate limit | `@limiter.limit("5/15minute")` |
286
+ | AP-07 | `password=user.password` em response | `response_model=UserOut` sem password |
287
+ | AP-08 | Sem `from_attributes=True` | response_model não converte ORM |
288
+
289
+ ## Segurança
290
+
291
+ - Senhas: `argon2.hash()` (passlib)
292
+ - JWT: HS256 com `JWT_SECRET ≥ 32 bytes`, ou RS256 com par de chaves
293
+ - Headers: middleware com HSTS, X-Frame-Options, CSP
294
+ - CORS específico, nunca `*`
295
+ - Rate limit em login + APIs públicas
296
+ - Refresh token com rotação
297
+
298
+ ## CI
299
+
300
+ ```bash
301
+ ruff check .
302
+ ruff format --check .
303
+ mypy app
304
+ pytest --cov=app --cov-fail-under=80
305
+ pip-audit
306
+ alembic upgrade head --sql > /dev/null # valida migrations
307
+ ```
308
+
309
+ ## Como aplicar
310
+
311
+ ### Passo 1: Audit
312
+
313
+ ```bash
314
+ grep -rn "db\.execute\|db\.query" app/api/ # AP-01
315
+ grep -rn "request\.json()" app/api/ # AP-02
316
+ grep -rn "JWT_SECRET\s*=\s*['\"]" app/ # AP-05
317
+ ```
318
+
319
+ ### Passo 2: Migrar para Pydantic schemas
320
+
321
+ Para cada `request.json()` ou validação inline → schema Pydantic.
322
+
323
+ ### Passo 3: Extrair Services
324
+
325
+ Lógica > 5 linhas no router → Service injetável.
326
+
327
+ ### Passo 4: Adicionar Repositories
328
+
329
+ Encapsular SQLAlchemy. Router chama Service via Depends, Service chama Repository.
330
+
331
+ ### Passo 5: Configurar slowapi + auth
332
+
333
+ `app.add_middleware(SlowAPIMiddleware)` global + `@limiter.limit` em login.
334
+
335
+ ## Dicas
336
+
337
+ - **Combine** com `dare-docker` (Python 3.11-slim, não-root, multi-stage)
338
+ - **Use** `dare-llm-integration` se houver Gemini/Claude (FastAPI + httpx async)
339
+ - **Para realtime**, FastAPI tem `WebSocket` nativo + `sse-starlette`
340
+
341
+ ---
342
+
343
+ Esta skill é parte do DARE Method e está sob licença MIT.