F6.2 Lote E: RPCs de cron/global roteadas/loopadas por tenant

DB (supabase_admin, manual/f6_2e_cron_rpcs.supabase_admin.sql):
- E2 (varrem TODOS os tenants via loop FROM tenant_schemas): cleanup/unstick_
  notification_queue, sync_overdue_financial_records (EXECUTE format por schema),
  populate_notification_queue (set_config search_path por tenant; profiles global)
- E1 (per-tenant via service_role): novo helper _tenant_schema_unchecked (sem
  is_tenant_member — service_role nao e membro; REVOKE de anon/authenticated).
  sla_open_breach, sla_mark_notified(+p_tenant_id), whatsapp_heartbeat_open_
  incident/mark_notified/resolve(+p_tenant_id). convert_abandoned_intake_to_lead
  resolve tenant internamente (intake public/F1b -> writes no schema).
  first_response_stats/_runs: _tenant_route (user-facing, frontend ja passa
  p_tenant_id); _first_response_runs computa thread_key (coluna nao existe).
- REVOKE das RPCs de servico de anon/authenticated; GRANT service_role

Edge: whatsapp-heartbeat-check (tdb.rpc->admin.rpc + p_tenant_id nos heartbeat
RPCs), conversation-sla-check (sla_mark_notified + p_tenant_id).

Gotchas: (1) service_role nao e tenant_member -> helper unchecked + REVOKE;
(2) conversation_messages nao tem coluna thread_key (computar); (3) DROP+CREATE
de nova assinatura precisa dropar ambas p/ idempotencia.

Smoke: E2 sync_overdue 13 across tenants; E1 sla_open_breach roteia; first_
response_stats user OK.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Leonardo
2026-06-13 15:25:36 -03:00
parent d3620f99ea
commit 02acc88da5
3 changed files with 314 additions and 5 deletions
@@ -286,7 +286,7 @@ async function notifyBreach(tdb: SupabaseClient, admin: SupabaseClient, tenantId
const { error: insertErr } = await tdb.from('notifications').insert(rows)
if (insertErr) return false
await admin.rpc('sla_mark_notified', { p_breach_id: params.breach_id })
await admin.rpc('sla_mark_notified', { p_tenant_id: tenantId, p_breach_id: params.breach_id })
return true
}