@evertonferreira96/agents 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/.claude/agents/api.md +45 -0
  2. package/.claude/agents/app.md +41 -0
  3. package/.claude/agents/architect.md +49 -0
  4. package/.claude/agents/infra.md +27 -0
  5. package/.claude/agents/product.md +58 -0
  6. package/.claude/agents/quick.md +33 -0
  7. package/.claude/agents/security.md +39 -0
  8. package/.claude/agents/ui.md +54 -0
  9. package/.claude/agents/verifier.md +56 -0
  10. package/.claude/agents/web.md +41 -0
  11. package/.claude/hooks/config-update-check.mjs +14 -0
  12. package/.claude/hooks/context-budget.mjs +51 -0
  13. package/.claude/hooks/graphify-update.sh +16 -0
  14. package/.claude/hooks/guard-bash.sh +64 -0
  15. package/.claude/hooks/orchestrator-guard.sh +49 -0
  16. package/.claude/hooks/post-compact.sh +26 -0
  17. package/.claude/hooks/readonly-guard.sh +54 -0
  18. package/.claude/hooks/stop-verify.sh +52 -0
  19. package/.claude/rules/api.md +21 -0
  20. package/.claude/rules/db.md +9 -0
  21. package/.claude/rules/delivery-diagram.md +16 -0
  22. package/.claude/rules/git-workflow.md +34 -0
  23. package/.claude/rules/graphify.md +3 -0
  24. package/.claude/rules/mobile.md +22 -0
  25. package/.claude/rules/tickets.md +9 -0
  26. package/.claude/rules/ui.md +14 -0
  27. package/.claude/rules/web.md +27 -0
  28. package/.claude/settings.json +114 -0
  29. package/.claude/skills/animate/RECIPES.md +324 -0
  30. package/.claude/skills/animate/SKILL.md +208 -0
  31. package/.claude/skills/animate/agents/openai.yaml +5 -0
  32. package/.claude/skills/animate-expo/RECIPES.md +385 -0
  33. package/.claude/skills/animate-expo/SKILL.md +264 -0
  34. package/.claude/skills/animate-expo/agents/openai.yaml +5 -0
  35. package/.claude/skills/animation-performance/SKILL.md +223 -0
  36. package/.claude/skills/animation-performance/agents/openai.yaml +5 -0
  37. package/.claude/skills/apple-design/SKILL.md +291 -0
  38. package/.claude/skills/apple-design/agents/openai.yaml +5 -0
  39. package/.claude/skills/arch-api/SKILL.md +291 -0
  40. package/.claude/skills/arch-api/agents/openai.yaml +3 -0
  41. package/.claude/skills/arch-api/references/common.md +174 -0
  42. package/.claude/skills/arch-api/references/contract.md +289 -0
  43. package/.claude/skills/arch-api/references/domain.md +301 -0
  44. package/.claude/skills/arch-api/references/endpoints.md +184 -0
  45. package/.claude/skills/arch-api/references/review.md +228 -0
  46. package/.claude/skills/arch-api/references/security.md +151 -0
  47. package/.claude/skills/arch-app/SKILL.md +278 -0
  48. package/.claude/skills/arch-app/agents/openai.yaml +3 -0
  49. package/.claude/skills/arch-app/references/navigation-session.md +257 -0
  50. package/.claude/skills/arch-app/references/review.md +155 -0
  51. package/.claude/skills/arch-app/references/screens.md +214 -0
  52. package/.claude/skills/arch-app/references/services.md +301 -0
  53. package/.claude/skills/arch-app/references/ui-mobile.md +124 -0
  54. package/.claude/skills/arch-db/SKILL.md +181 -0
  55. package/.claude/skills/arch-db/agents/openai.yaml +3 -0
  56. package/.claude/skills/arch-db/references/indexes-queries.md +251 -0
  57. package/.claude/skills/arch-db/references/migrations.md +191 -0
  58. package/.claude/skills/arch-db/references/modeling.md +214 -0
  59. package/.claude/skills/arch-db/references/mysql.md +262 -0
  60. package/.claude/skills/arch-db/references/pooling-ops.md +112 -0
  61. package/.claude/skills/arch-db/references/review.md +143 -0
  62. package/.claude/skills/arch-db/references/transactions-locks.md +141 -0
  63. package/.claude/skills/arch-web/SKILL.md +307 -0
  64. package/.claude/skills/arch-web/agents/openai.yaml +3 -0
  65. package/.claude/skills/arch-web/references/auth-session-env.md +165 -0
  66. package/.claude/skills/arch-web/references/blocks.md +198 -0
  67. package/.claude/skills/arch-web/references/cache.md +124 -0
  68. package/.claude/skills/arch-web/references/review.md +142 -0
  69. package/.claude/skills/arch-web/references/services.md +297 -0
  70. package/.claude/skills/arch-web/references/tests.md +159 -0
  71. package/.claude/skills/arch-web/references/ui-forms.md +143 -0
  72. package/.claude/skills/break-ui/CATALOG.md +135 -0
  73. package/.claude/skills/break-ui/SKILL.md +176 -0
  74. package/.claude/skills/break-ui/agents/openai.yaml +5 -0
  75. package/.claude/skills/brief/SKILL.md +91 -0
  76. package/.claude/skills/brief/agents/openai.yaml +3 -0
  77. package/.claude/skills/diagnosing-bugs/SKILL.md +138 -0
  78. package/.claude/skills/diagnosing-bugs/agents/openai.yaml +3 -0
  79. package/.claude/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +44 -0
  80. package/.claude/skills/emil-design-eng/SKILL.md +675 -0
  81. package/.claude/skills/emil-design-eng/agents/openai.yaml +5 -0
  82. package/.claude/skills/find-animation-opportunities/SKILL.md +141 -0
  83. package/.claude/skills/find-animation-opportunities/agents/openai.yaml +5 -0
  84. package/.claude/skills/graphify/.graphify_version +1 -0
  85. package/.claude/skills/graphify/SKILL.md +742 -0
  86. package/.claude/skills/graphify/agents/openai.yaml +3 -0
  87. package/.claude/skills/graphify/references/add-watch.md +56 -0
  88. package/.claude/skills/graphify/references/exports.md +91 -0
  89. package/.claude/skills/graphify/references/extraction-spec.md +70 -0
  90. package/.claude/skills/graphify/references/github-and-merge.md +46 -0
  91. package/.claude/skills/graphify/references/hooks.md +33 -0
  92. package/.claude/skills/graphify/references/query.md +317 -0
  93. package/.claude/skills/graphify/references/transcribe.md +52 -0
  94. package/.claude/skills/graphify/references/update.md +221 -0
  95. package/.claude/skills/grill-me/SKILL.md +7 -0
  96. package/.claude/skills/grill-me/agents/openai.yaml +5 -0
  97. package/.claude/skills/grill-with-docs/SKILL.md +64 -0
  98. package/.claude/skills/grill-with-docs/agents/openai.yaml +5 -0
  99. package/.claude/skills/grilling/SKILL.md +30 -0
  100. package/.claude/skills/grilling/agents/openai.yaml +3 -0
  101. package/.claude/skills/handoff/SKILL.md +28 -0
  102. package/.claude/skills/handoff/agents/openai.yaml +5 -0
  103. package/.claude/skills/impeccable/SKILL.md +89 -0
  104. package/.claude/skills/impeccable/agents/openai.yaml +5 -0
  105. package/.claude/skills/impeccable/reference/adapt.md +318 -0
  106. package/.claude/skills/impeccable/reference/adapt.native.md +58 -0
  107. package/.claude/skills/impeccable/reference/android.md +46 -0
  108. package/.claude/skills/impeccable/reference/animate.md +89 -0
  109. package/.claude/skills/impeccable/reference/audit.md +137 -0
  110. package/.claude/skills/impeccable/reference/audit.native.md +139 -0
  111. package/.claude/skills/impeccable/reference/bolder.md +33 -0
  112. package/.claude/skills/impeccable/reference/clarify.md +94 -0
  113. package/.claude/skills/impeccable/reference/colorize.md +86 -0
  114. package/.claude/skills/impeccable/reference/component-review.md +63 -0
  115. package/.claude/skills/impeccable/reference/craft-floor.md +44 -0
  116. package/.claude/skills/impeccable/reference/craft.md +5 -0
  117. package/.claude/skills/impeccable/reference/critique.md +809 -0
  118. package/.claude/skills/impeccable/reference/degraded/asset-producer.md +42 -0
  119. package/.claude/skills/impeccable/reference/degraded/documenter.md +24 -0
  120. package/.claude/skills/impeccable/reference/degraded/finish-reviewer.md +38 -0
  121. package/.claude/skills/impeccable/reference/degraded/manual-edit-applier.md +92 -0
  122. package/.claude/skills/impeccable/reference/delight.md +70 -0
  123. package/.claude/skills/impeccable/reference/distill.md +111 -0
  124. package/.claude/skills/impeccable/reference/doctor.md +54 -0
  125. package/.claude/skills/impeccable/reference/document.md +416 -0
  126. package/.claude/skills/impeccable/reference/extract.md +69 -0
  127. package/.claude/skills/impeccable/reference/generate.md +101 -0
  128. package/.claude/skills/impeccable/reference/harden.md +345 -0
  129. package/.claude/skills/impeccable/reference/hooks.md +113 -0
  130. package/.claude/skills/impeccable/reference/init.md +131 -0
  131. package/.claude/skills/impeccable/reference/ios.md +51 -0
  132. package/.claude/skills/impeccable/reference/layout.md +84 -0
  133. package/.claude/skills/impeccable/reference/live-setup.md +104 -0
  134. package/.claude/skills/impeccable/reference/live.md +325 -0
  135. package/.claude/skills/impeccable/reference/mode-operate.md +21 -0
  136. package/.claude/skills/impeccable/reference/mode-persuade.md +19 -0
  137. package/.claude/skills/impeccable/reference/mode-read.md +21 -0
  138. package/.claude/skills/impeccable/reference/new-work.md +154 -0
  139. package/.claude/skills/impeccable/reference/onboard.md +234 -0
  140. package/.claude/skills/impeccable/reference/operate.md +61 -0
  141. package/.claude/skills/impeccable/reference/optimize.md +258 -0
  142. package/.claude/skills/impeccable/reference/overdrive.md +127 -0
  143. package/.claude/skills/impeccable/reference/polish.md +105 -0
  144. package/.claude/skills/impeccable/reference/quieter.md +99 -0
  145. package/.claude/skills/impeccable/reference/region-map.md +26 -0
  146. package/.claude/skills/impeccable/reference/routing.md +24 -0
  147. package/.claude/skills/impeccable/reference/shape.md +59 -0
  148. package/.claude/skills/impeccable/reference/typeset.md +80 -0
  149. package/.claude/skills/impeccable/reference/visualize.md +47 -0
  150. package/.claude/skills/impeccable/scripts/VERSION +1 -0
  151. package/.claude/skills/impeccable/scripts/command-metadata.json +98 -0
  152. package/.claude/skills/impeccable/scripts/data/font-index-failures.json +121 -0
  153. package/.claude/skills/impeccable/scripts/data/font-index.json +1 -0
  154. package/.claude/skills/impeccable/scripts/impeccable +206 -0
  155. package/.claude/skills/impeccable/scripts/impeccable.cmd +214 -0
  156. package/.claude/skills/impeccable/scripts/live-browser-dom.js +281 -0
  157. package/.claude/skills/impeccable/scripts/live-browser-ignores.js +242 -0
  158. package/.claude/skills/impeccable/scripts/live-browser-session.js +148 -0
  159. package/.claude/skills/impeccable/scripts/live-browser.js +13532 -0
  160. package/.claude/skills/impeccable/scripts/modern-screenshot.umd.js +14 -0
  161. package/.claude/skills/improve-animations/AUDIT.md +115 -0
  162. package/.claude/skills/improve-animations/PLAN-TEMPLATE.md +73 -0
  163. package/.claude/skills/improve-animations/SKILL.md +110 -0
  164. package/.claude/skills/improve-animations/agents/openai.yaml +5 -0
  165. package/.claude/skills/mobile-native/SKILL.md +311 -0
  166. package/.claude/skills/mobile-native/agents/openai.yaml +3 -0
  167. package/.claude/skills/orchestrate/SKILL.md +181 -0
  168. package/.claude/skills/orchestrate/agents/openai.yaml +3 -0
  169. package/.claude/skills/pick-ui-library/SKILL.md +85 -0
  170. package/.claude/skills/pick-ui-library/agents/openai.yaml +5 -0
  171. package/.claude/skills/ponytail/SKILL.md +52 -0
  172. package/.claude/skills/ponytail/agents/openai.yaml +3 -0
  173. package/.claude/skills/ponytail-audit/SKILL.md +103 -0
  174. package/.claude/skills/ponytail-audit/agents/openai.yaml +3 -0
  175. package/.claude/skills/ponytail-debt/SKILL.md +44 -0
  176. package/.claude/skills/ponytail-debt/agents/openai.yaml +3 -0
  177. package/.claude/skills/ponytail-review/SKILL.md +101 -0
  178. package/.claude/skills/ponytail-review/agents/openai.yaml +3 -0
  179. package/.claude/skills/postgres-best-practices/SKILL.md +42 -0
  180. package/.claude/skills/postgres-best-practices/agents/openai.yaml +3 -0
  181. package/.claude/skills/postgres-best-practices/references/backup-restore.md +372 -0
  182. package/.claude/skills/postgres-best-practices/references/bulk-loading.md +315 -0
  183. package/.claude/skills/postgres-best-practices/references/connection-pooling.md +310 -0
  184. package/.claude/skills/postgres-best-practices/references/hot-standby.md +221 -0
  185. package/.claude/skills/postgres-best-practices/references/indexing.md +318 -0
  186. package/.claude/skills/postgres-best-practices/references/logical-replication.md +610 -0
  187. package/.claude/skills/postgres-best-practices/references/major-version-upgrades.md +334 -0
  188. package/.claude/skills/postgres-best-practices/references/performance-diagnostics.md +553 -0
  189. package/.claude/skills/postgres-best-practices/references/query-optimization.md +294 -0
  190. package/.claude/skills/postgres-best-practices/references/query-patterns.md +566 -0
  191. package/.claude/skills/postgres-best-practices/references/schema-design.md +362 -0
  192. package/.claude/skills/postgres-best-practices/references/security-roles.md +489 -0
  193. package/.claude/skills/postgres-best-practices/references/transaction-isolation.md +344 -0
  194. package/.claude/skills/project-docs/SKILL.md +330 -0
  195. package/.claude/skills/project-docs/agents/openai.yaml +3 -0
  196. package/.claude/skills/prototype/PICKER.md +197 -0
  197. package/.claude/skills/prototype/SKILL.md +98 -0
  198. package/.claude/skills/prototype/agents/openai.yaml +5 -0
  199. package/.claude/skills/retro/SKILL.md +43 -0
  200. package/.claude/skills/retro/agents/openai.yaml +5 -0
  201. package/.claude/skills/review/SKILL.md +74 -0
  202. package/.claude/skills/review/agents/openai.yaml +3 -0
  203. package/.claude/skills/review/references/smells.md +23 -0
  204. package/.claude/skills/review-animations/SKILL.md +120 -0
  205. package/.claude/skills/review-animations/STANDARDS.md +187 -0
  206. package/.claude/skills/review-animations/agents/openai.yaml +5 -0
  207. package/.claude/skills/tdd/SKILL.md +38 -0
  208. package/.claude/skills/tdd/agents/openai.yaml +3 -0
  209. package/.claude/skills/tdd/mocking.md +59 -0
  210. package/.claude/skills/tdd/tests.md +77 -0
  211. package/.claude/skills/triage/SKILL.md +58 -0
  212. package/.claude/skills/triage/agents/openai.yaml +3 -0
  213. package/.claude/skills/ui-ux-pro-max/SKILL.md +378 -0
  214. package/.claude/skills/ui-ux-pro-max/agents/openai.yaml +5 -0
  215. package/.claude/skills/ui-ux-pro-max/data/charts.csv +26 -0
  216. package/.claude/skills/ui-ux-pro-max/data/colors.csv +97 -0
  217. package/.claude/skills/ui-ux-pro-max/data/icons.csv +101 -0
  218. package/.claude/skills/ui-ux-pro-max/data/landing.csv +31 -0
  219. package/.claude/skills/ui-ux-pro-max/data/products.csv +97 -0
  220. package/.claude/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  221. package/.claude/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  222. package/.claude/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  223. package/.claude/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  224. package/.claude/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  225. package/.claude/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  226. package/.claude/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  227. package/.claude/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  228. package/.claude/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  229. package/.claude/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  230. package/.claude/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  231. package/.claude/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  232. package/.claude/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  233. package/.claude/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  234. package/.claude/skills/ui-ux-pro-max/data/styles.csv +68 -0
  235. package/.claude/skills/ui-ux-pro-max/data/typography.csv +58 -0
  236. package/.claude/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  237. package/.claude/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  238. package/.claude/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  239. package/.claude/skills/ui-ux-pro-max/scripts/core.py +253 -0
  240. package/.claude/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
  241. package/.claude/skills/ui-ux-pro-max/scripts/search.py +114 -0
  242. package/.claude/skills/writing-for-agents/SKILL-MECHANICS.md +22 -0
  243. package/.claude/skills/writing-for-agents/SKILL.md +81 -0
  244. package/.claude/skills/writing-for-agents/agents/openai.yaml +3 -0
  245. package/.worktreeinclude +3 -0
  246. package/AGENTS.md +44 -0
  247. package/README.md +14 -2
  248. package/VERSION +1 -0
  249. package/bin/agents.mjs +45 -0
  250. package/docs/adr/README.md +31 -0
  251. package/docs/brief-template.md +3 -0
  252. package/docs/plans/README.md +73 -0
  253. package/package.json +46 -4
  254. package/scripts/bootstrap.mjs +188 -0
  255. package/scripts/check-catalog.mjs +43 -0
  256. package/scripts/skills-update.mjs +51 -0
  257. package/skills-lock.json +269 -0
  258. package/templates/CLAUDE.project.md +41 -0
@@ -0,0 +1,291 @@
1
+ ---
2
+ name: arch-api
3
+ description: Implementa, revisa e refatora APIs NestJS contract-first - contrato OpenAPI por caso de uso em `props.surface` e controller fino em `exec.surface`, schemas Zod nomeados em `entities`, um service por caso de uso com `execute`, regras puras, autorização por recurso no arquivo de access do domínio, mapper e erros com `code` estável, port e adapter por domínio, módulos `surface` e `sgbds` por domínio, capacidades técnicas em `common`, em geral atrás de port e adapter, `openapi.json` gerado que alimenta os clients, paginação, idempotência, segurança, observabilidade e testes. Use ao criar ou revisar endpoints, surfaces, services, módulos, ports, adapters, repositórios, guards, decorators, env, erros ou o `openapi.json` de qualquer API NestJS. Para schema, SQL, índices e migrations no nível do banco, carregue `arch-db`. Não use para o web Next.js (`arch-web`) nem para o app React Native (`arch-app`).
4
+ ---
5
+
6
+ # Arquitetura de API NestJS contract-first
7
+
8
+ ```text
9
+ Fonte única: o props.surface declara path, verbo, status, security e schemas; o resto consome ou copia.
10
+ O exec.surface é fino: guards, pipes Zd* e um service.execute.
11
+ Um caso de uso por arquivo: <Acao>Service.execute decide; rules são puras; access autoriza o recurso.
12
+ O port abstrai com tipos escritos à mão; o adapter executa, abre a transação e traduz o erro do banco.
13
+ Capacidade técnica mora em common/<capacidade>, em geral atrás de um port; o banco, no módulo global de banco.
14
+ O openapi.json gerado é o contrato dos clients; geração, typecheck e testes quebram quando algo diverge.
15
+ ```
16
+
17
+ A skill descreve o padrão com nomes genéricos (`invoices`, `customers`, `<domain>`, `<acao>`). Nomes de pasta, scripts, decorators e helpers vêm do repo: faça o inventário antes. Onde o repo divergir, siga o repo e proponha migração em ondas (`references/review.md` §3). ADRs do repo vencem a skill.
18
+
19
+ | Abra quando for | Reference |
20
+ |---|---|
21
+ | escrever ou revisar `props`/`exec`, decorators de contexto, erros no contrato, paginação, nomes de schema, registry, versionamento, paridade | [`references/contract.md`](references/contract.md) |
22
+ | escrever service, rules, access, mapper, errors, port, adapter, SQL do adapter, módulos `sgbds`/`surface`, worker, outbox, idempotência | [`references/domain.md`](references/domain.md) |
23
+ | criar ou usar uma capacidade em `common/` (mailer, storage, hash, env, docs, observability, utils, bootstrap) | [`references/common.md`](references/common.md) |
24
+ | mexer em auth, guards, rate limit, tenant, formato de erro, logs, resiliência ou revisar OWASP | [`references/security.md`](references/security.md) |
25
+ | escolher o formato de um endpoint ou conferir o checklist dele | [`references/endpoints.md`](references/endpoints.md) |
26
+ | escrever testes, abrir domínio novo, planejar migração, ADR, scorecard de PR | [`references/review.md`](references/review.md) |
27
+ | tocar schema, SQL, índice, migration, seed, lock ou pool | skill `arch-db` (vence esta no nível do banco) |
28
+
29
+ ---
30
+
31
+ ## Antes de editar
32
+
33
+ Inventário (o que o repo já tem vence o que esta skill sugere):
34
+
35
+ ```txt
36
+ <pm> e monorepo (<pm> --filter <app> <script>); versões do Nest e do Zod; aliases (@/)
37
+ ORM e driver; nome e exports do módulo global de banco (na referência: common/sgbds)
38
+ padrão de surfaces (props/exec planos em surfaces/) e scaffold de domínio (scripts/*.mjs), se houver
39
+ decorators Zd*, AuthUser e de contexto; guards de auth e de rate limit
40
+ exceções de domínio (common/http/errors), formato de erro e envelope (common/schemas)
41
+ registry OpenAPI, script de geração, onde ficam o openapi.json e o client gerado
42
+ policy service de permissões que os arquivos <domain>-access chamam
43
+ ferramenta de migration e runner de seed; runner de teste, configs e <domain>.fixtures-spec.ts
44
+ scripts reais do package.json (o README pode estar desatualizado; o package.json vence)
45
+ ```
46
+
47
+ 1. **Leia o vizinho.** Abra um domínio maduro (com `doc.md`, `*-access.ts` e specs) e copie a forma dele. Critério: o arquivo novo tem os mesmos imports, sufixos e ordem de blocos do vizinho.
48
+ 2. **O helper já existe?** Paginação, erros, decorators, exceções, utils e capacidades de `common/` vêm antes de criar. Critério: nenhum helper novo duplica um de `common/`.
49
+ 3. **De onde vem o `.openapi()`?** O repo estende o `z` uma vez num módulo de setup carregado no boot (na referência, o `main.ts` importa `common/schemas/setup`, e os props importam `z` de `'zod'`). Todo ponto de entrada que carrega props sem passar pelo `main.ts` (script de geração, setup do runner de teste) precisa importar esse módulo antes, senão quebra com `.openapi is not a function`. Critério: o import do `z` segue o do vizinho e o `openapi:generate` roda.
50
+ 4. **Vai tocar tabela, SQL, índice ou migration?** Carregue `arch-db` antes de escrever. Critério: a migration segue a ferramenta e o formato das vizinhas.
51
+ 5. **Terminou?** Rode geração do OpenAPI, typecheck, lint e testes. Critério: os quatro passam e o diff do `openapi.json` contém só as operações que você mudou.
52
+
53
+ Se algo não existir, proponha criação incremental e localizada; não invente dependência global.
54
+
55
+ ---
56
+
57
+ ## Mapa
58
+
59
+ ```txt
60
+ src/
61
+ common/
62
+ server/ app.module.ts main.ts
63
+ <capacidade>/ com port e adapter: hash, mailer, encrypters, storage, messaging, resilience, secrets, html
64
+ ports/<capacidade>.<papel>.port.ts adapters/<tecnologia>.<capacidade>.<papel>.adapter.ts <capacidade>.module.ts
65
+ service concreto: cache, queue
66
+ forma própria: auth, environments (port + provider), realtime (port + gateway)
67
+ decorators/ guards/ policies/ HTTP transversal: contexto, autenticação, ownership
68
+ docs/openapi/ registries.docs.ts response.docs.ts build.ts generate.ts
69
+ http/ enums/ errors/
70
+ observability/ interceptor de correlação, filter de exceções, logger estruturado
71
+ prototypes/ extensões globais importadas no boot
72
+ schemas/ paginations.ts errors.ts setup.ts (só cross-domain)
73
+ sgbds/ containers/ ports/ adapters/<orm>/ settings/ migrations/ seeds/ generated/ (conteúdo: arch-db)
74
+ surfaces/ surface.module.ts (agrega todos os <domain>.surface.module.ts)
75
+ utils/<tipo>/ <nome>.<tipo>.util.ts (maioria; siga o vizinho da pasta), teste *.unit.spec.ts
76
+ modules/<domain>/
77
+ <domain>.surface.module.ts controllers (exec) + providers (services); importa <Domain>SgbdsModule e os de quem depende
78
+ <domain>.sgbds.module.ts { provide: <Domain>RepositoryPort, useClass: <Tecnologia><Domain>RepositoryAdapter }; exporta o port
79
+ doc.md visão, tabela endpoint x rota x permissão, autorização, regras, escrita, persistência, pendências
80
+ entities/<domain>.entities.ts schemas Zod nomeados (.openapi('Name')) e tipos do domínio
81
+ ports/<domain>.repository.port.ts classe abstrata + tipos Row/Record/New/Write escritos à mão
82
+ adapters/<tecnologia>.<domain>.repository.adapter.ts (+ .spec.ts)
83
+ adapters/<domain>.sql.ts SQL cru montado por funções puras (leituras quentes)
84
+ adapters/<domain>-db-errors.ts constraint/trigger -> exceção de domínio com code
85
+ services/<acao>.service.ts (+ .spec.ts) um caso de uso por arquivo: <Acao>Service.execute(input)
86
+ services/<assunto>.rules.ts (+ .spec.ts) regra pura
87
+ services/<domain>-access.ts (+ .spec.ts) autorização por recurso (a policy do domínio)
88
+ services/<domain>.mapper.ts Row -> resposta do contrato (datas ISO)
89
+ services/<domain>-errors.ts fábricas de exceção com code (na referência, nome no singular do recurso)
90
+ services/*.resolver.ts | *-context.ts | *.helpers.ts | <domain>.fixtures-spec.ts
91
+ surfaces/<acao>.<domain>.props.surface.ts contrato OpenAPI: registerPath + instructions + Instruction
92
+ surfaces/<acao>.<domain>.exec.surface.ts controller fino: guards, Zd*, service.execute
93
+ <assunto>.worker.ts consumidor de fila do domínio (quando há)
94
+ test/e2e/*.e2e.spec.ts libraries/test/ (configs do runner) openapi.json generated/openapi-client.d.ts
95
+ ```
96
+
97
+ O nome `sgbds` é do repo de referência; se o seu chama o módulo de banco de `database`, `db` ou `prisma`, troque o nome e mantenha os papéis. Pastas que o repo não usa (`dtos/`, `policies/` e `mappers/` dentro do módulo) não nascem por causa desta skill.
98
+
99
+ Colocação:
100
+
101
+ - Schema de domínio nasce em `entities/` do módulo dono; `common/schemas` guarda só o que dois ou mais domínios usam (paginação, erros, entidades compartilhadas).
102
+ - Um domínio usa outro importando, no seu `surface.module`, o módulo que exporta o port ou o service (`<Other>SgbdsModule`); o import TypeScript da classe é só o token de DI.
103
+ - Capacidade técnica nova é uma pasta `common/<capacidade>/` com port, adapter e módulo (receita em `references/common.md` §2).
104
+ - Regra repetida por vários services do domínio vira `*.rules.ts` (pura); leitura repetida (carregar e serializar o detalhe, conferir referências) vira função em `<domain>-context.ts`; resolução do recurso pai com 404 vira `<x>.resolver.ts` injetável.
105
+ - Ownership transversal (dono do recurso = ator) mora em `common/policies`; autorização por recurso do domínio mora em `<domain>-access.ts`.
106
+
107
+ ---
108
+
109
+ ## Camadas
110
+
111
+ | Peça | Responsabilidade | Depende de |
112
+ |---|---|---|
113
+ | `props.surface` | contrato: constantes, schemas registrados, `registerPath`, `instructions`, `Instruction` | `z`, `entities`, `common/docs`, `common/schemas`, `common/http/enums` |
114
+ | `exec.surface` | rota, guards, status, pipes, um `execute` | o props, o service, `common/decorators`, `common/guards`, `common/http/enums` |
115
+ | `<acao>.service` | o caso de uso: resolve, autoriza, decide, grava, devolve o contrato | port, rules, access, mapper, errors, entities, `common/http/errors`; o que outros módulos exportam |
116
+ | `*.rules` | regra pura com teste | entities, `common/http/errors` |
117
+ | `<domain>-access` | permissão, tenant, ownership, estado e visibilidade do recurso | policy service de permissões, `common/auth`, `common/http/errors`, tipos do port |
118
+ | `<domain>.mapper` | `*Row` -> schema de resposta | tipos de entities e do port, access (`can`), rules |
119
+ | `<domain>-errors` | fábricas de exceção com `code` | `common/http/errors` |
120
+ | `entities` | schemas Zod nomeados reutilizados por props, service e mapper | `z` |
121
+ | port | assinaturas e tipos escritos à mão | `import type` (regra 10) |
122
+ | adapter (+ `.sql`, `-db-errors`) | leitura, escrita, transação, tradução de constraint | port, módulo global de banco, errors e rules do domínio, `common/utils` |
123
+ | `<domain>.sgbds.module` | liga port -> adapter e exporta o port | port, adapter |
124
+ | `<domain>.surface.module` | controllers, providers, módulos importados, registro dos props | exec, services, `SgbdsModule`s, props por efeito colateral |
125
+ | `doc.md` | documentação viva do domínio | - |
126
+ | `common/<capacidade>` | capacidade técnica, em geral atrás de port (forma de cada uma no Mapa) | SDK da tecnologia, env provider |
127
+ | `common/sgbds` (módulo global de banco) | exporta os clientes de banco, traduz erro genérico, guarda migrations e seeds | ORM e driver |
128
+
129
+ ---
130
+
131
+ ## Nomes
132
+
133
+ | Arquivo | Exporta |
134
+ |---|---|
135
+ | `surfaces/<acao>.<domain>.props.surface.ts` | `instructions` e `namespace Instruction` (`Params`, `Query`, `Request`, `Response`) |
136
+ | `surfaces/<acao>.<domain>.exec.surface.ts` | `<Acao>Surface` com método `exec` |
137
+ | `services/<acao>.service.ts` | `<Acao>Service` com `execute(input)`; `<acao>` em kebab do `operationId` |
138
+ | `services/<assunto>.rules.ts` | funções puras e constantes |
139
+ | `services/<domain>-access.ts` | `<DOMAIN>_ACTIONS`, `assertCan*`, `can`, `viewerOf` |
140
+ | `services/<domain>.mapper.ts` | `serialize<Coisa>(row)` |
141
+ | `services/<domain>-errors.ts` (na referência, nome no singular do recurso) | fábricas como `stale<Coisa>()` |
142
+ | `entities/<domain>.entities.ts` | `<coisa>Schema` e `type <Coisa> = z.infer<...>` |
143
+ | `ports/<domain>.repository.port.ts` | `<Domain>RepositoryPort` e tipos `<Coisa>Row`, `<Coisa>Record`, `New<Coisa>`, `<Coisa>Write` |
144
+ | `adapters/<tecnologia>.<domain>.repository.adapter.ts` | `<Tecnologia><Domain>RepositoryAdapter` |
145
+ | `adapters/<domain>.sql.ts` | `build<Coisa>Query(...)` -> `{ text, values }`, constantes `*_SQL`, mapa `*_SORT` |
146
+ | `adapters/<domain>-db-errors.ts` | `rethrow<Domain>DbError` |
147
+ | `ports/<x>.provider.port.ts` / `adapters/<tecnologia>.<x>.provider.adapter.ts` | `I<X>Provider` / `<Tecnologia><X>ProviderAdapter` (integração externa do domínio) |
148
+ | `<domain>.sgbds.module.ts` / `<domain>.surface.module.ts` | `<Domain>SgbdsModule` / `<Domain>SurfaceModule` |
149
+ | `<assunto>.worker.ts` | consumidor de fila do domínio |
150
+ | `common/utils/<tipo>/<nome>.<tipo>.util.ts` (maioria; siga o vizinho da pasta), teste `*.unit.spec.ts` | helper puro, reexportado pelo `index.ts` da pasta |
151
+ | specs | `*.spec.ts` ao lado do arquivo; `*.unit.spec.ts` em utils; `<domain>.fixtures-spec.ts`; `test/e2e/*.e2e.spec.ts` |
152
+
153
+ ---
154
+
155
+ ## O caminho de uma request
156
+
157
+ ```txt
158
+ guards AuthUserGuard (se o props declara security); guard de rate limit do repo em rota sensível
159
+ interceptor correlação: traceId do header ou novo; envolve pipes + handler e loga o desfecho
160
+ pipes ZdParam / ZdQuery / ZdBody com instructions.settings.request.*
161
+ exec.surface this.service.execute({ actorId: user.id, ...params, ...query, ...body })
162
+ service resolve o recurso -> assert* do <domain>-access -> rules -> port
163
+ adapter leitura: driver + <domain>.sql.ts | escrita: ORM em transação; <domain>-db-errors traduz
164
+ mapper *Row -> resposta do contrato (datas ISO), devolvida pelo service
165
+ erro a exceção de domínio carrega o corpo (shape de common/schemas/errors.ts); a causa técnica vai só para o log
166
+ ```
167
+
168
+ ---
169
+
170
+ ## Regras não negociáveis
171
+
172
+ 1. **Fonte única.** `Method`, `Endpoint`, `OperationId`, `Tags`, `security`, status e schemas vivem no `props.surface`. O `exec` usa `@Controller()` e repete no decorator do verbo o `Endpoint` literal sem a barra inicial (é o que o scaffold gera); ao renomear rota, mude os dois no mesmo commit. A checagem de paridade rota x documento do repo confere, se existir; senão, o e2e da rota é a trava. Pipes e tipos vêm de `instructions` e `Instruction.*`, nunca escritos à mão.
173
+ 2. **`exec` fino.** Guards, `@HttpCode(http.status.*)`, `Zd*` com o schema do contrato e uma chamada a `execute`. Nada de regra, SQL, token, hash, transação, try/catch ou chamada externa.
174
+ 3. **Service recebe contexto extraído** (`actorId`, ref de tenant, IP, `traceId`), nunca `Request`, headers ou objeto do Nest. O `type Input` do service é escrito à mão e espelha o que o `exec` espalha.
175
+ 4. **`.strict()` em todo params, query e body.** É o que torna seguro o spread no `exec`: campo extra vira 400 antes do service. O adapter grava campo a campo a partir de `New<Coisa>`/`<Coisa>Write`; nenhum método recebe o body cru.
176
+ 5. **Schema que vira tipo no client tem nome**: `.openapi('<Nome>')` mais `openapi.register('<Nome>', schema)` no props; schemas de domínio nomeados em `entities/`.
177
+ 6. **Datas no JSON são string ISO** (`z.string().datetime()`); `Date` vira ISO no mapper.
178
+ 7. **Erros declarados onde ocorrem.** `...docs.response` (400/401/403/404) em todo endpoint; `...docs.conflict` e `...docs.unprocessable` só quando o endpoint devolve 409/422. Todo 409/422 tem `code` estável listado na `description` do `registerPath`. Módulos novos usam `<domain>.<motivo>`; módulo legado mantém o formato que já publica, porque mudar `code` é breaking.
179
+ 8. **Guard runtime = `security` do contrato**, nas duas direções, sem guard global de autenticação. Rota protegida: `@UseGuards(AuthUserGuard)` e `security: [{ bearerAuth: [] }]`. Rota pública: sem guard e `security: []` no `registerPath`; siga o vizinho público: se ele só omite `security`, o documento herda o global e mostra a rota como protegida, e isso se registra como melhoria (`references/review.md` §3).
180
+ 9. **`<domain>-access` autoriza o recurso.** Permissão, tenant, ownership e estado são decididos ali, chamados pelo service antes de qualquer escrita; quando revelar a existência é risco, responda 404 em vez de 403.
181
+ 10. **Port com tipos escritos à mão.** Do ORM e do módulo de banco entram só `import type` de enums gerados e do tipo de paginação; nunca model, payload, select ou namespace do ORM. Ausência é `null`.
182
+ 11. **Cliente de banco só do módulo global de banco.** O adapter injeta os serviços que ele exporta (na referência, ORM para escrita e driver para leitura quente); nenhum módulo abre conexão nem cria pool. Pool e timeouts: `arch-db`.
183
+ 12. **SQL só parametrizado** (`$n` montado por função pura em `<domain>.sql.ts`); `ORDER BY` só por mapa literal atrás de `z.enum` no contrato, sempre com tiebreaker por id.
184
+ 13. **Lista tem teto e `meta` pelo helper único**: `paginationQuery`, `paginatedResponse(item)` e `toPaginationMeta`. Envelope `{ data }` ou `{ data, meta }`, nenhum outro.
185
+ 14. **Transação dentro do método do adapter**, sem HTTP, e-mail, fila ou upload dentro. A constraint decide a corrida e o `<domain>-db-errors` a traduz para exceção com `code`; `version` no `WHERE` que não casa vira 409 `<domain>.stale`.
186
+ 15. **Fail-closed.** Toda env no schema Zod validado no boot; exposição (docs, CORS, `trust proxy`, limite de body) fechada por padrão, com o detalhe de cada uma em `references/security.md` §1.
187
+ 16. **Migration pela ferramenta do repo**, revisada com `arch-db`; nunca no boot nem por `push`/`synchronize`.
188
+ 17. **`doc.md` do domínio muda no mesmo PR** que muda endpoint, permissão, regra ou persistência.
189
+
190
+ ---
191
+
192
+ ## Criando um endpoint, nesta ordem
193
+
194
+ 1. **Scaffold: só para domínio novo e só com ele na config.** O da referência sobrescreve, sem checar, entities, port, adapter, os dois módulos e os props/exec de cada domínio da config do gerador, e reescreve o agregador `common/surfaces/surface.module.ts` só com os domínios da config. Deixe na config apenas o domínio novo; depois restaure o agregador e acrescente só a linha nova na posição certa. Sem essa garantia, copie um domínio vizinho. O que ele gera é stub: body `.passthrough()` (aceita qualquer campo), response `z.unknown()` (o client recebe `unknown`), nomes de schema e imports fora do padrão. Critério: `git status` mostra só arquivos do domínio novo mais uma linha no agregador, e nenhum stub sobra.
195
+ 2. **entities**: schemas nomeados reutilizáveis (params, filtros, enum de sort, item e detalhe da resposta). Critério: todo schema exportado que vira tipo tem `.openapi('<Nome>')`.
196
+ 3. **props.surface** (`references/contract.md` §1) e a linha `import './surfaces/<acao>.<domain>.props.surface'` no `<domain>.surface.module.ts`, que é o que registra o contrato. Critério: o endpoint aparece no `openapi.json` gerado com `operationId` camelCase único e a `description` lista os `code` de 409/422.
197
+ 4. **service** + rules, access e errors, e os métodos que ele pede no **port** com tipos `*Row`/`*Record`/`New*`/`*Write` (`references/domain.md` §1–5). Critério: o service compila contra o port (em `check-types`, o único erro restante é o adapter ainda sem os métodos novos, resolvido no passo 5) e o port não importa do ORM nada além de enums e paginação; o caso de acesso negado sem escrita entra no spec do passo 8.
198
+ 5. **adapter** + `.sql.ts` e `-db-errors.ts` (`references/domain.md` §6–7); tabela ou coluna nova pela migration com `arch-db`. Critério: toda constraint que o write pode violar está no mapa de tradução.
199
+ 6. **exec.surface** (`references/contract.md` §3). Critério: path do decorator = `Endpoint` sem a barra; guards batem com `security`.
200
+ 7. **módulos**: exec em `controllers` e service em `providers` do `<domain>.surface.module.ts`; port novo ligado e exportado no `<domain>.sgbds.module.ts`; domínio novo no agregador (`references/domain.md` §8). Critério: a app sobe e a rota responde.
201
+ 8. **specs** (`references/review.md` §1). Critério: cada `code` novo tem teste que o afirma, o caso de acesso negado mostra o port de escrita sem chamada, e o retorno do service passa no `instructions.settings.response.body`.
202
+ 9. **`doc.md` e gate**: atualize a tabela endpoint x rota x permissão e as seções afetadas; rode `openapi:generate`, `check-types`, `lint` e os testes. Critério: tudo verde.
203
+
204
+ Não crie o exec antes do contrato, nem o adapter antes do caso de uso. Formato por tipo de endpoint: `references/endpoints.md`.
205
+
206
+ ---
207
+
208
+ ## Matriz de decisão
209
+
210
+ | Situação | Padrão | Template (`endpoints.md`) |
211
+ |---|---|---|
212
+ | Ler um recurso | service + `assert*` do access + port por id (e tenant) | 1.1 |
213
+ | Lista de tela administrativa | offset com teto, sort `z.enum` + mapa, tiebreaker, `toPaginationMeta` | 1.2 |
214
+ | Feed, log, linha do tempo | cursor keyset | 1.2 |
215
+ | Criar com invariante | constraint + `-db-errors` -> 409/422 com `code` | 1.3 |
216
+ | Criar com risco de duplicidade | `Idempotency-Key` + `IIdempotencyProvider` | 1.3 |
217
+ | Atualizar parte | PATCH, `<Coisa>Write` campo a campo, `version` no `WHERE` | 1.4 |
218
+ | Transição de estado | POST `/<id>/<acao>` + audit na mesma transação | 1.7 |
219
+ | Multi-write no mesmo banco | um método do adapter com a transação dentro | 1.3, 1.7 |
220
+ | Write + efeito externo que não pode se perder | outbox (`common/messaging`) | 1.12 |
221
+ | Integração externa | port em `common/<capacidade>` ou `<x>.provider.port.ts` no domínio, com timeout | - |
222
+ | Arquivo | capacidade de storage, rota própria | 1.8, 1.9 |
223
+ | Sem autenticação | sem guard, `security: []`, rate limit revisado | 1.10 |
224
+ | Pública que personaliza com token | `OptionalAuthUserGuard` | 1.10 |
225
+ | Multi-tenant | ref de tenant do header resolvida no service + filtro em toda query | 1.11 |
226
+ | Trabalho demorado | 202 + fila e worker | 1.12 |
227
+ | Mudança de contrato | classificar patch/minor/major (`contract.md` §8) | - |
228
+ | Decisão transversal | ADR (`review.md` §4) | - |
229
+
230
+ ---
231
+
232
+ ## Comandos
233
+
234
+ Formas reais do repo de referência; descubra os nomes no `package.json` do seu.
235
+
236
+ ```bash
237
+ <pm> run openapi:generate # openapi.json + generated/openapi-client.d.ts a partir dos registries
238
+ <pm> run check-types # tsc --noEmit
239
+ <pm> run lint # linter/formatter do repo
240
+ <pm> run test:unit # e test:integration, test:e2e, test:load
241
+ <pm> run prisma:generate # ou o gerador do ORM do repo, depois de mudar o schema
242
+ <pm> run migrate:create # e migrate:up | down | validate (paridade migration x schema); regras em arch-db
243
+ <pm> run seed # runner de seed do repo
244
+ <pm> run build
245
+ # monorepo: <pm> --filter <app> <script>
246
+ ```
247
+
248
+ Se um comando falhar por erro fora do escopo, registre e valide o que foi alterado.
249
+
250
+ ---
251
+
252
+ ## Anti-padrões
253
+
254
+ Armadilhas que as regras acima não nomeiam; cada uma já quebrou algo.
255
+
256
+ **Contrato**
257
+ - `import type` de um props (no módulo, no build ou no script de geração): o TypeScript elide o import, o registro não roda e o endpoint some do `openapi.json` sem erro.
258
+ - Contornar no client um `operationId` ruim ou um contrato errado: corrige-se aqui, regenera-se o documento e os clients.
259
+
260
+ **Domínio**
261
+ - Service que só repassa argumentos a outro: ou tem decisão, ou não existe.
262
+ - Redeclarar em `providers` o service de outro domínio: segunda instância fora do grafo, estado e cache divergentes.
263
+ - Autorização no exec ou num guard novo para regra que o access resolve: some do teste do service e do `doc.md`.
264
+ - Exceções de 422 e de 409 com argumentos trocados: na referência a de 422 recebe o `code` primeiro e a de 409 a mensagem primeiro (`references/common.md` §4).
265
+
266
+ **Dados**
267
+ - Adapter que pega outro cliente no meio da transação: a escrita fica fora do `BEGIN` e o rollback não a alcança.
268
+
269
+ **Segurança**
270
+ - Senha mestra, coringa ou backdoor, ou comparação de senha fora do provider de hash (caminho legítimo em `references/security.md` §2).
271
+ - Log de segredo ou PII (lista em `references/security.md` §8).
272
+
273
+ **Processo**
274
+ - Client gerado de um servidor rodando em vez do `openapi.json` do build: o client passa a refletir o deploy, não o código revisado.
275
+ - Infra de teste sem specs: config de runner e relatório não são cobertura.
276
+
277
+ ---
278
+
279
+ ## Critério de aceite
280
+
281
+ Uma alteração feita com esta skill só está pronta quando:
282
+
283
+ - O endpoint funciona em runtime e o `openapi.json` gerado o representa (path, verbo, status, `security`, schemas nomeados, `code` de 409/422).
284
+ - O exec é fino, o service concentra a decisão, o access autoriza o recurso e o port não carrega tipo de model do ORM.
285
+ - Erros, paginação, datas e envelope seguem o helper único do repo.
286
+ - Mudança de contrato, inclusive de `code`, está classificada (patch/minor/major, `references/contract.md` §8).
287
+ - Specs cobrem o caminho feliz, cada `code` novo e o contrato da resposta.
288
+ - `doc.md` do domínio reflete a mudança.
289
+ - Geração do OpenAPI, typecheck, lint e testes passam.
290
+ - O código não carrega nomes ou decisões de outro projeto sem validação explícita.
291
+ - Item que não se aplica está registrado como "não aplicável" com motivo técnico.
@@ -0,0 +1,3 @@
1
+ interface:
2
+ display_name: "Arch Api"
3
+ short_description: "Implementa, revisa e refatora APIs NestJS contract-first - contrato OpenAPI por..."
@@ -0,0 +1,174 @@
1
+ # `common/`: capacidades técnicas e infraestrutura compartilhada
2
+
3
+ Abra ao criar ou usar uma capacidade de `common/` (mailer, storage, hash, segredos, mensageria, idempotência, tempo real), ao mexer em env, exceções, docs, observabilidade, utils ou no bootstrap. `common/` não conhece domínio: nada aqui importa de `modules/`, exceto o agregador de surfaces e os schemas cross-domain que o contrato exige (como a entidade do usuário autenticado).
4
+
5
+ ---
6
+
7
+ ## 1. Anatomia
8
+
9
+ ```txt
10
+ common/<capacidade>/
11
+ ports/<capacidade>.<papel>.port.ts abstract class I<Capacidade><Papel> + tipos de entrada e saída
12
+ adapters/<tecnologia>.<capacidade>.<papel>.adapter.ts <Tecnologia><Capacidade><Papel>Adapter extends o port
13
+ <capacidade>.module.ts { provide: I<Capacidade><Papel>, useClass: <adapter> } + exports
14
+ <assunto>.service.ts | <assunto>.worker.ts orquestração da capacidade, quando há (ex.: dispatcher, outbox)
15
+ templates/ | settings/ o que a capacidade precisa e só ela usa
16
+ ```
17
+
18
+ Papéis comuns: `provider` (faz algo para o domínio: enviar, gravar, hashear), `loader` (carrega algo no boot), `publisher` (emite eventos). Exemplos de forma (tecnologia é a do repo): `mailer.provider.port.ts` + `<tecnologia>.mailer.provider.adapter.ts`; `storage.provider.port.ts` + `<tecnologia>.storage.provider.adapter.ts`; `idempotency.provider.port.ts` + `db.idempotency.provider.adapter.ts`.
19
+
20
+ Port ou classe concreta: na referência, hash, mailer, encrypters, storage, messaging, resilience, secrets e html têm port + adapter mesmo com uma implementação só; cache e fila são um service concreto; auth, environments (port + provider) e realtime (port + gateway) têm forma própria. Capacidade nova nasce com port quando um domínio a injeta (o port é o token de DI e o double do teste) ou quando a tecnologia pode trocar por env. Service concreto fica para cola de infraestrutura usada só por outras capacidades. Se o repo já resolveu a capacidade de outro jeito, siga o repo.
21
+
22
+ ---
23
+
24
+ ## 2. Adicionando uma capacidade
25
+
26
+ ```ts
27
+ // common/mailer/ports/mailer.provider.port.ts
28
+ export type MailSendInput = { to: string | string[]; subject: string; html: string; text?: string };
29
+
30
+ export abstract class IMailerProvider {
31
+ abstract send(input: MailSendInput): Promise<void>;
32
+ }
33
+ ```
34
+
35
+ ```ts
36
+ // common/mailer/adapters/<tecnologia>.mailer.provider.adapter.ts
37
+ @Injectable()
38
+ export class SmtpMailerProviderAdapter extends IMailerProvider { // "Smtp": exemplo de tecnologia
39
+ private readonly logger = new Logger(SmtpMailerProviderAdapter.name);
40
+ private readonly from?: string;
41
+
42
+ constructor(private readonly env: IEnvironmentProvider) {
43
+ super();
44
+ this.from = env.get('MAIL_FROM_EMAIL');
45
+ }
46
+
47
+ async send(input: MailSendInput): Promise<void> {
48
+ if (!this.from) {
49
+ this.logger.warn('MAIL_FROM_EMAIL not configured; skipping email send');
50
+ return;
51
+ }
52
+ // chamada ao SDK ou cliente da tecnologia, com timeout (security.md §9)
53
+ }
54
+ }
55
+ ```
56
+
57
+ ```ts
58
+ // common/mailer/mailer.module.ts
59
+ @Module({
60
+ providers: [{ provide: IMailerProvider, useClass: SmtpMailerProviderAdapter }, MailDispatcherService],
61
+ exports: [IMailerProvider, MailDispatcherService],
62
+ })
63
+ export class MailerModule {}
64
+ ```
65
+
66
+ Passos:
67
+
68
+ 1. Port com a menor interface que o domínio precisa, em termos do domínio (`send`, `put`, `acquire`), sem tipo do SDK.
69
+ 2. Adapter `extends` o port, injeta `IEnvironmentProvider` para configuração e constrói o cliente da tecnologia no construtor. Critério: nenhum `process.env` no adapter.
70
+ 3. Toda env nova entra no schema (§3) com `describe`. Critério: o boot falha sem ela, ou o schema declara o default e o comportamento sem ela.
71
+ 4. Módulo liga port -> adapter e exporta o port (e o service de orquestração, se houver); o `app.module.ts` importa o módulo. Critério: a app sobe.
72
+ 5. Comportamento sem configuração é explícito: em dev, pular com `warn` é aceitável; em produção, decida fail-open ou fail-closed, registre no `describe` da env e, se fizer sentido, ofereça uma flag `..._FAIL_CLOSED`.
73
+ 6. Spec do adapter quando há tradução não trivial (montagem de cabeçalho, mapeamento de erro).
74
+
75
+ O domínio injeta o port (`constructor(private readonly mailer: IMailerProvider)`) e o seu `surface.module` importa o módulo da capacidade, a menos que ela seja global.
76
+
77
+ ---
78
+
79
+ ## 3. `environments/`: env validado no boot
80
+
81
+ ```txt
82
+ environments/environment.schema.ts z.object({...}) com toda variável usada no código
83
+ environments/environment.validate.ts validateEnvironment: parse do schema; erro derruba o boot
84
+ environments/ports/... + adapters/... IEnvironmentProvider com get(chave) tipado
85
+ environments/environment.module.ts
86
+ server/app.module.ts ConfigModule.forRoot({ isGlobal: true, validate: validateEnvironment })
87
+ ```
88
+
89
+ - Cada variável do schema (regra 15 do `SKILL.md`) tem `describe` dizendo o efeito e o default.
90
+ - Número com `z.coerce.number()`; duração e limite com `.positive()`: `.default()` não dispara quando a chave existe e está vazia (`''` vira `0`), e um TTL zero passaria calado.
91
+ - Boolean por literal: `z.preprocess((v) => v === 'true' || v === true, z.boolean())`; nunca `z.coerce.boolean()` (`'false'` vira `true`).
92
+ - Enum de modo normalizado por `z.preprocess` (aliases como `PRODUCTION` -> forma canônica); quem compara o modo usa o valor normalizado (`security.md` §1).
93
+ - Segredo com tamanho mínimo no schema.
94
+ - Fora do bootstrap, leia env pelo provider; o `main.ts` é a exceção, porque roda antes da DI.
95
+
96
+ ---
97
+
98
+ ## 4. `http/`: enums e exceções
99
+
100
+ - `http/enums/`: `http.status.success.{ok,created,noContent}`, `http.status.clientError.{badRequest,unauthorized,forbidden,notFound,conflict,unprocessableEntity}`, `http.header.{correlationId,idempotencyKey,...}`. Use o enum, nunca o número ou o nome de header solto.
101
+ - `http/errors/`: exceções de domínio que saem no shape do contrato (`security.md` §7). Nenhuma camada abaixo do exec lança `BadRequestException('texto')` cru quando existe a exceção de domínio. Na referência:
102
+
103
+ | Exceção | Status | Assinatura |
104
+ |---|---|---|
105
+ | `UnprocessableDomainException` | 422 | `(code, message, details?)` |
106
+ | `ConflictDomainException` | 409 | `(message, code?)` |
107
+ | `NotFoundDomainException` | 404 | `(message)` |
108
+ | `ForbiddenCustomHttpException` | 403 | `(message)` |
109
+ | exceção de 401 do repo | 401 | ver `unauthorized.custom.http.exceptions.ts` |
110
+
111
+ Exceção nova: `security.md` §7.
112
+
113
+ ---
114
+
115
+ ## 5. `docs/openapi/` e `schemas/`
116
+
117
+ - `docs/openapi/`: `registries.docs.ts` (lista global), `response.docs.ts` (blocos de erro), `build.ts` (documento), `generate.ts` (grava o arquivo) e, se o repo tiver, um passo de enriquecimento das extensões `x-*`. Mecânica em `contract.md` §2.
118
+ - `schemas/`: `paginations.ts` (`paginationQuery`, `paginatedResponse`, `toPaginationMeta`), `errors.ts` (shape de erro por status), entidades usadas por vários domínios e o setup do Zod com OpenAPI. Schema de um domínio só fica no módulo dele.
119
+
120
+ ---
121
+
122
+ ## 6. `sgbds/`: o módulo global de banco
123
+
124
+ ```txt
125
+ sgbds/containers/sgbds.module.ts @Global(); providers e exports: os serviços de banco (na referência, ORM e driver)
126
+ sgbds/settings/ schema do ORM, serviços de banco, db-errors.ts (rethrowDbError), runner de seed
127
+ sgbds/ports/ sgbds/adapters/<orm>/ repositório base genérico (CRUD) e IPaginatedResult
128
+ sgbds/generated/ client gerado pelo ORM: nunca editar à mão
129
+ sgbds/migrations/ <timestamp>_<NNNN>_<nome>.ts com up e down (ferramenta do repo)
130
+ sgbds/seeds/ <timestamp>-<Nome>.ts + dataset/ + README
131
+ ```
132
+
133
+ - O módulo é global; adapters injetam os serviços que ele exporta (regra 11 do `SKILL.md`).
134
+ - O serviço do ORM conecta em `onModuleInit` sem engolir erro (falhar no boot é melhor que subir saudável e devolver 500) e fixa limites de transação interativa (espera e duração máximas) para uma transação presa não segurar conexão.
135
+ - Na referência há dois clientes exportados: ORM para escrita e driver para leitura quente. `arch-db` recomenda um pool por processo e vence no dimensionamento (reference `pooling-ops.md` de lá): se cada cliente abre o seu pool, some os dois no orçamento de conexões; não crie um terceiro.
136
+ - O repositório base genérico é o que o scaffold usa; domínio com regra declara métodos próprios (`domain.md` §5).
137
+ - Migrations, seeds, schema, índices e pool: `arch-db`. Aqui só a fiação.
138
+
139
+ ---
140
+
141
+ ## 7. `observability/`, `guards/`, `decorators/`, `policies/`
142
+
143
+ - `observability/`: interceptor de correlação (lê o header de correlação ou gera um id e loga o desfecho da request), filter de exceções, logger estruturado e o módulo. Campos e limites em `security.md` §8.
144
+ - `guards/`: autenticação (`AuthUserGuard`, que estende o guard do passport com a estratégia JWT de `common/auth/`), autenticação opcional e rate limit por tipo de rota. Regras em `security.md` §3.
145
+ - `decorators/`: usuário autenticado, `Zd*` (validação com o schema do contrato) e contexto HTTP. Tabela em `contract.md` §4.
146
+ - `policies/`: ownership transversal (`assertResourceOwner(owner, actorId, message?)` lança 403). Autorização por recurso de um domínio fica no `<domain>-access.ts` dele.
147
+ - `auth/`: estratégia JWT, catálogo de permissões (`permissions.ts`) e validade de sessão.
148
+
149
+ ---
150
+
151
+ ## 8. `utils/<tipo>/`
152
+
153
+ Helpers puros agrupados por tipo (`array`, `http`, `json`, `pagination`, `sql`, `string` ...): `utils/<tipo>/<nome>.<tipo>.util.ts` (maioria; siga o vizinho da pasta), teste `*.unit.spec.ts`, exportados pelo `index.ts` da pasta. Exemplos: `utils/string/interpolate.string.util.ts`, `utils/array/remove-duplicated-objects.array.util.ts`; algumas pastas usam o nome sem o tipo (o escape de curingas para `ILIKE` em `utils/sql/`), e o arquivo novo segue a pasta onde entra. Util não injeta nada e não conhece domínio; se precisa de DI, é capacidade (§2).
154
+
155
+ ---
156
+
157
+ ## 9. `server/`: bootstrap
158
+
159
+ `app.module.ts` importa `ConfigModule` com a validação de env, o módulo global de banco, os módulos de capacidade e o `SurfaceModule`. `main.ts`, nesta ordem:
160
+
161
+ ```txt
162
+ imports de efeito colateral setup do Zod com OpenAPI e extensões globais do repo
163
+ segredos loader de segredos antes do NestFactory, para o schema de env validar já com eles
164
+ NestFactory.create CORS por lista do env (credentials), logger
165
+ prefixo global ex.: api/v1, que é o mesmo do servers do documento
166
+ body parser limite explícito
167
+ x-powered-by desligado
168
+ trust proxy pelo parser do repo (server/trust-proxy.ts + spec), default loopback
169
+ helmet CSP desligada só se a API não serve HTML além da UI de docs
170
+ docs SwaggerModule.setup só quando a exposição está ligada (fail-closed)
171
+ listen porta do env
172
+ ```
173
+
174
+ As regras de cada linha (CORS, `trust proxy`, limite de body, docs fail-closed, comparação do modo) estão em `security.md` §1.