@luanpdd/kit-mcp 1.30.2 → 1.32.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 (365) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +168 -168
  3. package/gates/agent-no-recursive-dispatch.md +84 -82
  4. package/kit/COMANDOS.md +138 -138
  5. package/kit/COMPATIBILITY.md +5 -0
  6. package/kit/README.md +76 -76
  7. package/kit/agents/advisor-researcher.md +107 -106
  8. package/kit/agents/ai-mutation-tester.md +1 -0
  9. package/kit/agents/assumptions-analyzer.md +108 -107
  10. package/kit/agents/audit-log-implementer.md +314 -313
  11. package/kit/agents/auditor-consistencia-isolamento.md +414 -413
  12. package/kit/agents/b2b-saas-architect.md +157 -156
  13. package/kit/agents/burn-rate-forecaster.md +1 -0
  14. package/kit/agents/cascading-failures-auditor.md +299 -298
  15. package/kit/agents/codebase-mapper.md +769 -768
  16. package/kit/agents/crm-pipeline-implementer.md +257 -256
  17. package/kit/agents/debugger.md +814 -813
  18. package/kit/agents/detector-tenant-quente.md +338 -337
  19. package/kit/agents/evolution-go-integrator.md +201 -200
  20. package/kit/agents/example-reviewer.md +22 -21
  21. package/kit/agents/executor.md +565 -564
  22. package/kit/agents/golden-signals-instrumenter.md +1 -0
  23. package/kit/agents/incident-investigator.md +1 -0
  24. package/kit/agents/integration-checker.md +201 -200
  25. package/kit/agents/invite-flow-implementer.md +190 -189
  26. package/kit/agents/legacy-characterizer.md +369 -368
  27. package/kit/agents/lgpd-compliance-auditor.md +296 -295
  28. package/kit/agents/load-shedding-instrumenter.md +1 -0
  29. package/kit/agents/multi-tenant-isolation-auditor.md +254 -253
  30. package/kit/agents/multi-tenant-rls-writer.md +341 -340
  31. package/kit/agents/nyquist-auditor.md +179 -178
  32. package/kit/agents/observability-coverage-auditor.md +316 -315
  33. package/kit/agents/observability-instrumenter.md +1 -0
  34. package/kit/agents/omm-auditor.md +1 -0
  35. package/kit/agents/org-onboarding-implementer.md +224 -223
  36. package/kit/agents/payload-capture-instrumenter.md +274 -273
  37. package/kit/agents/phase-researcher.md +697 -696
  38. package/kit/agents/plan-checker.md +273 -272
  39. package/kit/agents/planner.md +923 -922
  40. package/kit/agents/postmortem-writer.md +1 -0
  41. package/kit/agents/project-researcher.md +653 -652
  42. package/kit/agents/prr-conductor.md +1 -0
  43. package/kit/agents/refactor-safety-auditor.md +405 -404
  44. package/kit/agents/release-pipeline-auditor.md +1 -0
  45. package/kit/agents/research-synthesizer.md +246 -245
  46. package/kit/agents/roadmapper.md +678 -677
  47. package/kit/agents/schema-checker.md +1 -0
  48. package/kit/agents/seam-finder.md +360 -359
  49. package/kit/agents/shotgun-surgery-detector.md +350 -349
  50. package/kit/agents/slo-engineer.md +1 -0
  51. package/kit/agents/storytelling-analyst.md +1 -0
  52. package/kit/agents/supabase-architect.md +1 -0
  53. package/kit/agents/supabase-auth-bootstrapper.md +16 -1
  54. package/kit/agents/supabase-auth-hook-writer.md +418 -0
  55. package/kit/agents/supabase-branching-architect.md +563 -562
  56. package/kit/agents/supabase-cicd-pipeline-implementer.md +778 -777
  57. package/kit/agents/supabase-column-privileges-writer.md +400 -399
  58. package/kit/agents/supabase-edge-fn-tester.md +2 -1
  59. package/kit/agents/supabase-edge-fn-writer.md +2 -1
  60. package/kit/agents/supabase-mfa-implementer.md +439 -0
  61. package/kit/agents/supabase-migration-writer.md +386 -385
  62. package/kit/agents/supabase-oauth-server-implementer.md +507 -0
  63. package/kit/agents/supabase-rbac-implementer.md +393 -392
  64. package/kit/agents/supabase-realtime-implementer.md +364 -363
  65. package/kit/agents/supabase-rls-hardener.md +522 -521
  66. package/kit/agents/supabase-rls-writer.md +324 -323
  67. package/kit/agents/supabase-roles-implementer.md +356 -355
  68. package/kit/agents/supabase-social-auth-implementer.md +451 -0
  69. package/kit/agents/supabase-sso-saml-architect.md +549 -0
  70. package/kit/agents/supabase-storage-implementer.md +1 -0
  71. package/kit/agents/super-admin-implementer.md +282 -281
  72. package/kit/agents/toil-auditor.md +1 -0
  73. package/kit/agents/ui-auditor.md +438 -437
  74. package/kit/agents/ui-checker.md +303 -302
  75. package/kit/agents/ui-researcher.md +356 -355
  76. package/kit/agents/user-profiler.md +176 -175
  77. package/kit/agents/validador-evolucao-schema.md +336 -335
  78. package/kit/agents/verifier.md +729 -728
  79. package/kit/commands/adicionar-backlog.md +75 -75
  80. package/kit/commands/adicionar-fase.md +42 -42
  81. package/kit/commands/adicionar-tarefa.md +45 -45
  82. package/kit/commands/adicionar-testes.md +41 -41
  83. package/kit/commands/ajuda.md +21 -21
  84. package/kit/commands/atualizar.md +37 -37
  85. package/kit/commands/auditar-cascading.md +111 -111
  86. package/kit/commands/auditar-marco.md +179 -179
  87. package/kit/commands/auditar-observabilidade-cobertura.md +183 -183
  88. package/kit/commands/auditar-refactor.md +219 -219
  89. package/kit/commands/auditar-release.md +109 -109
  90. package/kit/commands/auditar-uat.md +23 -23
  91. package/kit/commands/autonomo.md +40 -40
  92. package/kit/commands/branch-pr.md +24 -24
  93. package/kit/commands/burn-rate-status.md +408 -408
  94. package/kit/commands/capturar-payloads.md +193 -193
  95. package/kit/commands/caracterizar.md +212 -212
  96. package/kit/commands/concluir-marco.md +247 -247
  97. package/kit/commands/configuracoes.md +36 -36
  98. package/kit/commands/dados-distribuidos.md +188 -188
  99. package/kit/commands/definir-perfil.md +10 -10
  100. package/kit/commands/depurar.md +190 -190
  101. package/kit/commands/detectar-duplicacao.md +197 -197
  102. package/kit/commands/discutir-fase.md +131 -131
  103. package/kit/commands/encontrar-seams.md +136 -136
  104. package/kit/commands/entrar-discord.md +17 -17
  105. package/kit/commands/estatisticas.md +18 -18
  106. package/kit/commands/example-greeting.md +33 -33
  107. package/kit/commands/executar-fase.md +58 -58
  108. package/kit/commands/expresso.md +56 -56
  109. package/kit/commands/fase-ui.md +34 -34
  110. package/kit/commands/fazer.md +57 -57
  111. package/kit/commands/fio.md +125 -125
  112. package/kit/commands/fluxos-trabalho.md +64 -64
  113. package/kit/commands/forense.md +176 -176
  114. package/kit/commands/gerenciador.md +38 -38
  115. package/kit/commands/inserir-fase.md +31 -31
  116. package/kit/commands/legacy.md +263 -263
  117. package/kit/commands/limpeza.md +17 -17
  118. package/kit/commands/listar-hipoteses-fase.md +45 -45
  119. package/kit/commands/listar-workspaces.md +18 -18
  120. package/kit/commands/load-shedding.md +117 -117
  121. package/kit/commands/mapear-codebase.md +70 -70
  122. package/kit/commands/multi-tenant.md +163 -163
  123. package/kit/commands/nota.md +33 -33
  124. package/kit/commands/novo-marco.md +43 -43
  125. package/kit/commands/novo-projeto.md +41 -41
  126. package/kit/commands/novo-workspace.md +43 -43
  127. package/kit/commands/pausar-trabalho.md +37 -37
  128. package/kit/commands/perfil-usuario.md +45 -45
  129. package/kit/commands/pesquisar-fase.md +195 -195
  130. package/kit/commands/planejar-fase.md +67 -67
  131. package/kit/commands/planejar-lacunas.md +33 -33
  132. package/kit/commands/plantar-ideia.md +25 -25
  133. package/kit/commands/progresso.md +24 -24
  134. package/kit/commands/proximo.md +30 -30
  135. package/kit/commands/publicar.md +490 -490
  136. package/kit/commands/rapido.md +35 -35
  137. package/kit/commands/reaplicar-patches.md +124 -124
  138. package/kit/commands/refactor-seguro.md +321 -321
  139. package/kit/commands/relatorio-sessao.md +19 -19
  140. package/kit/commands/remover-fase.md +31 -31
  141. package/kit/commands/remover-workspace.md +26 -26
  142. package/kit/commands/resumo-marco.md +50 -50
  143. package/kit/commands/retomar-trabalho.md +40 -40
  144. package/kit/commands/revisar-backlog.md +60 -60
  145. package/kit/commands/revisar-ui.md +32 -32
  146. package/kit/commands/revisar.md +37 -37
  147. package/kit/commands/saude.md +21 -21
  148. package/kit/commands/setup-notion.md +93 -93
  149. package/kit/commands/storytelling.md +179 -179
  150. package/kit/commands/supabase.md +21 -1
  151. package/kit/commands/sync-main.md +68 -68
  152. package/kit/commands/validar-fase.md +35 -35
  153. package/kit/commands/verificar-tarefas.md +44 -44
  154. package/kit/commands/verificar-trabalho.md +64 -64
  155. package/kit/file-manifest.json +100 -84
  156. package/kit/framework/bin/lib/commands.cjs +959 -959
  157. package/kit/framework/bin/lib/config.cjs +442 -442
  158. package/kit/framework/bin/lib/core.cjs +1230 -1230
  159. package/kit/framework/bin/lib/frontmatter.cjs +336 -336
  160. package/kit/framework/bin/lib/init.cjs +1442 -1442
  161. package/kit/framework/bin/lib/milestone.cjs +252 -252
  162. package/kit/framework/bin/lib/model-profiles.cjs +68 -68
  163. package/kit/framework/bin/lib/phase.cjs +888 -888
  164. package/kit/framework/bin/lib/profile-output.cjs +952 -952
  165. package/kit/framework/bin/lib/profile-pipeline.cjs +539 -539
  166. package/kit/framework/bin/lib/roadmap.cjs +329 -329
  167. package/kit/framework/bin/lib/security.cjs +382 -382
  168. package/kit/framework/bin/lib/state.cjs +1031 -1031
  169. package/kit/framework/bin/lib/template.cjs +222 -222
  170. package/kit/framework/bin/lib/uat.cjs +282 -282
  171. package/kit/framework/bin/lib/verify.cjs +888 -888
  172. package/kit/framework/bin/lib/workstream.cjs +491 -491
  173. package/kit/framework/bin/tools.cjs +918 -918
  174. package/kit/framework/commands/workstreams.md +63 -63
  175. package/kit/framework/references/checkpoints.md +778 -778
  176. package/kit/framework/references/continuation-format.md +249 -249
  177. package/kit/framework/references/decimal-phase-calculation.md +64 -64
  178. package/kit/framework/references/git-integration.md +295 -295
  179. package/kit/framework/references/git-planning-commit.md +38 -38
  180. package/kit/framework/references/model-profile-resolution.md +36 -36
  181. package/kit/framework/references/model-profiles.md +139 -139
  182. package/kit/framework/references/phase-argument-parsing.md +61 -61
  183. package/kit/framework/references/planning-config.md +202 -202
  184. package/kit/framework/references/questioning.md +162 -162
  185. package/kit/framework/references/tdd.md +263 -263
  186. package/kit/framework/references/ui-brand.md +160 -160
  187. package/kit/framework/references/user-profiling.md +657 -657
  188. package/kit/framework/references/verification-patterns.md +612 -612
  189. package/kit/framework/references/workstream-flag.md +58 -58
  190. package/kit/framework/templates/DEBUG.md +164 -164
  191. package/kit/framework/templates/UAT.md +265 -265
  192. package/kit/framework/templates/UI-SPEC.md +100 -100
  193. package/kit/framework/templates/VALIDATION.md +76 -76
  194. package/kit/framework/templates/claude-md.md +122 -122
  195. package/kit/framework/templates/codebase/architecture.md +185 -185
  196. package/kit/framework/templates/codebase/concerns.md +205 -205
  197. package/kit/framework/templates/codebase/conventions.md +204 -204
  198. package/kit/framework/templates/codebase/integrations.md +192 -192
  199. package/kit/framework/templates/codebase/stack.md +158 -158
  200. package/kit/framework/templates/codebase/structure.md +199 -199
  201. package/kit/framework/templates/codebase/testing.md +301 -301
  202. package/kit/framework/templates/config.json +44 -44
  203. package/kit/framework/templates/context.md +352 -352
  204. package/kit/framework/templates/continue-here.md +78 -78
  205. package/kit/framework/templates/copilot-instructions.md +7 -7
  206. package/kit/framework/templates/debug-subagent-prompt.md +91 -91
  207. package/kit/framework/templates/dev-preferences.md +20 -20
  208. package/kit/framework/templates/discovery.md +146 -146
  209. package/kit/framework/templates/discussion-log.md +63 -63
  210. package/kit/framework/templates/milestone-archive.md +123 -123
  211. package/kit/framework/templates/milestone.md +115 -115
  212. package/kit/framework/templates/phase-prompt.md +610 -610
  213. package/kit/framework/templates/planner-subagent-prompt.md +117 -117
  214. package/kit/framework/templates/project.md +186 -186
  215. package/kit/framework/templates/requirements.md +231 -231
  216. package/kit/framework/templates/research-project/ARCHITECTURE.md +204 -204
  217. package/kit/framework/templates/research-project/FEATURES.md +147 -147
  218. package/kit/framework/templates/research-project/PITFALLS.md +200 -200
  219. package/kit/framework/templates/research-project/STACK.md +120 -120
  220. package/kit/framework/templates/research-project/SUMMARY.md +170 -170
  221. package/kit/framework/templates/research.md +419 -419
  222. package/kit/framework/templates/retrospective.md +54 -54
  223. package/kit/framework/templates/roadmap.md +202 -202
  224. package/kit/framework/templates/state.md +176 -176
  225. package/kit/framework/templates/summary-complex.md +59 -59
  226. package/kit/framework/templates/summary-minimal.md +41 -41
  227. package/kit/framework/templates/summary-standard.md +48 -48
  228. package/kit/framework/templates/summary.md +209 -209
  229. package/kit/framework/templates/user-profile.md +146 -146
  230. package/kit/framework/templates/user-setup.md +256 -256
  231. package/kit/framework/templates/verification-report.md +258 -258
  232. package/kit/framework/workflows/add-phase.md +112 -112
  233. package/kit/framework/workflows/add-tests.md +351 -351
  234. package/kit/framework/workflows/add-todo.md +158 -158
  235. package/kit/framework/workflows/audit-milestone.md +340 -340
  236. package/kit/framework/workflows/audit-uat.md +109 -109
  237. package/kit/framework/workflows/autonomous.md +891 -891
  238. package/kit/framework/workflows/check-todos.md +177 -177
  239. package/kit/framework/workflows/cleanup.md +152 -152
  240. package/kit/framework/workflows/complete-milestone.md +696 -696
  241. package/kit/framework/workflows/diagnose-issues.md +231 -231
  242. package/kit/framework/workflows/discovery-phase.md +289 -289
  243. package/kit/framework/workflows/discuss-phase-assumptions.md +653 -653
  244. package/kit/framework/workflows/discuss-phase.md +784 -784
  245. package/kit/framework/workflows/do.md +104 -104
  246. package/kit/framework/workflows/execute-phase.md +838 -838
  247. package/kit/framework/workflows/execute-plan.md +510 -510
  248. package/kit/framework/workflows/fast.md +102 -102
  249. package/kit/framework/workflows/forensics.md +265 -265
  250. package/kit/framework/workflows/health.md +181 -181
  251. package/kit/framework/workflows/help.md +619 -619
  252. package/kit/framework/workflows/insert-phase.md +130 -130
  253. package/kit/framework/workflows/list-phase-assumptions.md +178 -178
  254. package/kit/framework/workflows/list-workspaces.md +56 -56
  255. package/kit/framework/workflows/manager.md +362 -362
  256. package/kit/framework/workflows/map-codebase.md +377 -377
  257. package/kit/framework/workflows/milestone-summary.md +223 -223
  258. package/kit/framework/workflows/new-milestone.md +486 -486
  259. package/kit/framework/workflows/new-project.md +1159 -1159
  260. package/kit/framework/workflows/new-workspace.md +237 -237
  261. package/kit/framework/workflows/next.md +97 -97
  262. package/kit/framework/workflows/node-repair.md +92 -92
  263. package/kit/framework/workflows/note.md +156 -156
  264. package/kit/framework/workflows/pause-work.md +176 -176
  265. package/kit/framework/workflows/plan-milestone-gaps.md +273 -273
  266. package/kit/framework/workflows/plan-phase.md +765 -765
  267. package/kit/framework/workflows/plant-seed.md +169 -169
  268. package/kit/framework/workflows/pr-branch.md +129 -129
  269. package/kit/framework/workflows/profile-user.md +450 -450
  270. package/kit/framework/workflows/progress.md +507 -507
  271. package/kit/framework/workflows/quick.md +757 -757
  272. package/kit/framework/workflows/remove-phase.md +155 -155
  273. package/kit/framework/workflows/remove-workspace.md +90 -90
  274. package/kit/framework/workflows/research-phase.md +82 -82
  275. package/kit/framework/workflows/resume-project.md +326 -326
  276. package/kit/framework/workflows/review.md +228 -228
  277. package/kit/framework/workflows/session-report.md +146 -146
  278. package/kit/framework/workflows/settings.md +283 -283
  279. package/kit/framework/workflows/ship.md +228 -228
  280. package/kit/framework/workflows/stats.md +60 -60
  281. package/kit/framework/workflows/transition.md +671 -671
  282. package/kit/framework/workflows/ui-phase.md +302 -302
  283. package/kit/framework/workflows/ui-review.md +165 -165
  284. package/kit/framework/workflows/update.md +323 -323
  285. package/kit/framework/workflows/validate-phase.md +174 -174
  286. package/kit/framework/workflows/verify-phase.md +252 -252
  287. package/kit/framework/workflows/verify-work.md +637 -637
  288. package/kit/hooks/check-update.js +118 -118
  289. package/kit/hooks/context-monitor.js +163 -163
  290. package/kit/hooks/kit-attribution-reminder.cjs +29 -50
  291. package/kit/hooks/kit-router.cjs +137 -0
  292. package/kit/hooks/prompt-guard.js +103 -103
  293. package/kit/hooks/statusline.js +125 -125
  294. package/kit/hooks/workflow-guard.js +101 -101
  295. package/kit/settings.json +45 -45
  296. package/kit/skills/ai-prompt-characterization/SKILL.md +335 -335
  297. package/kit/skills/armadilhas-sistemas-distribuidos/SKILL.md +447 -447
  298. package/kit/skills/audit-log-multi-tenant/SKILL.md +340 -340
  299. package/kit/skills/b2b-saas-architecture/SKILL.md +300 -300
  300. package/kit/skills/consistencia-leitura-replica/SKILL.md +385 -385
  301. package/kit/skills/crm-lead-pipeline-patterns/SKILL.md +343 -343
  302. package/kit/skills/escolha-modelo-consistencia/SKILL.md +494 -494
  303. package/kit/skills/evolucao-schema-compativel/SKILL.md +448 -448
  304. package/kit/skills/evolution-go-whatsapp-integration/SKILL.md +322 -322
  305. package/kit/skills/example-skill/SKILL.md +42 -42
  306. package/kit/skills/legacy-api-only-applications/SKILL.md +358 -358
  307. package/kit/skills/legacy-characterization-tests/SKILL.md +330 -330
  308. package/kit/skills/legacy-effect-analysis/SKILL.md +331 -331
  309. package/kit/skills/legacy-extract-class/SKILL.md +203 -203
  310. package/kit/skills/legacy-programming-by-difference/SKILL.md +252 -252
  311. package/kit/skills/legacy-seams-and-test-harness/SKILL.md +460 -460
  312. package/kit/skills/legacy-shotgun-surgery/SKILL.md +286 -286
  313. package/kit/skills/legacy-sprout-wrap-techniques/SKILL.md +434 -434
  314. package/kit/skills/legacy-storytelling-naked-crc/SKILL.md +270 -270
  315. package/kit/skills/lgpd-multi-tenant-compliance/SKILL.md +340 -340
  316. package/kit/skills/member-invite-flow/SKILL.md +305 -305
  317. package/kit/skills/member-management-react-shadcn/SKILL.md +328 -328
  318. package/kit/skills/multi-tenant-performance-scaling/SKILL.md +316 -316
  319. package/kit/skills/multi-tenant-rls-hierarchy/SKILL.md +342 -342
  320. package/kit/skills/org-onboarding-flow/SKILL.md +257 -257
  321. package/kit/skills/org-switcher-react-pattern/SKILL.md +349 -349
  322. package/kit/skills/permission-gate-react-pattern/SKILL.md +271 -271
  323. package/kit/skills/postgres-isolamento-concorrencia/SKILL.md +552 -552
  324. package/kit/skills/pre-refactor-characterization/SKILL.md +421 -421
  325. package/kit/skills/rbac-permissions-matrix-supabase/SKILL.md +338 -338
  326. package/kit/skills/streams-eventos-cdc/SKILL.md +711 -711
  327. package/kit/skills/supabase-auth-hardening/SKILL.md +674 -0
  328. package/kit/skills/supabase-auth-hooks/SKILL.md +875 -0
  329. package/kit/skills/supabase-auth-methods/SKILL.md +486 -0
  330. package/kit/skills/supabase-auth-sessions/SKILL.md +579 -0
  331. package/kit/skills/supabase-auth-ssr/SKILL.md +60 -14
  332. package/kit/skills/supabase-branching-workflow/SKILL.md +544 -544
  333. package/kit/skills/supabase-ci-cd-github-actions/SKILL.md +880 -880
  334. package/kit/skills/supabase-column-level-security/SKILL.md +426 -426
  335. package/kit/skills/supabase-config-toml-remotes/SKILL.md +807 -807
  336. package/kit/skills/supabase-custom-claims-rbac/SKILL.md +472 -472
  337. package/kit/skills/supabase-edge-functions/SKILL.md +1 -1
  338. package/kit/skills/supabase-edge-functions-auth/SKILL.md +1 -1
  339. package/kit/skills/supabase-edge-functions-limits/SKILL.md +1 -1
  340. package/kit/skills/supabase-edge-functions-mcp-server/SKILL.md +1 -1
  341. package/kit/skills/supabase-edge-functions-testing/SKILL.md +1 -1
  342. package/kit/skills/supabase-edge-runtime-builtins/SKILL.md +1 -1
  343. package/kit/skills/supabase-enterprise-sso-saml/SKILL.md +545 -0
  344. package/kit/skills/supabase-jwt-signing-keys/SKILL.md +399 -0
  345. package/kit/skills/supabase-mfa/SKILL.md +488 -0
  346. package/kit/skills/supabase-migration-repair/SKILL.md +823 -823
  347. package/kit/skills/supabase-migrations/SKILL.md +297 -297
  348. package/kit/skills/supabase-oauth-server/SKILL.md +537 -0
  349. package/kit/skills/supabase-pgtap-testing/SKILL.md +1053 -1053
  350. package/kit/skills/supabase-postgres-roles/SKILL.md +392 -392
  351. package/kit/skills/supabase-realtime/SKILL.md +460 -460
  352. package/kit/skills/supabase-rls-defense-in-depth/SKILL.md +418 -418
  353. package/kit/skills/supabase-rls-policies/SKILL.md +635 -635
  354. package/kit/skills/supabase-social-oauth/SKILL.md +480 -0
  355. package/kit/skills/supabase-third-party-auth/SKILL.md +450 -0
  356. package/kit/skills/super-admin-platform-pattern/SKILL.md +326 -326
  357. package/kit/skills/tenant-quente-mitigacao/SKILL.md +605 -605
  358. package/kit/skills/whatsapp-conversation-state-machine/SKILL.md +287 -287
  359. package/package.json +1 -1
  360. package/src/core/kit.js +216 -216
  361. package/src/core/reflect.js +247 -247
  362. package/src/core/reverse-sync.js +372 -372
  363. package/src/core/sync.js +437 -418
  364. package/src/core/watch.js +121 -121
  365. package/src/mcp-server/index.js +794 -746
@@ -1,823 +1,823 @@
1
- ---
2
- name: supabase-migration-repair
3
- description: Use ao diagnosticar e reparar sync errors entre local supabase/migrations/ e remote supabase_migrations.schema_migrations tracking table…
4
- ---
5
-
6
- # Supabase — Migration Repair
7
-
8
- ## Quando usar
9
-
10
- Use esta skill ao enfrentar **sync errors** ou **estado inconsistente** entre o folder local `supabase/migrations/` e a tracking table remota `supabase_migrations.schema_migrations`, ou ao precisar de rollback de preview branch após migration falha.
11
-
12
- Trigger phrases:
13
-
14
- - "migration repair", "supabase migration repair"
15
- - "sync error Supabase", "migration history mismatch"
16
- - "supabase migration list mostra mismatch"
17
- - "schema drift Supabase", "git rebase migration timestamps"
18
- - "permission denied migration", "permission denied for table _type"
19
- - "permission denied 42501 Supabase", "custom_role to postgres"
20
- - "rollback preview branch Supabase"
21
- - "db push falhando re-aplicar migration"
22
- - "db pull pg_dump error graphql"
23
-
24
- **Use esta skill APENAS para:**
25
-
26
- - Diagnosticar mismatch entre folder local e tracking table remoto
27
- - Corrigir history record em `supabase_migrations.schema_migrations` quando schema state real está OK
28
- - Rollback de preview branch ephemeral via PR close+reopen (cross-ref skill `supabase-branching-workflow` Phase 149)
29
- - Resolver drift de timestamps após git rebase em equipe
30
- - Resolver erros `42501 permission denied` e `pg_dump error permission denied for table _type`
31
-
32
- **NÃO use esta skill para:**
33
-
34
- - Reverter mudanças de schema reais — `migration repair` NÃO reverte SQL (cross-ref CAVEAT CRÍTICO abaixo)
35
- - Substituir testes de migration — preview branch + DAG step 5 (cross-ref skill `supabase-branching-workflow` Phase 149) é o gate canônico
36
- - Bypassar migration files aplicando schema changes via Dashboard SQL editor — isso CRIA o problema que esta skill diagnostica
37
- - Recovery de production database com data loss — backup + point-in-time recovery do Supabase (fora do escopo desta skill)
38
-
39
- ## Princípio canônico
40
-
41
- Três princípios canônicos sustentam toda a skill:
42
-
43
- ### Princípio 1 — Tracking table state ≠ schema state real
44
-
45
- A tracking table `supabase_migrations.schema_migrations` é um **registro de histórico** de quais migrations foram aplicadas. O **schema state real** é o estado físico do DB (tabelas, colunas, indices, funções, policies).
46
-
47
- Os dois podem divergir:
48
-
49
- | Schema real | Tracking table | Causa | Sintoma |
50
- |---|---|---|---|
51
- | Tabela `foo` existe | Sem registro 20240102 | Migration aplicada manualmente via Dashboard SQL editor | `db push` tenta re-aplicar 20240102 e falha com "relation foo already exists" |
52
- | Tabela `foo` NÃO existe | Com registro 20240102 | Tracking table corrupto / migration teve rollback parcial | `db push` skip 20240102 mas tabela ausente |
53
- | Tabela `foo` existe | Com registro 20240102 | Estado normal — sincronizado | Nenhum |
54
- | Tabela `foo` NÃO existe | Sem registro 20240102 | Nada aplicado ainda — pendente | `db push` aplica 20240102 normalmente |
55
-
56
- ### Princípio 2 — Diagnose ANTES de repair
57
-
58
- NUNCA execute `supabase migration repair` sem primeiro rodar `supabase migration list` para entender QUAL migration está em qual estado de mismatch. Repair cego pode mascarar bug + tornar recovery mais difícil.
59
-
60
- ### Princípio 3 — Rollback preview preferível a manual revert
61
-
62
- Para preview branches Supabase Branching (Phase 149), **delete+reopen do PR** é canônico e seguro. Tentar criar "reverter migration" manualmente para desfazer schema changes em preview branch é anti-pattern — preview branches são ephemeral by design (cross-ref skill `supabase-branching-workflow` Phase 149).
63
-
64
- ## CAVEAT CRÍTICO — Tracking table apenas
65
-
66
- > **`supabase migration repair` atualiza APENAS a tracking table `supabase_migrations.schema_migrations`. NÃO aplica SQL nem reverte SQL.**
67
- >
68
- > Este caveat é repetido **DUAS VEZES** nesta skill (Pattern 2 + abaixo) porque é a fonte #1 de bugs em recovery de migrations Supabase. LLMs e humanos frequentemente assumem que `repair --status reverted` "desfaz" a migration — **NÃO DESFAZ**.
69
- >
70
- > Se a migration realmente alterou schema (criou tabela, alterou coluna, etc.), `repair --status reverted` APENAS remove o registro do histórico. As mudanças físicas no DB **permanecem**. Para reverter mudanças de schema reais:
71
- >
72
- > 1. Criar **nova migration** que desfaz as mudanças (`drop table ...`, `alter table ... drop column ...`)
73
- > 2. Aplicar via `supabase db push`
74
- > 3. NÃO usar `repair --status reverted` esperando reverter SQL
75
-
76
- ## Pattern 1: Diagnóstico via `supabase migration list` (REPAIR-01)
77
-
78
- Primeira ação canônica em qualquer cenário de migration error — **sempre** começar por aqui.
79
-
80
- ### Comando
81
-
82
- ```bash
83
- supabase migration list
84
- ```
85
-
86
- ### Output canônico
87
-
88
- ```
89
- LOCAL │ REMOTE │ TIME (UTC)
90
- ─────────────────────┼────────────────┼─────────────────────
91
- 20240101120000 │ 20240101120000 │ 2024-01-01 12:00:00
92
- 20240102140000 │ - │ 2024-01-02 14:00:00
93
- - │ 20240103160000 │ 2024-01-03 16:00:00
94
- ```
95
-
96
- ### Interpretação canônica das 3 colunas
97
-
98
- | Coluna | Significado |
99
- |---|---|
100
- | **LOCAL** | Timestamp encontrado em `supabase/migrations/*.sql` (folder local do repo git) |
101
- | **REMOTE** | Timestamp registrado em `supabase_migrations.schema_migrations` (tracking table no DB remoto) |
102
- | **TIME (UTC)** | Quando foi aplicada (presente apenas quando coluna REMOTE tem valor) |
103
-
104
- ### 3 estados canônicos por linha
105
-
106
- **Estado 1: sincronizado**
107
-
108
- ```
109
- 20240101120000 │ 20240101120000 │ 2024-01-01 12:00:00
110
- ```
111
-
112
- Migration presente em ambos — estado **normal**, nenhuma ação necessária.
113
-
114
- **Estado 2: local-only (pending push)**
115
-
116
- ```
117
- 20240102140000 │ - │ 2024-01-02 14:00:00
118
- ```
119
-
120
- Migration existe no folder local mas NÃO foi aplicada no remote. Ação canônica:
121
-
122
- ```bash
123
- supabase db push
124
- ```
125
-
126
- Aplica migrations pendentes em ordem cronológica.
127
-
128
- **Estado 3: remote-only (drift)**
129
-
130
- ```
131
- - │ 20240103160000 │ 2024-01-03 16:00:00
132
- ```
133
-
134
- Migration foi aplicada no remote (registrada na tracking table) MAS o arquivo `.sql` correspondente NÃO existe no folder local. Causas possíveis:
135
-
136
- - Migration aplicada manualmente via Dashboard SQL editor sem commit no git
137
- - Outro dev aplicou migration e ainda não pushou para git remoto
138
- - Arquivo local foi deletado por engano
139
-
140
- Ação canônica:
141
-
142
- ```bash
143
- supabase db pull
144
- ```
145
-
146
- Gera arquivo `.sql` local correspondente à migration registrada no remote. Sincroniza folder local com tracking table.
147
-
148
- ### Comportamento canônico de `supabase db push`
149
-
150
- `supabase db push` compara local folder vs remote tracking table:
151
-
152
- 1. Lista migrations em `supabase/migrations/*.sql` (folder local)
153
- 2. Lista migrations em `supabase_migrations.schema_migrations` (tracking table)
154
- 3. Calcula diff: migrations no folder MAS não na tracking table
155
- 4. Aplica em ordem cronológica (por timestamp) — registra cada uma na tracking table após sucesso
156
-
157
- **Caveat — tracking table é fonte de verdade para "o que foi aplicado":**
158
-
159
- Se você deleta o folder local, `db push` NÃO re-aplica migrations já registradas na tracking table. Para forçar re-aplicação, precisa:
160
-
161
- 1. `db pull` para regenerar folder local a partir do remote, OU
162
- 2. `migration repair --status reverted <timestamp>` para remover o registro da tracking table (CAVEAT CRÍTICO repetido — isso só remove o registro, NÃO reverte schema)
163
-
164
- ### Estrutura interna da tracking table
165
-
166
- ```sql
167
- -- estrutura canônica da tracking table (não modificar manualmente)
168
- \d supabase_migrations.schema_migrations
169
-
170
- Column │ Type
171
- ──────────────────┼─────────────────────────
172
- version │ text NOT NULL PRIMARY KEY
173
- name │ text
174
- statements │ text[]
175
- ```
176
-
177
- - `version` — timestamp da migration (PK)
178
- - `name` — descrição da migration
179
- - `statements` — array com SQL aplicado (audit trail)
180
-
181
- **NUNCA modifique esta tabela diretamente.** Use `migration repair` (Pattern 2) para mutação segura via CLI.
182
-
183
- ## Pattern 2: `migration repair --status applied|reverted` (REPAIR-02)
184
-
185
- > **CAVEAT CRÍTICO REPETIDO — tracking table apenas:**
186
- >
187
- > `supabase migration repair` atualiza APENAS a tracking table `supabase_migrations.schema_migrations`. **NÃO aplica SQL nem reverte SQL.**
188
- >
189
- > Se a migration realmente alterou schema, `repair --status reverted` remove o registro do histórico MAS as mudanças físicas no DB **permanecem**. Para reverter schema changes reais, crie nova migration via `supabase migration new`.
190
-
191
- ### Sintaxe canônica
192
-
193
- ```bash
194
- supabase migration repair --status <applied|reverted> <migration-timestamp>
195
- ```
196
-
197
- Dois subcomandos canônicos:
198
-
199
- - `--status applied <timestamp>` — adiciona registro à tracking table (marca como aplicada)
200
- - `--status reverted <timestamp>` — remove registro da tracking table (marca como reverted)
201
-
202
- ### Caso 1 — Migration aplicada manualmente (precisa marcar como applied)
203
-
204
- **Cenário:**
205
-
206
- - Dev abriu Dashboard → SQL editor → executou `CREATE TABLE foo (...)` direto no DB remoto
207
- - Schema state OK (tabela existe), mas tracking table NÃO tem registro
208
- - Posteriormente, dev criou migration `20240102_create_foo.sql` no folder local com o mesmo SQL
209
- - `supabase db push` lista migration como pending → tenta aplicar → falha com `relation "foo" already exists`
210
-
211
- **Diagnóstico:**
212
-
213
- ```bash
214
- supabase migration list
215
- # Output:
216
- # 20240102140000 │ - │ 2024-01-02 14:00:00
217
- ```
218
-
219
- Confirma migration está local-only — porém schema state real tem a tabela. Repair canônico:
220
-
221
- ```bash
222
- supabase migration repair --status applied 20240102140000
223
- ```
224
-
225
- **O que acontece:**
226
-
227
- - Tracking table recebe novo registro: `INSERT INTO supabase_migrations.schema_migrations (version, name) VALUES ('20240102140000', 'create_foo')`
228
- - Schema state físico NÃO é alterado (tabela `foo` continua existindo, sem nenhuma operação SQL extra)
229
- - Próximo `supabase migration list` mostra migration sincronizada
230
-
231
- **Quando usar este caso:**
232
-
233
- - Hotfix aplicado emergencialmente via Dashboard SQL editor sem migration file
234
- - Migration aplicada manualmente em ambiente novo (ex: replicar schema de produção)
235
- - Schema gerado por ferramenta externa (Drizzle, Prisma) onde tracking table está fora de sync
236
-
237
- ### Caso 2 — Migration registrada mas nunca aplicada (precisa marcar como reverted)
238
-
239
- **Cenário:**
240
-
241
- - Tracking table tem registro `20240102140000` MAS schema state real NÃO tem a tabela criada por essa migration
242
- - Causas possíveis: tracking table corrupto, migration teve rollback parcial, restore parcial de backup
243
-
244
- **Diagnóstico:**
245
-
246
- ```bash
247
- supabase migration list
248
- # Output:
249
- # 20240102140000 │ 20240102140000 │ 2024-01-02 14:00:00
250
- ```
251
-
252
- Aparenta sincronizado, mas tabela não existe. Confirmar via:
253
-
254
- ```sql
255
- -- conectar via psql ou Dashboard SQL editor
256
- select table_name from information_schema.tables where table_schema = 'public' and table_name = 'foo';
257
- -- 0 rows
258
- ```
259
-
260
- Repair canônico:
261
-
262
- ```bash
263
- supabase migration repair --status reverted 20240102140000
264
- ```
265
-
266
- **O que acontece:**
267
-
268
- - Tracking table tem registro DELETADO: `DELETE FROM supabase_migrations.schema_migrations WHERE version = '20240102140000'`
269
- - Schema state físico NÃO é alterado (tabela `foo` continua não existindo — `repair` não cria nada)
270
- - `supabase db push` agora considera migration como pending → aplica normalmente
271
-
272
- **Quando usar este caso:**
273
-
274
- - Tracking table está fora de sync por motivo desconhecido
275
- - Migration tem registro mas schema state real não reflete (tabela ausente, coluna ausente, etc.)
276
- - Precisa "forçar" re-aplicação de migration via `db push` após confirmar que schema real não tem as mudanças
277
-
278
- ### Anti-uso CRÍTICO — não usar para reverter schema
279
-
280
- ```bash
281
- # ERRADO — esperar que isso reverta a tabela criada pela migration
282
- supabase migration repair --status reverted 20240102140000
283
- ```
284
-
285
- **Por quê:** apenas remove o registro. A tabela `foo` continua existindo. Próximo `supabase db push` vai tentar aplicar a migration novamente, falhar com `relation already exists`, e você fica em loop infinito.
286
-
287
- **Certo — para reverter schema changes reais:**
288
-
289
- ```bash
290
- # 1. Criar nova migration que desfaz as mudanças
291
- supabase migration new drop_foo
292
-
293
- # 2. Editar arquivo gerado supabase/migrations/<novo-timestamp>_drop_foo.sql:
294
- # drop table if exists public.foo;
295
-
296
- # 3. Aplicar
297
- supabase db push
298
- ```
299
-
300
- ### Fluxograma canônico de decisão
301
-
302
- ```
303
- Sync error em supabase migration list?
304
-
305
- ├─ Local-only (LOCAL=X, REMOTE=-)
306
- │ │
307
- │ ├─ Schema real TEM as mudanças?
308
- │ │ ├─ SIM → repair --status applied <X>
309
- │ │ └─ NÃO → supabase db push (aplicação normal)
310
- │ │
311
-
312
- ├─ Remote-only (LOCAL=-, REMOTE=Y)
313
- │ │
314
- │ ├─ Schema real TEM as mudanças?
315
- │ │ ├─ SIM → supabase db pull (regenera arquivo local)
316
- │ │ └─ NÃO → repair --status reverted <Y> (limpa registro órfão)
317
-
318
- └─ Aparenta sincronizado mas erros persistem
319
-
320
- ├─ Conectar via psql + verificar schema state real
321
- └─ Decidir entre repair vs nova migration baseado em estado
322
- ```
323
-
324
- ## Pattern 3: Rollback preview branch via delete + reopen (REPAIR-03)
325
-
326
- Quando uma migration ruim foi pushada para preview branch Supabase Branching e DAG falhou no step 5 (migrate), o **canônico** é NÃO criar reverter migration — use rollback via PR close+reopen.
327
-
328
- ### Workflow canônico (5 passos)
329
-
330
- ```
331
- 1. Dev pusha migration ruim em PR
332
-
333
- 2. Supabase webhook → DAG step 5 (migrate) FALHA
334
- ↓ status no PR: "Supabase Preview ✗"
335
-
336
- 3. Dev fecha PR (GitHub UI: "Close pull request")
337
-
338
- 4. Supabase Branching detecta PR closed → DELETA preview branch
339
- ↓ (cleanup completo: DB, Edge Functions, Storage config)
340
-
341
- 5. Dev fixa migration + reopen PR (GitHub UI: "Reopen pull request")
342
-
343
- 6. Supabase Branching detecta PR reopened → CRIA novo preview branch
344
- ↓ DAG roda steps 1-7 do zero com migration corrigida
345
- ```
346
-
347
- ### Equivalência canônica
348
-
349
- **Delete preview branch + reopen** = **`supabase db reset` local**.
350
-
351
- Ambos:
352
-
353
- - Limpam DB state completamente
354
- - Re-executam todas migrations em ordem cronológica
355
- - Re-aplicam `supabase/seed.sql`
356
- - Resetam Edge Functions para versão atual do branch git
357
-
358
- ### Caveats canônicos
359
-
360
- **Caveat 1 — Data changes adicionais SÃO PERDIDOS**
361
-
362
- `seed.sql` é re-aplicado como dataless setup. Quaisquer rows inseridas/atualizadas manualmente durante uso do preview branch:
363
-
364
- - Via Dashboard Table editor
365
- - Via testes manuais (insert, update direto)
366
- - Via Edge Function execution (que escreveu em tabelas)
367
-
368
- **são perdidas** no reset. Aceito como trade-off canônico para reset limpo — preview branches são ephemeral by design (cross-ref skill `supabase-branching-workflow` Phase 149).
369
-
370
- **Caveat 2 — Auto-pause em inatividade NÃO substitui reset**
371
-
372
- Preview branches auto-pausam após inatividade (~24h sem requests), mas isso preserva o state. NÃO é equivalente a reset. Para limpeza real, sempre use close+reopen.
373
-
374
- **Caveat 3 — Branching Compute Hours acumulam novamente**
375
-
376
- Reopen recria preview branch do zero → nova hora de Branching Compute Hours é cobrada (cross-ref skill `supabase-branching-workflow` Phase 149 — Pattern 5 custo). Se rollback acontece 5× para o mesmo PR, são 5 horas extras cobradas. Considere disciplina: testar migration localmente antes de push.
377
-
378
- ### Quando usar este pattern
379
-
380
- - Migration ruim foi pushada para preview branch
381
- - DAG step 5 (migrate) falhou — sem possibilidade de recovery via re-push (porque o branch já está em estado "failed")
382
- - Você quer voltar ao estado limpo sem aplicar reverter migration manualmente
383
- - Aceita perda de data changes adicionais que não estavam em seed.sql
384
-
385
- ### Quando NÃO usar este pattern
386
-
387
- - Persistent branches (staging/QA) — NÃO use delete+reopen; persistent branches são long-lived (cross-ref skill `supabase-branching-workflow` Phase 149 — Pattern 1)
388
- - Production project — production NUNCA tem rollback via "close PR" — use migration de reversão + `db push` + cuidados extras (backup + monitoramento)
389
- - Quando você precisa preservar data changes — não há recovery dos dados após delete
390
-
391
- ### Workflow alternativo: push corrected migration
392
-
393
- Se o branch ainda está em estado "failed" mas branch ainda existe (PR não foi fechado):
394
-
395
- ```
396
- 1. Identificar root cause via Dashboard → branch deployment logs (step 5 stderr)
397
- 2. Corrigir migration localmente
398
- 3. git commit + git push (mesmo PR)
399
- 4. Supabase webhook detecta push → re-run DAG do step 1
400
- 5. Se passa step 5 → step 6 (seed) e step 7 (deploy) executam
401
- ```
402
-
403
- Este workflow é **preferível** se o erro foi simples (typo, syntax error) — evita Branching Compute Hours extras do reset.
404
-
405
- ## Pattern 4: Schema drift após git rebase (REPAIR-04)
406
-
407
- Cenário canônico em equipes que mergem migrations em paralelo via PRs em main.
408
-
409
- ### Problema canônico
410
-
411
- ```
412
- Timeline:
413
- T = Dev A cria PR-A com migration 20240106120000_dev_A.sql
414
- T+1 = Dev B cria PR-B com migration 20240106130000_dev_B.sql
415
- T+2 = PR-B é merged primeiro (dev_B agora está em main)
416
- T+3 = Dev A faz git pull origin main → traz dev_B
417
- T+4 = Dev A faz git rebase main em sua branch
418
- T+5 = Estado: branch de Dev A tem dev_B (timestamp 13:00) + dev_A (timestamp 12:00)
419
- ```
420
-
421
- **Problema:** após rebase, Dev A tem migrations em ordem:
422
-
423
- ```
424
- supabase/migrations/
425
- ├── 20240106120000_dev_A.sql (mais antiga)
426
- ├── 20240106130000_dev_B.sql (mais nova)
427
- ```
428
-
429
- Local `supabase db reset` aplica em ordem cronológica:
430
-
431
- 1. Aplica `20240106120000_dev_A.sql` PRIMEIRO
432
- 2. Aplica `20240106130000_dev_B.sql` DEPOIS
433
-
434
- Se `dev_A` depende de schema state que só existe APÓS `dev_B` (ex: dev_A adiciona FK para tabela que dev_B criou), `supabase db reset` falha.
435
-
436
- **Pior:** quando `db push` para production, ordem cronológica força dev_A primeiro → falha em produção.
437
-
438
- ### Solução canônica (4 passos)
439
-
440
- ```bash
441
- # Passo 1: Pull main (traz migrations recentes da equipe)
442
- git pull origin main
443
-
444
- # Passo 2: Criar nova migration com timestamp atualizado (placeholder)
445
- supabase migration new dev_A
446
- # Cria: supabase/migrations/20240106140000_dev_A.sql (timestamp ATUAL, mais novo)
447
-
448
- # Passo 3: Renomear migration antiga para o novo timestamp
449
- mv supabase/migrations/20240106120000_dev_A.sql supabase/migrations/20240106140000_dev_A.sql
450
-
451
- # (Passo 2 criou arquivo vazio; passo 3 sobrescreve com conteúdo correto)
452
-
453
- # Passo 4: Reset local para reaplicar tudo em ordem cronológica correta
454
- supabase db reset
455
- ```
456
-
457
- ### Resultado final
458
-
459
- ```
460
- supabase/migrations/
461
- ├── 20240106130000_dev_B.sql (do teammate, vem primeiro)
462
- ├── 20240106140000_dev_A.sql (renomeada com timestamp posterior, vem depois)
463
- ```
464
-
465
- `supabase db reset` aplica em ordem correta:
466
-
467
- 1. Aplica `20240106130000_dev_B.sql` (tabela criada por dev_B)
468
- 2. Aplica `20240106140000_dev_A.sql` (FK funciona porque tabela já existe)
469
-
470
- ### Princípio canônico
471
-
472
- > **Changes que dependem de earlier changes DEVEM ter later timestamps.**
473
- >
474
- > Append-only migration history não tolera reordering retroativo. Se você precisa ordenar migration A antes de B mas A tem timestamp mais antigo, **renomeie** A para timestamp posterior a B.
475
-
476
- ### Cuidado canônico — git history
477
-
478
- Após `mv supabase/migrations/<old>.sql supabase/migrations/<new>.sql`:
479
-
480
- ```bash
481
- # git detecta como rename (boa preservação de history)
482
- git status
483
- # renamed: supabase/migrations/20240106120000_dev_A.sql -> supabase/migrations/20240106140000_dev_A.sql
484
-
485
- git add supabase/migrations/
486
- git commit -m "fix: rebase migration dev_A após merge de dev_B em main"
487
- ```
488
-
489
- ### Caveat — se a migration JÁ FOI PUSHADA para preview/staging
490
-
491
- Se sua migration `dev_A` já foi pushada para preview branch e DAG executou (mesmo se falhou), a tracking table do preview tem registro `20240106120000`. Renomear o arquivo local cria mismatch:
492
-
493
- - Local folder: `20240106140000_dev_A.sql` (renomeado)
494
- - Tracking table preview: `20240106120000` (registro antigo)
495
-
496
- Solução canônica nesse caso:
497
-
498
- 1. Renomear arquivo localmente (passos 1-4 acima)
499
- 2. Close+reopen PR (Pattern 3 — rollback preview) → recria preview branch do zero
500
- 3. Push do branch corrigido → DAG roda com timestamp correto
501
-
502
- ### Quando este pattern NÃO se aplica
503
-
504
- - Migrations independentes (não há dependência de ordem) — pode ignorar drift, ordem cronológica resolve corretamente
505
- - Migrations já aplicadas em produção — NÃO renomeie migrations em produção; cria mismatch entre tracking table e folder local. Use forward-only migration de correção.
506
-
507
- ## Pattern 5: Permission denied troubleshooting (REPAIR-05)
508
-
509
- Dois casos canônicos documentados na doc oficial Supabase — ambos exigem aplicação manual de GRANT via Dashboard SQL Editor.
510
-
511
- ### Caso 1 — db pull erro "permission denied for table _type"
512
-
513
- #### Erro completo
514
-
515
- ```
516
- $ supabase db pull
517
- Error: Error running pg_dump on remote database:
518
- pg_dump: error: query failed: ERROR: permission denied for table _type
519
- pg_dump: error: query was: LOCK TABLE "graphql"."_type" IN ACCESS SHARE MODE
520
- ```
521
-
522
- #### Causa canônica
523
-
524
- Projetos Supabase **antigos** (criados antes da introdução do GraphQL schema com grants padrão) NÃO têm GRANTs corretos em `graphql._type`. `pg_dump` requer LOCK ACCESS SHARE em todas as tabelas do schema para snapshot consistente — falha sem GRANT.
525
-
526
- #### Solução canônica
527
-
528
- Executar no **Dashboard → SQL Editor** (não em migration file porque é one-time fix para schema graphql gerenciado pelo Supabase):
529
-
530
- ```sql
531
- grant all on all tables in schema graphql to postgres, anon, authenticated, service_role;
532
- grant all on all functions in schema graphql to postgres, anon, authenticated, service_role;
533
- grant all on all sequences in schema graphql to postgres, anon, authenticated, service_role;
534
- ```
535
-
536
- #### Verificação após fix
537
-
538
- ```bash
539
- supabase db pull
540
- # Output esperado: "Schema pulled successfully" sem erro de permission denied
541
- ```
542
-
543
- #### Caveat canônico — projetos novos
544
-
545
- Projetos criados após 2024 vêm com esses GRANTs configurados automaticamente. Se você está em projeto criado recentemente e ainda recebe esse erro, verifique se há roles customizadas que precisam de GRANT também:
546
-
547
- ```sql
548
- -- exemplo: se você criou role "data_team_reader" e quer permitir db pull com ela
549
- grant all on all tables in schema graphql to data_team_reader;
550
- grant all on all functions in schema graphql to data_team_reader;
551
- grant all on all sequences in schema graphql to data_team_reader;
552
- ```
553
-
554
- ### Caso 2 — db push erro 42501 com custom role
555
-
556
- #### Erro completo
557
-
558
- ```
559
- $ supabase db push
560
- Applying migration 20240107120000_alter_orders.sql...
561
- ERROR: permission denied for table orders (SQLSTATE 42501)
562
- Error: failed to apply migration
563
- ```
564
-
565
- #### Causa canônica
566
-
567
- Tabela `orders` foi criada com **custom role** (ex: `app_admin` ou similar) em migration anterior. Quando `supabase db push` executa a próxima migration, o conexão é feita como role `postgres` (default do CLI), e `postgres` NÃO tem permission para modificar a tabela porque o owner é `app_admin`.
568
-
569
- SQLSTATE `42501` é o código canônico Postgres para "insufficient_privilege". Cross-ref skill `supabase-postgres-roles` (v1.26) para entendimento completo de custom roles.
570
-
571
- #### Solução canônica
572
-
573
- Conceder membership do custom role para `postgres`:
574
-
575
- ```sql
576
- grant "custom_role" to "postgres";
577
- ```
578
-
579
- Substituindo `custom_role` pelo nome real (ex: `app_admin`, `lead_manager`, etc.):
580
-
581
- ```sql
582
- -- exemplo concreto
583
- grant "app_admin" to "postgres";
584
- ```
585
-
586
- #### Como funciona
587
-
588
- - `grant "app_admin" to "postgres"` torna `postgres` **membro** do role `app_admin`
589
- - Por default, roles em Postgres usam INHERIT — `postgres` herda permissions de `app_admin`
590
- - Agora `postgres` consegue modificar tabelas que têm owner = `app_admin`
591
-
592
- #### Caveat canônico — INHERIT vs SET ROLE
593
-
594
- Se `app_admin` foi criado com NOINHERIT (cross-ref skill `supabase-postgres-roles` v1.26 — Pattern 3), simples GRANT membership NÃO é suficiente. `postgres` precisa `SET ROLE app_admin` explicitamente antes de cada operação:
595
-
596
- ```sql
597
- -- na migration (não recomendado, mas funciona)
598
- set role app_admin;
599
- alter table public.orders add column foo text;
600
- reset role;
601
- ```
602
-
603
- Solução **preferível** se você está em projeto novo: criar custom roles com INHERIT default (cross-ref skill `supabase-postgres-roles` v1.26 — Pattern 3).
604
-
605
- #### Quando aplicar este GRANT
606
-
607
- Aplique **uma única vez** após criar a custom role:
608
-
609
- ```sql
610
- -- na primeira migration que cria a custom role (cross-ref skill supabase-postgres-roles)
611
- create role "app_admin" noinherit;
612
- alter role "app_admin" with bypassrls;
613
- grant "app_admin" to "postgres"; -- ⚡ esta linha resolve o erro 42501
614
- ```
615
-
616
- Comments explicativos canônicos na migration:
617
-
618
- ```sql
619
- -- GRANT membership de app_admin para postgres
620
- -- Permite que supabase db push (conectado como postgres) modifique tabelas
621
- -- com owner app_admin sem precisar SET ROLE explícito.
622
- -- Sem isso: erro SQLSTATE 42501 ao alterar tabela.
623
- grant "app_admin" to "postgres";
624
- ```
625
-
626
- ### Tabela canônica — erros + soluções
627
-
628
- | Erro | SQLSTATE | Comando que dispara | Solução canônica |
629
- |---|---|---|---|
630
- | `permission denied for table _type` | (sem código) pg_dump error | `supabase db pull` | `grant all on all tables in schema graphql to postgres, anon, authenticated, service_role` |
631
- | `permission denied for table X` | 42501 | `supabase db push` | `grant "custom_role" to "postgres"` |
632
- | `relation X already exists` | 42P07 | `supabase db push` | `migration repair --status applied <timestamp>` (Pattern 2) |
633
- | `relation X does not exist` | 42P01 | `supabase db push` | Verificar ordem de migrations (Pattern 4) ou pull do remote (Pattern 1) |
634
-
635
- ## Anti-patterns
636
-
637
- ### Anti-pattern 1: Usar `migration repair --status reverted` esperando reverter SQL
638
-
639
- **Errado:**
640
-
641
- ```bash
642
- # Dev quer "desfazer" CREATE TABLE foo que migration 20240102 criou
643
- supabase migration repair --status reverted 20240102140000
644
- # Espera: tabela foo deletada
645
- # Realidade: apenas registro de tracking table removido — tabela foo continua existindo
646
- ```
647
-
648
- **Por quê:** `repair` é tracking-table-only. CAVEAT CRÍTICO repetido nesta skill (Pattern 2 + introdução). LLMs e humanos frequentemente assumem semantics de "rollback completo" — incorreto.
649
-
650
- **Sintoma do bug:** próximo `supabase db push` tenta re-aplicar a migration → falha com `relation "foo" already exists` (SQLSTATE 42P07) → loop infinito de tentativas de repair.
651
-
652
- **Certo:**
653
-
654
- ```bash
655
- # Para reverter schema changes reais, crie nova migration
656
- supabase migration new drop_foo
657
- # Editar arquivo gerado:
658
- # drop table if exists public.foo;
659
- supabase db push
660
- ```
661
-
662
- ### Anti-pattern 2: Schema changes direto no remote bypassing migration files
663
-
664
- **Errado:**
665
-
666
- ```sql
667
- -- Dev abre Dashboard → SQL Editor → executa direto no DB remoto:
668
- create table public.audit_log (
669
- id uuid primary key default gen_random_uuid(),
670
- event text not null,
671
- created_at timestamptz not null default now()
672
- );
673
-
674
- -- Sem commit no git, sem migration file, sem registro na tracking table
675
- ```
676
-
677
- **Por quê:** cria divergência canônica entre schema real (tabela existe) e tracking table (sem registro). Cross-ref Princípio 1. Próximo dev que clonar repo + rodar `supabase db reset` local NÃO terá a tabela.
678
-
679
- **Sintomas:**
680
-
681
- - Outros devs reportam "minha app não funciona, tabela audit_log não existe"
682
- - CI/CD pipeline falha em ambientes novos (preview branches, persistent staging)
683
- - `supabase db pull` mostra surpresas (tabela "remote-only")
684
-
685
- **Certo:**
686
-
687
- ```bash
688
- # 1. Criar migration file via CLI
689
- supabase migration new create_audit_log
690
-
691
- # 2. Editar arquivo gerado com SQL (incluindo GRANTs + RLS — cross-ref skill supabase-migrations)
692
- # supabase/migrations/<timestamp>_create_audit_log.sql
693
-
694
- # 3. Testar localmente
695
- supabase db reset
696
-
697
- # 4. Commit + push + PR (cross-ref skill supabase-branching-workflow Phase 149)
698
- git add supabase/migrations/
699
- git commit -m "feat: add audit_log table"
700
- git push
701
- # Abre PR → preview branch criado → DAG step 5 valida migration
702
- ```
703
-
704
- ### Anti-pattern 3: Não rebase local antes de db push em equipe
705
-
706
- **Errado:**
707
-
708
- ```
709
- Dev A workflow:
710
- 1. Cria branch feature-A com migration 20240106120000_dev_A.sql
711
- 2. NÃO pulla main por 1 semana (dev_B foi merged enquanto isso)
712
- 3. Direto: supabase db push para staging
713
- 4. Resultado: ordem cronológica força dev_A antes de dev_B → falha
714
- ```
715
-
716
- **Por quê:** ordem cronológica de migrations é determinada por timestamp. Sem rebase, sua migration pode estar "presa" no passado relativo a migrations da equipe.
717
-
718
- **Sintomas:**
719
-
720
- - `db push` falha com "relation X does not exist" (FK para tabela que dev_B criou)
721
- - Staging branch entra em estado "failed" do DAG
722
- - Production fica em risco de mesma falha se dev fizer merge sem revisão
723
-
724
- **Certo:**
725
-
726
- ```bash
727
- # Antes de QUALQUER db push
728
- git pull origin main
729
- git rebase main
730
-
731
- # Se houver conflito de timestamps → aplicar Pattern 4 (rename migration files)
732
- supabase migration list # diagnose primeiro
733
- # se mismatch detectado, renomear migration antiga para timestamp atualizado
734
-
735
- supabase db reset # validar localmente em ordem cronológica correta
736
- supabase db push # só depois disso
737
- ```
738
-
739
- ### Anti-pattern 4: Concurrent db push from different machines
740
-
741
- **Errado:**
742
-
743
- ```
744
- Dev A (machine 1):
745
- 19:00 — supabase db push (target: staging)
746
-
747
- Dev B (machine 2):
748
- 19:01 — supabase db push (target: staging)
749
- ↓ race condition
750
- ```
751
-
752
- **Por quê:** dois processos `db push` simultâneos podem ambos detectar a mesma migration como pending → ambos tentam aplicar → race condition na tracking table → pode resultar em registro duplicado OU registro ausente após retry.
753
-
754
- **Sintomas:**
755
-
756
- - Tracking table corrompido (duplicate version OU missing version)
757
- - Migration aplicada parcialmente (algumas statements rodaram, outras não)
758
- - `supabase migration list` mostra estado inconsistente que não bate com nenhum cenário canônico
759
-
760
- **Certo:**
761
-
762
- - **Centralizar `db push` em CI/CD** — apenas pipelines (GitHub Actions, GitLab CI) executam `db push` em ambientes compartilhados (staging, production). Cross-ref skill `supabase-ci-cd-github-actions` (Phase 151).
763
- - **Lock manual em produção** — se você precisa fazer manual push em production, comunique no canal #release-coordination ANTES (humano lock)
764
- - **Dev workflow** — devs NUNCA fazem `db push` para staging direto da máquina local; sempre via PR + merge + CI/CD pipeline
765
-
766
- ### Anti-pattern 5: Renomear migrations em produção
767
-
768
- **Errado:**
769
-
770
- ```bash
771
- # Production tracking table tem registro 20240106120000
772
- # Dev renomeia o arquivo local para 20240106140000 (sem entender o impacto)
773
- mv supabase/migrations/20240106120000_old.sql supabase/migrations/20240106140000_old.sql
774
-
775
- # Push para production
776
- supabase db push --target=production
777
- # ↓ falha: 20240106120000 (registrado) ≠ 20240106140000 (folder)
778
- ```
779
-
780
- **Por quê:** tracking table em produção é **append-only history**. Renomear arquivos locais cria mismatch irreversível. Diferente de Pattern 4 (rename ANTES de qualquer push), em produção a migration JÁ foi registrada — renomear local é destrutivo.
781
-
782
- **Sintomas:**
783
-
784
- - `db push` para production falha permanentemente
785
- - `migration repair` é necessário para corrigir, mas pode levar a mais bugs se aplicado errado
786
- - Worst case: rollback de production via point-in-time recovery (custo + downtime)
787
-
788
- **Certo:**
789
-
790
- - **Renames de migration são VÁLIDOS apenas se nunca foram aplicados** (preview branch deletado + recriado, ou apenas em folder local sem nenhum push)
791
- - **Em produção, sempre forward-only**: criar nova migration que desfaz/corrige, nunca renomear histórico
792
- - **Treinamento de equipe**: documentar este anti-pattern no onboarding; novo dev pode descobrir Pattern 4 e aplicar inadvertidamente em produção
793
-
794
- ## Cross-suite integration (v1.27)
795
-
796
- Esta skill é o **complemento operacional** das skills v1.27 introduzidas em Phases 149-152:
797
-
798
- - **`supabase-branching-workflow`** (Phase 149) — quando DAG step 5 (migrate) falha em preview branch, use Pattern 3 (rollback via delete+reopen). Forward-ref de Phase 149 fechado nesta skill.
799
- - **`supabase-config-toml-remotes`** (Phase 150) — secrets per-branch podem mascarar permission errors se a migration espera env var diferente. Diagnosticar via Pattern 5 quando aplicável.
800
- - **`supabase-ci-cd-github-actions`** (Phase 151) — pipelines que executam `supabase db push` podem falhar com erros documentados em Pattern 5. Fix one-time via Dashboard SQL editor, depois pipeline funciona.
801
- - **`supabase-pgtap-testing`** (Phase 152) — tests falhando em CI por schema desatualizado podem indicar tracking table mismatch — diagnose via Pattern 1 antes de assumir bug no test.
802
-
803
- Esta skill é **standalone** — não cria agent novo. É consumida por:
804
-
805
- - `supabase-migration-writer` — referencia para ações pós-falha de migration
806
- - `supabase-rls-writer` (v1.23) — quando RLS depende de schema state que pode estar drifted
807
- - Agents futuros Phase 154 (`supabase-branching-architect`, `supabase-cicd-pipeline-implementer`) — incorporam diagnóstico Pattern 1 em workflows recomendados
808
-
809
- Pattern de handoff cooperativo herdado v1.23-v1.26: **architect** projeta workflow → **pipeline-implementer** materializa pipeline → quando falha, **migration-repair** skill é o "kit de emergência" canônico para recovery.
810
-
811
- ## Ver também
812
-
813
- - [supabase-migrations](../supabase-migrations/SKILL.md) (v1.23) — pattern canônico de migration files (5 blocos obrigatórios + naming)
814
- - [supabase-branching-workflow](../supabase-branching-workflow/SKILL.md) (v1.27, Phase 149) — preview branch lifecycle + DAG 7 steps + delete+reopen rollback
815
- - [supabase-config-toml-remotes](../supabase-config-toml-remotes/SKILL.md) (v1.27, Phase 150) — `[remotes]` block + secrets per-branch
816
- - [supabase-ci-cd-github-actions](../supabase-ci-cd-github-actions/SKILL.md) (v1.27, Phase 151) — 8 workflows canônicos GitHub Actions
817
- - [supabase-pgtap-testing](../supabase-pgtap-testing/SKILL.md) (v1.27, Phase 152) — testes pgTAP integrados no DAG
818
- - [supabase-postgres-roles](../supabase-postgres-roles/SKILL.md) (v1.26) — INHERIT/NOINHERIT, GRANT membership, predefined Supabase roles
819
- - [evolucao-schema-compativel](../evolucao-schema-compativel/SKILL.md) (v1.22) — 3-step migration safe rolling upgrade (expand → migrate data → contract)
820
- - [supabase-declarative-schema](../supabase-declarative-schema/SKILL.md) — workflow alternativo (declarative-first → diff → migrate)
821
- - [supabase-rls-policies](../supabase-rls-policies/SKILL.md) (v1.23) — RLS deve ser parte de cada migration nova
822
- - [glossário compartilhado](../_shared-supabase/glossary.md) — termos canônicos migration repair, tracking table, schema drift, sync error
823
- - Doc oficial Supabase: [Migration Repair](https://supabase.com/docs/reference/cli/supabase-migration-repair), [Local Development](https://supabase.com/docs/guides/local-development/cli/getting-started), [Branching](https://supabase.com/docs/guides/deployment/branching)
1
+ ---
2
+ name: supabase-migration-repair
3
+ description: Use ao diagnosticar e reparar sync errors entre local supabase/migrations/ e remote supabase_migrations.schema_migrations tracking table…
4
+ ---
5
+
6
+ # Supabase — Migration Repair
7
+
8
+ ## Quando usar
9
+
10
+ Use esta skill ao enfrentar **sync errors** ou **estado inconsistente** entre o folder local `supabase/migrations/` e a tracking table remota `supabase_migrations.schema_migrations`, ou ao precisar de rollback de preview branch após migration falha.
11
+
12
+ Trigger phrases:
13
+
14
+ - "migration repair", "supabase migration repair"
15
+ - "sync error Supabase", "migration history mismatch"
16
+ - "supabase migration list mostra mismatch"
17
+ - "schema drift Supabase", "git rebase migration timestamps"
18
+ - "permission denied migration", "permission denied for table _type"
19
+ - "permission denied 42501 Supabase", "custom_role to postgres"
20
+ - "rollback preview branch Supabase"
21
+ - "db push falhando re-aplicar migration"
22
+ - "db pull pg_dump error graphql"
23
+
24
+ **Use esta skill APENAS para:**
25
+
26
+ - Diagnosticar mismatch entre folder local e tracking table remoto
27
+ - Corrigir history record em `supabase_migrations.schema_migrations` quando schema state real está OK
28
+ - Rollback de preview branch ephemeral via PR close+reopen (cross-ref skill `supabase-branching-workflow` Phase 149)
29
+ - Resolver drift de timestamps após git rebase em equipe
30
+ - Resolver erros `42501 permission denied` e `pg_dump error permission denied for table _type`
31
+
32
+ **NÃO use esta skill para:**
33
+
34
+ - Reverter mudanças de schema reais — `migration repair` NÃO reverte SQL (cross-ref CAVEAT CRÍTICO abaixo)
35
+ - Substituir testes de migration — preview branch + DAG step 5 (cross-ref skill `supabase-branching-workflow` Phase 149) é o gate canônico
36
+ - Bypassar migration files aplicando schema changes via Dashboard SQL editor — isso CRIA o problema que esta skill diagnostica
37
+ - Recovery de production database com data loss — backup + point-in-time recovery do Supabase (fora do escopo desta skill)
38
+
39
+ ## Princípio canônico
40
+
41
+ Três princípios canônicos sustentam toda a skill:
42
+
43
+ ### Princípio 1 — Tracking table state ≠ schema state real
44
+
45
+ A tracking table `supabase_migrations.schema_migrations` é um **registro de histórico** de quais migrations foram aplicadas. O **schema state real** é o estado físico do DB (tabelas, colunas, indices, funções, policies).
46
+
47
+ Os dois podem divergir:
48
+
49
+ | Schema real | Tracking table | Causa | Sintoma |
50
+ |---|---|---|---|
51
+ | Tabela `foo` existe | Sem registro 20240102 | Migration aplicada manualmente via Dashboard SQL editor | `db push` tenta re-aplicar 20240102 e falha com "relation foo already exists" |
52
+ | Tabela `foo` NÃO existe | Com registro 20240102 | Tracking table corrupto / migration teve rollback parcial | `db push` skip 20240102 mas tabela ausente |
53
+ | Tabela `foo` existe | Com registro 20240102 | Estado normal — sincronizado | Nenhum |
54
+ | Tabela `foo` NÃO existe | Sem registro 20240102 | Nada aplicado ainda — pendente | `db push` aplica 20240102 normalmente |
55
+
56
+ ### Princípio 2 — Diagnose ANTES de repair
57
+
58
+ NUNCA execute `supabase migration repair` sem primeiro rodar `supabase migration list` para entender QUAL migration está em qual estado de mismatch. Repair cego pode mascarar bug + tornar recovery mais difícil.
59
+
60
+ ### Princípio 3 — Rollback preview preferível a manual revert
61
+
62
+ Para preview branches Supabase Branching (Phase 149), **delete+reopen do PR** é canônico e seguro. Tentar criar "reverter migration" manualmente para desfazer schema changes em preview branch é anti-pattern — preview branches são ephemeral by design (cross-ref skill `supabase-branching-workflow` Phase 149).
63
+
64
+ ## CAVEAT CRÍTICO — Tracking table apenas
65
+
66
+ > **`supabase migration repair` atualiza APENAS a tracking table `supabase_migrations.schema_migrations`. NÃO aplica SQL nem reverte SQL.**
67
+ >
68
+ > Este caveat é repetido **DUAS VEZES** nesta skill (Pattern 2 + abaixo) porque é a fonte #1 de bugs em recovery de migrations Supabase. LLMs e humanos frequentemente assumem que `repair --status reverted` "desfaz" a migration — **NÃO DESFAZ**.
69
+ >
70
+ > Se a migration realmente alterou schema (criou tabela, alterou coluna, etc.), `repair --status reverted` APENAS remove o registro do histórico. As mudanças físicas no DB **permanecem**. Para reverter mudanças de schema reais:
71
+ >
72
+ > 1. Criar **nova migration** que desfaz as mudanças (`drop table ...`, `alter table ... drop column ...`)
73
+ > 2. Aplicar via `supabase db push`
74
+ > 3. NÃO usar `repair --status reverted` esperando reverter SQL
75
+
76
+ ## Pattern 1: Diagnóstico via `supabase migration list` (REPAIR-01)
77
+
78
+ Primeira ação canônica em qualquer cenário de migration error — **sempre** começar por aqui.
79
+
80
+ ### Comando
81
+
82
+ ```bash
83
+ supabase migration list
84
+ ```
85
+
86
+ ### Output canônico
87
+
88
+ ```
89
+ LOCAL │ REMOTE │ TIME (UTC)
90
+ ─────────────────────┼────────────────┼─────────────────────
91
+ 20240101120000 │ 20240101120000 │ 2024-01-01 12:00:00
92
+ 20240102140000 │ - │ 2024-01-02 14:00:00
93
+ - │ 20240103160000 │ 2024-01-03 16:00:00
94
+ ```
95
+
96
+ ### Interpretação canônica das 3 colunas
97
+
98
+ | Coluna | Significado |
99
+ |---|---|
100
+ | **LOCAL** | Timestamp encontrado em `supabase/migrations/*.sql` (folder local do repo git) |
101
+ | **REMOTE** | Timestamp registrado em `supabase_migrations.schema_migrations` (tracking table no DB remoto) |
102
+ | **TIME (UTC)** | Quando foi aplicada (presente apenas quando coluna REMOTE tem valor) |
103
+
104
+ ### 3 estados canônicos por linha
105
+
106
+ **Estado 1: sincronizado**
107
+
108
+ ```
109
+ 20240101120000 │ 20240101120000 │ 2024-01-01 12:00:00
110
+ ```
111
+
112
+ Migration presente em ambos — estado **normal**, nenhuma ação necessária.
113
+
114
+ **Estado 2: local-only (pending push)**
115
+
116
+ ```
117
+ 20240102140000 │ - │ 2024-01-02 14:00:00
118
+ ```
119
+
120
+ Migration existe no folder local mas NÃO foi aplicada no remote. Ação canônica:
121
+
122
+ ```bash
123
+ supabase db push
124
+ ```
125
+
126
+ Aplica migrations pendentes em ordem cronológica.
127
+
128
+ **Estado 3: remote-only (drift)**
129
+
130
+ ```
131
+ - │ 20240103160000 │ 2024-01-03 16:00:00
132
+ ```
133
+
134
+ Migration foi aplicada no remote (registrada na tracking table) MAS o arquivo `.sql` correspondente NÃO existe no folder local. Causas possíveis:
135
+
136
+ - Migration aplicada manualmente via Dashboard SQL editor sem commit no git
137
+ - Outro dev aplicou migration e ainda não pushou para git remoto
138
+ - Arquivo local foi deletado por engano
139
+
140
+ Ação canônica:
141
+
142
+ ```bash
143
+ supabase db pull
144
+ ```
145
+
146
+ Gera arquivo `.sql` local correspondente à migration registrada no remote. Sincroniza folder local com tracking table.
147
+
148
+ ### Comportamento canônico de `supabase db push`
149
+
150
+ `supabase db push` compara local folder vs remote tracking table:
151
+
152
+ 1. Lista migrations em `supabase/migrations/*.sql` (folder local)
153
+ 2. Lista migrations em `supabase_migrations.schema_migrations` (tracking table)
154
+ 3. Calcula diff: migrations no folder MAS não na tracking table
155
+ 4. Aplica em ordem cronológica (por timestamp) — registra cada uma na tracking table após sucesso
156
+
157
+ **Caveat — tracking table é fonte de verdade para "o que foi aplicado":**
158
+
159
+ Se você deleta o folder local, `db push` NÃO re-aplica migrations já registradas na tracking table. Para forçar re-aplicação, precisa:
160
+
161
+ 1. `db pull` para regenerar folder local a partir do remote, OU
162
+ 2. `migration repair --status reverted <timestamp>` para remover o registro da tracking table (CAVEAT CRÍTICO repetido — isso só remove o registro, NÃO reverte schema)
163
+
164
+ ### Estrutura interna da tracking table
165
+
166
+ ```sql
167
+ -- estrutura canônica da tracking table (não modificar manualmente)
168
+ \d supabase_migrations.schema_migrations
169
+
170
+ Column │ Type
171
+ ──────────────────┼─────────────────────────
172
+ version │ text NOT NULL PRIMARY KEY
173
+ name │ text
174
+ statements │ text[]
175
+ ```
176
+
177
+ - `version` — timestamp da migration (PK)
178
+ - `name` — descrição da migration
179
+ - `statements` — array com SQL aplicado (audit trail)
180
+
181
+ **NUNCA modifique esta tabela diretamente.** Use `migration repair` (Pattern 2) para mutação segura via CLI.
182
+
183
+ ## Pattern 2: `migration repair --status applied|reverted` (REPAIR-02)
184
+
185
+ > **CAVEAT CRÍTICO REPETIDO — tracking table apenas:**
186
+ >
187
+ > `supabase migration repair` atualiza APENAS a tracking table `supabase_migrations.schema_migrations`. **NÃO aplica SQL nem reverte SQL.**
188
+ >
189
+ > Se a migration realmente alterou schema, `repair --status reverted` remove o registro do histórico MAS as mudanças físicas no DB **permanecem**. Para reverter schema changes reais, crie nova migration via `supabase migration new`.
190
+
191
+ ### Sintaxe canônica
192
+
193
+ ```bash
194
+ supabase migration repair --status <applied|reverted> <migration-timestamp>
195
+ ```
196
+
197
+ Dois subcomandos canônicos:
198
+
199
+ - `--status applied <timestamp>` — adiciona registro à tracking table (marca como aplicada)
200
+ - `--status reverted <timestamp>` — remove registro da tracking table (marca como reverted)
201
+
202
+ ### Caso 1 — Migration aplicada manualmente (precisa marcar como applied)
203
+
204
+ **Cenário:**
205
+
206
+ - Dev abriu Dashboard → SQL editor → executou `CREATE TABLE foo (...)` direto no DB remoto
207
+ - Schema state OK (tabela existe), mas tracking table NÃO tem registro
208
+ - Posteriormente, dev criou migration `20240102_create_foo.sql` no folder local com o mesmo SQL
209
+ - `supabase db push` lista migration como pending → tenta aplicar → falha com `relation "foo" already exists`
210
+
211
+ **Diagnóstico:**
212
+
213
+ ```bash
214
+ supabase migration list
215
+ # Output:
216
+ # 20240102140000 │ - │ 2024-01-02 14:00:00
217
+ ```
218
+
219
+ Confirma migration está local-only — porém schema state real tem a tabela. Repair canônico:
220
+
221
+ ```bash
222
+ supabase migration repair --status applied 20240102140000
223
+ ```
224
+
225
+ **O que acontece:**
226
+
227
+ - Tracking table recebe novo registro: `INSERT INTO supabase_migrations.schema_migrations (version, name) VALUES ('20240102140000', 'create_foo')`
228
+ - Schema state físico NÃO é alterado (tabela `foo` continua existindo, sem nenhuma operação SQL extra)
229
+ - Próximo `supabase migration list` mostra migration sincronizada
230
+
231
+ **Quando usar este caso:**
232
+
233
+ - Hotfix aplicado emergencialmente via Dashboard SQL editor sem migration file
234
+ - Migration aplicada manualmente em ambiente novo (ex: replicar schema de produção)
235
+ - Schema gerado por ferramenta externa (Drizzle, Prisma) onde tracking table está fora de sync
236
+
237
+ ### Caso 2 — Migration registrada mas nunca aplicada (precisa marcar como reverted)
238
+
239
+ **Cenário:**
240
+
241
+ - Tracking table tem registro `20240102140000` MAS schema state real NÃO tem a tabela criada por essa migration
242
+ - Causas possíveis: tracking table corrupto, migration teve rollback parcial, restore parcial de backup
243
+
244
+ **Diagnóstico:**
245
+
246
+ ```bash
247
+ supabase migration list
248
+ # Output:
249
+ # 20240102140000 │ 20240102140000 │ 2024-01-02 14:00:00
250
+ ```
251
+
252
+ Aparenta sincronizado, mas tabela não existe. Confirmar via:
253
+
254
+ ```sql
255
+ -- conectar via psql ou Dashboard SQL editor
256
+ select table_name from information_schema.tables where table_schema = 'public' and table_name = 'foo';
257
+ -- 0 rows
258
+ ```
259
+
260
+ Repair canônico:
261
+
262
+ ```bash
263
+ supabase migration repair --status reverted 20240102140000
264
+ ```
265
+
266
+ **O que acontece:**
267
+
268
+ - Tracking table tem registro DELETADO: `DELETE FROM supabase_migrations.schema_migrations WHERE version = '20240102140000'`
269
+ - Schema state físico NÃO é alterado (tabela `foo` continua não existindo — `repair` não cria nada)
270
+ - `supabase db push` agora considera migration como pending → aplica normalmente
271
+
272
+ **Quando usar este caso:**
273
+
274
+ - Tracking table está fora de sync por motivo desconhecido
275
+ - Migration tem registro mas schema state real não reflete (tabela ausente, coluna ausente, etc.)
276
+ - Precisa "forçar" re-aplicação de migration via `db push` após confirmar que schema real não tem as mudanças
277
+
278
+ ### Anti-uso CRÍTICO — não usar para reverter schema
279
+
280
+ ```bash
281
+ # ERRADO — esperar que isso reverta a tabela criada pela migration
282
+ supabase migration repair --status reverted 20240102140000
283
+ ```
284
+
285
+ **Por quê:** apenas remove o registro. A tabela `foo` continua existindo. Próximo `supabase db push` vai tentar aplicar a migration novamente, falhar com `relation already exists`, e você fica em loop infinito.
286
+
287
+ **Certo — para reverter schema changes reais:**
288
+
289
+ ```bash
290
+ # 1. Criar nova migration que desfaz as mudanças
291
+ supabase migration new drop_foo
292
+
293
+ # 2. Editar arquivo gerado supabase/migrations/<novo-timestamp>_drop_foo.sql:
294
+ # drop table if exists public.foo;
295
+
296
+ # 3. Aplicar
297
+ supabase db push
298
+ ```
299
+
300
+ ### Fluxograma canônico de decisão
301
+
302
+ ```
303
+ Sync error em supabase migration list?
304
+
305
+ ├─ Local-only (LOCAL=X, REMOTE=-)
306
+ │ │
307
+ │ ├─ Schema real TEM as mudanças?
308
+ │ │ ├─ SIM → repair --status applied <X>
309
+ │ │ └─ NÃO → supabase db push (aplicação normal)
310
+ │ │
311
+
312
+ ├─ Remote-only (LOCAL=-, REMOTE=Y)
313
+ │ │
314
+ │ ├─ Schema real TEM as mudanças?
315
+ │ │ ├─ SIM → supabase db pull (regenera arquivo local)
316
+ │ │ └─ NÃO → repair --status reverted <Y> (limpa registro órfão)
317
+
318
+ └─ Aparenta sincronizado mas erros persistem
319
+
320
+ ├─ Conectar via psql + verificar schema state real
321
+ └─ Decidir entre repair vs nova migration baseado em estado
322
+ ```
323
+
324
+ ## Pattern 3: Rollback preview branch via delete + reopen (REPAIR-03)
325
+
326
+ Quando uma migration ruim foi pushada para preview branch Supabase Branching e DAG falhou no step 5 (migrate), o **canônico** é NÃO criar reverter migration — use rollback via PR close+reopen.
327
+
328
+ ### Workflow canônico (5 passos)
329
+
330
+ ```
331
+ 1. Dev pusha migration ruim em PR
332
+
333
+ 2. Supabase webhook → DAG step 5 (migrate) FALHA
334
+ ↓ status no PR: "Supabase Preview ✗"
335
+
336
+ 3. Dev fecha PR (GitHub UI: "Close pull request")
337
+
338
+ 4. Supabase Branching detecta PR closed → DELETA preview branch
339
+ ↓ (cleanup completo: DB, Edge Functions, Storage config)
340
+
341
+ 5. Dev fixa migration + reopen PR (GitHub UI: "Reopen pull request")
342
+
343
+ 6. Supabase Branching detecta PR reopened → CRIA novo preview branch
344
+ ↓ DAG roda steps 1-7 do zero com migration corrigida
345
+ ```
346
+
347
+ ### Equivalência canônica
348
+
349
+ **Delete preview branch + reopen** = **`supabase db reset` local**.
350
+
351
+ Ambos:
352
+
353
+ - Limpam DB state completamente
354
+ - Re-executam todas migrations em ordem cronológica
355
+ - Re-aplicam `supabase/seed.sql`
356
+ - Resetam Edge Functions para versão atual do branch git
357
+
358
+ ### Caveats canônicos
359
+
360
+ **Caveat 1 — Data changes adicionais SÃO PERDIDOS**
361
+
362
+ `seed.sql` é re-aplicado como dataless setup. Quaisquer rows inseridas/atualizadas manualmente durante uso do preview branch:
363
+
364
+ - Via Dashboard Table editor
365
+ - Via testes manuais (insert, update direto)
366
+ - Via Edge Function execution (que escreveu em tabelas)
367
+
368
+ **são perdidas** no reset. Aceito como trade-off canônico para reset limpo — preview branches são ephemeral by design (cross-ref skill `supabase-branching-workflow` Phase 149).
369
+
370
+ **Caveat 2 — Auto-pause em inatividade NÃO substitui reset**
371
+
372
+ Preview branches auto-pausam após inatividade (~24h sem requests), mas isso preserva o state. NÃO é equivalente a reset. Para limpeza real, sempre use close+reopen.
373
+
374
+ **Caveat 3 — Branching Compute Hours acumulam novamente**
375
+
376
+ Reopen recria preview branch do zero → nova hora de Branching Compute Hours é cobrada (cross-ref skill `supabase-branching-workflow` Phase 149 — Pattern 5 custo). Se rollback acontece 5× para o mesmo PR, são 5 horas extras cobradas. Considere disciplina: testar migration localmente antes de push.
377
+
378
+ ### Quando usar este pattern
379
+
380
+ - Migration ruim foi pushada para preview branch
381
+ - DAG step 5 (migrate) falhou — sem possibilidade de recovery via re-push (porque o branch já está em estado "failed")
382
+ - Você quer voltar ao estado limpo sem aplicar reverter migration manualmente
383
+ - Aceita perda de data changes adicionais que não estavam em seed.sql
384
+
385
+ ### Quando NÃO usar este pattern
386
+
387
+ - Persistent branches (staging/QA) — NÃO use delete+reopen; persistent branches são long-lived (cross-ref skill `supabase-branching-workflow` Phase 149 — Pattern 1)
388
+ - Production project — production NUNCA tem rollback via "close PR" — use migration de reversão + `db push` + cuidados extras (backup + monitoramento)
389
+ - Quando você precisa preservar data changes — não há recovery dos dados após delete
390
+
391
+ ### Workflow alternativo: push corrected migration
392
+
393
+ Se o branch ainda está em estado "failed" mas branch ainda existe (PR não foi fechado):
394
+
395
+ ```
396
+ 1. Identificar root cause via Dashboard → branch deployment logs (step 5 stderr)
397
+ 2. Corrigir migration localmente
398
+ 3. git commit + git push (mesmo PR)
399
+ 4. Supabase webhook detecta push → re-run DAG do step 1
400
+ 5. Se passa step 5 → step 6 (seed) e step 7 (deploy) executam
401
+ ```
402
+
403
+ Este workflow é **preferível** se o erro foi simples (typo, syntax error) — evita Branching Compute Hours extras do reset.
404
+
405
+ ## Pattern 4: Schema drift após git rebase (REPAIR-04)
406
+
407
+ Cenário canônico em equipes que mergem migrations em paralelo via PRs em main.
408
+
409
+ ### Problema canônico
410
+
411
+ ```
412
+ Timeline:
413
+ T = Dev A cria PR-A com migration 20240106120000_dev_A.sql
414
+ T+1 = Dev B cria PR-B com migration 20240106130000_dev_B.sql
415
+ T+2 = PR-B é merged primeiro (dev_B agora está em main)
416
+ T+3 = Dev A faz git pull origin main → traz dev_B
417
+ T+4 = Dev A faz git rebase main em sua branch
418
+ T+5 = Estado: branch de Dev A tem dev_B (timestamp 13:00) + dev_A (timestamp 12:00)
419
+ ```
420
+
421
+ **Problema:** após rebase, Dev A tem migrations em ordem:
422
+
423
+ ```
424
+ supabase/migrations/
425
+ ├── 20240106120000_dev_A.sql (mais antiga)
426
+ ├── 20240106130000_dev_B.sql (mais nova)
427
+ ```
428
+
429
+ Local `supabase db reset` aplica em ordem cronológica:
430
+
431
+ 1. Aplica `20240106120000_dev_A.sql` PRIMEIRO
432
+ 2. Aplica `20240106130000_dev_B.sql` DEPOIS
433
+
434
+ Se `dev_A` depende de schema state que só existe APÓS `dev_B` (ex: dev_A adiciona FK para tabela que dev_B criou), `supabase db reset` falha.
435
+
436
+ **Pior:** quando `db push` para production, ordem cronológica força dev_A primeiro → falha em produção.
437
+
438
+ ### Solução canônica (4 passos)
439
+
440
+ ```bash
441
+ # Passo 1: Pull main (traz migrations recentes da equipe)
442
+ git pull origin main
443
+
444
+ # Passo 2: Criar nova migration com timestamp atualizado (placeholder)
445
+ supabase migration new dev_A
446
+ # Cria: supabase/migrations/20240106140000_dev_A.sql (timestamp ATUAL, mais novo)
447
+
448
+ # Passo 3: Renomear migration antiga para o novo timestamp
449
+ mv supabase/migrations/20240106120000_dev_A.sql supabase/migrations/20240106140000_dev_A.sql
450
+
451
+ # (Passo 2 criou arquivo vazio; passo 3 sobrescreve com conteúdo correto)
452
+
453
+ # Passo 4: Reset local para reaplicar tudo em ordem cronológica correta
454
+ supabase db reset
455
+ ```
456
+
457
+ ### Resultado final
458
+
459
+ ```
460
+ supabase/migrations/
461
+ ├── 20240106130000_dev_B.sql (do teammate, vem primeiro)
462
+ ├── 20240106140000_dev_A.sql (renomeada com timestamp posterior, vem depois)
463
+ ```
464
+
465
+ `supabase db reset` aplica em ordem correta:
466
+
467
+ 1. Aplica `20240106130000_dev_B.sql` (tabela criada por dev_B)
468
+ 2. Aplica `20240106140000_dev_A.sql` (FK funciona porque tabela já existe)
469
+
470
+ ### Princípio canônico
471
+
472
+ > **Changes que dependem de earlier changes DEVEM ter later timestamps.**
473
+ >
474
+ > Append-only migration history não tolera reordering retroativo. Se você precisa ordenar migration A antes de B mas A tem timestamp mais antigo, **renomeie** A para timestamp posterior a B.
475
+
476
+ ### Cuidado canônico — git history
477
+
478
+ Após `mv supabase/migrations/<old>.sql supabase/migrations/<new>.sql`:
479
+
480
+ ```bash
481
+ # git detecta como rename (boa preservação de history)
482
+ git status
483
+ # renamed: supabase/migrations/20240106120000_dev_A.sql -> supabase/migrations/20240106140000_dev_A.sql
484
+
485
+ git add supabase/migrations/
486
+ git commit -m "fix: rebase migration dev_A após merge de dev_B em main"
487
+ ```
488
+
489
+ ### Caveat — se a migration JÁ FOI PUSHADA para preview/staging
490
+
491
+ Se sua migration `dev_A` já foi pushada para preview branch e DAG executou (mesmo se falhou), a tracking table do preview tem registro `20240106120000`. Renomear o arquivo local cria mismatch:
492
+
493
+ - Local folder: `20240106140000_dev_A.sql` (renomeado)
494
+ - Tracking table preview: `20240106120000` (registro antigo)
495
+
496
+ Solução canônica nesse caso:
497
+
498
+ 1. Renomear arquivo localmente (passos 1-4 acima)
499
+ 2. Close+reopen PR (Pattern 3 — rollback preview) → recria preview branch do zero
500
+ 3. Push do branch corrigido → DAG roda com timestamp correto
501
+
502
+ ### Quando este pattern NÃO se aplica
503
+
504
+ - Migrations independentes (não há dependência de ordem) — pode ignorar drift, ordem cronológica resolve corretamente
505
+ - Migrations já aplicadas em produção — NÃO renomeie migrations em produção; cria mismatch entre tracking table e folder local. Use forward-only migration de correção.
506
+
507
+ ## Pattern 5: Permission denied troubleshooting (REPAIR-05)
508
+
509
+ Dois casos canônicos documentados na doc oficial Supabase — ambos exigem aplicação manual de GRANT via Dashboard SQL Editor.
510
+
511
+ ### Caso 1 — db pull erro "permission denied for table _type"
512
+
513
+ #### Erro completo
514
+
515
+ ```
516
+ $ supabase db pull
517
+ Error: Error running pg_dump on remote database:
518
+ pg_dump: error: query failed: ERROR: permission denied for table _type
519
+ pg_dump: error: query was: LOCK TABLE "graphql"."_type" IN ACCESS SHARE MODE
520
+ ```
521
+
522
+ #### Causa canônica
523
+
524
+ Projetos Supabase **antigos** (criados antes da introdução do GraphQL schema com grants padrão) NÃO têm GRANTs corretos em `graphql._type`. `pg_dump` requer LOCK ACCESS SHARE em todas as tabelas do schema para snapshot consistente — falha sem GRANT.
525
+
526
+ #### Solução canônica
527
+
528
+ Executar no **Dashboard → SQL Editor** (não em migration file porque é one-time fix para schema graphql gerenciado pelo Supabase):
529
+
530
+ ```sql
531
+ grant all on all tables in schema graphql to postgres, anon, authenticated, service_role;
532
+ grant all on all functions in schema graphql to postgres, anon, authenticated, service_role;
533
+ grant all on all sequences in schema graphql to postgres, anon, authenticated, service_role;
534
+ ```
535
+
536
+ #### Verificação após fix
537
+
538
+ ```bash
539
+ supabase db pull
540
+ # Output esperado: "Schema pulled successfully" sem erro de permission denied
541
+ ```
542
+
543
+ #### Caveat canônico — projetos novos
544
+
545
+ Projetos criados após 2024 vêm com esses GRANTs configurados automaticamente. Se você está em projeto criado recentemente e ainda recebe esse erro, verifique se há roles customizadas que precisam de GRANT também:
546
+
547
+ ```sql
548
+ -- exemplo: se você criou role "data_team_reader" e quer permitir db pull com ela
549
+ grant all on all tables in schema graphql to data_team_reader;
550
+ grant all on all functions in schema graphql to data_team_reader;
551
+ grant all on all sequences in schema graphql to data_team_reader;
552
+ ```
553
+
554
+ ### Caso 2 — db push erro 42501 com custom role
555
+
556
+ #### Erro completo
557
+
558
+ ```
559
+ $ supabase db push
560
+ Applying migration 20240107120000_alter_orders.sql...
561
+ ERROR: permission denied for table orders (SQLSTATE 42501)
562
+ Error: failed to apply migration
563
+ ```
564
+
565
+ #### Causa canônica
566
+
567
+ Tabela `orders` foi criada com **custom role** (ex: `app_admin` ou similar) em migration anterior. Quando `supabase db push` executa a próxima migration, o conexão é feita como role `postgres` (default do CLI), e `postgres` NÃO tem permission para modificar a tabela porque o owner é `app_admin`.
568
+
569
+ SQLSTATE `42501` é o código canônico Postgres para "insufficient_privilege". Cross-ref skill `supabase-postgres-roles` (v1.26) para entendimento completo de custom roles.
570
+
571
+ #### Solução canônica
572
+
573
+ Conceder membership do custom role para `postgres`:
574
+
575
+ ```sql
576
+ grant "custom_role" to "postgres";
577
+ ```
578
+
579
+ Substituindo `custom_role` pelo nome real (ex: `app_admin`, `lead_manager`, etc.):
580
+
581
+ ```sql
582
+ -- exemplo concreto
583
+ grant "app_admin" to "postgres";
584
+ ```
585
+
586
+ #### Como funciona
587
+
588
+ - `grant "app_admin" to "postgres"` torna `postgres` **membro** do role `app_admin`
589
+ - Por default, roles em Postgres usam INHERIT — `postgres` herda permissions de `app_admin`
590
+ - Agora `postgres` consegue modificar tabelas que têm owner = `app_admin`
591
+
592
+ #### Caveat canônico — INHERIT vs SET ROLE
593
+
594
+ Se `app_admin` foi criado com NOINHERIT (cross-ref skill `supabase-postgres-roles` v1.26 — Pattern 3), simples GRANT membership NÃO é suficiente. `postgres` precisa `SET ROLE app_admin` explicitamente antes de cada operação:
595
+
596
+ ```sql
597
+ -- na migration (não recomendado, mas funciona)
598
+ set role app_admin;
599
+ alter table public.orders add column foo text;
600
+ reset role;
601
+ ```
602
+
603
+ Solução **preferível** se você está em projeto novo: criar custom roles com INHERIT default (cross-ref skill `supabase-postgres-roles` v1.26 — Pattern 3).
604
+
605
+ #### Quando aplicar este GRANT
606
+
607
+ Aplique **uma única vez** após criar a custom role:
608
+
609
+ ```sql
610
+ -- na primeira migration que cria a custom role (cross-ref skill supabase-postgres-roles)
611
+ create role "app_admin" noinherit;
612
+ alter role "app_admin" with bypassrls;
613
+ grant "app_admin" to "postgres"; -- ⚡ esta linha resolve o erro 42501
614
+ ```
615
+
616
+ Comments explicativos canônicos na migration:
617
+
618
+ ```sql
619
+ -- GRANT membership de app_admin para postgres
620
+ -- Permite que supabase db push (conectado como postgres) modifique tabelas
621
+ -- com owner app_admin sem precisar SET ROLE explícito.
622
+ -- Sem isso: erro SQLSTATE 42501 ao alterar tabela.
623
+ grant "app_admin" to "postgres";
624
+ ```
625
+
626
+ ### Tabela canônica — erros + soluções
627
+
628
+ | Erro | SQLSTATE | Comando que dispara | Solução canônica |
629
+ |---|---|---|---|
630
+ | `permission denied for table _type` | (sem código) pg_dump error | `supabase db pull` | `grant all on all tables in schema graphql to postgres, anon, authenticated, service_role` |
631
+ | `permission denied for table X` | 42501 | `supabase db push` | `grant "custom_role" to "postgres"` |
632
+ | `relation X already exists` | 42P07 | `supabase db push` | `migration repair --status applied <timestamp>` (Pattern 2) |
633
+ | `relation X does not exist` | 42P01 | `supabase db push` | Verificar ordem de migrations (Pattern 4) ou pull do remote (Pattern 1) |
634
+
635
+ ## Anti-patterns
636
+
637
+ ### Anti-pattern 1: Usar `migration repair --status reverted` esperando reverter SQL
638
+
639
+ **Errado:**
640
+
641
+ ```bash
642
+ # Dev quer "desfazer" CREATE TABLE foo que migration 20240102 criou
643
+ supabase migration repair --status reverted 20240102140000
644
+ # Espera: tabela foo deletada
645
+ # Realidade: apenas registro de tracking table removido — tabela foo continua existindo
646
+ ```
647
+
648
+ **Por quê:** `repair` é tracking-table-only. CAVEAT CRÍTICO repetido nesta skill (Pattern 2 + introdução). LLMs e humanos frequentemente assumem semantics de "rollback completo" — incorreto.
649
+
650
+ **Sintoma do bug:** próximo `supabase db push` tenta re-aplicar a migration → falha com `relation "foo" already exists` (SQLSTATE 42P07) → loop infinito de tentativas de repair.
651
+
652
+ **Certo:**
653
+
654
+ ```bash
655
+ # Para reverter schema changes reais, crie nova migration
656
+ supabase migration new drop_foo
657
+ # Editar arquivo gerado:
658
+ # drop table if exists public.foo;
659
+ supabase db push
660
+ ```
661
+
662
+ ### Anti-pattern 2: Schema changes direto no remote bypassing migration files
663
+
664
+ **Errado:**
665
+
666
+ ```sql
667
+ -- Dev abre Dashboard → SQL Editor → executa direto no DB remoto:
668
+ create table public.audit_log (
669
+ id uuid primary key default gen_random_uuid(),
670
+ event text not null,
671
+ created_at timestamptz not null default now()
672
+ );
673
+
674
+ -- Sem commit no git, sem migration file, sem registro na tracking table
675
+ ```
676
+
677
+ **Por quê:** cria divergência canônica entre schema real (tabela existe) e tracking table (sem registro). Cross-ref Princípio 1. Próximo dev que clonar repo + rodar `supabase db reset` local NÃO terá a tabela.
678
+
679
+ **Sintomas:**
680
+
681
+ - Outros devs reportam "minha app não funciona, tabela audit_log não existe"
682
+ - CI/CD pipeline falha em ambientes novos (preview branches, persistent staging)
683
+ - `supabase db pull` mostra surpresas (tabela "remote-only")
684
+
685
+ **Certo:**
686
+
687
+ ```bash
688
+ # 1. Criar migration file via CLI
689
+ supabase migration new create_audit_log
690
+
691
+ # 2. Editar arquivo gerado com SQL (incluindo GRANTs + RLS — cross-ref skill supabase-migrations)
692
+ # supabase/migrations/<timestamp>_create_audit_log.sql
693
+
694
+ # 3. Testar localmente
695
+ supabase db reset
696
+
697
+ # 4. Commit + push + PR (cross-ref skill supabase-branching-workflow Phase 149)
698
+ git add supabase/migrations/
699
+ git commit -m "feat: add audit_log table"
700
+ git push
701
+ # Abre PR → preview branch criado → DAG step 5 valida migration
702
+ ```
703
+
704
+ ### Anti-pattern 3: Não rebase local antes de db push em equipe
705
+
706
+ **Errado:**
707
+
708
+ ```
709
+ Dev A workflow:
710
+ 1. Cria branch feature-A com migration 20240106120000_dev_A.sql
711
+ 2. NÃO pulla main por 1 semana (dev_B foi merged enquanto isso)
712
+ 3. Direto: supabase db push para staging
713
+ 4. Resultado: ordem cronológica força dev_A antes de dev_B → falha
714
+ ```
715
+
716
+ **Por quê:** ordem cronológica de migrations é determinada por timestamp. Sem rebase, sua migration pode estar "presa" no passado relativo a migrations da equipe.
717
+
718
+ **Sintomas:**
719
+
720
+ - `db push` falha com "relation X does not exist" (FK para tabela que dev_B criou)
721
+ - Staging branch entra em estado "failed" do DAG
722
+ - Production fica em risco de mesma falha se dev fizer merge sem revisão
723
+
724
+ **Certo:**
725
+
726
+ ```bash
727
+ # Antes de QUALQUER db push
728
+ git pull origin main
729
+ git rebase main
730
+
731
+ # Se houver conflito de timestamps → aplicar Pattern 4 (rename migration files)
732
+ supabase migration list # diagnose primeiro
733
+ # se mismatch detectado, renomear migration antiga para timestamp atualizado
734
+
735
+ supabase db reset # validar localmente em ordem cronológica correta
736
+ supabase db push # só depois disso
737
+ ```
738
+
739
+ ### Anti-pattern 4: Concurrent db push from different machines
740
+
741
+ **Errado:**
742
+
743
+ ```
744
+ Dev A (machine 1):
745
+ 19:00 — supabase db push (target: staging)
746
+
747
+ Dev B (machine 2):
748
+ 19:01 — supabase db push (target: staging)
749
+ ↓ race condition
750
+ ```
751
+
752
+ **Por quê:** dois processos `db push` simultâneos podem ambos detectar a mesma migration como pending → ambos tentam aplicar → race condition na tracking table → pode resultar em registro duplicado OU registro ausente após retry.
753
+
754
+ **Sintomas:**
755
+
756
+ - Tracking table corrompido (duplicate version OU missing version)
757
+ - Migration aplicada parcialmente (algumas statements rodaram, outras não)
758
+ - `supabase migration list` mostra estado inconsistente que não bate com nenhum cenário canônico
759
+
760
+ **Certo:**
761
+
762
+ - **Centralizar `db push` em CI/CD** — apenas pipelines (GitHub Actions, GitLab CI) executam `db push` em ambientes compartilhados (staging, production). Cross-ref skill `supabase-ci-cd-github-actions` (Phase 151).
763
+ - **Lock manual em produção** — se você precisa fazer manual push em production, comunique no canal #release-coordination ANTES (humano lock)
764
+ - **Dev workflow** — devs NUNCA fazem `db push` para staging direto da máquina local; sempre via PR + merge + CI/CD pipeline
765
+
766
+ ### Anti-pattern 5: Renomear migrations em produção
767
+
768
+ **Errado:**
769
+
770
+ ```bash
771
+ # Production tracking table tem registro 20240106120000
772
+ # Dev renomeia o arquivo local para 20240106140000 (sem entender o impacto)
773
+ mv supabase/migrations/20240106120000_old.sql supabase/migrations/20240106140000_old.sql
774
+
775
+ # Push para production
776
+ supabase db push --target=production
777
+ # ↓ falha: 20240106120000 (registrado) ≠ 20240106140000 (folder)
778
+ ```
779
+
780
+ **Por quê:** tracking table em produção é **append-only history**. Renomear arquivos locais cria mismatch irreversível. Diferente de Pattern 4 (rename ANTES de qualquer push), em produção a migration JÁ foi registrada — renomear local é destrutivo.
781
+
782
+ **Sintomas:**
783
+
784
+ - `db push` para production falha permanentemente
785
+ - `migration repair` é necessário para corrigir, mas pode levar a mais bugs se aplicado errado
786
+ - Worst case: rollback de production via point-in-time recovery (custo + downtime)
787
+
788
+ **Certo:**
789
+
790
+ - **Renames de migration são VÁLIDOS apenas se nunca foram aplicados** (preview branch deletado + recriado, ou apenas em folder local sem nenhum push)
791
+ - **Em produção, sempre forward-only**: criar nova migration que desfaz/corrige, nunca renomear histórico
792
+ - **Treinamento de equipe**: documentar este anti-pattern no onboarding; novo dev pode descobrir Pattern 4 e aplicar inadvertidamente em produção
793
+
794
+ ## Cross-suite integration (v1.27)
795
+
796
+ Esta skill é o **complemento operacional** das skills v1.27 introduzidas em Phases 149-152:
797
+
798
+ - **`supabase-branching-workflow`** (Phase 149) — quando DAG step 5 (migrate) falha em preview branch, use Pattern 3 (rollback via delete+reopen). Forward-ref de Phase 149 fechado nesta skill.
799
+ - **`supabase-config-toml-remotes`** (Phase 150) — secrets per-branch podem mascarar permission errors se a migration espera env var diferente. Diagnosticar via Pattern 5 quando aplicável.
800
+ - **`supabase-ci-cd-github-actions`** (Phase 151) — pipelines que executam `supabase db push` podem falhar com erros documentados em Pattern 5. Fix one-time via Dashboard SQL editor, depois pipeline funciona.
801
+ - **`supabase-pgtap-testing`** (Phase 152) — tests falhando em CI por schema desatualizado podem indicar tracking table mismatch — diagnose via Pattern 1 antes de assumir bug no test.
802
+
803
+ Esta skill é **standalone** — não cria agent novo. É consumida por:
804
+
805
+ - `supabase-migration-writer` — referencia para ações pós-falha de migration
806
+ - `supabase-rls-writer` (v1.23) — quando RLS depende de schema state que pode estar drifted
807
+ - Agents futuros Phase 154 (`supabase-branching-architect`, `supabase-cicd-pipeline-implementer`) — incorporam diagnóstico Pattern 1 em workflows recomendados
808
+
809
+ Pattern de handoff cooperativo herdado v1.23-v1.26: **architect** projeta workflow → **pipeline-implementer** materializa pipeline → quando falha, **migration-repair** skill é o "kit de emergência" canônico para recovery.
810
+
811
+ ## Ver também
812
+
813
+ - [supabase-migrations](../supabase-migrations/SKILL.md) (v1.23) — pattern canônico de migration files (5 blocos obrigatórios + naming)
814
+ - [supabase-branching-workflow](../supabase-branching-workflow/SKILL.md) (v1.27, Phase 149) — preview branch lifecycle + DAG 7 steps + delete+reopen rollback
815
+ - [supabase-config-toml-remotes](../supabase-config-toml-remotes/SKILL.md) (v1.27, Phase 150) — `[remotes]` block + secrets per-branch
816
+ - [supabase-ci-cd-github-actions](../supabase-ci-cd-github-actions/SKILL.md) (v1.27, Phase 151) — 8 workflows canônicos GitHub Actions
817
+ - [supabase-pgtap-testing](../supabase-pgtap-testing/SKILL.md) (v1.27, Phase 152) — testes pgTAP integrados no DAG
818
+ - [supabase-postgres-roles](../supabase-postgres-roles/SKILL.md) (v1.26) — INHERIT/NOINHERIT, GRANT membership, predefined Supabase roles
819
+ - [evolucao-schema-compativel](../evolucao-schema-compativel/SKILL.md) (v1.22) — 3-step migration safe rolling upgrade (expand → migrate data → contract)
820
+ - [supabase-declarative-schema](../supabase-declarative-schema/SKILL.md) — workflow alternativo (declarative-first → diff → migrate)
821
+ - [supabase-rls-policies](../supabase-rls-policies/SKILL.md) (v1.23) — RLS deve ser parte de cada migration nova
822
+ - [glossário compartilhado](../_shared-supabase/glossary.md) — termos canônicos migration repair, tracking table, schema drift, sync error
823
+ - Doc oficial Supabase: [Migration Repair](https://supabase.com/docs/reference/cli/supabase-migration-repair), [Local Development](https://supabase.com/docs/guides/local-development/cli/getting-started), [Branching](https://supabase.com/docs/guides/deployment/branching)