Files
agenciapsilmno/commit.md
T
Leonardo d6eb992f71 Sessoes 6cont-10: hardening em 6 areas + scan completo do SaaS
Continuacao de 7c20b51. Esta etapa fechou TODA revisao senior do SaaS
(15 areas auditadas) + refator parcial de pacientes.

Ver commit.md para descricao completa por sessao.

# Estado final do projeto
- A# auditoria abertos: 1 (A#31 Deploy real)
- V# verificacoes abertos: 14 (todos medios/baixos adiados com plano)
- Criticos: 0
- Altos: 0
- Vitest: 208/208 (era 192, +16 nos novos composables)
- SQL integration: 33/33
- E2E (Playwright): 5/5
- Areas auditadas: 15

# Highlights
- Documentos 100% fechado (V#50/51/52: portal-paciente policy + content_sha256 + 4 cron jobs retention)
- Tenants V#1 P0: tenant_invites com RLS off + 0 policies (mesmo padrao A#30)
- Calendario 100% fechado: feriados WITH CHECK
- Addons V#1 P0 (dinheiro): addon_transactions WITH CHECK saas_admin
- Central SaaS V#1: faq write so saas_admin (era tenant_admin)
- Servicos/Prontuarios 100% fechado: services/medicos/insurance_plans + cascades
- Pacientes V#9: 2 composables novos (useCep, usePatientSupportContacts) + repo estendido + script extraido (template intocado, fica para quando houver E2E)

# 8 migrations novas neste commit
- 20260419000011_documents_portal_patient_policy.sql
- 20260419000012_documents_content_hash.sql
- 20260419000013_cron_retention_jobs.sql
- 20260419000014_financial_security_hardening.sql
- 20260419000015_communication_security_hardening.sql
- 20260419000016_tenants_calendario_hardening.sql
- 20260419000017_addons_central_saas_hardening.sql
- 20260419000018_servicos_prontuarios_hardening.sql

Total acumulado: 18 migrations (Sessoes 1-10).

# A#31 reformulado pra proxima sessao
"Deploy real" muda escopo: como nao ha cloud Supabase nem secrets reais
ainda (MVP), proxima sessao vira "Preparacao completa pra deploy" (DEPLOY.md,
validar migrations num container limpo, audit edge functions, listar env vars,
script db.cjs deploy-check).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 22:00:06 -03:00

8.9 KiB

Sessões 6 (continuação) → 10 — hardening em 6 áreas + scan completo do SaaS

Continuação do commit 7c20b51 (Sessões 1-6 iniciais). Esta etapa fechou toda revisão sênior do SaaS + refator parcial de pacientes.

Estado final do projeto:

  • A# auditoria abertos: 1 (A#31 Deploy real)
  • V# verificações abertos: 14 (todos médios/baixos adiados com plano completo no DB)
  • 🔴 Críticos: 0
  • 🟠 Altos: 0
  • Vitest: 208/208 (era 192)
  • SQL integration: 33/33
  • E2E (Playwright): 5/5
  • Áreas auditadas: 15 (todas as principais do SaaS)

Sessão 6 (continuação) — Documentos pendentes + Pacientes V#3

Documentos: 100% fechado (V#50, V#51, V#52)

  • V#50 — Policy documents: portal patient read adicional. Paciente lê documento via portal quando compartilhado_portal=true AND patient pertence a auth.uid AND não expirou.
  • V#51documents.content_sha256 (nullable, índice parcial). Documents.service.uploadDocument calcula SHA-256 hex client-side via crypto.subtle.digest. Helper novo verifyDocumentIntegrity(docId) baixa arquivo e re-hash.
  • V#52 — Migration ...13 cron retention via pg_cron: 4 jobs (document_access_logs 1 ano, math_challenges 1h, public_submission_attempts 90 dias, submission_rate_limits 30 dias).

Pacientes V#3 (parcial — fundação)

  • src/features/patients/services/patientsRepository.js — list/get/create/update/softDelete + groups + tags + getSessionCounts.
  • src/features/patients/composables/usePatients.js — wrapper reativo (rows/loading/error).
  • PatientsListPage.hydrateAssociationsSupabase migrada — substitui 4 queries diretas por chamadas ao repo (paralelismo preservado).
  • V#9 (PatientsCadastroPage 1991 linhas) → adiado pra Sessão 10.

Sessão 7 — Tenants + Calendário

Tenants (8 V#)

  • 🔴 V#1 P0tenant_invites com RLS off + 0 policies (mesmo padrão A#30 Sessão 5). Tabela tinha 0 rows. Migration: ENABLE RLS + 4 policies (SELECT tenant_admin/saas; INSERT WITH CHECK invited_by=auth.uid; UPDATE só revogação; DELETE tenant_admin/saas). Aceitar invite continua via RPC tenant_accept_invite SECURITY DEFINER.
  • 🟠 V#2 profiles INSERT WITH CHECK (id = auth.uid)
  • 🟠 V#3 support_sessions INSERT WITH CHECK (admin_id = auth.uid + saas_admin guard)
  • 🟡 V#4 (signup público) verificado: RPC ensure_personal_tenant SECURITY DEFINER já existia (Signup.vue:232) → ok
  • 🟡 V#5 (accept_invite) verificado: RPCs tenant_accept_invite + tenant_invite_member_by_email já existiam → ok
  • 🟡 V#6 user_settings INSERT WITH CHECK
  • 🟢 V#7/V#8 baixos — adiados

Calendário (2 V#) — 100% fechado

  • 🔴 V#1 feriados_insert + feriados_saas_insert ganharam WITH CHECK. Spam de feriado global bloqueado.
  • 🟢 V#2 feriados_delete agora permite tenant_admin (não só owner).

Sessão 8 — Addons + Central SaaS

Addons (4 V#)

  • 🔴 V#1 P0 (dinheiro)addon_transactions_admin_insert ganhou WITH CHECK (EXISTS saas_admins). Edge functions com service_role bypassam RLS, pipeline preservado. Authenticated comum não cria mais transação fake.
  • 🟠 V#2 — 3 CHECK constraints em addon_credits: balance >= 0, total_consumed >= 0, total_purchased >= 0. Saldo negativo silencioso eliminado.
  • 🟡 V#3 (UI extrato) — adiado.
  • 🟡 V#4 — verificado: addon_products não tem tenant_id (catálogo global por design) → ok.

Central SaaS (3 V#)

  • 🟠 V#1faq_admin_write substituído por faq_saas_admin_write em saas_faq E saas_faq_itens — só saas_admin escreve. Tenant_admin lê via faq_auth_read (permanece).
  • 🟢 V#2/V#3 médios/baixos — adiados.

Sessão 9 — Serviços/Prontuários (100% fechado)

5/5 V# corrigidos:

  • 🔴 V#1 services + insurance_plans → 4 policies separadas (SELECT tenant_member; INSERT/UPDATE/DELETE owner+saas).
  • 🔴 V#2 medicos → 4 policies separadas (catálogo de médicos referenciadores compartilhado entre profissionais do tenant).
  • 🟠 V#3 commitment_services — cascade reescrito via JOIN com services (USING permite tenant_member; WITH CHECK só owner).
  • 🟠 V#4 insurance_plan_services — cascade reescrito via JOIN com insurance_plans.
  • 🟡 V#5 commitment_time_logs/determined_commitments/determined_commitment_fields ganharam WITH CHECK em INSERT.

Sessão 10 — Pacientes V#9 (script extraído)

PatientsCadastroPage.vue: 1991 → 1951 linhas (qualitativo > quantitativo).

2 composables novos

  • useCep.js — busca ViaCEP reutilizável. 6 testes (sem rede, mock fetch).
  • usePatientSupportContacts.js — CRUD de contatos de suporte encapsulado (load/save/add/remove/iniciaisFor). 10 testes com builder thenable.

patientsRepository estendido

  • getPatientRelations(patientId) — retorna {groupIds, tagIds}
  • replacePatientGroup(patientId, groupId, {tenantId})
  • replacePatientTags(patientId, tagIds, {tenantId, ownerId})

PatientsCadastroPage refatorado

  • 8 funções de query → delegação 1-linha ao patientsRepository
  • onCepBlur → usa composable useCep
  • Contatos de suporte → composable
  • Template não foi tocado (zero risco de regressão visual)
  • Quebra de template em sub-componentes Vue → adiado pra quando houver E2E cobrindo a página

📦 Migrations consolidadas neste commit (8)

20260419000011_documents_portal_patient_policy.sql      (V#50)
20260419000012_documents_content_hash.sql               (V#51)
20260419000013_cron_retention_jobs.sql                  (V#52 + math_challenges + submissions + rate_limits)
20260419000014_financial_security_hardening.sql         (5 V# financeiro — fechados na Sessão 6)
20260419000015_communication_security_hardening.sql     (5 V# comunicação — fechados na Sessão 6)
20260419000016_tenants_calendario_hardening.sql         (Tenants V#1-V#3,V#6 + Calendário V#1-V#2)
20260419000017_addons_central_saas_hardening.sql        (Addons V#1-V#2 + Central SaaS V#1)
20260419000018_servicos_prontuarios_hardening.sql       (Serviços V#1-V#5)

Total acumulado de migrations no histórico: 18 (Sessões 1-10).

Várias dessas exigiram conexão direta como supabase_admin (ver memory project_supabase_admin_gotcha.md e commit.md anterior) por causa de tabelas owned por esse role.


🆕 Novos arquivos (código)

src/features/patients/composables/useCep.js
src/features/patients/composables/usePatientSupportContacts.js
src/features/patients/composables/usePatients.js
src/features/patients/composables/__tests__/useCep.spec.js                    (+6 testes)
src/features/patients/composables/__tests__/usePatientSupportContacts.spec.js (+10 testes)
src/features/patients/services/patientsRepository.js

🛠️ Modificações

  • src/features/patients/PatientsListPage.vue — hydrateAssociationsSupabase usa repo
  • src/features/patients/cadastro/PatientsCadastroPage.vue — script extraído (queries → repo, CEP → composable, contatos → composable). Template intocado.
  • src/services/Documents.service.js — uploadDocument calcula content_sha256 + helper verifyDocumentIntegrity

📊 Áreas auditadas (estado final)

Área V# total Estado
auth 10 100% fechado/ok
router 9 100%
stores 1 100%
agenda 11 100%
pacientes 10 100% fechado
seguranca 1 100%
saas 10 100%
documentos 10 100% fechado
financeiro 11 5 fechados, 6 médios/baixos adiados
comunicacao 10 5 fechados, 5 médios/baixos adiados
tenants 8 6 fechados, 2 baixos adiados
calendario 2 100% fechado
addons 4 3 resolvidos, 1 médio adiado
central_saas 3 1 alto fechado, 2 médios adiados
servicos 5 100% fechado

Zero crítico/alto restante no sistema inteiro.


⚠️ Pendências documentadas no DB (não esquecidas)

A# (1 aberto)

  • A#31 Deploy real — alto. Reformulação pendente: como ainda não há cloud Supabase nem secrets reais, próxima sessão é "Preparação completa pra deploy" (DEPLOY.md, validar migrations num container limpo, audit de edge functions, listar env vars, script db.cjs deploy-check).

V# adiados (14)

Todos médios/baixos com plano completo em dev_verificacoes_items.acao_sugerida:

  • financeiro (6): parcelamento CHECK, payouts flow, recurrence DELETE policy, composables, máscara PIX, dashboard inadimplência
  • comunicacao (5): notifications/schedules silos, email_templates_global filtros, retention notification_logs, dashboard health, audit dismissals/preferences
  • tenants (2): owner_users policies, company_profiles + dev_user_credentials
  • central_saas (2): rate limit voto, valores tipo_acesso
  • addons (1): UI de extrato

Outros

  • PatientsCadastroPage template breakdown — quando houver E2E
  • Pacientes V#9 segue 100% no banco (script foi extraído; template é refator visual separado)