nexus-core-v3 3.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 (232) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -0
  3. package/agents/README.md +133 -0
  4. package/agents/_protocol.md +107 -0
  5. package/agents/analyst.md +138 -0
  6. package/agents/architect.md +146 -0
  7. package/agents/data-engineer.md +170 -0
  8. package/agents/dev.md +134 -0
  9. package/agents/devops.md +141 -0
  10. package/agents/nexus-master.md +147 -0
  11. package/agents/pm.md +133 -0
  12. package/agents/po.md +138 -0
  13. package/agents/qa.md +192 -0
  14. package/agents/sm.md +122 -0
  15. package/agents/squad-creator.md +121 -0
  16. package/agents/ux-design-expert.md +165 -0
  17. package/artifact-manifest.json +903 -0
  18. package/bin/nexus.mjs +37 -0
  19. package/checklists/README.md +49 -0
  20. package/checklists/architect-checklist.md +47 -0
  21. package/checklists/change-checklist.md +61 -0
  22. package/checklists/db-predeploy-checklist.md +57 -0
  23. package/checklists/design-quality-checklist.md +57 -0
  24. package/checklists/discovery-checklist.md +36 -0
  25. package/checklists/foundation-checklist.md +39 -0
  26. package/checklists/launch-checklist.md +39 -0
  27. package/checklists/pm-checklist.md +48 -0
  28. package/checklists/po-master-checklist.md +64 -0
  29. package/checklists/reality-check-checklist.md +49 -0
  30. package/checklists/story-dod-checklist.md +52 -0
  31. package/checklists/story-draft-checklist.md +36 -0
  32. package/dist/bin/dashboard.html +279 -0
  33. package/dist/bin/nexus.mjs +20008 -0
  34. package/dist/constitution.yaml +76 -0
  35. package/knowledge/README.md +57 -0
  36. package/knowledge/architecture/architectural-styles-map.md +182 -0
  37. package/knowledge/architecture/design-patterns-gof.md +192 -0
  38. package/knowledge/architecture/distributed-patterns-cheatsheet.md +201 -0
  39. package/knowledge/architecture/saas-subscription-blueprint.md +355 -0
  40. package/knowledge/architecture/system-design-tradeoffs.md +231 -0
  41. package/knowledge/architecture/t3-fullstack-typesafe-stack.md +273 -0
  42. package/knowledge/copy/landing-copy-that-converts.md +168 -0
  43. package/knowledge/data/postgres-indexing-and-tuning.md +263 -0
  44. package/knowledge/data/schema-modeling-decisions.md +273 -0
  45. package/knowledge/data/supabase-rls-patterns.md +316 -0
  46. package/knowledge/data/zero-downtime-migrations.md +308 -0
  47. package/knowledge/devops/cicd-pipeline-best-practices.md +318 -0
  48. package/knowledge/devops/production-dockerfile.md +283 -0
  49. package/knowledge/devops/twelve-factor-app.md +398 -0
  50. package/knowledge/engineering/clean-code-principles.md +429 -0
  51. package/knowledge/engineering/effective-code-review.md +204 -0
  52. package/knowledge/engineering/testing-strategy-beyond-unit.md +307 -0
  53. package/knowledge/governance/risk-matrix.md +56 -0
  54. package/knowledge/integration/mcp-server-selection-matrix.md +235 -0
  55. package/knowledge/marketing/copy-que-converte.md +43 -0
  56. package/knowledge/marketing/funil-e-jornada.md +36 -0
  57. package/knowledge/negocios/proposta-vencedora.md +38 -0
  58. package/knowledge/negocios/roi-e-unit-economics.md +46 -0
  59. package/knowledge/pipeline/1-descobrir.md +26 -0
  60. package/knowledge/pipeline/2-estrategizar.md +26 -0
  61. package/knowledge/pipeline/3-estruturar.md +27 -0
  62. package/knowledge/pipeline/4-construir.md +27 -0
  63. package/knowledge/pipeline/5-endurecer.md +28 -0
  64. package/knowledge/pipeline/6-lancar.md +27 -0
  65. package/knowledge/pipeline/7-operar.md +27 -0
  66. package/knowledge/security/lgpd-conformidade-basica.md +35 -0
  67. package/knowledge/security/owasp-secure-coding-gates.md +220 -0
  68. package/knowledge/security/owasp-top10-threat-assessment.md +287 -0
  69. package/knowledge/security/threat-modeling-stride.md +34 -0
  70. package/knowledge/web-craft/a11y-audit-checklist.md +251 -0
  71. package/knowledge/web-craft/accessible-component-patterns.md +383 -0
  72. package/knowledge/web-craft/anti-ai-look.md +114 -0
  73. package/knowledge/web-craft/design-system-from-code.md +195 -0
  74. package/knowledge/web-craft/intrinsic-css-layout.md +420 -0
  75. package/knowledge/web-craft/style-cloning.md +185 -0
  76. package/knowledge/web-craft/visual-polish-review.md +183 -0
  77. package/package.json +55 -0
  78. package/runbooks/campanha-de-conteudo.md +36 -0
  79. package/runbooks/feature-em-projeto-existente.md +37 -0
  80. package/runbooks/mvp-startup.md +38 -0
  81. package/runbooks/resposta-a-incidente.md +37 -0
  82. package/squads/exemplo-conteudo/agents/editor-chefe.md +48 -0
  83. package/squads/exemplo-conteudo/agents/pesquisador.md +44 -0
  84. package/squads/exemplo-conteudo/agents/redator.md +45 -0
  85. package/squads/exemplo-conteudo/knowledge/estilo-editorial.md +21 -0
  86. package/squads/exemplo-conteudo/squad.yaml +19 -0
  87. package/squads/exemplo-conteudo/tasks/pesquisar-fontes.md +26 -0
  88. package/squads/exemplo-conteudo/tasks/planejar-pauta.md +27 -0
  89. package/squads/exemplo-conteudo/tasks/redigir-artigo.md +26 -0
  90. package/squads/exemplo-conteudo/tasks/revisar-artigo.md +27 -0
  91. package/squads/marketing/agents/analista.md +56 -0
  92. package/squads/marketing/agents/chefe-marketing.md +65 -0
  93. package/squads/marketing/agents/conteudo.md +55 -0
  94. package/squads/marketing/agents/copy.md +55 -0
  95. package/squads/marketing/agents/growth.md +56 -0
  96. package/squads/marketing/agents/social.md +55 -0
  97. package/squads/marketing/squad.yaml +17 -0
  98. package/squads/marketing/tasks/aprovar-campanha.md +43 -0
  99. package/squads/negocios/agents/chefe-negocios.md +65 -0
  100. package/squads/negocios/agents/financas-roi.md +55 -0
  101. package/squads/negocios/agents/suporte.md +55 -0
  102. package/squads/negocios/agents/vendas-proposta.md +56 -0
  103. package/squads/negocios/squad.yaml +17 -0
  104. package/squads/negocios/tasks/aprovar-proposta.md +40 -0
  105. package/squads/security/agents/appsec-reviewer.md +59 -0
  106. package/squads/security/agents/chefe-seguranca.md +65 -0
  107. package/squads/security/agents/compliance-auditor.md +60 -0
  108. package/squads/security/agents/threat-modeler.md +60 -0
  109. package/squads/security/squad.yaml +20 -0
  110. package/squads/security/tasks/aprovar-gate-seguranca.md +42 -0
  111. package/squads/security/tasks/emitir-parecer-conformidade.md +42 -0
  112. package/tasks/README.md +72 -0
  113. package/tasks/accessibility-wcag-checklist.md +69 -0
  114. package/tasks/advanced-elicitation.md +42 -0
  115. package/tasks/analyze-performance.md +54 -0
  116. package/tasks/analyze-project-structure.md +59 -0
  117. package/tasks/apply-qa-fixes.md +57 -0
  118. package/tasks/architect-analyze-impact.md +62 -0
  119. package/tasks/archive-squad.md +52 -0
  120. package/tasks/audit-codebase.md +53 -0
  121. package/tasks/build-component.md +61 -0
  122. package/tasks/calculate-roi.md +63 -0
  123. package/tasks/ci-cd-configuration.md +51 -0
  124. package/tasks/collect-visual-evidence.md +62 -0
  125. package/tasks/compose-molecule.md +57 -0
  126. package/tasks/consolidate-patterns.md +54 -0
  127. package/tasks/create-brownfield-prd.md +54 -0
  128. package/tasks/create-competitor-analysis.md +42 -0
  129. package/tasks/create-deep-research-prompt.md +62 -0
  130. package/tasks/create-doc.md +62 -0
  131. package/tasks/create-epic.md +49 -0
  132. package/tasks/create-front-end-spec.md +56 -0
  133. package/tasks/create-migration-plan.md +57 -0
  134. package/tasks/create-next-story.md +66 -0
  135. package/tasks/create-prd.md +53 -0
  136. package/tasks/create-project-brief.md +47 -0
  137. package/tasks/create-rls-policies.md +59 -0
  138. package/tasks/create-schema.md +57 -0
  139. package/tasks/create-service.md +55 -0
  140. package/tasks/create-squad.md +100 -0
  141. package/tasks/create-suite.md +62 -0
  142. package/tasks/db-apply-migration.md +56 -0
  143. package/tasks/db-domain-modeling.md +57 -0
  144. package/tasks/db-dry-run.md +50 -0
  145. package/tasks/db-env-check.md +57 -0
  146. package/tasks/db-load-csv.md +54 -0
  147. package/tasks/db-policy-apply.md +58 -0
  148. package/tasks/db-rollback.md +51 -0
  149. package/tasks/db-run-sql.md +61 -0
  150. package/tasks/db-seed.md +52 -0
  151. package/tasks/db-smoke-test.md +51 -0
  152. package/tasks/db-snapshot.md +48 -0
  153. package/tasks/db-verify-order.md +49 -0
  154. package/tasks/deliberate.md +46 -0
  155. package/tasks/design-indexes.md +59 -0
  156. package/tasks/dev-develop-story.md +61 -0
  157. package/tasks/document-project.md +59 -0
  158. package/tasks/execute-checklist.md +57 -0
  159. package/tasks/execute-epic-plan.md +52 -0
  160. package/tasks/execute-subtask.md +51 -0
  161. package/tasks/extend-pattern.md +63 -0
  162. package/tasks/extend-squad.md +60 -0
  163. package/tasks/extract-patterns.md +64 -0
  164. package/tasks/extract-tokens.md +59 -0
  165. package/tasks/facilitate-brainstorming-session.md +42 -0
  166. package/tasks/generate-ai-frontend-prompt.md +57 -0
  167. package/tasks/generate-documentation.md +60 -0
  168. package/tasks/generate-migration-strategy.md +57 -0
  169. package/tasks/generate-shock-report.md +56 -0
  170. package/tasks/mcp-management.md +66 -0
  171. package/tasks/orchestrate.md +50 -0
  172. package/tasks/perform-market-research.md +42 -0
  173. package/tasks/plan-create-context.md +57 -0
  174. package/tasks/plan-create-implementation.md +58 -0
  175. package/tasks/po-close-story.md +60 -0
  176. package/tasks/po-manage-story-backlog.md +59 -0
  177. package/tasks/po-pull-story.md +60 -0
  178. package/tasks/po-sync-story.md +59 -0
  179. package/tasks/pr-automation.md +50 -0
  180. package/tasks/pre-push-quality-gate.md +54 -0
  181. package/tasks/push.md +53 -0
  182. package/tasks/qa-browser-console-check.md +52 -0
  183. package/tasks/qa-create-fix-request.md +58 -0
  184. package/tasks/qa-evidence-requirements.md +55 -0
  185. package/tasks/qa-false-positive-detection.md +55 -0
  186. package/tasks/qa-fix-issues.md +55 -0
  187. package/tasks/qa-gate.md +53 -0
  188. package/tasks/qa-migration-validation.md +58 -0
  189. package/tasks/qa-nfr-assess.md +45 -0
  190. package/tasks/qa-review-story.md +56 -0
  191. package/tasks/qa-risk-profile.md +45 -0
  192. package/tasks/qa-security-checklist.md +64 -0
  193. package/tasks/qa-test-design.md +47 -0
  194. package/tasks/qa-trace-requirements.md +48 -0
  195. package/tasks/release-management.md +53 -0
  196. package/tasks/repository-cleanup.md +61 -0
  197. package/tasks/route.md +44 -0
  198. package/tasks/run-tests.md +50 -0
  199. package/tasks/security-audit.md +54 -0
  200. package/tasks/setup-database.md +60 -0
  201. package/tasks/setup-design-system.md +60 -0
  202. package/tasks/shard-doc.md +60 -0
  203. package/tasks/spec-assess-complexity.md +55 -0
  204. package/tasks/spec-critique.md +64 -0
  205. package/tasks/spec-gather-requirements.md +48 -0
  206. package/tasks/spec-research-dependencies.md +42 -0
  207. package/tasks/spec-write-spec.md +50 -0
  208. package/tasks/test-as-user.md +52 -0
  209. package/tasks/ux-create-wireframe.md +54 -0
  210. package/tasks/ux-user-research.md +55 -0
  211. package/tasks/validate-next-story.md +61 -0
  212. package/tasks/validate-squad.md +55 -0
  213. package/tasks/verify-subtask.md +52 -0
  214. package/tasks/version-management.md +45 -0
  215. package/templates/README.md +47 -0
  216. package/templates/architecture-tmpl.md +115 -0
  217. package/templates/competitor-analysis-tmpl.md +87 -0
  218. package/templates/epic-tmpl.md +83 -0
  219. package/templates/front-end-spec-tmpl.md +110 -0
  220. package/templates/market-research-tmpl.md +98 -0
  221. package/templates/migration-plan-tmpl.md +92 -0
  222. package/templates/prd-tmpl.md +95 -0
  223. package/templates/project-brief-tmpl.md +100 -0
  224. package/templates/qa-verdict-tmpl.md +73 -0
  225. package/templates/rls-policies-tmpl.md +93 -0
  226. package/templates/schema-design-tmpl.md +107 -0
  227. package/templates/spec-tmpl.md +88 -0
  228. package/templates/squad/agent-dna-tmpl.md +72 -0
  229. package/templates/squad/chief-dna-tmpl.md +98 -0
  230. package/templates/squad/squad-task-tmpl.md +50 -0
  231. package/templates/squad/squad-yaml-tmpl.md +47 -0
  232. package/templates/story-tmpl.md +63 -0
@@ -0,0 +1,168 @@
1
+ ---
2
+ id: landing-copy-that-converts
3
+ domain: copy
4
+ agents: [ux-design-expert, pm]
5
+ when: "ao escrever a copy de uma landing page que precisa converter e ter voz, não soar genérica"
6
+ ---
7
+
8
+ # Landing Copy That Converts — copy com voz e gatilho real, não texto de IA
9
+
10
+ Copy de IA converte mal pelo mesmo motivo que página de IA parece genérica: ela descreve um produto
11
+ abstrato, sem nome, sem cara, sem ninguém do outro lado. A régua aqui é simples: **toda frase tem que
12
+ passar no teste do concorrente.** Se o seu concorrente direto pudesse colar a mesma headline no site
13
+ dele sem mentir, a headline não diz nada. "Empower your workflow" cabe em qualquer SaaS do planeta — por
14
+ isso é lixo. "Feche o mês contábil em 3 dias, não 3 semanas" só cabe em quem faz aquilo.
15
+
16
+ ## Os tells (reconheça pra evitar)
17
+
18
+ Se a copy tem 3+ destes, ela grita "IA" e converte mal:
19
+
20
+ 1. **Verbo de empoderamento vago**: *empower, unlock, elevate, supercharge, transform, streamline,
21
+ revolutionize, harness*. Em PT: *potencialize, desbloqueie, eleve, revolucione, descomplique.* Todos
22
+ prometem sensação, nenhum entrega fato.
23
+ 2. **"Seamless / effortless / intuitive / cutting-edge"** como adjetivo de enchimento. Ninguém acredita
24
+ em "intuitivo" escrito — só na demonstração.
25
+ 3. **Benefício sem mecanismo**: "tome decisões melhores", "trabalhe de forma mais inteligente", "alcance
26
+ seus objetivos". *Melhores como? Mais inteligente fazendo o quê?* Falta o "como".
27
+ 4. **"We" em vez de "você"**: "We help teams to…", "Nossa missão é…", "Acreditamos que…". A landing é
28
+ sobre o problema do leitor, não sobre a empresa se apresentar.
29
+ 5. **Headline que descreve a categoria, não o resultado**: "A plataforma all-in-one de gestão de
30
+ projetos". Isso é uma etiqueta de prateleira, não uma promessa.
31
+ 6. **Prova social fantasma**: "Amado por milhares de equipes", "Trusted by industry leaders" — sem
32
+ número, sem nome, sem logo. Mil de quê? Quais líderes?
33
+ 7. **Adjetivo no lugar de número**: "rápido", "poderoso", "robusto", "escalável". Número é prova;
34
+ adjetivo é opinião do vendedor.
35
+ 8. **Três features paralelas de duas palavras** com ícone: "Fácil de usar · Seguro · Escalável". O
36
+ tríptico genérico — não diz o que muda na vida de quem usa.
37
+ 9. **CTA covarde**: "Saiba mais", "Comece agora", "Get started". Não diz o que acontece no clique nem o
38
+ que você ganha.
39
+ 10. **Voz de ninguém**: registro neutro, corporativo, sem atrito, sem opinião. Lê-se como release de
40
+ imprensa traduzido. Não tem como soar como uma pessoa real falando.
41
+ 11. **Objeção ignorada**: a página vende como se ninguém tivesse medo de migrar, de configurar, de
42
+ pagar. Silêncio sobre a dúvida óbvia = leitor desconfia sozinho e sai.
43
+ 12. **Jargão como muleta**: "solução end-to-end", "sinergia de dados", "ecossistema". Palavra grande
44
+ escondendo que não há promessa concreta embaixo.
45
+
46
+ ## Os princípios do craft (como o redator faz diferente)
47
+
48
+ ### 1. Headline diz o que faz, pra quem, e o resultado — nessa ordem de prioridade
49
+
50
+ A headline tem um trabalho: em 5 segundos, o leitor certo pensa "isso é pra mim" e o errado vai embora
51
+ (filtrar é bom). Estruturas que funcionam:
52
+
53
+ - **Resultado + prazo/atrito removido**: "Feche a folha de 50 pessoas em 1 tarde." A especificidade
54
+ (50, 1 tarde) faz o leitor se reconhecer.
55
+ - **[Faz X] sem [a dor conhecida]**: "Cobre clientes recorrentes sem planilha e sem cobrar no boca a
56
+ boca." O "sem" nomeia a dor que ele já vive.
57
+ - **Pra quem + o que muda**: "Pra contador que atende 30+ empresas: feche o mês sem virar a noite."
58
+ Quando o público é nichado, **dizer pra quem** converte mais do que esconder.
59
+
60
+ Regra: se você trocar o nome do produto pelo do concorrente e a headline continuar verdadeira, reescreva.
61
+
62
+ ### 2. Clareza ganha de esperteza — sempre, e principalmente acima da dobra
63
+
64
+ Trocadilho, frase de efeito e mistério ("Repense o trabalho.") custam um segundo de decodificação que o
65
+ leitor não dá. Se você precisa de uma subheadline pra explicar a piada da headline, a piada perdeu.
66
+ Ordem: **primeiro fica claro, depois fica bonito.** A esperteza é permitida em microcopy (botão, estado
67
+ vazio), onde o risco de confundir é baixo e a personalidade rende.
68
+
69
+ Teste do estranho: leia só a headline e a subheadline pra alguém que nunca ouviu falar do produto. Se
70
+ ele não souber dizer o que é e pra quem, não está claro ainda.
71
+
72
+ ### 3. Subheadline carrega o mecanismo (o "como")
73
+
74
+ A headline promete o resultado; a subheadline entrega a credibilidade dizendo **como**. "Feche o mês em
75
+ 3 dias" (headline) + "Conciliação bancária automática e fechamento guiado por checklist — você revisa,
76
+ não digita" (subheadline). O mecanismo é o que separa promessa de propaganda.
77
+
78
+ ### 4. Prova específica com número real, ancorada
79
+
80
+ Número solto é fraco ("aumente 40%"). Número **ancorado** é forte: diz de quê, comparado a quê, de quem.
81
+
82
+ - Fraco: "Economize tempo." → Forte: "Clientes economizam ~6h/semana no fechamento (média de 40 contas
83
+ ativas)."
84
+ - Fraco: "Confiado por milhares." → Forte: "1.240 escritórios contábeis usam — incluindo [Logo], [Logo]."
85
+ - Depoimento com cargo e resultado, não elogio vago: não "Adorei a ferramenta!", e sim "Cortei o
86
+ fechamento de 9 pra 3 dias. — Marina, sócia, escritório de 12 pessoas."
87
+
88
+ **Ética (inegociável):** todo número e claim tem que ser verdadeiro e verificável. Se você não tem o
89
+ dado, não invente — use prova qualitativa honesta ("desenhado com 30 escritórios em beta") ou foque no
90
+ mecanismo concreto. Gatilho honesto é específico; gatilho desonesto é inflar número. Inflar mata a
91
+ confiança no primeiro contato do cliente com a realidade.
92
+
93
+ ### 5. Antecipe a objeção número 1 na própria página
94
+
95
+ Toda categoria tem o medo óbvio. A landing que converte **diz o medo em voz alta e desarma**:
96
+
97
+ - Medo de migração → "Importamos seus dados do [concorrente] em 1 clique. Você não recomeça do zero."
98
+ - Medo de preço → faixa de preço visível, ou "Sem cartão pra testar. Cancela em 2 cliques."
99
+ - Medo de complexidade → "Configurado em 10 min. Sem implementação, sem consultoria."
100
+
101
+ Onde colocar: logo após a primeira prova, ou como microcopy abaixo do CTA ("Leva 30s · sem cartão").
102
+ Objeção não-respondida não some — o leitor a responde sozinho, pro lado pior.
103
+
104
+ ### 6. Um CTA, verbo de ação, dizendo o que acontece no clique
105
+
106
+ Uma landing, um objetivo primário. O botão descreve **a ação e o ganho**, não o esforço:
107
+
108
+ - Fraco: "Enviar" / "Saiba mais" / "Comece agora".
109
+ - Forte: "Testar grátis por 14 dias", "Ver meu fechamento simulado", "Agendar demo de 20 min".
110
+ - Microcopy abaixo remove o último atrito: "Sem cartão · cancela quando quiser · seus dados são seus".
111
+
112
+ Repetir o **mesmo** CTA ao longo da página é bom; oferecer 4 ações concorrentes (testar, comprar, falar
113
+ com vendas, baixar PDF) dispersa e derruba conversão.
114
+
115
+ ### 7. Achar a voz: escreva pra uma pessoa, não pra um mercado
116
+
117
+ Voz não é escolher palavras bonitas; é ter um ponto de vista e um leitor concreto.
118
+
119
+ - **Defina o leitor de um**: nome, cargo, a frase exata que ele resmunga sobre o problema ("de novo vou
120
+ virar a noite no fechamento"). Escreva como se respondesse essa frase.
121
+ - **Roube a voz do cliente**: as melhores frases da landing saem de transcrição de call de vendas e
122
+ review — as palavras que o cliente usa pra descrever a dor. Não invente o vocabulário dele; cite.
123
+ - **Escolha um eixo de tom** e mantenha: direto-e-seco vs. caloroso-e-próximo, técnico vs. simples,
124
+ ousado vs. confiável. Uma fintech séria e uma marca de hobby não falam igual — e nenhuma fala "neutro".
125
+ - **Microcopy é onde a voz aparece barato**: botão, placeholder, estado de erro, confirmação. "Pronto,
126
+ já era" rende mais voz que um parágrafo institucional.
127
+ - **Teste de voz**: leia em voz alta. Se você não falaria aquilo pra um cliente num café, reescreva. Se
128
+ poderia estar no site de qualquer concorrente, falta ponto de vista.
129
+
130
+ ### 8. Cortar é metade do trabalho
131
+
132
+ Copy de IA é gorda. O leitor escaneia, não lê.
133
+
134
+ - **Uma ideia por frase, uma frase por linha** acima da dobra. Frase de 40 palavras some no scan.
135
+ - **Corte advérbio e adjetivo de enchimento**: "muito", "realmente", "incrivelmente", "simplesmente".
136
+ Se a frase sobrevive sem a palavra, ela estava pesando.
137
+ - **Verbo forte > verbo fraco + advérbio**: "elimina" > "ajuda a reduzir significativamente".
138
+ - **Específico encolhe e fortalece ao mesmo tempo**: "rápido" (vago, 1 palavra) perde pra "em 2 min"
139
+ (concreto, 2 palavras). Mais curto E mais forte.
140
+
141
+ ## Checklist "esta copy parece de IA?"
142
+
143
+ Antes de entregar, responda — qualquer "sim" é um tell a corrigir:
144
+
145
+ - [ ] A headline cabe no site de um concorrente sem virar mentira?
146
+ - [ ] Tem *empower / unlock / elevate / seamless / streamline / potencialize / descomplique* em destaque?
147
+ - [ ] Algum benefício promete resultado sem dizer o mecanismo (o "como")?
148
+ - [ ] A página fala mais de "nós / nossa missão" do que do problema de "você"?
149
+ - [ ] A prova social é "milhares de equipes" sem número, nome ou logo?
150
+ - [ ] Tem adjetivo ("poderoso", "robusto") onde caberia um número?
151
+ - [ ] O CTA é "Saiba mais / Comece agora" em vez de dizer o que acontece no clique?
152
+ - [ ] A objeção número 1 da categoria (preço, migração, setup) ficou sem resposta na página?
153
+ - [ ] A copy lê como release neutro — sem ponto de vista, sem soar como pessoa real?
154
+ - [ ] Tem número ou claim que você não conseguiria provar se o cliente pedisse?
155
+
156
+ ## Antes → depois
157
+
158
+ | Tell (IA) | Craft (com voz e prova) |
159
+ |---|---|
160
+ | "Empower your team to achieve more." | "Feche o mês contábil em 3 dias, não 3 semanas." |
161
+ | "A plataforma all-in-one de gestão." | "Pra contador com 30+ empresas: fecha o mês sem virar a noite." |
162
+ | "Streamline your workflow seamlessly." | "Conciliação bancária automática — você revisa, não digita." |
163
+ | "Aumente sua produtividade." | "Clientes economizam ~6h/semana no fechamento (média de 40 contas)." |
164
+ | "Trusted by thousands of teams." | "1.240 escritórios usam — incluindo [Logo], [Logo]." |
165
+ | "Adorei, recomendo!" — Cliente | "Cortei o fechamento de 9 pra 3 dias. — Marina, sócia, 12 pessoas." |
166
+ | "Fácil de usar · Seguro · Escalável" | "Importa seus dados do [concorrente] em 1 clique. Você não recomeça do zero." |
167
+ | CTA: "Saiba mais" | CTA: "Ver meu fechamento simulado" + "Leva 30s · sem cartão" |
168
+ | (silêncio sobre o medo de migrar) | "Migra do [concorrente] em 10 min. Sem implementação, sem consultoria." |
@@ -0,0 +1,263 @@
1
+ ---
2
+ id: postgres-indexing-and-tuning
3
+ domain: data
4
+ agents: [data-engineer]
5
+ when: "ao otimizar performance de queries no PostgreSQL"
6
+ ---
7
+
8
+ # PostgreSQL — indexação e tuning que muda o plano
9
+
10
+ A maioria dos "índices" que se cria no PostgreSQL é B-tree em coluna única — e isso resolve o caso fácil.
11
+ O craft está no que B-tree não resolve: `jsonb @> '{}'`, `tags && ARRAY[...]`, busca geográfica, tabelas de
12
+ bilhões de linhas append-only, filtro em `lower(email)`, `WHERE deleted_at IS NULL`. Trocar o tipo de
13
+ índice, a ordem das colunas ou um parâmetro de memória vira `Seq Scan` de 3 segundos em `Index Scan` de 2ms.
14
+ A régua deste pack: **toda decisão de índice se justifica lendo o `EXPLAIN (ANALYZE, BUFFERS)`** — não no
15
+ chute. Se você não rodou o EXPLAIN antes e depois, não otimizou, adivinhou.
16
+
17
+ ## O problema (os tells de quem não lê o plano)
18
+
19
+ Sinais de que a otimização foi no chute, não no plano:
20
+
21
+ 1. **B-tree em tudo.** Criar B-tree numa coluna `jsonb`, `text[]` ou `tsvector` — o planner ignora e faz
22
+ `Seq Scan`. Esses tipos pedem GIN, não B-tree.
23
+ 2. **Índice composto na ordem errada.** `CREATE INDEX ON pedidos (status, cliente_id)` quando a query
24
+ filtra só por `cliente_id`. A coluna líder não é usada → o índice não serve à query.
25
+ 3. **Índice em `coluna` mas a query usa `lower(coluna)` ou `coluna::date`.** Qualquer função/cast na
26
+ coluna invalida o índice simples. Precisa de índice de expressão.
27
+ 4. **Indexar a tabela inteira quando 95% das linhas nunca são consultadas** (ex.: `WHERE deleted_at IS
28
+ NULL` em soft-delete). Índice parcial é menor, mais rápido e mais barato de manter.
29
+ 5. **Otimizar `EXPLAIN` sem `ANALYZE`** — você só vê a estimativa do planner, não o tempo real nem os
30
+ buffers. Custo em "unidades de página", não em ms, não prova nada sozinho.
31
+ 6. **`shared_buffers`/`work_mem` no default de instalação** (128MB / 4MB) num servidor de 32GB — sorts
32
+ derramam pra disco (`external merge Disk`), cache mínimo, tudo lento sem aparecer no plano de índice.
33
+ 7. **Adicionar índice e nunca medir o custo de escrita.** Todo índice é overhead em `INSERT`/`UPDATE`.
34
+ Índice que ninguém usa (cheque `pg_stat_user_indexes.idx_scan = 0`) só atrasa escrita.
35
+
36
+ ## O conhecimento / os princípios
37
+
38
+ ### 1. Escolha do tipo de índice pelo operador, não pelo hábito
39
+
40
+ O planner só usa um índice se ele suporta o **operador** da sua cláusula `WHERE`. Cada tipo cobre um
41
+ conjunto de operadores (fonte: PostgreSQL docs, *11.2 Index Types*):
42
+
43
+ | Tipo | Operadores suportados | Casos reais |
44
+ |---|---|---|
45
+ | **B-tree** (default) | `< <= = >= >`, `BETWEEN`, `IN`, `IS NULL`, `LIKE 'foo%'` (ancorado no início) | igualdade e range em qualquer tipo ordenável; PK/FK; `ORDER BY` (retorna ordenado) |
46
+ | **Hash** | `=` apenas | igualdade pura; útil em coluna grande onde só se compara `=` |
47
+ | **GIN** | `@> <@ = &&` (e `@@` para FTS, `?`/`@?` para jsonb) | `jsonb`, `array`, `tsvector`, `hstore` — múltiplos valores numa coluna |
48
+ | **GiST** | `<< &< &> @> <@ &&` e vizinhança `<->` | dados geométricos/`geometry` (PostGIS), ranges, nearest-neighbor (`ORDER BY ponto <-> '(x,y)'`) |
49
+ | **SP-GiST** | `<< >> ~= <@` | dados não-balanceados: quadtree, k-d tree, roteamento IP, `inet` |
50
+ | **BRIN** | `< <= = >= >` (linear) | tabelas enormes onde o valor é **correlacionado com a ordem física** (timestamps append-only, IDs sequenciais) |
51
+
52
+ Sintaxe de seleção do método:
53
+
54
+ ```sql
55
+ -- B-tree é o default; os outros são explícitos:
56
+ CREATE INDEX ON eventos USING gin (payload jsonb_path_ops); -- jsonb com @>
57
+ CREATE INDEX ON posts USING gin (to_tsvector('portuguese', corpo)); -- FTS
58
+ CREATE INDEX ON lugares USING gist (geom); -- geo + <->
59
+ CREATE INDEX ON logs USING brin (criado_em); -- append-only gigante
60
+ CREATE INDEX ON contas USING hash (token); -- só =
61
+ ```
62
+
63
+ Regra de leitura: se a query usa `@>`, `&&`, `@@` ou nearest-neighbor `<->`, **não é B-tree** — é GIN
64
+ (contém/sobrepõe em jsonb/array/FTS) ou GiST (geo/range/vizinhança).
65
+
66
+ **GIN x GiST para o mesmo dado:** GIN é mais rápido para **ler** e maior/mais lento para **escrever**;
67
+ GiST é menor e mais rápido de atualizar, com leitura "lossy" (pode gerar falsos positivos que o
68
+ re-check elimina). FTS de alto volume de leitura → GIN. Dado que muda muito → GiST.
69
+
70
+ ### 2. BRIN: o índice de 99% menos espaço para tabelas append-only
71
+
72
+ BRIN guarda só o **mínimo e máximo de cada faixa de blocos físicos** — não uma entrada por linha. Só
73
+ funciona se os valores estiverem **correlacionados com a ordem física** das linhas (ex.: `criado_em`
74
+ numa tabela que só cresce por append). Numa tabela de 500M linhas, um BRIN em `criado_em` ocupa
75
+ kilobytes onde um B-tree ocuparia gigabytes.
76
+
77
+ ```sql
78
+ -- tabela de telemetria, 1 bilhão de linhas, inserida em ordem temporal:
79
+ CREATE INDEX ON telemetria USING brin (criado_em);
80
+ -- query de range temporal:
81
+ SELECT * FROM telemetria WHERE criado_em BETWEEN '2026-06-01' AND '2026-06-02';
82
+ ```
83
+
84
+ Se os dados **não** forem fisicamente ordenados pela coluna, BRIN é inútil — use B-tree.
85
+
86
+ ### 3. Ordem das colunas em índice composto: leftmost prefix
87
+
88
+ Em índice B-tree multicoluna, vale a regra exata da doc (*11.5 Multicolumn Indexes*):
89
+
90
+ > "Equality constraints on leading columns, plus any inequality constraints on the first column that
91
+ > does not have an equality constraint, will always be used to limit the portion of the index scanned."
92
+
93
+ Traduzindo: **a coluna mais à esquerda manda.** Para `CREATE INDEX ON pedidos (cliente_id, status, criado_em)`:
94
+
95
+ | Query `WHERE` | Usa o índice eficientemente? |
96
+ |---|---|
97
+ | `cliente_id = 7` | Sim (prefixo líder) |
98
+ | `cliente_id = 7 AND status = 'pago'` | Sim (igualdade nas líderes) |
99
+ | `cliente_id = 7 AND status = 'pago' AND criado_em > '...'` | Sim — ideal |
100
+ | `cliente_id = 7 AND criado_em > '...'` (pula `status`) | Parcial: usa `cliente_id`, mas `criado_em` vira filtro pós-scan |
101
+ | `status = 'pago'` (sem `cliente_id`) | Não eficiente — pode até virar `Seq Scan` |
102
+
103
+ Regra prática de ordenação das colunas:
104
+ 1. Colunas de **igualdade primeiro** (`=`), na ordem de uso.
105
+ 2. A coluna de **range/`ORDER BY` por último**.
106
+ 3. Da mais **seletiva** para a menos, entre as de igualdade.
107
+
108
+ Da doc: índices com mais de 3 colunas raramente compensam; índice multicoluna deve ser usado com
109
+ parcimônia — em geral um índice de coluna única já basta. Para GIN e BRIN, a ordem das colunas **não**
110
+ importa ("effectiveness is the same regardless of which column the query uses").
111
+
112
+ ### 4. Covering index (INCLUDE) → index-only scan
113
+
114
+ Um `Index Scan` ainda visita o heap para buscar colunas que não estão no índice. Se **todas** as colunas
115
+ do `SELECT` e do `WHERE` estiverem no índice, o planner faz **Index-Only Scan** — zero acesso ao heap.
116
+ Use `INCLUDE` para carregar colunas de payload sem inflar a chave de busca:
117
+
118
+ ```sql
119
+ -- query: SELECT total FROM pedidos WHERE cliente_id = 7;
120
+ CREATE INDEX pedidos_cliente_inc ON pedidos (cliente_id) INCLUDE (total);
121
+ ```
122
+
123
+ Pontos da doc (*11.9 Index-Only Scans*):
124
+ - Colunas em `INCLUDE` **não** fazem parte da chave; em índice único, a unicidade vale só nas colunas-chave.
125
+ - Só **B-tree, GiST e SP-GiST** suportam `INCLUDE`. **GIN não** suporta index-only scan.
126
+ - O index-only scan depende do **visibility map**: só é vantagem se "uma fração significativa das heap
127
+ pages estiver com o bit all-visible setado". Tabela com muito `UPDATE`/`DELETE` recente → rode
128
+ `VACUUM` para o bit valer, senão volta a visitar o heap.
129
+
130
+ ### 5. Índice parcial: indexe só as linhas que importam
131
+
132
+ `CREATE INDEX ... WHERE` constrói o índice sobre um **subconjunto** das linhas. Menor, mais rápido de
133
+ escanear, mais barato em escrita. Exemplos da doc (*11.8 Partial Indexes*):
134
+
135
+ ```sql
136
+ -- soft-delete: 95% das queries só querem linhas vivas
137
+ CREATE INDEX pedidos_ativos ON pedidos (cliente_id) WHERE deleted_at IS NULL;
138
+
139
+ -- só pedidos não-faturados são consultados com frequência:
140
+ CREATE INDEX orders_unbilled_index ON orders (order_nr) WHERE billed IS NOT TRUE;
141
+
142
+ -- unicidade parcial: só 1 "sucesso" por (subject, target), mas N falhas:
143
+ CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target) WHERE success;
144
+ ```
145
+
146
+ Pegadinha: o planner só usa o índice parcial se a `WHERE` da query **implica logicamente** o predicado
147
+ do índice. `WHERE deleted_at IS NULL` casa; `WHERE deleted_at = $1` (parametrizado) **não** casa.
148
+
149
+ ### 6. Índice de expressão: quando a query usa função/cast na coluna
150
+
151
+ `lower(email)`, `criado_em::date`, `(first || ' ' || last)` — qualquer transformação invalida o índice
152
+ da coluna crua. Indexe a **expressão** (*11.7 Indexes on Expressions*):
153
+
154
+ ```sql
155
+ -- query: SELECT * FROM users WHERE lower(email) = 'a@b.com';
156
+ CREATE INDEX users_lower_email ON users (lower(email));
157
+
158
+ -- nome completo concatenado:
159
+ CREATE INDEX people_names ON people ((first_name || ' ' || last_name));
160
+ ```
161
+
162
+ Custo: a expressão é recalculada a cada `INSERT`/`UPDATE` não-HOT (mais caro em escrita) — mas **não**
163
+ durante a busca (já está armazenada). Vale quando leitura > escrita.
164
+
165
+ ### 7. Tuning de memória — os 4 parâmetros que mexem no plano
166
+
167
+ Defaults de instalação são minúsculos. Em servidor dedicado (fonte: *PostgreSQL Wiki — Tuning Your
168
+ PostgreSQL Server*):
169
+
170
+ | Parâmetro | Recomendação | O que faz / sintoma do default |
171
+ |---|---|---|
172
+ | `shared_buffers` | **25% da RAM** (≥1GB de RAM) | cache de páginas do Postgres. Default ~128MB; baixo → mais `read` de disco. Exige restart. |
173
+ | `effective_cache_size` | **50–75% da RAM** | só uma *dica* ao planner do cache total (SO+PG). Baixo → planner subestima e evita índice. Sem restart. |
174
+ | `work_mem` | `(RAM − shared_buffers) / max_connections`, conservador | memória por operação de sort/hash. Default ~4MB → sort derrama pra disco (`external merge Disk` no EXPLAIN). É **por operação**: 50MB × 30 conexões × N sorts = GBs reais. Ajustável por sessão. |
175
+ | `maintenance_work_mem` | bem maior que `work_mem` (ex.: 256MB–1GB) | usado por `CREATE INDEX`, `VACUUM`, `ALTER TABLE`. Default 64MB. Maior = índice cria mais rápido. |
176
+
177
+ `work_mem` é a alavanca mais comum: se o EXPLAIN ANALYZE mostra `Sort Method: external merge Disk:
178
+ NkB`, subir `work_mem` (na sessão) transforma em `quicksort Memory`.
179
+
180
+ ### 8. Ler o EXPLAIN (ANALYZE, BUFFERS) — onde mora a verdade
181
+
182
+ Sempre meça com `EXPLAIN (ANALYZE, BUFFERS)` — executa de verdade e mostra tempo real + I/O:
183
+
184
+ ```sql
185
+ EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM tenk1 WHERE unique1 < 100;
186
+ ```
187
+
188
+ Anatomia de uma linha (*14.1 Using EXPLAIN*):
189
+
190
+ ```
191
+ Index Scan using tenk1_unique1 on tenk1
192
+ (cost=0.29..8.30 rows=1 width=244) (actual time=0.005..0.007 rows=1.00 loops=1)
193
+ ```
194
+
195
+ - `cost=start..total` — unidades arbitrárias do planner (page fetches), **não ms**. Só comparáveis entre planos.
196
+ - `rows=` (em `cost`) = **estimativa**; `rows=` (em `actual`) = **real**. Discrepância grande (ex.: estima
197
+ 1, retorna 50.000) → estatística desatualizada → rode `ANALYZE tabela`.
198
+ - `actual time=start..end` em **ms**. `loops=N` → multiplique `actual time × loops` para o tempo total
199
+ do nó (crítico em Nested Loop).
200
+ - `Buffers: shared hit=N read=M` → `hit` = veio do cache; `read` = leu do disco. `read` alto = I/O caro;
201
+ alvo é maximizar `hit`.
202
+
203
+ **Os três scans e o que cada um diz:**
204
+
205
+ | Nó | Significa | Quando é bom / ruim |
206
+ |---|---|---|
207
+ | `Seq Scan` | lê a tabela inteira | OK em tabela pequena ou query que retorna >~5–10% das linhas; **ruim** se há filtro seletivo e existe índice ignorado |
208
+ | `Index Scan` | navega o índice, busca cada linha no heap | ótimo para queries muito seletivas (1 ou poucas linhas) ou que casam `ORDER BY` |
209
+ | `Bitmap Index Scan` + `Bitmap Heap Scan` | índice monta um bitmap de localizações, depois lê o heap em ordem física | melhor que Index Scan quando há **muitas** linhas (centenas/milhares): minimiza saltos de disco; combina vários índices com `BitmapAnd`/`BitmapOr` |
210
+
211
+ Pistas no plano:
212
+ - `Recheck Cond` no Bitmap Heap Scan: re-checagem após o bitmap (normal).
213
+ - `Filter: (...)` + `Rows Removed by Filter: N`: condição que **não** virou `Index Cond` — candidata a
214
+ entrar num índice composto ou de expressão.
215
+ - `Heap Blocks: exact=N` / `lossy=N`: `lossy` alto sugere subir `work_mem` (bitmap não coube na memória).
216
+ - `Index Cond` vs `Filter`: o que está em `Index Cond` foi resolvido pelo índice; o que está em `Filter`
217
+ passou linha a linha.
218
+
219
+ Diagnóstico típico: query lenta → EXPLAIN ANALYZE mostra `Seq Scan` + `Filter` + `Rows Removed by
220
+ Filter` enorme → criar índice no campo do filtro → re-rodar → vira `Index Scan`/`Bitmap Heap Scan` com
221
+ `actual time` menor e `Buffers shared read` menor.
222
+
223
+ ## Checklist
224
+
225
+ Antes de dar por otimizada uma query, responda — qualquer "não" é trabalho a fazer:
226
+
227
+ - [ ] Rodei `EXPLAIN (ANALYZE, BUFFERS)` **antes e depois** e comparei `actual time` e `Buffers read`?
228
+ - [ ] O tipo de índice casa com o **operador** da `WHERE`? (`@>`/`&&`/`@@` → GIN; geo/`<->` → GiST;
229
+ append-only gigante → BRIN; só `=` → Hash; resto → B-tree)
230
+ - [ ] Em índice composto, a coluna **mais à esquerda** é a que a query filtra por igualdade, e o range/
231
+ `ORDER BY` ficou por último?
232
+ - [ ] A query usa função/cast na coluna (`lower()`, `::date`)? Se sim, existe índice de **expressão**?
233
+ - [ ] Se a query sempre filtra um subconjunto (`deleted_at IS NULL`, `status='ativo'`), há índice **parcial**?
234
+ - [ ] Dá pra virar **Index-Only Scan** com `INCLUDE` nas colunas do `SELECT`? (e o `VACUUM` está em dia
235
+ pro visibility map valer?)
236
+ - [ ] Conferi `pg_stat_user_indexes.idx_scan` — não estou criando índice que ninguém usa (custo de escrita à toa)?
237
+ - [ ] As estatísticas estão frescas (`ANALYZE`) — a estimativa de `rows` bate com o `actual`?
238
+ - [ ] O EXPLAIN mostra `external merge Disk` ou `lossy` no bitmap? Se sim, ajustei `work_mem`?
239
+ - [ ] `shared_buffers` (~25% RAM) e `effective_cache_size` (50–75% RAM) saíram do default da instalação?
240
+
241
+ ## Tabela de decisão — use X quando Y
242
+
243
+ | Use… | Quando… |
244
+ |---|---|
245
+ | **B-tree** | igualdade/range em tipo ordenável, PK/FK, `ORDER BY`, `LIKE 'prefixo%'` (o default, 90% dos casos) |
246
+ | **GIN** | coluna `jsonb`/`array`/`tsvector`/`hstore` com `@>`, `&&`, `@@`; busca full-text de alta leitura |
247
+ | **GiST** | dados geométricos/PostGIS, ranges, nearest-neighbor (`ORDER BY geom <-> ponto`), dado que muda muito |
248
+ | **BRIN** | tabela enorme append-only com coluna correlacionada à ordem física (timestamp, ID sequencial) |
249
+ | **Hash** | só compara `=`, nunca range nem ordenação, e quer índice menor que B-tree |
250
+ | **Índice de expressão** | a query filtra por `lower(col)`, `col::date`, concatenação — qualquer transformação da coluna |
251
+ | **Índice parcial (`WHERE`)** | a query sempre toca um subconjunto fixo (soft-delete, status, flag) e o resto é ruído |
252
+ | **Covering (`INCLUDE`) / index-only** | leitura quente que retorna poucas colunas e você quer eliminar o acesso ao heap |
253
+ | **Índice composto** | a query filtra 2–3 colunas juntas com frequência; ordene igualdade→range, mais seletiva primeiro |
254
+ | **Subir `work_mem`** | EXPLAIN mostra `Sort Method: external merge Disk` ou `Heap Blocks: lossy=N` |
255
+ | **Subir `shared_buffers`/`effective_cache_size`** | `Buffers shared read` alto, planner evitando índices, ainda no default da instalação |
256
+ | **`Seq Scan` (deixar como está)** | tabela pequena, ou a query retorna >5–10% das linhas (índice não compensaria) |
257
+ | **`ANALYZE` / estatística** | estimativa de `rows` diverge muito do `actual rows` no EXPLAIN ANALYZE |
258
+
259
+ ---
260
+
261
+ Fontes: PostgreSQL Documentation — *11.2 Index Types*, *11.5 Multicolumn Indexes*, *11.7 Indexes on
262
+ Expressions*, *11.8 Partial Indexes*, *11.9 Index-Only Scans*, *14.1 Using EXPLAIN*; PostgreSQL Wiki —
263
+ *Tuning Your PostgreSQL Server*.