wiki: F6.0+F6.1 done, plano F6.2

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Leonardo
2026-06-13 12:53:22 -03:00
parent 003f2eb2a6
commit c3220f159c
2 changed files with 28 additions and 1 deletions
+3
View File
@@ -1657,3 +1657,6 @@ Touched: Migracao Schema-per-Tenant
## [2026-06-13 09:26] session | F5 PostgREST expoe schemas tenant (E2E HTTP)
Touched: Migracao Schema-per-Tenant
## [2026-06-13 12:53] session | F6.0+F6.1 clones + migracao dados; plano F6.2
Touched: Migracao Schema-per-Tenant
@@ -1,6 +1,30 @@
# Migração Schema-per-Tenant
**Status:** F5 concluída e testada E2E via HTTP (2026-06-13). Próximo: F6 (rewrite funções + migração de dados + drops). F0-F2 em `main`; F3+/F1b/F5 no branch até cutover.
**Status:** F6.0 + F6.1 concluídas e verificadas (2026-06-13). Dados dos 9 tenants migrados pros schemas, AINDA espelhados em public (nada dropado), backup em `database-novo/backups/pre-F6/`. Próximo: **F6.2 (rewrite das funções — push dedicado)**, depois checkpoint de teste do app, depois F6.3 (DROP, só com OK do Leonardo). F0-F2 em `main`; F3+/F1b/F5/F6.0-1 no branch.
## F6.0 + F6.1 — entregue (commit 003f2eb)
- F6.0 (migration 20260613000003): clone dos 9 tenants reais (schemas vazios, expostos no PostgREST via trigger F5).
- F6.1 (manual `database-novo/manual/f6_1_migrate_data.supabase_admin.sql`, rodar como supabase_admin): copia dados public→schemas com `session_replication_role=replica`. Tabelas com tenant_id por filtro; 3 filhas sem tenant_id (commitment_services, insurance_plan_services, recurrence_rule_services) por JOIN no pai; exclui colunas GENERATED (`net_amount`, `margin_brl`); reset de 4 sequences; ON CONFLICT DO NOTHING.
- **Verificado**: contagens public vs schemas batem (35 patients, 37 eventos, 355 mensagens, 54 financeiro, 13 commitment_services…). notification_templates "146" = 144 seeds (16×9) + 2 tenant — esperado.
- Gotcha: colunas GENERATED não aceitam INSERT → excluir via `is_generated='NEVER'`. DO block é atômico → erro no meio dá rollback total (re-rodar é seguro com ON CONFLICT).
## F6.2 — PLANO (rewrite de 66 funções + split notifications) — próximo push
Decisões já tomadas: parar antes do DROP pra testar app; split notifications JUNTO na F6.
Inventário de triggers (81 attachments nas tabelas tenant em public):
- **Schema-agnósticos** (só NEW/OLD, sem refs a tabela): família `set_updated_at`/`set_*_updated_at`, `fn_clinical_notes_updated_at`, `prevent_promoting_to_system`, `prevent_system_group_changes`, `patients_validate_member_consistency`, `fn_agenda_regras_semanais_no_overlap` → anexar nos schemas como estão.
- **Schema-aware** (~10, escrevem em OUTRA tabela tenant / audit / notifications) → reescrever com `set_config('search_path', TG_TABLE_SCHEMA||',public,pg_temp', true)` e `tenant_id_for_schema(TG_TABLE_SCHEMA)` onde precisam do tenant_id (audit_logs/notifications_sistema são globais): `auto_create_financial_record_from_session`, `sync_busy_mirror_agenda_eventos`, `notify_on_session_status`, `fanout_inbound_message_to_notifications`, `log_audit_change`, `fn_sla_resolve_on_outbound`, `fn_clinical_note_version`, `fn_document_signature_timeline`, `fn_documents_timeline_insert`, `trg_fn_patient_status_history/timeline/risco`, `sync_legacy_email/phone_fields`, `agenda_cfg_sync`, `cancel_notifications_*`, `fn_notify_agenda_status_change`, `trg_fn_financial_records_auto_overdue`.
- **`financial_records_inject_tenant` → OBSOLETO** no schema (não há coluna tenant_id) — NÃO anexar.
Sub-lotes propostos (cada um com smoke test + commit):
- **A** triggers schema-agnósticos: anexar aos 9 schemas + embutir no clone_tenant_template (backfill + futuro).
- **B** triggers schema-aware: reescrever (search_path dinâmico) + anexar.
- **C** split notifications: `public.notifications_sistema` (tipos cross-tenant: avisos SaaS, suporte, system_alert) + `tenant_<x>.notifications` (locais); refatorar notify_user/notify_tenant_admins/notify_all_devs/mark/archive (2 variantes); migrar dados por type; `useNotifications.js` lê 2 fontes (campo `_origem`), realtime 2 canais; ALTER PUBLICATION add notifications_sistema.
- **D** RPCs de usuário (~30: mark_as_paid, create_financial_record_for_session, safe_delete_patient, search_global, cancel_recurrence_from, export_patient_data…) → `p_tenant_id` validado com `is_tenant_member` + `set_config(search_path)`.
- **E** RPCs global/cron (~10: populate/cleanup/unstick_notification_queue, sync_overdue_financial_records, whatsapp_heartbeat_*, sla_*) → loop `FROM tenants`.
- **F** RPCs anon/token (~8: get_patient_intake_invite_info, sign_document_by_token, validate_share_token, agendador_*) → leem tabelas anon (public, F1b) e roteiam writes de tabela tenant (ex. document_signatures) pro schema via tenant resolvido do token.
- **G** SQL→plpgsql (8: can_delete_patient, get_financial_report/summary, list_financial_records, get_patient_session_counts, get_entity_primary_phone, _first_response_runs) — DROP+CREATE (muda linguagem).
- Depois: re-anexar todos triggers reescritos nos 9 + clone. Então **F6.3 DROP** (com OK).
## F5 — entregue (commit 6b542cd) — PRIMEIRO teste real via HTTP do PostgREST
- `postgres` NÃO é superuser neste stack → não consegue `ALTER ROLE authenticator`. Quem consegue: `supabase_admin` (superuser, conecta com senha `postgres` via `psql -U supabase_admin -h 127.0.0.1`).