@luanpdd/kit-mcp 1.29.0 → 1.30.1

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 (331) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +168 -168
  3. package/gates/agent-no-recursive-dispatch.md +82 -82
  4. package/kit/COMANDOS.md +138 -138
  5. package/kit/README.md +76 -76
  6. package/kit/agents/advisor-researcher.md +106 -106
  7. package/kit/agents/assumptions-analyzer.md +107 -107
  8. package/kit/agents/audit-log-implementer.md +313 -313
  9. package/kit/agents/auditor-consistencia-isolamento.md +413 -413
  10. package/kit/agents/b2b-saas-architect.md +156 -156
  11. package/kit/agents/cascading-failures-auditor.md +298 -298
  12. package/kit/agents/codebase-mapper.md +768 -768
  13. package/kit/agents/crm-pipeline-implementer.md +256 -256
  14. package/kit/agents/debugger.md +813 -813
  15. package/kit/agents/detector-tenant-quente.md +337 -337
  16. package/kit/agents/evolution-go-integrator.md +200 -200
  17. package/kit/agents/example-reviewer.md +21 -21
  18. package/kit/agents/executor.md +564 -564
  19. package/kit/agents/integration-checker.md +200 -200
  20. package/kit/agents/invite-flow-implementer.md +189 -189
  21. package/kit/agents/legacy-characterizer.md +368 -368
  22. package/kit/agents/lgpd-compliance-auditor.md +295 -295
  23. package/kit/agents/multi-tenant-isolation-auditor.md +253 -253
  24. package/kit/agents/multi-tenant-rls-writer.md +340 -340
  25. package/kit/agents/nyquist-auditor.md +178 -178
  26. package/kit/agents/observability-coverage-auditor.md +315 -315
  27. package/kit/agents/org-onboarding-implementer.md +223 -223
  28. package/kit/agents/payload-capture-instrumenter.md +273 -273
  29. package/kit/agents/phase-researcher.md +696 -696
  30. package/kit/agents/plan-checker.md +272 -272
  31. package/kit/agents/planner.md +922 -922
  32. package/kit/agents/project-researcher.md +652 -652
  33. package/kit/agents/refactor-safety-auditor.md +404 -404
  34. package/kit/agents/research-synthesizer.md +245 -245
  35. package/kit/agents/roadmapper.md +677 -677
  36. package/kit/agents/seam-finder.md +359 -359
  37. package/kit/agents/shotgun-surgery-detector.md +349 -349
  38. package/kit/agents/supabase-branching-architect.md +562 -562
  39. package/kit/agents/supabase-cicd-pipeline-implementer.md +777 -777
  40. package/kit/agents/supabase-column-privileges-writer.md +399 -399
  41. package/kit/agents/supabase-edge-fn-tester.md +287 -0
  42. package/kit/agents/supabase-edge-fn-writer.md +239 -210
  43. package/kit/agents/supabase-migration-writer.md +385 -385
  44. package/kit/agents/supabase-rbac-implementer.md +392 -392
  45. package/kit/agents/supabase-realtime-implementer.md +363 -267
  46. package/kit/agents/supabase-rls-hardener.md +521 -521
  47. package/kit/agents/supabase-rls-writer.md +323 -323
  48. package/kit/agents/supabase-roles-implementer.md +355 -355
  49. package/kit/agents/super-admin-implementer.md +281 -281
  50. package/kit/agents/ui-auditor.md +437 -437
  51. package/kit/agents/ui-checker.md +302 -302
  52. package/kit/agents/ui-researcher.md +355 -355
  53. package/kit/agents/user-profiler.md +175 -175
  54. package/kit/agents/validador-evolucao-schema.md +335 -335
  55. package/kit/agents/verifier.md +728 -728
  56. package/kit/commands/adicionar-backlog.md +75 -75
  57. package/kit/commands/adicionar-fase.md +42 -42
  58. package/kit/commands/adicionar-tarefa.md +45 -45
  59. package/kit/commands/adicionar-testes.md +41 -41
  60. package/kit/commands/ajuda.md +21 -21
  61. package/kit/commands/atualizar.md +37 -37
  62. package/kit/commands/auditar-cascading.md +111 -111
  63. package/kit/commands/auditar-marco.md +179 -179
  64. package/kit/commands/auditar-observabilidade-cobertura.md +183 -183
  65. package/kit/commands/auditar-refactor.md +219 -219
  66. package/kit/commands/auditar-release.md +109 -109
  67. package/kit/commands/auditar-uat.md +23 -23
  68. package/kit/commands/autonomo.md +40 -40
  69. package/kit/commands/branch-pr.md +24 -24
  70. package/kit/commands/burn-rate-status.md +408 -408
  71. package/kit/commands/capturar-payloads.md +193 -193
  72. package/kit/commands/caracterizar.md +212 -212
  73. package/kit/commands/concluir-marco.md +247 -247
  74. package/kit/commands/configuracoes.md +36 -36
  75. package/kit/commands/dados-distribuidos.md +188 -188
  76. package/kit/commands/definir-perfil.md +10 -10
  77. package/kit/commands/depurar.md +190 -190
  78. package/kit/commands/detectar-duplicacao.md +197 -197
  79. package/kit/commands/discutir-fase.md +131 -131
  80. package/kit/commands/encontrar-seams.md +136 -136
  81. package/kit/commands/entrar-discord.md +17 -17
  82. package/kit/commands/estatisticas.md +18 -18
  83. package/kit/commands/example-greeting.md +33 -33
  84. package/kit/commands/executar-fase.md +58 -58
  85. package/kit/commands/expresso.md +56 -56
  86. package/kit/commands/fase-ui.md +34 -34
  87. package/kit/commands/fazer.md +57 -57
  88. package/kit/commands/fio.md +125 -125
  89. package/kit/commands/fluxos-trabalho.md +64 -64
  90. package/kit/commands/forense.md +176 -176
  91. package/kit/commands/gerenciador.md +38 -38
  92. package/kit/commands/inserir-fase.md +31 -31
  93. package/kit/commands/legacy.md +263 -263
  94. package/kit/commands/limpeza.md +17 -17
  95. package/kit/commands/listar-hipoteses-fase.md +45 -45
  96. package/kit/commands/listar-workspaces.md +18 -18
  97. package/kit/commands/load-shedding.md +117 -117
  98. package/kit/commands/mapear-codebase.md +70 -70
  99. package/kit/commands/multi-tenant.md +163 -163
  100. package/kit/commands/nota.md +33 -33
  101. package/kit/commands/novo-marco.md +43 -43
  102. package/kit/commands/novo-projeto.md +41 -41
  103. package/kit/commands/novo-workspace.md +43 -43
  104. package/kit/commands/pausar-trabalho.md +37 -37
  105. package/kit/commands/perfil-usuario.md +45 -45
  106. package/kit/commands/pesquisar-fase.md +195 -195
  107. package/kit/commands/planejar-fase.md +67 -67
  108. package/kit/commands/planejar-lacunas.md +33 -33
  109. package/kit/commands/plantar-ideia.md +25 -25
  110. package/kit/commands/progresso.md +24 -24
  111. package/kit/commands/proximo.md +30 -30
  112. package/kit/commands/publicar.md +490 -490
  113. package/kit/commands/rapido.md +35 -35
  114. package/kit/commands/reaplicar-patches.md +124 -124
  115. package/kit/commands/refactor-seguro.md +321 -321
  116. package/kit/commands/relatorio-sessao.md +19 -19
  117. package/kit/commands/remover-fase.md +31 -31
  118. package/kit/commands/remover-workspace.md +26 -26
  119. package/kit/commands/resumo-marco.md +50 -50
  120. package/kit/commands/retomar-trabalho.md +40 -40
  121. package/kit/commands/revisar-backlog.md +60 -60
  122. package/kit/commands/revisar-ui.md +32 -32
  123. package/kit/commands/revisar.md +37 -37
  124. package/kit/commands/saude.md +21 -21
  125. package/kit/commands/setup-notion.md +93 -93
  126. package/kit/commands/storytelling.md +179 -179
  127. package/kit/commands/supabase.md +30 -7
  128. package/kit/commands/sync-main.md +68 -68
  129. package/kit/commands/validar-fase.md +35 -35
  130. package/kit/commands/verificar-tarefas.md +44 -44
  131. package/kit/commands/verificar-trabalho.md +64 -64
  132. package/kit/file-manifest.json +15 -8
  133. package/kit/framework/bin/lib/commands.cjs +959 -959
  134. package/kit/framework/bin/lib/config.cjs +442 -442
  135. package/kit/framework/bin/lib/core.cjs +1230 -1230
  136. package/kit/framework/bin/lib/frontmatter.cjs +336 -336
  137. package/kit/framework/bin/lib/init.cjs +1442 -1442
  138. package/kit/framework/bin/lib/milestone.cjs +252 -252
  139. package/kit/framework/bin/lib/model-profiles.cjs +68 -68
  140. package/kit/framework/bin/lib/phase.cjs +888 -888
  141. package/kit/framework/bin/lib/profile-output.cjs +952 -952
  142. package/kit/framework/bin/lib/profile-pipeline.cjs +539 -539
  143. package/kit/framework/bin/lib/roadmap.cjs +329 -329
  144. package/kit/framework/bin/lib/security.cjs +382 -382
  145. package/kit/framework/bin/lib/state.cjs +1031 -1031
  146. package/kit/framework/bin/lib/template.cjs +222 -222
  147. package/kit/framework/bin/lib/uat.cjs +282 -282
  148. package/kit/framework/bin/lib/verify.cjs +888 -888
  149. package/kit/framework/bin/lib/workstream.cjs +491 -491
  150. package/kit/framework/bin/tools.cjs +918 -918
  151. package/kit/framework/commands/workstreams.md +63 -63
  152. package/kit/framework/references/checkpoints.md +778 -778
  153. package/kit/framework/references/continuation-format.md +249 -249
  154. package/kit/framework/references/decimal-phase-calculation.md +64 -64
  155. package/kit/framework/references/git-integration.md +295 -295
  156. package/kit/framework/references/git-planning-commit.md +38 -38
  157. package/kit/framework/references/model-profile-resolution.md +36 -36
  158. package/kit/framework/references/model-profiles.md +139 -139
  159. package/kit/framework/references/phase-argument-parsing.md +61 -61
  160. package/kit/framework/references/planning-config.md +202 -202
  161. package/kit/framework/references/questioning.md +162 -162
  162. package/kit/framework/references/tdd.md +263 -263
  163. package/kit/framework/references/ui-brand.md +160 -160
  164. package/kit/framework/references/user-profiling.md +657 -657
  165. package/kit/framework/references/verification-patterns.md +612 -612
  166. package/kit/framework/references/workstream-flag.md +58 -58
  167. package/kit/framework/templates/DEBUG.md +164 -164
  168. package/kit/framework/templates/UAT.md +265 -265
  169. package/kit/framework/templates/UI-SPEC.md +100 -100
  170. package/kit/framework/templates/VALIDATION.md +76 -76
  171. package/kit/framework/templates/claude-md.md +122 -122
  172. package/kit/framework/templates/codebase/architecture.md +185 -185
  173. package/kit/framework/templates/codebase/concerns.md +205 -205
  174. package/kit/framework/templates/codebase/conventions.md +204 -204
  175. package/kit/framework/templates/codebase/integrations.md +192 -192
  176. package/kit/framework/templates/codebase/stack.md +158 -158
  177. package/kit/framework/templates/codebase/structure.md +199 -199
  178. package/kit/framework/templates/codebase/testing.md +301 -301
  179. package/kit/framework/templates/config.json +44 -44
  180. package/kit/framework/templates/context.md +352 -352
  181. package/kit/framework/templates/continue-here.md +78 -78
  182. package/kit/framework/templates/copilot-instructions.md +7 -7
  183. package/kit/framework/templates/debug-subagent-prompt.md +91 -91
  184. package/kit/framework/templates/dev-preferences.md +20 -20
  185. package/kit/framework/templates/discovery.md +146 -146
  186. package/kit/framework/templates/discussion-log.md +63 -63
  187. package/kit/framework/templates/milestone-archive.md +123 -123
  188. package/kit/framework/templates/milestone.md +115 -115
  189. package/kit/framework/templates/phase-prompt.md +610 -610
  190. package/kit/framework/templates/planner-subagent-prompt.md +117 -117
  191. package/kit/framework/templates/project.md +186 -186
  192. package/kit/framework/templates/requirements.md +231 -231
  193. package/kit/framework/templates/research-project/ARCHITECTURE.md +204 -204
  194. package/kit/framework/templates/research-project/FEATURES.md +147 -147
  195. package/kit/framework/templates/research-project/PITFALLS.md +200 -200
  196. package/kit/framework/templates/research-project/STACK.md +120 -120
  197. package/kit/framework/templates/research-project/SUMMARY.md +170 -170
  198. package/kit/framework/templates/research.md +419 -419
  199. package/kit/framework/templates/retrospective.md +54 -54
  200. package/kit/framework/templates/roadmap.md +202 -202
  201. package/kit/framework/templates/state.md +176 -176
  202. package/kit/framework/templates/summary-complex.md +59 -59
  203. package/kit/framework/templates/summary-minimal.md +41 -41
  204. package/kit/framework/templates/summary-standard.md +48 -48
  205. package/kit/framework/templates/summary.md +209 -209
  206. package/kit/framework/templates/user-profile.md +146 -146
  207. package/kit/framework/templates/user-setup.md +256 -256
  208. package/kit/framework/templates/verification-report.md +258 -258
  209. package/kit/framework/workflows/add-phase.md +112 -112
  210. package/kit/framework/workflows/add-tests.md +351 -351
  211. package/kit/framework/workflows/add-todo.md +158 -158
  212. package/kit/framework/workflows/audit-milestone.md +340 -340
  213. package/kit/framework/workflows/audit-uat.md +109 -109
  214. package/kit/framework/workflows/autonomous.md +891 -891
  215. package/kit/framework/workflows/check-todos.md +177 -177
  216. package/kit/framework/workflows/cleanup.md +152 -152
  217. package/kit/framework/workflows/complete-milestone.md +696 -696
  218. package/kit/framework/workflows/diagnose-issues.md +231 -231
  219. package/kit/framework/workflows/discovery-phase.md +289 -289
  220. package/kit/framework/workflows/discuss-phase-assumptions.md +653 -653
  221. package/kit/framework/workflows/discuss-phase.md +784 -784
  222. package/kit/framework/workflows/do.md +104 -104
  223. package/kit/framework/workflows/execute-phase.md +838 -838
  224. package/kit/framework/workflows/execute-plan.md +510 -510
  225. package/kit/framework/workflows/fast.md +102 -102
  226. package/kit/framework/workflows/forensics.md +265 -265
  227. package/kit/framework/workflows/health.md +181 -181
  228. package/kit/framework/workflows/help.md +619 -619
  229. package/kit/framework/workflows/insert-phase.md +130 -130
  230. package/kit/framework/workflows/list-phase-assumptions.md +178 -178
  231. package/kit/framework/workflows/list-workspaces.md +56 -56
  232. package/kit/framework/workflows/manager.md +362 -362
  233. package/kit/framework/workflows/map-codebase.md +377 -377
  234. package/kit/framework/workflows/milestone-summary.md +223 -223
  235. package/kit/framework/workflows/new-milestone.md +486 -486
  236. package/kit/framework/workflows/new-project.md +1159 -1159
  237. package/kit/framework/workflows/new-workspace.md +237 -237
  238. package/kit/framework/workflows/next.md +97 -97
  239. package/kit/framework/workflows/node-repair.md +92 -92
  240. package/kit/framework/workflows/note.md +156 -156
  241. package/kit/framework/workflows/pause-work.md +176 -176
  242. package/kit/framework/workflows/plan-milestone-gaps.md +273 -273
  243. package/kit/framework/workflows/plan-phase.md +765 -765
  244. package/kit/framework/workflows/plant-seed.md +169 -169
  245. package/kit/framework/workflows/pr-branch.md +129 -129
  246. package/kit/framework/workflows/profile-user.md +450 -450
  247. package/kit/framework/workflows/progress.md +507 -507
  248. package/kit/framework/workflows/quick.md +757 -757
  249. package/kit/framework/workflows/remove-phase.md +155 -155
  250. package/kit/framework/workflows/remove-workspace.md +90 -90
  251. package/kit/framework/workflows/research-phase.md +82 -82
  252. package/kit/framework/workflows/resume-project.md +326 -326
  253. package/kit/framework/workflows/review.md +228 -228
  254. package/kit/framework/workflows/session-report.md +146 -146
  255. package/kit/framework/workflows/settings.md +283 -283
  256. package/kit/framework/workflows/ship.md +228 -228
  257. package/kit/framework/workflows/stats.md +60 -60
  258. package/kit/framework/workflows/transition.md +671 -671
  259. package/kit/framework/workflows/ui-phase.md +302 -302
  260. package/kit/framework/workflows/ui-review.md +165 -165
  261. package/kit/framework/workflows/update.md +323 -323
  262. package/kit/framework/workflows/validate-phase.md +174 -174
  263. package/kit/framework/workflows/verify-phase.md +252 -252
  264. package/kit/framework/workflows/verify-work.md +637 -637
  265. package/kit/hooks/check-update.js +118 -118
  266. package/kit/hooks/context-monitor.js +163 -163
  267. package/kit/hooks/kit-attribution-reminder.cjs +98 -0
  268. package/kit/hooks/prompt-guard.js +103 -103
  269. package/kit/hooks/statusline.js +125 -125
  270. package/kit/hooks/workflow-guard.js +101 -101
  271. package/kit/settings.json +45 -45
  272. package/kit/skills/_shared-supabase/glossary.md +17 -0
  273. package/kit/skills/ai-prompt-characterization/SKILL.md +335 -335
  274. package/kit/skills/armadilhas-sistemas-distribuidos/SKILL.md +447 -447
  275. package/kit/skills/audit-log-multi-tenant/SKILL.md +340 -340
  276. package/kit/skills/b2b-saas-architecture/SKILL.md +300 -300
  277. package/kit/skills/consistencia-leitura-replica/SKILL.md +385 -385
  278. package/kit/skills/crm-lead-pipeline-patterns/SKILL.md +343 -343
  279. package/kit/skills/escolha-modelo-consistencia/SKILL.md +494 -494
  280. package/kit/skills/evolucao-schema-compativel/SKILL.md +448 -448
  281. package/kit/skills/evolution-go-whatsapp-integration/SKILL.md +322 -322
  282. package/kit/skills/example-skill/SKILL.md +42 -42
  283. package/kit/skills/legacy-api-only-applications/SKILL.md +358 -358
  284. package/kit/skills/legacy-characterization-tests/SKILL.md +330 -330
  285. package/kit/skills/legacy-effect-analysis/SKILL.md +331 -331
  286. package/kit/skills/legacy-extract-class/SKILL.md +203 -203
  287. package/kit/skills/legacy-programming-by-difference/SKILL.md +252 -252
  288. package/kit/skills/legacy-seams-and-test-harness/SKILL.md +460 -460
  289. package/kit/skills/legacy-shotgun-surgery/SKILL.md +286 -286
  290. package/kit/skills/legacy-sprout-wrap-techniques/SKILL.md +434 -434
  291. package/kit/skills/legacy-storytelling-naked-crc/SKILL.md +270 -270
  292. package/kit/skills/lgpd-multi-tenant-compliance/SKILL.md +340 -340
  293. package/kit/skills/member-invite-flow/SKILL.md +305 -305
  294. package/kit/skills/member-management-react-shadcn/SKILL.md +328 -328
  295. package/kit/skills/multi-tenant-performance-scaling/SKILL.md +316 -316
  296. package/kit/skills/multi-tenant-rls-hierarchy/SKILL.md +342 -342
  297. package/kit/skills/org-onboarding-flow/SKILL.md +257 -257
  298. package/kit/skills/org-switcher-react-pattern/SKILL.md +349 -349
  299. package/kit/skills/permission-gate-react-pattern/SKILL.md +271 -271
  300. package/kit/skills/postgres-isolamento-concorrencia/SKILL.md +552 -552
  301. package/kit/skills/pre-refactor-characterization/SKILL.md +421 -421
  302. package/kit/skills/rbac-permissions-matrix-supabase/SKILL.md +338 -338
  303. package/kit/skills/streams-eventos-cdc/SKILL.md +711 -711
  304. package/kit/skills/supabase-branching-workflow/SKILL.md +544 -544
  305. package/kit/skills/supabase-ci-cd-github-actions/SKILL.md +880 -880
  306. package/kit/skills/supabase-column-level-security/SKILL.md +426 -426
  307. package/kit/skills/supabase-config-toml-remotes/SKILL.md +807 -807
  308. package/kit/skills/supabase-custom-claims-rbac/SKILL.md +472 -472
  309. package/kit/skills/supabase-edge-functions/SKILL.md +229 -141
  310. package/kit/skills/supabase-edge-functions-auth/SKILL.md +309 -0
  311. package/kit/skills/supabase-edge-functions-limits/SKILL.md +302 -0
  312. package/kit/skills/supabase-edge-functions-mcp-server/SKILL.md +279 -0
  313. package/kit/skills/supabase-edge-functions-testing/SKILL.md +277 -0
  314. package/kit/skills/supabase-edge-runtime-builtins/SKILL.md +357 -0
  315. package/kit/skills/supabase-migration-repair/SKILL.md +823 -823
  316. package/kit/skills/supabase-migrations/SKILL.md +297 -297
  317. package/kit/skills/supabase-pgtap-testing/SKILL.md +1053 -1053
  318. package/kit/skills/supabase-postgres-roles/SKILL.md +392 -392
  319. package/kit/skills/supabase-realtime/SKILL.md +460 -236
  320. package/kit/skills/supabase-rls-defense-in-depth/SKILL.md +418 -418
  321. package/kit/skills/supabase-rls-policies/SKILL.md +635 -635
  322. package/kit/skills/super-admin-platform-pattern/SKILL.md +326 -326
  323. package/kit/skills/tenant-quente-mitigacao/SKILL.md +605 -605
  324. package/kit/skills/whatsapp-conversation-state-machine/SKILL.md +287 -287
  325. package/package.json +1 -1
  326. package/src/core/kit.js +216 -216
  327. package/src/core/reflect.js +247 -247
  328. package/src/core/reverse-sync.js +372 -372
  329. package/src/core/sync.js +418 -418
  330. package/src/core/watch.js +121 -121
  331. package/src/mcp-server/index.js +715 -693
@@ -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)