@girardelli/architect-agents 8.1.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/dist/src/core/agent-generator/context-enricher.d.ts +17 -0
- package/dist/src/core/agent-generator/context-enricher.js +51 -0
- package/dist/src/core/agent-generator/context-enricher.js.map +1 -0
- package/dist/src/core/agent-generator/detectors/base-detector.d.ts +8 -0
- package/dist/src/core/agent-generator/detectors/base-detector.js +12 -0
- package/dist/src/core/agent-generator/detectors/base-detector.js.map +1 -0
- package/dist/src/core/agent-generator/detectors/dart-detector.d.ts +5 -0
- package/dist/src/core/agent-generator/detectors/dart-detector.js +16 -0
- package/dist/src/core/agent-generator/detectors/dart-detector.js.map +1 -0
- package/dist/src/core/agent-generator/detectors/framework-registry.d.ts +5 -0
- package/dist/src/core/agent-generator/detectors/framework-registry.js +81 -0
- package/dist/src/core/agent-generator/detectors/framework-registry.js.map +1 -0
- package/dist/src/core/agent-generator/detectors/go-detector.d.ts +5 -0
- package/dist/src/core/agent-generator/detectors/go-detector.js +25 -0
- package/dist/src/core/agent-generator/detectors/go-detector.js.map +1 -0
- package/dist/src/core/agent-generator/detectors/java-detector.d.ts +5 -0
- package/dist/src/core/agent-generator/detectors/java-detector.js +44 -0
- package/dist/src/core/agent-generator/detectors/java-detector.js.map +1 -0
- package/dist/src/core/agent-generator/detectors/node-detector.d.ts +5 -0
- package/dist/src/core/agent-generator/detectors/node-detector.js +28 -0
- package/dist/src/core/agent-generator/detectors/node-detector.js.map +1 -0
- package/dist/src/core/agent-generator/detectors/php-detector.d.ts +5 -0
- package/dist/src/core/agent-generator/detectors/php-detector.js +28 -0
- package/dist/src/core/agent-generator/detectors/php-detector.js.map +1 -0
- package/dist/src/core/agent-generator/detectors/python-detector.d.ts +7 -0
- package/dist/src/core/agent-generator/detectors/python-detector.js +116 -0
- package/dist/src/core/agent-generator/detectors/python-detector.js.map +1 -0
- package/dist/src/core/agent-generator/detectors/ruby-detector.d.ts +5 -0
- package/dist/src/core/agent-generator/detectors/ruby-detector.js +23 -0
- package/dist/src/core/agent-generator/detectors/ruby-detector.js.map +1 -0
- package/dist/src/core/agent-generator/detectors/rust-detector.d.ts +5 -0
- package/dist/src/core/agent-generator/detectors/rust-detector.js +18 -0
- package/dist/src/core/agent-generator/detectors/rust-detector.js.map +1 -0
- package/dist/src/core/agent-generator/detectors/structure-detector.d.ts +4 -0
- package/dist/src/core/agent-generator/detectors/structure-detector.js +35 -0
- package/dist/src/core/agent-generator/detectors/structure-detector.js.map +1 -0
- package/dist/src/core/agent-generator/detectors/toolchain-detector.d.ts +5 -0
- package/dist/src/core/agent-generator/detectors/toolchain-detector.js +164 -0
- package/dist/src/core/agent-generator/detectors/toolchain-detector.js.map +1 -0
- package/dist/src/core/agent-generator/domain-inferrer.d.ts +51 -0
- package/dist/src/core/agent-generator/domain-inferrer.js +585 -0
- package/dist/src/core/agent-generator/domain-inferrer.js.map +1 -0
- package/dist/src/core/agent-generator/engines/audit-engine.d.ts +8 -0
- package/dist/src/core/agent-generator/engines/audit-engine.js +84 -0
- package/dist/src/core/agent-generator/engines/audit-engine.js.map +1 -0
- package/dist/src/core/agent-generator/engines/context-builder.d.ts +12 -0
- package/dist/src/core/agent-generator/engines/context-builder.js +84 -0
- package/dist/src/core/agent-generator/engines/context-builder.js.map +1 -0
- package/dist/src/core/agent-generator/engines/generation-engine.d.ts +7 -0
- package/dist/src/core/agent-generator/engines/generation-engine.js +160 -0
- package/dist/src/core/agent-generator/engines/generation-engine.js.map +1 -0
- package/dist/src/core/agent-generator/engines/generation-engine_deps.d.ts +21 -0
- package/dist/src/core/agent-generator/engines/generation-engine_deps.js +17 -0
- package/dist/src/core/agent-generator/engines/generation-engine_deps.js.map +1 -0
- package/dist/src/core/agent-generator/engines/suggestion-engine.d.ts +13 -0
- package/dist/src/core/agent-generator/engines/suggestion-engine.js +171 -0
- package/dist/src/core/agent-generator/engines/suggestion-engine.js.map +1 -0
- package/dist/src/core/agent-generator/engines/suggestion-engine_deps.d.ts +8 -0
- package/dist/src/core/agent-generator/engines/suggestion-engine_deps.js +5 -0
- package/dist/src/core/agent-generator/engines/suggestion-engine_deps.js.map +1 -0
- package/dist/src/core/agent-generator/enrichers/analysis-helpers.d.ts +9 -0
- package/dist/src/core/agent-generator/enrichers/analysis-helpers.js +51 -0
- package/dist/src/core/agent-generator/enrichers/analysis-helpers.js.map +1 -0
- package/dist/src/core/agent-generator/enrichers/description-generator.d.ts +4 -0
- package/dist/src/core/agent-generator/enrichers/description-generator.js +82 -0
- package/dist/src/core/agent-generator/enrichers/description-generator.js.map +1 -0
- package/dist/src/core/agent-generator/enrichers/endpoint-extractor.d.ts +7 -0
- package/dist/src/core/agent-generator/enrichers/endpoint-extractor.js +90 -0
- package/dist/src/core/agent-generator/enrichers/endpoint-extractor.js.map +1 -0
- package/dist/src/core/agent-generator/enrichers/layer-classifier.d.ts +12 -0
- package/dist/src/core/agent-generator/enrichers/layer-classifier.js +152 -0
- package/dist/src/core/agent-generator/enrichers/layer-classifier.js.map +1 -0
- package/dist/src/core/agent-generator/enrichers/module-extractor.d.ts +10 -0
- package/dist/src/core/agent-generator/enrichers/module-extractor.js +173 -0
- package/dist/src/core/agent-generator/enrichers/module-extractor.js.map +1 -0
- package/dist/src/core/agent-generator/framework-detector.d.ts +17 -0
- package/dist/src/core/agent-generator/framework-detector.js +56 -0
- package/dist/src/core/agent-generator/framework-detector.js.map +1 -0
- package/dist/src/core/agent-generator/index.d.ts +25 -0
- package/dist/src/core/agent-generator/index.js +37 -0
- package/dist/src/core/agent-generator/index.js.map +1 -0
- package/dist/src/core/agent-generator/stack-detector.d.ts +13 -0
- package/dist/src/core/agent-generator/stack-detector.js +124 -0
- package/dist/src/core/agent-generator/stack-detector.js.map +1 -0
- package/dist/src/core/agent-generator/templates/core/agents.d.ts +9 -0
- package/dist/src/core/agent-generator/templates/core/agents.js +1127 -0
- package/dist/src/core/agent-generator/templates/core/agents.js.map +1 -0
- package/dist/src/core/agent-generator/templates/core/architecture-rules.d.ts +6 -0
- package/dist/src/core/agent-generator/templates/core/architecture-rules.js +275 -0
- package/dist/src/core/agent-generator/templates/core/architecture-rules.js.map +1 -0
- package/dist/src/core/agent-generator/templates/core/general-rules.d.ts +7 -0
- package/dist/src/core/agent-generator/templates/core/general-rules.js +301 -0
- package/dist/src/core/agent-generator/templates/core/general-rules.js.map +1 -0
- package/dist/src/core/agent-generator/templates/core/hooks-generator.d.ts +20 -0
- package/dist/src/core/agent-generator/templates/core/hooks-generator.js +235 -0
- package/dist/src/core/agent-generator/templates/core/hooks-generator.js.map +1 -0
- package/dist/src/core/agent-generator/templates/core/index-md.d.ts +6 -0
- package/dist/src/core/agent-generator/templates/core/index-md.js +247 -0
- package/dist/src/core/agent-generator/templates/core/index-md.js.map +1 -0
- package/dist/src/core/agent-generator/templates/core/orchestrator.d.ts +7 -0
- package/dist/src/core/agent-generator/templates/core/orchestrator.js +423 -0
- package/dist/src/core/agent-generator/templates/core/orchestrator.js.map +1 -0
- package/dist/src/core/agent-generator/templates/core/preflight.d.ts +7 -0
- package/dist/src/core/agent-generator/templates/core/preflight.js +213 -0
- package/dist/src/core/agent-generator/templates/core/preflight.js.map +1 -0
- package/dist/src/core/agent-generator/templates/core/quality-gates.d.ts +10 -0
- package/dist/src/core/agent-generator/templates/core/quality-gates.js +255 -0
- package/dist/src/core/agent-generator/templates/core/quality-gates.js.map +1 -0
- package/dist/src/core/agent-generator/templates/core/security-rules.d.ts +6 -0
- package/dist/src/core/agent-generator/templates/core/security-rules.js +529 -0
- package/dist/src/core/agent-generator/templates/core/security-rules.js.map +1 -0
- package/dist/src/core/agent-generator/templates/core/skills-generator.d.ts +18 -0
- package/dist/src/core/agent-generator/templates/core/skills-generator.js +547 -0
- package/dist/src/core/agent-generator/templates/core/skills-generator.js.map +1 -0
- package/dist/src/core/agent-generator/templates/core/workflow-fix-bug.d.ts +6 -0
- package/dist/src/core/agent-generator/templates/core/workflow-fix-bug.js +238 -0
- package/dist/src/core/agent-generator/templates/core/workflow-fix-bug.js.map +1 -0
- package/dist/src/core/agent-generator/templates/core/workflow-new-feature.d.ts +7 -0
- package/dist/src/core/agent-generator/templates/core/workflow-new-feature.js +321 -0
- package/dist/src/core/agent-generator/templates/core/workflow-new-feature.js.map +1 -0
- package/dist/src/core/agent-generator/templates/core/workflow-review.d.ts +6 -0
- package/dist/src/core/agent-generator/templates/core/workflow-review.js +105 -0
- package/dist/src/core/agent-generator/templates/core/workflow-review.js.map +1 -0
- package/dist/src/core/agent-generator/templates/domain/index.d.ts +21 -0
- package/dist/src/core/agent-generator/templates/domain/index.js +1179 -0
- package/dist/src/core/agent-generator/templates/domain/index.js.map +1 -0
- package/dist/src/core/agent-generator/templates/helpers/base-helpers.d.ts +10 -0
- package/dist/src/core/agent-generator/templates/helpers/base-helpers.js +20 -0
- package/dist/src/core/agent-generator/templates/helpers/base-helpers.js.map +1 -0
- package/dist/src/core/agent-generator/templates/helpers/cross-ref-helpers.d.ts +2 -0
- package/dist/src/core/agent-generator/templates/helpers/cross-ref-helpers.js +77 -0
- package/dist/src/core/agent-generator/templates/helpers/cross-ref-helpers.js.map +1 -0
- package/dist/src/core/agent-generator/templates/helpers/security-helpers.d.ts +2 -0
- package/dist/src/core/agent-generator/templates/helpers/security-helpers.js +182 -0
- package/dist/src/core/agent-generator/templates/helpers/security-helpers.js.map +1 -0
- package/dist/src/core/agent-generator/templates/helpers/stack-helpers.d.ts +4 -0
- package/dist/src/core/agent-generator/templates/helpers/stack-helpers.js +69 -0
- package/dist/src/core/agent-generator/templates/helpers/stack-helpers.js.map +1 -0
- package/dist/src/core/agent-generator/templates/helpers/structure-helpers.d.ts +2 -0
- package/dist/src/core/agent-generator/templates/helpers/structure-helpers.js +275 -0
- package/dist/src/core/agent-generator/templates/helpers/structure-helpers.js.map +1 -0
- package/dist/src/core/agent-generator/templates/helpers/summary-helpers.d.ts +6 -0
- package/dist/src/core/agent-generator/templates/helpers/summary-helpers.js +56 -0
- package/dist/src/core/agent-generator/templates/helpers/summary-helpers.js.map +1 -0
- package/dist/src/core/agent-generator/templates/stack/index.d.ts +7 -0
- package/dist/src/core/agent-generator/templates/stack/index.js +695 -0
- package/dist/src/core/agent-generator/templates/stack/index.js.map +1 -0
- package/dist/src/core/agent-generator/templates/template-helpers.d.ts +11 -0
- package/dist/src/core/agent-generator/templates/template-helpers.js +12 -0
- package/dist/src/core/agent-generator/templates/template-helpers.js.map +1 -0
- package/dist/src/core/agent-generator/types/agent.d.ts +39 -0
- package/dist/src/core/agent-generator/types/agent.js +27 -0
- package/dist/src/core/agent-generator/types/agent.js.map +1 -0
- package/dist/src/core/agent-generator/types/domain.d.ts +58 -0
- package/dist/src/core/agent-generator/types/domain.js +2 -0
- package/dist/src/core/agent-generator/types/domain.js.map +1 -0
- package/dist/src/core/agent-generator/types/stack.d.ts +36 -0
- package/dist/src/core/agent-generator/types/stack.js +2 -0
- package/dist/src/core/agent-generator/types/stack.js.map +1 -0
- package/dist/src/core/agent-generator/types/template.d.ts +29 -0
- package/dist/src/core/agent-generator/types/template.js +2 -0
- package/dist/src/core/agent-generator/types/template.js.map +1 -0
- package/dist/src/core/agent-runtime/ai-provider.d.ts +33 -0
- package/dist/src/core/agent-runtime/ai-provider.js +146 -0
- package/dist/src/core/agent-runtime/ai-provider.js.map +1 -0
- package/dist/src/core/agent-runtime/executor.d.ts +13 -0
- package/dist/src/core/agent-runtime/executor.js +138 -0
- package/dist/src/core/agent-runtime/executor.js.map +1 -0
- package/dist/src/core/agent-runtime/human-gate.d.ts +16 -0
- package/dist/src/core/agent-runtime/human-gate.js +70 -0
- package/dist/src/core/agent-runtime/human-gate.js.map +1 -0
- package/dist/tests/agent-generator.test.d.ts +1 -0
- package/dist/tests/agent-generator.test.js +349 -0
- package/dist/tests/agent-generator.test.js.map +1 -0
- package/dist/tests/agent-runtime.test.d.ts +1 -0
- package/dist/tests/agent-runtime.test.js +107 -0
- package/dist/tests/agent-runtime.test.js.map +1 -0
- package/dist/tests/context-enricher.test.d.ts +1 -0
- package/dist/tests/context-enricher.test.js +875 -0
- package/dist/tests/context-enricher.test.js.map +1 -0
- package/dist/tests/framework-detector.test.d.ts +1 -0
- package/dist/tests/framework-detector.test.js +882 -0
- package/dist/tests/framework-detector.test.js.map +1 -0
- package/dist/tests/stack-detector.test.d.ts +1 -0
- package/dist/tests/stack-detector.test.js +183 -0
- package/dist/tests/stack-detector.test.js.map +1 -0
- package/dist/tests/template-generation.test.d.ts +1 -0
- package/dist/tests/template-generation.test.js +571 -0
- package/dist/tests/template-generation.test.js.map +1 -0
- package/dist/tests/template-helpers.test.d.ts +1 -0
- package/dist/tests/template-helpers.test.js +967 -0
- package/dist/tests/template-helpers.test.js.map +1 -0
- package/package.json +24 -0
- package/src/core/agent-generator/context-enricher.ts +67 -0
- package/src/core/agent-generator/detectors/base-detector.ts +18 -0
- package/src/core/agent-generator/detectors/dart-detector.ts +17 -0
- package/src/core/agent-generator/detectors/framework-registry.ts +82 -0
- package/src/core/agent-generator/detectors/go-detector.ts +26 -0
- package/src/core/agent-generator/detectors/java-detector.ts +46 -0
- package/src/core/agent-generator/detectors/node-detector.ts +28 -0
- package/src/core/agent-generator/detectors/php-detector.ts +28 -0
- package/src/core/agent-generator/detectors/python-detector.ts +125 -0
- package/src/core/agent-generator/detectors/ruby-detector.ts +24 -0
- package/src/core/agent-generator/detectors/rust-detector.ts +19 -0
- package/src/core/agent-generator/detectors/structure-detector.ts +38 -0
- package/src/core/agent-generator/detectors/toolchain-detector.ts +181 -0
- package/src/core/agent-generator/domain-inferrer.ts +630 -0
- package/src/core/agent-generator/engines/audit-engine.ts +98 -0
- package/src/core/agent-generator/engines/context-builder.ts +96 -0
- package/src/core/agent-generator/engines/generation-engine.ts +184 -0
- package/src/core/agent-generator/engines/generation-engine_deps.ts +21 -0
- package/src/core/agent-generator/engines/suggestion-engine.ts +202 -0
- package/src/core/agent-generator/engines/suggestion-engine_deps.ts +8 -0
- package/src/core/agent-generator/enrichers/analysis-helpers.ts +58 -0
- package/src/core/agent-generator/enrichers/description-generator.ts +91 -0
- package/src/core/agent-generator/enrichers/endpoint-extractor.ts +114 -0
- package/src/core/agent-generator/enrichers/layer-classifier.ts +156 -0
- package/src/core/agent-generator/enrichers/module-extractor.ts +203 -0
- package/src/core/agent-generator/framework-detector.ts +66 -0
- package/src/core/agent-generator/index.ts +55 -0
- package/src/core/agent-generator/stack-detector.ts +115 -0
- package/src/core/agent-generator/templates/core/agents.ts +1168 -0
- package/src/core/agent-generator/templates/core/architecture-rules.ts +288 -0
- package/src/core/agent-generator/templates/core/general-rules.ts +306 -0
- package/src/core/agent-generator/templates/core/hooks-generator.ts +244 -0
- package/src/core/agent-generator/templates/core/index-md.ts +261 -0
- package/src/core/agent-generator/templates/core/orchestrator.ts +462 -0
- package/src/core/agent-generator/templates/core/preflight.ts +216 -0
- package/src/core/agent-generator/templates/core/quality-gates.ts +257 -0
- package/src/core/agent-generator/templates/core/security-rules.ts +544 -0
- package/src/core/agent-generator/templates/core/skills-generator.ts +586 -0
- package/src/core/agent-generator/templates/core/workflow-fix-bug.ts +240 -0
- package/src/core/agent-generator/templates/core/workflow-new-feature.ts +323 -0
- package/src/core/agent-generator/templates/core/workflow-review.ts +107 -0
- package/src/core/agent-generator/templates/domain/index.ts +1204 -0
- package/src/core/agent-generator/templates/helpers/base-helpers.ts +33 -0
- package/src/core/agent-generator/templates/helpers/cross-ref-helpers.ts +79 -0
- package/src/core/agent-generator/templates/helpers/security-helpers.ts +198 -0
- package/src/core/agent-generator/templates/helpers/stack-helpers.ts +80 -0
- package/src/core/agent-generator/templates/helpers/structure-helpers.ts +293 -0
- package/src/core/agent-generator/templates/helpers/summary-helpers.ts +67 -0
- package/src/core/agent-generator/templates/stack/index.ts +705 -0
- package/src/core/agent-generator/templates/template-helpers.ts +12 -0
- package/src/core/agent-generator/types/agent.ts +65 -0
- package/src/core/agent-generator/types/domain.ts +63 -0
- package/src/core/agent-generator/types/stack.ts +38 -0
- package/src/core/agent-generator/types/template.ts +31 -0
- package/src/core/agent-runtime/ai-provider.ts +178 -0
- package/src/core/agent-runtime/executor.ts +148 -0
- package/src/core/agent-runtime/human-gate.ts +69 -0
- package/tests/agent-generator.test.ts +428 -0
- package/tests/agent-runtime.test.ts +125 -0
- package/tests/context-enricher.test.ts +972 -0
- package/tests/framework-detector.test.ts +1172 -0
- package/tests/stack-detector.test.ts +241 -0
- package/tests/template-generation.test.ts +709 -0
- package/tests/template-helpers.test.ts +1130 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,1127 @@
|
|
|
1
|
+
// @ts-ignore - Audit cleanup unused variable
|
|
2
|
+
import { crossRef, depthIndicator, getEnriched, frameworkBadge, frameworkModuleStructure, frameworkSecurityChecklist, projectStructureBadge } from '../template-helpers.js';
|
|
3
|
+
/**
|
|
4
|
+
* Generates all specialist agent cards.
|
|
5
|
+
* Each is stack-aware and enterprise-grade detailed.
|
|
6
|
+
*
|
|
7
|
+
* All functions support both TemplateContext (backward compat) and EnrichedTemplateContext.
|
|
8
|
+
* Use getEnriched() to safely extract enriched fields when available.
|
|
9
|
+
*/
|
|
10
|
+
import { i18n } from '@girardelli/architect-core/src/core/i18n.js';
|
|
11
|
+
export function generateBackendAgent(ctx) {
|
|
12
|
+
const { stack, projectName, config, report } = ctx;
|
|
13
|
+
const enriched = getEnriched(ctx);
|
|
14
|
+
const lang = stack.primary;
|
|
15
|
+
// v8.1: Use detected primary framework instead of generic stack.frameworks
|
|
16
|
+
const primaryFw = enriched.primaryFramework;
|
|
17
|
+
const fw = primaryFw ? primaryFw.name : (stack.frameworks.filter(f => ['Django', 'Flask', 'FastAPI', 'NestJS', 'Spring', 'Express', 'Fastify', 'Rails', 'Laravel'].includes(f)).join(', ') || lang);
|
|
18
|
+
// Build module structure section if enriched data available
|
|
19
|
+
const modulesSection = enriched.modules && enriched.modules.length > 0
|
|
20
|
+
? `
|
|
21
|
+
## ${i18n.t('agents.backend.modules')}
|
|
22
|
+
|
|
23
|
+
${enriched.modules.map(m => `### ${m.name}
|
|
24
|
+
- **Path:** \`${m.path}\`
|
|
25
|
+
- **${i18n.t('cli.results.files')}:** ${m.fileCount}${m.lineCount > 0 ? ` · **${i18n.t('cli.results.lines')}:** ${m.lineCount.toLocaleString()}` : ''}
|
|
26
|
+
- **Descrição:** ${m.description}
|
|
27
|
+
- **Testes:** ${m.hasTests ? '✅ ' + i18n.t('common.yes') : '❌ ' + i18n.t('common.no')}
|
|
28
|
+
${m.entities.length > 0 ? `- **Entidades:** ${m.entities.join(', ')}` : ''}
|
|
29
|
+
`).join('\n')}
|
|
30
|
+
`
|
|
31
|
+
: '';
|
|
32
|
+
// Build endpoints section if enriched data available
|
|
33
|
+
const endpointsSection = enriched.endpoints && enriched.endpoints.length > 0
|
|
34
|
+
? `
|
|
35
|
+
## ${i18n.t('enriched.endpoints')}
|
|
36
|
+
|
|
37
|
+
${enriched.endpoints.map(e => `- \`${e.method}\` \`${e.path}\` — ${e.handler} (Auth: ${e.hasAuth ? i18n.t('common.yes') : i18n.t('common.no')}, Validação: ${e.hasValidation ? i18n.t('common.yes') : i18n.t('common.no')})`).join('\n')}
|
|
38
|
+
`
|
|
39
|
+
: '';
|
|
40
|
+
// Build domain section if enriched data available
|
|
41
|
+
const domainSection = enriched.domain
|
|
42
|
+
? `
|
|
43
|
+
## ${i18n.t('agents.backend.domainContext')}
|
|
44
|
+
|
|
45
|
+
- **Domínio:** ${enriched.domain.domain}
|
|
46
|
+
- **Sub-domínio:** ${enriched.domain.subDomain}
|
|
47
|
+
- **Descrição:** ${enriched.domain.description}
|
|
48
|
+
- **Confiança na Inferência:** ${Math.round(enriched.domain.confidence * 100)}%
|
|
49
|
+
${enriched.domain.businessEntities && enriched.domain.businessEntities.length > 0
|
|
50
|
+
? `
|
|
51
|
+
### Entidades de Negócio Detectadas
|
|
52
|
+
|
|
53
|
+
${enriched.domain.businessEntities.map(e => `- **${e.name}** (${e.layer}) — de \`${e.source}\`
|
|
54
|
+
- Campos: ${e.fields.join(', ')}
|
|
55
|
+
- Relacionamentos: ${e.relationships.length > 0 ? e.relationships.join(', ') : 'nenhum'}`).join('\n')}
|
|
56
|
+
`
|
|
57
|
+
: ''}
|
|
58
|
+
`
|
|
59
|
+
: '';
|
|
60
|
+
return `---
|
|
61
|
+
antigravity:
|
|
62
|
+
trigger: 'on_demand'
|
|
63
|
+
globs: ['**/*.${lang === 'Python' ? 'py' : lang === 'Dart' ? 'dart' : lang === 'Go' ? 'go' : 'ts'}']
|
|
64
|
+
description: '${i18n.t('agents.backend.description', { lang })}'
|
|
65
|
+
agent_card:
|
|
66
|
+
id: '${lang.toLowerCase()}-backend'
|
|
67
|
+
name: '${lang} Backend Developer'
|
|
68
|
+
role: 'development'
|
|
69
|
+
capabilities: [api-design, service-architecture, business-logic, data-modeling, testing]
|
|
70
|
+
inputs: [user-story, api-contracts, business-rules, integration-doc]
|
|
71
|
+
outputs: [controllers, services, entities, migrations, tests, integration-doc]
|
|
72
|
+
depends_on: [${stack.hasDatabase ? 'database-engineer' : ''}]
|
|
73
|
+
version: 3.1.0
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
# ${i18n.t('agents.backend.title', { lang: lang.toUpperCase() })}
|
|
77
|
+
|
|
78
|
+
${depthIndicator(ctx)}
|
|
79
|
+
|
|
80
|
+
> ${i18n.t('agents.backend.specialistIn', { fw, projectName })}
|
|
81
|
+
|
|
82
|
+
## ${i18n.t('agents.backend.stack')}
|
|
83
|
+
|
|
84
|
+
- **${i18n.t('agents.backend.language')}:** ${lang}
|
|
85
|
+
- **${i18n.t('agents.backend.framework')}:** ${fw}${primaryFw?.version ? ` v${primaryFw.version}` : ''}
|
|
86
|
+
- **${i18n.t('agents.backend.architecture')}:** ${projectStructureBadge(ctx)}
|
|
87
|
+
- **${i18n.t('agents.backend.test')}:** ${stack.testFramework}
|
|
88
|
+
- **${i18n.t('agents.backend.packageManager')}:** ${stack.packageManager}
|
|
89
|
+
- **${i18n.t('agents.backend.currentScore')}:** ${report.score.overall}/100
|
|
90
|
+
|
|
91
|
+
${frameworkBadge(ctx)}
|
|
92
|
+
${domainSection}
|
|
93
|
+
|
|
94
|
+
## ${i18n.t('agents.backend.principles')}
|
|
95
|
+
|
|
96
|
+
1. **S** — Single Responsibility
|
|
97
|
+
2. **O** — Open/Closed
|
|
98
|
+
3. **L** — Liskov Substitution
|
|
99
|
+
4. **I** — Interface Segregation
|
|
100
|
+
5. **D** — Dependency Inversion
|
|
101
|
+
${modulesSection}
|
|
102
|
+
|
|
103
|
+
## ${i18n.t('agents.backend.projectStructure')}
|
|
104
|
+
|
|
105
|
+
${frameworkModuleStructure(ctx)}
|
|
106
|
+
${endpointsSection}
|
|
107
|
+
|
|
108
|
+
## ${i18n.t('agents.backend.implementationRules')}
|
|
109
|
+
|
|
110
|
+
\`\`\`
|
|
111
|
+
${i18n.t('agents.backend.implementationRulesBody', { coverage: config.coverageMinimum })}
|
|
112
|
+
\`\`\`
|
|
113
|
+
|
|
114
|
+
## ${i18n.t('agents.backend.afterImplementation')}
|
|
115
|
+
|
|
116
|
+
${i18n.t('agents.backend.afterImplementationBody')}
|
|
117
|
+
|
|
118
|
+
${crossRef('backend', ctx)}
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
**${i18n.t('agents.generatedBy')}**
|
|
123
|
+
`;
|
|
124
|
+
}
|
|
125
|
+
export function generateFrontendAgent(ctx) {
|
|
126
|
+
const { stack, projectName, config, report } = ctx;
|
|
127
|
+
const enriched = getEnriched(ctx);
|
|
128
|
+
// v5.1: Use enriched primaryFramework or detect from all frameworks
|
|
129
|
+
const FRONTEND_FWS = ['Angular', 'Vue', 'Vue.js', 'Next.js', 'React', 'Nuxt', 'Svelte', 'Remix'];
|
|
130
|
+
const detectedFw = enriched.detectedFrameworks?.find(f => FRONTEND_FWS.includes(f.name));
|
|
131
|
+
const fw = detectedFw?.name ||
|
|
132
|
+
stack.frameworks.find(f => FRONTEND_FWS.includes(f)) || 'Frontend';
|
|
133
|
+
// Build endpoints integration guide if available
|
|
134
|
+
const endpointsGuide = enriched.endpoints && enriched.endpoints.length > 0
|
|
135
|
+
? `
|
|
136
|
+
## ${i18n.t('enriched.endpoints')}
|
|
137
|
+
|
|
138
|
+
${enriched.endpoints.filter(e => ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'].includes(e.method))
|
|
139
|
+
.slice(0, 15) // limit to 15 most important
|
|
140
|
+
.map(e => `- \`${e.method}\` \`${e.path}\` (${e.handler})`)
|
|
141
|
+
.join('\n')}
|
|
142
|
+
${enriched.endpoints.length > 15 ? `
|
|
143
|
+
... e mais ${enriched.endpoints.length - 15} endpoints. Ver documento de integração completo.` : ''}
|
|
144
|
+
`
|
|
145
|
+
: '';
|
|
146
|
+
// Build modules structure if available
|
|
147
|
+
const modulesGuide = enriched.modules && enriched.modules.length > 0
|
|
148
|
+
? `
|
|
149
|
+
## ${i18n.t('agents.backend.modules')}
|
|
150
|
+
|
|
151
|
+
${enriched.modules.map(m => `- \`${m.path}\` — ${m.description}`).join('\n')}
|
|
152
|
+
`
|
|
153
|
+
: '';
|
|
154
|
+
return `---
|
|
155
|
+
antigravity:
|
|
156
|
+
trigger: 'on_demand'
|
|
157
|
+
globs: ['**/*.{ts,tsx,vue,jsx,html,css,scss}']
|
|
158
|
+
description: '${i18n.t('agents.frontend.description', { fw })}'
|
|
159
|
+
agent_card:
|
|
160
|
+
id: '${fw.toLowerCase().replace('.', '')}-frontend'
|
|
161
|
+
name: '${fw} Frontend Developer'
|
|
162
|
+
role: 'development'
|
|
163
|
+
capabilities: [component-development, state-management, responsive-design, form-handling, api-integration]
|
|
164
|
+
inputs: [mockup, integration-doc, user-story, design-system]
|
|
165
|
+
outputs: [components, pages, services, tests]
|
|
166
|
+
depends_on: [orchestrator]
|
|
167
|
+
version: 3.1.0
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
# ${i18n.t('agents.frontend.title', { fw: fw.toUpperCase().replace('.', '') })}
|
|
171
|
+
|
|
172
|
+
${depthIndicator(ctx)}
|
|
173
|
+
|
|
174
|
+
> ${i18n.t('agents.frontend.specialistIn', { fw, projectName })}
|
|
175
|
+
|
|
176
|
+
## ${i18n.t('agents.backend.stack')}
|
|
177
|
+
|
|
178
|
+
- **${i18n.t('agents.backend.framework')}:** ${fw}
|
|
179
|
+
- **${i18n.t('agents.backend.language')}s:** ${stack.languages.join(', ')}
|
|
180
|
+
- **${i18n.t('agents.backend.test')}:** ${stack.testFramework}
|
|
181
|
+
- **${i18n.t('agents.backend.currentScore')}:** ${report.score.overall}/100
|
|
182
|
+
|
|
183
|
+
## ${i18n.t('agents.frontend.prerequisites')}
|
|
184
|
+
|
|
185
|
+
\`\`\`
|
|
186
|
+
${i18n.t('agents.frontend.prerequisitesBody')}
|
|
187
|
+
\`\`\`
|
|
188
|
+
${modulesGuide}${endpointsGuide}
|
|
189
|
+
|
|
190
|
+
## ${i18n.t('agents.frontend.implementationRules')}
|
|
191
|
+
|
|
192
|
+
\`\`\`
|
|
193
|
+
${i18n.t('agents.frontend.implementationRulesBody', { coverage: config.coverageMinimum })}
|
|
194
|
+
\`\`\`
|
|
195
|
+
|
|
196
|
+
${crossRef('frontend', ctx)}
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
**${i18n.t('agents.generatedBy')}**
|
|
201
|
+
`;
|
|
202
|
+
}
|
|
203
|
+
export function generateSecurityAgent(ctx) {
|
|
204
|
+
// @ts-ignore - Audit cleanup unused variable
|
|
205
|
+
const { projectName, config, stack } = ctx;
|
|
206
|
+
const enriched = getEnriched(ctx);
|
|
207
|
+
// Build compliance section if available
|
|
208
|
+
const complianceSection = enriched.domain && enriched.domain.compliance && enriched.domain.compliance.length > 0
|
|
209
|
+
? `
|
|
210
|
+
## ${i18n.t('dynamic.compliance.title')}
|
|
211
|
+
|
|
212
|
+
${enriched.domain.compliance.map(c => `### ${c.name}
|
|
213
|
+
**${i18n.t('dynamic.compliance.reason')}:** ${c.reason}
|
|
214
|
+
|
|
215
|
+
**${i18n.t('dynamic.compliance.mandatoryChecks')}:**
|
|
216
|
+
${c.mandatoryChecks.map(check => `- □ ${check}`).join('\n')}
|
|
217
|
+
`).join('\n')}
|
|
218
|
+
`
|
|
219
|
+
: '';
|
|
220
|
+
// Build integrations security section if available
|
|
221
|
+
const integrationsSection = enriched.domain && enriched.domain.integrations && enriched.domain.integrations.length > 0
|
|
222
|
+
? `
|
|
223
|
+
## ${i18n.t('dynamic.integrations.title')}
|
|
224
|
+
|
|
225
|
+
${enriched.domain.integrations.map(i => {
|
|
226
|
+
let threat = '';
|
|
227
|
+
if (i.type === 'payment')
|
|
228
|
+
threat = i18n.t('dynamic.integrations.types.payment');
|
|
229
|
+
else if (i.type === 'auth')
|
|
230
|
+
threat = i18n.t('dynamic.integrations.types.auth');
|
|
231
|
+
else if (i.type === 'api')
|
|
232
|
+
threat = i18n.t('dynamic.integrations.types.api');
|
|
233
|
+
else if (i.type === 'database')
|
|
234
|
+
threat = i18n.t('dynamic.integrations.types.database');
|
|
235
|
+
else if (i.type === 'government')
|
|
236
|
+
threat = i18n.t('dynamic.integrations.types.government');
|
|
237
|
+
else
|
|
238
|
+
threat = i18n.t('dynamic.integrations.types.default');
|
|
239
|
+
return `- **${i.name}** (${i.type}) — ${i18n.t('dynamic.integrations.threats')}: ${threat}`;
|
|
240
|
+
}).join('\n')}
|
|
241
|
+
`
|
|
242
|
+
: '';
|
|
243
|
+
// Domain-specific threats
|
|
244
|
+
const domainThreatsSection = enriched.domain
|
|
245
|
+
? `
|
|
246
|
+
## ${i18n.t('dynamic.domainThreats.title', { domain: enriched.domain.domain })}
|
|
247
|
+
|
|
248
|
+
${enriched.domain.domain === 'fintech' || enriched.domain.domain === 'payments'
|
|
249
|
+
? i18n.t('dynamic.domainThreats.fintech')
|
|
250
|
+
: enriched.domain.domain === 'healthtech'
|
|
251
|
+
? i18n.t('dynamic.domainThreats.healthtech')
|
|
252
|
+
: enriched.domain.domain === 'e-commerce'
|
|
253
|
+
? i18n.t('dynamic.domainThreats.ecommerce')
|
|
254
|
+
: i18n.t('dynamic.domainThreats.default')}
|
|
255
|
+
`
|
|
256
|
+
: '';
|
|
257
|
+
// v8.1: Framework-specific security checklist
|
|
258
|
+
const stackSecuritySection = frameworkSecurityChecklist(ctx);
|
|
259
|
+
return `---
|
|
260
|
+
antigravity:
|
|
261
|
+
trigger: 'on_demand'
|
|
262
|
+
description: '${i18n.t('agents.security.description')}'
|
|
263
|
+
agent_card:
|
|
264
|
+
id: 'security-auditor'
|
|
265
|
+
name: 'Security Auditor'
|
|
266
|
+
role: 'quality'
|
|
267
|
+
capabilities: [threat-modeling, owasp-analysis, compliance-check, vulnerability-detection]
|
|
268
|
+
inputs: [architecture-doc, source-code, api-contracts]
|
|
269
|
+
outputs: [threat-model, security-findings, compliance-report]
|
|
270
|
+
depends_on: []
|
|
271
|
+
version: 3.1.0
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
# ${i18n.t('agents.security.title')}
|
|
275
|
+
|
|
276
|
+
${depthIndicator(ctx)}
|
|
277
|
+
|
|
278
|
+
> ${i18n.t('agents.security.analysisFor', { projectName })}
|
|
279
|
+
|
|
280
|
+
## ${i18n.t('agents.security.checklist')}
|
|
281
|
+
|
|
282
|
+
\`\`\`
|
|
283
|
+
${i18n.t('agents.security.checklistBody')}
|
|
284
|
+
\`\`\`
|
|
285
|
+
${stackSecuritySection}
|
|
286
|
+
${complianceSection}${integrationsSection}${domainThreatsSection}
|
|
287
|
+
|
|
288
|
+
## ${i18n.t('agents.security.whenToActivate')}
|
|
289
|
+
|
|
290
|
+
${i18n.t('agents.security.whenToActivateBody')}
|
|
291
|
+
|
|
292
|
+
## ${i18n.t('agents.security.expectedOutput')}
|
|
293
|
+
|
|
294
|
+
${i18n.t('agents.security.expectedOutputBody')}
|
|
295
|
+
|
|
296
|
+
${crossRef('security-auditor', ctx)}
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
**${i18n.t('agents.generatedBy')}**
|
|
301
|
+
`;
|
|
302
|
+
}
|
|
303
|
+
export function generateQAAgent(ctx) {
|
|
304
|
+
const { projectName, config, stack, plan } = ctx;
|
|
305
|
+
const enriched = getEnriched(ctx);
|
|
306
|
+
// Build untested modules warning (reference canonical source)
|
|
307
|
+
const untestedCount = enriched.untestedModules?.length || 0;
|
|
308
|
+
const unterstedWarning = untestedCount > 0
|
|
309
|
+
? `
|
|
310
|
+
## ⚠️ ${i18n.t('enriched.untestedModules')}
|
|
311
|
+
|
|
312
|
+
${i18n.t('enriched.untestedModulesBody', { count: untestedCount })}
|
|
313
|
+
`
|
|
314
|
+
: '';
|
|
315
|
+
// Build test scenarios from endpoints
|
|
316
|
+
const testScenariosSection = enriched.endpoints && enriched.endpoints.length > 0
|
|
317
|
+
? `
|
|
318
|
+
## Cenários de Teste por Endpoint
|
|
319
|
+
|
|
320
|
+
${enriched.endpoints.slice(0, 10).map(e => `### \`${e.method}\` \`${e.path}\`
|
|
321
|
+
|
|
322
|
+
**Casos de teste:**
|
|
323
|
+
- ✅ Sucesso com dados válidos
|
|
324
|
+
- ⚠️ Validação: entrada inválida
|
|
325
|
+
${e.hasAuth ? `- 🔒 Autenticação: sem token, token inválido
|
|
326
|
+
- 🔒 Autorização: usuário sem permissão` : ''}
|
|
327
|
+
- ❌ Erro: recurso não encontrado (404)
|
|
328
|
+
- ❌ Erro: conflito (409)
|
|
329
|
+
`).join('\n')}
|
|
330
|
+
|
|
331
|
+
${enriched.endpoints.length > 10 ? `... e mais ${enriched.endpoints.length - 10} endpoints para testar.` : ''}
|
|
332
|
+
`
|
|
333
|
+
: '';
|
|
334
|
+
// Build domain-specific test scenarios
|
|
335
|
+
const domainTestsSection = enriched.domain
|
|
336
|
+
? `
|
|
337
|
+
## ${i18n.t('dynamic.qaDomain.title', { domain: enriched.domain.domain })}
|
|
338
|
+
|
|
339
|
+
${enriched.domain.domain === 'fintech' || enriched.domain.domain === 'payments'
|
|
340
|
+
? i18n.t('dynamic.qaDomain.fintech')
|
|
341
|
+
: enriched.domain.domain === 'healthtech'
|
|
342
|
+
? i18n.t('dynamic.qaDomain.healthtech')
|
|
343
|
+
: enriched.domain.domain === 'e-commerce'
|
|
344
|
+
? i18n.t('dynamic.qaDomain.ecommerce')
|
|
345
|
+
: i18n.t('dynamic.qaDomain.default')}
|
|
346
|
+
`
|
|
347
|
+
: '';
|
|
348
|
+
return `---
|
|
349
|
+
antigravity:
|
|
350
|
+
trigger: 'on_demand'
|
|
351
|
+
description: '${i18n.t('agents.qa.description')}'
|
|
352
|
+
agent_card:
|
|
353
|
+
id: 'qa-test-engineer'
|
|
354
|
+
name: 'QA Test Engineer'
|
|
355
|
+
role: 'quality'
|
|
356
|
+
capabilities: [test-planning, bdd-scenarios, tdd-implementation, coverage-analysis, regression-testing]
|
|
357
|
+
inputs: [user-story, bdd-scenarios, source-code]
|
|
358
|
+
outputs: [test-plan, test-cases, coverage-report]
|
|
359
|
+
depends_on: []
|
|
360
|
+
version: 3.1.0
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
# ${i18n.t('agents.qa.title')}
|
|
364
|
+
|
|
365
|
+
${depthIndicator(ctx)}
|
|
366
|
+
|
|
367
|
+
> ${i18n.t('agents.qa.qualityFor', { projectName })}
|
|
368
|
+
|
|
369
|
+
## ${i18n.t('agents.qa.nonNegotiable')}
|
|
370
|
+
|
|
371
|
+
\`\`\`
|
|
372
|
+
${i18n.t('agents.qa.nonNegotiableBody', { coverage: config.coverageMinimum })}
|
|
373
|
+
\`\`\`
|
|
374
|
+
${unterstedWarning}
|
|
375
|
+
|
|
376
|
+
## ${i18n.t('agents.qa.pyramid')}
|
|
377
|
+
|
|
378
|
+
\`\`\`
|
|
379
|
+
${i18n.t('agents.qa.pyramidBody')}
|
|
380
|
+
\`\`\`
|
|
381
|
+
|
|
382
|
+
## ${i18n.t('agents.qa.process')}
|
|
383
|
+
|
|
384
|
+
${i18n.t('agents.qa.processBody')}
|
|
385
|
+
|
|
386
|
+
## Framework: ${stack.testFramework}
|
|
387
|
+
${testScenariosSection}${domainTestsSection}
|
|
388
|
+
|
|
389
|
+
## ${i18n.t('agents.qa.refactoringRoadmap')}
|
|
390
|
+
|
|
391
|
+
${plan.steps.slice(0, 5).map((step, idx) => `${idx + 1}. ${step.description} (${step.priority || 'MEDIUM'})`).join('\n')}
|
|
392
|
+
${plan.steps.length > 5 ? `\n... e mais ${plan.steps.length - 5} steps.` : ''}
|
|
393
|
+
|
|
394
|
+
${crossRef('qa-test', ctx)}
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
**${i18n.t('agents.generatedBy')}**
|
|
399
|
+
`;
|
|
400
|
+
}
|
|
401
|
+
export function generateTechDebtAgent(ctx) {
|
|
402
|
+
const { projectName, report, plan, config } = ctx;
|
|
403
|
+
const enriched = getEnriched(ctx);
|
|
404
|
+
// Group anti-patterns by severity
|
|
405
|
+
const criticalPatterns = report.antiPatterns.filter(a => a.severity === 'CRITICAL');
|
|
406
|
+
const highPatterns = report.antiPatterns.filter(a => a.severity === 'HIGH');
|
|
407
|
+
const mediumPatterns = report.antiPatterns.filter(a => a.severity === 'MEDIUM');
|
|
408
|
+
const lowPatterns = report.antiPatterns.filter(a => a.severity === 'LOW');
|
|
409
|
+
const antiPatternsSection = `
|
|
410
|
+
## Anti-Patterns Detectados (Agrupados por Severidade)
|
|
411
|
+
|
|
412
|
+
${criticalPatterns.length > 0 ? `
|
|
413
|
+
### 🔴 CRÍTICOS (${criticalPatterns.length})
|
|
414
|
+
${criticalPatterns.map(a => `- **${a.name}** — \`${a.location}\`
|
|
415
|
+
Ação: Resolver no próximo sprint`).join('\n')}
|
|
416
|
+
` : ''}
|
|
417
|
+
|
|
418
|
+
${highPatterns.length > 0 ? `
|
|
419
|
+
### 🟠 ALTOS (${highPatterns.length})
|
|
420
|
+
${highPatterns.map(a => `- **${a.name}** — \`${a.location}\`
|
|
421
|
+
Ação: Planejar correção para próximas 2 semanas`).join('\n')}
|
|
422
|
+
` : ''}
|
|
423
|
+
|
|
424
|
+
${mediumPatterns.length > 0 ? `
|
|
425
|
+
### 🟡 MÉDIOS (${mediumPatterns.length})
|
|
426
|
+
${mediumPatterns.map(a => `- **${a.name}** — \`${a.location}\`
|
|
427
|
+
Ação: Adicionar ao backlog de técnico`).join('\n')}
|
|
428
|
+
` : ''}
|
|
429
|
+
|
|
430
|
+
${lowPatterns.length > 0 ? `
|
|
431
|
+
### 🟢 BAIXOS (${lowPatterns.length})
|
|
432
|
+
${lowPatterns.map(a => `- **${a.name}** — \`${a.location}\`
|
|
433
|
+
Ação: Considerar em refatorações futuras`).join('\n')}
|
|
434
|
+
` : ''}
|
|
435
|
+
|
|
436
|
+
${report.antiPatterns.length === 0 ? '✅ Nenhum anti-pattern detectado.' : ''}
|
|
437
|
+
`;
|
|
438
|
+
// Critical coupling hotspots
|
|
439
|
+
const couplingSection = enriched.criticalPaths && enriched.criticalPaths.length > 0
|
|
440
|
+
? `
|
|
441
|
+
## Hotspots de Acoplamento (Tech Debt)
|
|
442
|
+
|
|
443
|
+
Arquivos com alta complexidade de acoplamento — priorizar refatoração:
|
|
444
|
+
|
|
445
|
+
${enriched.criticalPaths.slice(0, 10).map(p => `- \`${p}\` — Alto acoplamento detectado`).join('\n')}
|
|
446
|
+
${enriched.criticalPaths.length > 10 ? `\n... e mais ${enriched.criticalPaths.length - 10} caminhos críticos.` : ''}
|
|
447
|
+
`
|
|
448
|
+
: '';
|
|
449
|
+
// Untested modules as debt (reference canonical source)
|
|
450
|
+
const untestedDebtCount = enriched.untestedModules?.length || 0;
|
|
451
|
+
const unterstedDebtSection = untestedDebtCount > 0
|
|
452
|
+
? `
|
|
453
|
+
## Débito em Cobertura de Teste
|
|
454
|
+
|
|
455
|
+
**${untestedDebtCount} módulos sem testes adequados detectados.**
|
|
456
|
+
|
|
457
|
+
> 📋 Lista canônica e gates de cobertura: ver [QUALITY-GATES.md](../guards/QUALITY-GATES.md#módulos-sem-testes)
|
|
458
|
+
|
|
459
|
+
**Plano de ação:**
|
|
460
|
+
1. Priorizar módulos com mais dependências
|
|
461
|
+
2. Seguir workflow TDD para cada módulo
|
|
462
|
+
3. Meta: reduzir lista a zero em ${Math.ceil(untestedDebtCount / 3)} sprints
|
|
463
|
+
`
|
|
464
|
+
: '';
|
|
465
|
+
return `---
|
|
466
|
+
antigravity:
|
|
467
|
+
trigger: 'on_demand'
|
|
468
|
+
description: '${i18n.t('agents.techDebt.description')}'
|
|
469
|
+
agent_card:
|
|
470
|
+
id: 'tech-debt-controller'
|
|
471
|
+
name: 'Tech Debt Controller'
|
|
472
|
+
role: 'governance'
|
|
473
|
+
capabilities: [debt-tracking, score-monitoring, refactoring-prioritization]
|
|
474
|
+
inputs: [architecture-report, anti-patterns, score-history]
|
|
475
|
+
outputs: [debt-backlog, refactoring-plan, score-targets]
|
|
476
|
+
depends_on: []
|
|
477
|
+
version: 3.1.0
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
# ${i18n.t('agents.techDebt.title')}
|
|
481
|
+
|
|
482
|
+
${depthIndicator(ctx)}
|
|
483
|
+
|
|
484
|
+
> ${i18n.t('agents.techDebt.controlFor', { projectName })}
|
|
485
|
+
|
|
486
|
+
## ${i18n.t('agents.techDebt.currentState')}
|
|
487
|
+
|
|
488
|
+
${i18n.t('agents.techDebt.stateTable', { score: report.score.overall, target: Math.min(100, report.score.overall + 10), antiPatterns: report.antiPatterns.length, refactoringSteps: plan.steps.length, improvement: plan.estimatedScoreAfter.overall - report.score.overall })}
|
|
489
|
+
${antiPatternsSection}${couplingSection}${unterstedDebtSection}
|
|
490
|
+
|
|
491
|
+
## ${i18n.t('agents.techDebt.refactoringRoadmap')}
|
|
492
|
+
|
|
493
|
+
Prioridade por impacto:
|
|
494
|
+
|
|
495
|
+
${plan.steps.slice(0, 8).map((step, idx) => `
|
|
496
|
+
${idx + 1}. **${step.title}** — ${step.description}
|
|
497
|
+
- Tier: ${step.tier === 1 ? 'Crítico' : 'Importante'}
|
|
498
|
+
- Prioridade: ${step.priority}
|
|
499
|
+
`).join('\n')}
|
|
500
|
+
|
|
501
|
+
${plan.steps.length > 8 ? `
|
|
502
|
+
... e mais ${plan.steps.length - 8} steps no plano completo.
|
|
503
|
+
` : ''}
|
|
504
|
+
|
|
505
|
+
## ${i18n.t('agents.techDebt.scoreTargets')}
|
|
506
|
+
|
|
507
|
+
\`\`\`
|
|
508
|
+
${i18n.t('agents.techDebt.scoreTargetsBody', { score: report.score.overall, targetShort: Math.min(100, report.score.overall + 5), targetMedium: Math.min(100, report.score.overall + 10), threshold: config.scoreThreshold })}
|
|
509
|
+
\`\`\`
|
|
510
|
+
|
|
511
|
+
## ${i18n.t('agents.techDebt.rules')}
|
|
512
|
+
|
|
513
|
+
\`\`\`
|
|
514
|
+
${i18n.t('agents.techDebt.rulesBody', { threshold: config.scoreThreshold })}
|
|
515
|
+
\`\`\`
|
|
516
|
+
|
|
517
|
+
${crossRef('tech-debt', ctx)}
|
|
518
|
+
|
|
519
|
+
---
|
|
520
|
+
|
|
521
|
+
**${i18n.t('agents.generatedBy')}**
|
|
522
|
+
`;
|
|
523
|
+
}
|
|
524
|
+
export function generateCodeReviewChecklist(ctx) {
|
|
525
|
+
const { projectName, config, stack } = ctx;
|
|
526
|
+
const enriched = getEnriched(ctx);
|
|
527
|
+
// Domain-specific review items
|
|
528
|
+
const domainReviewItems = enriched.domain
|
|
529
|
+
? `
|
|
530
|
+
## Itens de Revisão Específicos do Domínio: ${enriched.domain.domain}
|
|
531
|
+
|
|
532
|
+
${enriched.domain.domain === 'fintech' || enriched.domain.domain === 'payments'
|
|
533
|
+
? `□ Transações são idempotentes?
|
|
534
|
+
□ Auditoria completa de todas as operações?
|
|
535
|
+
□ Sem exposição de dados sensíveis em logs?
|
|
536
|
+
□ Valores monetários não usam float (usar Decimal)?
|
|
537
|
+
□ PCI-DSS compliance verificado?`
|
|
538
|
+
: enriched.domain.domain === 'healthtech'
|
|
539
|
+
? `□ LGPD compliance verificado (consentimento, retenção)?
|
|
540
|
+
□ Dados sensíveis criptografados em repouso?
|
|
541
|
+
□ Acesso auditado e logado?
|
|
542
|
+
□ Anonimização implementada corretamente?
|
|
543
|
+
□ 2FA em operações sensíveis?`
|
|
544
|
+
: enriched.domain.domain === 'e-commerce'
|
|
545
|
+
? `□ Carrinho é idempotente?
|
|
546
|
+
□ Inventário é atualizado corretamente (race conditions)?
|
|
547
|
+
□ Preços são validados (sem manipulação client-side)?
|
|
548
|
+
□ Cupons/descontos aplicados corretamente?
|
|
549
|
+
□ Fraude detection implementado?`
|
|
550
|
+
: `□ Fluxo crítico de negócio não quebrou?
|
|
551
|
+
□ Rollback é seguro?
|
|
552
|
+
□ Concorrência tratada?
|
|
553
|
+
□ State final é consistente?`}
|
|
554
|
+
`
|
|
555
|
+
: '';
|
|
556
|
+
// Stack-specific review items
|
|
557
|
+
const stackReviewItems = `
|
|
558
|
+
## Checklist Específico para ${stack.primary}
|
|
559
|
+
|
|
560
|
+
${stack.primary === 'TypeScript' || stack.primary === 'JavaScript'
|
|
561
|
+
? `□ \`strict: true\` em tsconfig (sem any sem justificativa)?
|
|
562
|
+
□ Imports circulares?
|
|
563
|
+
□ Async/await tratado (sem unhandled promises)?
|
|
564
|
+
□ Memory leaks (EventListeners desinscritos)?
|
|
565
|
+
□ Console.log/debugger removidos?`
|
|
566
|
+
: stack.primary === 'Python'
|
|
567
|
+
? `□ Type hints em todas as funções públicas?
|
|
568
|
+
□ Docstrings formatadas (Google ou NumPy style)?
|
|
569
|
+
□ Sem mutable default arguments?
|
|
570
|
+
□ Context managers usados para resources?
|
|
571
|
+
□ F-strings em vez de % ou .format()?
|
|
572
|
+
□ Sem \`eval()\` ou \`exec()\`?`
|
|
573
|
+
: stack.primary === 'Go'
|
|
574
|
+
? `□ Erros tratados (não ignorados com _)?
|
|
575
|
+
□ Defer para cleanup?
|
|
576
|
+
□ Goroutines com contexto?
|
|
577
|
+
□ Race conditions testadas?
|
|
578
|
+
□ Timeouts implementados?`
|
|
579
|
+
: stack.primary === 'Dart'
|
|
580
|
+
? `□ Null-safety (! evitado)?
|
|
581
|
+
□ Widgets têm keys quando em listas?
|
|
582
|
+
□ BuildContext acessado apenas em build?
|
|
583
|
+
□ Listeners desinscritos?
|
|
584
|
+
□ Imagens/assets fazem lazy-load?`
|
|
585
|
+
: `□ Código segue padrões do projeto?
|
|
586
|
+
□ Dependencies atualizadas?
|
|
587
|
+
□ Sem warnings do compilador/linter?`}
|
|
588
|
+
`;
|
|
589
|
+
// Integration/endpoint specific items
|
|
590
|
+
const integrationReviewItems = enriched.endpoints && enriched.endpoints.length > 0
|
|
591
|
+
? `
|
|
592
|
+
## Itens de Revisão de Integração
|
|
593
|
+
|
|
594
|
+
□ Endpoint trata todos os status codes esperados?
|
|
595
|
+
□ Validação do payload de entrada?
|
|
596
|
+
${enriched.endpoints.some(e => e.hasAuth) ? '□ Autenticação/autorização verificadas?' : ''}
|
|
597
|
+
${enriched.endpoints.some(e => e.hasValidation) ? '□ Validação de input implementada?' : ''}
|
|
598
|
+
□ Resposta segue o contrato documentado?
|
|
599
|
+
□ Erros retornam mensagens claras?
|
|
600
|
+
□ Rate limiting aplicado?
|
|
601
|
+
□ Logging estruturado?
|
|
602
|
+
`
|
|
603
|
+
: '';
|
|
604
|
+
return `---
|
|
605
|
+
antigravity:
|
|
606
|
+
trigger: 'on_demand'
|
|
607
|
+
description: 'Code Review Checklist — Pontos obrigatórios de revisão'
|
|
608
|
+
---
|
|
609
|
+
|
|
610
|
+
# 🔍 CODE REVIEW CHECKLIST — ${projectName}
|
|
611
|
+
|
|
612
|
+
${depthIndicator(ctx)}
|
|
613
|
+
|
|
614
|
+
> **Todo PR deve ser verificado contra este checklist.**
|
|
615
|
+
|
|
616
|
+
## Obrigatório
|
|
617
|
+
|
|
618
|
+
\`\`\`
|
|
619
|
+
□ Código compila sem erros
|
|
620
|
+
□ Todos os testes passam
|
|
621
|
+
□ Cobertura ≥ ${config.coverageMinimum}%
|
|
622
|
+
□ Lint sem errors
|
|
623
|
+
□ Nenhum secret hardcoded
|
|
624
|
+
□ Score não regrediu
|
|
625
|
+
\`\`\`
|
|
626
|
+
|
|
627
|
+
## Funcional
|
|
628
|
+
|
|
629
|
+
\`\`\`
|
|
630
|
+
□ Atende aos critérios de aceite
|
|
631
|
+
□ Edge cases tratados
|
|
632
|
+
□ Erros tratados adequadamente
|
|
633
|
+
□ Não quebra features existentes
|
|
634
|
+
\`\`\`
|
|
635
|
+
|
|
636
|
+
## Qualidade
|
|
637
|
+
|
|
638
|
+
\`\`\`
|
|
639
|
+
□ Código legível sem comentários explicativos
|
|
640
|
+
□ Naming descritivo e consistente
|
|
641
|
+
□ Sem duplicação (DRY)
|
|
642
|
+
□ Sem magic numbers
|
|
643
|
+
□ Sem any / type: ignore injustificado
|
|
644
|
+
□ Arquivos < 500 linhas
|
|
645
|
+
\`\`\`
|
|
646
|
+
|
|
647
|
+
## Segurança
|
|
648
|
+
|
|
649
|
+
\`\`\`
|
|
650
|
+
□ Inputs validados
|
|
651
|
+
□ Queries parametrizadas
|
|
652
|
+
□ Auth/authz verificados
|
|
653
|
+
□ Dados sensíveis protegidos
|
|
654
|
+
\`\`\`
|
|
655
|
+
${stackReviewItems}${domainReviewItems}${integrationReviewItems}
|
|
656
|
+
|
|
657
|
+
${crossRef('code-review', ctx)}
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
661
|
+
**Gerado por Architect v8.1**
|
|
662
|
+
`;
|
|
663
|
+
}
|
|
664
|
+
export function generateDatabaseAgent(ctx) {
|
|
665
|
+
// @ts-ignore - Audit cleanup unused variable
|
|
666
|
+
const { projectName, config, stack } = ctx;
|
|
667
|
+
const enriched = getEnriched(ctx);
|
|
668
|
+
// Detect ORM/database framework
|
|
669
|
+
const dbFramework = stack.frameworks.filter(f => ['TypeORM', 'Prisma', 'SQLAlchemy', 'Django ORM', 'Sequelize', 'Knex'].includes(f)).join(', ') || 'SQL';
|
|
670
|
+
// Build business entities section
|
|
671
|
+
const entitiesSection = enriched.domain && enriched.domain.businessEntities && enriched.domain.businessEntities.length > 0
|
|
672
|
+
? `
|
|
673
|
+
## Entidades de Negócio (Entity Relationship)
|
|
674
|
+
|
|
675
|
+
${enriched.domain.businessEntities.map(e => `
|
|
676
|
+
### ${e.name}
|
|
677
|
+
**Camada:** ${e.layer} | **Fonte:** \`${e.source}\`
|
|
678
|
+
|
|
679
|
+
**Campos:**
|
|
680
|
+
${e.fields.map(f => `- ${f}`).join('\n')}
|
|
681
|
+
|
|
682
|
+
**Relacionamentos:**
|
|
683
|
+
${e.relationships.length > 0 ? e.relationships.map(r => `- ${r}`).join('\n') : '- Nenhum'}
|
|
684
|
+
`).join('\n')}
|
|
685
|
+
`
|
|
686
|
+
: '';
|
|
687
|
+
// Migration strategy based on framework
|
|
688
|
+
const migrationStrategy = `
|
|
689
|
+
## Estratégia de Migrations
|
|
690
|
+
|
|
691
|
+
### Framework: ${dbFramework}
|
|
692
|
+
|
|
693
|
+
${dbFramework.includes('TypeORM')
|
|
694
|
+
? `\`\`\`bash
|
|
695
|
+
# Criar migration
|
|
696
|
+
npm run typeorm migration:generate -- -n DescricaoDaMigracao
|
|
697
|
+
|
|
698
|
+
# Executar
|
|
699
|
+
npm run typeorm migration:run
|
|
700
|
+
|
|
701
|
+
# Reverter
|
|
702
|
+
npm run typeorm migration:revert
|
|
703
|
+
\`\`\`
|
|
704
|
+
|
|
705
|
+
**Padrão:**
|
|
706
|
+
- Uma migration por feature
|
|
707
|
+
- Naming: \`YYYY-MM-DD-HH-mm-ss-description.ts\`
|
|
708
|
+
- Ambos up() e down() implementados
|
|
709
|
+
- Testar reverter em staging antes de produção`
|
|
710
|
+
: dbFramework.includes('Prisma')
|
|
711
|
+
? `\`\`\`bash
|
|
712
|
+
# Criar migration
|
|
713
|
+
npx prisma migrate dev --name DescricaoDaMigracao
|
|
714
|
+
|
|
715
|
+
# Produção
|
|
716
|
+
npx prisma migrate deploy
|
|
717
|
+
\`\`\`
|
|
718
|
+
|
|
719
|
+
**Padrão:**
|
|
720
|
+
- Schema.prisma é source of truth
|
|
721
|
+
- Migrations em \`prisma/migrations/\`
|
|
722
|
+
- Sempre testar \`prisma migrate resolve\` se houver problema
|
|
723
|
+
- Usar \`@relation\` para relacionamentos`
|
|
724
|
+
: dbFramework.includes('SQLAlchemy')
|
|
725
|
+
? `\`\`\`bash
|
|
726
|
+
# Criar migration
|
|
727
|
+
alembic revision --autogenerate -m "description"
|
|
728
|
+
|
|
729
|
+
# Executar
|
|
730
|
+
alembic upgrade head
|
|
731
|
+
|
|
732
|
+
# Reverter
|
|
733
|
+
alembic downgrade -1
|
|
734
|
+
\`\`\`
|
|
735
|
+
|
|
736
|
+
**Padrão:**
|
|
737
|
+
- Alembic em \`alembic/versions/\`
|
|
738
|
+
- Sempre revisar .py autogenerado
|
|
739
|
+
- Testar em staging antes de produção`
|
|
740
|
+
: `\`\`\`bash
|
|
741
|
+
# Criar arquivos .sql com:
|
|
742
|
+
-- migrations/001-create-table.up.sql
|
|
743
|
+
-- migrations/001-create-table.down.sql
|
|
744
|
+
\`\`\`
|
|
745
|
+
|
|
746
|
+
**Padrão:**
|
|
747
|
+
- Um arquivo up/down por migration
|
|
748
|
+
- Idempotent (IF NOT EXISTS, etc.)
|
|
749
|
+
- Testar reverter`}
|
|
750
|
+
`;
|
|
751
|
+
// Indexing strategy
|
|
752
|
+
const indexingStrategy = `
|
|
753
|
+
## Estratégia de Indexing
|
|
754
|
+
|
|
755
|
+
### Índices Obrigatórios:
|
|
756
|
+
|
|
757
|
+
\`\`\`
|
|
758
|
+
□ PRIMARY KEY em toda tabela
|
|
759
|
+
□ FOREIGN KEYS entre entidades relacionadas
|
|
760
|
+
□ Índice em campos usados em WHERE frequente
|
|
761
|
+
□ Índice em campos de JOIN
|
|
762
|
+
□ Índice em campos de ORDER BY
|
|
763
|
+
\`\`\`
|
|
764
|
+
|
|
765
|
+
### Exemplo:
|
|
766
|
+
|
|
767
|
+
\`\`\`sql
|
|
768
|
+
-- Por frequência de query
|
|
769
|
+
CREATE INDEX idx_user_email ON users(email);
|
|
770
|
+
CREATE INDEX idx_order_user_id ON orders(user_id);
|
|
771
|
+
CREATE INDEX idx_order_status_created ON orders(status, created_at);
|
|
772
|
+
|
|
773
|
+
-- Composto para filtros múltiplos
|
|
774
|
+
CREATE INDEX idx_order_user_status ON orders(user_id, status);
|
|
775
|
+
\`\`\`
|
|
776
|
+
|
|
777
|
+
### Cuidado:
|
|
778
|
+
|
|
779
|
+
\`\`\`
|
|
780
|
+
□ Não criar índice para CADA coluna (overhead)
|
|
781
|
+
□ Medir com EXPLAIN PLAN antes/depois
|
|
782
|
+
□ Índices consomem storage e memória
|
|
783
|
+
□ Atualizar índices em ALTER TABLE é lento
|
|
784
|
+
\`\`\`
|
|
785
|
+
`;
|
|
786
|
+
// Build domain patterns section with conditional content
|
|
787
|
+
let domainPatternsContent = '';
|
|
788
|
+
if (enriched.domain) {
|
|
789
|
+
if (enriched.domain.domain === 'fintech' || enriched.domain.domain === 'payments') {
|
|
790
|
+
domainPatternsContent = `### Requisitos:
|
|
791
|
+
- **Audit Trail:** TODA transação registrada com timestamp/user
|
|
792
|
+
- **Soft Deletes:** Nunca deletar, marcar como inativo
|
|
793
|
+
- **Idempotência:** Transação com mesmo ID é processada 1x
|
|
794
|
+
- **Timestamps:** created_at, updated_at, deleted_at em todas as tabelas
|
|
795
|
+
- **Denormalização:** Guardar valor em repouso na transação
|
|
796
|
+
|
|
797
|
+
### Exemplo Schema:
|
|
798
|
+
\`\`\`sql
|
|
799
|
+
CREATE TABLE transactions (
|
|
800
|
+
id UUID PRIMARY KEY,
|
|
801
|
+
user_id UUID NOT NULL REFERENCES users(id),
|
|
802
|
+
amount DECIMAL(19,2) NOT NULL,
|
|
803
|
+
status VARCHAR(20) NOT NULL, -- PENDING, COMPLETED, FAILED
|
|
804
|
+
idempotency_key VARCHAR(255) UNIQUE, -- para replay-safety
|
|
805
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
806
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
807
|
+
deleted_at TIMESTAMP NULL
|
|
808
|
+
);
|
|
809
|
+
|
|
810
|
+
CREATE TABLE transaction_audit (
|
|
811
|
+
id UUID PRIMARY KEY,
|
|
812
|
+
transaction_id UUID REFERENCES transactions(id),
|
|
813
|
+
action VARCHAR(50),
|
|
814
|
+
user_id UUID,
|
|
815
|
+
old_value JSONB,
|
|
816
|
+
new_value JSONB,
|
|
817
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
818
|
+
);
|
|
819
|
+
\`\`\``;
|
|
820
|
+
}
|
|
821
|
+
else if (enriched.domain.domain === 'healthtech') {
|
|
822
|
+
domainPatternsContent = `### Requisitos:
|
|
823
|
+
- **Criptografia:** Dados sensíveis criptografados em repouso
|
|
824
|
+
- **Anonimização:** Poder remover PII mantendo histórico
|
|
825
|
+
- **Retention:** Política de retenção de dados
|
|
826
|
+
- **Access Logs:** Quem acessou o que, quando
|
|
827
|
+
- **Consentimento:** Rastrear consentimento de paciente
|
|
828
|
+
|
|
829
|
+
### Exemplo Schema:
|
|
830
|
+
\`\`\`sql
|
|
831
|
+
CREATE TABLE patients (
|
|
832
|
+
id UUID PRIMARY KEY,
|
|
833
|
+
name_encrypted BYTEA NOT NULL, -- criptografado
|
|
834
|
+
ssn_encrypted BYTEA NOT NULL,
|
|
835
|
+
created_at TIMESTAMP,
|
|
836
|
+
deleted_at TIMESTAMP NULL
|
|
837
|
+
);
|
|
838
|
+
|
|
839
|
+
CREATE TABLE access_logs (
|
|
840
|
+
id UUID PRIMARY KEY,
|
|
841
|
+
patient_id UUID REFERENCES patients(id),
|
|
842
|
+
accessed_by UUID REFERENCES users(id),
|
|
843
|
+
accessed_at TIMESTAMP,
|
|
844
|
+
data_type VARCHAR(50),
|
|
845
|
+
purpose VARCHAR(100)
|
|
846
|
+
);
|
|
847
|
+
|
|
848
|
+
CREATE TABLE consents (
|
|
849
|
+
id UUID PRIMARY KEY,
|
|
850
|
+
patient_id UUID REFERENCES patients(id),
|
|
851
|
+
type VARCHAR(50),
|
|
852
|
+
granted_at TIMESTAMP,
|
|
853
|
+
expires_at TIMESTAMP
|
|
854
|
+
);
|
|
855
|
+
\`\`\``;
|
|
856
|
+
}
|
|
857
|
+
else if (enriched.domain.domain === 'e-commerce') {
|
|
858
|
+
domainPatternsContent = `### Requisitos:
|
|
859
|
+
- **Inventário:** Stock é crítico (race condition)
|
|
860
|
+
- **Preços:** Histórico de preço por produto
|
|
861
|
+
- **Pedidos:** Snapshot do preço no momento da venda
|
|
862
|
+
- **Cupons:** Validação e uso limitado
|
|
863
|
+
- **Pagamento:** Separado de pedido (pode estar pendente)
|
|
864
|
+
|
|
865
|
+
### Exemplo Schema:
|
|
866
|
+
\`\`\`sql
|
|
867
|
+
CREATE TABLE products (
|
|
868
|
+
id UUID PRIMARY KEY,
|
|
869
|
+
name VARCHAR(255),
|
|
870
|
+
price DECIMAL(19,2), -- preço atual
|
|
871
|
+
stock INT DEFAULT 0
|
|
872
|
+
);
|
|
873
|
+
|
|
874
|
+
CREATE TABLE product_prices (
|
|
875
|
+
id UUID PRIMARY KEY,
|
|
876
|
+
product_id UUID REFERENCES products(id),
|
|
877
|
+
price DECIMAL(19,2),
|
|
878
|
+
effective_from TIMESTAMP,
|
|
879
|
+
effective_to TIMESTAMP NULL
|
|
880
|
+
);
|
|
881
|
+
|
|
882
|
+
CREATE TABLE orders (
|
|
883
|
+
id UUID PRIMARY KEY,
|
|
884
|
+
user_id UUID REFERENCES users(id),
|
|
885
|
+
total DECIMAL(19,2),
|
|
886
|
+
status VARCHAR(20),
|
|
887
|
+
created_at TIMESTAMP
|
|
888
|
+
);
|
|
889
|
+
|
|
890
|
+
CREATE TABLE order_items (
|
|
891
|
+
id UUID PRIMARY KEY,
|
|
892
|
+
order_id UUID REFERENCES orders(id),
|
|
893
|
+
product_id UUID REFERENCES products(id),
|
|
894
|
+
quantity INT,
|
|
895
|
+
price_at_purchase DECIMAL(19,2) -- snapshot
|
|
896
|
+
);
|
|
897
|
+
\`\`\``;
|
|
898
|
+
}
|
|
899
|
+
else {
|
|
900
|
+
domainPatternsContent = `### Requisitos Genéricos:
|
|
901
|
+
- Timestamps: created_at, updated_at
|
|
902
|
+
- Soft deletes: deleted_at (se aplicável)
|
|
903
|
+
- Índices em ForeignKeys
|
|
904
|
+
- Constraints em integridade`;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
const domainPatternsSection = enriched.domain
|
|
908
|
+
? `
|
|
909
|
+
## Padrões de Dados Específicos do Domínio: ${enriched.domain.domain}
|
|
910
|
+
|
|
911
|
+
${domainPatternsContent}
|
|
912
|
+
`
|
|
913
|
+
: '';
|
|
914
|
+
// Compliance section
|
|
915
|
+
const complianceSection = enriched.domain && enriched.domain.compliance && enriched.domain.compliance.length > 0
|
|
916
|
+
? `
|
|
917
|
+
## Compliance & Dados
|
|
918
|
+
|
|
919
|
+
${enriched.domain.compliance.map(c => `### ${c.name}
|
|
920
|
+
${c.mandatoryChecks.map(check => `- □ ${check}`).join('\n')}
|
|
921
|
+
`).join('\n')}
|
|
922
|
+
`
|
|
923
|
+
: '';
|
|
924
|
+
return `---
|
|
925
|
+
antigravity:
|
|
926
|
+
trigger: 'on_demand'
|
|
927
|
+
description: 'Database Engineer — Schema, migrations, performance'
|
|
928
|
+
agent_card:
|
|
929
|
+
id: 'database-engineer'
|
|
930
|
+
name: 'Database Engineer'
|
|
931
|
+
role: 'development'
|
|
932
|
+
capabilities: [schema-design, migration-management, indexing, query-optimization]
|
|
933
|
+
inputs: [entity-model, business-rules, performance-requirements]
|
|
934
|
+
outputs: [migrations, indexes, seeds, query-optimization]
|
|
935
|
+
depends_on: []
|
|
936
|
+
version: 3.1.0
|
|
937
|
+
---
|
|
938
|
+
|
|
939
|
+
# 🗄️ DATABASE ENGINEER
|
|
940
|
+
|
|
941
|
+
${depthIndicator(ctx)}
|
|
942
|
+
|
|
943
|
+
> Schema design, migrations, e performance para ${projectName}
|
|
944
|
+
${entitiesSection}${migrationStrategy}${indexingStrategy}${domainPatternsSection}${complianceSection}
|
|
945
|
+
|
|
946
|
+
## Regras Gerais
|
|
947
|
+
|
|
948
|
+
\`\`\`
|
|
949
|
+
□ TODA migration deve ser reversível (up + down)
|
|
950
|
+
□ Índices para queries frequentes (validar com EXPLAIN)
|
|
951
|
+
□ Foreign keys onde há relacionamento
|
|
952
|
+
□ Constraints (NOT NULL, UNIQUE, CHECK) por negócio
|
|
953
|
+
□ Sem ALTER TABLE em tabelas grandes sem plano
|
|
954
|
+
□ Seed data atualizado para dev/test
|
|
955
|
+
□ Queries otimizadas (sem N+1, sem full scan)
|
|
956
|
+
□ Performance de migrations testada em staging
|
|
957
|
+
\`\`\`
|
|
958
|
+
|
|
959
|
+
${crossRef('database-engineer', ctx)}
|
|
960
|
+
|
|
961
|
+
---
|
|
962
|
+
|
|
963
|
+
**Gerado por Architect v8.1**
|
|
964
|
+
`;
|
|
965
|
+
}
|
|
966
|
+
export function generateMobileAgent(ctx) {
|
|
967
|
+
const { projectName, config, stack } = ctx;
|
|
968
|
+
const enriched = getEnriched(ctx);
|
|
969
|
+
// Build endpoints for mobile integration
|
|
970
|
+
const endpointsSection = enriched.endpoints && enriched.endpoints.length > 0
|
|
971
|
+
? `
|
|
972
|
+
## Endpoints para Integração Mobile
|
|
973
|
+
|
|
974
|
+
${enriched.endpoints.slice(0, 12).map(e => `- \`${e.method}\` \`${e.path}\` — ${e.handler}`).join('\n')}
|
|
975
|
+
${enriched.endpoints.length > 12 ? `\n... e mais ${enriched.endpoints.length - 12} endpoints. Ver documento de integração.` : ''}
|
|
976
|
+
`
|
|
977
|
+
: '';
|
|
978
|
+
// Build modules structure
|
|
979
|
+
const modulesSection = enriched.modules && enriched.modules.length > 0
|
|
980
|
+
? `
|
|
981
|
+
## Estrutura de Módulos
|
|
982
|
+
|
|
983
|
+
${enriched.modules.map(m => `- \`${m.path}\` — ${m.description}`).join('\n')}
|
|
984
|
+
`
|
|
985
|
+
: '';
|
|
986
|
+
// Build domain-specific mobile considerations
|
|
987
|
+
let domainMobileContent = '';
|
|
988
|
+
if (enriched.domain) {
|
|
989
|
+
if (enriched.domain.domain === 'fintech' || enriched.domain.domain === 'payments') {
|
|
990
|
+
domainMobileContent = `### Screens Críticas:
|
|
991
|
+
- **Carteira:** Saldo disponível, histórico de transações
|
|
992
|
+
- **Enviar Dinheiro:** Validação de conta destino, confirmação
|
|
993
|
+
- **Pagamentos:** 2FA, biometria, confirmação final
|
|
994
|
+
- **Segurança:** Definir PIN, mudar senha, 2FA setup
|
|
995
|
+
|
|
996
|
+
### Estados Especiais:
|
|
997
|
+
- Offline: Mostrar saldo em cache, desabilitar transações
|
|
998
|
+
- Sincronizando: Indicator de atualização
|
|
999
|
+
- Erro de rede: Retry com backoff exponencial
|
|
1000
|
+
- Transação pendente: Status em tempo real`;
|
|
1001
|
+
}
|
|
1002
|
+
else if (enriched.domain.domain === 'healthtech') {
|
|
1003
|
+
domainMobileContent = `### Screens Críticas:
|
|
1004
|
+
- **Prontuário:** Histórico médico, medicações
|
|
1005
|
+
- **Agendamento:** Calendário, confirmação SMS
|
|
1006
|
+
- **Consulta:** Receitas, encaminhamentos
|
|
1007
|
+
- **Privacidade:** Consentimento, biometria
|
|
1008
|
+
|
|
1009
|
+
### Estados Especiais:
|
|
1010
|
+
- Offline: Dados sincronizam quando online
|
|
1011
|
+
- Dados sensíveis: Sempre requer biometria
|
|
1012
|
+
- Consulta em andamento: Status em tempo real
|
|
1013
|
+
- Privacidade: Diálogos de consentimento antes de acessar`;
|
|
1014
|
+
}
|
|
1015
|
+
else if (enriched.domain.domain === 'e-commerce') {
|
|
1016
|
+
domainMobileContent = `### Screens Críticas:
|
|
1017
|
+
- **Catálogo:** Filtros, busca, avaliações
|
|
1018
|
+
- **Carrinho:** Quantidade, preço atualizado, cupom
|
|
1019
|
+
- **Checkout:** Endereço, cartão, 3D Secure
|
|
1020
|
+
- **Pedidos:** Status, rastreamento, devolução
|
|
1021
|
+
|
|
1022
|
+
### Estados Especiais:
|
|
1023
|
+
- Offline: Carrinho em cache, sincroniza depois
|
|
1024
|
+
- Estoque zerado: Mostrar de forma clara
|
|
1025
|
+
- Frete: Calcular por CEP em tempo real
|
|
1026
|
+
- Promoção: Aplicar cupom com feedback imediato`;
|
|
1027
|
+
}
|
|
1028
|
+
else {
|
|
1029
|
+
domainMobileContent = `### Screens Padrão:
|
|
1030
|
+
- Lista: Com busca, filtro, paginação
|
|
1031
|
+
- Detalhe: Completo com ações
|
|
1032
|
+
- Formulário: Validação em tempo real
|
|
1033
|
+
- Confirmação: Antes de ação crítica
|
|
1034
|
+
|
|
1035
|
+
### Estados Especiais:
|
|
1036
|
+
- Loading: Skeleton ou spinner
|
|
1037
|
+
- Empty: Mensagem clara
|
|
1038
|
+
- Error: Com retry
|
|
1039
|
+
- Offline: Modo read-only`;
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
const domainSection = enriched.domain
|
|
1043
|
+
? `
|
|
1044
|
+
## Considerações de UX por Domínio: ${enriched.domain.domain}
|
|
1045
|
+
|
|
1046
|
+
${domainMobileContent}
|
|
1047
|
+
`
|
|
1048
|
+
: '';
|
|
1049
|
+
return `---
|
|
1050
|
+
antigravity:
|
|
1051
|
+
trigger: 'on_demand'
|
|
1052
|
+
globs: ['**/*.dart']
|
|
1053
|
+
description: 'Flutter UI Developer — Screens, widgets, navegação'
|
|
1054
|
+
agent_card:
|
|
1055
|
+
id: 'flutter-ui-developer'
|
|
1056
|
+
name: 'Flutter UI Developer'
|
|
1057
|
+
role: 'development'
|
|
1058
|
+
capabilities: [screen-development, widget-composition, navigation, api-integration, state-management]
|
|
1059
|
+
inputs: [mockup, integration-doc, user-story]
|
|
1060
|
+
outputs: [screens, widgets, services, tests]
|
|
1061
|
+
depends_on: [orchestrator]
|
|
1062
|
+
version: 3.1.0
|
|
1063
|
+
---
|
|
1064
|
+
|
|
1065
|
+
# 📱 FLUTTER UI DEVELOPER
|
|
1066
|
+
|
|
1067
|
+
${depthIndicator(ctx)}
|
|
1068
|
+
|
|
1069
|
+
> Screens mobile, widgets, navegação para ${projectName}
|
|
1070
|
+
|
|
1071
|
+
## Stack
|
|
1072
|
+
|
|
1073
|
+
- **Framework:** Flutter / Dart
|
|
1074
|
+
- **Package Manager:** ${stack.packageManager}
|
|
1075
|
+
- **Teste:** ${stack.testFramework}
|
|
1076
|
+
|
|
1077
|
+
## Pré-Requisitos
|
|
1078
|
+
|
|
1079
|
+
\`\`\`
|
|
1080
|
+
□ MOCKUP do app aprovado (com todos os estados e fluxos)
|
|
1081
|
+
□ Documento de Integração disponível
|
|
1082
|
+
□ User stories com critérios de aceite
|
|
1083
|
+
□ Design system aprovado (cores, tipografia, componentes)
|
|
1084
|
+
\`\`\`
|
|
1085
|
+
${modulesSection}${endpointsSection}${domainSection}
|
|
1086
|
+
|
|
1087
|
+
## Regras
|
|
1088
|
+
|
|
1089
|
+
\`\`\`
|
|
1090
|
+
□ TODOS os estados: normal, loading, error, empty
|
|
1091
|
+
□ Padrão visual do app (cores, fontes, espaçamentos) consistente
|
|
1092
|
+
□ Navegação consistente (back button, deep link funcionando)
|
|
1093
|
+
□ Sem lógica de negócio em widgets (usar ChangeNotifier/Bloc)
|
|
1094
|
+
□ ListView.builder para listas longas (NUNCA Column com itens dinâmicos)
|
|
1095
|
+
□ Offline graceful quando aplicável (cache local)
|
|
1096
|
+
□ Imagens com lazy-load e placeholder
|
|
1097
|
+
□ Screens responsivas (testar orientação portrait + landscape)
|
|
1098
|
+
□ Acessibilidade (Semantics, labels)
|
|
1099
|
+
□ Cobertura ≥ ${config.coverageMinimum}%
|
|
1100
|
+
\`\`\`
|
|
1101
|
+
|
|
1102
|
+
## Estrutura de Projeto
|
|
1103
|
+
|
|
1104
|
+
\`\`\`
|
|
1105
|
+
lib/
|
|
1106
|
+
├── main.dart
|
|
1107
|
+
├── models/
|
|
1108
|
+
│ └── [domain].dart
|
|
1109
|
+
├── screens/
|
|
1110
|
+
│ └── [feature]/
|
|
1111
|
+
│ ├── [feature]_screen.dart
|
|
1112
|
+
│ └── widgets/
|
|
1113
|
+
│ └── [component].dart
|
|
1114
|
+
├── services/
|
|
1115
|
+
│ └── api_service.dart
|
|
1116
|
+
└── __tests__/
|
|
1117
|
+
└── [feature]_test.dart
|
|
1118
|
+
\`\`\`
|
|
1119
|
+
|
|
1120
|
+
${crossRef('flutter', ctx)}
|
|
1121
|
+
|
|
1122
|
+
---
|
|
1123
|
+
|
|
1124
|
+
**Gerado por Architect v8.1**
|
|
1125
|
+
`;
|
|
1126
|
+
}
|
|
1127
|
+
//# sourceMappingURL=agents.js.map
|