@luanpdd/kit-mcp 1.33.0 → 1.35.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.
- package/LICENSE +21 -21
- package/README.md +168 -168
- package/gates/agent-no-recursive-dispatch.md +84 -84
- package/kit/COMANDOS.md +138 -138
- package/kit/COMPATIBILITY.md +70 -70
- package/kit/README.md +76 -76
- package/kit/agents/advisor-researcher.md +109 -109
- package/kit/agents/ai-mutation-tester.md +289 -289
- package/kit/agents/assumptions-analyzer.md +110 -110
- package/kit/agents/audit-log-implementer.md +314 -314
- package/kit/agents/auditor-consistencia-isolamento.md +414 -414
- package/kit/agents/b2b-saas-architect.md +157 -157
- package/kit/agents/burn-rate-forecaster.md +153 -153
- package/kit/agents/cascading-failures-auditor.md +299 -299
- package/kit/agents/codebase-mapper.md +769 -769
- package/kit/agents/crm-pipeline-implementer.md +257 -257
- package/kit/agents/debugger.md +814 -814
- package/kit/agents/designer-ui.md +216 -216
- package/kit/agents/detector-tenant-quente.md +338 -338
- package/kit/agents/evolution-go-integrator.md +201 -201
- package/kit/agents/example-reviewer.md +22 -22
- package/kit/agents/executor.md +565 -565
- package/kit/agents/golden-signals-instrumenter.md +232 -232
- package/kit/agents/incident-investigator.md +238 -238
- package/kit/agents/integration-checker.md +203 -203
- package/kit/agents/invite-flow-implementer.md +190 -190
- package/kit/agents/legacy-characterizer.md +369 -369
- package/kit/agents/lgpd-compliance-auditor.md +296 -296
- package/kit/agents/load-shedding-instrumenter.md +290 -290
- package/kit/agents/multi-tenant-isolation-auditor.md +254 -254
- package/kit/agents/multi-tenant-rls-writer.md +341 -341
- package/kit/agents/nyquist-auditor.md +181 -181
- package/kit/agents/observability-coverage-auditor.md +316 -316
- package/kit/agents/observability-instrumenter.md +191 -191
- package/kit/agents/omm-auditor.md +291 -291
- package/kit/agents/org-onboarding-implementer.md +224 -224
- package/kit/agents/payload-capture-instrumenter.md +274 -274
- package/kit/agents/phase-researcher.md +697 -697
- package/kit/agents/plan-checker.md +275 -275
- package/kit/agents/planner.md +923 -923
- package/kit/agents/postmortem-writer.md +273 -273
- package/kit/agents/project-researcher.md +653 -653
- package/kit/agents/prr-conductor.md +287 -287
- package/kit/agents/refactor-safety-auditor.md +405 -405
- package/kit/agents/release-pipeline-auditor.md +364 -364
- package/kit/agents/research-synthesizer.md +246 -246
- package/kit/agents/roadmapper.md +678 -678
- package/kit/agents/schema-checker.md +160 -160
- package/kit/agents/seam-finder.md +360 -360
- package/kit/agents/shotgun-surgery-detector.md +350 -350
- package/kit/agents/slo-engineer.md +217 -217
- package/kit/agents/storytelling-analyst.md +300 -300
- package/kit/agents/supabase-architect.md +249 -249
- package/kit/agents/supabase-auth-bootstrapper.md +400 -400
- package/kit/agents/supabase-auth-hook-writer.md +418 -418
- package/kit/agents/supabase-branching-architect.md +563 -563
- package/kit/agents/supabase-cicd-pipeline-implementer.md +778 -778
- package/kit/agents/supabase-column-privileges-writer.md +400 -400
- package/kit/agents/supabase-edge-fn-tester.md +288 -288
- package/kit/agents/supabase-edge-fn-writer.md +341 -341
- package/kit/agents/supabase-mfa-implementer.md +439 -439
- package/kit/agents/supabase-migration-writer.md +386 -386
- package/kit/agents/supabase-oauth-server-implementer.md +507 -507
- package/kit/agents/supabase-rbac-implementer.md +393 -393
- package/kit/agents/supabase-realtime-implementer.md +364 -364
- package/kit/agents/supabase-rls-hardener.md +522 -522
- package/kit/agents/supabase-rls-writer.md +324 -324
- package/kit/agents/supabase-roles-implementer.md +356 -356
- package/kit/agents/supabase-social-auth-implementer.md +451 -451
- package/kit/agents/supabase-sso-saml-architect.md +549 -549
- package/kit/agents/supabase-storage-implementer.md +407 -407
- package/kit/agents/super-admin-implementer.md +282 -282
- package/kit/agents/toil-auditor.md +268 -268
- package/kit/agents/ui-auditor.md +438 -438
- package/kit/agents/ui-checker.md +305 -305
- package/kit/agents/ui-researcher.md +356 -356
- package/kit/agents/user-profiler.md +176 -176
- package/kit/agents/validador-evolucao-schema.md +336 -336
- package/kit/agents/verifier.md +729 -729
- package/kit/agents/workflow-generator.md +167 -0
- package/kit/commands/adicionar-backlog.md +75 -75
- package/kit/commands/adicionar-fase.md +42 -42
- package/kit/commands/adicionar-tarefa.md +45 -45
- package/kit/commands/adicionar-testes.md +41 -41
- package/kit/commands/ajuda.md +21 -21
- package/kit/commands/atualizar.md +37 -37
- package/kit/commands/auditar-cascading.md +111 -111
- package/kit/commands/auditar-marco.md +179 -179
- package/kit/commands/auditar-observabilidade-cobertura-workflow.md +121 -0
- package/kit/commands/auditar-observabilidade-cobertura.md +183 -183
- package/kit/commands/auditar-refactor.md +219 -219
- package/kit/commands/auditar-release.md +109 -109
- package/kit/commands/auditar-uat.md +23 -23
- package/kit/commands/autonomo.md +40 -40
- package/kit/commands/branch-pr.md +24 -24
- package/kit/commands/burn-rate-status.md +408 -408
- package/kit/commands/capturar-payloads.md +193 -193
- package/kit/commands/caracterizar.md +212 -212
- package/kit/commands/concluir-marco.md +247 -247
- package/kit/commands/configuracoes.md +36 -36
- package/kit/commands/criar-workflow.md +158 -0
- package/kit/commands/dados-distribuidos.md +188 -188
- package/kit/commands/definir-perfil.md +10 -10
- package/kit/commands/depurar.md +190 -190
- package/kit/commands/detectar-duplicacao.md +197 -197
- package/kit/commands/discutir-fase.md +131 -131
- package/kit/commands/encontrar-seams.md +136 -136
- package/kit/commands/entrar-discord.md +17 -17
- package/kit/commands/estatisticas.md +18 -18
- package/kit/commands/example-greeting.md +33 -33
- package/kit/commands/executar-fase.md +58 -58
- package/kit/commands/expresso.md +56 -56
- package/kit/commands/fase-ui.md +34 -34
- package/kit/commands/fazer.md +57 -57
- package/kit/commands/fio.md +125 -125
- package/kit/commands/fluxos-trabalho.md +64 -64
- package/kit/commands/forense.md +176 -176
- package/kit/commands/gerenciador.md +38 -38
- package/kit/commands/inserir-fase.md +31 -31
- package/kit/commands/legacy.md +263 -263
- package/kit/commands/limpeza.md +17 -17
- package/kit/commands/listar-hipoteses-fase.md +45 -45
- package/kit/commands/listar-workspaces.md +18 -18
- package/kit/commands/load-shedding.md +117 -117
- package/kit/commands/mapear-codebase.md +70 -70
- package/kit/commands/multi-tenant.md +163 -163
- package/kit/commands/nota.md +33 -33
- package/kit/commands/novo-marco.md +43 -43
- package/kit/commands/novo-projeto.md +41 -41
- package/kit/commands/novo-workspace.md +43 -43
- package/kit/commands/pausar-trabalho.md +37 -37
- package/kit/commands/perfil-usuario.md +45 -45
- package/kit/commands/pesquisar-fase.md +195 -195
- package/kit/commands/planejar-fase.md +67 -67
- package/kit/commands/planejar-lacunas.md +33 -33
- package/kit/commands/plantar-ideia.md +25 -25
- package/kit/commands/progresso.md +24 -24
- package/kit/commands/proximo.md +30 -30
- package/kit/commands/publicar.md +490 -490
- package/kit/commands/rapido.md +35 -35
- package/kit/commands/reaplicar-patches.md +124 -124
- package/kit/commands/refactor-seguro.md +321 -321
- package/kit/commands/relatorio-sessao.md +19 -19
- package/kit/commands/remover-fase.md +31 -31
- package/kit/commands/remover-workspace.md +26 -26
- package/kit/commands/resumo-marco.md +50 -50
- package/kit/commands/retomar-trabalho.md +40 -40
- package/kit/commands/revisar-backlog.md +60 -60
- package/kit/commands/revisar-ui.md +32 -32
- package/kit/commands/revisar.md +37 -37
- package/kit/commands/saude.md +21 -21
- package/kit/commands/setup-notion.md +93 -93
- package/kit/commands/storytelling.md +179 -179
- package/kit/commands/supabase.md +238 -238
- package/kit/commands/sync-main.md +68 -68
- package/kit/commands/validar-fase.md +35 -35
- package/kit/commands/verificar-tarefas.md +44 -44
- package/kit/commands/verificar-trabalho.md +64 -64
- package/kit/file-manifest.json +424 -419
- package/kit/framework/bin/lib/commands.cjs +959 -959
- package/kit/framework/bin/lib/config.cjs +442 -442
- package/kit/framework/bin/lib/core.cjs +1230 -1230
- package/kit/framework/bin/lib/frontmatter.cjs +336 -336
- package/kit/framework/bin/lib/init.cjs +1442 -1442
- package/kit/framework/bin/lib/milestone.cjs +252 -252
- package/kit/framework/bin/lib/model-profiles.cjs +68 -68
- package/kit/framework/bin/lib/phase.cjs +888 -888
- package/kit/framework/bin/lib/profile-output.cjs +952 -952
- package/kit/framework/bin/lib/profile-pipeline.cjs +539 -539
- package/kit/framework/bin/lib/roadmap.cjs +329 -329
- package/kit/framework/bin/lib/security.cjs +382 -382
- package/kit/framework/bin/lib/state.cjs +1031 -1031
- package/kit/framework/bin/lib/template.cjs +222 -222
- package/kit/framework/bin/lib/uat.cjs +282 -282
- package/kit/framework/bin/lib/verify.cjs +888 -888
- package/kit/framework/bin/lib/workstream.cjs +491 -491
- package/kit/framework/bin/tools.cjs +918 -918
- package/kit/framework/commands/workstreams.md +63 -63
- package/kit/framework/references/checkpoints.md +778 -778
- package/kit/framework/references/continuation-format.md +249 -249
- package/kit/framework/references/decimal-phase-calculation.md +64 -64
- package/kit/framework/references/git-integration.md +295 -295
- package/kit/framework/references/git-planning-commit.md +38 -38
- package/kit/framework/references/model-profile-resolution.md +36 -36
- package/kit/framework/references/model-profiles.md +139 -139
- package/kit/framework/references/phase-argument-parsing.md +61 -61
- package/kit/framework/references/planning-config.md +202 -202
- package/kit/framework/references/questioning.md +162 -162
- package/kit/framework/references/tdd.md +263 -263
- package/kit/framework/references/ui-brand.md +160 -160
- package/kit/framework/references/user-profiling.md +657 -657
- package/kit/framework/references/verification-patterns.md +612 -612
- package/kit/framework/references/workstream-flag.md +58 -58
- package/kit/framework/templates/DEBUG.md +164 -164
- package/kit/framework/templates/UAT.md +265 -265
- package/kit/framework/templates/UI-SPEC.md +100 -100
- package/kit/framework/templates/VALIDATION.md +76 -76
- package/kit/framework/templates/claude-md.md +122 -122
- package/kit/framework/templates/codebase/architecture.md +185 -185
- package/kit/framework/templates/codebase/concerns.md +205 -205
- package/kit/framework/templates/codebase/conventions.md +204 -204
- package/kit/framework/templates/codebase/integrations.md +192 -192
- package/kit/framework/templates/codebase/stack.md +158 -158
- package/kit/framework/templates/codebase/structure.md +199 -199
- package/kit/framework/templates/codebase/testing.md +301 -301
- package/kit/framework/templates/config.json +44 -44
- package/kit/framework/templates/context.md +352 -352
- package/kit/framework/templates/continue-here.md +78 -78
- package/kit/framework/templates/copilot-instructions.md +7 -7
- package/kit/framework/templates/debug-subagent-prompt.md +91 -91
- package/kit/framework/templates/dev-preferences.md +20 -20
- package/kit/framework/templates/discovery.md +146 -146
- package/kit/framework/templates/discussion-log.md +63 -63
- package/kit/framework/templates/milestone-archive.md +123 -123
- package/kit/framework/templates/milestone.md +115 -115
- package/kit/framework/templates/phase-prompt.md +610 -610
- package/kit/framework/templates/planner-subagent-prompt.md +117 -117
- package/kit/framework/templates/project.md +186 -186
- package/kit/framework/templates/requirements.md +231 -231
- package/kit/framework/templates/research-project/ARCHITECTURE.md +204 -204
- package/kit/framework/templates/research-project/FEATURES.md +147 -147
- package/kit/framework/templates/research-project/PITFALLS.md +200 -200
- package/kit/framework/templates/research-project/STACK.md +120 -120
- package/kit/framework/templates/research-project/SUMMARY.md +170 -170
- package/kit/framework/templates/research.md +419 -419
- package/kit/framework/templates/retrospective.md +54 -54
- package/kit/framework/templates/roadmap.md +202 -202
- package/kit/framework/templates/state.md +176 -176
- package/kit/framework/templates/summary-complex.md +59 -59
- package/kit/framework/templates/summary-minimal.md +41 -41
- package/kit/framework/templates/summary-standard.md +48 -48
- package/kit/framework/templates/summary.md +209 -209
- package/kit/framework/templates/user-profile.md +146 -146
- package/kit/framework/templates/user-setup.md +256 -256
- package/kit/framework/templates/verification-report.md +258 -258
- package/kit/framework/workflows/add-phase.md +112 -112
- package/kit/framework/workflows/add-tests.md +351 -351
- package/kit/framework/workflows/add-todo.md +158 -158
- package/kit/framework/workflows/audit-milestone.md +340 -340
- package/kit/framework/workflows/audit-uat.md +109 -109
- package/kit/framework/workflows/autonomous.md +891 -891
- package/kit/framework/workflows/check-todos.md +177 -177
- package/kit/framework/workflows/cleanup.md +152 -152
- package/kit/framework/workflows/complete-milestone.md +696 -696
- package/kit/framework/workflows/diagnose-issues.md +231 -231
- package/kit/framework/workflows/discovery-phase.md +289 -289
- package/kit/framework/workflows/discuss-phase-assumptions.md +653 -653
- package/kit/framework/workflows/discuss-phase.md +784 -784
- package/kit/framework/workflows/do.md +104 -104
- package/kit/framework/workflows/execute-phase.md +838 -838
- package/kit/framework/workflows/execute-plan.md +510 -510
- package/kit/framework/workflows/fast.md +102 -102
- package/kit/framework/workflows/forensics.md +265 -265
- package/kit/framework/workflows/health.md +181 -181
- package/kit/framework/workflows/help.md +619 -619
- package/kit/framework/workflows/insert-phase.md +130 -130
- package/kit/framework/workflows/list-phase-assumptions.md +178 -178
- package/kit/framework/workflows/list-workspaces.md +56 -56
- package/kit/framework/workflows/manager.md +362 -362
- package/kit/framework/workflows/map-codebase.md +377 -377
- package/kit/framework/workflows/milestone-summary.md +223 -223
- package/kit/framework/workflows/new-milestone.md +486 -486
- package/kit/framework/workflows/new-project.md +1159 -1159
- package/kit/framework/workflows/new-workspace.md +237 -237
- package/kit/framework/workflows/next.md +97 -97
- package/kit/framework/workflows/node-repair.md +92 -92
- package/kit/framework/workflows/note.md +156 -156
- package/kit/framework/workflows/pause-work.md +176 -176
- package/kit/framework/workflows/plan-milestone-gaps.md +273 -273
- package/kit/framework/workflows/plan-phase.md +765 -765
- package/kit/framework/workflows/plant-seed.md +169 -169
- package/kit/framework/workflows/pr-branch.md +129 -129
- package/kit/framework/workflows/profile-user.md +450 -450
- package/kit/framework/workflows/progress.md +507 -507
- package/kit/framework/workflows/quick.md +757 -757
- package/kit/framework/workflows/remove-phase.md +155 -155
- package/kit/framework/workflows/remove-workspace.md +90 -90
- package/kit/framework/workflows/research-phase.md +82 -82
- package/kit/framework/workflows/resume-project.md +326 -326
- package/kit/framework/workflows/review.md +228 -228
- package/kit/framework/workflows/session-report.md +146 -146
- package/kit/framework/workflows/settings.md +283 -283
- package/kit/framework/workflows/ship.md +228 -228
- package/kit/framework/workflows/stats.md +60 -60
- package/kit/framework/workflows/transition.md +671 -671
- package/kit/framework/workflows/ui-phase.md +302 -302
- package/kit/framework/workflows/ui-review.md +165 -165
- package/kit/framework/workflows/update.md +323 -323
- package/kit/framework/workflows/validate-phase.md +174 -174
- package/kit/framework/workflows/verify-phase.md +252 -252
- package/kit/framework/workflows/verify-work.md +637 -637
- package/kit/hooks/check-update.js +118 -118
- package/kit/hooks/context-monitor.js +163 -163
- package/kit/hooks/kit-attribution-reminder.cjs +92 -92
- package/kit/hooks/kit-router.cjs +137 -137
- package/kit/hooks/prompt-guard.js +103 -103
- package/kit/hooks/statusline.js +125 -125
- package/kit/hooks/workflow-guard.js +101 -101
- package/kit/settings.json +45 -45
- package/kit/skills/ai-prompt-characterization/SKILL.md +335 -335
- package/kit/skills/armadilhas-sistemas-distribuidos/SKILL.md +447 -447
- package/kit/skills/audit-log-multi-tenant/SKILL.md +340 -340
- package/kit/skills/b2b-saas-architecture/SKILL.md +300 -300
- package/kit/skills/consistencia-leitura-replica/SKILL.md +385 -385
- package/kit/skills/crm-lead-pipeline-patterns/SKILL.md +343 -343
- package/kit/skills/dynamic-workflow-authoring/SKILL.md +223 -0
- package/kit/skills/escolha-modelo-consistencia/SKILL.md +494 -494
- package/kit/skills/evolucao-schema-compativel/SKILL.md +448 -448
- package/kit/skills/evolution-go-whatsapp-integration/SKILL.md +322 -322
- package/kit/skills/example-skill/SKILL.md +42 -42
- package/kit/skills/legacy-api-only-applications/SKILL.md +358 -358
- package/kit/skills/legacy-characterization-tests/SKILL.md +330 -330
- package/kit/skills/legacy-effect-analysis/SKILL.md +331 -331
- package/kit/skills/legacy-extract-class/SKILL.md +203 -203
- package/kit/skills/legacy-programming-by-difference/SKILL.md +252 -252
- package/kit/skills/legacy-seams-and-test-harness/SKILL.md +460 -460
- package/kit/skills/legacy-shotgun-surgery/SKILL.md +286 -286
- package/kit/skills/legacy-sprout-wrap-techniques/SKILL.md +434 -434
- package/kit/skills/legacy-storytelling-naked-crc/SKILL.md +270 -270
- package/kit/skills/lgpd-multi-tenant-compliance/SKILL.md +340 -340
- package/kit/skills/member-invite-flow/SKILL.md +305 -305
- package/kit/skills/member-management-react-shadcn/SKILL.md +328 -328
- package/kit/skills/multi-tenant-performance-scaling/SKILL.md +316 -316
- package/kit/skills/multi-tenant-rls-hierarchy/SKILL.md +342 -342
- package/kit/skills/org-onboarding-flow/SKILL.md +257 -257
- package/kit/skills/org-switcher-react-pattern/SKILL.md +349 -349
- package/kit/skills/permission-gate-react-pattern/SKILL.md +271 -271
- package/kit/skills/postgres-isolamento-concorrencia/SKILL.md +552 -552
- package/kit/skills/pre-refactor-characterization/SKILL.md +421 -421
- package/kit/skills/rbac-permissions-matrix-supabase/SKILL.md +338 -338
- package/kit/skills/streams-eventos-cdc/SKILL.md +711 -711
- package/kit/skills/supabase-auth-hardening/SKILL.md +674 -674
- package/kit/skills/supabase-auth-hooks/SKILL.md +875 -875
- package/kit/skills/supabase-auth-methods/SKILL.md +486 -486
- package/kit/skills/supabase-auth-sessions/SKILL.md +579 -579
- package/kit/skills/supabase-auth-ssr/SKILL.md +306 -306
- package/kit/skills/supabase-branching-workflow/SKILL.md +544 -544
- package/kit/skills/supabase-ci-cd-github-actions/SKILL.md +880 -880
- package/kit/skills/supabase-column-level-security/SKILL.md +426 -426
- package/kit/skills/supabase-config-toml-remotes/SKILL.md +807 -807
- package/kit/skills/supabase-custom-claims-rbac/SKILL.md +472 -472
- package/kit/skills/supabase-edge-functions/SKILL.md +330 -330
- package/kit/skills/supabase-edge-functions-auth/SKILL.md +309 -309
- package/kit/skills/supabase-edge-functions-limits/SKILL.md +302 -302
- package/kit/skills/supabase-edge-functions-mcp-server/SKILL.md +279 -279
- package/kit/skills/supabase-edge-functions-testing/SKILL.md +277 -277
- package/kit/skills/supabase-edge-runtime-builtins/SKILL.md +357 -357
- package/kit/skills/supabase-enterprise-sso-saml/SKILL.md +545 -545
- package/kit/skills/supabase-jwt-signing-keys/SKILL.md +399 -399
- package/kit/skills/supabase-mfa/SKILL.md +488 -488
- package/kit/skills/supabase-migration-repair/SKILL.md +823 -823
- package/kit/skills/supabase-migrations/SKILL.md +297 -297
- package/kit/skills/supabase-oauth-server/SKILL.md +537 -537
- package/kit/skills/supabase-pgtap-testing/SKILL.md +1053 -1053
- package/kit/skills/supabase-postgres-roles/SKILL.md +392 -392
- package/kit/skills/supabase-realtime/SKILL.md +460 -460
- package/kit/skills/supabase-rls-defense-in-depth/SKILL.md +418 -418
- package/kit/skills/supabase-rls-policies/SKILL.md +635 -635
- package/kit/skills/supabase-social-oauth/SKILL.md +480 -480
- package/kit/skills/supabase-third-party-auth/SKILL.md +450 -450
- package/kit/skills/super-admin-platform-pattern/SKILL.md +326 -326
- package/kit/skills/tenant-quente-mitigacao/SKILL.md +605 -605
- package/kit/skills/ui-anti-padroes-ia/SKILL.md +261 -261
- package/kit/skills/ui-contexto-produto/SKILL.md +248 -248
- package/kit/skills/ui-cor-estrategia/SKILL.md +213 -213
- package/kit/skills/ui-critica-auditoria/SKILL.md +260 -260
- package/kit/skills/ui-motion-funcional/SKILL.md +264 -264
- package/kit/skills/ui-ritmo-espacial/SKILL.md +259 -259
- package/kit/skills/ui-tipografia/SKILL.md +211 -211
- package/kit/skills/whatsapp-conversation-state-machine/SKILL.md +287 -287
- package/kit/workflows/auditar-observabilidade-cobertura.workflow.js +250 -0
- package/package.json +65 -63
- package/src/core/kit.js +333 -216
- package/src/core/reflect.js +247 -247
- package/src/core/registry.js +123 -112
- package/src/core/reverse-sync.js +448 -372
- package/src/core/sync.js +477 -437
- package/src/core/watch.js +121 -121
- package/src/mcp-server/index.js +794 -794
|
@@ -1,302 +1,302 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: supabase-edge-functions-limits
|
|
3
|
-
description: Use ao planejar limites e retries em Edge Functions Supabase — runtime caps 256MB/2s CPU/wall clock, status codes canônicos, RateLimitError + retryAfterMs, error classes client-side, idempotency.
|
|
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
|
|
1
|
+
---
|
|
2
|
+
name: supabase-edge-functions-limits
|
|
3
|
+
description: Use ao planejar limites e retries em Edge Functions Supabase — runtime caps 256MB/2s CPU/wall clock, status codes canônicos, RateLimitError + retryAfterMs, error classes client-side, idempotency.
|
|
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
|