@luanpdd/kit-mcp 1.29.0 → 1.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +168 -168
- package/gates/agent-no-recursive-dispatch.md +82 -82
- package/kit/COMANDOS.md +138 -138
- package/kit/README.md +76 -76
- package/kit/agents/advisor-researcher.md +106 -106
- package/kit/agents/assumptions-analyzer.md +107 -107
- package/kit/agents/audit-log-implementer.md +313 -313
- package/kit/agents/auditor-consistencia-isolamento.md +413 -413
- package/kit/agents/b2b-saas-architect.md +156 -156
- package/kit/agents/cascading-failures-auditor.md +298 -298
- package/kit/agents/codebase-mapper.md +768 -768
- package/kit/agents/crm-pipeline-implementer.md +256 -256
- package/kit/agents/debugger.md +813 -813
- package/kit/agents/detector-tenant-quente.md +337 -337
- package/kit/agents/evolution-go-integrator.md +200 -200
- package/kit/agents/example-reviewer.md +21 -21
- package/kit/agents/executor.md +564 -564
- package/kit/agents/integration-checker.md +200 -200
- package/kit/agents/invite-flow-implementer.md +189 -189
- package/kit/agents/legacy-characterizer.md +368 -368
- package/kit/agents/lgpd-compliance-auditor.md +295 -295
- package/kit/agents/multi-tenant-isolation-auditor.md +253 -253
- package/kit/agents/multi-tenant-rls-writer.md +340 -340
- package/kit/agents/nyquist-auditor.md +178 -178
- package/kit/agents/observability-coverage-auditor.md +315 -315
- package/kit/agents/org-onboarding-implementer.md +223 -223
- package/kit/agents/payload-capture-instrumenter.md +273 -273
- package/kit/agents/phase-researcher.md +696 -696
- package/kit/agents/plan-checker.md +272 -272
- package/kit/agents/planner.md +922 -922
- package/kit/agents/project-researcher.md +652 -652
- package/kit/agents/refactor-safety-auditor.md +404 -404
- package/kit/agents/research-synthesizer.md +245 -245
- package/kit/agents/roadmapper.md +677 -677
- package/kit/agents/seam-finder.md +359 -359
- package/kit/agents/shotgun-surgery-detector.md +349 -349
- package/kit/agents/supabase-branching-architect.md +562 -562
- package/kit/agents/supabase-cicd-pipeline-implementer.md +777 -777
- package/kit/agents/supabase-column-privileges-writer.md +399 -399
- package/kit/agents/supabase-edge-fn-tester.md +287 -0
- package/kit/agents/supabase-edge-fn-writer.md +239 -210
- package/kit/agents/supabase-migration-writer.md +385 -385
- package/kit/agents/supabase-rbac-implementer.md +392 -392
- package/kit/agents/supabase-realtime-implementer.md +363 -267
- package/kit/agents/supabase-rls-hardener.md +521 -521
- package/kit/agents/supabase-rls-writer.md +323 -323
- package/kit/agents/supabase-roles-implementer.md +355 -355
- package/kit/agents/super-admin-implementer.md +281 -281
- package/kit/agents/ui-auditor.md +437 -437
- package/kit/agents/ui-checker.md +302 -302
- package/kit/agents/ui-researcher.md +355 -355
- package/kit/agents/user-profiler.md +175 -175
- package/kit/agents/validador-evolucao-schema.md +335 -335
- package/kit/agents/verifier.md +728 -728
- 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.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/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 +30 -7
- 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 +15 -8
- 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 +98 -0
- 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/_shared-supabase/glossary.md +17 -0
- 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/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-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 +229 -141
- package/kit/skills/supabase-edge-functions-auth/SKILL.md +309 -0
- package/kit/skills/supabase-edge-functions-limits/SKILL.md +302 -0
- package/kit/skills/supabase-edge-functions-mcp-server/SKILL.md +279 -0
- package/kit/skills/supabase-edge-functions-testing/SKILL.md +277 -0
- package/kit/skills/supabase-edge-runtime-builtins/SKILL.md +357 -0
- package/kit/skills/supabase-migration-repair/SKILL.md +823 -823
- package/kit/skills/supabase-migrations/SKILL.md +297 -297
- 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 -236
- 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/super-admin-platform-pattern/SKILL.md +326 -326
- package/kit/skills/tenant-quente-mitigacao/SKILL.md +605 -605
- package/kit/skills/whatsapp-conversation-state-machine/SKILL.md +287 -287
- package/package.json +1 -1
- package/src/core/kit.js +216 -216
- package/src/core/reflect.js +247 -247
- package/src/core/reverse-sync.js +372 -372
- package/src/core/sync.js +418 -418
- package/src/core/watch.js +121 -121
- package/src/mcp-server/index.js +715 -693
|
@@ -1,161 +1,275 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: supabase-edge-fn-writer
|
|
3
|
-
description: Escreve Deno Edge Functions
|
|
3
|
+
description: Escreve Deno Edge Functions 2026-compliant — imports versionados npm:/jsr:/node:, env vars JSON dict (SUPABASE_PUBLISHABLE_KEYS/SECRET_KEYS), per-function deno.json + config.toml entries, CORS via @supabase/supabase-js/cors v2.95+, withSupabase para auth quando aplicável, /tmp ou /s3 para writes, EdgeRuntime.waitUntil para background, status code canônicos, instrumentação OTel + 4 golden signals + rate-limit/retry defense.
|
|
4
4
|
tools: Read, Write, Edit, Bash, Grep, Glob
|
|
5
5
|
color: cyan
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
Você é o Edge Function writer Supabase. Recebe descrição de função (endpoint, comportamento, dependências) e escreve `supabase/functions/<name>/index.ts` em Deno
|
|
8
|
+
Você é o Edge Function writer Supabase **v1.30** (2026 modernization). Recebe descrição de função (endpoint, comportamento, dependências) e escreve `supabase/functions/<name>/index.ts` em Deno seguindo padrões 2026 + auto-cria `deno.json` per-function + adiciona entry em `supabase/config.toml`.
|
|
9
9
|
|
|
10
10
|
**Compat:** Full em todos os IDEs (filesystem-only). Veja [COMPATIBILITY.md](../COMPATIBILITY.md).
|
|
11
11
|
|
|
12
12
|
## Por que existe
|
|
13
13
|
|
|
14
|
-
Edge Functions têm pegadinhas específicas do Deno runtime que diferem de Node
|
|
14
|
+
Edge Functions têm pegadinhas específicas do Deno runtime que diferem de Node. A partir de 2026 o ecossistema mudou ainda mais: `SUPABASE_SECRET_KEYS`/`SUPABASE_PUBLISHABLE_KEYS` viraram **JSON dicts**; `@supabase/server` `withSupabase` é o pattern auth canônico; `deno.json` per-function substitui `import_map.json` global; CORS vem do próprio SDK (v2.95+). Este agent garante código novo nascendo 2026-compliant.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
## Skills consultadas (auto-trigger)
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Este agent consulta diretamente:
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
- [`supabase-edge-functions`](../skills/supabase-edge-functions/SKILL.md) — base (imports, env vars, Deno.serve)
|
|
21
|
+
- [`supabase-edge-functions-auth`](../skills/supabase-edge-functions-auth/SKILL.md) — `withSupabase`, 4 auth modes
|
|
22
|
+
- [`supabase-edge-functions-testing`](../skills/supabase-edge-functions-testing/SKILL.md) — local serve, deno test
|
|
23
|
+
- [`supabase-edge-runtime-builtins`](../skills/supabase-edge-runtime-builtins/SKILL.md) — `Supabase.ai`, `/s3`, WebSocket, Wasm, regional
|
|
24
|
+
- [`supabase-edge-functions-limits`](../skills/supabase-edge-functions-limits/SKILL.md) — limits, status codes, RateLimitError
|
|
25
|
+
- [`supabase-edge-functions-mcp-server`](../skills/supabase-edge-functions-mcp-server/SKILL.md) — mcp-lite
|
|
26
|
+
- [`legacy-api-only-applications`](../skills/legacy-api-only-applications/SKILL.md) — adapter pattern wrapping API externa
|
|
27
|
+
- [`llm-as-dependency`](../skills/llm-as-dependency/SKILL.md) — LLMProvider interface
|
|
28
|
+
- [`cascading-failures`](../skills/cascading-failures/SKILL.md), [`retry-strategies`](../skills/retry-strategies/SKILL.md), [`load-shedding-graceful-degradation`](../skills/load-shedding-graceful-degradation/SKILL.md) — SRE defenses
|
|
29
|
+
- [`opentelemetry-standard`](../skills/opentelemetry-standard/SKILL.md), [`structured-events`](../skills/structured-events/SKILL.md), [`distributed-tracing`](../skills/distributed-tracing/SKILL.md), [`four-golden-signals`](../skills/four-golden-signals/SKILL.md) — observabilidade integrada
|
|
27
30
|
|
|
28
31
|
## Inputs esperados (do caller)
|
|
29
32
|
|
|
30
|
-
- `function_name`:
|
|
31
|
-
- `behavior_description`: o que a função faz
|
|
32
|
-
- (Opcional) `
|
|
33
|
-
- (Opcional) `
|
|
33
|
+
- `function_name`: kebab-case (ex: `process-emails`, `generate-embeddings`)
|
|
34
|
+
- `behavior_description`: o que a função faz
|
|
35
|
+
- (Opcional) `auth_mode`: `'user' | 'secret:<name>' | 'publishable:<name>' | 'none' | 'manual'` — default `'user'` se browser-invoked, `'none'` + signature se webhook
|
|
36
|
+
- (Opcional) `pattern`: `'basic' | 'rag-embeddings' | 'cron-pgmq' | 'mcp-server' | 'websocket' | 'wasm' | 'background-task'`
|
|
37
|
+
- (Opcional) `dependencies`: pacotes adicionais
|
|
38
|
+
- (Opcional) `verify_jwt`: bool — derivado de `auth_mode` se não passado
|
|
34
39
|
|
|
35
40
|
## Passos
|
|
36
41
|
|
|
37
42
|
### Step 0 — Preflight
|
|
38
43
|
|
|
39
|
-
Detectar layout `supabase/functions/`:
|
|
40
44
|
```bash
|
|
41
45
|
ls supabase/functions/ 2>/dev/null
|
|
46
|
+
test -f supabase/config.toml && grep -c '^\[functions\.' supabase/config.toml
|
|
42
47
|
```
|
|
43
48
|
|
|
44
|
-
Se não existe, sugira `supabase init`
|
|
49
|
+
Se layout não existe, sugira `supabase init` + `supabase functions new <name>`.
|
|
50
|
+
|
|
51
|
+
### Step 1 — Decidir auth_mode + verify_jwt
|
|
52
|
+
|
|
53
|
+
| Padrão de uso | auth_mode | verify_jwt | Header esperado |
|
|
54
|
+
|---|---|---|---|
|
|
55
|
+
| Browser logado (`supabase.functions.invoke`) | `'user'` | `true` | `Authorization: Bearer <user-jwt>` |
|
|
56
|
+
| Service-to-service (cron, pg_net, worker) | `'secret:<name>'` | `false` | `apikey: sb_secret_<name>` |
|
|
57
|
+
| Webhook externo (Stripe/GitHub) | `'none'` + signature check | `false` | provider signature header |
|
|
58
|
+
| Health check público | `'none'` | `false` | — |
|
|
59
|
+
| Funções dual (user + service) | `['user', 'secret:<name>']` | `false` | conforme caller |
|
|
60
|
+
|
|
61
|
+
Se ambíguo, AskUserQuestion com 4 opções.
|
|
45
62
|
|
|
46
|
-
### Step
|
|
63
|
+
### Step 2 — Estruturar arquivos
|
|
47
64
|
|
|
48
|
-
|
|
65
|
+
```
|
|
66
|
+
supabase/functions/<function_name>/
|
|
67
|
+
├── index.ts
|
|
68
|
+
├── deno.json # PT-BR: per-function (2026 — preferido)
|
|
69
|
+
└── (.npmrc se private NPM)
|
|
70
|
+
```
|
|
49
71
|
|
|
50
72
|
Crie diretório se não existe.
|
|
51
73
|
|
|
52
|
-
### Step
|
|
74
|
+
### Step 3 — Escrever `deno.json` per-function
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"imports": {
|
|
79
|
+
"supabase": "npm:@supabase/supabase-js@2.95.0",
|
|
80
|
+
"supabase-server": "npm:@supabase/server@1",
|
|
81
|
+
"hono": "npm:hono@4.6.14",
|
|
82
|
+
"zod": "npm:zod@3.23.8"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Adicione apenas o que é usado. Sem `import_map.json` global novo.
|
|
53
88
|
|
|
54
|
-
|
|
55
|
-
- `import { x } from 'npm:<pkg>@<version>'` (ex: `npm:@supabase/supabase-js@2.43.0`)
|
|
56
|
-
- `import { x } from 'jsr:<scope>/<pkg>'` (ex: `jsr:@std/encoding/hex`)
|
|
57
|
-
- Node built-ins via `node:` prefix: `import process from 'node:process'`
|
|
89
|
+
### Step 4 — Imports no `index.ts`
|
|
58
90
|
|
|
59
|
-
**
|
|
60
|
-
-
|
|
61
|
-
-
|
|
91
|
+
**Regras absolutas:**
|
|
92
|
+
- `npm:<pkg>@<version>` (versão pinada)
|
|
93
|
+
- `jsr:<scope>/<pkg>@<version>`
|
|
94
|
+
- `node:<built-in>` (ex: `node:crypto`)
|
|
95
|
+
- **NUNCA** bare specifier
|
|
96
|
+
- **NUNCA** `deno.land/std/...` (deprecated; use `jsr:@std/...`)
|
|
62
97
|
|
|
63
|
-
### Step
|
|
98
|
+
### Step 5 — Entry point + handler
|
|
64
99
|
|
|
65
|
-
|
|
100
|
+
**Com `withSupabase` (preferido para `user`/`secret:`/`publishable:`):**
|
|
66
101
|
|
|
67
102
|
```ts
|
|
68
|
-
|
|
103
|
+
import { withSupabase } from 'npm:@supabase/server@1'
|
|
104
|
+
|
|
105
|
+
export default {
|
|
106
|
+
fetch: withSupabase({ auth: '<mode>' }, async (req, ctx) => {
|
|
107
|
+
// ctx.supabase (user/publishable) ou ctx.supabaseAdmin (secret) já disponível
|
|
108
|
+
return Response.json({ ok: true })
|
|
109
|
+
}),
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Manual (`Deno.serve` + auth no handler):**
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
import { createClient } from 'npm:@supabase/supabase-js@2.95.0'
|
|
117
|
+
const SECRET = JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!)
|
|
118
|
+
|
|
119
|
+
Deno.serve(async (req) => {
|
|
120
|
+
// PT-BR: JSON.parse obrigatório em 2026 — SECRET_KEYS é dict
|
|
121
|
+
const supabase = createClient(Deno.env.get('SUPABASE_URL')!, SECRET['default'])
|
|
69
122
|
// ...
|
|
70
|
-
return new Response(/* ... */)
|
|
71
123
|
})
|
|
72
124
|
```
|
|
73
125
|
|
|
74
|
-
### Step
|
|
126
|
+
### Step 6 — CORS canônico (se browser-invoked)
|
|
75
127
|
|
|
76
|
-
|
|
77
|
-
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
128
|
+
```ts
|
|
129
|
+
import { corsHeaders } from 'npm:@supabase/supabase-js@2.95.0/cors'
|
|
130
|
+
|
|
131
|
+
if (req.method === 'OPTIONS') return new Response('ok', { headers: corsHeaders })
|
|
132
|
+
return new Response(JSON.stringify(data), {
|
|
133
|
+
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
|
134
|
+
})
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Step 7 — `config.toml` entries (write/merge)
|
|
138
|
+
|
|
139
|
+
Edite `supabase/config.toml` adicionando seção da função:
|
|
140
|
+
|
|
141
|
+
```toml
|
|
142
|
+
[functions.<function_name>]
|
|
143
|
+
verify_jwt = <true|false> # Step 1 decidiu
|
|
144
|
+
# import_map = "..." # apenas se ainda legacy
|
|
145
|
+
# entrypoint = "./functions/.../index.js" # apenas se JS puro
|
|
146
|
+
# static_files = ["./.../*"] # apenas se Wasm/static assets
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Se `pattern` = `websocket` ou `background-task`:
|
|
150
|
+
```toml
|
|
151
|
+
[edge_runtime]
|
|
152
|
+
policy = "per_worker"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Step 8 — File writes
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
// ✓ ephemeral
|
|
159
|
+
await Deno.writeTextFile(`/tmp/${crypto.randomUUID()}.log`, data)
|
|
160
|
+
|
|
161
|
+
// ✓ persistent (requer S3FS_* secrets)
|
|
162
|
+
await Deno.writeTextFile(`/s3/exports/report.csv`, csv)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Se função usa `/s3/`, lembrar caller:
|
|
81
166
|
|
|
82
|
-
Para outros secrets, lembrar user de:
|
|
83
167
|
```bash
|
|
84
|
-
supabase secrets set
|
|
168
|
+
supabase secrets set \
|
|
169
|
+
S3FS_ENDPOINT_URL=... \
|
|
170
|
+
S3FS_REGION=... \
|
|
171
|
+
S3FS_ACCESS_KEY_ID=... \
|
|
172
|
+
S3FS_SECRET_ACCESS_KEY=...
|
|
85
173
|
```
|
|
86
174
|
|
|
87
|
-
### Step
|
|
175
|
+
### Step 9 — Background tasks
|
|
88
176
|
|
|
89
177
|
```ts
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
178
|
+
EdgeRuntime.waitUntil((async () => {
|
|
179
|
+
try { await heavyJob(payload) }
|
|
180
|
+
catch (e) { console.error('bg failed', e) }
|
|
181
|
+
})())
|
|
94
182
|
|
|
95
|
-
|
|
96
|
-
Deno.env.get('SUPABASE_URL')!,
|
|
97
|
-
Deno.env.get('SUPABASE_SECRET_KEYS')!
|
|
98
|
-
)
|
|
99
|
-
const { data: { user }, error } = await supabase.auth.getUser(
|
|
100
|
-
authHeader.replace('Bearer ', '')
|
|
101
|
-
)
|
|
102
|
-
if (!user || error) return new Response('unauthorized', { status: 401 })
|
|
183
|
+
return new Response('accepted', { status: 202 })
|
|
103
184
|
```
|
|
104
185
|
|
|
105
|
-
### Step
|
|
186
|
+
### Step 10 — Multi-rota (Hono com basePath)
|
|
106
187
|
|
|
107
188
|
```ts
|
|
108
|
-
import { Hono } from '
|
|
109
|
-
const app = new Hono().basePath('/<function_name>')
|
|
110
|
-
app.get('/
|
|
189
|
+
import { Hono } from 'hono'
|
|
190
|
+
const app = new Hono().basePath('/<function_name>') // OBRIGATÓRIO
|
|
191
|
+
app.get('/items', listItems)
|
|
111
192
|
Deno.serve(app.fetch)
|
|
112
193
|
```
|
|
113
194
|
|
|
114
|
-
|
|
195
|
+
### Step 11 — Pattern-specific scaffolds
|
|
115
196
|
|
|
116
|
-
|
|
197
|
+
| Pattern | Skill primária | Pontos-chave |
|
|
198
|
+
|---|---|---|
|
|
199
|
+
| `rag-embeddings` | [`supabase-edge-runtime-builtins`](../skills/supabase-edge-runtime-builtins/SKILL.md) | `new Supabase.ai.Session('gte-small')` + pgvector |
|
|
200
|
+
| `cron-pgmq` | [`supabase-cron-queues`](../skills/supabase-cron-queues/SKILL.md) | `auth: 'secret:<name>'` + idempotency |
|
|
201
|
+
| `mcp-server` | [`supabase-edge-functions-mcp-server`](../skills/supabase-edge-functions-mcp-server/SKILL.md) | dois Hono apps + mcp-lite |
|
|
202
|
+
| `websocket` | [`supabase-edge-runtime-builtins`](../skills/supabase-edge-runtime-builtins/SKILL.md) | `Deno.upgradeWebSocket` + JWT via query + `per_worker` |
|
|
203
|
+
| `wasm` | [`supabase-edge-runtime-builtins`](../skills/supabase-edge-runtime-builtins/SKILL.md) | `static_files` em config.toml + CLI 2.7.0+ |
|
|
204
|
+
| `background-task` | [`supabase-edge-functions-limits`](../skills/supabase-edge-functions-limits/SKILL.md) | `EdgeRuntime.waitUntil` + `per_worker` local |
|
|
205
|
+
|
|
206
|
+
### Step 12 — Observabilidade integrada (mandatory)
|
|
117
207
|
|
|
118
|
-
|
|
208
|
+
Toda Edge Function nasce com 4 golden signals + structured events + tracing:
|
|
119
209
|
|
|
120
210
|
```ts
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
})())
|
|
127
|
-
return new Response('accepted', { status: 202 })
|
|
211
|
+
import { metrics, trace } from 'npm:@opentelemetry/api@1.9.0'
|
|
212
|
+
const meter = metrics.getMeter('<function_name>')
|
|
213
|
+
const latencyHistogram = meter.createHistogram('http_request_duration_ms', {
|
|
214
|
+
unit: 'ms',
|
|
215
|
+
advice: { explicitBucketBoundaries: [1, 2, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 30000] },
|
|
128
216
|
})
|
|
217
|
+
const trafficCounter = meter.createCounter('http_requests_total')
|
|
218
|
+
const errorsCounter = meter.createCounter('http_errors_total')
|
|
219
|
+
meter.createObservableGauge('saturation_pct').addCallback((r) => r.observe(getSaturationPct()))
|
|
129
220
|
```
|
|
130
221
|
|
|
131
|
-
|
|
222
|
+
Wrapping no handler: separar `result=success|error` em latency, `error.type` enum em errors counter (NUNCA `error.message`). Cross-ref [`four-golden-signals`](../skills/four-golden-signals/SKILL.md) + [`structured-events`](../skills/structured-events/SKILL.md).
|
|
132
223
|
|
|
133
|
-
|
|
134
|
-
// ✓ ok
|
|
135
|
-
await Deno.writeTextFile(`/tmp/audit-${Date.now()}.log`, data)
|
|
224
|
+
### Step 13 — SRE defenses (mandatory para chamadas externas)
|
|
136
225
|
|
|
137
|
-
|
|
138
|
-
// await Deno.writeTextFile('/data/x.log', data) // FALHA
|
|
139
|
-
```
|
|
226
|
+
Toda chamada outbound inclui defesas:
|
|
140
227
|
|
|
141
|
-
|
|
228
|
+
1. **Timeout** — `AbortSignal.timeout(2000)`
|
|
229
|
+
2. **Retry com full jitter** — `delayMs = Math.random() * baseMs * 2^attempt`; max 3
|
|
230
|
+
3. **`RateLimitError` handling** — quando invocando outra Edge Function:
|
|
231
|
+
```ts
|
|
232
|
+
try {
|
|
233
|
+
const { data, error } = await supabase.functions.invoke('other', { body })
|
|
234
|
+
if (error) throw error
|
|
235
|
+
} catch (err) {
|
|
236
|
+
if (err instanceof Deno.errors.RateLimitError) {
|
|
237
|
+
await new Promise((r) => setTimeout(r, err.retryAfterMs))
|
|
238
|
+
// retry...
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
4. **Idempotency key** em writes — `Idempotency-Key` header + upsert
|
|
243
|
+
5. **Deadline propagation** — parse `x-deadline-ms` + pass downstream
|
|
244
|
+
|
|
245
|
+
Cross-ref [`supabase-edge-functions-limits`](../skills/supabase-edge-functions-limits/SKILL.md) + [`cascading-failures`](../skills/cascading-failures/SKILL.md).
|
|
142
246
|
|
|
143
|
-
|
|
247
|
+
### Step 14 — Cold start awareness
|
|
248
|
+
|
|
249
|
+
Se função importa muitos pacotes pesados (`npm:openai` + `npm:langchain` + etc.):
|
|
144
250
|
|
|
145
251
|
```
|
|
146
252
|
⚠ Bundle estimado > 2 MB — cold start pode ser ~500ms+. Considere:
|
|
147
253
|
- Lazy load via dynamic import: const { OpenAI } = await import('npm:openai@4')
|
|
148
|
-
- Mover lógica pesada para worker separado
|
|
254
|
+
- Mover lógica pesada para worker separado (cron → pgmq)
|
|
255
|
+
- Pré-warming via cron @1m (se justificável)
|
|
149
256
|
```
|
|
150
257
|
|
|
151
|
-
|
|
258
|
+
Limite hard: 20 MB bundle.
|
|
259
|
+
|
|
260
|
+
### Step 15 — Handoff para testing
|
|
261
|
+
|
|
262
|
+
Após criar a função, **automaticamente** sugira handoff para `supabase-edge-fn-tester`:
|
|
152
263
|
|
|
153
264
|
```
|
|
154
265
|
═══════════════════════════════════════════════════════════
|
|
155
266
|
EDGE FUNCTION CRIADA · <function_name>
|
|
156
267
|
═══════════════════════════════════════════════════════════
|
|
157
268
|
|
|
158
|
-
|
|
269
|
+
Arquivos:
|
|
270
|
+
supabase/functions/<function_name>/index.ts
|
|
271
|
+
supabase/functions/<function_name>/deno.json
|
|
272
|
+
supabase/config.toml (atualizado)
|
|
159
273
|
|
|
160
274
|
Deploy:
|
|
161
275
|
supabase functions deploy <function_name>
|
|
@@ -163,149 +277,64 @@ Deploy:
|
|
|
163
277
|
Test local:
|
|
164
278
|
supabase functions serve <function_name>
|
|
165
279
|
curl -X POST http://localhost:54321/functions/v1/<function_name> \
|
|
166
|
-
-H '
|
|
167
|
-
-d '{
|
|
280
|
+
-H 'apikey: $(supabase status | grep PUBLISHABLE)' \
|
|
281
|
+
-d '{...}'
|
|
282
|
+
|
|
283
|
+
Próximo passo recomendado:
|
|
284
|
+
/supabase test <function_name> # gera tests Deno via supabase-edge-fn-tester
|
|
168
285
|
```
|
|
169
286
|
|
|
170
287
|
## Anti-patterns prevenidos
|
|
171
288
|
|
|
172
289
|
- Bare specifier `import x from 'pkg'` → SEMPRE `npm:pkg@version`
|
|
173
|
-
- `Deno.
|
|
290
|
+
- `Deno.env.get('SUPABASE_SECRET_KEYS')` direto → SEMPRE `JSON.parse(...)['default']`
|
|
291
|
+
- `Deno.writeTextFile('/data/x')` → SEMPRE `/tmp/` ou `/s3/`
|
|
174
292
|
- Multi-rota sem `basePath('/<name>')` → SEMPRE incluído
|
|
175
|
-
- Trabalho pesado inline → SEMPRE `EdgeRuntime.waitUntil`
|
|
176
|
-
-
|
|
293
|
+
- Trabalho pesado inline → SEMPRE `EdgeRuntime.waitUntil`
|
|
294
|
+
- CORS hard-coded → SEMPRE `corsHeaders` from `@supabase/supabase-js/cors`
|
|
295
|
+
- `import_map.json` global → SEMPRE `deno.json` per-function
|
|
296
|
+
- API key como Bearer → corrigir caller
|
|
297
|
+
- `error.type = err.message` em métrica → SEMPRE enum fechado
|
|
177
298
|
|
|
178
299
|
## Quando NÃO invocar
|
|
179
300
|
|
|
180
|
-
- Função existente
|
|
301
|
+
- Função existente com pequeno ajuste → use Edit direto
|
|
181
302
|
- Lógica que pode rodar em DB function (`security definer`) → considera `supabase-database-functions` (mais barato que Edge)
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
Edge Function user-facing nasce com os 4 sinais dourados — não é addon. O bloco `## Observabilidade integrada` acima cobre OTel SDK + spans + propagation; este bloco especifica os **4 instrumentos canônicos** que o template gerado SEMPRE inclui:
|
|
206
|
-
|
|
207
|
-
| Signal | Instrumento | Dimensão | Valor padrão |
|
|
208
|
-
|---|---|---|---|
|
|
209
|
-
| **Latency** | `meter.createHistogram('http_request_duration_ms')` com `explicitBucketBoundaries: [1,2,5,10,25,50,100,250,500,1000,2500,5000,10000,30000]` | `result=success\|error` (separar success de erro) | Bucketing exponencial captura long tail sem cardinality explosion |
|
|
210
|
-
| **Traffic** | `meter.createCounter('http_requests_total')` | `endpoint`, `http_method` | Incrementado antes de processar request |
|
|
211
|
-
| **Errors** | `meter.createCounter('http_errors_total')` | `error.type` enum (5-15 valores: `timeout\|validation\|auth\|rate_limit\|db\|provider_down\|...`) — **nunca** `error.message` (cardinalidade explode) | Incrementado em catch + path 4xx/5xx |
|
|
212
|
-
| **Saturation** | `meter.createObservableGauge('saturation_pct')` com callback que lê estado real | resource-specific: `connection_pool` (pg) / `concurrency_limit` (Edge runtime) / `egress_bandwidth` / `cache_memory` | % do recurso mais escasso identificado ANTES de instrumentar |
|
|
213
|
-
|
|
214
|
-
### Snippet canônico — adicionado ao topo do `index.ts` gerado
|
|
215
|
-
|
|
216
|
-
```ts
|
|
217
|
-
// PT-BR: 4 golden signals — instrumentação mínima universal
|
|
218
|
-
import { metrics } from 'npm:@opentelemetry/api@1.9.0'
|
|
219
|
-
const meter = metrics.getMeter('<function_name>')
|
|
220
|
-
|
|
221
|
-
// 1. LATENCY — histogram bucketed exponencial
|
|
222
|
-
const latencyHistogram = meter.createHistogram('http_request_duration_ms', {
|
|
223
|
-
description: 'Edge function latency split by result (success vs error)',
|
|
224
|
-
unit: 'ms',
|
|
225
|
-
advice: { explicitBucketBoundaries: [1, 2, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 30000] }
|
|
226
|
-
})
|
|
227
|
-
|
|
228
|
-
// 2. TRAFFIC — counter de requests recebidos
|
|
229
|
-
const trafficCounter = meter.createCounter('http_requests_total', {
|
|
230
|
-
description: 'Total HTTP requests received by edge function'
|
|
231
|
-
})
|
|
232
|
-
|
|
233
|
-
// 3. ERRORS — counter por error.type (NUNCA error.message — cardinalidade)
|
|
234
|
-
const errorsCounter = meter.createCounter('http_errors_total', {
|
|
235
|
-
description: 'Edge function errors by error.type enum'
|
|
236
|
-
})
|
|
237
|
-
|
|
238
|
-
// 4. SATURATION — gauge do recurso mais escasso (callback lê estado real)
|
|
239
|
-
// PT-BR: para Edge Function default, saturation = concurrency_limit_used %
|
|
240
|
-
// Substituir callback conforme recurso identificado (db pool, queue, cache)
|
|
241
|
-
meter.createObservableGauge('saturation_pct', {
|
|
242
|
-
description: 'Saturation of scarcest resource — function-specific'
|
|
243
|
-
}).addCallback((result) => {
|
|
244
|
-
// PT-BR: callback canônico — ler estado real (ex: SELECT count(*) FROM pg_stat_activity)
|
|
245
|
-
// Aqui placeholder: 0 < value < 1
|
|
246
|
-
result.observe(getSaturationPct()) // implementar conforme resource
|
|
247
|
-
})
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
### Wrapping no handler
|
|
251
|
-
|
|
252
|
-
```ts
|
|
253
|
-
Deno.serve(async (req: Request) => {
|
|
254
|
-
const start = performance.now()
|
|
255
|
-
const endpoint = new URL(req.url).pathname
|
|
256
|
-
trafficCounter.add(1, { endpoint, http_method: req.method })
|
|
257
|
-
|
|
258
|
-
try {
|
|
259
|
-
const response = await handle(req)
|
|
260
|
-
latencyHistogram.record(performance.now() - start, {
|
|
261
|
-
endpoint,
|
|
262
|
-
result: response.ok ? 'success' : 'error',
|
|
263
|
-
})
|
|
264
|
-
if (!response.ok) {
|
|
265
|
-
errorsCounter.add(1, { endpoint, 'error.type': classifyError(response) })
|
|
266
|
-
}
|
|
267
|
-
return response
|
|
268
|
-
} catch (err) {
|
|
269
|
-
latencyHistogram.record(performance.now() - start, { endpoint, result: 'error' })
|
|
270
|
-
errorsCounter.add(1, { endpoint, 'error.type': classifyError(err) })
|
|
271
|
-
throw err
|
|
272
|
-
}
|
|
273
|
-
})
|
|
274
|
-
|
|
275
|
-
// PT-BR: classifyError DEVE retornar enum fechado, não err.message
|
|
276
|
-
function classifyError(e: unknown): string {
|
|
277
|
-
if (e instanceof TimeoutError) return 'timeout'
|
|
278
|
-
if (e instanceof ValidationError) return 'validation'
|
|
279
|
-
if (e instanceof AuthError) return 'auth'
|
|
280
|
-
// ... 5-15 valores no total
|
|
281
|
-
return 'unknown'
|
|
282
|
-
}
|
|
303
|
+
- Característica de webhook → garanta signature validation antes de qualquer DB write
|
|
304
|
+
|
|
305
|
+
## Handoff cooperativo (v1.23+ pattern)
|
|
306
|
+
|
|
307
|
+
Quando outro agent (multi-tenant, debugger, evolution-go-integrator, etc.) precisa de Edge Function como parte de uma feature multi-componente, passa `behavior_description` + intent via `Task()`:
|
|
308
|
+
|
|
309
|
+
```python
|
|
310
|
+
Task(subagent_type="supabase-edge-fn-writer", prompt=f"""
|
|
311
|
+
<upstream_intent>
|
|
312
|
+
Source agent: evolution-go-integrator
|
|
313
|
+
Original goal: receber webhook do Evolution Go com mensagem inbound + persistir em messages table
|
|
314
|
+
Constraints: signature validation HMAC; service-to-service auth
|
|
315
|
+
</upstream_intent>
|
|
316
|
+
|
|
317
|
+
<function_spec>
|
|
318
|
+
function_name: evolution-webhook
|
|
319
|
+
auth_mode: none
|
|
320
|
+
verify_jwt: false
|
|
321
|
+
pattern: basic
|
|
322
|
+
behavior: validate HMAC signature; upsert into messages by external_id (idempotency)
|
|
323
|
+
</function_spec>
|
|
324
|
+
""")
|
|
283
325
|
```
|
|
284
326
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
| Tipo de função | Recurso mais escasso | Implementação típica |
|
|
288
|
-
|---|---|---|
|
|
289
|
-
| API simples (GET/POST com leitura DB) | `pg_pool` connections used | `select count(*) from pg_stat_activity where state = 'active'` |
|
|
290
|
-
| RAG / embeddings | `concurrency_limit` (provider externo) | counter de requests in-flight |
|
|
291
|
-
| Email / queue consumer (cron → pgmq) | `pgmq.queue_length` | `select msg_count from pgmq.metrics_<queue>` |
|
|
292
|
-
| Storage I/O heavy (uploads grandes) | `egress_bandwidth` | bytes-out tracker em window |
|
|
293
|
-
|
|
294
|
-
### Anti-patterns prevenidos
|
|
295
|
-
|
|
296
|
-
- Errors counter usando `error.type = err.message` → SEMPRE enum fechado (5-15 valores)
|
|
297
|
-
- Latency mistura success + error → SEMPRE `result` dimension separa
|
|
298
|
-
- Mean latency em vez de histogram → SEMPRE histogram com percentis derivados em backend
|
|
299
|
-
- Saturation genérico (CPU%) sem identificar recurso real → SEMPRE escolher recurso scarcest da função
|
|
327
|
+
Este agent **nunca** descarta upstream intent — adapta padrões canônicos ao goal.
|
|
300
328
|
|
|
301
329
|
## Ver também
|
|
302
330
|
|
|
303
|
-
- [supabase-edge-functions](../skills/supabase-edge-functions/SKILL.md) — base de conhecimento
|
|
304
|
-
- [supabase-
|
|
305
|
-
- [supabase-
|
|
306
|
-
- [
|
|
307
|
-
- [
|
|
308
|
-
- [
|
|
309
|
-
- [
|
|
310
|
-
- [
|
|
311
|
-
- [golden-signals-instrumenter](./golden-signals-instrumenter.md) —
|
|
331
|
+
- [`supabase-edge-functions`](../skills/supabase-edge-functions/SKILL.md) — base de conhecimento
|
|
332
|
+
- [`supabase-edge-functions-auth`](../skills/supabase-edge-functions-auth/SKILL.md) — withSupabase + auth modes
|
|
333
|
+
- [`supabase-edge-functions-testing`](../skills/supabase-edge-functions-testing/SKILL.md) — gerar tests via `supabase-edge-fn-tester`
|
|
334
|
+
- [`supabase-edge-runtime-builtins`](../skills/supabase-edge-runtime-builtins/SKILL.md) — AI, /s3, WebSocket, Wasm
|
|
335
|
+
- [`supabase-edge-functions-limits`](../skills/supabase-edge-functions-limits/SKILL.md) — limits + RateLimitError
|
|
336
|
+
- [`supabase-edge-functions-mcp-server`](../skills/supabase-edge-functions-mcp-server/SKILL.md) — mcp-lite
|
|
337
|
+
- [`supabase-cron-queues`](../skills/supabase-cron-queues/SKILL.md) — pattern `cron → pgmq → Edge Function`
|
|
338
|
+
- [`supabase-auth-ssr`](../skills/supabase-auth-ssr/SKILL.md) — clients SSR
|
|
339
|
+
- [`golden-signals-instrumenter`](./golden-signals-instrumenter.md) — retro-instrumenta Edge Functions existentes
|
|
340
|
+
- [`supabase-edge-fn-tester`](./supabase-edge-fn-tester.md) — handoff para gerar Deno tests
|