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,145 @@
1
+ ---
2
+ name: jhipster-kafka
3
+ description: Configurar Apache Kafka no JHipster para comunicação assíncrona entre microsserviços com eventos de domínio. Use quando precisar de messaging, eventos entre serviços, ou processamento assíncrono.
4
+ ---
5
+
6
+ # Kafka no JHipster Microservices
7
+
8
+ ## Setup
9
+
10
+ ```yaml
11
+ # docker-compose/kafka.yml
12
+ services:
13
+ zookeeper:
14
+ image: confluentinc/cp-zookeeper:7.5.0
15
+ environment:
16
+ ZOOKEEPER_CLIENT_PORT: 2181
17
+
18
+ kafka:
19
+ image: confluentinc/cp-kafka:7.5.0
20
+ depends_on:
21
+ - zookeeper
22
+ ports:
23
+ - "9092:9092"
24
+ environment:
25
+ KAFKA_BROKER_ID: 1
26
+ KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
27
+ KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
28
+ KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
29
+ KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
30
+ ```
31
+
32
+ ## Tópicos por domínio
33
+
34
+ | Tópico | Producer | Consumer | Evento |
35
+ |---|---|---|---|
36
+ | `demand-events` | demand-service | agent-service, tracking-service | DemandCreated, DemandDecomposed |
37
+ | `agent-events` | agent-service | demand-service, tracking-service | AgentAllocated, TaskCompleted |
38
+ | `bundle-events` | bundle-service | agent-service | BundleUpdated, SkillAdded |
39
+ | `tracking-events` | tracking-service | gateway (WebSocket) | MetricsUpdated |
40
+
41
+ ## Eventos de domínio
42
+
43
+ ```java
44
+ // Evento base
45
+ public sealed interface DomainEvent permits DemandCreated, DemandDecomposed, TaskCompleted {
46
+ String eventId();
47
+ Instant occurredAt();
48
+ String aggregateId();
49
+ }
50
+
51
+ // Eventos específicos
52
+ public record DemandCreated(
53
+ String eventId,
54
+ Instant occurredAt,
55
+ String aggregateId,
56
+ String description,
57
+ String priority
58
+ ) implements DomainEvent {}
59
+
60
+ public record TaskCompleted(
61
+ String eventId,
62
+ Instant occurredAt,
63
+ String aggregateId,
64
+ Long taskId,
65
+ Long agentId,
66
+ String branchName,
67
+ double durationSeconds
68
+ ) implements DomainEvent {}
69
+ ```
70
+
71
+ ## Producer
72
+
73
+ ```java
74
+ @Service
75
+ @RequiredArgsConstructor
76
+ public class DemandEventProducer {
77
+
78
+ private final KafkaTemplate<String, DomainEvent> kafkaTemplate;
79
+
80
+ public void publish(DomainEvent event) {
81
+ kafkaTemplate.send("demand-events", event.aggregateId(), event)
82
+ .whenComplete((result, ex) -> {
83
+ if (ex != null) {
84
+ log.error("Failed to publish event {}", event.eventId(), ex);
85
+ } else {
86
+ log.info("Published {} to partition {}", event.eventId(),
87
+ result.getRecordMetadata().partition());
88
+ }
89
+ });
90
+ }
91
+ }
92
+ ```
93
+
94
+ ## Consumer com idempotência
95
+
96
+ ```java
97
+ @Service
98
+ @RequiredArgsConstructor
99
+ public class DemandEventConsumer {
100
+
101
+ private final ProcessedEventRepository processedEventRepo;
102
+ private final AgentAllocationService allocationService;
103
+
104
+ @KafkaListener(topics = "demand-events", groupId = "agent-service")
105
+ public void onDemandEvent(DomainEvent event) {
106
+ // Idempotência: ignorar evento já processado
107
+ if (processedEventRepo.existsById(event.eventId())) {
108
+ log.info("Event {} already processed, skipping", event.eventId());
109
+ return;
110
+ }
111
+
112
+ switch (event) {
113
+ case DemandDecomposed e -> allocationService.allocateForDemand(e);
114
+ case DemandCreated e -> log.info("Demand created: {}", e.aggregateId());
115
+ default -> log.warn("Unknown event type: {}", event.getClass().getSimpleName());
116
+ }
117
+
118
+ processedEventRepo.save(new ProcessedEvent(event.eventId(), Instant.now()));
119
+ }
120
+ }
121
+ ```
122
+
123
+ ## Dead Letter Queue
124
+
125
+ ```yaml
126
+ spring:
127
+ cloud:
128
+ stream:
129
+ kafka:
130
+ bindings:
131
+ demandEvents-in-0:
132
+ consumer:
133
+ enableDlq: true
134
+ dlqName: demand-events-dlq
135
+ autoCommitOnError: false
136
+ ```
137
+
138
+ ## Regras
139
+
140
+ - Um tópico por bounded context (não por entidade)
141
+ - Consumers DEVEM ser idempotentes
142
+ - DLQ para eventos que falharam
143
+ - Events são imutáveis (records)
144
+ - Incluir `eventId` e `occurredAt` em todo evento
145
+ - Consumer group = nome do serviço
@@ -0,0 +1,83 @@
1
+ ---
2
+ name: jhipster-registry
3
+ description: Configurar service discovery com JHipster Registry (Consul ou Eureka) e configuração centralizada. Use quando precisar registrar serviços, configurar discovery, ou centralizar configurações.
4
+ ---
5
+
6
+ # JHipster Registry / Service Discovery
7
+
8
+ ## Consul (recomendado)
9
+
10
+ ### Docker Compose
11
+ ```yaml
12
+ consul:
13
+ image: consul:1.15
14
+ ports:
15
+ - "8500:8500"
16
+ command: agent -server -bootstrap -ui -client=0.0.0.0
17
+ ```
18
+
19
+ ### Configuração no serviço
20
+ ```yaml
21
+ # application.yml de cada microsserviço
22
+ spring:
23
+ cloud:
24
+ consul:
25
+ host: consul
26
+ port: 8500
27
+ discovery:
28
+ service-name: ${spring.application.name}
29
+ health-check-path: /management/health
30
+ health-check-interval: 15s
31
+ instance-id: ${spring.application.name}:${random.value}
32
+ config:
33
+ enabled: true
34
+ format: yaml
35
+ default-context: application
36
+ ```
37
+
38
+ ### Configuração centralizada no Consul
39
+
40
+ Colocar configs compartilhadas no Consul KV store:
41
+
42
+ ```yaml
43
+ # config/application/data no Consul KV
44
+ spring:
45
+ datasource:
46
+ type: com.zaxxer.hikari.HikariDataSource
47
+ hikari:
48
+ maximum-pool-size: 20
49
+
50
+ management:
51
+ endpoints:
52
+ web:
53
+ exposure:
54
+ include: health,info,prometheus
55
+ ```
56
+
57
+ ## Service-to-Service communication
58
+
59
+ Cada serviço se registra automaticamente. Para chamar outro serviço:
60
+
61
+ ```java
62
+ // Feign Client com discovery
63
+ @FeignClient(name = "agent-service")
64
+ public interface AgentServiceClient {
65
+ @GetMapping("/api/agents/{id}")
66
+ AgentDTO getAgent(@PathVariable Long id);
67
+ }
68
+
69
+ // O nome "agent-service" é resolvido via Consul/Eureka
70
+ ```
71
+
72
+ ## Health checks
73
+
74
+ - Consul verifica `/management/health` de cada serviço
75
+ - Se um serviço ficar unhealthy, Consul remove do registry
76
+ - Gateway para de rotear para instâncias unhealthy automaticamente
77
+
78
+ ## Regras
79
+
80
+ - Todo serviço DEVE se registrar no discovery
81
+ - Health check endpoint DEVE responder em < 1s
82
+ - Usar `instance-id` com random para permitir múltiplas instâncias
83
+ - Configs compartilhadas no Consul KV, específicas no application.yml local
@@ -0,0 +1,131 @@
1
+ ---
2
+ name: jhipster-service
3
+ description: Criar e configurar um microsserviço JHipster com Spring Boot, incluindo API, banco próprio e comunicação inter-serviço. Use quando precisar criar um novo microsserviço, configurar Feign clients, ou definir APIs internas.
4
+ ---
5
+
6
+ # JHipster Microservice
7
+
8
+ ## Criar novo serviço
9
+
10
+ ```bash
11
+ # Gerar via JDL (recomendado)
12
+ jhipster import-jdl jhipster-jdl.jdl
13
+
14
+ # Ou gerar manualmente
15
+ mkdir bundle-service && cd bundle-service
16
+ jhipster --blueprints="" --skip-client
17
+ ```
18
+
19
+ ## Configuração do serviço
20
+
21
+ ```yaml
22
+ # application.yml
23
+ spring:
24
+ application:
25
+ name: bundle-service
26
+ server:
27
+ port: 8084
28
+
29
+ # Banco próprio (database per service)
30
+ spring:
31
+ datasource:
32
+ url: jdbc:postgresql://localhost:5432/bundle_service
33
+ username: bundle
34
+ password: bundle
35
+
36
+ # Kafka
37
+ spring:
38
+ cloud:
39
+ stream:
40
+ kafka:
41
+ binder:
42
+ brokers: kafka:9092
43
+ bindings:
44
+ bundleEvents-out-0:
45
+ destination: bundle-events
46
+ demandEvents-in-0:
47
+ destination: demand-events
48
+ group: bundle-service
49
+ ```
50
+
51
+ ## Comunicação Síncrona — Feign
52
+
53
+ ```java
54
+ @FeignClient(name = "demand-service", fallback = DemandServiceFallback.class)
55
+ public interface DemandServiceClient {
56
+
57
+ @GetMapping("/api/demands/{id}")
58
+ DemandDTO getDemand(@PathVariable Long id);
59
+
60
+ @PutMapping("/api/demands/{id}/status")
61
+ void updateStatus(@PathVariable Long id, @RequestBody StatusUpdateDTO dto);
62
+ }
63
+
64
+ @Component
65
+ public class DemandServiceFallback implements DemandServiceClient {
66
+
67
+ @Override
68
+ public DemandDTO getDemand(Long id) {
69
+ log.warn("Demand service unavailable for demand {}", id);
70
+ return null;
71
+ }
72
+
73
+ @Override
74
+ public void updateStatus(Long id, StatusUpdateDTO dto) {
75
+ log.warn("Cannot update demand {} status, service unavailable", id);
76
+ throw new ServiceUnavailableException("demand-service");
77
+ }
78
+ }
79
+ ```
80
+
81
+ ## Comunicação Assíncrona — Kafka
82
+
83
+ ```java
84
+ // Producer
85
+ @Service
86
+ public class BundleEventProducer {
87
+ private final StreamBridge streamBridge;
88
+
89
+ public void publishBundleUpdated(Bundle bundle) {
90
+ BundleUpdatedEvent event = new BundleUpdatedEvent(
91
+ bundle.getId(), bundle.getName(), bundle.getVersion()
92
+ );
93
+ streamBridge.send("bundleEvents-out-0", event);
94
+ }
95
+ }
96
+
97
+ // Consumer
98
+ @Bean
99
+ public Consumer<DemandCreatedEvent> demandEvents() {
100
+ return event -> {
101
+ log.info("Demand created: {}", event.demandId());
102
+ bundleService.suggestBundleForDemand(event.demandId(), event.description());
103
+ };
104
+ }
105
+ ```
106
+
107
+ ## Padrão de API interna
108
+
109
+ APIs entre serviços usam DTOs compartilhados (nunca entities):
110
+
111
+ ```java
112
+ // Shared DTO — package separado ou duplicado (não compartilhar JARs)
113
+ public record AgentAllocationRequest(
114
+ Long taskId,
115
+ AgentType requiredType,
116
+ String branchName
117
+ ) {}
118
+
119
+ public record AgentAllocationResponse(
120
+ Long agentId,
121
+ String worktreePath,
122
+ String status
123
+ ) {}
124
+ ```
125
+
126
+ ## Regras
127
+
128
+ - Cada serviço tem seu próprio banco — NUNCA acessar banco de outro
129
+ - Falha de um serviço NÃO pode derrubar outros (circuit breaker)
130
+ - Eventos Kafka para notificação, Feign para query
131
+ - Idempotência em consumers Kafka (mesmo evento pode chegar 2x)
@@ -0,0 +1,95 @@
1
+ ---
2
+ name: testing-strategy
3
+ description: Implementar estratégia de testes com unitários, integração e e2e usando Pytest ou JUnit. Use quando for escrever testes, definir estratégia de testes, ou melhorar cobertura.
4
+ ---
5
+
6
+ # Estratégia de Testes
7
+
8
+ ## Pirâmide
9
+
10
+ ```
11
+ / E2E \ Poucos, lentos, caros
12
+ / Integr. \ Moderados
13
+ / Unitários \ Muitos, rápidos, baratos
14
+ ```
15
+
16
+ ## Testes Unitários — Domínio
17
+
18
+ Testar regras de negócio sem infraestrutura.
19
+
20
+ ```python
21
+ # tests/domain/test_demand.py
22
+ class TestDemand:
23
+ def test_should_decompose_new_demand(self):
24
+ demand = Demand(id=DemandId.generate(), description="Criar CRUD")
25
+ planner = FakePlanner(tasks=[Task(...), Task(...)])
26
+
27
+ tasks = demand.decompose(planner)
28
+
29
+ assert len(tasks) == 2
30
+ assert demand.status == DemandStatus.PLANNED
31
+
32
+ def test_should_reject_decompose_if_already_planned(self):
33
+ demand = Demand(id=DemandId.generate(), description="Criar CRUD")
34
+ demand.decompose(FakePlanner(tasks=[Task(...)]))
35
+
36
+ with pytest.raises(DemandAlreadyDecomposedException):
37
+ demand.decompose(FakePlanner(tasks=[]))
38
+
39
+ def test_should_not_allow_more_than_20_tasks(self):
40
+ demand = Demand(id=DemandId.generate(), description="Mega projeto")
41
+ for i in range(20):
42
+ demand.add_task(Task(...))
43
+
44
+ with pytest.raises(TooManyTasksException):
45
+ demand.add_task(Task(...))
46
+ ```
47
+
48
+ ## Testes Unitários — Value Objects
49
+
50
+ ```python
51
+ class TestComplianceScore:
52
+ def test_passing_score(self):
53
+ score = ComplianceScore(85.0)
54
+ assert score.is_passing() is True
55
+
56
+ def test_failing_score(self):
57
+ score = ComplianceScore(60.0)
58
+ assert score.is_passing() is False
59
+
60
+ def test_invalid_score_raises(self):
61
+ with pytest.raises(ValueError):
62
+ ComplianceScore(150.0)
63
+ ```
64
+
65
+ ## Testes de Integração — Repositórios
66
+
67
+ ```python
68
+ # tests/infrastructure/test_pg_demand_repository.py
69
+ @pytest.fixture
70
+ def db_session():
71
+ engine = create_engine(TEST_DATABASE_URL)
72
+ with Session(engine) as session:
73
+ yield session
74
+ session.rollback()
75
+
76
+ class TestPgDemandRepository:
77
+ def test_should_save_and_find_demand(self, db_session):
78
+ repo = PgDemandRepository(db_session)
79
+ demand = Demand(id=DemandId.generate(), description="Test")
80
+
81
+ repo.save(demand)
82
+ found = repo.find_by_id(demand.id)
83
+
84
+ assert found.description == "Test"
85
+ ```
86
+
87
+ ## Naming
88
+
89
+ ```
90
+ test_should_<resultado>_when_<condição>
91
+
92
+ test_should_return_error_when_email_is_invalid
93
+ test_should_decompose_demand_when_status_is_created
94
+ test_should_reject_merge_when_conflicts_exist
95
+ ```
@@ -0,0 +1,32 @@
1
+ # Constitution — Projeto JHipster Monorepo
2
+
3
+ ## Princípios
4
+
5
+ 1. **Spec primeiro, código depois** — Toda demanda passa pelo fluxo SDD antes de implementação
6
+ 2. **JDL como fonte de verdade** — Modelo de entidades definido em JDL, código gerado pelo JHipster
7
+ 3. **Enriquecer, não substituir** — Entidades geradas pelo JHipster são enriquecidas com DDD, não reescritas do zero
8
+ 4. **Migrations versionadas** — Toda mudança de schema via Liquibase changeset, nunca manual
9
+ 5. **DTO na fronteira** — Nunca expor entidade JPA na API REST
10
+
11
+ ## Padrões de desenvolvimento
12
+
13
+ ### Java / Spring Boot
14
+ - Java 21+, Records para DTOs
15
+ - Constructor injection (nunca @Autowired em campo)
16
+ - @Transactional apenas no Service
17
+ - Entidades com comportamento rico (não anêmicas)
18
+ - MapStruct para conversão Entity ↔ DTO
19
+
20
+ ### Angular
21
+ - Standalone components (Angular 17+)
22
+ - Lazy loading por rota
23
+ - Reactive Forms com validação
24
+ - Services para chamadas HTTP
25
+
26
+ ## Padrões de qualidade
27
+
28
+ - Cobertura mínima: 80%
29
+ - JUnit 5 + Mockito para backend
30
+ - Jest + Cypress para frontend
31
+ - Code review obrigatório
32
+ - Commits seguem Conventional Commits