Files
agenciapsilmno/src/features/agenda/composables/useInsurancePlans.js
T
Leonardo a7f6bcbe66 F3 schema-per-tenant: frontend usa tenantDb() pra tabelas tenant
- useTenantDb composable + lib/supabase/tenantClient (tenantDb/tenantSchemaName)
- tenantStore: getters activeTenantSlug/activeTenantSchema; my_tenants() RPC
  passa a devolver slug+nome (migration 07)
- codemod scripts/codemod-tenant-db.py: supabase.from('<84 tabelas + 6 views
  tenant>') -> tenantDb().from(...) em 139 arquivos (777 chamadas), remove
  .eq('tenant_id') das cadeias tenant (173)
- passada manual (4 agentes): remove tenant_id de payloads insert/upsert/update,
  selects, .or/.is de defaults; onConflict ajustado pros uniques sem tenant_id
  (singletons usam 'singleton'); realtime de tabelas tenant aponta pro schema
  do tenant ativo; repos dropam tenant_id defensivamente de payloads externos
- agendaSelects: tenant_id fora do AGENDA_EVENT_SELECT (quebraria PostgREST)
- zero embeds cross-schema (todos FK embeds sao tenant->tenant ou global->global)
- build de producao passa; 67 .js checados

Pendente (fora do escopo F3, sao cross-tenant/anon -> F4/F6):
- AgendadorPublicoPage (anon, resolve tenant por link_slug)
- Saas{Feriados,NotificationTemplates,DocumentTemplates,Whatsapp}Page
  (gerenciam defaults do sistema / views cross-tenant)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 04:44:59 -03:00

190 lines
6.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/features/agenda/composables/useInsurancePlans.js
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
*/
// Interface pública:
// plans ref([]) todos os planos do owner (ativos e inativos)
// loading ref(false)
// error ref(null)
//
// load(ownerId) carrega planos com seus procedimentos
// save(payload) insert ou update do plano (name, notes)
// toggle(id, active) alterna active do plano
// remove(id) soft-delete do plano
// savePlanService(payload) insert ou update de procedimento { id?, insurance_plan_id, name, value }
// togglePlanService(id, active) alterna active do procedimento
// removePlanService(id) DELETE definitivo do procedimento
import { ref } from 'vue';
import { supabase } from '@/lib/supabase/client';
import { tenantDb } from '@/lib/supabase/tenantClient';
export function useInsurancePlans() {
const plans = ref([]);
const loading = ref(false);
const error = ref(null);
async function load(ownerId) {
if (!ownerId) return;
loading.value = true;
error.value = null;
try {
const { data, error: err } = await tenantDb().from('insurance_plans')
.select(
`
*,
insurance_plan_services (
id, name, value, active
)
`
)
.eq('owner_id', ownerId)
.order('name');
if (err) throw err;
plans.value = data || [];
} catch (e) {
error.value = e?.message || 'Erro ao carregar convênios';
plans.value = [];
} finally {
loading.value = false;
}
}
async function save(payload) {
error.value = null;
try {
if (payload.id) {
const { error: err } = await tenantDb().from('insurance_plans')
.update({
name: payload.name,
notes: payload.notes || null,
updated_at: new Date().toISOString()
})
.eq('id', payload.id);
if (err) throw err;
} else {
const { error: err } = await tenantDb().from('insurance_plans').insert({
owner_id: payload.owner_id,
name: payload.name,
notes: payload.notes || null
});
if (err) throw err;
}
} catch (e) {
error.value = e?.message || 'Erro ao salvar convênio';
throw e;
}
}
async function toggle(id, active) {
error.value = null;
try {
const { error: err } = await tenantDb().from('insurance_plans').update({ active }).eq('id', id);
if (err) throw err;
const plan = plans.value.find((p) => p.id === id);
if (plan) plan.active = active;
} catch (e) {
error.value = e?.message || 'Erro ao atualizar convênio';
throw e;
}
}
async function remove(id) {
error.value = null;
try {
const { error: err } = await tenantDb().from('insurance_plans').update({ active: false }).eq('id', id);
if (err) throw err;
const plan = plans.value.find((p) => p.id === id);
if (plan) plan.active = false;
} catch (e) {
error.value = e?.message || 'Erro ao remover convênio';
throw e;
}
}
async function savePlanService(payload) {
error.value = null;
try {
if (payload.id) {
const { error: err } = await tenantDb().from('insurance_plan_services')
.update({
name: payload.name,
value: payload.value
})
.eq('id', payload.id);
if (err) throw err;
} else {
const { error: err } = await tenantDb().from('insurance_plan_services').insert({
insurance_plan_id: payload.insurance_plan_id,
name: payload.name,
value: payload.value
});
if (err) throw err;
}
} catch (e) {
error.value = e?.message || 'Erro ao salvar procedimento';
throw e;
}
}
async function togglePlanService(id, active) {
error.value = null;
try {
const { error: err } = await tenantDb().from('insurance_plan_services').update({ active }).eq('id', id);
if (err) throw err;
} catch (e) {
error.value = e?.message || 'Erro ao atualizar procedimento';
throw e;
}
}
async function removeDefinitivo(id) {
error.value = null;
try {
const { error: err } = await tenantDb().from('insurance_plans').delete().eq('id', id);
if (err) throw err;
plans.value = plans.value.filter((p) => p.id !== id);
} catch (e) {
error.value = e?.message || 'Erro ao remover convênio';
throw e;
}
}
async function removePlanService(id) {
error.value = null;
try {
const { error: err } = await tenantDb().from('insurance_plan_services').delete().eq('id', id);
if (err) throw err;
} catch (e) {
error.value = e?.message || 'Erro ao remover procedimento';
throw e;
}
}
return {
plans,
loading,
error,
load,
save,
toggle,
remove,
removeDefinitivo,
savePlanService,
togglePlanService,
removePlanService
};
}