@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,147 @@
|
|
|
1
|
+
# /dare-feature-design
|
|
2
|
+
|
|
3
|
+
Analisa um projeto existente e gera `DARE/DESIGN-Feature-[Nome].md` focado apenas em adicionar uma nova feature, respeitando a arquitetura legada.
|
|
4
|
+
|
|
5
|
+
## Como usar
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
/dare-feature-design # interativo
|
|
9
|
+
/dare-feature-design "Adicionar 2FA via TOTP no login" # com descrição
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Quando usar
|
|
13
|
+
|
|
14
|
+
- Projeto já existe e usuário pede para adicionar uma feature
|
|
15
|
+
- Projeto não nasceu com Método DARE, mas vai adotar para novas funcionalidades
|
|
16
|
+
- Feature é grande o suficiente para precisar de planejamento (não é fix de uma linha)
|
|
17
|
+
|
|
18
|
+
## O que fazer
|
|
19
|
+
|
|
20
|
+
### 1. Análise de contexto (obrigatória)
|
|
21
|
+
|
|
22
|
+
Antes de propor qualquer coisa, leia o projeto:
|
|
23
|
+
|
|
24
|
+
- **Stack** — `composer.json` / `package.json` / `Cargo.toml` / `go.mod` / `requirements.txt`
|
|
25
|
+
- **Arquitetura** — MVC, Hexagonal, CQRS? Layered? Onde moram Controllers, Services, Repositories?
|
|
26
|
+
- **Banco de dados** — leia migrations existentes para entender esquema da feature
|
|
27
|
+
- **Dependências chave** — auth (Sanctum, JWT, Devise?), permissões (Spatie, Pundit?), forms, ORM
|
|
28
|
+
- **Convenções** — naming, estrutura de pastas, padrões de teste
|
|
29
|
+
|
|
30
|
+
### 2. Entender a feature
|
|
31
|
+
|
|
32
|
+
- **Valor de negócio** — qual problema do usuário resolve?
|
|
33
|
+
- **Novos endpoints / telas** — quais?
|
|
34
|
+
- **Conexão com o existente** — usa que módulos? quem chama?
|
|
35
|
+
- **Dados novos vs existentes** — tabela nova ou só colunas?
|
|
36
|
+
|
|
37
|
+
### 3. Avaliar impacto e segurança
|
|
38
|
+
|
|
39
|
+
- **Arquivos novos** — controllers, services, repositories, components a criar
|
|
40
|
+
- **Arquivos modificados** — quais existentes vão precisar mudar?
|
|
41
|
+
- **Banco de dados** — migrations + scripts de seed?
|
|
42
|
+
- **Segurança específica (OWASP)** — auth, autorização por recurso, validação, rate limit
|
|
43
|
+
- **Performance** — query nova é cara? cache? índice?
|
|
44
|
+
|
|
45
|
+
### 4. Gerar `DARE/DESIGN-Feature-[Nome].md`
|
|
46
|
+
|
|
47
|
+
Estrutura obrigatória:
|
|
48
|
+
|
|
49
|
+
```markdown
|
|
50
|
+
# Feature Design: [Nome da Feature]
|
|
51
|
+
|
|
52
|
+
## Contexto no Projeto Existente
|
|
53
|
+
Resumo de como a feature se encaixa no ecossistema atual.
|
|
54
|
+
|
|
55
|
+
## Objetivos da Feature
|
|
56
|
+
- [O-01] [objetivo 1 com métrica]
|
|
57
|
+
- [O-02] [objetivo 2 com métrica]
|
|
58
|
+
|
|
59
|
+
## Stakeholders
|
|
60
|
+
| Papel | Pessoa/Time | Interesse |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
|
|
63
|
+
## Análise de Impacto
|
|
64
|
+
|
|
65
|
+
### Novos Arquivos
|
|
66
|
+
- `app/Controllers/TwoFactorController.php`
|
|
67
|
+
- `app/Services/EnrollTotp.php`
|
|
68
|
+
- `app/Models/UserMfaSecret.php`
|
|
69
|
+
|
|
70
|
+
### Arquivos Modificados
|
|
71
|
+
- `app/Controllers/AuthController.php` — adiciona challenge step
|
|
72
|
+
- `routes/api.php` — novas rotas
|
|
73
|
+
|
|
74
|
+
### Banco de Dados
|
|
75
|
+
- Nova tabela `user_mfa_secrets`
|
|
76
|
+
- Coluna `users.mfa_enabled` (boolean default false)
|
|
77
|
+
|
|
78
|
+
## Requisitos Funcionais
|
|
79
|
+
| ID | Requisito | Prioridade | Critério de aceite |
|
|
80
|
+
|---|---|---|---|
|
|
81
|
+
| RF-01 | … | MUST | … |
|
|
82
|
+
|
|
83
|
+
## Segurança Específica (OWASP)
|
|
84
|
+
- **A01 (Access Control):** [como filtra por owner]
|
|
85
|
+
- **A02 (Crypto):** [TOTP secret cifrado at rest]
|
|
86
|
+
- **A03 (Injection):** [validações]
|
|
87
|
+
- **A07 (Auth):** [rate limit no challenge]
|
|
88
|
+
|
|
89
|
+
## Restrições e Cuidados
|
|
90
|
+
- **NÃO alterar:** [partes do código legado intocáveis]
|
|
91
|
+
- **Compatibilidade:** [usuários antigos sem MFA continuam funcionando]
|
|
92
|
+
- **Migrations:** [reversível? safe em produção sem downtime?]
|
|
93
|
+
|
|
94
|
+
## Estratégia de Rollout
|
|
95
|
+
- Feature flag `feature.mfa_enabled` default off
|
|
96
|
+
- Habilitar para 1% → 10% → 100%
|
|
97
|
+
- Rollback = desabilitar flag
|
|
98
|
+
|
|
99
|
+
## Métricas de Sucesso
|
|
100
|
+
- M-01: % de usuários com MFA habilitado após 30 dias
|
|
101
|
+
- M-02: queda em logins fraudulentos
|
|
102
|
+
- M-03: 0 incidentes de lockout de conta legítima
|
|
103
|
+
|
|
104
|
+
## Riscos e Mitigações
|
|
105
|
+
| Risco | Probabilidade | Impacto | Mitigação |
|
|
106
|
+
|---|---|---|---|
|
|
107
|
+
|
|
108
|
+
## Fora do Escopo (v1)
|
|
109
|
+
- WebAuthn (apenas TOTP)
|
|
110
|
+
- Backup codes (próxima iteração)
|
|
111
|
+
|
|
112
|
+
## Próximas Etapas
|
|
113
|
+
1. Revisar e aprovar este Feature Design
|
|
114
|
+
2. Rodar `/dare-blueprint` apontando para este arquivo
|
|
115
|
+
3. Gerar tasks com `/dare-tasks`
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 5. Pedir aprovação
|
|
119
|
+
|
|
120
|
+
Apresente o documento ao usuário. Mostre especialmente:
|
|
121
|
+
- Os arquivos que serão modificados (impacto no legado)
|
|
122
|
+
- A análise de segurança específica
|
|
123
|
+
- O que NÃO será mudado
|
|
124
|
+
|
|
125
|
+
## Regras de ouro para features em projetos existentes
|
|
126
|
+
|
|
127
|
+
1. **Siga os padrões locais** — adapte a feature ao padrão existente, mesmo que você ache que poderia ser melhor (refactor é outra história)
|
|
128
|
+
2. **Isolamento máximo** — mantenha o impacto no legado o mínimo possível
|
|
129
|
+
3. **Testes nascem com a feature** — mesmo que o legado não tenha testes, a nova feature DEVE nascer com testes isolados
|
|
130
|
+
4. **Segurança inegociável** — aplique OWASP na feature nova, mesmo que o legado seja inseguro
|
|
131
|
+
5. **Feature flag quando possível** — permite rollout gradual e rollback fácil
|
|
132
|
+
|
|
133
|
+
## Antipatterns
|
|
134
|
+
|
|
135
|
+
| AP | Antipattern | Por quê |
|
|
136
|
+
|---|---|---|
|
|
137
|
+
| AP-01 | Refatorar legado junto com feature | Aumenta blast radius e dificulta revisão |
|
|
138
|
+
| AP-02 | Ignorar padrões existentes | Feature vira "ilha" inconsistente |
|
|
139
|
+
| AP-03 | Feature sem teste porque "legado não tem" | Perpetua o problema |
|
|
140
|
+
| AP-04 | Modificar o que não é necessário | Bug introduzido em código não relacionado |
|
|
141
|
+
| AP-05 | Pular análise de impacto | Surpresas em produção |
|
|
142
|
+
|
|
143
|
+
$ARGUMENTS
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
Skill MIT — parte do DARE Method.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# /dare-frontend-design
|
|
2
|
+
|
|
3
|
+
Arquitetura frontend DARE para projetos React e Vue. Detecta god components, fetch inline em JSX/template, e gera scaffold DARE-compliant.
|
|
4
|
+
|
|
5
|
+
## Como usar
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
/dare-frontend-design # audita projeto atual
|
|
9
|
+
/dare-frontend-design lint # roda checks AP-01 a AP-06
|
|
10
|
+
/dare-frontend-design scaffold <página> # gera Page + Container + Hook + Presentational
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Arquitetura
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
Page → Container (lógica) → Presentational (puro)
|
|
17
|
+
↑
|
|
18
|
+
Hook (fetch + cache)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## As 4 regras
|
|
22
|
+
|
|
23
|
+
### 1. Componente < 300 linhas
|
|
24
|
+
|
|
25
|
+
Se passar de 300, quebrar em sub-componentes, hooks ou helpers.
|
|
26
|
+
|
|
27
|
+
### 2. Zero `fetch()` em JSX/template
|
|
28
|
+
|
|
29
|
+
Use TanStack Query (React/Vue), SWR ou similar. Hook devolve `{ data, isLoading, error }`.
|
|
30
|
+
|
|
31
|
+
### 3. Error Boundary em cada Page
|
|
32
|
+
|
|
33
|
+
React: `<ErrorBoundary>` wrapping rotas.
|
|
34
|
+
Vue: `onErrorCaptured` em layout/page-level.
|
|
35
|
+
|
|
36
|
+
### 4. Bundle size monitorado
|
|
37
|
+
|
|
38
|
+
`rollup-plugin-visualizer`, `webpack-bundle-analyzer`. Limite por chunk (ex: <300KB inicial).
|
|
39
|
+
|
|
40
|
+
## Métricas obrigatórias
|
|
41
|
+
|
|
42
|
+
| ID | Métrica |
|
|
43
|
+
|---|---|
|
|
44
|
+
| M-01 | 100% de componentes < 300 linhas |
|
|
45
|
+
| M-02 | 0 `fetch()` direto em JSX/template |
|
|
46
|
+
| M-03 | 100% de páginas com error boundary |
|
|
47
|
+
| M-04 | Bundle config presente |
|
|
48
|
+
|
|
49
|
+
## Antipatterns
|
|
50
|
+
|
|
51
|
+
| AP | Antipattern | Correção |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| AP-01 | God component (>300 linhas) | Quebrar em sub-componentes + hooks |
|
|
54
|
+
| AP-02 | Fetch em JSX | Mover para hook |
|
|
55
|
+
| AP-03 | Booleanos isLoading espalhados | Discriminated union de estados |
|
|
56
|
+
| AP-04 | Sem error boundary | Wrap em `<ErrorBoundary>` |
|
|
57
|
+
| AP-05 | Estilo inline pesado | CSS module/styled |
|
|
58
|
+
| AP-06 | Props drilling profundo | Context/Zustand/Pinia |
|
|
59
|
+
|
|
60
|
+
## O que fazer
|
|
61
|
+
|
|
62
|
+
### Passo 1: Detectar god components
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
find src/ -name "*.tsx" -o -name "*.vue" | xargs wc -l | sort -rn | head -20
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Passo 2: Detectar fetch inline
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
grep -rn "fetch(\|axios\." src/components/ src/pages/
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Passo 3: Migrar para hooks de dados
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
// Antes
|
|
78
|
+
function UserList() {
|
|
79
|
+
const [users, setUsers] = useState([]);
|
|
80
|
+
useEffect(() => { fetch('/api/users').then(r => r.json()).then(setUsers); }, []);
|
|
81
|
+
return <ul>{users.map(...)}</ul>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Depois
|
|
85
|
+
function UserList() {
|
|
86
|
+
const { data, isLoading, error } = useUsers();
|
|
87
|
+
if (isLoading) return <Spinner />;
|
|
88
|
+
if (error) return <ErrorMessage error={error} />;
|
|
89
|
+
return <ul>{data.map(...)}</ul>;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function useUsers() {
|
|
93
|
+
return useQuery({ queryKey: ['users'], queryFn: () => api.users.list() });
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Passo 4: Error boundaries
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
// React
|
|
101
|
+
class ErrorBoundary extends React.Component { ... }
|
|
102
|
+
|
|
103
|
+
<ErrorBoundary fallback={<ErrorPage />}>
|
|
104
|
+
<UserList />
|
|
105
|
+
</ErrorBoundary>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```vue
|
|
109
|
+
<!-- Vue -->
|
|
110
|
+
<script setup>
|
|
111
|
+
import { onErrorCaptured } from 'vue';
|
|
112
|
+
onErrorCaptured((err) => { logError(err); return false; });
|
|
113
|
+
</script>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Passo 5: Bundle analyzer
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
// vite.config.ts
|
|
120
|
+
import { visualizer } from 'rollup-plugin-visualizer';
|
|
121
|
+
export default {
|
|
122
|
+
plugins: [visualizer({ open: false, gzipSize: true })],
|
|
123
|
+
build: { chunkSizeWarningLimit: 300 }
|
|
124
|
+
};
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Stack recomendada
|
|
128
|
+
|
|
129
|
+
| Camada | React | Vue |
|
|
130
|
+
|---|---|---|
|
|
131
|
+
| Roteamento | React Router / Next | Vue Router / Nuxt |
|
|
132
|
+
| Estado server | TanStack Query | TanStack Vue Query |
|
|
133
|
+
| Estado client | Zustand / Jotai | Pinia |
|
|
134
|
+
| Styling | Tailwind / CSS Modules | Tailwind / SCSS |
|
|
135
|
+
| Testes | Vitest + Testing Library | Vitest + Testing Library |
|
|
136
|
+
|
|
137
|
+
## Saída esperada
|
|
138
|
+
|
|
139
|
+
Reporte:
|
|
140
|
+
- Top 10 componentes com mais linhas
|
|
141
|
+
- Lista de `fetch()`/`axios` inline em componentes
|
|
142
|
+
- Páginas sem error boundary
|
|
143
|
+
- Configuração de bundle (presente/ausente)
|
|
144
|
+
|
|
145
|
+
$ARGUMENTS
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
Skill MIT — parte do DARE Method.
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# /dare-laravel-api
|
|
2
|
+
|
|
3
|
+
Padrões DARE para APIs REST em Laravel 11 + PHP 8.3. Strict Types, FormRequests, Services, Resources, Repositories, Eloquent + casts, tratamento global de exceções, testes Pest, PHPStan/Larastan nível 8.
|
|
4
|
+
|
|
5
|
+
## Como usar
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
/dare-laravel-api # audita projeto Laravel
|
|
9
|
+
/dare-laravel-api scaffold users # gera CRUD com camadas
|
|
10
|
+
/dare-laravel-api migrate-controllers # extrai lógica de Controllers para Services
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Stack canônica
|
|
14
|
+
|
|
15
|
+
- PHP 8.3 com `declare(strict_types=1);` em todo arquivo
|
|
16
|
+
- Laravel 11.x modo API
|
|
17
|
+
- PostgreSQL 16 ou MySQL 8
|
|
18
|
+
- Pest para testes (ou PHPUnit 11)
|
|
19
|
+
- PHPStan + Larastan nível 8
|
|
20
|
+
- Pint para formatação
|
|
21
|
+
- Sanctum para auth
|
|
22
|
+
|
|
23
|
+
## Layered Design
|
|
24
|
+
|
|
25
|
+
| Camada | Pasta Laravel |
|
|
26
|
+
|---|---|
|
|
27
|
+
| Handler | `app/Http/Controllers/` |
|
|
28
|
+
| Service | `app/Services/` |
|
|
29
|
+
| Repository | `app/Repositories/` |
|
|
30
|
+
| Model | `app/Models/` |
|
|
31
|
+
| Presenter | `app/Http/Resources/` |
|
|
32
|
+
|
|
33
|
+
## Controllers (Handler)
|
|
34
|
+
|
|
35
|
+
```php
|
|
36
|
+
<?php declare(strict_types=1);
|
|
37
|
+
|
|
38
|
+
namespace App\Http\Controllers;
|
|
39
|
+
|
|
40
|
+
use App\Http\Requests\StoreUserRequest;
|
|
41
|
+
use App\Http\Resources\UserResource;
|
|
42
|
+
use App\Services\RegisterUser;
|
|
43
|
+
|
|
44
|
+
final class UserApiController extends Controller
|
|
45
|
+
{
|
|
46
|
+
public function __construct(private RegisterUser $service) {}
|
|
47
|
+
|
|
48
|
+
public function store(StoreUserRequest $request): UserResource
|
|
49
|
+
{
|
|
50
|
+
$user = $this->service->execute($request->validated());
|
|
51
|
+
return new UserResource($user);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Regras:
|
|
57
|
+
- Apenas: recebe → valida via FormRequest → chama Service → retorna Resource
|
|
58
|
+
- NUNCA: query Eloquent, lógica de negócio, validação inline
|
|
59
|
+
|
|
60
|
+
## FormRequests
|
|
61
|
+
|
|
62
|
+
```php
|
|
63
|
+
final class StoreUserRequest extends FormRequest
|
|
64
|
+
{
|
|
65
|
+
public function authorize(): bool { return $this->user()->can('create', User::class); }
|
|
66
|
+
|
|
67
|
+
public function rules(): array {
|
|
68
|
+
return [
|
|
69
|
+
'email' => ['required', 'email', 'unique:users,email'],
|
|
70
|
+
'password' => ['required', 'string', 'min:12'],
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Services
|
|
77
|
+
|
|
78
|
+
Uma operação por classe:
|
|
79
|
+
|
|
80
|
+
```php
|
|
81
|
+
final class RegisterUser
|
|
82
|
+
{
|
|
83
|
+
public function __construct(private UserRepository $users) {}
|
|
84
|
+
|
|
85
|
+
public function execute(array $data): User
|
|
86
|
+
{
|
|
87
|
+
if ($this->users->existsByEmail($data['email'])) {
|
|
88
|
+
throw new UserAlreadyExistsException();
|
|
89
|
+
}
|
|
90
|
+
return $this->users->create([...$data, 'password' => Hash::make($data['password'])]);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Repositories
|
|
96
|
+
|
|
97
|
+
```php
|
|
98
|
+
final class UserRepository
|
|
99
|
+
{
|
|
100
|
+
public function existsByEmail(string $email): bool {
|
|
101
|
+
return User::where('email', $email)->exists();
|
|
102
|
+
}
|
|
103
|
+
public function create(array $data): User {
|
|
104
|
+
return User::create($data);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Resources
|
|
110
|
+
|
|
111
|
+
Nunca retorne Model direto:
|
|
112
|
+
|
|
113
|
+
```php
|
|
114
|
+
final class UserResource extends JsonResource
|
|
115
|
+
{
|
|
116
|
+
public function toArray($request): array {
|
|
117
|
+
return [
|
|
118
|
+
'id' => $this->id,
|
|
119
|
+
'email' => $this->email,
|
|
120
|
+
'createdAt' => $this->created_at?->toIso8601String(),
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Exceções globais (`bootstrap/app.php`)
|
|
127
|
+
|
|
128
|
+
```php
|
|
129
|
+
->withExceptions(function (Exceptions $exceptions) {
|
|
130
|
+
$exceptions->render(fn (UserAlreadyExistsException $e) =>
|
|
131
|
+
response()->json(['error' => 'User exists', 'code' => 'USER_EXISTS'], 409));
|
|
132
|
+
})
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Transações
|
|
136
|
+
|
|
137
|
+
```php
|
|
138
|
+
DB::transaction(function () use ($data) {
|
|
139
|
+
$user = User::create($data);
|
|
140
|
+
UserProfile::create([...]);
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Testes Pest
|
|
145
|
+
|
|
146
|
+
```php
|
|
147
|
+
it('cria usuário com sucesso', function () {
|
|
148
|
+
$this->actingAs(User::factory()->admin()->create())
|
|
149
|
+
->postJson('/api/users', ['email' => 'jane@example.com', 'name' => 'Jane', 'password' => 'longsecret123'])
|
|
150
|
+
->assertCreated();
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('rejeita email duplicado', function () {
|
|
154
|
+
User::factory()->create(['email' => 'taken@example.com']);
|
|
155
|
+
$this->actingAs(User::factory()->admin()->create())
|
|
156
|
+
->postJson('/api/users', ['email' => 'taken@example.com', ...])
|
|
157
|
+
->assertStatus(409);
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Cobertura mínima por endpoint: 200/201, 422, 401/403, 404.
|
|
162
|
+
|
|
163
|
+
## Antipatterns
|
|
164
|
+
|
|
165
|
+
| AP | Antipattern | Correção |
|
|
166
|
+
|---|---|---|
|
|
167
|
+
| AP-01 | `$request->validate()` no Controller | FormRequest |
|
|
168
|
+
| AP-02 | Query Eloquent no Controller | Repository |
|
|
169
|
+
| AP-03 | Lógica no Controller | Service |
|
|
170
|
+
| AP-04 | Retornar Model direto | JsonResource |
|
|
171
|
+
| AP-05 | `$guarded = []` | `$fillable` explícito |
|
|
172
|
+
| AP-06 | Sem `declare(strict_types=1)` | Adicionar no topo |
|
|
173
|
+
| AP-07 | Múltiplas inserções sem transaction | `DB::transaction()` |
|
|
174
|
+
| AP-08 | `bcrypt()` default cost | `Hash::make($pwd, ['rounds' => 12])` |
|
|
175
|
+
|
|
176
|
+
## Validação no CI
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
./vendor/bin/phpstan analyse --level=8
|
|
180
|
+
./vendor/bin/pint --test
|
|
181
|
+
./vendor/bin/pest --coverage --min=80
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## O que fazer
|
|
185
|
+
|
|
186
|
+
1. Audit:
|
|
187
|
+
```bash
|
|
188
|
+
grep -rn "request()->validate" app/Http/Controllers/
|
|
189
|
+
grep -rn "::where\|::find" app/Http/Controllers/
|
|
190
|
+
./vendor/bin/phpstan analyse --level=8
|
|
191
|
+
```
|
|
192
|
+
2. Para cada `$request->validate(...)` → FormRequest com `php artisan make:request`
|
|
193
|
+
3. Para cada Controller com lógica > 10 linhas → Service
|
|
194
|
+
4. Para cada query Eloquent em Controller → Repository
|
|
195
|
+
5. Substituir `return $user` por `return new UserResource($user)`
|
|
196
|
+
6. Adicionar `declare(strict_types=1);` em todo arquivo
|
|
197
|
+
|
|
198
|
+
## Segurança (combinar com `/dare-security`)
|
|
199
|
+
|
|
200
|
+
- Hash com `Hash::make($pwd, ['rounds' => 12])` ou Argon2
|
|
201
|
+
- Sanctum para SPA/mobile
|
|
202
|
+
- `ThrottleRequests` middleware
|
|
203
|
+
- Headers de segurança (HSTS, X-Frame, CSP) em middleware
|
|
204
|
+
- CORS específico, nunca `*` em produção
|
|
205
|
+
- `$fillable` SEMPRE, nunca `$guarded = []`
|
|
206
|
+
|
|
207
|
+
$ARGUMENTS
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
Skill MIT — parte do DARE Method.
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# /dare-layered-design
|
|
2
|
+
|
|
3
|
+
Enforce arquitetura estrita de 4 camadas (Handlers, Services, Repositories, Models) em projetos DARE — independente de linguagem.
|
|
4
|
+
|
|
5
|
+
## Como usar
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
/dare-layered-design # audita projeto atual
|
|
9
|
+
/dare-layered-design lint # roda checks AP-01 a AP-06
|
|
10
|
+
/dare-layered-design scaffold <recurso> # gera CRUD com camadas corretas
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## As 4 camadas
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
Handler → Service → Repository → Model
|
|
17
|
+
(HTTP) (negócio) (I/O) (domínio)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Handler
|
|
21
|
+
- Recebe request, valida input, chama um Service, retorna response
|
|
22
|
+
- **Nunca** acessa Repository direto, **nunca** instancia Service com `new`
|
|
23
|
+
|
|
24
|
+
### Service
|
|
25
|
+
- Implementa uma operação de negócio (`RegisterUser`, `RefundPayment`)
|
|
26
|
+
- Orquestra Repositories
|
|
27
|
+
- **Nunca** sabe sobre HTTP, **nunca** faz SQL inline
|
|
28
|
+
|
|
29
|
+
### Repository
|
|
30
|
+
- Abstrai persistência (DB, cache, API externa)
|
|
31
|
+
- Retorna Model ou primitivo
|
|
32
|
+
- **Nunca** retorna HTTP status, **nunca** lança exceção de domínio
|
|
33
|
+
|
|
34
|
+
### Model
|
|
35
|
+
- Entidade pura do domínio
|
|
36
|
+
- **Nunca** importa Repository/Service/Handler
|
|
37
|
+
|
|
38
|
+
## Métricas obrigatórias
|
|
39
|
+
|
|
40
|
+
| ID | Métrica |
|
|
41
|
+
|---|---|
|
|
42
|
+
| M-01 | 100% dos Services têm testes unitários (sem DB/HTTP real) |
|
|
43
|
+
| M-02 | 0% de chamadas Handler→Repository direto |
|
|
44
|
+
| M-03 | 100% dos Handlers usam injeção (sem `new Service()`) |
|
|
45
|
+
| M-04 | 100% dos Repositories são agnósticos das camadas superiores |
|
|
46
|
+
|
|
47
|
+
## Tabela por linguagem
|
|
48
|
+
|
|
49
|
+
| Camada | Laravel | NestJS | FastAPI | Rails | Rust | Go |
|
|
50
|
+
|---|---|---|---|---|---|---|
|
|
51
|
+
| Handler | `Http/Controllers/` | `*.controller.ts` | `routers/` | `app/controllers/` | `handlers/` | `handlers/` |
|
|
52
|
+
| Service | `Services/` | `*.service.ts` | `services/` | `app/services/` | `services/` | `services/` |
|
|
53
|
+
| Repository | `Repositories/` | `*.repository.ts` | `repositories/` | `app/repositories/` | `repositories/` | `repositories/` |
|
|
54
|
+
| Model | `Models/` | `entities/` | `models/` | `app/models/` | `domain/` | `models/` |
|
|
55
|
+
|
|
56
|
+
## Antipatterns
|
|
57
|
+
|
|
58
|
+
| AP | Antipattern | Sinal |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| AP-01 | Handler→Repository direto | `controller.repo.find()` |
|
|
61
|
+
| AP-02 | Service com SQL inline | `db.query()` em Service |
|
|
62
|
+
| AP-03 | Repository lança exceção de domínio | `throw UserNotFound` |
|
|
63
|
+
| AP-04 | Model importa Service | acoplamento invertido |
|
|
64
|
+
| AP-05 | God Service (>20 métodos) | `UserService.everything()` |
|
|
65
|
+
| AP-06 | Fat Controller (>100 linhas) | lógica em Handler |
|
|
66
|
+
|
|
67
|
+
## O que fazer
|
|
68
|
+
|
|
69
|
+
### Passo 1: Mapear camadas existentes
|
|
70
|
+
|
|
71
|
+
Liste as pastas atuais e classifique cada uma como Handler, Service, Repository, Model ou "indefinido". Indefinido = candidato a refactor.
|
|
72
|
+
|
|
73
|
+
### Passo 2: Detectar violações com grep
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# AP-01: Handler→Repository direto
|
|
77
|
+
grep -rn "Repository" src/controllers/ # Laravel/NestJS
|
|
78
|
+
grep -rn "Repository" app/controllers/ # Rails
|
|
79
|
+
|
|
80
|
+
# AP-02: SQL inline em Service
|
|
81
|
+
grep -rn "SELECT\\|INSERT\\|UPDATE\\|DELETE" src/services/
|
|
82
|
+
|
|
83
|
+
# AP-03: Exceção de domínio em Repository
|
|
84
|
+
grep -rn "throw.*NotFound\\|raise.*NotFound" src/repositories/
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Passo 3: Quebrar God Service
|
|
88
|
+
|
|
89
|
+
Para cada Service com >20 métodos, separe em vários services nomeados por operação:
|
|
90
|
+
- `UserService.register()` → `RegisterUser`
|
|
91
|
+
- `UserService.resetPassword()` → `ResetPassword`
|
|
92
|
+
- `UserService.delete()` → `DeleteUser`
|
|
93
|
+
|
|
94
|
+
### Passo 4: Cobrir Services com testes unitários
|
|
95
|
+
|
|
96
|
+
Service não depende de DB nem HTTP real — Repository é mockado:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
const repo = { findByEmail: jest.fn().mockResolvedValue({id: 1}) };
|
|
100
|
+
const sut = new RegisterUserService(repo as any);
|
|
101
|
+
await expect(sut.execute(...)).rejects.toThrow();
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Passo 5: Adicionar lint no CI
|
|
105
|
+
|
|
106
|
+
```yaml
|
|
107
|
+
- name: Layered design lint
|
|
108
|
+
run: |
|
|
109
|
+
grep -rn "Repository" src/controllers/ && exit 1 || true
|
|
110
|
+
grep -rn "new .*Service" src/controllers/ && exit 1 || true
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Saída esperada
|
|
114
|
+
|
|
115
|
+
Reporte numerado por antipattern (AP-01 a AP-06):
|
|
116
|
+
- Quantas violações por arquivo
|
|
117
|
+
- Sugestão concreta de refactor para cada uma
|
|
118
|
+
- Lista de Services sem cobertura unitária
|
|
119
|
+
|
|
120
|
+
$ARGUMENTS
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
Skill MIT — parte do DARE Method. Inspirado em "Layered Design for Ruby on Rails Applications" de Vladimir Dementyev (Evil Martians).
|