jarvis-ai-framework 1.0.3 → 2.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 (193) hide show
  1. package/AGENTS.md +66 -64
  2. package/README.md +24 -10
  3. package/agents/AGENTS.md +12 -8
  4. package/agents/README.md +14 -16
  5. package/agents/engineering/data/eng.data-engineer.agent.md +6 -6
  6. package/agents/engineering/eng.agent.md +19 -36
  7. package/agents/engineering/eng.bug-hunter.md +13 -12
  8. package/agents/engineering/eng.cybersecurity.agent.md +20 -35
  9. package/agents/engineering/eng.docs-writer.md +2 -2
  10. package/agents/engineering/eng.frontend.agent.md +17 -22
  11. package/agents/engineering/eng.rpa.agent.md +5 -15
  12. package/agents/engineering/qa/eng.qa.test-architect.md +4 -4
  13. package/agents/engineering/qa/eng.qa.test-planner.md +3 -3
  14. package/agents/engineering/qa/eng.qa.testing-engineer.md +3 -3
  15. package/agents/product/prod.discovery-interviewer.md +86 -0
  16. package/bin/commands/init.js +6 -6
  17. package/bin/jarvis.js +1 -1
  18. package/bin/lib/config/constants.js +47 -0
  19. package/bin/lib/core/sync-engine.js +12 -0
  20. package/package.json +2 -5
  21. package/rules/AGENTS.md +6 -4
  22. package/rules/engineering/eng-rules.md +5 -3
  23. package/rules/engineering/eng-security-rules.md +4 -4
  24. package/rules/engineering/eng.breakdown-subtasks-rules.md +208 -37
  25. package/rules/engineering/eng.docs-scraping-rules.md +1 -1
  26. package/rules/engineering/eng.downstream-flow-rules.md +1 -1
  27. package/rules/engineering/eng.integrations-rules.md +2 -2
  28. package/rules/engineering/eng.pre-pr-rules.md +1 -1
  29. package/rules/engineering/eng.skills-rules.md +60 -0
  30. package/rules/engineering/eng.specializations-rules.md +69 -0
  31. package/rules/engineering/eng.start-rules.md +11 -11
  32. package/rules/engineering/eng.work-rules.md +19 -14
  33. package/rules/engineering/frontend/eng.frontend-rules.md +70 -69
  34. package/rules/product/README.md +2 -0
  35. package/rules/product/prod-rules.md +7 -5
  36. package/{skills/prod-specs/rules/prod-spec-rules.md → rules/product/prod.spec-rules.md} +55 -50
  37. package/skills/AGENTS.md +111 -47
  38. package/skills/SKILLS-ROADMAP.md +26 -45
  39. package/skills/eng-ai-engineer/SKILL.md +1 -0
  40. package/skills/eng-backend/SKILL.md +142 -644
  41. package/skills/eng-backend/references/1-fundamentos-programacao.md +41 -0
  42. package/skills/eng-backend/references/10-seguranca.md +61 -0
  43. package/skills/eng-backend/references/11-performance.md +49 -0
  44. package/skills/eng-backend/references/12-erros-logging.md +42 -0
  45. package/skills/eng-backend/references/13-qualidade-codigo.md +51 -0
  46. package/skills/eng-backend/references/2-design-arquitetura.md +48 -0
  47. package/skills/eng-backend/references/3-design-patterns.md +50 -0
  48. package/skills/eng-backend/references/4-algoritmos-estruturas.md +43 -0
  49. package/skills/eng-backend/references/5-banco-dados.md +53 -0
  50. package/skills/eng-backend/references/6-api-comunicacao.md +42 -0
  51. package/skills/eng-backend/references/7-concorrencia-async.md +49 -0
  52. package/skills/eng-backend/references/8-arquitetura-servidor.md +49 -0
  53. package/skills/eng-backend/references/9-testes.md +43 -0
  54. package/skills/{eng-arch-c4 → eng-backend-arch-c4}/SKILL.md +12 -7
  55. package/skills/{eng-ms-trace → eng-backend-microservices-trace}/SKILL.md +6 -4
  56. package/skills/{eng-nestjs → eng-backend-nestjs}/SKILL.md +3 -1
  57. package/skills/{eng-rabbitmq → eng-backend-rabbitmq}/SKILL.md +3 -1
  58. package/skills/eng-data-bi/SKILL.md +1 -0
  59. package/skills/eng-data-debug/SKILL.md +2 -1
  60. package/skills/eng-data-engineer/SKILL.md +1 -0
  61. package/skills/eng-data-onboard/SKILL.md +1 -0
  62. package/skills/eng-data-orchestrator/SKILL.md +1 -0
  63. package/skills/{eng-performance-engineer → eng-devops-performance-engineer}/SKILL.md +2 -1
  64. package/skills/eng-frontend/SKILL.md +145 -782
  65. package/skills/eng-frontend/references/1-fundamentos-programacao.md +37 -0
  66. package/skills/eng-frontend/references/10-testes.md +47 -0
  67. package/skills/eng-frontend/references/11-seguranca.md +56 -0
  68. package/skills/eng-frontend/references/12-qualidade-codigo.md +51 -0
  69. package/skills/eng-frontend/references/2-html-fundamentals.md +51 -0
  70. package/skills/eng-frontend/references/3-css-responsive.md +61 -0
  71. package/skills/eng-frontend/references/4-javascript-dom.md +60 -0
  72. package/skills/eng-frontend/references/5-state-management.md +55 -0
  73. package/skills/eng-frontend/references/6-uiux-design.md +59 -0
  74. package/skills/eng-frontend/references/7-acessibilidade.md +46 -0
  75. package/skills/eng-frontend/references/8-performance.md +58 -0
  76. package/skills/eng-frontend/references/9-browser-apis.md +54 -0
  77. package/skills/{eng-design-system → eng-frontend-design-system}/SKILL.md +4 -2
  78. package/skills/{eng-microfrontend → eng-frontend-microfrontend}/SKILL.md +4 -2
  79. package/skills/{eng-browser-extension-builder → eng-global-browser-extension-builder}/SKILL.md +2 -1
  80. package/skills/{eng-docs-write → eng-global-docs-write}/SKILL.md +8 -4
  81. package/skills/eng-global-jira-comment/SKILL.md +21 -0
  82. package/skills/{eng-pr → eng-global-pr}/SKILL.md +7 -3
  83. package/skills/{eng-task-comment → eng-global-task-comment}/SKILL.md +6 -2
  84. package/skills/eng-qa-a11y-audit/SKILL.md +1 -0
  85. package/skills/eng-qa-bug-report/SKILL.md +2 -1
  86. package/skills/eng-qa-bug-report/TASK_MANAGERS.md +1 -1
  87. package/skills/eng-qa-cypress-e2e/SKILL.md +1 -0
  88. package/skills/eng-qa-dev-guide/SKILL.md +1 -0
  89. package/skills/eng-qa-e2e/SKILL.md +1 -0
  90. package/skills/eng-qa-e2e-spec-writer/SKILL.md +1 -0
  91. package/skills/eng-qa-exploratory/SKILL.md +1 -0
  92. package/skills/eng-qa-gate/SKILL.md +3 -2
  93. package/skills/eng-qa-graphql-contract/SKILL.md +1 -0
  94. package/skills/eng-qa-quality-report/SKILL.md +3 -2
  95. package/skills/eng-qa-test-plan/SKILL.md +1 -0
  96. package/skills/eng-qa-testsprite/SKILL.md +2 -1
  97. package/skills/eng-qa-unit-test/SKILL.md +1 -0
  98. package/skills/eng-scraper/SKILL.md +1 -0
  99. package/skills/eng-scraper-robot-builder/SKILL.md +1 -0
  100. package/skills/{eng-cybersecurity → eng-security-cybersecurity}/SKILL.md +3 -2
  101. package/skills/eng-security-patch/SKILL.md +6 -2
  102. package/skills/{eng-threat-model → eng-security-threat-model}/SKILL.md +6 -2
  103. package/skills/eng-security-triage/SKILL.md +4 -0
  104. package/skills/{context-detect → jarvis-context-detect}/SKILL.md +6 -5
  105. package/skills/{context-detect → jarvis-context-detect}/assets/context-profile-template.md +3 -3
  106. package/skills/jarvis-create-specialization/SKILL.md +230 -0
  107. package/skills/jarvis-create-specialization/assets/referencia-template.md +39 -0
  108. package/skills/jarvis-create-specialization/assets/skill-especializacao-template.md +78 -0
  109. package/skills/{docs-central → jarvis-docs-central}/README.md +1 -1
  110. package/skills/{docs-central → jarvis-docs-central}/SKILL.md +3 -40
  111. package/skills/{docs-index → jarvis-docs-index}/SKILL.md +8 -4
  112. package/skills/{init-jarvis → jarvis-init}/SKILL.md +42 -19
  113. package/skills/{init-jarvis → jarvis-init}/assets/mcp-configs.md +3 -3
  114. package/skills/{init-jarvis → jarvis-init}/assets/onboarding-checklist.md +1 -1
  115. package/skills/jarvis-init/assets/passo-adicionar-stacks.md +163 -0
  116. package/skills/{init-jarvis → jarvis-init}/assets/setup-guide.md +1 -1
  117. package/skills/jarvis-init/assets/sinais-de-stack.md +54 -0
  118. package/skills/jarvis-list-specializations/SKILL.md +148 -0
  119. package/skills/{report-issue → jarvis-report-issue}/SKILL.md +3 -2
  120. package/skills/{prod-roadmap-report → product-roadmap-report}/SKILL.md +2 -1
  121. package/skills/product-specs/SKILL.md +45 -0
  122. package/skills/{prod-specs-update → product-specs-update}/SKILL.md +3 -2
  123. package/taxonomy.md +3 -21
  124. package/templates/AGENTS.md +7 -6
  125. package/templates/CDD aplicado a Prompts.md +5 -5
  126. package/templates/ENV-template.md +12 -9
  127. package/templates/engineering/AGENTS-template.md +1 -1
  128. package/templates/engineering/CONTACTS-template.md +1 -1
  129. package/templates/product/prod-discovery-template.md +98 -0
  130. package/{skills/prod-specs/templates → templates/product}/prod-epic-template.md +1 -0
  131. package/{skills/prod-specs/templates → templates/product}/prod-frd-template.md +1 -0
  132. package/{skills/prod-specs/templates → templates/product}/prod-issue-template.md +1 -0
  133. package/{skills/prod-specs/templates → templates/product}/prod-prd-template.md +1 -0
  134. package/workflows/AGENTS.md +3 -1
  135. package/workflows/README.md +2 -0
  136. package/workflows/engineering/eng.bug-audit.md +2 -2
  137. package/workflows/engineering/eng.build-tech-spec.md +38 -49
  138. package/workflows/engineering/eng.debug.md +10 -10
  139. package/workflows/engineering/eng.docs.md +2 -2
  140. package/workflows/engineering/eng.plan.md +5 -5
  141. package/workflows/engineering/eng.pr.md +8 -8
  142. package/workflows/engineering/eng.pre-pr.md +16 -20
  143. package/workflows/engineering/eng.review.md +5 -10
  144. package/workflows/engineering/eng.rpa.robot.md +3 -3
  145. package/workflows/engineering/eng.security-audit.md +5 -5
  146. package/workflows/engineering/eng.security-incident.md +2 -2
  147. package/workflows/engineering/eng.security-pipeline.md +2 -2
  148. package/workflows/engineering/eng.start.md +16 -50
  149. package/workflows/engineering/eng.work.md +9 -12
  150. package/workflows/engineering/frontend/eng.frontend-component.md +68 -96
  151. package/workflows/engineering/frontend/eng.frontend-perf-audit.md +90 -220
  152. package/workflows/engineering/frontend/eng.frontend-review.md +57 -63
  153. package/workflows/engineering/qa/eng.qa-quality-report.md +0 -5
  154. package/workflows/product/prod.roadmap.preview.md +2 -2
  155. package/workflows/product/prod.spec.breakdown.md +3 -8
  156. package/workflows/product/prod.spec.discovery.md +152 -0
  157. package/workflows/product/prod.spec.epic.md +3 -0
  158. package/workflows/product/prod.spec.frd.md +123 -8
  159. package/workflows/product/prod.spec.issue.md +3 -2
  160. package/workflows/product/prod.spec.md +2 -0
  161. package/workflows/product/prod.spec.prd.md +105 -6
  162. package/workflows/taxonomy.md +1 -1
  163. package/workflows/warm-up.md +5 -26
  164. package/agents/engineering/eng.tech-analyst.agent.md +0 -102
  165. package/skills/churn-audit/SKILL.md +0 -385
  166. package/skills/eng-jira-comment/SKILL.md +0 -17
  167. package/skills/eng-tech-analyst/SKILL.md +0 -529
  168. package/skills/lovable-prompt-generator/SKILL.md +0 -304
  169. package/skills/prod-specs/SKILL.md +0 -108
  170. package/skills/prod-specs/references/prod.spec.clarify.md +0 -176
  171. package/skills/prod-specs/references/prod.spec.epic.md +0 -107
  172. package/skills/prod-specs/references/prod.spec.frd.md +0 -135
  173. package/skills/prod-specs/references/prod.spec.issue.md +0 -145
  174. package/skills/prod-specs/references/prod.spec.prd.md +0 -118
  175. package/skills/prod-specs/templates/prod-prd-full-template.md +0 -159
  176. package/workflows/engineering/ta/eng.ta.atendimento.md +0 -93
  177. /package/skills/{eng-arch-c4 → eng-backend-arch-c4}/assets/example-code.md +0 -0
  178. /package/skills/{eng-arch-c4 → eng-backend-arch-c4}/assets/example-component.md +0 -0
  179. /package/skills/{eng-arch-c4 → eng-backend-arch-c4}/assets/example-container.md +0 -0
  180. /package/skills/{eng-arch-c4 → eng-backend-arch-c4}/assets/example-context.md +0 -0
  181. /package/skills/{prod-roadmap-report → product-roadmap-report}/README.md +0 -0
  182. /package/skills/{prod-roadmap-report → product-roadmap-report}/commands/status.compiled.single.team.md +0 -0
  183. /package/skills/{prod-roadmap-report → product-roadmap-report}/commands/status.list.projects.md +0 -0
  184. /package/skills/{prod-roadmap-report → product-roadmap-report}/commands/status.memory.md +0 -0
  185. /package/skills/{prod-roadmap-report → product-roadmap-report}/commands/status.roadmap.preview.md +0 -0
  186. /package/skills/{prod-roadmap-report → product-roadmap-report}/references/detailed-guide.md +0 -0
  187. /package/skills/{prod-roadmap-report → product-roadmap-report}/rules/detailed-guide.md +0 -0
  188. /package/skills/{prod-roadmap-report → product-roadmap-report}/rules/status-report-rules.md +0 -0
  189. /package/skills/{prod-roadmap-report → product-roadmap-report}/templates/template-multiple-teams-compiled-status.md +0 -0
  190. /package/skills/{prod-roadmap-report → product-roadmap-report}/templates/template-projects-list.md +0 -0
  191. /package/skills/{prod-roadmap-report → product-roadmap-report}/templates/template-single-team-compiled-status.md +0 -0
  192. /package/skills/{prod-roadmap-report → product-roadmap-report}/templates/template-single-team-status.md +0 -0
  193. /package/{skills/prod-specs/templates → templates/product}/prod-breakdown-template.md +0 -0
@@ -1,49 +1,49 @@
1
1
  ---
2
2
  name: eng-backend
3
3
  description: >
4
- Especialista em desenvolvimento backend: APIs REST/GraphQL, autenticação, workers, jobs,
5
- integrações externas, caching e boas práticas de produção com NestJS e RabbitMQ.
6
- Trigger: Use para APIs, auth, lógica de negócio, workers, jobs, integrações, caching ou backend em geral.
4
+ Skill base de desenvolvimento backend, válida em qualquer linguagem ou framework: design de APIs,
5
+ autenticação e autorização, banco de dados, concorrência, arquitetura de servidor, testes, segurança,
6
+ performance e tratamento de erros. Pode ser complementada por skills especializados de uma stack.
7
+ Trigger: Use para APIs, autenticação, lógica de negócio, workers, jobs, integrações, caching,
8
+ banco de dados ou backend em geral.
7
9
  license: AGPL-3.0
8
10
  compatibility: Designed for Claude Code (or similar products)
9
11
  allowed-tools: Read Write Edit Glob Grep Bash
10
12
  metadata:
11
13
  author: jarvis-team
12
- version: "1.0"
14
+ version: "2.0"
15
+ area: backend
13
16
  # Campos Claude Code-specific (não fazem parte da spec oficial agentskills.io):
14
17
  argument-hint: "[endpoint|auth|worker|integração|refactor|debug] [contexto]"
15
18
  disable-model-invocation: false
16
19
  ---
17
20
 
18
- # Eng Backend - Especialista em Desenvolvimento de Servidor
21
+ # Eng Backend - Skill Base de Desenvolvimento de Servidor
19
22
 
20
- Você é um **especialista em desenvolvimento backend moderno** com domínio em APIs, autenticação/autorização, arquiteturas de serviços, workers assíncronos e integrações externas prontas para produção.
23
+ Você é uma **pessoa desenvolvedora backend sênior**, com domínio dos princípios que valem em qualquer linguagem ou framework: APIs, autenticação e autorização, dados, concorrência, arquitetura de servidor, segurança e observabilidade.
21
24
 
22
25
  ## Objetivo
23
26
 
24
- Construir backends confiáveis, seguros e escaláveis — desde endpoints simples até arquiteturas de serviços complexas com workers, filas e integrações de terceiros.
27
+ Construir backends confiáveis, seguros e fáceis de evoluir, aplicando a **base universal** de backend. Este skill não presume uma stack: ele descobre a stack do projeto pelo próprio código e segue o padrão que encontra.
25
28
 
26
29
  ## Entrada
27
30
 
28
- - `$ARGUMENTS` - Operação, feature ou problema a resolver (ex: `criar-endpoint-produtos`, `implementar-jwt-refresh`, `worker-envio-email`, `integrar-stripe`, `otimizar-query-lenta`)
31
+ - `$ARGUMENTS` - Operação, funcionalidade ou problema a resolver (ex: `criar-endpoint-produtos`, `implementar-refresh-de-token`, `worker-envio-email`, `integrar-servico-externo`, `otimizar-consulta-lenta`)
29
32
 
30
33
  ## Recursos
31
34
 
32
- - **ENV**: `$IDE/ENV.md` (variáveis de ambiente, incluindo MESSAGE_BROKER_URL e credenciais RabbitMQ)
33
- - **Saída**: código no repositório atual (controllers, services, workers, testes)
35
+ - **ENV**: `$IDE/ENV.md` (variáveis de ambiente e configurações do projeto)
36
+ - **Base universal**: os 13 temas em [references/](references/), carregados sob demanda
37
+ - **Saída**: código e testes no repositório atual
34
38
 
35
39
  ---
36
40
 
37
41
  ## Pré-requisito
38
42
 
39
- Verificar se o `ENV.md` existe e se as variáveis necessárias estão configuradas:
43
+ Verificar se o `ENV.md` existe e se as variáveis necessárias ao projeto estão configuradas:
40
44
 
41
45
  ```bash
42
- # Verificar existência do ENV.md
43
46
  cat $IDE/ENV.md
44
-
45
- # Verificar credenciais do message broker (obrigatório para workers RabbitMQ)
46
- grep "MESSAGE_BROKER" $IDE/ENV.md
47
47
  ```
48
48
 
49
49
  ---
@@ -51,693 +51,179 @@ grep "MESSAGE_BROKER" $IDE/ENV.md
51
51
  ## Quando Usar
52
52
 
53
53
  Use este skill quando:
54
- - Criar ou refatorar endpoints REST ou GraphQL
55
- - Implementar autenticação (JWT, OAuth2, sessions) ou autorização (RBAC)
56
- - Criar workers, jobs em background ou processamento assíncrono (RabbitMQ, cron)
57
- - Integrar com APIs externas (webhooks, third-party, retry logic)
58
- - Implementar caching (Redis, in-memory, invalidação)
59
- - Aplicar boas práticas de API design (paginação, versionamento, idempotência)
60
- - Escrever testes de backend (unitários, integração, mocks)
54
+ - Criar ou refatorar endpoints e contratos de API
55
+ - Implementar autenticação, autorização e controle de acesso
56
+ - Criar workers, jobs em background ou processamento assíncrono
57
+ - Integrar com serviços externos (webhooks, APIs de terceiros, tentativas de repetição)
58
+ - Modelar dados, escrever consultas ou criar migrações
59
+ - Implementar cache e otimizar desempenho
60
+ - Escrever testes de backend, tratar erros e registrar logs
61
61
 
62
62
  **NÃO usar quando:**
63
- - A tarefa é exclusivamente de frontend, banco de dados ou infraestrutura
64
- - Não há lógica de servidor, API ou processamento assíncrono envolvido
63
+ - A tarefa é exclusivamente de frontend ou de infraestrutura
64
+ - Não há lógica de servidor, API, dados ou processamento assíncrono envolvido
65
65
 
66
66
  ---
67
67
 
68
68
  ## Validação de Entrada
69
69
 
70
- Se $ARGUMENTS está vazio, o skill funciona em modo interativo: solicitar ao usuário o contexto da tarefa backend antes de prosseguir.
70
+ Se `$ARGUMENTS` está vazio, o skill funciona em modo interativo: pergunte à pessoa o contexto da tarefa de backend antes de prosseguir.
71
71
 
72
72
  ---
73
73
 
74
74
  ## Padrões Críticos
75
75
 
76
- ### Padrão 1: Ler o Projeto Antes de Escrever
77
-
78
- ```bash
79
- # Verificar framework e dependências
80
- cat package.json | grep -E '"nest|amqplib|@golevelup/nestjs-rabbitmq|redis|prisma|typeorm|drizzle|jest|vitest"'
76
+ ### Padrão 1: Ler o projeto antes de escrever
81
77
 
82
- # Verificar estrutura de rotas/controllers
83
- ls src/ 2>/dev/null
78
+ Antes de criar qualquer coisa, descubra como o projeto já funciona:
84
79
 
85
- # Verificar como auth está implementada
86
- grep -r "JwtModule\|passport\|jwt.sign\|jwt.verify" src/ --include="*.ts" -l
80
+ ```
81
+ 1. Qual é a linguagem e o framework? (pelos arquivos de manifesto e de dependências do projeto)
82
+ 2. Como as rotas, os serviços e os dados estão organizados? (estrutura de pastas)
83
+ 3. Como a autenticação e a autorização já são feitas?
84
+ 4. Como os erros, os logs e os testes são escritos?
85
+ 5. Existe uma convenção de nomes e de camadas a seguir?
87
86
  ```
88
87
 
89
- ### Padrão 2: Segurança por Padrão
88
+ Siga o padrão existente do projeto, **não** o padrão genérico deste skill. Se não conseguir identificar a stack, pergunte antes de prosseguir.
89
+
90
+ ### Padrão 2: Segurança por padrão
90
91
 
91
92
  Toda API precisa considerar:
92
93
 
93
94
  ```
94
95
  1. Validação de entrada → nunca confiar em dados externos
95
- 2. Autenticação → verificar identidade antes de processar
96
- 3. Autorização → verificar permissão após autenticação
97
- 4. Rate limiting → proteger contra abuso
98
- 5. Sanitização → prevenir injeção (SQL, NoSQL, command)
99
- 6. Não expor detalhes de erro internos em produção
96
+ 2. Autenticação → verificar a identidade antes de processar
97
+ 3. Autorização → verificar a permissão depois de autenticar
98
+ 4. Limitação de taxa → proteger contra abuso
99
+ 5. Sanitização → prevenir injeção (SQL, comandos, documentos)
100
+ 6. Não expor detalhes internos de erro em produção
100
101
  ```
101
102
 
102
- ### Padrão 3: Tratamento de Erros Consistente
103
-
104
- ```typescript
105
- // ✅ Erro tipado com contexto
106
- export class AppError extends Error {
107
- constructor(
108
- public readonly message: string,
109
- public readonly statusCode: number = 500,
110
- public readonly code: string = 'INTERNAL_ERROR'
111
- ) {
112
- super(message)
113
- this.name = 'AppError'
114
- }
115
- }
116
-
117
- // ✅ Erros de negócio explícitos
118
- export class NotFoundError extends AppError {
119
- constructor(resource: string, id: string) {
120
- super(`${resource} com id '${id}' não encontrado`, 404, 'NOT_FOUND')
121
- }
122
- }
123
-
124
- export class UnauthorizedError extends AppError {
125
- constructor(message = 'Não autorizado') {
126
- super(message, 401, 'UNAUTHORIZED')
127
- }
128
- }
129
- ```
103
+ ### Padrão 3: Tratamento de erros consistente
130
104
 
131
- ### Padrão 4: Idempotência em Operações Críticas
105
+ - Erros tipados, com **código** estável e **mensagem** útil, e com o status de resposta adequado
106
+ - Erros de negócio explícitos (não encontrado, não autorizado, conflito, entrada inválida)
107
+ - O detalhe técnico vai para o log, nunca para a resposta ao cliente
108
+ - O mesmo formato de erro em toda a API
132
109
 
133
- ```typescript
134
- // ✅ Idempotency key para mutations críticas (pagamentos, envios)
135
- async function processPayment(idempotencyKey: string, data: PaymentData) {
136
- const existing = await redis.get(`payment:idempotency:${idempotencyKey}`)
137
- if (existing) return JSON.parse(existing)
110
+ ### Padrão 4: Idempotência em operações críticas
138
111
 
139
- const result = await stripe.charge(data)
140
- await redis.set(`payment:idempotency:${idempotencyKey}`, JSON.stringify(result), 'EX', 86400)
141
- return result
142
- }
143
- ```
112
+ Mutações críticas (pagamentos, envios, criação de recursos) devem poder ser repetidas sem repetir o efeito:
144
113
 
145
- ---
114
+ - Aceitar uma **chave de idempotência** do chamador
115
+ - Guardar o resultado da primeira execução por um tempo definido
116
+ - Devolver o resultado guardado quando a mesma chave chegar de novo
146
117
 
147
- ## Árvore de Decisão
118
+ ### Padrão 5: Rastreabilidade entre serviços
148
119
 
149
- ```
150
- Criar/modificar endpoint? → Seção: API Design
151
- Implementar autenticação? → Seção: Autenticação e Autorização
152
- Criar worker ou job? → Seção: Workers e Jobs Assíncronos
153
- Integrar API externa? → Seção: Integrações Externas
154
- Implementar caching? → Seção: Caching
155
- Escrever testes? → Seção: Testes
156
- Debug de problema? → Seção: Debugging e Observabilidade
157
- ```
120
+ Em fluxos que cruzam serviços, propague um **identificador de correlação** nas chamadas de saída e nas mensagens publicadas, e inclua-o nos logs. Sem ele, um defeito intermitente só é rastreável à mão.
158
121
 
159
122
  ---
160
123
 
161
- ## Fluxo de Trabalho
162
-
163
- ### API Design
164
-
165
- #### REST — boas práticas
166
-
167
- ```typescript
168
- // ✅ Estrutura de rotas REST
169
- GET /products → listar produtos (com paginação)
170
- GET /products/:id → buscar produto por ID
171
- POST /products → criar produto
172
- PUT /products/:id → atualizar produto completo
173
- PATCH /products/:id → atualizar produto parcialmente
174
- DELETE /products/:id → remover produto
175
-
176
- // ✅ Resposta padronizada
177
- interface ApiResponse<T> {
178
- data: T
179
- meta?: {
180
- page: number
181
- pageSize: number
182
- total: number
183
- totalPages: number
184
- }
185
- }
186
-
187
- // ✅ Erros padronizados
188
- interface ApiError {
189
- error: {
190
- code: string // ex: "PRODUCT_NOT_FOUND"
191
- message: string // mensagem legível
192
- details?: unknown // erros de validação, etc.
193
- }
194
- }
195
- ```
196
-
197
- #### Paginação
198
-
199
- ```typescript
200
- // ✅ Cursor-based (recomendado para grandes volumes)
201
- interface CursorPaginationParams {
202
- cursor?: string // ID do último item retornado
203
- limit?: number // default: 20, max: 100
204
- }
205
-
206
- // ✅ Offset-based (simples, para volumes menores)
207
- interface OffsetPaginationParams {
208
- page?: number // default: 1
209
- pageSize?: number // default: 20, max: 100
210
- }
211
-
212
- // Implementação com Prisma
213
- async function listProducts({ page = 1, pageSize = 20 }: OffsetPaginationParams) {
214
- const [items, total] = await Promise.all([
215
- prisma.product.findMany({
216
- skip: (page - 1) * pageSize,
217
- take: pageSize,
218
- orderBy: { createdAt: 'desc' },
219
- }),
220
- prisma.product.count(),
221
- ])
222
-
223
- return {
224
- data: items,
225
- meta: { page, pageSize, total, totalPages: Math.ceil(total / pageSize) },
226
- }
227
- }
228
- ```
229
-
230
- #### Versionamento de API
231
-
232
- ```typescript
233
- // ✅ Versionamento por URL (mais explícito)
234
- app.register(v1Routes, { prefix: '/api/v1' })
235
- app.register(v2Routes, { prefix: '/api/v2' })
236
-
237
- // ✅ Versionamento por header (para APIs internas)
238
- // Accept: application/vnd.api+json;version=2
239
- ```
240
-
241
- ### Autenticação e Autorização
242
-
243
- #### JWT com refresh token
244
-
245
- ```typescript
246
- // ✅ Par de tokens: access (curto) + refresh (longo)
247
- const ACCESS_TOKEN_EXPIRY = '15m'
248
- const REFRESH_TOKEN_EXPIRY = '7d'
249
-
250
- async function generateTokens(userId: string) {
251
- const accessToken = jwt.sign({ sub: userId, type: 'access' }, JWT_SECRET, {
252
- expiresIn: ACCESS_TOKEN_EXPIRY,
253
- })
254
-
255
- const refreshToken = jwt.sign({ sub: userId, type: 'refresh' }, JWT_REFRESH_SECRET, {
256
- expiresIn: REFRESH_TOKEN_EXPIRY,
257
- })
124
+ ## Base ou especialização?
258
125
 
259
- // Armazenar refresh token no banco (para revogação)
260
- await db.refreshToken.create({
261
- data: { token: hashToken(refreshToken), userId, expiresAt: addDays(new Date(), 7) },
262
- })
126
+ Pergunta-chave para decidir onde um conhecimento mora:
263
127
 
264
- return { accessToken, refreshToken }
265
- }
266
-
267
- // ✅ Rota de refresh
268
- async function refreshAccessToken(refreshToken: string) {
269
- const payload = jwt.verify(refreshToken, JWT_REFRESH_SECRET)
270
- const stored = await db.refreshToken.findUnique({ where: { token: hashToken(refreshToken) } })
271
-
272
- if (!stored || stored.revokedAt || stored.expiresAt < new Date()) {
273
- throw new UnauthorizedError('Refresh token inválido ou expirado')
274
- }
275
-
276
- return generateTokens(payload.sub)
277
- }
278
- ```
279
-
280
- #### RBAC — Role-Based Access Control
281
-
282
- ```typescript
283
- // ✅ Definição de roles e permissões
284
- const permissions = {
285
- admin: ['products:read', 'products:write', 'products:delete', 'users:manage'],
286
- editor: ['products:read', 'products:write'],
287
- viewer: ['products:read'],
288
- } as const
289
-
290
- type Permission = (typeof permissions)[keyof typeof permissions][number]
291
-
292
- // ✅ Middleware de autorização
293
- function requirePermission(permission: Permission) {
294
- return async (req: Request, res: Response, next: NextFunction) => {
295
- const userPermissions = permissions[req.user.role] ?? []
296
- if (!userPermissions.includes(permission)) {
297
- throw new ForbiddenError(`Permissão '${permission}' necessária`)
298
- }
299
- next()
300
- }
301
- }
302
-
303
- // Uso na rota
304
- router.delete('/products/:id', authenticate, requirePermission('products:delete'), deleteProduct)
305
- ```
306
-
307
- #### OAuth2 — fluxo básico
308
-
309
- ```typescript
310
- // ✅ Authorization Code Flow (para apps com frontend)
311
- // 1. Redirecionar para provider → GET /oauth/authorize?provider=github
312
- // 2. Receber callback com code → GET /oauth/callback?code=xxx
313
- // 3. Trocar code por token → POST ao provider
314
- // 4. Buscar perfil do usuário → GET /user no provider
315
- // 5. Criar/atualizar usuário local → gerar tokens da aplicação
316
-
317
- async function handleOAuthCallback(provider: string, code: string) {
318
- const { access_token } = await exchangeCodeForToken(provider, code)
319
- const profile = await fetchUserProfile(provider, access_token)
320
-
321
- const user = await upsertUser({
322
- email: profile.email,
323
- name: profile.name,
324
- oauthProvider: provider,
325
- oauthId: profile.id,
326
- })
327
-
328
- return generateTokens(user.id)
329
- }
330
- ```
331
-
332
- ### Workers e Jobs Assíncronos
333
-
334
- #### RabbitMQ com NestJS — padrão do projeto
335
-
336
- O projeto usa RabbitMQ como broker de mensagens. Verificar variáveis no ENV.md:
337
-
338
- ```bash
339
- grep "MESSAGE_BROKER\|RABBITMQ" $IDE/ENV.md
340
- ```
341
-
342
- **Variáveis esperadas:** `MESSAGE_BROKER_URL`, `MESSAGE_BROKER_USER`, `MESSAGE_BROKER_PASS` (ou equivalentes — checar ENV.md).
343
-
344
- ##### Publicar mensagem (Producer)
345
-
346
- ```typescript
347
- // ✅ NestJS com @golevelup/nestjs-rabbitmq
348
- import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'
349
- import { Injectable } from '@nestjs/common'
350
-
351
- @Injectable()
352
- export class EmailProducerService {
353
- constructor(private readonly amqpConnection: AmqpConnection) {}
354
-
355
- async sendWelcomeEmail(to: string, name: string): Promise<void> {
356
- await this.amqpConnection.publish(
357
- 'email.exchange', // exchange
358
- 'email.welcome', // routing key
359
- { to, name }, // payload (serializado como JSON)
360
- )
361
- }
362
- }
363
- ```
364
-
365
- ##### Consumir mensagem (Consumer / Worker)
366
-
367
- ```typescript
368
- // ✅ Consumer com @golevelup/nestjs-rabbitmq
369
- import { RabbitSubscribe, Nack } from '@golevelup/nestjs-rabbitmq'
370
- import { Injectable, Logger } from '@nestjs/common'
371
-
372
- @Injectable()
373
- export class EmailConsumerService {
374
- private readonly logger = new Logger(EmailConsumerService.name)
375
-
376
- @RabbitSubscribe({
377
- exchange: 'email.exchange',
378
- routingKey: 'email.welcome',
379
- queue: 'email.welcome.queue',
380
- queueOptions: {
381
- durable: true,
382
- deadLetterExchange: 'email.exchange.dlx',
383
- },
384
- })
385
- async handleWelcomeEmail(payload: { to: string; name: string }): Promise<void | Nack> {
386
- try {
387
- await sendEmail({ to: payload.to, template: 'welcome', data: { name: payload.name } })
388
- } catch (error) {
389
- this.logger.error({ error, payload }, 'Falha ao processar email de boas-vindas')
390
- return new Nack(false) // rejeitar sem requeue → vai para DLX
391
- }
392
- }
393
- }
394
- ```
395
-
396
- ##### Configuração do módulo
397
-
398
- ```typescript
399
- // ✅ RabbitMQModule no AppModule
400
- import { RabbitMQModule } from '@golevelup/nestjs-rabbitmq'
401
-
402
- RabbitMQModule.forRootAsync({
403
- useFactory: (configService: ConfigService) => ({
404
- uri: configService.getOrThrow('MESSAGE_BROKER_URL'),
405
- exchanges: [
406
- { name: 'email.exchange', type: 'direct', options: { durable: true } },
407
- { name: 'email.exchange.dlx', type: 'direct', options: { durable: true } },
408
- ],
409
- connectionInitOptions: { wait: true },
410
- }),
411
- inject: [ConfigService],
412
- })
413
- ```
128
+ > **Esse conhecimento continua válido quando eu mudo de linguagem ou de framework?**
129
+ > **Sim** → pertence à base universal (este skill). **Não** → pertence a uma especialização de stack.
414
130
 
415
- #### Cron jobs com NestJS
416
-
417
- ```typescript
418
- // ✅ @nestjs/schedule — decorator nativo
419
- import { Injectable, Logger } from '@nestjs/common'
420
- import { Cron, CronExpression } from '@nestjs/schedule'
421
-
422
- @Injectable()
423
- export class ReportSchedulerService {
424
- private readonly logger = new Logger(ReportSchedulerService.name)
425
-
426
- // Rodar às 9h todo dia útil (horário de São Paulo)
427
- @Cron('0 9 * * 1-5', { timeZone: 'America/Sao_Paulo' })
428
- async handleDailyReport(): Promise<void> {
429
- this.logger.log('Iniciando relatório diário')
430
- try {
431
- await this.reportService.generateDaily()
432
- } catch (error) {
433
- this.logger.error({ error }, 'Falha ao gerar relatório diário')
434
- }
435
- }
436
- }
437
- ```
438
-
439
- ### Integrações Externas
440
-
441
- #### Padrão de integração robusta
442
-
443
- ```typescript
444
- // ✅ Cliente HTTP com retry e timeout
445
- import axios, { AxiosInstance } from 'axios'
446
- import axiosRetry from 'axios-retry'
447
-
448
- function createHttpClient(baseURL: string): AxiosInstance {
449
- const client = axios.create({
450
- baseURL,
451
- timeout: 10_000, // 10 segundos
452
- headers: { 'Content-Type': 'application/json' },
453
- })
454
-
455
- // Retry automático para erros de rede e 5xx
456
- axiosRetry(client, {
457
- retries: 3,
458
- retryDelay: axiosRetry.exponentialDelay,
459
- retryCondition: (error) =>
460
- axiosRetry.isNetworkError(error) ||
461
- axiosRetry.isRetryableError(error),
462
- })
463
-
464
- return client
465
- }
466
- ```
467
-
468
- #### Webhooks — receber e processar
469
-
470
- ```typescript
471
- // ✅ Verificação de assinatura (ex: Stripe)
472
- function verifyWebhookSignature(payload: Buffer, signature: string, secret: string): boolean {
473
- const expected = crypto
474
- .createHmac('sha256', secret)
475
- .update(payload)
476
- .digest('hex')
477
-
478
- // Comparação segura contra timing attacks
479
- return crypto.timingSafeEqual(
480
- Buffer.from(signature),
481
- Buffer.from(expected)
482
- )
483
- }
484
-
485
- // ✅ Controller NestJS para webhook com processamento assíncrono
486
- @Controller('webhooks')
487
- export class WebhookController {
488
- constructor(private readonly stripeProducer: StripeEventProducerService) {}
489
-
490
- @Post('stripe')
491
- @HttpCode(200)
492
- async handleStripe(
493
- @Headers('stripe-signature') signature: string,
494
- @Req() req: RawBodyRequest<Request>,
495
- ) {
496
- if (!verifyWebhookSignature(req.rawBody!, signature, process.env.STRIPE_WEBHOOK_SECRET!)) {
497
- throw new BadRequestException('Assinatura inválida')
498
- }
499
-
500
- const event = JSON.parse(req.rawBody!.toString())
501
-
502
- // Enfileirar no RabbitMQ — processar de forma assíncrona
503
- await this.stripeProducer.publish('stripe.events', event.type, event)
504
-
505
- return { received: true }
506
- }
507
- }
508
- ```
509
-
510
- ### Caching
511
-
512
- #### Estratégias de cache com Redis
513
-
514
- ```typescript
515
- // ✅ Cache-aside (padrão mais comum)
516
- async function getProduct(id: string): Promise<Product> {
517
- const cacheKey = `product:${id}`
518
-
519
- // 1. Verificar cache
520
- const cached = await redis.get(cacheKey)
521
- if (cached) return JSON.parse(cached)
522
-
523
- // 2. Buscar no banco
524
- const product = await db.product.findUniqueOrThrow({ where: { id } })
525
-
526
- // 3. Armazenar no cache
527
- await redis.set(cacheKey, JSON.stringify(product), 'EX', 300) // TTL: 5 minutos
528
-
529
- return product
530
- }
531
-
532
- // ✅ Invalidar cache ao atualizar
533
- async function updateProduct(id: string, data: UpdateProductDto): Promise<Product> {
534
- const product = await db.product.update({ where: { id }, data })
535
-
536
- // Invalidar cache deste produto e listas relacionadas
537
- await redis.del(`product:${id}`)
538
- await redis.del('products:list:*') // ou usar tags
539
-
540
- return product
541
- }
542
- ```
543
-
544
- #### Quando usar cada estratégia
545
-
546
- | Estratégia | Quando usar |
547
- |-----------|-------------|
548
- | Cache-aside (lazy) | Dados lidos frequentemente, escritas ocasionais |
549
- | Write-through | Dados críticos onde consistência é prioridade |
550
- | Write-behind | Alta frequência de escrita, consistência eventual ok |
551
- | TTL curto (< 1min) | Dados mutáveis com tolerância a leve stale |
552
- | TTL longo (> 1h) | Dados estáticos ou de referência |
553
- | Cache de sessão | User session, tokens temporários |
554
-
555
- ### Testes
556
-
557
- #### Testes unitários
558
-
559
- ```typescript
560
- import { describe, it, expect, vi, beforeEach } from 'vitest'
561
- import { ProductService } from './product.service'
562
- import { ProductRepository } from './product.repository'
563
-
564
- describe('ProductService', () => {
565
- let service: ProductService
566
- let repository: ProductRepository
567
-
568
- beforeEach(() => {
569
- // ✅ Mock do repositório — não precisa de banco real
570
- repository = {
571
- findById: vi.fn(),
572
- create: vi.fn(),
573
- update: vi.fn(),
574
- } as unknown as ProductRepository
575
-
576
- service = new ProductService(repository)
577
- })
578
-
579
- it('lança NotFoundError quando produto não existe', async () => {
580
- vi.mocked(repository.findById).mockResolvedValue(null)
581
-
582
- await expect(service.getById('id-inexistente')).rejects.toThrow('Produto não encontrado')
583
- })
131
+ ---
584
132
 
585
- it('retorna produto quando encontrado', async () => {
586
- const product = { id: '1', name: 'Produto A', price: 100 }
587
- vi.mocked(repository.findById).mockResolvedValue(product)
133
+ ## Árvore de Decisão
588
134
 
589
- const result = await service.getById('1')
590
- expect(result).toEqual(product)
591
- })
592
- })
593
135
  ```
594
-
595
- #### Testes de integração (NestJS + Supertest)
596
-
597
- ```typescript
598
- import { Test, TestingModule } from '@nestjs/testing'
599
- import { INestApplication, ValidationPipe } from '@nestjs/common'
600
- import * as request from 'supertest'
601
- import { ProductsModule } from '../products.module'
602
-
603
- describe('POST /api/products', () => {
604
- let app: INestApplication
605
-
606
- beforeAll(async () => {
607
- const module: TestingModule = await Test.createTestingModule({
608
- imports: [ProductsModule],
609
- })
610
- .overrideProvider(ProductRepository)
611
- .useValue({ create: jest.fn(), findById: jest.fn() })
612
- .compile()
613
-
614
- app = module.createNestApplication()
615
- app.useGlobalPipes(new ValidationPipe({ whitelist: true }))
616
- await app.init()
617
- })
618
-
619
- afterAll(() => app.close())
620
-
621
- it('cria produto e retorna 201', async () => {
622
- const response = await request(app.getHttpServer())
623
- .post('/api/products')
624
- .set('Authorization', `Bearer ${testToken}`)
625
- .send({ name: 'Produto Teste', price: 29.90 })
626
-
627
- expect(response.status).toBe(201)
628
- expect(response.body).toMatchObject({
629
- data: { name: 'Produto Teste', price: 29.90 },
630
- })
631
- })
632
-
633
- it('retorna 400 quando dados inválidos', async () => {
634
- const response = await request(app.getHttpServer())
635
- .post('/api/products')
636
- .set('Authorization', `Bearer ${testToken}`)
637
- .send({ name: '' }) // nome vazio, preço ausente
638
-
639
- expect(response.status).toBe(400)
640
- expect(response.body.message).toBeDefined()
641
- })
642
- })
136
+ Criar ou modificar um endpoint? → tema 6 (API e comunicação) e tema 10 (segurança)
137
+ Implementar autenticação? → tema 6 (API) e tema 10 (segurança)
138
+ Modelar dados, consultas ou migração? → tema 5 (banco de dados)
139
+ Criar worker, job ou fila? → tema 7 (concorrência) e tema 8 (servidor)
140
+ Integrar um serviço externo? → tema 6 (API), tema 8 (resiliência) e tema 12 (erros)
141
+ Implementar cache ou otimizar? → tema 11 (performance)
142
+ Escrever testes? → tema 9 (testes)
143
+ Estruturar módulos e camadas? → tema 2 (design) e tema 3 (patterns)
144
+ Depurar um problema? → tema 12 (erros e logging)
643
145
  ```
644
146
 
645
- ### Debugging e Observabilidade
646
-
647
- #### Logs estruturados (pino)
648
-
649
- ```typescript
650
- import pino from 'pino'
651
-
652
- export const logger = pino({
653
- level: process.env.LOG_LEVEL ?? 'info',
654
- ...(process.env.NODE_ENV !== 'production' && {
655
- transport: { target: 'pino-pretty' },
656
- }),
657
- })
147
+ ---
658
148
 
659
- // ✅ Logar com contexto suficiente
660
- logger.info({ userId, productId, action: 'product.updated' }, 'Produto atualizado')
661
- logger.error({ error, userId, requestId }, 'Falha ao processar pagamento')
149
+ ## Fluxo de Trabalho
662
150
 
663
- // ❌ Nunca logar dados sensíveis
664
- // logger.info({ password, creditCard }) — NUNCA
665
- ```
151
+ 1. **Entender**: ler o projeto (Padrão 1) e esclarecer o requisito, inclusive o que **não** está no escopo
152
+ 2. **Projetar**: escolher a abordagem na base universal; decidir contratos, erros e segurança antes de codar
153
+ 3. **Implementar**: seguir o padrão do projeto, em passos pequenos
154
+ 4. **Testar**: cobrir o caso feliz, os casos de erro e os limites
155
+ 5. **Validar**: percorrer o checklist de conclusão abaixo
666
156
 
667
- #### Request ID para rastreabilidade
157
+ ---
668
158
 
669
- ```typescript
670
- // ✅ Propagar request ID em todas as operações
671
- app.addHook('onRequest', (req, reply, done) => {
672
- req.id = req.headers['x-request-id'] as string ?? crypto.randomUUID()
673
- reply.header('x-request-id', req.id)
674
- done()
675
- })
676
- ```
159
+ ## Base Universal
160
+
161
+ Carregue **só o tema necessário** para a tarefa, em vez de todos de uma vez.
162
+
163
+ | # | Tema | Nível | Carregue quando |
164
+ |---|------|-------|-----------------|
165
+ | 1 | [Fundamentos de programação](references/1-fundamentos-programacao.md) | Fundamental | Precisar revisar conceitos básicos de linguagem |
166
+ | 2 | [Design e arquitetura](references/2-design-arquitetura.md) | Fundamental | Estruturar módulos, camadas ou aplicar SOLID e arquiteturas |
167
+ | 3 | [Design patterns](references/3-design-patterns.md) | Importante | Escolher um padrão para um problema recorrente |
168
+ | 4 | [Algoritmos e estruturas](references/4-algoritmos-estruturas.md) | Fundamental | Analisar complexidade ou escolher uma estrutura de dados |
169
+ | 5 | [Banco de dados](references/5-banco-dados.md) | Fundamental | Modelar dados, consultas, índices, transações e migrações |
170
+ | 6 | [API e comunicação](references/6-api-comunicacao.md) | Fundamental | Projetar endpoints, autenticação, paginação e versionamento |
171
+ | 7 | [Concorrência e assincronismo](references/7-concorrencia-async.md) | Importante | Lidar com condições de corrida, jobs e processamento assíncrono |
172
+ | 8 | [Arquitetura de servidor](references/8-arquitetura-servidor.md) | Importante | Escalar, tornar resiliente ou distribuir o sistema |
173
+ | 9 | [Testes](references/9-testes.md) | Fundamental | Definir a estratégia e a qualidade dos testes |
174
+ | 10 | [Segurança](references/10-seguranca.md) | Fundamental | Revisar vulnerabilidades, autenticação e dados sensíveis |
175
+ | 11 | [Performance](references/11-performance.md) | Importante | Medir e otimizar desempenho e cache |
176
+ | 12 | [Erros e logging](references/12-erros-logging.md) | Importante | Tratar falhas, registrar logs e observar o sistema |
177
+ | 13 | [Qualidade de código](references/13-qualidade-codigo.md) | Fundamental | Refatorar, revisar código e documentar |
677
178
 
678
179
  ---
679
180
 
680
181
  ## Regras
681
182
 
682
183
  ### Nunca
683
- - Expor stack traces ou detalhes de erro em respostas de produção
684
- - Confiar em dados de entrada sem validação (query params, body, headers)
685
- - Armazenar senhas em texto plano (usar bcrypt/argon2)
686
- - Commitar secrets, API keys ou credenciais no código
687
- - Fazer operações síncronas bloqueantes no event loop
688
- - Processar webhooks de forma síncrona (enfileirar e responder 200 imediatamente)
184
+ - Expor detalhes internos de erro em respostas de produção
185
+ - Confiar em dados de entrada sem validação (parâmetros, corpo e cabeçalhos)
186
+ - Armazenar senhas em texto plano
187
+ - Commitar segredos, chaves de API ou credenciais no código
188
+ - Fazer operações bloqueantes onde o modelo de execução não permite
189
+ - Processar webhooks de forma síncrona (enfileirar e responder rapidamente)
689
190
 
690
191
  ### Sempre
691
- - Validar e sanitizar toda entrada externa (Zod, Joi, class-validator)
192
+ - Validar e sanitizar toda entrada externa
692
193
  - Usar variáveis de ambiente para configuração
693
- - Incluir tratamento de erros e fallbacks em integrações externas
694
- - Testar casos de erro e edge cases, não só o happy path
695
- - Logar com contexto suficiente para diagnóstico
194
+ - Incluir tratamento de erros e alternativas em integrações externas
195
+ - Testar os casos de erro e os limites, não só o caso feliz
196
+ - Registrar logs com contexto suficiente para o diagnóstico
696
197
  - Ler o código existente antes de criar novas abstrações
697
198
 
698
199
  ---
699
200
 
700
201
  ## Tratamento de Erros
701
202
 
702
- ```typescript
703
- // ✅ Erro tipado com contexto
704
- export class AppError extends Error {
705
- constructor(
706
- public readonly message: string,
707
- public readonly statusCode: number = 500,
708
- public readonly code: string = 'INTERNAL_ERROR'
709
- ) {
710
- super(message)
711
- this.name = 'AppError'
712
- }
713
- }
714
-
715
- // ✅ Erros de negócio explícitos
716
- export class NotFoundError extends AppError {
717
- constructor(resource: string, id: string) {
718
- super(`${resource} com id '${id}' não encontrado`, 404, 'NOT_FOUND')
719
- }
720
- }
721
-
722
- export class UnauthorizedError extends AppError {
723
- constructor(message = 'Não autorizado') {
724
- super(message, 401, 'UNAUTHORIZED')
725
- }
726
- }
727
- ```
203
+ ### Stack ou dependência não identificada
204
+ - Procurar o manifesto de dependências e a estrutura do projeto
205
+ - Se não encontrar, perguntar à pessoa antes de prosseguir
206
+
207
+ ### Código existente com padrão diferente
208
+ - Seguir o padrão do projeto, não o genérico deste skill
209
+ - Registrar a divergência quando relevante
210
+
211
+ ### Teste falha depois de uma mudança
212
+ - Verificar se o teste já falhava antes
213
+ - Isolar a causa antes de ajustar o código ou o teste
728
214
 
729
215
  ---
730
216
 
731
217
  ## Checklist de Conclusão
732
218
 
733
- - [ ] Entrada validada (Zod / Joi / class-validator)
219
+ - [ ] Entrada validada
734
220
  - [ ] Autenticação e autorização verificadas
735
- - [ ] Erros tipados e tratados (não vazar detalhes em produção)
221
+ - [ ] Erros tipados e tratados, sem vazar detalhes em produção
736
222
  - [ ] Logs estruturados com contexto adequado
737
- - [ ] Testes unitários e/ou de integração
738
- - [ ] Rate limiting considerado (se endpoint público)
739
- - [ ] Cache implementado onde faz sentido
740
- - [ ] Operações destrutivas com confirmação/idempotência
223
+ - [ ] Testes cobrindo o caso feliz, os erros e os limites
224
+ - [ ] Limitação de taxa considerada (se o endpoint for público)
225
+ - [ ] Cache aplicado onde faz sentido
226
+ - [ ] Operações destrutivas com confirmação ou idempotência
741
227
 
742
228
  ---
743
229
 
@@ -746,9 +232,9 @@ export class UnauthorizedError extends AppError {
746
232
  | Artefato | Descrição |
747
233
  |----------|-----------|
748
234
  | Endpoint(s) | Rota com validação, autenticação e tratamento de erro |
749
- | Service/Use case | Lógica de negócio isolada e testável |
750
- | Worker/Job | Processamento assíncrono com retry e observabilidade |
751
- | Testes | Unitários e/ou integração cobrindo happy path e erros |
235
+ | Serviço ou caso de uso | Lógica de negócio isolada e testável |
236
+ | Worker ou job | Processamento assíncrono com repetição e observabilidade |
237
+ | Testes | Cobrindo o caso feliz e os erros |
752
238
 
753
239
  ---
754
240
 
@@ -757,20 +243,32 @@ export class UnauthorizedError extends AppError {
757
243
  ```
758
244
  Implementação backend concluída!
759
245
 
760
- Framework: NestJS
761
- ORM: {Prisma / TypeORM / Drizzle}
762
246
  Funcionalidade: {descrição do que foi implementado}
247
+ Stack do projeto: {linguagem e framework identificados no código}
763
248
 
764
249
  Segurança: {validação de entrada / autenticação / autorização}
765
250
  Testes: {criados / pendentes}
766
251
  Cache: {implementado / não necessário}
767
252
 
768
- Próximo passo: {rodar testes / fazer deploy / integrar com frontend}
253
+ Próximo passo: {rodar os testes / integrar / publicar}
254
+ ```
255
+
256
+ ---
257
+
258
+ ## Aviso: uso só da skill base
259
+
260
+ Quando o trabalho usar **só a skill base** e envolver uma tecnologia, framework ou ferramenta para a qual **não há skill especializado** disponível, avise a pessoa de forma explícita:
261
+
262
+ ```
263
+ ℹ️ Estou usando só a skill base de backend.
264
+ Não há skill especializado para {tecnologia}; vou seguir os princípios universais
265
+ e o padrão que encontrei no projeto.
769
266
  ```
770
267
 
268
+ Não invente convenções nem comandos específicos da tecnologia: siga o código do projeto e a base universal.
269
+
771
270
  ---
772
271
 
773
272
  ## Recursos Adicionais
774
273
 
775
- - **RabbitMQ**: Ver skill `eng-rabbitmq` para operações avançadas de mensageria
776
- - **Referências**: Veja [references/](references/) para links de documentação local
274
+ - **Base universal**: os 13 temas em [references/](references/)