maestro-bundle 1.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.
Files changed (60) hide show
  1. package/README.md +91 -0
  2. package/package.json +25 -0
  3. package/src/cli.mjs +212 -0
  4. package/templates/bundle-ai-agents/.spec/constitution.md +33 -0
  5. package/templates/bundle-ai-agents/AGENTS.md +140 -0
  6. package/templates/bundle-ai-agents/skills/agent-orchestration/SKILL.md +132 -0
  7. package/templates/bundle-ai-agents/skills/api-design/SKILL.md +100 -0
  8. package/templates/bundle-ai-agents/skills/clean-architecture/SKILL.md +99 -0
  9. package/templates/bundle-ai-agents/skills/context-engineering/SKILL.md +98 -0
  10. package/templates/bundle-ai-agents/skills/database-modeling/SKILL.md +59 -0
  11. package/templates/bundle-ai-agents/skills/docker-containerization/SKILL.md +114 -0
  12. package/templates/bundle-ai-agents/skills/eval-testing/SKILL.md +115 -0
  13. package/templates/bundle-ai-agents/skills/memory-management/SKILL.md +106 -0
  14. package/templates/bundle-ai-agents/skills/prompt-engineering/SKILL.md +66 -0
  15. package/templates/bundle-ai-agents/skills/rag-pipeline/SKILL.md +128 -0
  16. package/templates/bundle-ai-agents/skills/testing-strategy/SKILL.md +95 -0
  17. package/templates/bundle-base/AGENTS.md +118 -0
  18. package/templates/bundle-base/skills/branch-strategy/SKILL.md +42 -0
  19. package/templates/bundle-base/skills/code-review/SKILL.md +54 -0
  20. package/templates/bundle-base/skills/commit-pattern/SKILL.md +58 -0
  21. package/templates/bundle-data-pipeline/.spec/constitution.md +32 -0
  22. package/templates/bundle-data-pipeline/AGENTS.md +115 -0
  23. package/templates/bundle-data-pipeline/skills/data-preprocessing/SKILL.md +75 -0
  24. package/templates/bundle-data-pipeline/skills/docker-containerization/SKILL.md +114 -0
  25. package/templates/bundle-data-pipeline/skills/feature-engineering/SKILL.md +76 -0
  26. package/templates/bundle-data-pipeline/skills/mlops-pipeline/SKILL.md +77 -0
  27. package/templates/bundle-data-pipeline/skills/model-training/SKILL.md +68 -0
  28. package/templates/bundle-data-pipeline/skills/rag-pipeline/SKILL.md +128 -0
  29. package/templates/bundle-frontend-spa/.spec/constitution.md +32 -0
  30. package/templates/bundle-frontend-spa/AGENTS.md +107 -0
  31. package/templates/bundle-frontend-spa/skills/authentication/SKILL.md +90 -0
  32. package/templates/bundle-frontend-spa/skills/component-design/SKILL.md +115 -0
  33. package/templates/bundle-frontend-spa/skills/e2e-testing/SKILL.md +101 -0
  34. package/templates/bundle-frontend-spa/skills/integration-api/SKILL.md +95 -0
  35. package/templates/bundle-frontend-spa/skills/react-patterns/SKILL.md +130 -0
  36. package/templates/bundle-frontend-spa/skills/responsive-layout/SKILL.md +65 -0
  37. package/templates/bundle-frontend-spa/skills/state-management/SKILL.md +86 -0
  38. package/templates/bundle-jhipster-microservices/.spec/constitution.md +37 -0
  39. package/templates/bundle-jhipster-microservices/AGENTS.md +307 -0
  40. package/templates/bundle-jhipster-microservices/skills/ci-cd-pipeline/SKILL.md +112 -0
  41. package/templates/bundle-jhipster-microservices/skills/clean-architecture/SKILL.md +99 -0
  42. package/templates/bundle-jhipster-microservices/skills/ddd-tactical/SKILL.md +138 -0
  43. package/templates/bundle-jhipster-microservices/skills/jhipster-angular/SKILL.md +97 -0
  44. package/templates/bundle-jhipster-microservices/skills/jhipster-docker-k8s/SKILL.md +183 -0
  45. package/templates/bundle-jhipster-microservices/skills/jhipster-entities/SKILL.md +87 -0
  46. package/templates/bundle-jhipster-microservices/skills/jhipster-gateway/SKILL.md +96 -0
  47. package/templates/bundle-jhipster-microservices/skills/jhipster-kafka/SKILL.md +145 -0
  48. package/templates/bundle-jhipster-microservices/skills/jhipster-registry/SKILL.md +83 -0
  49. package/templates/bundle-jhipster-microservices/skills/jhipster-service/SKILL.md +131 -0
  50. package/templates/bundle-jhipster-microservices/skills/testing-strategy/SKILL.md +95 -0
  51. package/templates/bundle-jhipster-monorepo/.spec/constitution.md +32 -0
  52. package/templates/bundle-jhipster-monorepo/AGENTS.md +227 -0
  53. package/templates/bundle-jhipster-monorepo/skills/clean-architecture/SKILL.md +99 -0
  54. package/templates/bundle-jhipster-monorepo/skills/ddd-tactical/SKILL.md +138 -0
  55. package/templates/bundle-jhipster-monorepo/skills/jhipster-angular/SKILL.md +166 -0
  56. package/templates/bundle-jhipster-monorepo/skills/jhipster-entities/SKILL.md +141 -0
  57. package/templates/bundle-jhipster-monorepo/skills/jhipster-liquibase/SKILL.md +95 -0
  58. package/templates/bundle-jhipster-monorepo/skills/jhipster-security/SKILL.md +89 -0
  59. package/templates/bundle-jhipster-monorepo/skills/jhipster-spring/SKILL.md +155 -0
  60. package/templates/bundle-jhipster-monorepo/skills/testing-strategy/SKILL.md +95 -0
@@ -0,0 +1,86 @@
1
+ ---
2
+ name: state-management
3
+ description: Gerenciar estado com Zustand para estado global e React Query para server state. Use quando precisar gerenciar estado da aplicação, cache de API, ou estado compartilhado entre componentes.
4
+ ---
5
+
6
+ # State Management
7
+
8
+ ## Regra de ouro
9
+
10
+ | Tipo de estado | Solução | Exemplo |
11
+ |---|---|---|
12
+ | Server state (API data) | React Query | Lista de demands, dados de agentes |
13
+ | UI state global | Zustand | Sidebar aberta, tema, user logado |
14
+ | UI state local | useState | Modal aberto, input controlado |
15
+ | Form state | React Hook Form | Dados do formulário, validação |
16
+ | Real-time state | Zustand + WebSocket | Status dos agentes, eventos ao vivo |
17
+
18
+ ## React Query — Server State
19
+
20
+ ```tsx
21
+ // services/demandApi.ts
22
+ export const demandApi = {
23
+ list: (filters?: DemandFilters) =>
24
+ api.get<PaginatedResponse<Demand>>('/api/v1/demands', { params: filters }),
25
+ get: (id: string) =>
26
+ api.get<Demand>(`/api/v1/demands/${id}`),
27
+ create: (data: CreateDemandDto) =>
28
+ api.post<Demand>('/api/v1/demands', data),
29
+ };
30
+
31
+ // hooks/useDemands.ts — nunca duplicar dados da API no Zustand
32
+ export function useDemands(filters?: DemandFilters) {
33
+ return useQuery({
34
+ queryKey: ['demands', filters],
35
+ queryFn: () => demandApi.list(filters),
36
+ });
37
+ }
38
+ ```
39
+
40
+ ## Zustand — UI State Global
41
+
42
+ ```tsx
43
+ interface AppStore {
44
+ sidebarOpen: boolean;
45
+ toggleSidebar: () => void;
46
+ selectedDemandId: string | null;
47
+ selectDemand: (id: string | null) => void;
48
+ }
49
+
50
+ export const useAppStore = create<AppStore>((set) => ({
51
+ sidebarOpen: true,
52
+ toggleSidebar: () => set((s) => ({ sidebarOpen: !s.sidebarOpen })),
53
+ selectedDemandId: null,
54
+ selectDemand: (id) => set({ selectedDemandId: id }),
55
+ }));
56
+ ```
57
+
58
+ ## WebSocket — Real-time
59
+
60
+ ```tsx
61
+ interface RealtimeStore {
62
+ agentStatuses: Record<string, AgentStatus>;
63
+ events: TrackingEvent[];
64
+ connect: () => void;
65
+ disconnect: () => void;
66
+ }
67
+
68
+ export const useRealtimeStore = create<RealtimeStore>((set) => {
69
+ let socket: Socket | null = null;
70
+
71
+ return {
72
+ agentStatuses: {},
73
+ events: [],
74
+ connect: () => {
75
+ socket = io(WS_URL);
76
+ socket.on('agent:status', (data) =>
77
+ set((s) => ({ agentStatuses: { ...s.agentStatuses, [data.agentId]: data.status } }))
78
+ );
79
+ socket.on('tracking:event', (event) =>
80
+ set((s) => ({ events: [event, ...s.events].slice(0, 100) }))
81
+ );
82
+ },
83
+ disconnect: () => socket?.disconnect(),
84
+ };
85
+ });
86
+ ```
@@ -0,0 +1,37 @@
1
+ # Constitution — Projeto JHipster Microservices
2
+
3
+ ## Princípios
4
+
5
+ 1. **Spec primeiro, código depois** — Toda demanda passa pelo fluxo SDD antes de implementação
6
+ 2. **Database per service** — Cada microsserviço tem seu próprio banco, nunca acessar banco de outro
7
+ 3. **Eventos sobre chamadas síncronas** — Preferir Kafka para comunicação, Feign apenas para queries
8
+ 4. **Resiliência obrigatória** — Circuit breaker em toda chamada inter-serviço
9
+ 5. **Deploy independente** — Cada serviço pode ser deployado sozinho
10
+ 6. **Saga over 2PC** — Transações distribuídas via Saga pattern, nunca Two-Phase Commit
11
+
12
+ ## Padrões de desenvolvimento
13
+
14
+ ### Java / Spring Boot
15
+ - Java 21+, Records para DTOs e Events
16
+ - Constructor injection
17
+ - Idempotência em consumers Kafka
18
+ - Fallback methods para circuit breakers
19
+ - Entidades pertencem a UM serviço
20
+
21
+ ### Comunicação
22
+ - Kafka para eventos de domínio (assíncrono)
23
+ - Feign Client para queries (síncrono)
24
+ - DTOs compartilhados por contrato, nunca por JAR
25
+
26
+ ### Infraestrutura
27
+ - Docker Compose para dev
28
+ - Kubernetes/K3s para prod
29
+ - Consul para service discovery
30
+ - Keycloak para OAuth2
31
+
32
+ ## Padrões de qualidade
33
+
34
+ - Spring Cloud Contract entre serviços
35
+ - Testcontainers para integração
36
+ - Gatling para load testing
37
+ - Deploy via CI/CD, nunca manual
@@ -0,0 +1,307 @@
1
+ # Projeto: JHipster Microservices
2
+
3
+ Você está construindo uma arquitetura de microsserviços com JHipster. Múltiplos serviços Spring Boot, gateway centralizado, service discovery, messaging assíncrono e frontend Angular.
4
+
5
+ ## Specification-Driven Development (SDD)
6
+
7
+ Este projeto usa **GitHub Spec Kit** para governança. Antes de implementar qualquer demanda:
8
+
9
+ 1. Rodar `/speckit.constitution` — se `.spec/constitution.md` não existir
10
+ 2. Rodar `/speckit.specify` — descrever O QUE e POR QUÊ (não como)
11
+ 3. Rodar `/speckit.plan` — arquitetura e decisões técnicas
12
+ 4. Rodar `/speckit.tasks` — quebrar em tasks atômicas
13
+ 5. Rodar `/speckit.implement` — executar as tasks
14
+
15
+ Nunca pular direto para código. Spec primeiro, código depois.
16
+
17
+ ## References
18
+
19
+ Documentos de referência que o agente deve consultar quando necessário:
20
+
21
+ - `references/jhipster-microservices-guide.md` — Guia de microsserviços JHipster
22
+ - `references/kafka-patterns.md` — Padrões de eventos Kafka
23
+ - `references/saga-patterns.md` — Saga pattern para transações distribuídas
24
+ - `references/k8s-deployment.md` — Deploy em Kubernetes
25
+
26
+ ## Stack do projeto
27
+
28
+ - **Backend:** Java 21 + Spring Boot 3.x (múltiplos serviços JHipster)
29
+ - **Gateway:** JHipster Gateway (Spring Cloud Gateway)
30
+ - **Service Discovery:** JHipster Registry (Eureka) ou Consul
31
+ - **Frontend:** Angular 17+ (no Gateway ou app separado)
32
+ - **Banco:** PostgreSQL (um banco por serviço)
33
+ - **Messaging:** Apache Kafka (padrão JHipster para microservices)
34
+ - **Cache:** Redis (compartilhado)
35
+ - **Auth:** OAuth2 + Keycloak (recomendado para microservices)
36
+ - **Containers:** Docker Compose (dev) + Kubernetes/K3s (prod)
37
+ - **Migrations:** Liquibase (por serviço)
38
+ - **CI/CD:** GitLab CI
39
+ - **Monitoring:** Prometheus + Grafana + ELK/Loki
40
+
41
+ ## Estrutura Multi-Repo ou Monorepo
42
+
43
+ ### Monorepo (recomendado para times pequenos)
44
+ ```
45
+ maestro/
46
+ ├── gateway/ # JHipster Gateway + Angular
47
+ │ ├── src/main/java/
48
+ │ ├── src/main/webapp/ # Angular app
49
+ │ └── pom.xml
50
+ ├── demand-service/ # Microserviço de demandas
51
+ │ ├── src/main/java/com/empresa/demand/
52
+ │ │ ├── domain/
53
+ │ │ ├── repository/
54
+ │ │ ├── service/
55
+ │ │ ├── web/rest/
56
+ │ │ └── config/
57
+ │ ├── src/main/resources/
58
+ │ │ └── config/liquibase/
59
+ │ └── pom.xml
60
+ ├── agent-service/ # Microserviço de agentes
61
+ │ └── ...
62
+ ├── tracking-service/ # Microserviço de rastreamento
63
+ │ └── ...
64
+ ├── bundle-service/ # Microserviço de bundles/skills
65
+ │ └── ...
66
+ ├── docker-compose/ # Docker Compose para dev
67
+ │ ├── docker-compose.yml
68
+ │ ├── keycloak.yml
69
+ │ ├── kafka.yml
70
+ │ ├── postgresql.yml
71
+ │ └── monitoring.yml
72
+ ├── k8s/ # Kubernetes manifests
73
+ │ ├── demand-service/
74
+ │ ├── agent-service/
75
+ │ ├── gateway/
76
+ │ └── registry/
77
+ └── jhipster-jdl.jdl # JDL completo
78
+ ```
79
+
80
+ ## JDL para Microservices
81
+
82
+ ```jdl
83
+ application {
84
+ config {
85
+ baseName gateway
86
+ applicationType gateway
87
+ packageName com.empresa.gateway
88
+ serviceDiscoveryType consul
89
+ authenticationType oauth2
90
+ prodDatabaseType postgresql
91
+ buildTool maven
92
+ clientFramework angular
93
+ }
94
+ }
95
+
96
+ application {
97
+ config {
98
+ baseName demandService
99
+ applicationType microservice
100
+ packageName com.empresa.demand
101
+ serviceDiscoveryType consul
102
+ authenticationType oauth2
103
+ prodDatabaseType postgresql
104
+ buildTool maven
105
+ serverPort 8081
106
+ }
107
+ entities Demand, Task
108
+ }
109
+
110
+ application {
111
+ config {
112
+ baseName agentService
113
+ applicationType microservice
114
+ packageName com.empresa.agent
115
+ serviceDiscoveryType consul
116
+ authenticationType oauth2
117
+ prodDatabaseType postgresql
118
+ buildTool maven
119
+ serverPort 8082
120
+ }
121
+ entities Agent, AgentTeam, Worktree
122
+ }
123
+
124
+ application {
125
+ config {
126
+ baseName trackingService
127
+ applicationType microservice
128
+ packageName com.empresa.tracking
129
+ serviceDiscoveryType consul
130
+ authenticationType oauth2
131
+ prodDatabaseType postgresql
132
+ buildTool maven
133
+ serverPort 8083
134
+ }
135
+ entities TrackingEvent, TrackingSession
136
+ }
137
+
138
+ /* Entities */
139
+ entity Demand {
140
+ description TextBlob required
141
+ status DemandStatus required
142
+ priority Priority required
143
+ }
144
+
145
+ entity Task {
146
+ description String required
147
+ status TaskStatus required
148
+ branchName String
149
+ }
150
+
151
+ entity Agent {
152
+ name String required
153
+ type AgentType required
154
+ status AgentStatus required
155
+ }
156
+
157
+ /* Enums */
158
+ enum DemandStatus { CREATED, PLANNED, IN_PROGRESS, COMPLETED }
159
+ enum TaskStatus { PENDING, IN_PROGRESS, COMPLETED, FAILED }
160
+ enum AgentType { FRONTEND, BACKEND, DEVOPS, ML, QA }
161
+ enum AgentStatus { IDLE, BUSY, OFFLINE }
162
+
163
+ /* Relationships */
164
+ relationship OneToMany {
165
+ Demand{tasks} to Task{demand required}
166
+ }
167
+
168
+ /* Options */
169
+ paginate * with pagination
170
+ dto * with mapstruct
171
+ service * with serviceImpl
172
+
173
+ /* Deployments */
174
+ deployment {
175
+ deploymentType docker-compose
176
+ dockerRepositoryName "registry.local/maestro"
177
+ appsFolders [gateway, demandService, agentService, trackingService]
178
+ monitoring yes
179
+ serviceDiscoveryType consul
180
+ }
181
+
182
+ deployment {
183
+ deploymentType kubernetes
184
+ kubernetesNamespace maestro
185
+ kubernetesServiceType Ingress
186
+ appsFolders [gateway, demandService, agentService, trackingService]
187
+ dockerRepositoryName "registry.local/maestro"
188
+ monitoring yes
189
+ serviceDiscoveryType consul
190
+ }
191
+ ```
192
+
193
+ ## Comunicação entre serviços
194
+
195
+ ### Síncrona — Feign Client (entre serviços)
196
+ ```java
197
+ @FeignClient(name = "agentService")
198
+ public interface AgentServiceClient {
199
+ @GetMapping("/api/agents/available")
200
+ List<AgentDTO> getAvailableAgents(@RequestParam("type") AgentType type);
201
+
202
+ @PostMapping("/api/agents/{id}/allocate")
203
+ AgentDTO allocateAgent(@PathVariable Long id, @RequestBody AllocateRequest request);
204
+ }
205
+ ```
206
+
207
+ ### Assíncrona — Kafka (eventos de domínio)
208
+ ```java
209
+ // Producer — demand-service
210
+ @Service
211
+ public class DemandEventProducer {
212
+ private final KafkaTemplate<String, DemandEvent> kafka;
213
+
214
+ public void publishDemandDecomposed(Demand demand) {
215
+ DemandDecomposed event = new DemandDecomposed(
216
+ demand.getId(), demand.getTasks().stream().map(Task::getId).toList()
217
+ );
218
+ kafka.send("demand-events", demand.getId().toString(), event);
219
+ }
220
+ }
221
+
222
+ // Consumer — agent-service
223
+ @Service
224
+ public class DemandEventConsumer {
225
+ @KafkaListener(topics = "demand-events", groupId = "agent-service")
226
+ public void onDemandDecomposed(DemandDecomposed event) {
227
+ // Alocar agentes para as tasks
228
+ taskAllocationService.allocateForDemand(event.demandId(), event.taskIds());
229
+ }
230
+ }
231
+ ```
232
+
233
+ ## Padrões obrigatórios
234
+
235
+ ### Database per Service
236
+ Cada microsserviço tem seu próprio banco PostgreSQL. Nunca acessar banco de outro serviço diretamente.
237
+
238
+ ### Saga Pattern para transações distribuídas
239
+ ```
240
+ demand-service: CreateDemand
241
+ → kafka: DemandCreated
242
+ → agent-service: AllocateAgents
243
+ → kafka: AgentsAllocated
244
+ → demand-service: UpdateDemandStatus(PLANNED)
245
+
246
+ Se AgentAllocation falhar:
247
+ → kafka: AllocationFailed
248
+ → demand-service: CompensateDemand(CANCELLED)
249
+ ```
250
+
251
+ ### Circuit Breaker
252
+ ```java
253
+ @CircuitBreaker(name = "agentService", fallbackMethod = "fallbackGetAgents")
254
+ public List<AgentDTO> getAvailableAgents(AgentType type) {
255
+ return agentServiceClient.getAvailableAgents(type);
256
+ }
257
+
258
+ public List<AgentDTO> fallbackGetAgents(AgentType type, Throwable t) {
259
+ log.warn("Agent service unavailable, returning cached agents", t);
260
+ return cachedAgentService.getCachedAgents(type);
261
+ }
262
+ ```
263
+
264
+ ## Docker Compose para dev
265
+
266
+ ```bash
267
+ # Subir tudo
268
+ docker-compose -f docker-compose/docker-compose.yml up -d
269
+
270
+ # Subir serviço específico
271
+ docker-compose -f docker-compose/docker-compose.yml up -d demand-service
272
+ ```
273
+
274
+ ## Kubernetes para prod
275
+
276
+ ```bash
277
+ # Deploy via JHipster
278
+ jhipster kubernetes
279
+
280
+ # Aplicar
281
+ kubectl apply -f k8s/
282
+ ```
283
+
284
+ ## Testes
285
+
286
+ - **Unit:** JUnit 5 — entidades e services (>= 90% domínio)
287
+ - **Integration:** Testcontainers + PostgreSQL real (>= 70%)
288
+ - **Contract:** Spring Cloud Contract — contratos entre serviços
289
+ - **E2E:** Cypress no gateway
290
+ - **Load:** Gatling (incluso no JHipster)
291
+
292
+ ## Git
293
+
294
+ - Commits: `feat(demand-service): adicionar saga de alocação`
295
+ - Branches: `feature/<service>-<descricao>`
296
+ - Um PR por serviço quando possível
297
+ - Nunca fazer breaking change em API sem versionar
298
+
299
+ ## O que NÃO fazer
300
+
301
+ - Não acessar banco de outro serviço diretamente
302
+ - Não fazer chamadas síncronas em cadeia (A→B→C→D) — usar eventos
303
+ - Não compartilhar entities entre serviços — cada um tem seus DTOs
304
+ - Não deployar todos os serviços juntos — deploy independente
305
+ - Não ignorar circuit breakers em chamadas inter-serviço
306
+ - Não usar transações distribuídas (2PC) — usar Saga
307
+ - Não criar um "serviço de tudo" — manter bounded contexts
@@ -0,0 +1,112 @@
1
+ ---
2
+ name: ci-cd-pipeline
3
+ description: Criar pipelines CI/CD com GitLab CI incluindo lint, test, build, compliance check e deploy. Use quando for configurar CI/CD, criar pipelines, ou automatizar deploy.
4
+ ---
5
+
6
+ # CI/CD Pipeline — GitLab CI
7
+
8
+ ## Pipeline completo
9
+
10
+ ```yaml
11
+ # .gitlab-ci.yml
12
+ stages:
13
+ - lint
14
+ - test
15
+ - security
16
+ - compliance
17
+ - build
18
+ - deploy-staging
19
+ - deploy-prod
20
+
21
+ variables:
22
+ DOCKER_IMAGE: $CI_REGISTRY_IMAGE
23
+ K3S_NAMESPACE: maestro
24
+
25
+ # ===== LINT =====
26
+ lint:python:
27
+ stage: lint
28
+ image: python:3.11-slim
29
+ script:
30
+ - pip install ruff mypy
31
+ - ruff check src/
32
+ - mypy src/ --ignore-missing-imports
33
+
34
+ lint:frontend:
35
+ stage: lint
36
+ image: node:20-slim
37
+ script:
38
+ - npm ci
39
+ - npm run lint
40
+ - npm run type-check
41
+
42
+ # ===== TEST =====
43
+ test:backend:
44
+ stage: test
45
+ image: python:3.11-slim
46
+ services:
47
+ - postgres:16
48
+ - redis:7
49
+ variables:
50
+ DATABASE_URL: postgresql://test:test@postgres/testdb
51
+ REDIS_URL: redis://redis:6379
52
+ script:
53
+ - pip install -r requirements.txt
54
+ - pytest --cov=src --cov-report=xml --cov-fail-under=80
55
+ artifacts:
56
+ reports:
57
+ coverage_report:
58
+ coverage_format: cobertura
59
+ path: coverage.xml
60
+
61
+ test:frontend:
62
+ stage: test
63
+ image: node:20-slim
64
+ script:
65
+ - npm ci
66
+ - npm run test -- --coverage
67
+
68
+ # ===== SECURITY =====
69
+ security:scan:
70
+ stage: security
71
+ image: python:3.11-slim
72
+ script:
73
+ - pip install bandit safety
74
+ - bandit -r src/ -ll
75
+ - safety check
76
+
77
+ # ===== COMPLIANCE =====
78
+ compliance:bundle:
79
+ stage: compliance
80
+ script:
81
+ - python scripts/check_bundle_compliance.py --bundle $BUNDLE_NAME
82
+ - python scripts/check_structure.py
83
+ allow_failure: false
84
+
85
+ # ===== BUILD =====
86
+ build:api:
87
+ stage: build
88
+ script:
89
+ - docker build -f docker/Dockerfile.api -t $DOCKER_IMAGE/api:$CI_COMMIT_SHA .
90
+ - docker push $DOCKER_IMAGE/api:$CI_COMMIT_SHA
91
+ only:
92
+ - main
93
+ - develop
94
+
95
+ # ===== DEPLOY =====
96
+ deploy:staging:
97
+ stage: deploy-staging
98
+ script:
99
+ - kubectl -n $K3S_NAMESPACE-staging set image deployment/api api=$DOCKER_IMAGE/api:$CI_COMMIT_SHA
100
+ - kubectl -n $K3S_NAMESPACE-staging rollout status deployment/api --timeout=120s
101
+ only:
102
+ - develop
103
+
104
+ deploy:prod:
105
+ stage: deploy-prod
106
+ script:
107
+ - kubectl -n $K3S_NAMESPACE set image deployment/api api=$DOCKER_IMAGE/api:$CI_COMMIT_SHA
108
+ - kubectl -n $K3S_NAMESPACE rollout status deployment/api --timeout=120s
109
+ only:
110
+ - main
111
+ when: manual
112
+ ```
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: clean-architecture
3
+ description: Implementar Clean Architecture com camadas de domínio, aplicação e infraestrutura. Use quando for criar módulos, organizar código em camadas, separar regras de negócio de infraestrutura, ou estruturar um projeto novo.
4
+ ---
5
+
6
+ # Clean Architecture
7
+
8
+ ## Camadas
9
+
10
+ ```
11
+ ┌──────────────────────────────┐
12
+ │ API / CLI │ ← Controllers, Routers
13
+ ├──────────────────────────────┤
14
+ │ APPLICATION │ ← Use Cases, DTOs
15
+ ├──────────────────────────────┤
16
+ │ DOMAIN │ ← Entities, VOs, Events, Repos (interface)
17
+ ├──────────────────────────────┤
18
+ │ INFRASTRUCTURE │ ← DB, HTTP clients, Frameworks
19
+ └──────────────────────────────┘
20
+
21
+ Dependency Rule: setas apontam para DENTRO (infra → domain)
22
+ Domain NUNCA importa de infrastructure
23
+ ```
24
+
25
+ ## Domain Layer
26
+
27
+ ```python
28
+ # domain/entities/demand.py
29
+ class Demand:
30
+ def __init__(self, id: DemandId, description: str):
31
+ self._id = id
32
+ self._description = description
33
+ self._status = DemandStatus.CREATED
34
+ self._events: list[DomainEvent] = []
35
+
36
+ def decompose(self, planner: TaskPlanner) -> list[Task]:
37
+ if self._status != DemandStatus.CREATED:
38
+ raise DemandAlreadyDecomposedException(self._id)
39
+ tasks = planner.plan(self._description)
40
+ self._status = DemandStatus.PLANNED
41
+ self._events.append(DemandDecomposed(self._id, [t.id for t in tasks]))
42
+ return tasks
43
+
44
+ @property
45
+ def pending_events(self) -> list[DomainEvent]:
46
+ return list(self._events)
47
+
48
+ # domain/repositories/demand_repository.py (PORT - apenas interface)
49
+ class DemandRepository(ABC):
50
+ @abstractmethod
51
+ def find_by_id(self, id: DemandId) -> Demand: ...
52
+ @abstractmethod
53
+ def save(self, demand: Demand) -> None: ...
54
+ ```
55
+
56
+ ## Application Layer
57
+
58
+ ```python
59
+ # application/use_cases/decompose_demand.py
60
+ class DecomposeDemand:
61
+ def __init__(self, repo: DemandRepository, planner: TaskPlanner, event_bus: EventBus):
62
+ self._repo = repo
63
+ self._planner = planner
64
+ self._event_bus = event_bus
65
+
66
+ def execute(self, demand_id: str) -> DecomposeDemandOutput:
67
+ demand = self._repo.find_by_id(DemandId(demand_id))
68
+ tasks = demand.decompose(self._planner)
69
+ self._repo.save(demand)
70
+ for event in demand.pending_events:
71
+ self._event_bus.publish(event)
72
+ return DecomposeDemandOutput(tasks=[TaskDTO.from_entity(t) for t in tasks])
73
+ ```
74
+
75
+ ## Infrastructure Layer
76
+
77
+ ```python
78
+ # infrastructure/persistence/pg_demand_repository.py (ADAPTER)
79
+ class PgDemandRepository(DemandRepository):
80
+ def __init__(self, session: Session):
81
+ self._session = session
82
+
83
+ def find_by_id(self, id: DemandId) -> Demand:
84
+ model = self._session.query(DemandModel).get(str(id))
85
+ if not model:
86
+ raise DemandNotFoundException(id)
87
+ return self._to_entity(model)
88
+
89
+ def save(self, demand: Demand) -> None:
90
+ model = self._to_model(demand)
91
+ self._session.merge(model)
92
+ self._session.commit()
93
+ ```
94
+
95
+ ## Regra de ouro
96
+
97
+ Use Case orquestra → Entity contém regra → Repository persiste
98
+
99
+ Nunca colocar regra de negócio no Controller, Repository ou "Service" genérico.