@dewtech/dare-cli 2.17.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 +98 -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.js +49 -49
- 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.js +38 -38
- package/dist/__tests__/validate.test.js +65 -65
- package/dist/bin/dare.js +32 -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/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/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/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/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/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.js +252 -252
- 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/package.json +8 -3
- package/templates/DARE-dag-example.yaml +280 -280
- package/templates/UPDATE-MANIFEST.json +48 -48
- 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-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 -114
- package/templates/ide/antigravity/.agents/skills/dare-reverse/SKILL.md +108 -0
- package/templates/ide/antigravity/.agents/skills/dare-review/SKILL.md +111 -111
- 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 -265
- 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 -141
- package/templates/ide/claude/.claude/commands/dare-ax.md +131 -0
- package/templates/ide/claude/.claude/commands/dare-blueprint.md +134 -134
- package/templates/ide/claude/.claude/commands/dare-bugfix-design.md +119 -0
- package/templates/ide/claude/.claude/commands/dare-dag-build.md +151 -151
- 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 -145
- package/templates/ide/claude/.claude/commands/dare-reverse.md +139 -0
- package/templates/ide/claude/.claude/commands/dare-review.md +113 -113
- 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 -141
- package/templates/ide/cursor/.cursor/commands/dag-viz.md +139 -0
- package/templates/ide/cursor/.cursor/commands/generate-blueprint.md +86 -86
- package/templates/ide/cursor/.cursor/commands/generate-design.md +35 -35
- package/templates/ide/cursor/.cursor/commands/generate-tasks.md +184 -184
- package/templates/ide/cursor/.cursor/commands/refine-task.md +107 -107
- package/templates/ide/cursor/.cursor/commands/review-task.md +91 -91
- 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 -141
- 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,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Camada semântica da migração (Fase 2 brownfield). Roda depois do comando `dare migrate` e escreve a estratégia de migração + cenários Gherkin de paridade reais no DARE/MIGRATION/, garantindo reimplementação fiel ao legado.
|
|
3
|
+
globs: DARE/MIGRATION/**
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill: Migrate — Migração com paridade (brownfield Fase 2)
|
|
8
|
+
|
|
9
|
+
Camada **semântica** da migração. Roda **depois** do comando `dare migrate`, que já leu os artefatos
|
|
10
|
+
do `reverse`/`dna` e gerou os esqueletos. Sua função é **escrever a estratégia de migração e os
|
|
11
|
+
cenários Gherkin de paridade reais** — o contrato comportamental que garante reimplementação fiel.
|
|
12
|
+
|
|
13
|
+
> Pré-requisito: rodar `dare migrate --to <stack>` antes (gera `DARE/MIGRATION/MIGRATION.md`,
|
|
14
|
+
> `migration-facts.json`, `parity/*.feature`). Que por sua vez exige `dare reverse` já feito.
|
|
15
|
+
|
|
16
|
+
## Quando usar
|
|
17
|
+
- Projeto legado entendido (`reverse` + `dna`) que será reimplementado em outra stack.
|
|
18
|
+
- Acabou de rodar `dare migrate` e há seções `<!-- AGENT -->` / `# AGENT` em aberto.
|
|
19
|
+
|
|
20
|
+
## O que fazer
|
|
21
|
+
|
|
22
|
+
### 1. Carregar contexto (não re-varrer)
|
|
23
|
+
Leia `migration-facts.json` (origem/alvo/módulos/blocking gaps), `IDEIA.md` + `REVERSE/module-*.md`
|
|
24
|
+
e `PROJECT-DNA.md`. Abra arquivos-chave do legado só o necessário.
|
|
25
|
+
|
|
26
|
+
### 2. Preencher `MIGRATION.md`
|
|
27
|
+
- **Decisão de Paradigma** — mudou (procedural→OO, monólito→serviços)? Decisão + justificativa.
|
|
28
|
+
- **Estratégia** — big-bang vs. strangler/parallel-run; ordem dos módulos; feature flags.
|
|
29
|
+
- **Registro de Risco** — tratar cada blocking gap (🔴) + riscos de regressão/dados/performance.
|
|
30
|
+
- **Arquitetura-alvo** — na stack-alvo, alinhada ao DNA quando o paradigma for preservado.
|
|
31
|
+
- **Cutover & Rollback** — passos, validação de paridade (rodar `.feature`), go/no-go, rollback.
|
|
32
|
+
|
|
33
|
+
### 3. Gherkin de paridade (`parity/<módulo>.feature`)
|
|
34
|
+
Um `Scenario` por fluxo observável, derivado do **comportamento legado real**: `Given` → `When` →
|
|
35
|
+
`Then` idêntico ao legado. Inclua bordas/formatos (arredondamento, máscaras). É o contrato de aceite.
|
|
36
|
+
|
|
37
|
+
### 4. Apresentar ao usuário
|
|
38
|
+
Resumo: paradigma, estratégia, nº de cenários, blocking gaps a resolver.
|
|
39
|
+
|
|
40
|
+
## Regras de ouro
|
|
41
|
+
1. **Paridade primeiro** — todo fluxo crítico vira `Scenario`.
|
|
42
|
+
2. **Blocking gaps são bloqueantes** — 🔴 não resolvido é risco; trate ou registre.
|
|
43
|
+
3. **Respeite o DNA** — arquitetura-alvo segue as convenções da casa.
|
|
44
|
+
4. **Não invente comportamento** — cenário sem base no legado = regressão silenciosa.
|
|
45
|
+
5. **Strangler quando possível** — incremental com parallel-run reduz risco.
|
|
46
|
+
|
|
47
|
+
## Antipatterns
|
|
48
|
+
| AP | Antipattern | Por quê |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| AP-01 | Gherkin genérico sem base no legado | Não garante paridade |
|
|
51
|
+
| AP-02 | Ignorar blocking gaps (🔴) | Reimplementa sobre incerteza |
|
|
52
|
+
| AP-03 | Big-bang sem necessidade | Maximiza risco |
|
|
53
|
+
| AP-04 | Arquitetura-alvo desalinhada do DNA | Código vira ilha inconsistente |
|
|
54
|
+
| AP-05 | Reescrever os fatos determinísticos do CLI | Quebra a fonte de verdade |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
Skill MIT — parte do DARE Method. Fase 2 (brownfield). Pareia com o comando `dare migrate`.
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Padrões DARE para APIs REST em NestJS + TypeScript + Prisma + Swagger. Modules, Controllers, Services, DTOs com class-validator, Guards JWT, throttler, exceções globais, Jest + Supertest, OpenAPI auto-gerado.
|
|
3
|
+
globs: src/**/*.ts,src/**/*.controller.ts,src/**/*.service.ts,src/**/*.module.ts,prisma/schema.prisma
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill: NestJS API DARE
|
|
8
|
+
|
|
9
|
+
Você é um desenvolvedor sênior TypeScript / NestJS focado em APIs REST. Esta skill garante código **idiomático Nest, fortemente tipado, com auth/autz robustos e OpenAPI auto-gerado**, seguindo Layered Design DARE.
|
|
10
|
+
|
|
11
|
+
## Stack canônica
|
|
12
|
+
|
|
13
|
+
- **TypeScript 5.5+** com `strict: true`
|
|
14
|
+
- **NestJS 11.x**
|
|
15
|
+
- **Prisma 5.x** ORM (PostgreSQL ou MySQL)
|
|
16
|
+
- **class-validator + class-transformer**
|
|
17
|
+
- **@nestjs/swagger**
|
|
18
|
+
- **@nestjs/throttler**
|
|
19
|
+
- **@nestjs/passport + @nestjs/jwt**
|
|
20
|
+
- **Jest + Supertest**
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Estrutura de módulo (Layered Design)
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
src/<feature>/
|
|
28
|
+
├── <feature>.module.ts ← providers + controllers
|
|
29
|
+
├── <feature>.controller.ts ← Handler
|
|
30
|
+
├── <feature>.service.ts ← Service (1 operação ou facade)
|
|
31
|
+
├── <feature>.repository.ts ← Repository (Prisma)
|
|
32
|
+
├── dto/
|
|
33
|
+
│ ├── create-<feature>.dto.ts
|
|
34
|
+
│ └── update-<feature>.dto.ts
|
|
35
|
+
├── entities/
|
|
36
|
+
│ └── <feature>.entity.ts ← Model
|
|
37
|
+
└── tests/
|
|
38
|
+
├── <feature>.service.spec.ts
|
|
39
|
+
└── <feature>.e2e-spec.ts
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Controllers (Handler)
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { Body, Controller, Post, UseGuards } from '@nestjs/common';
|
|
48
|
+
import { ApiTags, ApiOperation, ApiCreatedResponse } from '@nestjs/swagger';
|
|
49
|
+
import { JwtAuthGuard } from '@/auth/jwt-auth.guard';
|
|
50
|
+
import { CreateUserDto } from './dto/create-user.dto';
|
|
51
|
+
import { UserResponseDto } from './dto/user-response.dto';
|
|
52
|
+
import { RegisterUserService } from './register-user.service';
|
|
53
|
+
|
|
54
|
+
@ApiTags('users')
|
|
55
|
+
@Controller('users')
|
|
56
|
+
@UseGuards(JwtAuthGuard)
|
|
57
|
+
export class UsersController {
|
|
58
|
+
constructor(private readonly register: RegisterUserService) {}
|
|
59
|
+
|
|
60
|
+
@Post()
|
|
61
|
+
@ApiOperation({ summary: 'Criar novo usuário' })
|
|
62
|
+
@ApiCreatedResponse({ type: UserResponseDto })
|
|
63
|
+
async create(@Body() dto: CreateUserDto): Promise<UserResponseDto> {
|
|
64
|
+
const user = await this.register.execute(dto);
|
|
65
|
+
return UserResponseDto.from(user);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Regras:
|
|
71
|
+
- Apenas: recebe → valida via DTO → chama Service → retorna ResponseDto
|
|
72
|
+
- NUNCA: Prisma direto, lógica de negócio, validação inline
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## DTOs com class-validator
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { IsEmail, IsString, MinLength } from 'class-validator';
|
|
80
|
+
import { ApiProperty } from '@nestjs/swagger';
|
|
81
|
+
|
|
82
|
+
export class CreateUserDto {
|
|
83
|
+
@ApiProperty({ example: 'jane@example.com' })
|
|
84
|
+
@IsEmail() email!: string;
|
|
85
|
+
|
|
86
|
+
@ApiProperty({ example: 'Jane Doe' })
|
|
87
|
+
@IsString() name!: string;
|
|
88
|
+
|
|
89
|
+
@ApiProperty({ minLength: 12 })
|
|
90
|
+
@IsString() @MinLength(12) password!: string;
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`main.ts` global pipe:
|
|
95
|
+
```typescript
|
|
96
|
+
app.useGlobalPipes(new ValidationPipe({
|
|
97
|
+
whitelist: true,
|
|
98
|
+
forbidNonWhitelisted: true,
|
|
99
|
+
transform: true,
|
|
100
|
+
}));
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Services
|
|
106
|
+
|
|
107
|
+
Uma operação por classe:
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { Injectable } from '@nestjs/common';
|
|
111
|
+
import { hash } from '@node-rs/argon2';
|
|
112
|
+
import { UsersRepository } from './users.repository';
|
|
113
|
+
import { CreateUserDto } from './dto/create-user.dto';
|
|
114
|
+
import { UserAlreadyExistsError } from './errors';
|
|
115
|
+
|
|
116
|
+
@Injectable()
|
|
117
|
+
export class RegisterUserService {
|
|
118
|
+
constructor(private readonly repo: UsersRepository) {}
|
|
119
|
+
|
|
120
|
+
async execute(dto: CreateUserDto) {
|
|
121
|
+
if (await this.repo.existsByEmail(dto.email)) {
|
|
122
|
+
throw new UserAlreadyExistsError();
|
|
123
|
+
}
|
|
124
|
+
return this.repo.create({
|
|
125
|
+
...dto,
|
|
126
|
+
password: await hash(dto.password),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Repositories (Prisma)
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
@Injectable()
|
|
138
|
+
export class UsersRepository {
|
|
139
|
+
constructor(private readonly prisma: PrismaService) {}
|
|
140
|
+
|
|
141
|
+
async existsByEmail(email: string): Promise<boolean> {
|
|
142
|
+
return !!(await this.prisma.user.findUnique({ where: { email } }));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async create(data: { email: string; name: string; password: string }) {
|
|
146
|
+
return this.prisma.user.create({ data });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Tratamento global de exceções
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
@Catch()
|
|
157
|
+
export class AllExceptionsFilter implements ExceptionFilter {
|
|
158
|
+
catch(exception: unknown, host: ArgumentsHost) {
|
|
159
|
+
const response = host.switchToHttp().getResponse<Response>();
|
|
160
|
+
|
|
161
|
+
if (exception instanceof UserAlreadyExistsError) {
|
|
162
|
+
return response.status(409).json({ error: 'USER_EXISTS' });
|
|
163
|
+
}
|
|
164
|
+
if (exception instanceof HttpException) {
|
|
165
|
+
return response.status(exception.getStatus()).json(exception.getResponse());
|
|
166
|
+
}
|
|
167
|
+
return response.status(500).json({ error: 'INTERNAL' });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// main.ts
|
|
172
|
+
app.useGlobalFilters(new AllExceptionsFilter());
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## OpenAPI auto-gerado
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
const config = new DocumentBuilder()
|
|
181
|
+
.setTitle('Projeto API')
|
|
182
|
+
.setVersion('1.0')
|
|
183
|
+
.addBearerAuth()
|
|
184
|
+
.build();
|
|
185
|
+
|
|
186
|
+
const document = SwaggerModule.createDocument(app, config);
|
|
187
|
+
SwaggerModule.setup('docs', app, document); // UI em /docs
|
|
188
|
+
writeFileSync('./public/openapi.json', JSON.stringify(document));
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Rate limiting
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
import { ThrottlerModule, Throttle } from '@nestjs/throttler';
|
|
197
|
+
|
|
198
|
+
@Module({
|
|
199
|
+
imports: [
|
|
200
|
+
ThrottlerModule.forRoot([{ ttl: 60_000, limit: 100 }]),
|
|
201
|
+
],
|
|
202
|
+
})
|
|
203
|
+
export class AppModule {}
|
|
204
|
+
|
|
205
|
+
// Endpoint sensível
|
|
206
|
+
@Throttle({ default: { limit: 5, ttl: 900_000 } }) // 5/15min
|
|
207
|
+
@Post('login')
|
|
208
|
+
async login() {...}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Auth (JWT + Passport)
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
@Injectable()
|
|
217
|
+
export class JwtStrategy extends PassportStrategy(Strategy) {
|
|
218
|
+
constructor(config: ConfigService) {
|
|
219
|
+
super({
|
|
220
|
+
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
|
221
|
+
secretOrKey: config.getOrThrow('JWT_SECRET'),
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
async validate(payload: any) {
|
|
225
|
+
return { id: payload.sub, email: payload.email };
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
@Injectable()
|
|
230
|
+
export class JwtAuthGuard extends AuthGuard('jwt') {}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Testes
|
|
236
|
+
|
|
237
|
+
### Unit (service)
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
describe('RegisterUserService', () => {
|
|
241
|
+
it('falha se email já existe', async () => {
|
|
242
|
+
const repo = { existsByEmail: jest.fn().mockResolvedValue(true) } as any;
|
|
243
|
+
const sut = new RegisterUserService(repo);
|
|
244
|
+
await expect(sut.execute({ email: 'x@y.com', name: 'X', password: 'longsecret123' }))
|
|
245
|
+
.rejects.toThrow(UserAlreadyExistsError);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### E2E (Supertest)
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
describe('POST /users', () => {
|
|
254
|
+
it('cria com sucesso', async () => {
|
|
255
|
+
const res = await request(app.getHttpServer())
|
|
256
|
+
.post('/users')
|
|
257
|
+
.set('Authorization', `Bearer ${adminToken}`)
|
|
258
|
+
.send({ email: 'jane@example.com', name: 'Jane', password: 'longsecret123' });
|
|
259
|
+
expect(res.status).toBe(201);
|
|
260
|
+
expect(res.body.email).toBe('jane@example.com');
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Antipatterns
|
|
268
|
+
|
|
269
|
+
| AP | Antipattern | Correção |
|
|
270
|
+
|---|---|---|
|
|
271
|
+
| AP-01 | Validação inline | DTO + ValidationPipe |
|
|
272
|
+
| AP-02 | Prisma no Controller | Repository |
|
|
273
|
+
| AP-03 | Lógica no Controller | Service |
|
|
274
|
+
| AP-04 | Sem DTO de saída | `UserResponseDto.from(user)` |
|
|
275
|
+
| AP-05 | Secret hardcoded | `ConfigService.getOrThrow` |
|
|
276
|
+
| AP-06 | Login sem throttler | rate limit obrigatório |
|
|
277
|
+
| AP-07 | OpenAPI à mão | `@nestjs/swagger` |
|
|
278
|
+
| AP-08 | Erros sem filter global | inconsistência de response |
|
|
279
|
+
| AP-09 | `Prisma.user.findFirst` sem WHERE em tenant | A01 — Broken Access Control |
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Segurança (combinar com `skill-security`)
|
|
284
|
+
|
|
285
|
+
- Hash com `@node-rs/argon2` (Argon2id)
|
|
286
|
+
- JWT RS256 público, HS256+secret≥256bits interno
|
|
287
|
+
- `helmet` middleware para headers
|
|
288
|
+
- CORS específico
|
|
289
|
+
- Rate limit em login (5/15min)
|
|
290
|
+
- Refresh token com rotação no DB
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## CI
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
npm run lint
|
|
298
|
+
npm run test
|
|
299
|
+
npm run test:e2e
|
|
300
|
+
npm run build
|
|
301
|
+
npx prisma migrate deploy --dry-run
|
|
302
|
+
npm audit --audit-level=high
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Aplicação por fase DARE
|
|
308
|
+
|
|
309
|
+
### Design
|
|
310
|
+
- Listar endpoints REST com tags e métodos
|
|
311
|
+
- Definir DTOs de input e output
|
|
312
|
+
- Auth strategy escolhida
|
|
313
|
+
|
|
314
|
+
### Blueprint
|
|
315
|
+
- Estrutura de módulos
|
|
316
|
+
- Prisma schema preliminar
|
|
317
|
+
- Endpoints com `@ApiOperation` documentados
|
|
318
|
+
|
|
319
|
+
### Tasks
|
|
320
|
+
- Por módulo: 4 tasks (Module, Controller+DTO, Service, Repository)
|
|
321
|
+
- Task de configuração Swagger + throttler + global filter
|
|
322
|
+
|
|
323
|
+
### Execute
|
|
324
|
+
- Ralph Loop:
|
|
325
|
+
```bash
|
|
326
|
+
npm run lint && npm run test && npm run test:e2e && npm run build
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## Checklist final
|
|
332
|
+
|
|
333
|
+
- [ ] `strict: true` no tsconfig
|
|
334
|
+
- [ ] Todos os Controllers usam DTOs com class-validator
|
|
335
|
+
- [ ] `ValidationPipe` global em main.ts
|
|
336
|
+
- [ ] Services injetáveis (não `new`)
|
|
337
|
+
- [ ] Repositories encapsulam Prisma
|
|
338
|
+
- [ ] OpenAPI gerado em `public/openapi.json`
|
|
339
|
+
- [ ] ThrottlerModule global + endpoints sensíveis com `@Throttle`
|
|
340
|
+
- [ ] AllExceptionsFilter global
|
|
341
|
+
- [ ] Auth via `JwtAuthGuard` + secret via env
|
|
342
|
+
- [ ] Testes unit + E2E
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
Skill licenciada MIT — parte do DARE Method v3.
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Coleta de métricas de qualidade e detecção de regressões em projetos DARE. Agrega métricas das skills filhas (dare-ax, dare-layered-design, etc.), persiste histórico em tmp/dare_metrics.json e detecta regressões contra baseline.
|
|
3
|
+
globs: dare.config.yml,tmp/dare_metrics*.json,.github/workflows/dare-metrics.yml
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill: Quality Telemetry DARE
|
|
8
|
+
|
|
9
|
+
Você é um engenheiro de plataforma especialista em observabilidade de qualidade. Esta skill agrega as métricas de todas as skills DARE aplicadas no projeto (ax, layered-design, llm-integration, frontend-design, realtime) e detecta regressões.
|
|
10
|
+
|
|
11
|
+
## O que essa skill faz
|
|
12
|
+
|
|
13
|
+
1. **Coleta** — roda collectors de cada skill filha em paralelo
|
|
14
|
+
2. **Agrega** — junta tudo em um snapshot estruturado
|
|
15
|
+
3. **Persiste** — `tmp/dare_metrics.json` (append-only)
|
|
16
|
+
4. **Compara** — diff contra `tmp/dare_metrics_baseline.json`
|
|
17
|
+
5. **Reporta** — markdown report no CI ou stdout
|
|
18
|
+
6. **Bloqueia** — exit code ≠ 0 se regressão crítica detectada
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Arquitetura
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
┌────────────────────────────────────────────────────────────┐
|
|
26
|
+
│ collect.ts (orquestrador) │
|
|
27
|
+
└────────────────────────────────────────────────────────────┘
|
|
28
|
+
↓ paralelo
|
|
29
|
+
┌───────────────┬──────────────┬──────────────┬──────────────┐
|
|
30
|
+
│ ax collector │ layered │ llm │ realtime … │
|
|
31
|
+
└───────────────┴──────────────┴──────────────┴──────────────┘
|
|
32
|
+
↓
|
|
33
|
+
┌────────────────────────────────────────────────────────────┐
|
|
34
|
+
│ Aggregator → snapshot { skill: { M-01: value, status } } │
|
|
35
|
+
└────────────────────────────────────────────────────────────┘
|
|
36
|
+
↓
|
|
37
|
+
┌────────────────────────────────────────────────────────────┐
|
|
38
|
+
│ tmp/dare_metrics.json (append) + Regression detector │
|
|
39
|
+
└────────────────────────────────────────────────────────────┘
|
|
40
|
+
↓
|
|
41
|
+
┌────────────────────────────────────────────────────────────┐
|
|
42
|
+
│ Reporter → markdown / JSON / GH Actions step summary │
|
|
43
|
+
└────────────────────────────────────────────────────────────┘
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Métricas (da própria skill)
|
|
49
|
+
|
|
50
|
+
| ID | Métrica | Como medir |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| M-01 | 100% dos builds incluem coleta | skill instalada = sempre true |
|
|
53
|
+
| M-02 | 0 regressões passam despercebidas | `test -f tmp/dare_metrics_baseline.json` |
|
|
54
|
+
| M-03 | Histórico mantido | `test -f tmp/dare_metrics.json` e tem N entradas |
|
|
55
|
+
| M-04 | Workflow GH Actions existe | `test -f .github/workflows/dare-metrics.yml` |
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Configuração `dare.config.yml`
|
|
60
|
+
|
|
61
|
+
```yaml
|
|
62
|
+
telemetry:
|
|
63
|
+
skills:
|
|
64
|
+
- dare-ax
|
|
65
|
+
- dare-layered-design
|
|
66
|
+
- dare-llm-integration
|
|
67
|
+
- dare-frontend-design
|
|
68
|
+
- dare-realtime
|
|
69
|
+
output: tmp/dare_metrics.json
|
|
70
|
+
baseline: tmp/dare_metrics_baseline.json
|
|
71
|
+
fail_on_regression: true
|
|
72
|
+
regression_threshold_critical: 0.05 # ≥5% queda = CRITICAL
|
|
73
|
+
regression_threshold_warning: 0.01 # ≥1% queda = WARNING
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Schema do snapshot
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"timestamp": "2026-05-26T10:30:00Z",
|
|
83
|
+
"commit": "1d4a1417",
|
|
84
|
+
"branch": "main",
|
|
85
|
+
"skills": {
|
|
86
|
+
"dare-ax": {
|
|
87
|
+
"M-01": { "value": 1.0, "status": "PASS", "details": "llms.txt válido" },
|
|
88
|
+
"M-02": { "value": 1.0, "status": "PASS" },
|
|
89
|
+
"M-03": { "value": 1.0, "status": "PASS" },
|
|
90
|
+
"M-04": { "value": 1.0, "status": "PASS" }
|
|
91
|
+
},
|
|
92
|
+
"dare-layered-design": {
|
|
93
|
+
"M-01": { "value": 0.95, "status": "PASS", "details": "19/20 services com teste" },
|
|
94
|
+
"M-02": { "value": 1.0, "status": "PASS" },
|
|
95
|
+
"M-03": { "value": 1.0, "status": "PASS" },
|
|
96
|
+
"M-04": { "value": 1.0, "status": "PASS" }
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"summary": {
|
|
100
|
+
"totalMetrics": 24,
|
|
101
|
+
"passing": 23,
|
|
102
|
+
"failing": 1,
|
|
103
|
+
"warningRegressions": 0,
|
|
104
|
+
"criticalRegressions": 0
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Detecção de regressão
|
|
112
|
+
|
|
113
|
+
Para cada métrica, comparar valor atual com `baseline`:
|
|
114
|
+
|
|
115
|
+
| Mudança | Severidade | Ação |
|
|
116
|
+
|---|---|---|
|
|
117
|
+
| value caiu ≥ 5% | CRITICAL | exit 1 — bloqueia PR |
|
|
118
|
+
| value caiu ≥ 1% e < 5% | WARNING | comentar no PR — não bloqueia |
|
|
119
|
+
| value subiu | INFO | celebrar no report |
|
|
120
|
+
| value igual | NEUTRAL | nenhuma |
|
|
121
|
+
|
|
122
|
+
Configurar thresholds em `dare.config.yml`.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Workflow GitHub Actions
|
|
127
|
+
|
|
128
|
+
```yaml
|
|
129
|
+
# .github/workflows/dare-metrics.yml
|
|
130
|
+
name: DARE Metrics
|
|
131
|
+
|
|
132
|
+
on:
|
|
133
|
+
push:
|
|
134
|
+
branches: [main]
|
|
135
|
+
pull_request:
|
|
136
|
+
|
|
137
|
+
jobs:
|
|
138
|
+
metrics:
|
|
139
|
+
runs-on: ubuntu-latest
|
|
140
|
+
steps:
|
|
141
|
+
- uses: actions/checkout@v4
|
|
142
|
+
with: { fetch-depth: 0 }
|
|
143
|
+
- uses: actions/setup-node@v4
|
|
144
|
+
with: { node-version: '20' }
|
|
145
|
+
- run: pnpm install --frozen-lockfile
|
|
146
|
+
- name: Collect DARE metrics
|
|
147
|
+
run: pnpm dare metrics collect
|
|
148
|
+
- name: Compare against baseline
|
|
149
|
+
run: pnpm dare metrics compare
|
|
150
|
+
# exit 1 se regressão CRITICAL
|
|
151
|
+
- name: Upload metrics artifact
|
|
152
|
+
if: always()
|
|
153
|
+
uses: actions/upload-artifact@v4
|
|
154
|
+
with:
|
|
155
|
+
name: dare-metrics-${{ github.sha }}
|
|
156
|
+
path: tmp/dare_metrics*.json
|
|
157
|
+
- name: Comment on PR
|
|
158
|
+
if: github.event_name == 'pull_request'
|
|
159
|
+
run: pnpm dare metrics report --markdown >> $GITHUB_STEP_SUMMARY
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Antipatterns
|
|
165
|
+
|
|
166
|
+
| AP | Antipattern | Por que evitar |
|
|
167
|
+
|---|---|---|
|
|
168
|
+
| AP-01 | Coletar sem baseline | Não dá pra detectar regressão |
|
|
169
|
+
| AP-02 | Histórico não versionado | Perde contexto histórico |
|
|
170
|
+
| AP-03 | Coletar mas não bloquear | CI vira teatro |
|
|
171
|
+
| AP-04 | Baseline desatualizado | Regressão real fica invisível |
|
|
172
|
+
| AP-05 | Métricas opacas (sem `details`) | Difícil debugar quando falha |
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Custom collectors
|
|
177
|
+
|
|
178
|
+
Para métricas específicas do projeto (cobertura, build time, lighthouse score, etc.), criar collector custom:
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// src/telemetry/coverage_collector.ts
|
|
182
|
+
export const coverageCollector: DareCollector = {
|
|
183
|
+
name: 'project-coverage',
|
|
184
|
+
async collect() {
|
|
185
|
+
const cov = await readCoverageReport('coverage/coverage-summary.json');
|
|
186
|
+
return {
|
|
187
|
+
'CV-01': { value: cov.lines.pct / 100, status: cov.lines.pct > 80 ? 'PASS' : 'FAIL' },
|
|
188
|
+
'CV-02': { value: cov.branches.pct / 100, status: cov.branches.pct > 70 ? 'PASS' : 'FAIL' },
|
|
189
|
+
};
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Registrar em `dare.config.yml`:
|
|
195
|
+
```yaml
|
|
196
|
+
telemetry:
|
|
197
|
+
customCollectors:
|
|
198
|
+
- src/telemetry/coverage_collector.ts
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Aplicação por fase DARE
|
|
204
|
+
|
|
205
|
+
### Design
|
|
206
|
+
- Documentar quais métricas serão coletadas
|
|
207
|
+
- Definir baselines de qualidade (cobertura ≥ X%, etc.)
|
|
208
|
+
|
|
209
|
+
### Blueprint
|
|
210
|
+
- Decidir frequência de baseline update (por release? por sprint?)
|
|
211
|
+
- Thresholds CRITICAL e WARNING
|
|
212
|
+
|
|
213
|
+
### Tasks
|
|
214
|
+
- Task: instalar `@dare/quality-telemetry`
|
|
215
|
+
- Task: configurar `dare.config.yml`
|
|
216
|
+
- Task: rodar primeira coleta e capturar baseline
|
|
217
|
+
- Task: adicionar workflow CI
|
|
218
|
+
|
|
219
|
+
### Execute
|
|
220
|
+
- Em cada PR, CI roda coleta + compare
|
|
221
|
+
- Regressão CRITICAL = bloqueia merge
|
|
222
|
+
- Regressão WARNING = comenta no PR
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Boas práticas
|
|
227
|
+
|
|
228
|
+
1. **Baseline por release**, não por commit — evita "shift baseline" silencioso
|
|
229
|
+
2. **Regressão = bloqueio**, não comentário ignorável
|
|
230
|
+
3. **Exportar para Datadog/Grafana** após N coletas — visualizar tendência
|
|
231
|
+
4. **Collectors paralelos** — total deve rodar em < 60s
|
|
232
|
+
5. **Métricas com `details`** — quando falhar, fácil de debugar
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Checklist final
|
|
237
|
+
|
|
238
|
+
- [ ] `@dare/quality-telemetry` instalada
|
|
239
|
+
- [ ] `dare.config.yml` lista as skills a rastrear
|
|
240
|
+
- [ ] Primeira coleta gerou `tmp/dare_metrics.json`
|
|
241
|
+
- [ ] Baseline capturado em `tmp/dare_metrics_baseline.json`
|
|
242
|
+
- [ ] Workflow `.github/workflows/dare-metrics.yml` existe
|
|
243
|
+
- [ ] Thresholds CRITICAL/WARNING definidos
|
|
244
|
+
- [ ] `fail_on_regression: true` em produção
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
Skill licenciada MIT — parte do DARE Method v3.
|