@luanpdd/kit-mcp 1.30.1 → 1.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +168 -168
  3. package/gates/agent-no-recursive-dispatch.md +84 -82
  4. package/kit/COMANDOS.md +138 -138
  5. package/kit/README.md +76 -76
  6. package/kit/agents/advisor-researcher.md +107 -106
  7. package/kit/agents/ai-mutation-tester.md +1 -0
  8. package/kit/agents/assumptions-analyzer.md +108 -107
  9. package/kit/agents/audit-log-implementer.md +314 -313
  10. package/kit/agents/auditor-consistencia-isolamento.md +414 -413
  11. package/kit/agents/b2b-saas-architect.md +157 -156
  12. package/kit/agents/burn-rate-forecaster.md +1 -0
  13. package/kit/agents/cascading-failures-auditor.md +299 -298
  14. package/kit/agents/codebase-mapper.md +769 -768
  15. package/kit/agents/crm-pipeline-implementer.md +257 -256
  16. package/kit/agents/debugger.md +814 -813
  17. package/kit/agents/detector-tenant-quente.md +338 -337
  18. package/kit/agents/evolution-go-integrator.md +201 -200
  19. package/kit/agents/example-reviewer.md +22 -21
  20. package/kit/agents/executor.md +565 -564
  21. package/kit/agents/golden-signals-instrumenter.md +1 -0
  22. package/kit/agents/incident-investigator.md +1 -0
  23. package/kit/agents/integration-checker.md +201 -200
  24. package/kit/agents/invite-flow-implementer.md +190 -189
  25. package/kit/agents/legacy-characterizer.md +369 -368
  26. package/kit/agents/lgpd-compliance-auditor.md +296 -295
  27. package/kit/agents/load-shedding-instrumenter.md +1 -0
  28. package/kit/agents/multi-tenant-isolation-auditor.md +254 -253
  29. package/kit/agents/multi-tenant-rls-writer.md +341 -340
  30. package/kit/agents/nyquist-auditor.md +179 -178
  31. package/kit/agents/observability-coverage-auditor.md +316 -315
  32. package/kit/agents/observability-instrumenter.md +1 -0
  33. package/kit/agents/omm-auditor.md +1 -0
  34. package/kit/agents/org-onboarding-implementer.md +224 -223
  35. package/kit/agents/payload-capture-instrumenter.md +274 -273
  36. package/kit/agents/phase-researcher.md +697 -696
  37. package/kit/agents/plan-checker.md +273 -272
  38. package/kit/agents/planner.md +923 -922
  39. package/kit/agents/postmortem-writer.md +1 -0
  40. package/kit/agents/project-researcher.md +653 -652
  41. package/kit/agents/prr-conductor.md +1 -0
  42. package/kit/agents/refactor-safety-auditor.md +405 -404
  43. package/kit/agents/release-pipeline-auditor.md +1 -0
  44. package/kit/agents/research-synthesizer.md +246 -245
  45. package/kit/agents/roadmapper.md +678 -677
  46. package/kit/agents/schema-checker.md +1 -0
  47. package/kit/agents/seam-finder.md +360 -359
  48. package/kit/agents/shotgun-surgery-detector.md +350 -349
  49. package/kit/agents/slo-engineer.md +1 -0
  50. package/kit/agents/storytelling-analyst.md +1 -0
  51. package/kit/agents/supabase-architect.md +1 -0
  52. package/kit/agents/supabase-auth-bootstrapper.md +1 -0
  53. package/kit/agents/supabase-branching-architect.md +563 -562
  54. package/kit/agents/supabase-cicd-pipeline-implementer.md +778 -777
  55. package/kit/agents/supabase-column-privileges-writer.md +400 -399
  56. package/kit/agents/supabase-edge-fn-tester.md +2 -1
  57. package/kit/agents/supabase-edge-fn-writer.md +2 -1
  58. package/kit/agents/supabase-migration-writer.md +386 -385
  59. package/kit/agents/supabase-rbac-implementer.md +393 -392
  60. package/kit/agents/supabase-realtime-implementer.md +364 -363
  61. package/kit/agents/supabase-rls-hardener.md +522 -521
  62. package/kit/agents/supabase-rls-writer.md +324 -323
  63. package/kit/agents/supabase-roles-implementer.md +356 -355
  64. package/kit/agents/supabase-storage-implementer.md +1 -0
  65. package/kit/agents/super-admin-implementer.md +282 -281
  66. package/kit/agents/toil-auditor.md +1 -0
  67. package/kit/agents/ui-auditor.md +438 -437
  68. package/kit/agents/ui-checker.md +303 -302
  69. package/kit/agents/ui-researcher.md +356 -355
  70. package/kit/agents/user-profiler.md +176 -175
  71. package/kit/agents/validador-evolucao-schema.md +336 -335
  72. package/kit/agents/verifier.md +729 -728
  73. package/kit/commands/adicionar-backlog.md +75 -75
  74. package/kit/commands/adicionar-fase.md +42 -42
  75. package/kit/commands/adicionar-tarefa.md +45 -45
  76. package/kit/commands/adicionar-testes.md +41 -41
  77. package/kit/commands/ajuda.md +21 -21
  78. package/kit/commands/atualizar.md +37 -37
  79. package/kit/commands/auditar-cascading.md +111 -111
  80. package/kit/commands/auditar-marco.md +179 -179
  81. package/kit/commands/auditar-observabilidade-cobertura.md +183 -183
  82. package/kit/commands/auditar-refactor.md +219 -219
  83. package/kit/commands/auditar-release.md +109 -109
  84. package/kit/commands/auditar-uat.md +23 -23
  85. package/kit/commands/autonomo.md +40 -40
  86. package/kit/commands/branch-pr.md +24 -24
  87. package/kit/commands/burn-rate-status.md +408 -408
  88. package/kit/commands/capturar-payloads.md +193 -193
  89. package/kit/commands/caracterizar.md +212 -212
  90. package/kit/commands/concluir-marco.md +247 -247
  91. package/kit/commands/configuracoes.md +36 -36
  92. package/kit/commands/dados-distribuidos.md +188 -188
  93. package/kit/commands/definir-perfil.md +10 -10
  94. package/kit/commands/depurar.md +190 -190
  95. package/kit/commands/detectar-duplicacao.md +197 -197
  96. package/kit/commands/discutir-fase.md +131 -131
  97. package/kit/commands/encontrar-seams.md +136 -136
  98. package/kit/commands/entrar-discord.md +17 -17
  99. package/kit/commands/estatisticas.md +18 -18
  100. package/kit/commands/example-greeting.md +33 -33
  101. package/kit/commands/executar-fase.md +58 -58
  102. package/kit/commands/expresso.md +56 -56
  103. package/kit/commands/fase-ui.md +34 -34
  104. package/kit/commands/fazer.md +57 -57
  105. package/kit/commands/fio.md +125 -125
  106. package/kit/commands/fluxos-trabalho.md +64 -64
  107. package/kit/commands/forense.md +176 -176
  108. package/kit/commands/gerenciador.md +38 -38
  109. package/kit/commands/inserir-fase.md +31 -31
  110. package/kit/commands/legacy.md +263 -263
  111. package/kit/commands/limpeza.md +17 -17
  112. package/kit/commands/listar-hipoteses-fase.md +45 -45
  113. package/kit/commands/listar-workspaces.md +18 -18
  114. package/kit/commands/load-shedding.md +117 -117
  115. package/kit/commands/mapear-codebase.md +70 -70
  116. package/kit/commands/multi-tenant.md +163 -163
  117. package/kit/commands/nota.md +33 -33
  118. package/kit/commands/novo-marco.md +43 -43
  119. package/kit/commands/novo-projeto.md +41 -41
  120. package/kit/commands/novo-workspace.md +43 -43
  121. package/kit/commands/pausar-trabalho.md +37 -37
  122. package/kit/commands/perfil-usuario.md +45 -45
  123. package/kit/commands/pesquisar-fase.md +195 -195
  124. package/kit/commands/planejar-fase.md +67 -67
  125. package/kit/commands/planejar-lacunas.md +33 -33
  126. package/kit/commands/plantar-ideia.md +25 -25
  127. package/kit/commands/progresso.md +24 -24
  128. package/kit/commands/proximo.md +30 -30
  129. package/kit/commands/publicar.md +490 -490
  130. package/kit/commands/rapido.md +35 -35
  131. package/kit/commands/reaplicar-patches.md +124 -124
  132. package/kit/commands/refactor-seguro.md +321 -321
  133. package/kit/commands/relatorio-sessao.md +19 -19
  134. package/kit/commands/remover-fase.md +31 -31
  135. package/kit/commands/remover-workspace.md +26 -26
  136. package/kit/commands/resumo-marco.md +50 -50
  137. package/kit/commands/retomar-trabalho.md +40 -40
  138. package/kit/commands/revisar-backlog.md +60 -60
  139. package/kit/commands/revisar-ui.md +32 -32
  140. package/kit/commands/revisar.md +37 -37
  141. package/kit/commands/saude.md +21 -21
  142. package/kit/commands/setup-notion.md +93 -93
  143. package/kit/commands/storytelling.md +179 -179
  144. package/kit/commands/sync-main.md +68 -68
  145. package/kit/commands/validar-fase.md +35 -35
  146. package/kit/commands/verificar-tarefas.md +44 -44
  147. package/kit/commands/verificar-trabalho.md +64 -64
  148. package/kit/file-manifest.json +82 -81
  149. package/kit/framework/bin/lib/commands.cjs +959 -959
  150. package/kit/framework/bin/lib/config.cjs +442 -442
  151. package/kit/framework/bin/lib/core.cjs +1230 -1230
  152. package/kit/framework/bin/lib/frontmatter.cjs +336 -336
  153. package/kit/framework/bin/lib/init.cjs +1442 -1442
  154. package/kit/framework/bin/lib/milestone.cjs +252 -252
  155. package/kit/framework/bin/lib/model-profiles.cjs +68 -68
  156. package/kit/framework/bin/lib/phase.cjs +888 -888
  157. package/kit/framework/bin/lib/profile-output.cjs +952 -952
  158. package/kit/framework/bin/lib/profile-pipeline.cjs +539 -539
  159. package/kit/framework/bin/lib/roadmap.cjs +329 -329
  160. package/kit/framework/bin/lib/security.cjs +382 -382
  161. package/kit/framework/bin/lib/state.cjs +1031 -1031
  162. package/kit/framework/bin/lib/template.cjs +222 -222
  163. package/kit/framework/bin/lib/uat.cjs +282 -282
  164. package/kit/framework/bin/lib/verify.cjs +888 -888
  165. package/kit/framework/bin/lib/workstream.cjs +491 -491
  166. package/kit/framework/bin/tools.cjs +918 -918
  167. package/kit/framework/commands/workstreams.md +63 -63
  168. package/kit/framework/references/checkpoints.md +778 -778
  169. package/kit/framework/references/continuation-format.md +249 -249
  170. package/kit/framework/references/decimal-phase-calculation.md +64 -64
  171. package/kit/framework/references/git-integration.md +295 -295
  172. package/kit/framework/references/git-planning-commit.md +38 -38
  173. package/kit/framework/references/model-profile-resolution.md +36 -36
  174. package/kit/framework/references/model-profiles.md +139 -139
  175. package/kit/framework/references/phase-argument-parsing.md +61 -61
  176. package/kit/framework/references/planning-config.md +202 -202
  177. package/kit/framework/references/questioning.md +162 -162
  178. package/kit/framework/references/tdd.md +263 -263
  179. package/kit/framework/references/ui-brand.md +160 -160
  180. package/kit/framework/references/user-profiling.md +657 -657
  181. package/kit/framework/references/verification-patterns.md +612 -612
  182. package/kit/framework/references/workstream-flag.md +58 -58
  183. package/kit/framework/templates/DEBUG.md +164 -164
  184. package/kit/framework/templates/UAT.md +265 -265
  185. package/kit/framework/templates/UI-SPEC.md +100 -100
  186. package/kit/framework/templates/VALIDATION.md +76 -76
  187. package/kit/framework/templates/claude-md.md +122 -122
  188. package/kit/framework/templates/codebase/architecture.md +185 -185
  189. package/kit/framework/templates/codebase/concerns.md +205 -205
  190. package/kit/framework/templates/codebase/conventions.md +204 -204
  191. package/kit/framework/templates/codebase/integrations.md +192 -192
  192. package/kit/framework/templates/codebase/stack.md +158 -158
  193. package/kit/framework/templates/codebase/structure.md +199 -199
  194. package/kit/framework/templates/codebase/testing.md +301 -301
  195. package/kit/framework/templates/config.json +44 -44
  196. package/kit/framework/templates/context.md +352 -352
  197. package/kit/framework/templates/continue-here.md +78 -78
  198. package/kit/framework/templates/copilot-instructions.md +7 -7
  199. package/kit/framework/templates/debug-subagent-prompt.md +91 -91
  200. package/kit/framework/templates/dev-preferences.md +20 -20
  201. package/kit/framework/templates/discovery.md +146 -146
  202. package/kit/framework/templates/discussion-log.md +63 -63
  203. package/kit/framework/templates/milestone-archive.md +123 -123
  204. package/kit/framework/templates/milestone.md +115 -115
  205. package/kit/framework/templates/phase-prompt.md +610 -610
  206. package/kit/framework/templates/planner-subagent-prompt.md +117 -117
  207. package/kit/framework/templates/project.md +186 -186
  208. package/kit/framework/templates/requirements.md +231 -231
  209. package/kit/framework/templates/research-project/ARCHITECTURE.md +204 -204
  210. package/kit/framework/templates/research-project/FEATURES.md +147 -147
  211. package/kit/framework/templates/research-project/PITFALLS.md +200 -200
  212. package/kit/framework/templates/research-project/STACK.md +120 -120
  213. package/kit/framework/templates/research-project/SUMMARY.md +170 -170
  214. package/kit/framework/templates/research.md +419 -419
  215. package/kit/framework/templates/retrospective.md +54 -54
  216. package/kit/framework/templates/roadmap.md +202 -202
  217. package/kit/framework/templates/state.md +176 -176
  218. package/kit/framework/templates/summary-complex.md +59 -59
  219. package/kit/framework/templates/summary-minimal.md +41 -41
  220. package/kit/framework/templates/summary-standard.md +48 -48
  221. package/kit/framework/templates/summary.md +209 -209
  222. package/kit/framework/templates/user-profile.md +146 -146
  223. package/kit/framework/templates/user-setup.md +256 -256
  224. package/kit/framework/templates/verification-report.md +258 -258
  225. package/kit/framework/workflows/add-phase.md +112 -112
  226. package/kit/framework/workflows/add-tests.md +351 -351
  227. package/kit/framework/workflows/add-todo.md +158 -158
  228. package/kit/framework/workflows/audit-milestone.md +340 -340
  229. package/kit/framework/workflows/audit-uat.md +109 -109
  230. package/kit/framework/workflows/autonomous.md +891 -891
  231. package/kit/framework/workflows/check-todos.md +177 -177
  232. package/kit/framework/workflows/cleanup.md +152 -152
  233. package/kit/framework/workflows/complete-milestone.md +696 -696
  234. package/kit/framework/workflows/diagnose-issues.md +231 -231
  235. package/kit/framework/workflows/discovery-phase.md +289 -289
  236. package/kit/framework/workflows/discuss-phase-assumptions.md +653 -653
  237. package/kit/framework/workflows/discuss-phase.md +784 -784
  238. package/kit/framework/workflows/do.md +104 -104
  239. package/kit/framework/workflows/execute-phase.md +838 -838
  240. package/kit/framework/workflows/execute-plan.md +510 -510
  241. package/kit/framework/workflows/fast.md +102 -102
  242. package/kit/framework/workflows/forensics.md +265 -265
  243. package/kit/framework/workflows/health.md +181 -181
  244. package/kit/framework/workflows/help.md +619 -619
  245. package/kit/framework/workflows/insert-phase.md +130 -130
  246. package/kit/framework/workflows/list-phase-assumptions.md +178 -178
  247. package/kit/framework/workflows/list-workspaces.md +56 -56
  248. package/kit/framework/workflows/manager.md +362 -362
  249. package/kit/framework/workflows/map-codebase.md +377 -377
  250. package/kit/framework/workflows/milestone-summary.md +223 -223
  251. package/kit/framework/workflows/new-milestone.md +486 -486
  252. package/kit/framework/workflows/new-project.md +1159 -1159
  253. package/kit/framework/workflows/new-workspace.md +237 -237
  254. package/kit/framework/workflows/next.md +97 -97
  255. package/kit/framework/workflows/node-repair.md +92 -92
  256. package/kit/framework/workflows/note.md +156 -156
  257. package/kit/framework/workflows/pause-work.md +176 -176
  258. package/kit/framework/workflows/plan-milestone-gaps.md +273 -273
  259. package/kit/framework/workflows/plan-phase.md +765 -765
  260. package/kit/framework/workflows/plant-seed.md +169 -169
  261. package/kit/framework/workflows/pr-branch.md +129 -129
  262. package/kit/framework/workflows/profile-user.md +450 -450
  263. package/kit/framework/workflows/progress.md +507 -507
  264. package/kit/framework/workflows/quick.md +757 -757
  265. package/kit/framework/workflows/remove-phase.md +155 -155
  266. package/kit/framework/workflows/remove-workspace.md +90 -90
  267. package/kit/framework/workflows/research-phase.md +82 -82
  268. package/kit/framework/workflows/resume-project.md +326 -326
  269. package/kit/framework/workflows/review.md +228 -228
  270. package/kit/framework/workflows/session-report.md +146 -146
  271. package/kit/framework/workflows/settings.md +283 -283
  272. package/kit/framework/workflows/ship.md +228 -228
  273. package/kit/framework/workflows/stats.md +60 -60
  274. package/kit/framework/workflows/transition.md +671 -671
  275. package/kit/framework/workflows/ui-phase.md +302 -302
  276. package/kit/framework/workflows/ui-review.md +165 -165
  277. package/kit/framework/workflows/update.md +323 -323
  278. package/kit/framework/workflows/validate-phase.md +174 -174
  279. package/kit/framework/workflows/verify-phase.md +252 -252
  280. package/kit/framework/workflows/verify-work.md +637 -637
  281. package/kit/hooks/check-update.js +118 -118
  282. package/kit/hooks/context-monitor.js +163 -163
  283. package/kit/hooks/kit-attribution-reminder.cjs +30 -36
  284. package/kit/hooks/kit-router.cjs +137 -0
  285. package/kit/hooks/prompt-guard.js +103 -103
  286. package/kit/hooks/statusline.js +125 -125
  287. package/kit/hooks/workflow-guard.js +101 -101
  288. package/kit/settings.json +45 -45
  289. package/kit/skills/ai-prompt-characterization/SKILL.md +335 -335
  290. package/kit/skills/armadilhas-sistemas-distribuidos/SKILL.md +447 -447
  291. package/kit/skills/audit-log-multi-tenant/SKILL.md +340 -340
  292. package/kit/skills/b2b-saas-architecture/SKILL.md +300 -300
  293. package/kit/skills/consistencia-leitura-replica/SKILL.md +385 -385
  294. package/kit/skills/crm-lead-pipeline-patterns/SKILL.md +343 -343
  295. package/kit/skills/escolha-modelo-consistencia/SKILL.md +494 -494
  296. package/kit/skills/evolucao-schema-compativel/SKILL.md +448 -448
  297. package/kit/skills/evolution-go-whatsapp-integration/SKILL.md +322 -322
  298. package/kit/skills/example-skill/SKILL.md +42 -42
  299. package/kit/skills/legacy-api-only-applications/SKILL.md +358 -358
  300. package/kit/skills/legacy-characterization-tests/SKILL.md +330 -330
  301. package/kit/skills/legacy-effect-analysis/SKILL.md +331 -331
  302. package/kit/skills/legacy-extract-class/SKILL.md +203 -203
  303. package/kit/skills/legacy-programming-by-difference/SKILL.md +252 -252
  304. package/kit/skills/legacy-seams-and-test-harness/SKILL.md +460 -460
  305. package/kit/skills/legacy-shotgun-surgery/SKILL.md +286 -286
  306. package/kit/skills/legacy-sprout-wrap-techniques/SKILL.md +434 -434
  307. package/kit/skills/legacy-storytelling-naked-crc/SKILL.md +270 -270
  308. package/kit/skills/lgpd-multi-tenant-compliance/SKILL.md +340 -340
  309. package/kit/skills/member-invite-flow/SKILL.md +305 -305
  310. package/kit/skills/member-management-react-shadcn/SKILL.md +328 -328
  311. package/kit/skills/multi-tenant-performance-scaling/SKILL.md +316 -316
  312. package/kit/skills/multi-tenant-rls-hierarchy/SKILL.md +342 -342
  313. package/kit/skills/org-onboarding-flow/SKILL.md +257 -257
  314. package/kit/skills/org-switcher-react-pattern/SKILL.md +349 -349
  315. package/kit/skills/permission-gate-react-pattern/SKILL.md +271 -271
  316. package/kit/skills/postgres-isolamento-concorrencia/SKILL.md +552 -552
  317. package/kit/skills/pre-refactor-characterization/SKILL.md +421 -421
  318. package/kit/skills/rbac-permissions-matrix-supabase/SKILL.md +338 -338
  319. package/kit/skills/streams-eventos-cdc/SKILL.md +711 -711
  320. package/kit/skills/supabase-branching-workflow/SKILL.md +544 -544
  321. package/kit/skills/supabase-ci-cd-github-actions/SKILL.md +880 -880
  322. package/kit/skills/supabase-column-level-security/SKILL.md +426 -426
  323. package/kit/skills/supabase-config-toml-remotes/SKILL.md +807 -807
  324. package/kit/skills/supabase-custom-claims-rbac/SKILL.md +472 -472
  325. package/kit/skills/supabase-edge-functions/SKILL.md +1 -1
  326. package/kit/skills/supabase-edge-functions-auth/SKILL.md +1 -1
  327. package/kit/skills/supabase-edge-functions-limits/SKILL.md +1 -1
  328. package/kit/skills/supabase-edge-functions-mcp-server/SKILL.md +1 -1
  329. package/kit/skills/supabase-edge-functions-testing/SKILL.md +1 -1
  330. package/kit/skills/supabase-edge-runtime-builtins/SKILL.md +1 -1
  331. package/kit/skills/supabase-migration-repair/SKILL.md +823 -823
  332. package/kit/skills/supabase-migrations/SKILL.md +297 -297
  333. package/kit/skills/supabase-pgtap-testing/SKILL.md +1053 -1053
  334. package/kit/skills/supabase-postgres-roles/SKILL.md +392 -392
  335. package/kit/skills/supabase-realtime/SKILL.md +460 -460
  336. package/kit/skills/supabase-rls-defense-in-depth/SKILL.md +418 -418
  337. package/kit/skills/supabase-rls-policies/SKILL.md +635 -635
  338. package/kit/skills/super-admin-platform-pattern/SKILL.md +326 -326
  339. package/kit/skills/tenant-quente-mitigacao/SKILL.md +605 -605
  340. package/kit/skills/whatsapp-conversation-state-machine/SKILL.md +287 -287
  341. package/package.json +1 -1
  342. package/src/core/kit.js +216 -216
  343. package/src/core/reflect.js +247 -247
  344. package/src/core/reverse-sync.js +372 -372
  345. package/src/core/sync.js +437 -418
  346. package/src/core/watch.js +121 -121
  347. package/src/mcp-server/index.js +794 -715
@@ -1,326 +1,326 @@
1
- ---
2
- name: super-admin-platform-pattern
3
- description: "Use ao implementar plataforma super-admin em B2B SaaS multi-tenant"
4
- ---
5
-
6
- # Super-Admin Platform Pattern — B2B SaaS Multi-Tenant
7
-
8
- ## Quando usar
9
-
10
- LLM carrega esta skill ao implementar painel de super-admin (você gerenciando todos tenants). Trigger phrases:
11
-
12
- - "super admin platform", "platform admin"
13
- - "cross-tenant view", "list all orgs"
14
- - "impersonation user", "support takeover"
15
- - "super_admin app_metadata"
16
- - "GitHub Enterprise impersonation pattern"
17
-
18
- ## Regras absolutas
19
-
20
- **REGRA #1 (audit obrigatório — BLOCKER):** Toda ação super-admin **DEVE** emitir evento `super_admin_action` em `audit_logs`. Sem audit log = ABORT no agent (REGRA do `super-admin-implementer`). Compliance LGPD exige rastreabilidade.
21
-
22
- **REGRA #2 (impersonation TTL 30min):** Sessão de impersonation expira em **30 minutos** automaticamente. Após TTL, sessão revogada (`signOut` automático), super-admin precisa re-iniciar impersonation. Previne sessão zombie.
23
-
24
- **REGRA #3 (reason obrigatório):** Impersonation requer campo `reason` text não-vazio (mín 10 chars). Registrado em audit_log para investigação posterior. Sem reason = recusar ação.
25
-
26
- **REGRA #4 (banner visual obrigatório):** Quando super-admin está impersonando, UI mostra **banner persistente** (top da viewport) com texto "Você está vendo como <user.email> em <org.name>. Clique para sair." Cor de aviso (amarelo/vermelho), z-index máximo, não fechável.
27
-
28
- **REGRA #5 (super_admin via service_role apenas):** `app_metadata.super_admin = true` é setado **EXCLUSIVAMENTE** via `auth.admin.updateUserById()` com `SUPABASE_SERVICE_ROLE_KEY`. Cliente NUNCA consegue mutar. Endpoint de promoção isolado em Edge Function `verify_jwt: false` ou backend admin separado.
29
-
30
- **REGRA #6 (delete org requer dupla confirmação):** Deletar uma `organizations` (cascade dropping membros, leads, audit_logs) requer:
31
- 1. super-admin clica botão delete
32
- 2. Modal pede org.slug exato + reason text + checkbox "Entendo que isso é irreversível"
33
- 3. RPC `super_admin_delete_org(p_org_id, p_typed_slug, p_reason)` valida + executa + audit
34
-
35
- ## Patterns canônicos
36
-
37
- ### Cross-tenant view — RLS via PERMISSIVE
38
-
39
- ```sql
40
- -- Policy permissive em organizations: super_admin vê todas
41
- create policy "organizations_super_admin_view"
42
- on public.organizations
43
- as permissive
44
- for select
45
- to authenticated
46
- using (private.is_super_admin());
47
-
48
- -- Policy normal (já deve existir): owner/admin vê apenas a própria
49
- create policy "organizations_select_member"
50
- on public.organizations
51
- for select
52
- to authenticated
53
- using (private.is_member_of(id));
54
-
55
- -- Mesma lógica para todas tabelas críticas: leads, organization_members, audit_logs, etc.
56
- -- Padronizar via agent multi-tenant-rls-writer (Phase 108) com super_admin_bypass=true
57
- ```
58
-
59
- ### Frontend — listar todos tenants (super-admin only)
60
-
61
- ```typescript
62
- // SuperAdminDashboard.tsx
63
- import { createClient } from '@/lib/supabase/client'
64
-
65
- export function SuperAdminDashboard() {
66
- const supabase = createClient()
67
- const [orgs, setOrgs] = useState<Org[]>([])
68
-
69
- useEffect(() => {
70
- // RLS retorna TODAS orgs porque user é super_admin
71
- supabase.from('organizations')
72
- .select('id, name, slug, plan, status, created_at, organization_members(count)')
73
- .order('created_at', { ascending: false })
74
- .then(({ data }) => setOrgs(data || []))
75
- }, [])
76
-
77
- return (
78
- <Table>
79
- {orgs.map(o => (
80
- <Row key={o.id}>
81
- <Cell>{o.name}</Cell>
82
- <Cell>{o.slug}</Cell>
83
- <Cell>{o.plan}</Cell>
84
- <Cell>{o.organization_members[0].count}</Cell>
85
- <Cell>
86
- <Button onClick={() => startImpersonation(o.id)}>Impersonate</Button>
87
- </Cell>
88
- </Row>
89
- ))}
90
- </Table>
91
- )
92
- }
93
- ```
94
-
95
- ### Impersonation — Edge Function com TTL 30min
96
-
97
- ```typescript
98
- // supabase/functions/super-admin-impersonate/index.ts
99
- import { createClient } from 'jsr:@supabase/supabase-js@2'
100
-
101
- Deno.serve(async (req) => {
102
- const auth = req.headers.get('Authorization')
103
- if (!auth) return new Response('unauthorized', { status: 401 })
104
-
105
- // Validar caller é super_admin via JWT app_metadata
106
- const supabase = createClient(
107
- Deno.env.get('SUPABASE_URL')!,
108
- Deno.env.get('SUPABASE_ANON_KEY')!,
109
- { global: { headers: { Authorization: auth } } }
110
- )
111
-
112
- const { data: { user } } = await supabase.auth.getUser()
113
- if (!user || !user.app_metadata.super_admin) {
114
- return new Response('forbidden', { status: 403 })
115
- }
116
-
117
- const { target_user_id, target_org_id, reason } = await req.json()
118
-
119
- // REGRA #3: reason obrigatório (min 10 chars)
120
- if (!reason || reason.trim().length < 10) {
121
- return new Response(JSON.stringify({ error: 'reason_required_min_10_chars' }), { status: 400 })
122
- }
123
-
124
- // Audit ANTES de criar sessão (se falhar audit, falha a ação)
125
- await supabase.rpc('audit_log', {
126
- p_event_type: 'super_admin_action',
127
- p_tenant_id: target_org_id,
128
- p_target_id: target_user_id,
129
- p_target_type: 'user',
130
- p_payload: {
131
- action: 'impersonation_started',
132
- reason,
133
- session_ttl_minutes: 30
134
- }
135
- })
136
-
137
- // Criar sessão impersonation via service_role
138
- const admin = createClient(
139
- Deno.env.get('SUPABASE_URL')!,
140
- Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')! // service role
141
- )
142
-
143
- const { data: targetUser } = await admin.auth.admin.getUserById(target_user_id)
144
- if (!targetUser.user) return new Response('target_not_found', { status: 404 })
145
-
146
- // Gerar magic link com expiry curto (30min)
147
- const { data: magicLink } = await admin.auth.admin.generateLink({
148
- type: 'magiclink',
149
- email: targetUser.user.email!,
150
- options: {
151
- redirectTo: `${Deno.env.get('APP_URL')}/?impersonating=1&original_admin_id=${user.id}`
152
- }
153
- })
154
-
155
- // Cookie marker no client side (banner visual lê isso)
156
- return new Response(JSON.stringify({
157
- magic_link: magicLink.properties.action_link,
158
- expires_at: new Date(Date.now() + 30 * 60 * 1000).toISOString()
159
- }), {
160
- headers: { 'Content-Type': 'application/json' }
161
- })
162
- })
163
- ```
164
-
165
- ### Banner visual de impersonation (React)
166
-
167
- ```typescript
168
- // app/components/ImpersonationBanner.tsx
169
- 'use client'
170
-
171
- export function ImpersonationBanner() {
172
- const searchParams = useSearchParams()
173
- const isImpersonating = searchParams.get('impersonating') === '1'
174
- const adminId = searchParams.get('original_admin_id')
175
-
176
- if (!isImpersonating) return null
177
-
178
- const stopImpersonation = async () => {
179
- await supabase.auth.signOut()
180
- window.location.href = `/super-admin?stopped_impersonation=1&original_admin_id=${adminId}`
181
- }
182
-
183
- return (
184
- <div className="fixed top-0 left-0 right-0 z-[9999] bg-yellow-400 text-black px-4 py-2 flex items-center justify-between">
185
- <span>
186
- ⚠ Você está vendo como outro usuário (super-admin impersonation).
187
- Sessão expira em <Countdown to={expiresAt} />.
188
- </span>
189
- <Button variant="destructive" size="sm" onClick={stopImpersonation}>
190
- Parar impersonation
191
- </Button>
192
- </div>
193
- )
194
- }
195
- ```
196
-
197
- ### Promover usuário a super_admin (backend admin script)
198
-
199
- ```typescript
200
- // scripts/promote-super-admin.ts (NÃO Edge Function — script administrativo)
201
- // Executado manualmente OU via CLI admin tool (NÃO frontend)
202
- import { createClient } from '@supabase/supabase-js'
203
-
204
- const admin = createClient(
205
- process.env.SUPABASE_URL!,
206
- process.env.SUPABASE_SERVICE_ROLE_KEY! // SECRET — NUNCA em frontend
207
- )
208
-
209
- await admin.auth.admin.updateUserById(userId, {
210
- app_metadata: { super_admin: true }
211
- })
212
- ```
213
-
214
- ### RPC delete org com dupla confirmação
215
-
216
- ```sql
217
- create or replace function public.super_admin_delete_org(
218
- p_org_id uuid,
219
- p_typed_slug text,
220
- p_reason text
221
- )
222
- returns void
223
- language plpgsql
224
- security invoker
225
- set search_path = ''
226
- as $$
227
- declare
228
- v_org_slug text;
229
- begin
230
- -- Validar caller é super_admin
231
- if not private.is_super_admin() then
232
- raise exception 'forbidden_super_admin_only';
233
- end if;
234
-
235
- -- Validar reason
236
- if length(trim(p_reason)) < 10 then
237
- raise exception 'reason_required_min_10_chars';
238
- end if;
239
-
240
- -- Validar typed_slug bate com slug real (REGRA #6 dupla confirmação)
241
- select slug into v_org_slug from public.organizations where id = p_org_id;
242
- if v_org_slug is null then raise exception 'org_not_found'; end if;
243
- if v_org_slug != p_typed_slug then
244
- raise exception 'slug_mismatch_confirmation_failed';
245
- end if;
246
-
247
- -- Audit ANTES (preserva histórico)
248
- perform private.audit_log(
249
- 'super_admin_action',
250
- p_org_id,
251
- null, 'org', null,
252
- jsonb_build_object('action', 'delete_org', 'slug', v_org_slug, 'reason', p_reason)
253
- );
254
-
255
- -- Soft delete preferred (status = 'archived'), hard delete se realmente necessário
256
- update public.organizations set status = 'archived' where id = p_org_id;
257
-
258
- -- Hard delete (se exigido — descomenta abaixo)
259
- -- delete from public.organizations where id = p_org_id;
260
- -- (cascade dropa: organization_members, departments, leads, etc.; audit_logs preservado por design)
261
- end;
262
- $$;
263
-
264
- grant execute on function public.super_admin_delete_org(uuid, text, text) to authenticated;
265
- ```
266
-
267
- ## Anti-patterns
268
-
269
- ### Anti-pattern 1: super_admin sem audit log (BLOCKER)
270
-
271
- **Errado:**
272
- ```sql
273
- -- super_admin policy permite tudo, sem trigger ou helper que registra
274
- ```
275
-
276
- **Por quê:** ação super-admin sem rastro = você (operador da plataforma) não consegue investigar incident "quem deletou todos os leads da org X em 03/04?". Compliance LGPD violation.
277
-
278
- **Certo:** REGRA #1 — toda RPC super-admin chama `private.audit_log` ANTES de operar. Trigger AFTER em tabelas críticas dispara automaticamente para super_admin (gerado pelo `multi-tenant-rls-writer` com `audit_super_admin=true`).
279
-
280
- ### Anti-pattern 2: Impersonation sem TTL
281
-
282
- **Errado:**
283
- ```typescript
284
- // Sessão impersonation persiste indefinidamente
285
- await supabase.auth.signInWithPassword({ email: targetUser.email, password: '...' })
286
- ```
287
-
288
- **Por quê:** super-admin esquece, sessão fica ativa por dias, usuário target cuja "como" foi assumida nem sabe. Ataque interno trivial.
289
-
290
- **Certo:** REGRA #2 — magic link com expiry 30min, frontend countdown + auto-logout.
291
-
292
- ### Anti-pattern 3: super_admin via user_metadata
293
-
294
- **Errado:**
295
- ```sql
296
- -- Policy lê super_admin de user_metadata
297
- using ((auth.jwt()->'user_metadata'->>'super_admin')::boolean = true)
298
- ```
299
-
300
- **Por quê:** `user_metadata` é editável pelo client via `supabase.auth.updateUser({ data: { super_admin: true } })`. Privilege escalation imediato — qualquer usuário se torna super-admin.
301
-
302
- **Certo:** REGRA #5 — `app_metadata.super_admin` (set apenas via service_role).
303
-
304
- ### Anti-pattern 4: Delete org sem confirmação dupla
305
-
306
- **Errado:**
307
- ```typescript
308
- <Button onClick={() => deleteOrg(orgId)}>Delete</Button>
309
- ```
310
-
311
- **Por quê:** click acidental destrói org com 100k records. Cascade delete = irreversible.
312
-
313
- **Certo:** REGRA #6 — modal exige typed slug + reason + checkbox + RPC valida tudo server-side. Soft delete preferred.
314
-
315
- ## Fencing Token para TTL de Impersonação (v1.22+)
316
-
317
- > A TTL de 30min de impersonação é vulnerável a split-brain durante GC pause: super-admin A inicia impersonação, sofre GC pause de 35min, TTL expira, super-admin B inicia outra impersonação no mesmo target, A volta ainda achando que tem sessão. Mitigação canônica: fencing token monotônico em `super_admin_impersonations` table — storage rejeita writes com token < último visto. Padrão completo em [`armadilhas-sistemas-distribuidos`](../armadilhas-sistemas-distribuidos/SKILL.md) (v1.22 — DDIA Ch 8).
318
-
319
- ## Ver também
320
-
321
- - [audit-log-multi-tenant](../audit-log-multi-tenant/SKILL.md) — Phase 109, audit_logs + event `super_admin_action` (REGRA #1)
322
- - [multi-tenant-rls-hierarchy](../multi-tenant-rls-hierarchy/SKILL.md) — `private.is_super_admin` + PERMISSIVE policy pattern
323
- - [b2b-saas-architecture](../b2b-saas-architecture/SKILL.md) — JWT minimal `super_admin: bool` em app_metadata (REGRA #5)
324
- - [supabase-edge-fn-writer](../../agents/supabase-edge-fn-writer.md) — agent invocado para Edge Function impersonation
325
- - [_shared-multi-tenant/glossary.md](../_shared-multi-tenant/glossary.md) — termos `super_admin`, `impersonation`, `cross-tenant view`, `platform admin`
326
- - [GitHub Enterprise — Impersonation](https://docs.github.com/en/enterprise-server@latest/admin/user-management/managing-users-in-your-enterprise/impersonating-a-user) — referência external pattern
1
+ ---
2
+ name: super-admin-platform-pattern
3
+ description: "Use ao implementar painel super-admin que gerencia TODOS os tenants — cross-tenant view, impersonation/support takeover, super_admin app_metadata, audit obrigatório de cada ação."
4
+ ---
5
+
6
+ # Super-Admin Platform Pattern — B2B SaaS Multi-Tenant
7
+
8
+ ## Quando usar
9
+
10
+ LLM carrega esta skill ao implementar painel de super-admin (você gerenciando todos tenants). Trigger phrases:
11
+
12
+ - "super admin platform", "platform admin"
13
+ - "cross-tenant view", "list all orgs"
14
+ - "impersonation user", "support takeover"
15
+ - "super_admin app_metadata"
16
+ - "GitHub Enterprise impersonation pattern"
17
+
18
+ ## Regras absolutas
19
+
20
+ **REGRA #1 (audit obrigatório — BLOCKER):** Toda ação super-admin **DEVE** emitir evento `super_admin_action` em `audit_logs`. Sem audit log = ABORT no agent (REGRA do `super-admin-implementer`). Compliance LGPD exige rastreabilidade.
21
+
22
+ **REGRA #2 (impersonation TTL 30min):** Sessão de impersonation expira em **30 minutos** automaticamente. Após TTL, sessão revogada (`signOut` automático), super-admin precisa re-iniciar impersonation. Previne sessão zombie.
23
+
24
+ **REGRA #3 (reason obrigatório):** Impersonation requer campo `reason` text não-vazio (mín 10 chars). Registrado em audit_log para investigação posterior. Sem reason = recusar ação.
25
+
26
+ **REGRA #4 (banner visual obrigatório):** Quando super-admin está impersonando, UI mostra **banner persistente** (top da viewport) com texto "Você está vendo como <user.email> em <org.name>. Clique para sair." Cor de aviso (amarelo/vermelho), z-index máximo, não fechável.
27
+
28
+ **REGRA #5 (super_admin via service_role apenas):** `app_metadata.super_admin = true` é setado **EXCLUSIVAMENTE** via `auth.admin.updateUserById()` com `SUPABASE_SERVICE_ROLE_KEY`. Cliente NUNCA consegue mutar. Endpoint de promoção isolado em Edge Function `verify_jwt: false` ou backend admin separado.
29
+
30
+ **REGRA #6 (delete org requer dupla confirmação):** Deletar uma `organizations` (cascade dropping membros, leads, audit_logs) requer:
31
+ 1. super-admin clica botão delete
32
+ 2. Modal pede org.slug exato + reason text + checkbox "Entendo que isso é irreversível"
33
+ 3. RPC `super_admin_delete_org(p_org_id, p_typed_slug, p_reason)` valida + executa + audit
34
+
35
+ ## Patterns canônicos
36
+
37
+ ### Cross-tenant view — RLS via PERMISSIVE
38
+
39
+ ```sql
40
+ -- Policy permissive em organizations: super_admin vê todas
41
+ create policy "organizations_super_admin_view"
42
+ on public.organizations
43
+ as permissive
44
+ for select
45
+ to authenticated
46
+ using (private.is_super_admin());
47
+
48
+ -- Policy normal (já deve existir): owner/admin vê apenas a própria
49
+ create policy "organizations_select_member"
50
+ on public.organizations
51
+ for select
52
+ to authenticated
53
+ using (private.is_member_of(id));
54
+
55
+ -- Mesma lógica para todas tabelas críticas: leads, organization_members, audit_logs, etc.
56
+ -- Padronizar via agent multi-tenant-rls-writer (Phase 108) com super_admin_bypass=true
57
+ ```
58
+
59
+ ### Frontend — listar todos tenants (super-admin only)
60
+
61
+ ```typescript
62
+ // SuperAdminDashboard.tsx
63
+ import { createClient } from '@/lib/supabase/client'
64
+
65
+ export function SuperAdminDashboard() {
66
+ const supabase = createClient()
67
+ const [orgs, setOrgs] = useState<Org[]>([])
68
+
69
+ useEffect(() => {
70
+ // RLS retorna TODAS orgs porque user é super_admin
71
+ supabase.from('organizations')
72
+ .select('id, name, slug, plan, status, created_at, organization_members(count)')
73
+ .order('created_at', { ascending: false })
74
+ .then(({ data }) => setOrgs(data || []))
75
+ }, [])
76
+
77
+ return (
78
+ <Table>
79
+ {orgs.map(o => (
80
+ <Row key={o.id}>
81
+ <Cell>{o.name}</Cell>
82
+ <Cell>{o.slug}</Cell>
83
+ <Cell>{o.plan}</Cell>
84
+ <Cell>{o.organization_members[0].count}</Cell>
85
+ <Cell>
86
+ <Button onClick={() => startImpersonation(o.id)}>Impersonate</Button>
87
+ </Cell>
88
+ </Row>
89
+ ))}
90
+ </Table>
91
+ )
92
+ }
93
+ ```
94
+
95
+ ### Impersonation — Edge Function com TTL 30min
96
+
97
+ ```typescript
98
+ // supabase/functions/super-admin-impersonate/index.ts
99
+ import { createClient } from 'jsr:@supabase/supabase-js@2'
100
+
101
+ Deno.serve(async (req) => {
102
+ const auth = req.headers.get('Authorization')
103
+ if (!auth) return new Response('unauthorized', { status: 401 })
104
+
105
+ // Validar caller é super_admin via JWT app_metadata
106
+ const supabase = createClient(
107
+ Deno.env.get('SUPABASE_URL')!,
108
+ Deno.env.get('SUPABASE_ANON_KEY')!,
109
+ { global: { headers: { Authorization: auth } } }
110
+ )
111
+
112
+ const { data: { user } } = await supabase.auth.getUser()
113
+ if (!user || !user.app_metadata.super_admin) {
114
+ return new Response('forbidden', { status: 403 })
115
+ }
116
+
117
+ const { target_user_id, target_org_id, reason } = await req.json()
118
+
119
+ // REGRA #3: reason obrigatório (min 10 chars)
120
+ if (!reason || reason.trim().length < 10) {
121
+ return new Response(JSON.stringify({ error: 'reason_required_min_10_chars' }), { status: 400 })
122
+ }
123
+
124
+ // Audit ANTES de criar sessão (se falhar audit, falha a ação)
125
+ await supabase.rpc('audit_log', {
126
+ p_event_type: 'super_admin_action',
127
+ p_tenant_id: target_org_id,
128
+ p_target_id: target_user_id,
129
+ p_target_type: 'user',
130
+ p_payload: {
131
+ action: 'impersonation_started',
132
+ reason,
133
+ session_ttl_minutes: 30
134
+ }
135
+ })
136
+
137
+ // Criar sessão impersonation via service_role
138
+ const admin = createClient(
139
+ Deno.env.get('SUPABASE_URL')!,
140
+ Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')! // service role
141
+ )
142
+
143
+ const { data: targetUser } = await admin.auth.admin.getUserById(target_user_id)
144
+ if (!targetUser.user) return new Response('target_not_found', { status: 404 })
145
+
146
+ // Gerar magic link com expiry curto (30min)
147
+ const { data: magicLink } = await admin.auth.admin.generateLink({
148
+ type: 'magiclink',
149
+ email: targetUser.user.email!,
150
+ options: {
151
+ redirectTo: `${Deno.env.get('APP_URL')}/?impersonating=1&original_admin_id=${user.id}`
152
+ }
153
+ })
154
+
155
+ // Cookie marker no client side (banner visual lê isso)
156
+ return new Response(JSON.stringify({
157
+ magic_link: magicLink.properties.action_link,
158
+ expires_at: new Date(Date.now() + 30 * 60 * 1000).toISOString()
159
+ }), {
160
+ headers: { 'Content-Type': 'application/json' }
161
+ })
162
+ })
163
+ ```
164
+
165
+ ### Banner visual de impersonation (React)
166
+
167
+ ```typescript
168
+ // app/components/ImpersonationBanner.tsx
169
+ 'use client'
170
+
171
+ export function ImpersonationBanner() {
172
+ const searchParams = useSearchParams()
173
+ const isImpersonating = searchParams.get('impersonating') === '1'
174
+ const adminId = searchParams.get('original_admin_id')
175
+
176
+ if (!isImpersonating) return null
177
+
178
+ const stopImpersonation = async () => {
179
+ await supabase.auth.signOut()
180
+ window.location.href = `/super-admin?stopped_impersonation=1&original_admin_id=${adminId}`
181
+ }
182
+
183
+ return (
184
+ <div className="fixed top-0 left-0 right-0 z-[9999] bg-yellow-400 text-black px-4 py-2 flex items-center justify-between">
185
+ <span>
186
+ ⚠ Você está vendo como outro usuário (super-admin impersonation).
187
+ Sessão expira em <Countdown to={expiresAt} />.
188
+ </span>
189
+ <Button variant="destructive" size="sm" onClick={stopImpersonation}>
190
+ Parar impersonation
191
+ </Button>
192
+ </div>
193
+ )
194
+ }
195
+ ```
196
+
197
+ ### Promover usuário a super_admin (backend admin script)
198
+
199
+ ```typescript
200
+ // scripts/promote-super-admin.ts (NÃO Edge Function — script administrativo)
201
+ // Executado manualmente OU via CLI admin tool (NÃO frontend)
202
+ import { createClient } from '@supabase/supabase-js'
203
+
204
+ const admin = createClient(
205
+ process.env.SUPABASE_URL!,
206
+ process.env.SUPABASE_SERVICE_ROLE_KEY! // SECRET — NUNCA em frontend
207
+ )
208
+
209
+ await admin.auth.admin.updateUserById(userId, {
210
+ app_metadata: { super_admin: true }
211
+ })
212
+ ```
213
+
214
+ ### RPC delete org com dupla confirmação
215
+
216
+ ```sql
217
+ create or replace function public.super_admin_delete_org(
218
+ p_org_id uuid,
219
+ p_typed_slug text,
220
+ p_reason text
221
+ )
222
+ returns void
223
+ language plpgsql
224
+ security invoker
225
+ set search_path = ''
226
+ as $$
227
+ declare
228
+ v_org_slug text;
229
+ begin
230
+ -- Validar caller é super_admin
231
+ if not private.is_super_admin() then
232
+ raise exception 'forbidden_super_admin_only';
233
+ end if;
234
+
235
+ -- Validar reason
236
+ if length(trim(p_reason)) < 10 then
237
+ raise exception 'reason_required_min_10_chars';
238
+ end if;
239
+
240
+ -- Validar typed_slug bate com slug real (REGRA #6 dupla confirmação)
241
+ select slug into v_org_slug from public.organizations where id = p_org_id;
242
+ if v_org_slug is null then raise exception 'org_not_found'; end if;
243
+ if v_org_slug != p_typed_slug then
244
+ raise exception 'slug_mismatch_confirmation_failed';
245
+ end if;
246
+
247
+ -- Audit ANTES (preserva histórico)
248
+ perform private.audit_log(
249
+ 'super_admin_action',
250
+ p_org_id,
251
+ null, 'org', null,
252
+ jsonb_build_object('action', 'delete_org', 'slug', v_org_slug, 'reason', p_reason)
253
+ );
254
+
255
+ -- Soft delete preferred (status = 'archived'), hard delete se realmente necessário
256
+ update public.organizations set status = 'archived' where id = p_org_id;
257
+
258
+ -- Hard delete (se exigido — descomenta abaixo)
259
+ -- delete from public.organizations where id = p_org_id;
260
+ -- (cascade dropa: organization_members, departments, leads, etc.; audit_logs preservado por design)
261
+ end;
262
+ $$;
263
+
264
+ grant execute on function public.super_admin_delete_org(uuid, text, text) to authenticated;
265
+ ```
266
+
267
+ ## Anti-patterns
268
+
269
+ ### Anti-pattern 1: super_admin sem audit log (BLOCKER)
270
+
271
+ **Errado:**
272
+ ```sql
273
+ -- super_admin policy permite tudo, sem trigger ou helper que registra
274
+ ```
275
+
276
+ **Por quê:** ação super-admin sem rastro = você (operador da plataforma) não consegue investigar incident "quem deletou todos os leads da org X em 03/04?". Compliance LGPD violation.
277
+
278
+ **Certo:** REGRA #1 — toda RPC super-admin chama `private.audit_log` ANTES de operar. Trigger AFTER em tabelas críticas dispara automaticamente para super_admin (gerado pelo `multi-tenant-rls-writer` com `audit_super_admin=true`).
279
+
280
+ ### Anti-pattern 2: Impersonation sem TTL
281
+
282
+ **Errado:**
283
+ ```typescript
284
+ // Sessão impersonation persiste indefinidamente
285
+ await supabase.auth.signInWithPassword({ email: targetUser.email, password: '...' })
286
+ ```
287
+
288
+ **Por quê:** super-admin esquece, sessão fica ativa por dias, usuário target cuja "como" foi assumida nem sabe. Ataque interno trivial.
289
+
290
+ **Certo:** REGRA #2 — magic link com expiry 30min, frontend countdown + auto-logout.
291
+
292
+ ### Anti-pattern 3: super_admin via user_metadata
293
+
294
+ **Errado:**
295
+ ```sql
296
+ -- Policy lê super_admin de user_metadata
297
+ using ((auth.jwt()->'user_metadata'->>'super_admin')::boolean = true)
298
+ ```
299
+
300
+ **Por quê:** `user_metadata` é editável pelo client via `supabase.auth.updateUser({ data: { super_admin: true } })`. Privilege escalation imediato — qualquer usuário se torna super-admin.
301
+
302
+ **Certo:** REGRA #5 — `app_metadata.super_admin` (set apenas via service_role).
303
+
304
+ ### Anti-pattern 4: Delete org sem confirmação dupla
305
+
306
+ **Errado:**
307
+ ```typescript
308
+ <Button onClick={() => deleteOrg(orgId)}>Delete</Button>
309
+ ```
310
+
311
+ **Por quê:** click acidental destrói org com 100k records. Cascade delete = irreversible.
312
+
313
+ **Certo:** REGRA #6 — modal exige typed slug + reason + checkbox + RPC valida tudo server-side. Soft delete preferred.
314
+
315
+ ## Fencing Token para TTL de Impersonação (v1.22+)
316
+
317
+ > A TTL de 30min de impersonação é vulnerável a split-brain durante GC pause: super-admin A inicia impersonação, sofre GC pause de 35min, TTL expira, super-admin B inicia outra impersonação no mesmo target, A volta ainda achando que tem sessão. Mitigação canônica: fencing token monotônico em `super_admin_impersonations` table — storage rejeita writes com token < último visto. Padrão completo em [`armadilhas-sistemas-distribuidos`](../armadilhas-sistemas-distribuidos/SKILL.md) (v1.22 — DDIA Ch 8).
318
+
319
+ ## Ver também
320
+
321
+ - [audit-log-multi-tenant](../audit-log-multi-tenant/SKILL.md) — Phase 109, audit_logs + event `super_admin_action` (REGRA #1)
322
+ - [multi-tenant-rls-hierarchy](../multi-tenant-rls-hierarchy/SKILL.md) — `private.is_super_admin` + PERMISSIVE policy pattern
323
+ - [b2b-saas-architecture](../b2b-saas-architecture/SKILL.md) — JWT minimal `super_admin: bool` em app_metadata (REGRA #5)
324
+ - [supabase-edge-fn-writer](../../agents/supabase-edge-fn-writer.md) — agent invocado para Edge Function impersonation
325
+ - [_shared-multi-tenant/glossary.md](../_shared-multi-tenant/glossary.md) — termos `super_admin`, `impersonation`, `cross-tenant view`, `platform admin`
326
+ - [GitHub Enterprise — Impersonation](https://docs.github.com/en/enterprise-server@latest/admin/user-management/managing-users-in-your-enterprise/impersonating-a-user) — referência external pattern