@dewtech/dare-cli 2.16.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +196 -3
- package/dist/__tests__/confidence.test.d.ts +2 -0
- package/dist/__tests__/confidence.test.d.ts.map +1 -0
- package/dist/__tests__/confidence.test.js +73 -0
- package/dist/__tests__/confidence.test.js.map +1 -0
- package/dist/__tests__/datamodel.test.d.ts +2 -0
- package/dist/__tests__/datamodel.test.d.ts.map +1 -0
- package/dist/__tests__/datamodel.test.js +131 -0
- package/dist/__tests__/datamodel.test.js.map +1 -0
- package/dist/__tests__/dna-detector.test.d.ts +2 -0
- package/dist/__tests__/dna-detector.test.d.ts.map +1 -0
- package/dist/__tests__/dna-detector.test.js +97 -0
- package/dist/__tests__/dna-detector.test.js.map +1 -0
- package/dist/__tests__/dna-facts.test.d.ts +2 -0
- package/dist/__tests__/dna-facts.test.d.ts.map +1 -0
- package/dist/__tests__/dna-facts.test.js +44 -0
- package/dist/__tests__/dna-facts.test.js.map +1 -0
- package/dist/__tests__/graph-renderer.test.d.ts +2 -0
- package/dist/__tests__/graph-renderer.test.d.ts.map +1 -0
- package/dist/__tests__/graph-renderer.test.js +85 -0
- package/dist/__tests__/graph-renderer.test.js.map +1 -0
- package/dist/__tests__/migration.test.d.ts +2 -0
- package/dist/__tests__/migration.test.d.ts.map +1 -0
- package/dist/__tests__/migration.test.js +77 -0
- package/dist/__tests__/migration.test.js.map +1 -0
- package/dist/__tests__/module-detector.test.d.ts +2 -0
- package/dist/__tests__/module-detector.test.d.ts.map +1 -0
- package/dist/__tests__/module-detector.test.js +83 -0
- package/dist/__tests__/module-detector.test.js.map +1 -0
- package/dist/__tests__/refine.test.d.ts +2 -0
- package/dist/__tests__/refine.test.d.ts.map +1 -0
- package/dist/__tests__/refine.test.js +186 -0
- package/dist/__tests__/refine.test.js.map +1 -0
- package/dist/__tests__/reverse-facts.test.d.ts +2 -0
- package/dist/__tests__/reverse-facts.test.d.ts.map +1 -0
- package/dist/__tests__/reverse-facts.test.js +78 -0
- package/dist/__tests__/reverse-facts.test.js.map +1 -0
- package/dist/__tests__/review.test.d.ts +2 -0
- package/dist/__tests__/review.test.d.ts.map +1 -0
- package/dist/__tests__/review.test.js +242 -0
- package/dist/__tests__/review.test.js.map +1 -0
- package/dist/__tests__/update.test.d.ts +2 -0
- package/dist/__tests__/update.test.d.ts.map +1 -0
- package/dist/__tests__/update.test.js +150 -0
- package/dist/__tests__/update.test.js.map +1 -0
- package/dist/__tests__/validate.test.js +65 -65
- package/dist/bin/dare.js +38 -3
- package/dist/bin/dare.js.map +1 -1
- package/dist/commands/blueprint.js +122 -122
- package/dist/commands/dag.d.ts.map +1 -1
- package/dist/commands/dag.js +43 -79
- package/dist/commands/dag.js.map +1 -1
- package/dist/commands/dna.d.ts +3 -0
- package/dist/commands/dna.d.ts.map +1 -0
- package/dist/commands/dna.js +69 -0
- package/dist/commands/dna.js.map +1 -0
- package/dist/commands/execute.d.ts.map +1 -1
- package/dist/commands/execute.js +76 -0
- package/dist/commands/execute.js.map +1 -1
- package/dist/commands/migrate.d.ts +3 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +101 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/new.d.ts +16 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +103 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/refine.d.ts +16 -0
- package/dist/commands/refine.d.ts.map +1 -0
- package/dist/commands/refine.js +167 -0
- package/dist/commands/refine.js.map +1 -0
- package/dist/commands/reverse.d.ts +3 -0
- package/dist/commands/reverse.d.ts.map +1 -0
- package/dist/commands/reverse.js +201 -0
- package/dist/commands/reverse.js.map +1 -0
- package/dist/commands/review.d.ts +16 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +106 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/update.d.ts +13 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +149 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/welcome.d.ts +14 -0
- package/dist/commands/welcome.d.ts.map +1 -0
- package/dist/commands/welcome.js +29 -0
- package/dist/commands/welcome.js.map +1 -0
- package/dist/skills/commands/add.d.ts +23 -0
- package/dist/skills/commands/add.d.ts.map +1 -0
- package/dist/skills/commands/add.js +206 -0
- package/dist/skills/commands/add.js.map +1 -0
- package/dist/skills/commands/info.d.ts +14 -0
- package/dist/skills/commands/info.d.ts.map +1 -0
- package/dist/skills/commands/info.js +99 -0
- package/dist/skills/commands/info.js.map +1 -0
- package/dist/skills/commands/list.d.ts +19 -0
- package/dist/skills/commands/list.d.ts.map +1 -0
- package/dist/skills/commands/list.js +163 -0
- package/dist/skills/commands/list.js.map +1 -0
- package/dist/skills/commands/publish.d.ts +56 -0
- package/dist/skills/commands/publish.d.ts.map +1 -0
- package/dist/skills/commands/publish.js +272 -0
- package/dist/skills/commands/publish.js.map +1 -0
- package/dist/skills/commands/remove.d.ts +19 -0
- package/dist/skills/commands/remove.d.ts.map +1 -0
- package/dist/skills/commands/remove.js +96 -0
- package/dist/skills/commands/remove.js.map +1 -0
- package/dist/skills/commands/update.d.ts +31 -0
- package/dist/skills/commands/update.d.ts.map +1 -0
- package/dist/skills/commands/update.js +132 -0
- package/dist/skills/commands/update.js.map +1 -0
- package/dist/skills/index.d.ts +22 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +33 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/manifest.d.ts +54 -0
- package/dist/skills/manifest.d.ts.map +1 -0
- package/dist/skills/manifest.js +162 -0
- package/dist/skills/manifest.js.map +1 -0
- package/dist/skills/registry-local.d.ts +67 -0
- package/dist/skills/registry-local.d.ts.map +1 -0
- package/dist/skills/registry-local.js +130 -0
- package/dist/skills/registry-local.js.map +1 -0
- package/dist/skills/registry-mock.json +109 -0
- package/dist/skills/registry-remote.d.ts +110 -0
- package/dist/skills/registry-remote.d.ts.map +1 -0
- package/dist/skills/registry-remote.js +246 -0
- package/dist/skills/registry-remote.js.map +1 -0
- package/dist/skills/registry.d.ts +49 -0
- package/dist/skills/registry.d.ts.map +1 -0
- package/dist/skills/registry.js +94 -0
- package/dist/skills/registry.js.map +1 -0
- package/dist/skills/tests/manifest.spec.d.ts +8 -0
- package/dist/skills/tests/manifest.spec.d.ts.map +1 -0
- package/dist/skills/tests/manifest.spec.js +176 -0
- package/dist/skills/tests/manifest.spec.js.map +1 -0
- package/dist/skills/tests/publish.spec.d.ts +12 -0
- package/dist/skills/tests/publish.spec.d.ts.map +1 -0
- package/dist/skills/tests/publish.spec.js +276 -0
- package/dist/skills/tests/publish.spec.js.map +1 -0
- package/dist/skills/tests/registry-local.spec.d.ts +8 -0
- package/dist/skills/tests/registry-local.spec.d.ts.map +1 -0
- package/dist/skills/tests/registry-local.spec.js +231 -0
- package/dist/skills/tests/registry-local.spec.js.map +1 -0
- package/dist/skills/tests/registry.spec.d.ts +7 -0
- package/dist/skills/tests/registry.spec.d.ts.map +1 -0
- package/dist/skills/tests/registry.spec.js +58 -0
- package/dist/skills/tests/registry.spec.js.map +1 -0
- package/dist/skills/tests/remote-registry.spec.d.ts +9 -0
- package/dist/skills/tests/remote-registry.spec.d.ts.map +1 -0
- package/dist/skills/tests/remote-registry.spec.js +357 -0
- package/dist/skills/tests/remote-registry.spec.js.map +1 -0
- package/dist/skills/tests/update.spec.d.ts +9 -0
- package/dist/skills/tests/update.spec.d.ts.map +1 -0
- package/dist/skills/tests/update.spec.js +166 -0
- package/dist/skills/tests/update.spec.js.map +1 -0
- package/dist/types/Refine.types.d.ts +96 -0
- package/dist/types/Refine.types.d.ts.map +1 -0
- package/dist/types/Refine.types.js +19 -0
- package/dist/types/Refine.types.js.map +1 -0
- package/dist/types/Review.types.d.ts +86 -0
- package/dist/types/Review.types.d.ts.map +1 -0
- package/dist/types/Review.types.js +15 -0
- package/dist/types/Review.types.js.map +1 -0
- package/dist/types/UpdateManifest.types.d.ts +91 -0
- package/dist/types/UpdateManifest.types.d.ts.map +1 -0
- package/dist/types/UpdateManifest.types.js +13 -0
- package/dist/types/UpdateManifest.types.js.map +1 -0
- package/dist/utils/ReviewRunner.d.ts +42 -0
- package/dist/utils/ReviewRunner.d.ts.map +1 -0
- package/dist/utils/ReviewRunner.js +175 -0
- package/dist/utils/ReviewRunner.js.map +1 -0
- package/dist/utils/UpdateApplier.d.ts +42 -0
- package/dist/utils/UpdateApplier.d.ts.map +1 -0
- package/dist/utils/UpdateApplier.js +207 -0
- package/dist/utils/UpdateApplier.js.map +1 -0
- package/dist/utils/UpdateDetector.d.ts +56 -0
- package/dist/utils/UpdateDetector.d.ts.map +1 -0
- package/dist/utils/UpdateDetector.js +164 -0
- package/dist/utils/UpdateDetector.js.map +1 -0
- package/dist/utils/banner.d.ts +28 -0
- package/dist/utils/banner.d.ts.map +1 -0
- package/dist/utils/banner.js +77 -0
- package/dist/utils/banner.js.map +1 -0
- package/dist/utils/banner.spec.d.ts +5 -0
- package/dist/utils/banner.spec.d.ts.map +1 -0
- package/dist/utils/banner.spec.js +253 -0
- package/dist/utils/banner.spec.js.map +1 -0
- package/dist/utils/complexity-analyzer.d.ts +60 -0
- package/dist/utils/complexity-analyzer.d.ts.map +1 -0
- package/dist/utils/complexity-analyzer.js +292 -0
- package/dist/utils/complexity-analyzer.js.map +1 -0
- package/dist/utils/confidence.d.ts +41 -0
- package/dist/utils/confidence.d.ts.map +1 -0
- package/dist/utils/confidence.js +101 -0
- package/dist/utils/confidence.js.map +1 -0
- package/dist/utils/datamodel.d.ts +41 -0
- package/dist/utils/datamodel.d.ts.map +1 -0
- package/dist/utils/datamodel.js +535 -0
- package/dist/utils/datamodel.js.map +1 -0
- package/dist/utils/dna-detector.d.ts +61 -0
- package/dist/utils/dna-detector.d.ts.map +1 -0
- package/dist/utils/dna-detector.js +354 -0
- package/dist/utils/dna-detector.js.map +1 -0
- package/dist/utils/dna-facts.d.ts +13 -0
- package/dist/utils/dna-facts.d.ts.map +1 -0
- package/dist/utils/dna-facts.js +109 -0
- package/dist/utils/dna-facts.js.map +1 -0
- package/dist/utils/excalidraw-renderer.d.ts +11 -71
- package/dist/utils/excalidraw-renderer.d.ts.map +1 -1
- package/dist/utils/excalidraw-renderer.js +29 -162
- package/dist/utils/excalidraw-renderer.js.map +1 -1
- package/dist/utils/graph-renderer.d.ts +115 -0
- package/dist/utils/graph-renderer.d.ts.map +1 -0
- package/dist/utils/graph-renderer.js +216 -0
- package/dist/utils/graph-renderer.js.map +1 -0
- package/dist/utils/migration.d.ts +64 -0
- package/dist/utils/migration.d.ts.map +1 -0
- package/dist/utils/migration.js +183 -0
- package/dist/utils/migration.js.map +1 -0
- package/dist/utils/module-detector.d.ts +46 -0
- package/dist/utils/module-detector.d.ts.map +1 -0
- package/dist/utils/module-detector.js +348 -0
- package/dist/utils/module-detector.js.map +1 -0
- package/dist/utils/project-generator.d.ts.map +1 -1
- package/dist/utils/project-generator.js +273 -254
- package/dist/utils/project-generator.js.map +1 -1
- package/dist/utils/reverse-facts.d.ts +50 -0
- package/dist/utils/reverse-facts.d.ts.map +1 -0
- package/dist/utils/reverse-facts.js +291 -0
- package/dist/utils/reverse-facts.js.map +1 -0
- package/dist/utils/stack-bootstrap.js +371 -371
- package/dist/utils/static-analyzer.d.ts +29 -0
- package/dist/utils/static-analyzer.d.ts.map +1 -0
- package/dist/utils/static-analyzer.js +390 -0
- package/dist/utils/static-analyzer.js.map +1 -0
- package/dist/utils/version-compare.d.ts +27 -0
- package/dist/utils/version-compare.d.ts.map +1 -0
- package/dist/utils/version-compare.js +47 -0
- package/dist/utils/version-compare.js.map +1 -0
- package/package.json +8 -3
- package/templates/DARE-dag-example.yaml +280 -280
- package/templates/UPDATE-MANIFEST.json +48 -0
- package/templates/backend/node-nestjs/.env.example +9 -9
- package/templates/backend/node-nestjs/nest-cli.json +8 -8
- package/templates/backend/node-nestjs/package.json +50 -50
- package/templates/backend/node-nestjs/src/app.controller.ts +12 -12
- package/templates/backend/node-nestjs/src/app.module.ts +15 -15
- package/templates/backend/node-nestjs/src/app.service.ts +8 -8
- package/templates/backend/node-nestjs/src/main.ts +24 -24
- package/templates/backend/node-nestjs/tsconfig.json +21 -21
- package/templates/backend/php-laravel/.env.example +22 -22
- package/templates/backend/php-laravel/app/Http/Controllers/HealthController.php +15 -15
- package/templates/backend/php-laravel/composer.json +40 -40
- package/templates/backend/python-fastapi/.env.example +4 -4
- package/templates/backend/python-fastapi/app/api/router.py +8 -8
- package/templates/backend/python-fastapi/app/core/config.py +20 -20
- package/templates/backend/python-fastapi/main.py +35 -35
- package/templates/backend/python-fastapi/requirements.txt +13 -13
- package/templates/backend/rust-axum/.env.example +3 -3
- package/templates/backend/rust-axum/Cargo.toml +23 -23
- package/templates/backend/rust-axum/src/errors.rs +30 -30
- package/templates/backend/rust-axum/src/main.rs +32 -32
- package/templates/backend/rust-axum/src/routes.rs +6 -6
- package/templates/frontend/leptos-csr/.cargo/config.toml +2 -2
- package/templates/frontend/leptos-csr/Cargo.toml +16 -16
- package/templates/frontend/leptos-csr/Trunk.toml +10 -10
- package/templates/frontend/leptos-csr/index.html +11 -11
- package/templates/frontend/leptos-csr/src/lib.rs +20 -20
- package/templates/frontend/leptos-csr/style/main.scss +19 -19
- package/templates/frontend/leptos-fullstack/.cargo/config.toml +4 -4
- package/templates/frontend/leptos-fullstack/Cargo.toml +56 -56
- package/templates/frontend/leptos-fullstack/src/app.rs +49 -49
- package/templates/frontend/leptos-fullstack/src/lib.rs +9 -9
- package/templates/frontend/leptos-fullstack/src/main.rs +29 -29
- package/templates/frontend/leptos-fullstack/style/main.scss +19 -19
- package/templates/frontend/react/index.html +12 -12
- package/templates/frontend/react/package.json +35 -35
- package/templates/frontend/react/src/App.tsx +25 -25
- package/templates/frontend/react/src/main.tsx +9 -9
- package/templates/frontend/vue/package.json +32 -32
- package/templates/frontend/vue/src/App.vue +7 -7
- package/templates/frontend/vue/src/main.ts +10 -10
- package/templates/frontend/vue/src/router/index.ts +14 -14
- package/templates/frontend/vue/src/views/HomeView.vue +6 -6
- package/templates/hooks/pre-commit-dare-validate +24 -24
- package/templates/ide/antigravity/.agents/skills/dare-ax/SKILL.md +152 -0
- package/templates/ide/antigravity/.agents/skills/dare-blueprint/SKILL.md +180 -36
- package/templates/ide/antigravity/.agents/skills/dare-dag-build/SKILL.md +154 -0
- package/templates/ide/antigravity/.agents/skills/dare-dag-run/SKILL.md +130 -0
- package/templates/ide/antigravity/.agents/skills/dare-dag-runner/SKILL.md +203 -203
- package/templates/ide/antigravity/.agents/skills/dare-dna/SKILL.md +63 -0
- package/templates/ide/antigravity/.agents/skills/dare-docker/SKILL.md +315 -0
- package/templates/ide/antigravity/.agents/skills/dare-frontend-design/SKILL.md +192 -0
- package/templates/ide/antigravity/.agents/skills/dare-laravel-api/SKILL.md +337 -0
- package/templates/ide/antigravity/.agents/skills/dare-layered-design/SKILL.md +166 -0
- package/templates/ide/antigravity/.agents/skills/dare-llm-integration/SKILL.md +217 -0
- package/templates/ide/antigravity/.agents/skills/dare-migrate/SKILL.md +61 -0
- package/templates/ide/antigravity/.agents/skills/dare-quality-telemetry/SKILL.md +187 -0
- package/templates/ide/antigravity/.agents/skills/dare-realtime/SKILL.md +217 -0
- package/templates/ide/antigravity/.agents/skills/dare-refine/SKILL.md +114 -0
- package/templates/ide/antigravity/.agents/skills/dare-reverse/SKILL.md +108 -0
- package/templates/ide/antigravity/.agents/skills/dare-review/SKILL.md +111 -0
- package/templates/ide/antigravity/.agents/skills/dare-rust-leptos/SKILL.md +263 -0
- package/templates/ide/antigravity/.agents/skills/dare-rust-workspace/SKILL.md +275 -275
- package/templates/ide/antigravity/.agents/skills/dare-security/SKILL.md +274 -0
- package/templates/ide/antigravity/.agents/skills/dare-tasks/SKILL.md +265 -224
- package/templates/ide/antigravity/.agents/skills/dare-telemetry/SKILL.md +188 -0
- package/templates/ide/antigravity/.agents/skills/skill-fastapi-api/SKILL.md +343 -0
- package/templates/ide/antigravity/.agents/skills/skill-go-gin-api/SKILL.md +377 -0
- package/templates/ide/antigravity/.agents/skills/skill-mcp-server/SKILL.md +382 -0
- package/templates/ide/antigravity/.agents/skills/skill-nestjs-api/SKILL.md +326 -0
- package/templates/ide/antigravity/.agents/skills/skill-rails-api/SKILL.md +393 -0
- package/templates/ide/antigravity/templates/BLUEPRINT-template.md +193 -193
- package/templates/ide/antigravity/templates/DESIGN-template.md +129 -129
- package/templates/ide/antigravity/templates/TASK-SPEC-template.md +141 -100
- package/templates/ide/claude/.claude/commands/dare-ax.md +131 -0
- package/templates/ide/claude/.claude/commands/dare-blueprint.md +134 -78
- package/templates/ide/claude/.claude/commands/dare-bugfix-design.md +119 -0
- package/templates/ide/claude/.claude/commands/dare-dag-build.md +151 -110
- package/templates/ide/claude/.claude/commands/dare-dag-run.md +109 -109
- package/templates/ide/claude/.claude/commands/dare-dag-runner.md +117 -0
- package/templates/ide/claude/.claude/commands/dare-dag-viz.md +197 -197
- package/templates/ide/claude/.claude/commands/dare-design.md +69 -69
- package/templates/ide/claude/.claude/commands/dare-dna.md +75 -0
- package/templates/ide/claude/.claude/commands/dare-docker.md +207 -0
- package/templates/ide/claude/.claude/commands/dare-execute.md +152 -152
- package/templates/ide/claude/.claude/commands/dare-feature-design.md +147 -0
- package/templates/ide/claude/.claude/commands/dare-frontend-design.md +149 -0
- package/templates/ide/claude/.claude/commands/dare-laravel-api.md +211 -0
- package/templates/ide/claude/.claude/commands/dare-layered-design.md +124 -0
- package/templates/ide/claude/.claude/commands/dare-llm-integration.md +148 -0
- package/templates/ide/claude/.claude/commands/dare-migrate.md +72 -0
- package/templates/ide/claude/.claude/commands/dare-quality-telemetry.md +166 -0
- package/templates/ide/claude/.claude/commands/dare-realtime.md +159 -0
- package/templates/ide/claude/.claude/commands/dare-refine.md +145 -0
- package/templates/ide/claude/.claude/commands/dare-reverse.md +139 -0
- package/templates/ide/claude/.claude/commands/dare-review.md +113 -0
- package/templates/ide/claude/.claude/commands/dare-rust-leptos.md +269 -269
- package/templates/ide/claude/.claude/commands/dare-rust-workspace.md +209 -209
- package/templates/ide/claude/.claude/commands/dare-security.md +232 -232
- package/templates/ide/claude/.claude/commands/dare-tasks.md +70 -70
- package/templates/ide/claude/.claude/commands/dare-telemetry.md +132 -0
- package/templates/ide/claude/.claude/commands/skill-fastapi-api.md +205 -0
- package/templates/ide/claude/.claude/commands/skill-go-gin-api.md +232 -0
- package/templates/ide/claude/.claude/commands/skill-mcp-server.md +228 -0
- package/templates/ide/claude/.claude/commands/skill-nestjs-api.md +210 -0
- package/templates/ide/claude/.claude/commands/skill-rails-api.md +236 -0
- package/templates/ide/claude/.claude/settings.example.json +35 -35
- package/templates/ide/claude/CLAUDE.md +146 -146
- package/templates/ide/claude/templates/BLUEPRINT-template.md +193 -193
- package/templates/ide/claude/templates/DESIGN-template.md +129 -129
- package/templates/ide/claude/templates/TASK-SPEC-template.md +141 -100
- package/templates/ide/cursor/.cursor/commands/dag-viz.md +139 -0
- package/templates/ide/cursor/.cursor/commands/generate-blueprint.md +86 -41
- package/templates/ide/cursor/.cursor/commands/generate-design.md +35 -35
- package/templates/ide/cursor/.cursor/commands/generate-tasks.md +184 -142
- package/templates/ide/cursor/.cursor/commands/refine-task.md +107 -0
- package/templates/ide/cursor/.cursor/commands/review-task.md +91 -0
- package/templates/ide/cursor/.cursor/commands/run-dag.md +110 -110
- package/templates/ide/cursor/.cursor/rules/skill-ax.mdc +263 -0
- package/templates/ide/cursor/.cursor/rules/skill-dag-build.mdc +173 -0
- package/templates/ide/cursor/.cursor/rules/skill-dag-run.mdc +134 -0
- package/templates/ide/cursor/.cursor/rules/skill-dag-runner.mdc +221 -221
- package/templates/ide/cursor/.cursor/rules/skill-dna.mdc +63 -0
- package/templates/ide/cursor/.cursor/rules/skill-fastapi-api.mdc +352 -0
- package/templates/ide/cursor/.cursor/rules/skill-frontend-design.mdc +244 -0
- package/templates/ide/cursor/.cursor/rules/skill-go-gin-api.mdc +371 -0
- package/templates/ide/cursor/.cursor/rules/skill-layered-design.mdc +266 -0
- package/templates/ide/cursor/.cursor/rules/skill-llm-integration.mdc +295 -0
- package/templates/ide/cursor/.cursor/rules/skill-mcp-server.mdc +367 -0
- package/templates/ide/cursor/.cursor/rules/skill-migrate.mdc +58 -0
- package/templates/ide/cursor/.cursor/rules/skill-nestjs-api.mdc +346 -0
- package/templates/ide/cursor/.cursor/rules/skill-quality-telemetry.mdc +248 -0
- package/templates/ide/cursor/.cursor/rules/skill-rails-api.mdc +400 -0
- package/templates/ide/cursor/.cursor/rules/skill-realtime.mdc +262 -0
- package/templates/ide/cursor/.cursor/rules/skill-reverse.mdc +107 -0
- package/templates/ide/cursor/.cursor/rules/skill-rust-leptos.mdc +281 -0
- package/templates/ide/cursor/.cursor/rules/skill-rust-workspace.mdc +312 -312
- package/templates/ide/cursor/.cursor/rules/skill-security.mdc +245 -245
- package/templates/ide/cursor/templates/BLUEPRINT-template.md +193 -193
- package/templates/ide/cursor/templates/DESIGN-template.md +129 -129
- package/templates/ide/cursor/templates/TASK-SPEC-template.md +141 -100
- package/templates/shared/docker-compose.yml +41 -41
- package/dist/__tests__/dag-runner/adapters.test.d.ts +0 -2
- package/dist/__tests__/dag-runner/adapters.test.d.ts.map +0 -1
- package/dist/__tests__/dag-runner/adapters.test.js +0 -134
- package/dist/__tests__/dag-runner/adapters.test.js.map +0 -1
- package/dist/dag-runner/adapters/antigravity.d.ts +0 -6
- package/dist/dag-runner/adapters/antigravity.d.ts.map +0 -1
- package/dist/dag-runner/adapters/antigravity.js +0 -54
- package/dist/dag-runner/adapters/antigravity.js.map +0 -1
- package/dist/dag-runner/adapters/claude.d.ts +0 -6
- package/dist/dag-runner/adapters/claude.d.ts.map +0 -1
- package/dist/dag-runner/adapters/claude.js +0 -48
- package/dist/dag-runner/adapters/claude.js.map +0 -1
- package/dist/dag-runner/adapters/cursor.d.ts +0 -6
- package/dist/dag-runner/adapters/cursor.d.ts.map +0 -1
- package/dist/dag-runner/adapters/cursor.js +0 -58
- package/dist/dag-runner/adapters/cursor.js.map +0 -1
- package/dist/dag-runner/adapters/index.d.ts +0 -46
- package/dist/dag-runner/adapters/index.d.ts.map +0 -1
- package/dist/dag-runner/adapters/index.js +0 -55
- package/dist/dag-runner/adapters/index.js.map +0 -1
- package/dist/dag-runner/utils/timeout.d.ts +0 -27
- package/dist/dag-runner/utils/timeout.d.ts.map +0 -1
- package/dist/dag-runner/utils/timeout.js +0 -55
- package/dist/dag-runner/utils/timeout.js.map +0 -1
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dare-laravel-api
|
|
3
|
+
description: Padrões DARE para APIs REST em Laravel 11 + PHP 8.3 — Strict Types, FormRequests, Services, JsonResources, Eloquent + casts, tratamento global de exceções, testes Feature/Pest, PHPStan/Larastan, Pint.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# DARE Laravel API Skill
|
|
7
|
+
|
|
8
|
+
Você é um desenvolvedor sênior PHP 8.3 / Laravel 11.x especializado em APIs REST. Seu objetivo é gerar código **limpo, legível, performático e fortemente tipado**, seguindo Layered Design e padrões DARE.
|
|
9
|
+
|
|
10
|
+
## Quando usar
|
|
11
|
+
|
|
12
|
+
- Projeto Laravel novo via DARE
|
|
13
|
+
- Adicionar feature em API Laravel existente
|
|
14
|
+
- Auditar projeto Laravel para conformidade DARE
|
|
15
|
+
- Migrar API antiga (Laravel 8/9/10) para padrões 11.x
|
|
16
|
+
|
|
17
|
+
## Stack canônica
|
|
18
|
+
|
|
19
|
+
- **PHP 8.3** — Strict Types em todos os arquivos (`declare(strict_types=1);`)
|
|
20
|
+
- **Laravel 11.x** — modo API (sem views server-side por default)
|
|
21
|
+
- **Banco** — PostgreSQL (preferido) ou MySQL 8
|
|
22
|
+
- **Testes** — Pest (preferido) ou PHPUnit 11
|
|
23
|
+
- **Análise estática** — PHPStan + Larastan (nível 8)
|
|
24
|
+
- **Formatação** — Laravel Pint (`pint`)
|
|
25
|
+
- **Auth** — Laravel Sanctum (tokens) ou Passport (OAuth)
|
|
26
|
+
|
|
27
|
+
## Layered Design em Laravel
|
|
28
|
+
|
|
29
|
+
Mapeamento DARE → Laravel:
|
|
30
|
+
|
|
31
|
+
| Camada DARE | Pasta Laravel |
|
|
32
|
+
|---|---|
|
|
33
|
+
| Handler | `app/Http/Controllers/` |
|
|
34
|
+
| Service | `app/Services/` |
|
|
35
|
+
| Repository | `app/Repositories/` |
|
|
36
|
+
| Model | `app/Models/` |
|
|
37
|
+
| Presenter | `app/Http/Resources/` |
|
|
38
|
+
|
|
39
|
+
### Controllers (Handlers)
|
|
40
|
+
|
|
41
|
+
- Apenas: receber request → chamar Service → retornar Resource
|
|
42
|
+
- NUNCA: lógica de negócio, queries Eloquent, validação inline
|
|
43
|
+
|
|
44
|
+
```php
|
|
45
|
+
<?php declare(strict_types=1);
|
|
46
|
+
|
|
47
|
+
namespace App\Http\Controllers;
|
|
48
|
+
|
|
49
|
+
use App\Http\Requests\StoreUserRequest;
|
|
50
|
+
use App\Http\Resources\UserResource;
|
|
51
|
+
use App\Services\RegisterUser;
|
|
52
|
+
|
|
53
|
+
final class UserApiController extends Controller
|
|
54
|
+
{
|
|
55
|
+
public function __construct(private RegisterUser $service) {}
|
|
56
|
+
|
|
57
|
+
public function store(StoreUserRequest $request): UserResource
|
|
58
|
+
{
|
|
59
|
+
$user = $this->service->execute($request->validated());
|
|
60
|
+
return new UserResource($user);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### FormRequests (Validação)
|
|
66
|
+
|
|
67
|
+
NUNCA validar inline no Controller. Sempre FormRequest:
|
|
68
|
+
|
|
69
|
+
```php
|
|
70
|
+
<?php declare(strict_types=1);
|
|
71
|
+
|
|
72
|
+
namespace App\Http\Requests;
|
|
73
|
+
|
|
74
|
+
use Illuminate\Foundation\Http\FormRequest;
|
|
75
|
+
|
|
76
|
+
final class StoreUserRequest extends FormRequest
|
|
77
|
+
{
|
|
78
|
+
public function authorize(): bool
|
|
79
|
+
{
|
|
80
|
+
return $this->user()->can('create', User::class);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public function rules(): array
|
|
84
|
+
{
|
|
85
|
+
return [
|
|
86
|
+
'email' => ['required', 'email', 'unique:users,email'],
|
|
87
|
+
'password' => ['required', 'string', 'min:12'],
|
|
88
|
+
'name' => ['required', 'string', 'max:255'],
|
|
89
|
+
];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Services (Business Logic)
|
|
95
|
+
|
|
96
|
+
Uma operação por classe. Strict types, exceções de domínio próprias.
|
|
97
|
+
|
|
98
|
+
```php
|
|
99
|
+
<?php declare(strict_types=1);
|
|
100
|
+
|
|
101
|
+
namespace App\Services;
|
|
102
|
+
|
|
103
|
+
use App\Exceptions\UserAlreadyExistsException;
|
|
104
|
+
use App\Models\User;
|
|
105
|
+
use App\Repositories\UserRepository;
|
|
106
|
+
use Illuminate\Support\Facades\Hash;
|
|
107
|
+
|
|
108
|
+
final class RegisterUser
|
|
109
|
+
{
|
|
110
|
+
public function __construct(private UserRepository $users) {}
|
|
111
|
+
|
|
112
|
+
public function execute(array $data): User
|
|
113
|
+
{
|
|
114
|
+
if ($this->users->existsByEmail($data['email'])) {
|
|
115
|
+
throw new UserAlreadyExistsException();
|
|
116
|
+
}
|
|
117
|
+
return $this->users->create([
|
|
118
|
+
'email' => $data['email'],
|
|
119
|
+
'name' => $data['name'],
|
|
120
|
+
'password' => Hash::make($data['password']),
|
|
121
|
+
]);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Repositories (Data Access)
|
|
127
|
+
|
|
128
|
+
Abstrai Eloquent. Service só conhece o Repository, não o Model direto.
|
|
129
|
+
|
|
130
|
+
```php
|
|
131
|
+
<?php declare(strict_types=1);
|
|
132
|
+
|
|
133
|
+
namespace App\Repositories;
|
|
134
|
+
|
|
135
|
+
use App\Models\User;
|
|
136
|
+
|
|
137
|
+
final class UserRepository
|
|
138
|
+
{
|
|
139
|
+
public function existsByEmail(string $email): bool
|
|
140
|
+
{
|
|
141
|
+
return User::where('email', $email)->exists();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public function create(array $data): User
|
|
145
|
+
{
|
|
146
|
+
return User::create($data);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Resources (Presentation)
|
|
152
|
+
|
|
153
|
+
Nunca retorne Model direto do Controller. Sempre passe por JsonResource.
|
|
154
|
+
|
|
155
|
+
```php
|
|
156
|
+
<?php declare(strict_types=1);
|
|
157
|
+
|
|
158
|
+
namespace App\Http\Resources;
|
|
159
|
+
|
|
160
|
+
use Illuminate\Http\Resources\Json\JsonResource;
|
|
161
|
+
|
|
162
|
+
final class UserResource extends JsonResource
|
|
163
|
+
{
|
|
164
|
+
public function toArray($request): array
|
|
165
|
+
{
|
|
166
|
+
return [
|
|
167
|
+
'id' => $this->id,
|
|
168
|
+
'email' => $this->email,
|
|
169
|
+
'name' => $this->name,
|
|
170
|
+
'createdAt' => $this->created_at?->toIso8601String(),
|
|
171
|
+
];
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Models
|
|
177
|
+
|
|
178
|
+
- Definir `$fillable` ou `$guarded`
|
|
179
|
+
- `casts` corretos para tipos não-string
|
|
180
|
+
- Relacionamentos explícitos
|
|
181
|
+
|
|
182
|
+
```php
|
|
183
|
+
<?php declare(strict_types=1);
|
|
184
|
+
|
|
185
|
+
namespace App\Models;
|
|
186
|
+
|
|
187
|
+
use Illuminate\Database\Eloquent\Model;
|
|
188
|
+
|
|
189
|
+
final class User extends Model
|
|
190
|
+
{
|
|
191
|
+
protected $fillable = ['email', 'name', 'password'];
|
|
192
|
+
protected $hidden = ['password'];
|
|
193
|
+
protected $casts = [
|
|
194
|
+
'email_verified_at' => 'datetime',
|
|
195
|
+
'created_at' => 'datetime',
|
|
196
|
+
];
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Tratamento de exceções
|
|
201
|
+
|
|
202
|
+
Em `bootstrap/app.php` (Laravel 11):
|
|
203
|
+
|
|
204
|
+
```php
|
|
205
|
+
->withExceptions(function (Exceptions $exceptions) {
|
|
206
|
+
$exceptions->render(function (UserAlreadyExistsException $e) {
|
|
207
|
+
return response()->json(['error' => 'User already exists', 'code' => 'USER_EXISTS'], 409);
|
|
208
|
+
});
|
|
209
|
+
$exceptions->render(function (ValidationException $e) {
|
|
210
|
+
return response()->json(['error' => 'Validation failed', 'errors' => $e->errors()], 422);
|
|
211
|
+
});
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Transações de banco
|
|
216
|
+
|
|
217
|
+
Sempre que inserir/atualizar múltiplas tabelas:
|
|
218
|
+
|
|
219
|
+
```php
|
|
220
|
+
DB::transaction(function () use ($data) {
|
|
221
|
+
$user = User::create($data);
|
|
222
|
+
UserProfile::create(['user_id' => $user->id, ...]);
|
|
223
|
+
AuditLog::log('user.created', $user);
|
|
224
|
+
});
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Testes (Pest)
|
|
228
|
+
|
|
229
|
+
Feature test para cada endpoint:
|
|
230
|
+
|
|
231
|
+
```php
|
|
232
|
+
<?php declare(strict_types=1);
|
|
233
|
+
|
|
234
|
+
use App\Models\User;
|
|
235
|
+
|
|
236
|
+
it('cria usuário com sucesso', function () {
|
|
237
|
+
$payload = ['email' => 'jane@example.com', 'name' => 'Jane', 'password' => 'longsecret123'];
|
|
238
|
+
|
|
239
|
+
$this->actingAs(User::factory()->create(['is_admin' => true]))
|
|
240
|
+
->postJson('/api/users', $payload)
|
|
241
|
+
->assertCreated()
|
|
242
|
+
->assertJsonStructure(['data' => ['id', 'email', 'name', 'createdAt']]);
|
|
243
|
+
|
|
244
|
+
$this->assertDatabaseHas('users', ['email' => 'jane@example.com']);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('rejeita email duplicado', function () {
|
|
248
|
+
User::factory()->create(['email' => 'taken@example.com']);
|
|
249
|
+
$this->actingAs(User::factory()->create(['is_admin' => true]))
|
|
250
|
+
->postJson('/api/users', ['email' => 'taken@example.com', 'name' => 'X', 'password' => 'longsecret123'])
|
|
251
|
+
->assertStatus(409);
|
|
252
|
+
});
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Cobertura mínima:
|
|
256
|
+
- Resposta de sucesso (200/201)
|
|
257
|
+
- Erro de validação (422)
|
|
258
|
+
- Auth/Autz (401/403)
|
|
259
|
+
- Not Found (404)
|
|
260
|
+
|
|
261
|
+
## Padrões de código
|
|
262
|
+
|
|
263
|
+
- Type hints estritos em todos os métodos (`function x(int $a): User`)
|
|
264
|
+
- Evite `null` — prefira exceção tipada ou `Optional` (collection helper)
|
|
265
|
+
- PHPDoc apenas onde tipo nativo não dá conta (`/** @var User[] $users */`)
|
|
266
|
+
- Comentários explicam o **porquê**, não o **o quê**
|
|
267
|
+
- Use `readonly` em propriedades imutáveis (`public function __construct(public readonly UserRepository $repo) {}`)
|
|
268
|
+
|
|
269
|
+
## Validação estática
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
./vendor/bin/phpstan analyse --level=8
|
|
273
|
+
./vendor/bin/pint --test
|
|
274
|
+
./vendor/bin/pest --coverage --min=80
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Antipatterns
|
|
278
|
+
|
|
279
|
+
| AP | Antipattern | Sinal | Correção |
|
|
280
|
+
|---|---|---|---|
|
|
281
|
+
| AP-01 | Validação no Controller | `$request->validate([...])` | FormRequest dedicada |
|
|
282
|
+
| AP-02 | Query Eloquent no Controller | `User::where(...)->get()` | Repository |
|
|
283
|
+
| AP-03 | Lógica no Controller | `if ($x) { ... } else { ... }` longo | Service |
|
|
284
|
+
| AP-04 | Retornar Model direto | `return $user` | JsonResource |
|
|
285
|
+
| AP-05 | `$guarded = []` | mass assignment vulnerável | `$fillable` explícito |
|
|
286
|
+
| AP-06 | Sem `declare(strict_types=1)` | Type coercion silenciosa | Adicionar no topo |
|
|
287
|
+
| AP-07 | Múltiplas inserções sem transaction | Estado inconsistente em falha parcial | `DB::transaction()` |
|
|
288
|
+
| AP-08 | Senha hash com `bcrypt()` default cost | Custo baixo | `Hash::make($pwd, ['rounds' => 12])` |
|
|
289
|
+
|
|
290
|
+
## Segurança (combinar com dare-security)
|
|
291
|
+
|
|
292
|
+
- **Senhas:** `Hash::make()` com `rounds >= 12` ou Argon2
|
|
293
|
+
- **Auth:** Sanctum para SPA/mobile, OAuth (Passport) para 3rd-party
|
|
294
|
+
- **Rate limit:** `ThrottleRequests` middleware (`->middleware('throttle:60,1')`)
|
|
295
|
+
- **Headers:** middleware com HSTS, X-Frame-Options, CSP
|
|
296
|
+
- **CORS:** `config/cors.php` específico, nunca `*` em produção
|
|
297
|
+
- **Mass assignment:** `$fillable` SEMPRE, nunca `$guarded = []`
|
|
298
|
+
|
|
299
|
+
## Como aplicar
|
|
300
|
+
|
|
301
|
+
### Passo 1: Audit do projeto
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
grep -rn "request()->validate" app/Http/Controllers/ # AP-01
|
|
305
|
+
grep -rn "::where\|::find" app/Http/Controllers/ # AP-02
|
|
306
|
+
./vendor/bin/phpstan analyse --level=8 # tipos
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Passo 2: Migrar Controllers para FormRequests
|
|
310
|
+
|
|
311
|
+
Para cada `$request->validate(...)`, gerar FormRequest correspondente:
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
php artisan make:request StoreUserRequest
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Passo 3: Extrair Services
|
|
318
|
+
|
|
319
|
+
Para cada Controller com lógica > 10 linhas, criar Service correspondente.
|
|
320
|
+
|
|
321
|
+
### Passo 4: Adicionar Repositories
|
|
322
|
+
|
|
323
|
+
Para cada Controller com query Eloquent direta, criar Repository.
|
|
324
|
+
|
|
325
|
+
### Passo 5: Adicionar Resources
|
|
326
|
+
|
|
327
|
+
Substituir `return $user` por `return new UserResource($user)`.
|
|
328
|
+
|
|
329
|
+
## Dicas
|
|
330
|
+
|
|
331
|
+
- **Combine** com `dare-docker` para containerizar (PHP-FPM + Nginx separados)
|
|
332
|
+
- **Use** `dare-security` para auditoria OWASP em FormRequests
|
|
333
|
+
- **Para realtime**, use Laravel Reverb (Pusher-compatible) ou Soketi
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
Esta skill é parte do DARE Method e está sob licença MIT.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dare-layered-design
|
|
3
|
+
description: Enforce arquitetura estrita de 4 camadas (Handlers, Services, Repositories, Models) em todos os projetos DARE, independente de linguagem ou framework. Inspirado em "Layered Design for Ruby on Rails Applications" de Vladimir Dementyev (Evil Martians).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# DARE Layered Design Skill
|
|
7
|
+
|
|
8
|
+
Você é um especialista em arquitetura de software e Layered Design. Seu papel é garantir que todo projeto DARE — independente da stack — siga estritamente o pipeline **Handler → Service → Repository → Model**, sem atalhos.
|
|
9
|
+
|
|
10
|
+
## Quando usar esta skill
|
|
11
|
+
|
|
12
|
+
- Você está revisando um Pull Request e quer verificar se as camadas foram respeitadas
|
|
13
|
+
- Você está gerando código de scaffold (CRUD, novo módulo, novo endpoint)
|
|
14
|
+
- Você está auditando um projeto legado que vai começar a usar DARE
|
|
15
|
+
- Você está em `/dare-blueprint` decidindo a estrutura de pastas
|
|
16
|
+
|
|
17
|
+
## As 4 camadas (regra única, sem exceção)
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
┌──────────────────────────────────────────┐
|
|
21
|
+
│ Handler (HTTP, gRPC, CLI, queue worker) │ ← entrada
|
|
22
|
+
└──────────────────────────────────────────┘
|
|
23
|
+
↓
|
|
24
|
+
┌──────────────────────────────────────────┐
|
|
25
|
+
│ Service (lógica de negócio, 1 operação) │ ← coração
|
|
26
|
+
└──────────────────────────────────────────┘
|
|
27
|
+
↓
|
|
28
|
+
┌──────────────────────────────────────────┐
|
|
29
|
+
│ Repository (acesso a dados, abstração) │ ← I/O
|
|
30
|
+
└──────────────────────────────────────────┘
|
|
31
|
+
↓
|
|
32
|
+
┌──────────────────────────────────────────┐
|
|
33
|
+
│ Model (entidade pura, sem HTTP/DB) │ ← domínio
|
|
34
|
+
└──────────────────────────────────────────┘
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Handlers (controllers, routers, routes)
|
|
38
|
+
|
|
39
|
+
**Responsabilidades**
|
|
40
|
+
- Receber request HTTP/gRPC/CLI
|
|
41
|
+
- Validar input (delegar para FormRequest/Pydantic/Zod/serde)
|
|
42
|
+
- Chamar **um** service
|
|
43
|
+
- Retornar response formatada
|
|
44
|
+
|
|
45
|
+
**NUNCA**
|
|
46
|
+
- Acessar Repository diretamente
|
|
47
|
+
- Conter lógica de negócio
|
|
48
|
+
- Fazer query em banco
|
|
49
|
+
- Instanciar Service com `new` (use injeção)
|
|
50
|
+
|
|
51
|
+
### Services (use_cases, interactors, commands)
|
|
52
|
+
|
|
53
|
+
**Responsabilidades**
|
|
54
|
+
- Implementar **uma** operação de negócio (`RegisterUser`, `RefundPayment`)
|
|
55
|
+
- Orquestrar Repositories
|
|
56
|
+
- Validar regras de negócio
|
|
57
|
+
- Lançar exceções de domínio (`UserAlreadyExists`, `InsufficientFunds`)
|
|
58
|
+
|
|
59
|
+
**NUNCA**
|
|
60
|
+
- Saber sobre HTTP (status code, headers)
|
|
61
|
+
- Saber sobre framework web
|
|
62
|
+
- Conter SQL inline (usa Repository)
|
|
63
|
+
|
|
64
|
+
### Repositories (repos, data_access, stores)
|
|
65
|
+
|
|
66
|
+
**Responsabilidades**
|
|
67
|
+
- Abstrair persistência (Postgres, Redis, S3, Stripe API)
|
|
68
|
+
- Retornar Models ou primitivos
|
|
69
|
+
- Esconder detalhes de SQL/HTTP externo
|
|
70
|
+
|
|
71
|
+
**NUNCA**
|
|
72
|
+
- Retornar HTTP status code
|
|
73
|
+
- Lançar exceções de domínio (retorna `Option<Model>` ou `null`)
|
|
74
|
+
- Conter regra de negócio
|
|
75
|
+
|
|
76
|
+
### Models (entities, domain, structs)
|
|
77
|
+
|
|
78
|
+
**Responsabilidades**
|
|
79
|
+
- Representar entidade do domínio
|
|
80
|
+
- Conter invariantes (`Email` válido, `Money` positivo)
|
|
81
|
+
|
|
82
|
+
**NUNCA**
|
|
83
|
+
- Conter referência a HTTP, DB, framework
|
|
84
|
+
- Importar de Repository/Service/Handler
|
|
85
|
+
|
|
86
|
+
## Métricas obrigatórias
|
|
87
|
+
|
|
88
|
+
| ID | Métrica | Como medir |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| M-01 | 100% dos Services têm testes unitários (sem DB/HTTP real) | linter checa `tests/services/*` |
|
|
91
|
+
| M-02 | 0% de chamadas Handler→Repository diretas | linter AST/grep |
|
|
92
|
+
| M-03 | 100% dos Handlers usam injeção (sem `new Service()` inline) | linter AST/grep |
|
|
93
|
+
| M-04 | 100% dos Repositories são agnósticos das camadas superiores (não retornam HTTP status) | linter |
|
|
94
|
+
|
|
95
|
+
## Tabela tradução por linguagem
|
|
96
|
+
|
|
97
|
+
| Camada DARE | Laravel | NestJS | FastAPI | Rails | Rust/Axum | Go/Gin |
|
|
98
|
+
|---|---|---|---|---|---|---|
|
|
99
|
+
| Handler | `Http/Controllers/` | `*.controller.ts` | `routers/*.py` | `app/controllers/` | `handlers/*.rs` | `handlers/*.go` |
|
|
100
|
+
| Service | `Services/` | `*.service.ts` | `services/*.py` | `app/services/` | `services/*.rs` | `services/*.go` |
|
|
101
|
+
| Repository | `Repositories/` | `*.repository.ts` | `repositories/*.py` | `app/repositories/` | `repositories/*.rs` | `repositories/*.go` |
|
|
102
|
+
| Model | `Models/` | `entities/*.ts` | `models/*.py` | `app/models/` | `domain/*.rs` | `models/*.go` |
|
|
103
|
+
|
|
104
|
+
## Antipatterns
|
|
105
|
+
|
|
106
|
+
| AP | Antipattern | Sinal | Correção |
|
|
107
|
+
|---|---|---|---|
|
|
108
|
+
| AP-01 | Handler chama Repository | `controller.repo.find()` | Criar Service entre eles |
|
|
109
|
+
| AP-02 | Service faz SQL inline | `db.query("SELECT...")` em Service | Mover para Repository |
|
|
110
|
+
| AP-03 | Repository lança exceção de domínio | `throw UserNotFound` em Repo | Retornar `null`/`Option`/`Maybe` |
|
|
111
|
+
| AP-04 | Model importa Service | `Model.payment_service` | Refatorar: Service usa Model, não o contrário |
|
|
112
|
+
| AP-05 | God Service (tudo em uma classe) | `UserService` com 30 métodos | Quebrar em `RegisterUser`, `ResetPassword`, ... |
|
|
113
|
+
| AP-06 | Fat Controller | Controller > 100 linhas | Mover lógica para Service |
|
|
114
|
+
|
|
115
|
+
## Como aplicar na prática
|
|
116
|
+
|
|
117
|
+
### Passo 1: Identificar as camadas no projeto
|
|
118
|
+
|
|
119
|
+
Mapear pastas existentes para as 4 camadas. Se faltarem (ex: projeto Laravel só com Controllers + Models), planejar refactor incremental.
|
|
120
|
+
|
|
121
|
+
### Passo 2: Adicionar lint
|
|
122
|
+
|
|
123
|
+
Use ESLint plugin custom, Rubocop cop custom, clippy lint custom, ou apenas grep em CI:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# Detecta Handler→Repository direto
|
|
127
|
+
grep -rn "import.*Repository" src/controllers/ && exit 1
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Passo 3: Cobrir Services com testes unitários
|
|
131
|
+
|
|
132
|
+
Service NÃO depende de DB nem HTTP real — usa Repository mockado. Suite roda em milissegundos.
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
// Exemplo NestJS
|
|
136
|
+
describe('RegisterUserService', () => {
|
|
137
|
+
it('falha se email já existe', async () => {
|
|
138
|
+
const repo = { findByEmail: jest.fn().mockResolvedValue({id: 1}) };
|
|
139
|
+
const sut = new RegisterUserService(repo as any);
|
|
140
|
+
await expect(sut.execute({email: 'x@y.com'})).rejects.toThrow('email exists');
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Passo 4: Validar com Ralph Loop
|
|
146
|
+
|
|
147
|
+
A cada task:
|
|
148
|
+
- `npm test` / `cargo test` / `pytest` — Services 100% verde
|
|
149
|
+
- `npm run lint` — sem AP-01 a AP-06
|
|
150
|
+
|
|
151
|
+
## Boas práticas
|
|
152
|
+
|
|
153
|
+
1. **Uma operação = um Service** — facilita teste, reuso e nomeação
|
|
154
|
+
2. **Repository devolve Model, não DTO** — DTO é responsabilidade do Handler/Presenter
|
|
155
|
+
3. **Models são imutáveis quando possível** — mudanças passam por Service
|
|
156
|
+
4. **Presenter como 5ª camada opcional** — converte Model → JSON/XML
|
|
157
|
+
|
|
158
|
+
## Dicas para melhor resultado
|
|
159
|
+
|
|
160
|
+
- **Leia** `docs/design/skills/dare-layered-design/DESIGN.md` para o "porquê" e exemplos detalhados
|
|
161
|
+
- **Combine** com `dare-feature-design` ao adicionar feature em código legado — siga as 4 camadas mesmo se o legado não seguir
|
|
162
|
+
- **Templates de scaffold** estão em `packages/skills/dare-layered-design/` por linguagem
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
Esta skill é parte do DARE Method e está sob licença MIT.
|