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