@luanpdd/kit-mcp 1.29.0 → 1.30.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 (330) 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 +14 -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/prompt-guard.js +103 -103
  268. package/kit/hooks/statusline.js +125 -125
  269. package/kit/hooks/workflow-guard.js +101 -101
  270. package/kit/settings.json +45 -45
  271. package/kit/skills/_shared-supabase/glossary.md +17 -0
  272. package/kit/skills/ai-prompt-characterization/SKILL.md +335 -335
  273. package/kit/skills/armadilhas-sistemas-distribuidos/SKILL.md +447 -447
  274. package/kit/skills/audit-log-multi-tenant/SKILL.md +340 -340
  275. package/kit/skills/b2b-saas-architecture/SKILL.md +300 -300
  276. package/kit/skills/consistencia-leitura-replica/SKILL.md +385 -385
  277. package/kit/skills/crm-lead-pipeline-patterns/SKILL.md +343 -343
  278. package/kit/skills/escolha-modelo-consistencia/SKILL.md +494 -494
  279. package/kit/skills/evolucao-schema-compativel/SKILL.md +448 -448
  280. package/kit/skills/evolution-go-whatsapp-integration/SKILL.md +322 -322
  281. package/kit/skills/example-skill/SKILL.md +42 -42
  282. package/kit/skills/legacy-api-only-applications/SKILL.md +358 -358
  283. package/kit/skills/legacy-characterization-tests/SKILL.md +330 -330
  284. package/kit/skills/legacy-effect-analysis/SKILL.md +331 -331
  285. package/kit/skills/legacy-extract-class/SKILL.md +203 -203
  286. package/kit/skills/legacy-programming-by-difference/SKILL.md +252 -252
  287. package/kit/skills/legacy-seams-and-test-harness/SKILL.md +460 -460
  288. package/kit/skills/legacy-shotgun-surgery/SKILL.md +286 -286
  289. package/kit/skills/legacy-sprout-wrap-techniques/SKILL.md +434 -434
  290. package/kit/skills/legacy-storytelling-naked-crc/SKILL.md +270 -270
  291. package/kit/skills/lgpd-multi-tenant-compliance/SKILL.md +340 -340
  292. package/kit/skills/member-invite-flow/SKILL.md +305 -305
  293. package/kit/skills/member-management-react-shadcn/SKILL.md +328 -328
  294. package/kit/skills/multi-tenant-performance-scaling/SKILL.md +316 -316
  295. package/kit/skills/multi-tenant-rls-hierarchy/SKILL.md +342 -342
  296. package/kit/skills/org-onboarding-flow/SKILL.md +257 -257
  297. package/kit/skills/org-switcher-react-pattern/SKILL.md +349 -349
  298. package/kit/skills/permission-gate-react-pattern/SKILL.md +271 -271
  299. package/kit/skills/postgres-isolamento-concorrencia/SKILL.md +552 -552
  300. package/kit/skills/pre-refactor-characterization/SKILL.md +421 -421
  301. package/kit/skills/rbac-permissions-matrix-supabase/SKILL.md +338 -338
  302. package/kit/skills/streams-eventos-cdc/SKILL.md +711 -711
  303. package/kit/skills/supabase-branching-workflow/SKILL.md +544 -544
  304. package/kit/skills/supabase-ci-cd-github-actions/SKILL.md +880 -880
  305. package/kit/skills/supabase-column-level-security/SKILL.md +426 -426
  306. package/kit/skills/supabase-config-toml-remotes/SKILL.md +807 -807
  307. package/kit/skills/supabase-custom-claims-rbac/SKILL.md +472 -472
  308. package/kit/skills/supabase-edge-functions/SKILL.md +229 -141
  309. package/kit/skills/supabase-edge-functions-auth/SKILL.md +309 -0
  310. package/kit/skills/supabase-edge-functions-limits/SKILL.md +302 -0
  311. package/kit/skills/supabase-edge-functions-mcp-server/SKILL.md +279 -0
  312. package/kit/skills/supabase-edge-functions-testing/SKILL.md +277 -0
  313. package/kit/skills/supabase-edge-runtime-builtins/SKILL.md +357 -0
  314. package/kit/skills/supabase-migration-repair/SKILL.md +823 -823
  315. package/kit/skills/supabase-migrations/SKILL.md +297 -297
  316. package/kit/skills/supabase-pgtap-testing/SKILL.md +1053 -1053
  317. package/kit/skills/supabase-postgres-roles/SKILL.md +392 -392
  318. package/kit/skills/supabase-realtime/SKILL.md +460 -236
  319. package/kit/skills/supabase-rls-defense-in-depth/SKILL.md +418 -418
  320. package/kit/skills/supabase-rls-policies/SKILL.md +635 -635
  321. package/kit/skills/super-admin-platform-pattern/SKILL.md +326 -326
  322. package/kit/skills/tenant-quente-mitigacao/SKILL.md +605 -605
  323. package/kit/skills/whatsapp-conversation-state-machine/SKILL.md +287 -287
  324. package/package.json +1 -1
  325. package/src/core/kit.js +216 -216
  326. package/src/core/reflect.js +247 -247
  327. package/src/core/reverse-sync.js +372 -372
  328. package/src/core/sync.js +418 -418
  329. package/src/core/watch.js +121 -121
  330. package/src/mcp-server/index.js +693 -693
@@ -0,0 +1,309 @@
1
+ ---
2
+ name: supabase-edge-functions-auth
3
+ description: Use ao autenticar Edge Functions Supabase em 2026 — `@supabase/server` package, `withSupabase({auth: 'user'|'secret:name'|'publishable:name'|'none'})`, `createSupabaseContext` para erros customizados, distinção Authorization (JWT) vs apikey (API key), toggle `verify_jwt` por função em config.toml, padrões canônicos para webhooks/service-to-service/user-facing/public.
4
+ ---
5
+
6
+ # Supabase — Edge Functions Auth (`@supabase/server`) · 2026
7
+
8
+ ## Quando usar
9
+
10
+ Carrega quando:
11
+
12
+ - "auth em Edge Function", "withSupabase", "createSupabaseContext"
13
+ - "verify_jwt true/false", "Authorization vs apikey", "401 edge function"
14
+ - "Stripe webhook auth", "service-to-service edge", "cron chamar edge function"
15
+ - "RBAC Edge Function", "user JWT no handler"
16
+
17
+ > Pré-requisito: [`supabase-edge-functions`](../supabase-edge-functions/SKILL.md) (Deno + env vars JSON dict).
18
+ > Complemento: [`supabase-edge-functions-limits`](../supabase-edge-functions-limits/SKILL.md) (status codes 401/403).
19
+
20
+ ## Conceito-chave: 2 headers, 2 camadas
21
+
22
+ | Header | Valor | Para |
23
+ |---|---|---|
24
+ | `Authorization` | `Bearer <user-jwt>` | Usuário logado via Supabase Auth |
25
+ | `apikey` | `sb_publishable_...` ou `sb_secret_...` | Cliente browser ou service-to-service |
26
+
27
+ **2 camadas de validação:**
28
+
29
+ 1. **Platform-level (`verify_jwt`)** — plataforma valida JWT em `Authorization` antes do handler. Se header ausente/inválido → **401 não chega no código**.
30
+ 2. **Handler-level** — você decide o que fazer com credencial recebida.
31
+
32
+ ### Pegadinha canônica (#1 causa de 401)
33
+
34
+ Mandar API key (`sb_publishable_*` / `sb_secret_*`) como Bearer:
35
+
36
+ ```
37
+ ⚠ Authorization: Bearer sb_publishable_abc123 → 401 (não é JWT)
38
+ ✓ Authorization: Bearer eyJhbGciOiJI... → JWT válido
39
+ ✓ apikey: sb_publishable_abc123 → API key correta
40
+ ```
41
+
42
+ API keys 2026 (`sb_*`) **não são JWTs** — a platform check não valida; seu handler não pode usar `auth.getUser()` nelas.
43
+
44
+ ## Toggle `verify_jwt` por função
45
+
46
+ ```toml
47
+ # supabase/config.toml
48
+ [functions.user-profile]
49
+ verify_jwt = true # default — para funções chamadas com JWT do usuário
50
+
51
+ [functions.stripe-webhook]
52
+ verify_jwt = false # webhook externo (Stripe assina o body — não envia JWT)
53
+
54
+ [functions.internal-cron]
55
+ verify_jwt = false # chamada por cron com apikey: secret_key
56
+ ```
57
+
58
+ Regra: deixe `true` quando o caller é browser logado (`supabase.functions.invoke`); desligue para webhooks externos ou service-to-service que autentica via `apikey`.
59
+
60
+ CLI local pode passar `--no-verify-jwt` para um deploy/serve único:
61
+
62
+ ```bash
63
+ supabase functions serve hello-world --no-verify-jwt
64
+ supabase functions deploy stripe-webhook --no-verify-jwt
65
+ ```
66
+
67
+ ## `@supabase/server` — wrapper canônico 2026
68
+
69
+ Package npm que reduz boilerplate de auth + contexto Supabase pré-configurado.
70
+
71
+ ### Auth modes
72
+
73
+ | Mode | Aceita | `ctx` recebido |
74
+ |---|---|---|
75
+ | `'user'` | JWT válido em `Authorization` | `ctx.supabase` scoped ao caller (respeita RLS), `ctx.userClaims` |
76
+ | `'secret:<name>'` | `sb_secret_<name>` em `apikey` | `ctx.supabaseAdmin` (bypassa RLS) |
77
+ | `'publishable:<name>'` | `sb_publishable_<name>` em `apikey` | `ctx.supabase` anon |
78
+ | `'none'` | Qualquer caller (sem check) | Cliente plain — handler responsabilidade total |
79
+
80
+ `<name>` referencia chaves nomeadas criadas em **Settings > API keys** (ex: `'secret:automations'`).
81
+
82
+ Combinar modos: `auth: ['user', 'secret:automations']` — primeiro match vence; `ctx.authMode` indica qual.
83
+
84
+ ## Patterns canônicos
85
+
86
+ ### Pattern 1 — User-facing (RLS aplicada)
87
+
88
+ ```ts
89
+ // supabase/functions/notes/index.ts
90
+ import { withSupabase } from 'npm:@supabase/server@1'
91
+
92
+ export default {
93
+ fetch: withSupabase({ auth: 'user' }, async (req, ctx) => {
94
+ // ctx.supabase já vem scoped ao caller → RLS policies do user aplicadas
95
+ const { data, error } = await ctx.supabase.from('notes').select('*')
96
+ if (error) return Response.json({ error: error.message }, { status: 500 })
97
+ return Response.json({ data, email: ctx.userClaims?.email })
98
+ }),
99
+ }
100
+ ```
101
+
102
+ ```toml
103
+ [functions.notes]
104
+ verify_jwt = true
105
+ ```
106
+
107
+ ### Pattern 2 — Service-to-service (cron/pg_net/worker)
108
+
109
+ ```ts
110
+ // supabase/functions/run-automations/index.ts
111
+ import { withSupabase } from 'npm:@supabase/server@1'
112
+
113
+ export default {
114
+ fetch: withSupabase({ auth: 'secret:automations' }, async (req, ctx) => {
115
+ // ctx.supabaseAdmin → bypassa RLS, scoped ao secret key 'automations'
116
+ await ctx.supabaseAdmin.from('automation_log').insert({ ran_at: new Date() })
117
+ return Response.json({ ok: true })
118
+ }),
119
+ }
120
+ ```
121
+
122
+ ```toml
123
+ [functions.run-automations]
124
+ verify_jwt = false
125
+ ```
126
+
127
+ Crie a chave nomeada no Dashboard → **Settings > API keys** com nome `automations`. Compartilhe `sb_secret_...` resultante apenas com o serviço chamador.
128
+
129
+ ### Pattern 3 — Webhook externo (Stripe/GitHub/Resend)
130
+
131
+ ```ts
132
+ // supabase/functions/stripe-webhook/index.ts
133
+ import { withSupabase } from 'npm:@supabase/server@1'
134
+ import Stripe from 'npm:stripe@17'
135
+
136
+ const stripe = new Stripe(Deno.env.get('STRIPE_SECRET_KEY')!)
137
+
138
+ export default {
139
+ fetch: withSupabase({ auth: 'none' }, async (req, ctx) => {
140
+ const signature = req.headers.get('stripe-signature') ?? ''
141
+ const body = await req.text()
142
+ try {
143
+ stripe.webhooks.constructEvent(body, signature, Deno.env.get('STRIPE_WEBHOOK_SECRET')!)
144
+ } catch {
145
+ return new Response('bad signature', { status: 400 })
146
+ }
147
+ // ctx.supabaseAdmin disponível para DB writes
148
+ await ctx.supabaseAdmin.from('stripe_events').insert({ raw: body })
149
+ return Response.json({ received: true })
150
+ }),
151
+ }
152
+ ```
153
+
154
+ ```toml
155
+ [functions.stripe-webhook]
156
+ verify_jwt = false
157
+ ```
158
+
159
+ `auth: 'none'` desliga toda checagem de credencial Supabase. **Você é responsável por validar via signature do provedor.** Nunca use em endpoint sensível sem outro mecanismo.
160
+
161
+ ### Pattern 4 — Função pública (health check)
162
+
163
+ ```ts
164
+ // supabase/functions/health/index.ts
165
+ import { withSupabase } from 'npm:@supabase/server@1'
166
+
167
+ export default {
168
+ fetch: withSupabase({ auth: 'none' }, async (_req, _ctx) => {
169
+ return Response.json({ ok: true, region: Deno.env.get('SB_REGION') })
170
+ }),
171
+ }
172
+ ```
173
+
174
+ ```toml
175
+ [functions.health]
176
+ verify_jwt = false
177
+ ```
178
+
179
+ ### Pattern 5 — Modo combinado (user + service)
180
+
181
+ ```ts
182
+ // supabase/functions/dual/index.ts
183
+ import { withSupabase } from 'npm:@supabase/server@1'
184
+
185
+ export default {
186
+ fetch: withSupabase({ auth: ['user', 'secret:automations'] }, async (req, ctx) => {
187
+ if (ctx.authMode === 'user') {
188
+ // user flow — ctx.supabase scoped ao caller
189
+ const { data } = await ctx.supabase.from('me').select('*').single()
190
+ return Response.json(data)
191
+ }
192
+ // service flow — ctx.supabaseAdmin bypassa RLS
193
+ await ctx.supabaseAdmin.from('audit').insert({ source: 'automation' })
194
+ return Response.json({ ok: true })
195
+ }),
196
+ }
197
+ ```
198
+
199
+ ### Pattern 6 — Erros customizados via `createSupabaseContext`
200
+
201
+ ```ts
202
+ import { createSupabaseContext } from 'npm:@supabase/server@1'
203
+
204
+ export default {
205
+ fetch: async (req: Request) => {
206
+ const { data: ctx, error } = await createSupabaseContext(req, { auth: 'user' })
207
+ if (error) {
208
+ // shape 401 conforme contrato API
209
+ return Response.json(
210
+ { message: error.message, code: error.code },
211
+ { status: error.status, headers: { 'WWW-Authenticate': 'Bearer' } },
212
+ )
213
+ }
214
+ return Response.json({ message: `hello ${ctx.userClaims?.email}` })
215
+ },
216
+ }
217
+ ```
218
+
219
+ ### Pattern 7 — Sem `@supabase/server` (RLS manual)
220
+
221
+ Quando precisar de controle fino ou não puder adicionar dependência:
222
+
223
+ ```ts
224
+ import { createClient } from 'npm:@supabase/supabase-js@2.95.0'
225
+
226
+ const PUBLISHABLE = JSON.parse(Deno.env.get('SUPABASE_PUBLISHABLE_KEYS')!)
227
+
228
+ Deno.serve(async (req) => {
229
+ // PT-BR: forward Authorization → supabase-js → queries respeitam RLS do user
230
+ const supabase = createClient(
231
+ Deno.env.get('SUPABASE_URL')!,
232
+ PUBLISHABLE['default'],
233
+ { global: { headers: { Authorization: req.headers.get('Authorization')! } } },
234
+ )
235
+ const { data, error } = await supabase.from('profiles').select('*')
236
+ if (error) return Response.json({ error: error.message }, { status: 500 })
237
+ return Response.json(data)
238
+ })
239
+ ```
240
+
241
+ Para validar JWT manualmente:
242
+
243
+ ```ts
244
+ const { data: { user }, error } = await supabase.auth.getUser(
245
+ req.headers.get('Authorization')?.replace('Bearer ', '') ?? ''
246
+ )
247
+ if (!user || error) return new Response('unauthorized', { status: 401 })
248
+ ```
249
+
250
+ ## Env vars 2026 esperadas
251
+
252
+ `@supabase/server` lê estas (auto-provisionadas na plataforma + CLI local):
253
+
254
+ | Variável | O que é |
255
+ |---|---|
256
+ | `SUPABASE_URL` | URL do projeto |
257
+ | `SUPABASE_PUBLISHABLE_KEYS` | JSON dict de chaves publishable |
258
+ | `SUPABASE_SECRET_KEYS` | JSON dict de chaves secret |
259
+ | `SUPABASE_JWKS` | JWK Set para validar user JWTs |
260
+
261
+ Fallback local (single-key): `SUPABASE_PUBLISHABLE_KEY` e `SUPABASE_SECRET_KEY` ainda funcionam.
262
+
263
+ ## Anti-patterns
264
+
265
+ ### AA1 — API key como Bearer
266
+
267
+ ```
268
+ ⚠ Authorization: Bearer sb_publishable_abc → 401, gateway rejeita
269
+ ✓ apikey: sb_publishable_abc
270
+ ```
271
+
272
+ ### AA2 — Chamar `auth.getUser()` em função `verify_jwt=false` sem repassar Authorization
273
+
274
+ Função com `verify_jwt=false` desliga apenas a **plataforma** — `auth.getUser()` ainda pode ser chamada se o caller mandar JWT. Mas se você não recebe JWT (webhook), `auth.getUser()` retorna `null`. Para Service-to-Service, use `auth: 'secret:<name>'` e `ctx.supabaseAdmin`.
275
+
276
+ ### AA3 — `service_role` no client browser
277
+
278
+ `SUPABASE_SECRET_KEYS` (e legacy `SUPABASE_SERVICE_ROLE_KEY`) bypassam RLS. NUNCA expor em código browser. Só server-side (Edge Function, backend Node).
279
+
280
+ ### AA4 — `auth: 'none'` em endpoint que lê/grava dado sensível
281
+
282
+ `'none'` aceita qualquer caller. Use apenas quando há outra validação (signature webhook, mTLS, etc.) ou endpoint genuinamente público (health check).
283
+
284
+ ### AA5 — Hardcode `'service_role'` em vez de chave nomeada
285
+
286
+ Em 2026, prefira chaves nomeadas (`secret:automations`, `secret:internal-cron`) — permite rotação granular e audit por consumidor. Legacy `SUPABASE_SERVICE_ROLE_KEY` ainda funciona mas é uma única chave global.
287
+
288
+ ### AA6 — `Authorization` E `apikey` ambos errados
289
+
290
+ Browser logado chamando `supabase.functions.invoke` envia **ambos**: `Authorization: Bearer <user-jwt>` + `apikey: sb_publishable_default`. É esperado e correto.
291
+
292
+ ## Diagnóstico de 401
293
+
294
+ | Sintoma | Causa provável | Fix |
295
+ |---|---|---|
296
+ | 401 antes do handler | `verify_jwt=true` + Authorization ausente/inválido | mandar JWT válido OU `verify_jwt = false` |
297
+ | 401 do handler (`@supabase/server`) | apikey errada para o mode declarado | conferir mode vs header enviado |
298
+ | 401 só em produção, ok em dev | env vars não setadas em prod | `supabase secrets set` |
299
+ | 401 com `auth.getUser()` returning null | JWT expirou ou JWKS errado | refresh JWT no client |
300
+
301
+ ## Ver também
302
+
303
+ - [`supabase-edge-functions`](../supabase-edge-functions/SKILL.md) — base Deno + env vars JSON dict
304
+ - [`supabase-edge-functions-limits`](../supabase-edge-functions-limits/SKILL.md) — status codes 401/403/405
305
+ - [`supabase-custom-claims-rbac`](../supabase-custom-claims-rbac/SKILL.md) — Custom Claims em JWT acessíveis via `ctx.userClaims`
306
+ - [`supabase-rls-policies`](../supabase-rls-policies/SKILL.md) — RLS aplicada quando `ctx.supabase` scoped
307
+ - [`supabase-rls-defense-in-depth`](../supabase-rls-defense-in-depth/SKILL.md) — `secret_role` caveat
308
+ - [`supabase-auth-ssr`](../supabase-auth-ssr/SKILL.md) — clients Next.js v16
309
+ - [`_shared-supabase/glossary.md`](../_shared-supabase/glossary.md) — termos canônicos auth
@@ -0,0 +1,302 @@
1
+ ---
2
+ name: supabase-edge-functions-limits
3
+ description: Use ao planejar limites, falhas e retries em Edge Functions Supabase — runtime caps (256MB / 2s CPU / 150-400s wall clock), platform caps (20MB bundle, 100/500/1000 funcs por plano), status codes canônicos (401/404/405/500/503/504/546 WORKER_LIMIT), recursive call budget ~5k req/min com `RateLimitError` + `retryAfterMs`, client-side error classes `FunctionsHttpError`/`FunctionsRelayError`/`FunctionsFetchError`, idempotency e backoff.
4
+ ---
5
+
6
+ # Supabase — Edge Functions Limits, Status Codes & Rate Limits · 2026
7
+
8
+ ## Quando usar
9
+
10
+ Carrega quando:
11
+
12
+ - "limites Edge Function", "256MB memory", "wall clock", "CPU time"
13
+ - "504 Edge Function timeout", "503 BOOT_ERROR", "546 WORKER_LIMIT"
14
+ - "FunctionsHttpError supabase", "client edge function error"
15
+ - "RateLimitError edge function", "nested function calls", "recursive function rate limit"
16
+ - "idempotency key edge function", "retry edge function"
17
+
18
+ > Pré-requisito: [`supabase-edge-functions`](../supabase-edge-functions/SKILL.md).
19
+ > Cross-ref SRE: [`retry-strategies`](../retry-strategies/SKILL.md) · [`cascading-failures`](../cascading-failures/SKILL.md) · [`load-shedding-graceful-degradation`](../load-shedding-graceful-degradation/SKILL.md).
20
+
21
+ ## Matriz de Limits
22
+
23
+ ### Runtime (per request)
24
+
25
+ | Recurso | Free | Pro / Team / Enterprise |
26
+ |---|---|---|
27
+ | **Memory** | 256 MB | 256 MB |
28
+ | **CPU time** | 2s | 2s |
29
+ | **Wall clock (isolate lifetime)** | 150s | 400s |
30
+ | **Request idle timeout** | 150s | 150s |
31
+ | **Max log message** | 10.000 chars | 10.000 chars |
32
+ | **Log event rate** | 100 / 10s | 100 / 10s |
33
+ | **Ephemeral `/tmp`** | 256 MB | 512 MB |
34
+
35
+ CPU time é **CPU real** (não inclui I/O async). Wall clock conta tudo. Função pode ter 400s wall clock mas estourar com 2.1s CPU.
36
+
37
+ ### Platform
38
+
39
+ | Recurso | Free | Pro | Team | Enterprise |
40
+ |---|---|---|---|---|
41
+ | **Max funcs/project** | 100 | 500 | 1000 | unlimited |
42
+ | **Max bundle size** | 20 MB | 20 MB | 20 MB | 20 MB |
43
+ | **Max secrets/project** | 100 | 100 | 100 | 100 |
44
+ | **Max secret size** | 48 KiB | 48 KiB | 48 KiB | 48 KiB |
45
+ | **Max secret name** | 256 chars (sem prefix `SUPABASE_`) | idem | idem | idem |
46
+
47
+ ### Restrições gerais
48
+
49
+ - **Outbound ports** `25` e `587` bloqueados (use Resend/SendGrid HTTP API).
50
+ - **HTML serving** só com custom domains (`text/html` reescrito para `text/plain` em domínio padrão).
51
+ - **Sem Web Worker API / `node:vm`**.
52
+ - **Multithreading** não suportado (Sharp/libvips falham — use `magick-wasm`).
53
+ - **Static files** deploy só via Docker (`--use-api` não suporta).
54
+
55
+ ## Status Codes Canônicos
56
+
57
+ | Code | Nome interno | Causa | Fix |
58
+ |---|---|---|---|
59
+ | `2xx` | success | Handler retornou OK | — |
60
+ | `3xx` | redirect | `Response.redirect()` | — |
61
+ | `401` | unauthorized | `verify_jwt=true` + Authorization inválido/ausente | Mandar JWT válido ou `verify_jwt=false` |
62
+ | `404` | not found | Função não existe / path errado | Conferir `supabase functions list` |
63
+ | `405` | method not allowed | Método fora de GET/POST/PUT/PATCH/DELETE/OPTIONS | Trocar método |
64
+ | `500` | `WORKER_ERROR` | Uncaught exception | Wrap em try/catch + log |
65
+ | `503` | `BOOT_ERROR` | Função falhou ao carregar (syntax error, import fail) | `supabase functions serve` local + logs |
66
+ | `504` | gateway timeout | Excedeu request idle timeout (150s) | Otimizar / mover para background |
67
+ | `546` | `WORKER_LIMIT` | Excedeu memory/CPU/wall clock | Reduzir bundle, chunk processing |
68
+
69
+ ### Diagnosticar 546 (resource limit)
70
+
71
+ ```bash
72
+ # Ver qual limite foi atingido
73
+ mcp__supabase__get_logs --service edge-function
74
+ ```
75
+
76
+ Tipicamente em logs:
77
+ ```
78
+ ERROR: WORKER_LIMIT: out of memory (256 MB)
79
+ ERROR: WORKER_LIMIT: CPU time limit exceeded (2s)
80
+ ERROR: WORKER_LIMIT: wall clock exceeded (400s)
81
+ ```
82
+
83
+ ## Client-side Error Classes
84
+
85
+ ```ts
86
+ import {
87
+ FunctionsHttpError, // 4xx/5xx da função (status code do handler)
88
+ FunctionsRelayError, // problema gateway↔Supabase (raro)
89
+ FunctionsFetchError, // função inalcançável (network)
90
+ } from 'npm:@supabase/supabase-js@2.95.0'
91
+
92
+ const { data, error } = await supabase.functions.invoke('orders', { body })
93
+
94
+ if (error instanceof FunctionsHttpError) {
95
+ const body = await error.context.json()
96
+ // Trate por status — body.code (seu enum) + retry decision
97
+ } else if (error instanceof FunctionsRelayError) {
98
+ // Quase sempre transiente — retry com backoff
99
+ } else if (error instanceof FunctionsFetchError) {
100
+ // Função down / DNS / cliente offline
101
+ }
102
+ ```
103
+
104
+ ## Nested Function Calls — Rate Limit
105
+
106
+ Quando uma Edge Function chama outra Edge Function via `fetch()` ou `supabase.functions.invoke()`, a Supabase aplica rate limit ao **chain** completo:
107
+
108
+ - **Budget**: ~**5.000 requisições/minuto/chain** (regiões mais movimentadas têm budget maior).
109
+ - **Conta**: direct recursion, function chaining, circular calls, fan-out.
110
+ - **Não conta**: inbound requests, chamadas para APIs externas (Stripe, OpenAI).
111
+
112
+ ### `RateLimitError` + `retryAfterMs`
113
+
114
+ ```ts
115
+ import { createClient } from 'npm:@supabase/supabase-js@2.95.0'
116
+
117
+ const SECRET = JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!)
118
+ const supabase = createClient(Deno.env.get('SUPABASE_URL')!, SECRET['default'])
119
+
120
+ Deno.serve(async (req) => {
121
+ try {
122
+ const { data, error } = await supabase.functions.invoke('downstream', { body: {} })
123
+ if (error) throw error
124
+ return Response.json(data)
125
+ } catch (err) {
126
+ if (err instanceof Deno.errors.RateLimitError) {
127
+ const retryAfterSec = Math.ceil(err.retryAfterMs / 1000)
128
+ return new Response(JSON.stringify({ error: 'service temporarily unavailable' }), {
129
+ status: 429,
130
+ headers: {
131
+ 'Content-Type': 'application/json',
132
+ 'Retry-After': retryAfterSec.toString(),
133
+ },
134
+ })
135
+ }
136
+ throw err
137
+ }
138
+ })
139
+ ```
140
+
141
+ ### Retry interno (com `retryAfterMs`)
142
+
143
+ ```ts
144
+ async function invokeWithRetry(fn: string, body: object, maxRetries = 3) {
145
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
146
+ try {
147
+ const { data, error } = await supabase.functions.invoke(fn, { body })
148
+ if (error) throw error
149
+ return data
150
+ } catch (err) {
151
+ if (err instanceof Deno.errors.RateLimitError && attempt < maxRetries - 1) {
152
+ // PT-BR: usar valor sugerido pelo runtime — evita thundering herd
153
+ await new Promise((r) => setTimeout(r, err.retryAfterMs))
154
+ continue
155
+ }
156
+ throw err
157
+ }
158
+ }
159
+ }
160
+ ```
161
+
162
+ ## Padrões para evitar rate limit
163
+
164
+ ### P1 — Batch em vez de N invocações
165
+
166
+ ```ts
167
+ // ⚠ Errado — N requests, estoura budget
168
+ for (const item of items) {
169
+ await supabase.functions.invoke('process-item', { body: item })
170
+ }
171
+
172
+ // ✓ Certo — 1 request
173
+ await supabase.functions.invoke('process-items', { body: { items } })
174
+ ```
175
+
176
+ ### P2 — Limite de profundidade em recursão
177
+
178
+ ```ts
179
+ Deno.serve(async (req) => {
180
+ const { depth = 0, data } = await req.json()
181
+ if (depth >= 5) return Response.json({ result: data }) // parar
182
+ const next = process(data)
183
+ const { data: result } = await supabase.functions.invoke('me', {
184
+ body: { depth: depth + 1, data: next },
185
+ })
186
+ return Response.json(result)
187
+ })
188
+ ```
189
+
190
+ ### P3 — Shared library (sem HTTP overhead)
191
+
192
+ Funções que compartilham lógica não devem chamar uma à outra via HTTP. Use `_shared/`:
193
+
194
+ ```ts
195
+ // supabase/functions/_shared/transform.ts
196
+ export function validate(d) { /* ... */ }
197
+ export function transform(d) { /* ... */ }
198
+ export async function save(d) { /* ... */ }
199
+
200
+ // supabase/functions/process/index.ts
201
+ import { validate, transform, save } from '../_shared/transform.ts'
202
+ // invocação direta — zero HTTP, zero rate limit
203
+ ```
204
+
205
+ ### P4 — Queue para workload alto
206
+
207
+ Cargas > 5k/min devem ir para `pgmq` + worker, não recursive Edge Function. Ver [`supabase-cron-queues`](../supabase-cron-queues/SKILL.md).
208
+
209
+ ## Idempotency keys
210
+
211
+ Para writes (POST/PATCH/PUT) em Edge Function chamada externamente, exija header `Idempotency-Key`:
212
+
213
+ ```ts
214
+ Deno.serve(async (req) => {
215
+ if (req.method === 'POST') {
216
+ const idempKey = req.headers.get('Idempotency-Key') ?? crypto.randomUUID()
217
+ const SECRET = JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!)
218
+ const supabase = createClient(Deno.env.get('SUPABASE_URL')!, SECRET['default'])
219
+
220
+ // PT-BR: insert com chave única; se já existe, retorna o registro existente
221
+ const { data, error } = await supabase
222
+ .from('orders')
223
+ .upsert({ idempotency_key: idempKey, /* ... */ }, { onConflict: 'idempotency_key' })
224
+ .select()
225
+ .single()
226
+ return Response.json(data)
227
+ }
228
+ })
229
+ ```
230
+
231
+ Cross-ref: [`retry-strategies`](../retry-strategies/SKILL.md) — full/equal/decorrelated jitter quando aplicável.
232
+
233
+ ## Error handling padrão
234
+
235
+ ```ts
236
+ Deno.serve(async (req) => {
237
+ try {
238
+ const result = await processRequest(req)
239
+ return Response.json(result)
240
+ } catch (error) {
241
+ console.error('function error:', error) // visível em Logs tab
242
+ // PT-BR: error.type enum fechado (NÃO error.message — cardinalidade)
243
+ const code = classifyError(error)
244
+ const status =
245
+ code === 'validation' ? 400 :
246
+ code === 'auth' ? 401 :
247
+ code === 'not_found' ? 404 :
248
+ code === 'rate_limit' ? 429 :
249
+ code === 'timeout' ? 504 :
250
+ 500
251
+ return Response.json({ code, message: error.message }, { status })
252
+ }
253
+ })
254
+
255
+ function classifyError(e: unknown): string {
256
+ if (e instanceof ValidationError) return 'validation'
257
+ if (e instanceof AuthError) return 'auth'
258
+ if (e instanceof NotFoundError) return 'not_found'
259
+ if (e instanceof Deno.errors.RateLimitError) return 'rate_limit'
260
+ if (e instanceof TimeoutError) return 'timeout'
261
+ return 'unknown'
262
+ }
263
+ ```
264
+
265
+ ## Quando otimizar
266
+
267
+ | Sintoma | Fix prioritário |
268
+ |---|---|
269
+ | 504 frequente | Mover trabalho para `EdgeRuntime.waitUntil` ou pgmq |
270
+ | 546 OOM (memory) | Stream em vez de buffer in-memory; chunk processing |
271
+ | 546 CPU exceeded | Profiler local (`deno test --inspect`); mover para Wasm |
272
+ | 546 wall clock | Background tasks; reduzir async chains |
273
+ | 503 BOOT_ERROR | Bundle muito grande; lazy-load imports pesados (`await import('npm:openai@4')`) |
274
+ | 503 em deploys novos | Erro de import/syntax; `supabase functions serve` antes do deploy |
275
+
276
+ ## Anti-patterns
277
+
278
+ ### AL1 — `error.message` como dimension em métricas
279
+ Cardinality explode. Use enum fechado (5-15 valores) em `error.type`.
280
+
281
+ ### AL2 — Retry sem `retryAfterMs`
282
+ Backoff manual com `1000ms` ignora hint do runtime. Sempre `setTimeout(_, err.retryAfterMs)` para RateLimitError.
283
+
284
+ ### AL3 — Fan-out síncrono massive
285
+ `Promise.all(items.map(invoke))` com 1000 items satura budget. Limite concorrência (`p-limit`) ou batch server-side.
286
+
287
+ ### AL4 — Polling em loop dentro da função
288
+ Wall clock estoura. Use webhook + database trigger (`pg_net.http_post`) ou WebSocket.
289
+
290
+ ### AL5 — Bundle > 20 MB
291
+ Deploy falha. Lazy-load: `const { OpenAI } = await import('npm:openai@4')` evita carregar tudo no boot.
292
+
293
+ ## Ver também
294
+
295
+ - [`supabase-edge-functions`](../supabase-edge-functions/SKILL.md) — base
296
+ - [`supabase-edge-functions-auth`](../supabase-edge-functions-auth/SKILL.md) — 401/403 detalhes
297
+ - [`supabase-edge-runtime-builtins`](../supabase-edge-runtime-builtins/SKILL.md) — `/tmp` 512MB paid
298
+ - [`supabase-cron-queues`](../supabase-cron-queues/SKILL.md) — pgmq quando recursive estoura
299
+ - [`retry-strategies`](../retry-strategies/SKILL.md) — full/equal/decorrelated jitter
300
+ - [`cascading-failures`](../cascading-failures/SKILL.md) — timeout/jitter/deadline/circuit breaker
301
+ - [`load-shedding-graceful-degradation`](../load-shedding-graceful-degradation/SKILL.md) — drop com 503 quando saturated
302
+ - [`four-golden-signals`](../four-golden-signals/SKILL.md) — saturation metric canônico