<!--
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/features/agenda/components/dev/AgendaDevDocs.vue
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
-->
<!-- Documentação técnica da Agenda — exibida apenas em modo suporte/dev.
     Acessível via SupportDebugBanner → botão "Docs". -->
<script setup>
import { ref } from 'vue';
import { tenantDb } from '@/lib/supabase/tenantClient';

const props = defineProps({
    visible: { type: Boolean, default: false }
});
const emit = defineEmits(['update:visible']);

function close() {
    emit('update:visible', false);
}

const activeTab = ref(0);
</script>

<template>
    <Dialog :visible="visible" @update:visible="emit('update:visible', $event)" modal header="📘 Documentação Técnica — Agenda" :style="{ width: '860px', maxWidth: '96vw' }" :pt="{ content: { style: 'padding: 0' } }">
        <TabView v-model:activeIndex="activeTab" class="dev-docs">
            <!-- ── Tab 0: Visão Geral ─────────────────────────────── -->
            <TabPanel header="Visão Geral">
                <div class="dd-section">
                    <div class="dd-alert">Este painel é visível <strong>apenas em modo suporte SaaS</strong> ativo. Nunca é exibido em produção sem um token válido.</div>

                    <h3 class="dd-h3">Propósito</h3>
                    <p class="dd-p">
                        A <strong>Agenda</strong> é o núcleo do sistema. Permite ao terapeuta gerenciar sessões, bloqueios, recorrências e compromissos determinísticos — tudo integrado ao sistema de precificação, convênios e agendamento online.
                    </p>

                    <h3 class="dd-h3">Stack técnica</h3>
                    <div class="dd-grid-2">
                        <div class="dd-card">
                            <div class="dd-card-title">Frontend</div>
                            <ul class="dd-list">
                                <li><span class="dd-tag blue">Vue 3</span> Composition API + <code>&lt;script setup&gt;</code></li>
                                <li><span class="dd-tag purple">FullCalendar</span> timeGrid / dayGrid + interaction plugin</li>
                                <li><span class="dd-tag green">PrimeVue</span> Dialog, DataTable, Select, Toast</li>
                                <li><span class="dd-tag orange">Pinia</span> tenantStore, entitlementsStore, menuStore</li>
                            </ul>
                        </div>
                        <div class="dd-card">
                            <div class="dd-card-title">Backend</div>
                            <ul class="dd-list">
                                <li><span class="dd-tag teal">Supabase</span> PostgreSQL + Row Level Security</li>
                                <li><span class="dd-tag red">RPCs</span> Funções PL/pgSQL para operações críticas</li>
                                <li><span class="dd-tag yellow">Realtime</span> Não utilizado na agenda (pull-based)</li>
                            </ul>
                        </div>
                    </div>

                    <h3 class="dd-h3">Arquitetura em camadas</h3>
                    <div class="dd-layers">
                        <div class="dd-layer dd-layer--page">
                            <strong>Pages</strong>
                            <span>AgendaTerapeutaPage · AgendaClinicaPage · CompromissosDeterminados</span>
                        </div>
                        <div class="dd-layer-arrow">▼</div>
                        <div class="dd-layer dd-layer--composable">
                            <strong>Composables</strong>
                            <span>useAgendaSettings · useAgendaEvents · useRecurrence · useCommitmentServices · useDeterminedCommitments</span>
                        </div>
                        <div class="dd-layer-arrow">▼</div>
                        <div class="dd-layer dd-layer--service">
                            <strong>Services / Repositories</strong>
                            <span>agendaRepository · agendaClinicRepository · agendaMappers</span>
                        </div>
                        <div class="dd-layer-arrow">▼</div>
                        <div class="dd-layer dd-layer--db">
                            <strong>Supabase</strong>
                            <span>Tables + RPCs + RLS Policies</span>
                        </div>
                    </div>

                    <h3 class="dd-h3">Rotas registradas</h3>
                    <table class="dd-table">
                        <thead>
                            <tr>
                                <th>Path</th>
                                <th>Name</th>
                                <th>Área</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td><code>/therapist/agenda</code></td>
                                <td>therapist-agenda</td>
                                <td>Terapeuta</td>
                            </tr>
                            <tr>
                                <td><code>/therapist/agenda/recorrencias</code></td>
                                <td>therapist-agenda-recorrencias</td>
                                <td>Terapeuta</td>
                            </tr>
                            <tr>
                                <td><code>/therapist/agenda/compromissos</code></td>
                                <td>therapist-agenda-compromissos</td>
                                <td>Terapeuta</td>
                            </tr>
                            <tr>
                                <td><code>/therapist/agendamentos-recebidos</code></td>
                                <td>therapist-agendamentos-recebidos</td>
                                <td>Terapeuta</td>
                            </tr>
                            <tr>
                                <td><code>/admin/agenda/clinica</code></td>
                                <td>admin-agenda-clinica</td>
                                <td>Clínica</td>
                            </tr>
                            <tr>
                                <td><code>/admin/agenda/compromissos</code></td>
                                <td>admin-agenda-compromissos</td>
                                <td>Clínica</td>
                            </tr>
                            <tr>
                                <td><code>/agendar/:slug</code></td>
                                <td>agendador.publico</td>
                                <td>Público</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </TabPanel>

            <!-- ── Tab 1: Tabelas ─────────────────────────────────── -->
            <TabPanel header="Tabelas">
                <div class="dd-section">
                    <p class="dd-p">Todas as tabelas usam <strong>Row Level Security (RLS)</strong> habilitada. As tabelas da agenda vivem no schema do tenant (<code>tenant_&lt;slug&gt;</code>, sem coluna <code>tenant_id</code>) e são acessadas via <code>tenantDb().from(...)</code>.</p>

                    <h3 class="dd-h3">Core</h3>
                    <table class="dd-table">
                        <thead>
                            <tr>
                                <th>Tabela</th>
                                <th>Propósito</th>
                                <th>Colunas-chave</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td><code>agenda_configuracoes</code></td>
                                <td>Configurações da agenda por owner (terapeuta ou clínica)</td>
                                <td>owner_id, slot_duration_minutes, start_time, end_time, days_of_week</td>
                            </tr>
                            <tr>
                                <td><code>agenda_eventos</code></td>
                                <td>Eventos individuais (sessões, bloqueios avulsos)</td>
                                <td>id, owner_id, patient_id, starts_at, ends_at, status, recurrence_rule_id, tipo</td>
                            </tr>
                            <tr>
                                <td><code>agenda_bloqueios</code></td>
                                <td>Períodos bloqueados na agenda</td>
                                <td>owner_id, starts_at, ends_at, motivo, recorrente</td>
                            </tr>
                            <tr>
                                <td><code>agenda_regras_semanais</code></td>
                                <td>Horários de trabalho semanais por dia</td>
                                <td>owner_id, day_of_week (0–6), start_time, end_time</td>
                            </tr>
                        </tbody>
                    </table>

                    <h3 class="dd-h3">Recorrência</h3>
                    <table class="dd-table">
                        <thead>
                            <tr>
                                <th>Tabela</th>
                                <th>Propósito</th>
                                <th>Colunas-chave</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td><code>recurrence_rules</code></td>
                                <td>Regra mãe de uma série recorrente</td>
                                <td>id, owner_id, patient_id, frequency, interval, start_date, end_date, days_of_week, status</td>
                            </tr>
                            <tr>
                                <td><code>recurrence_exceptions</code></td>
                                <td>Exceções a uma regra (cancelamentos, alterações pontuais)</td>
                                <td>rule_id, original_date, action (skip | reschedule), new_starts_at</td>
                            </tr>
                            <tr>
                                <td><code>recurrence_rule_services</code></td>
                                <td>Serviços-template associados a uma regra recorrente</td>
                                <td>rule_id, service_id, quantity, unit_price</td>
                            </tr>
                        </tbody>
                    </table>

                    <h3 class="dd-h3">Compromissos e Serviços</h3>
                    <table class="dd-table">
                        <thead>
                            <tr>
                                <th>Tabela</th>
                                <th>Propósito</th>
                                <th>Colunas-chave</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td><code>determined_commitments</code></td>
                                <td>Tipos de compromisso determinístico (ex: Avaliação, Supervisão)</td>
                                <td>id, owner_id, name, color, duration_minutes</td>
                            </tr>
                            <tr>
                                <td><code>determined_commitment_fields</code></td>
                                <td>Campos customizados por tipo de compromisso</td>
                                <td>commitment_id, field_key, label, type, required</td>
                            </tr>
                            <tr>
                                <td><code>commitment_services</code></td>
                                <td>Serviços vinculados a um evento específico</td>
                                <td>evento_id, service_id, quantity, unit_price, insurance_plan_id</td>
                            </tr>
                            <tr>
                                <td><code>services</code></td>
                                <td>Catálogo de serviços do terapeuta/clínica</td>
                                <td>id, owner_id, name, default_price, active</td>
                            </tr>
                            <tr>
                                <td><code>professional_pricing</code></td>
                                <td>Precificação por tipo de compromisso e profissional</td>
                                <td>owner_id, commitment_type_id, price, insurance_plan_id</td>
                            </tr>
                            <tr>
                                <td><code>insurance_plans</code></td>
                                <td>Convênios cadastrados</td>
                                <td>id, owner_id, name, active, notes</td>
                            </tr>
                            <tr>
                                <td><code>insurance_plan_services</code></td>
                                <td>Serviços cobertos por um convênio</td>
                                <td>plan_id, service_id, covered_price</td>
                            </tr>
                            <tr>
                                <td><code>patient_discounts</code></td>
                                <td>Descontos individuais por paciente</td>
                                <td>owner_id, patient_id, discount_type (pct | fixed), value</td>
                            </tr>
                            <tr>
                                <td><code>financial_exceptions</code></td>
                                <td>Exceções financeiras globais ou por owner</td>
                                <td>id, owner_id, scope, rule_key, value</td>
                            </tr>
                        </tbody>
                    </table>

                    <h3 class="dd-h3">Suporte técnico</h3>
                    <table class="dd-table">
                        <thead>
                            <tr>
                                <th>Tabela</th>
                                <th>Propósito</th>
                                <th>Colunas-chave</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td><code>support_sessions</code></td>
                                <td>Tokens de acesso temporário gerados pelo SaaS admin</td>
                                <td>id, tenant_id, token, expires_at, created_at</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </TabPanel>

            <!-- ── Tab 2: Composables ─────────────────────────────── -->
            <TabPanel header="Composables">
                <div class="dd-section">
                    <p class="dd-p">Todos os composables ficam em <code>src/features/agenda/composables/</code>. Cada um é responsável por um domínio isolado.</p>

                    <table class="dd-table">
                        <thead>
                            <tr>
                                <th>Composable</th>
                                <th>Responsabilidade</th>
                                <th>Retorna / Expõe</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td><code>useAgendaSettings</code></td>
                                <td>Carrega e persiste as configurações da agenda (horários, slots)</td>
                                <td>settings, saveSettings, loading</td>
                            </tr>
                            <tr>
                                <td><code>useAgendaEvents</code></td>
                                <td>CRUD de eventos em <code>agenda_eventos</code>; mapeia para FullCalendar</td>
                                <td>events, createEvent, updateEvent, deleteEvent, loadEvents</td>
                            </tr>
                            <tr>
                                <td><code>useRecurrence</code></td>
                                <td>Geração dinâmica de ocorrências a partir de <code>recurrence_rules</code>; split e cancel de série</td>
                                <td>rules, loadRules, createRule, splitAt, cancelFrom, exceptions</td>
                            </tr>
                            <tr>
                                <td><code>useCommitmentServices</code></td>
                                <td>CRUD dos serviços vinculados a um evento (<code>commitment_services</code>)</td>
                                <td>services, addService, removeService, updateService</td>
                            </tr>
                            <tr>
                                <td><code>useDeterminedCommitments</code></td>
                                <td>Carrega tipos de compromisso determinístico do tenant</td>
                                <td>commitments, loading, loadCommitments</td>
                            </tr>
                            <tr>
                                <td><code>useAgendaClinicStaff</code></td>
                                <td>Carrega membros do staff da clínica via <code>v_tenant_staff</code></td>
                                <td>staff, loadStaff, loading</td>
                            </tr>
                            <tr>
                                <td><code>useAgendaClinicEvents</code></td>
                                <td>CRUD de eventos da clínica (visão multi-profissional)</td>
                                <td>events, loadEvents, createEvent, updateEvent, deleteEvent</td>
                            </tr>
                            <tr>
                                <td><code>useServices</code></td>
                                <td>CRUD do catálogo de serviços do profissional</td>
                                <td>services, addService, editService, deleteService</td>
                            </tr>
                            <tr>
                                <td><code>useProfessionalPricing</code></td>
                                <td>Precificação por tipo de compromisso e convênio</td>
                                <td>pricing, loadPricing, savePricing</td>
                            </tr>
                            <tr>
                                <td><code>useInsurancePlans</code></td>
                                <td>CRUD de convênios e seus serviços cobertos</td>
                                <td>plans, addPlan, editPlan, deletePlan, planServices</td>
                            </tr>
                            <tr>
                                <td><code>usePatientDiscounts</code></td>
                                <td>Descontos individuais por paciente</td>
                                <td>discounts, addDiscount, removeDiscount</td>
                            </tr>
                            <tr>
                                <td><code>useFinancialExceptions</code></td>
                                <td>Exceções financeiras globais ou por owner</td>
                                <td>exceptions, saveException, deleteException</td>
                            </tr>
                            <tr>
                                <td><code>useFeriados</code></td>
                                <td>Carrega feriados nacionais/estaduais para bloquear slots</td>
                                <td>feriados, isHoliday, loadFeriados</td>
                            </tr>
                        </tbody>
                    </table>

                    <h3 class="dd-h3">Services / Repositories</h3>
                    <table class="dd-table">
                        <thead>
                            <tr>
                                <th>Arquivo</th>
                                <th>Propósito</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td><code>agendaRepository.js</code></td>
                                <td>Queries Supabase para terapeuta — eventos, bloqueios, configurações</td>
                            </tr>
                            <tr>
                                <td><code>agendaClinicRepository.js</code></td>
                                <td>Queries Supabase para clínica — eventos multi-profissional, staff</td>
                            </tr>
                            <tr>
                                <td><code>agendaMappers.js</code></td>
                                <td>
                                    Converte objetos do banco para formato FullCalendar.<br />
                                    <code>mapAgendaEventosToCalendarEvents()</code> · <code>buildWeeklyBreakBackgroundEvents()</code> · <code>minutesToDuration()</code>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </TabPanel>

            <!-- ── Tab 3: RPCs ────────────────────────────────────── -->
            <TabPanel header="RPCs">
                <div class="dd-section">
                    <p class="dd-p">Funções PL/pgSQL executadas via <code>supabase.rpc()</code>. Todas validam permissões server-side — sem bypass pelo frontend.</p>

                    <div class="dd-rpc-card">
                        <div class="dd-rpc-name">validate_support_session</div>
                        <div class="dd-rpc-desc">Valida um token de suporte e retorna o tenant associado. Único ponto de ativação do modo debug.</div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Parâmetros</span>
                            <code>p_token TEXT</code>
                        </div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Retorna</span>
                            <code>&#123; valid: boolean, tenant_id: uuid &#125;</code>
                        </div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Chamado em</span>
                            <code>supportDebugStore.validateAndActivate(token)</code>
                        </div>
                    </div>

                    <div class="dd-rpc-card">
                        <div class="dd-rpc-name">create_support_session</div>
                        <div class="dd-rpc-desc">Cria uma sessão de suporte com TTL. Requer role saas_admin. Valida e insere em <code>support_sessions</code>.</div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Parâmetros</span>
                            <code>p_tenant_id UUID, p_ttl_minutes INT</code>
                        </div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Retorna</span>
                            <code>&#123; token: text, expires_at: timestamptz, session_id: uuid &#125;</code>
                        </div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Chamado em</span>
                            <code>supportSessionService.createSupportSession()</code>
                        </div>
                    </div>

                    <div class="dd-rpc-card">
                        <div class="dd-rpc-name">revoke_support_session</div>
                        <div class="dd-rpc-desc">Invalida imediatamente um token de suporte, definindo <code>expires_at = now()</code>.</div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Parâmetros</span>
                            <code>p_token TEXT</code>
                        </div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Retorna</span>
                            <code>boolean</code>
                        </div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Chamado em</span>
                            <code>supportSessionService.revokeSupportSession()</code>
                        </div>
                    </div>

                    <div class="dd-rpc-card">
                        <div class="dd-rpc-name">split_recurrence_at</div>
                        <div class="dd-rpc-desc">Divide uma série recorrente em dois: encerra a original na data informada e cria uma nova regra a partir daí. Preserva exceções anteriores à divisão na regra original.</div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Parâmetros</span>
                            <code>p_rule_id UUID, p_split_date DATE</code>
                        </div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Retorna</span>
                            <code>&#123; old_rule_id: uuid, new_rule_id: uuid &#125;</code>
                        </div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Chamado em</span>
                            <code>useRecurrence.splitAt(ruleId, date)</code>
                        </div>
                    </div>

                    <div class="dd-rpc-card">
                        <div class="dd-rpc-name">cancel_recurrence_from</div>
                        <div class="dd-rpc-desc">Cancela todas as ocorrências de uma série a partir de uma data. Insere exceções do tipo <code>skip</code> para cada ocorrência futura e marca a regra como <code>cancelled</code>.</div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Parâmetros</span>
                            <code>p_rule_id UUID, p_from_date DATE</code>
                        </div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Retorna</span>
                            <code>boolean</code>
                        </div>
                        <div class="dd-rpc-row">
                            <span class="dd-rpc-label">Chamado em</span>
                            <code>useRecurrence.cancelFrom(ruleId, date)</code>
                        </div>
                    </div>
                </div>
            </TabPanel>

            <!-- ── Tab 4: Fluxos ──────────────────────────────────── -->
            <TabPanel header="Fluxos">
                <div class="dd-section">
                    <h3 class="dd-h3">1 — Criar evento simples</h3>
                    <ol class="dd-steps">
                        <li>Usuário clica num slot do FullCalendar → evento <code>dateClick</code></li>
                        <li><code>AgendaTerapeutaPage</code> abre <code>AgendaEventDialog</code> com horário pré-preenchido</li>
                        <li>Usuário preenche paciente, tipo, serviços → confirma</li>
                        <li><code>useAgendaEvents.createEvent()</code> → INSERT em <code>agenda_eventos</code></li>
                        <li>Retorno → <code>mapAgendaEventosToCalendarEvents()</code> → evento adicionado ao FullCalendar</li>
                    </ol>

                    <h3 class="dd-h3">2 — Criar recorrência</h3>
                    <ol class="dd-steps">
                        <li>No dialog do evento, usuário ativa "Repetir" e configura frequência/dias</li>
                        <li><code>useRecurrence.createRule(payload)</code> → INSERT em <code>recurrence_rules</code></li>
                        <li>Opcionalmente, serviços-template são inseridos em <code>recurrence_rule_services</code></li>
                        <li>Frontend gera ocorrências client-side a partir da regra (sem tabela de ocorrências)</li>
                        <li>Ocorrências são renderizadas como eventos "virtuais" no FullCalendar</li>
                    </ol>

                    <h3 class="dd-h3">3 — Editar ocorrência única de uma série</h3>
                    <ol class="dd-steps">
                        <li>Usuário clica em um evento recorrente → dialog pergunta: "Esta ocorrência" ou "Todas a partir daqui"</li>
                        <li><strong>Esta ocorrência:</strong> INSERT em <code>recurrence_exceptions</code> com <code>action = reschedule</code></li>
                        <li><strong>A partir daqui:</strong> chama RPC <code>split_recurrence_at</code> → cria nova regra para o trecho futuro</li>
                        <li>FullCalendar re-renderiza com as exceções aplicadas</li>
                    </ol>

                    <h3 class="dd-h3">4 — Cancelar série recorrente</h3>
                    <ol class="dd-steps">
                        <li>Usuário abre evento recorrente → "Cancelar a partir de..."</li>
                        <li>RPC <code>cancel_recurrence_from(ruleId, fromDate)</code> é chamado</li>
                        <li>Regra recebe <code>status = cancelled</code>; exceções <code>skip</code> são inseridas</li>
                        <li>Composable invalida cache local e recarrega regras</li>
                    </ol>

                    <h3 class="dd-h3">5 — Ativar modo suporte técnico</h3>
                    <ol class="dd-steps">
                        <li>SaaS admin acessa <code>/saas/support</code> e gera um token com TTL</li>
                        <li>Admin envia URL: <code>/therapist/agenda?support=TOKEN</code> para o terapeuta</li>
                        <li>Terapeuta abre a URL; <code>AgendaTerapeutaPage._initSupportMode()</code> detecta query param</li>
                        <li>RPC <code>validate_support_session(token)</code> é chamado — valida e retorna <code>tenant_id</code></li>
                        <li><code>supportDebugStore.isActive = true</code> → <code>SupportDebugBanner</code> aparece via Teleport</li>
                        <li>Todos os <code>logEvent / logAPI / logRecurrence</code> passam a ser registrados no painel</li>
                        <li>Token expira automaticamente após o TTL — sem ação do admin necessária</li>
                    </ol>

                    <h3 class="dd-h3">6 — Precificação de uma sessão</h3>
                    <ol class="dd-steps">
                        <li>Ao abrir/criar um evento, <code>useCommitmentServices</code> carrega serviços do evento</li>
                        <li><code>useProfessionalPricing</code> cruza tipo de compromisso × profissional × convênio</li>
                        <li>Se paciente tem convênio ativo, <code>useInsurancePlans</code> verifica cobertura</li>
                        <li>Se paciente tem desconto, <code>usePatientDiscounts</code> aplica sobre o valor base</li>
                        <li>Valor final é salvo em <code>commitment_services</code> no evento</li>
                    </ol>
                </div>
            </TabPanel>

            <!-- ── Tab 5: Suporte ─────────────────────────────────── -->
            <TabPanel header="Sistema de Suporte">
                <div class="dd-section">
                    <h3 class="dd-h3">Níveis de log disponíveis</h3>
                    <table class="dd-table">
                        <thead>
                            <tr>
                                <th>Nível</th>
                                <th>Helper</th>
                                <th>Quando usar</th>
                                <th>Cor no painel</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td><code>event</code></td>
                                <td><code>logEvent(source, msg, data)</code></td>
                                <td>Lifecycle, mudanças de estado gerais</td>
                                <td>Cinza</td>
                            </tr>
                            <tr>
                                <td><code>api</code></td>
                                <td><code>logAPI(source, msg, data)</code></td>
                                <td>Queries Supabase (antes e depois)</td>
                                <td>Azul</td>
                            </tr>
                            <tr>
                                <td><code>agenda</code></td>
                                <td><code>logAgenda(source, msg, data)</code></td>
                                <td>Eventos, slots, calendar renders</td>
                                <td>Roxo claro</td>
                            </tr>
                            <tr>
                                <td><code>recurrence</code></td>
                                <td><code>logRecurrence(msg, data)</code></td>
                                <td>Geração e manipulação de regras</td>
                                <td>Roxo</td>
                            </tr>
                            <tr>
                                <td><code>tenant</code></td>
                                <td><code>logTenant(source, msg, data)</code></td>
                                <td>Carregamento de sessão, role, tenant ativo</td>
                                <td>Ciano</td>
                            </tr>
                            <tr>
                                <td><code>menu</code></td>
                                <td><code>logMenu(msg, data)</code></td>
                                <td>Build e reset do menuStore</td>
                                <td>Verde limão</td>
                            </tr>
                            <tr>
                                <td><code>profile</code></td>
                                <td><code>logProfile(msg, data)</code></td>
                                <td>Perfil: carga e save de settings</td>
                                <td>Rosa</td>
                            </tr>
                            <tr>
                                <td><code>auth</code></td>
                                <td><code>logAuth(msg, data)</code></td>
                                <td>Login, logout, refresh, MFA</td>
                                <td>Laranja</td>
                            </tr>
                            <tr>
                                <td><code>guard</code></td>
                                <td><code>logGuard(msg, data)</code></td>
                                <td>Navegação via router guards</td>
                                <td>Verde</td>
                            </tr>
                            <tr>
                                <td><code>perf</code></td>
                                <td><code>logPerf(source, label)</code></td>
                                <td>Medição de performance (retorna end())</td>
                                <td>Amarelo</td>
                            </tr>
                            <tr>
                                <td><code>error</code></td>
                                <td><code>logError(source, msg, err)</code></td>
                                <td>Erros capturados em catch</td>
                                <td>Vermelho</td>
                            </tr>
                        </tbody>
                    </table>

                    <h3 class="dd-h3">Como adicionar logs a um composable</h3>
                    <pre class="dd-code">
import &#123; logAPI, logError, logPerf, logAgenda &#125; from '@/support/supportLogger'

async function loadEvents (ownerId, range) &#123;
  const end = logPerf('useAgendaEvents', 'loadEvents')
  logAPI('useAgendaEvents', 'loadEvents start', &#123; ownerId, range &#125;)

  try &#123;
    const &#123; data, error &#125; = await tenantDb().from('agenda_eventos')
      .select('*')
      .eq('owner_id', ownerId)

    if (error) throw error

    end(&#123; count: data.length &#125;)
    logAgenda('useAgendaEvents', 'eventos carregados', &#123; count: data.length &#125;)
    return data
  &#125; catch (e) &#123;
    logError('useAgendaEvents', 'loadEvents ERRO', e)
    throw e
  &#125;
&#125;</pre
                    >

                    <h3 class="dd-h3">Segurança do modo suporte</h3>
                    <ul class="dd-list dd-list--spaced">
                        <li>Token validado <strong>server-side</strong> via RPC — sem bypass pelo frontend possível</li>
                        <li>Token tem TTL máximo de 2 horas; expira automaticamente no banco</li>
                        <li>Apenas usuários com role <code>saas_admin</code> podem criar tokens (validado no RPC)</li>
                        <li>Revogar um token invalida imediatamente (<code>expires_at = now()</code>)</li>
                        <li><code>SupportDebugBanner</code> só é renderizado quando <code>supportStore.isActive === true</code></li>
                        <li>Em produção sem token válido, zero overhead — todos os <code>log*()</code> retornam imediatamente</li>
                    </ul>
                </div>
            </TabPanel>
        </TabView>
    </Dialog>
</template>

<style scoped>
.dev-docs {
    font-size: 0.85rem;
}

.dd-section {
    padding: 1.25rem 1.5rem 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* Alert */
.dd-alert {
    background: color-mix(in srgb, var(--yellow-500) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--yellow-500) 35%, transparent);
    border-left: 4px solid var(--yellow-500);
    border-radius: 8px;
    padding: 0.6rem 1rem;
    font-size: 0.82rem;
    color: var(--text-color);
}

/* Typography */
.dd-h3 {
    font-size: 0.78rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-color-secondary);
    opacity: 0.6;
    margin: 0.5rem 0 0;
}

.dd-p {
    margin: 0;
    color: var(--text-color-secondary);
    line-height: 1.6;
}

/* Tags */
.dd-tag {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 4px;
    font-size: 0.72rem;
    font-weight: 700;
    margin-right: 4px;
}
.dd-tag.blue {
    background: #dbeafe;
    color: #1d4ed8;
}
.dd-tag.purple {
    background: #ede9fe;
    color: #6d28d9;
}
.dd-tag.green {
    background: #dcfce7;
    color: #15803d;
}
.dd-tag.orange {
    background: #ffedd5;
    color: #c2410c;
}
.dd-tag.teal {
    background: #ccfbf1;
    color: #0f766e;
}
.dd-tag.red {
    background: #fee2e2;
    color: #b91c1c;
}
.dd-tag.yellow {
    background: #fef9c3;
    color: #a16207;
}

/* Dark mode tags */
:global(.app-dark) .dd-tag.blue {
    background: #1e3a5f;
    color: #93c5fd;
}
:global(.app-dark) .dd-tag.purple {
    background: #2e1065;
    color: #c4b5fd;
}
:global(.app-dark) .dd-tag.green {
    background: #14532d;
    color: #86efac;
}
:global(.app-dark) .dd-tag.orange {
    background: #431407;
    color: #fdba74;
}
:global(.app-dark) .dd-tag.teal {
    background: #042f2e;
    color: #5eead4;
}
:global(.app-dark) .dd-tag.red {
    background: #450a0a;
    color: #fca5a5;
}
:global(.app-dark) .dd-tag.yellow {
    background: #422006;
    color: #fde68a;
}

/* Grid 2 col */
.dd-grid-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
}
@media (max-width: 600px) {
    .dd-grid-2 {
        grid-template-columns: 1fr;
    }
}

/* Cards */
.dd-card {
    background: var(--surface-ground);
    border: 1px solid var(--surface-border);
    border-radius: 10px;
    padding: 0.85rem 1rem;
}
.dd-card-title {
    font-weight: 700;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-color-secondary);
    margin-bottom: 0.5rem;
}

/* Lists */
.dd-list {
    margin: 0;
    padding-left: 1.2rem;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    color: var(--text-color-secondary);
}
.dd-list--spaced {
    gap: 0.5rem;
}

/* Table */
.dd-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.8rem;
}
.dd-table th {
    text-align: left;
    padding: 0.45rem 0.75rem;
    background: var(--surface-ground);
    border-bottom: 2px solid var(--surface-border);
    font-weight: 700;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-color-secondary);
    white-space: nowrap;
}
.dd-table td {
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--surface-border);
    vertical-align: top;
    color: var(--text-color);
    line-height: 1.5;
}
.dd-table tr:hover td {
    background: var(--surface-ground);
}
.dd-table code {
    font-size: 0.78rem;
    background: var(--surface-ground);
    padding: 1px 5px;
    border-radius: 4px;
    font-family: 'JetBrains Mono', monospace;
}

/* Layers */
.dd-layers {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
}
.dd-layer {
    display: flex;
    align-items: baseline;
    gap: 1rem;
    padding: 0.6rem 1rem;
    border-radius: 8px;
    font-size: 0.82rem;
}
.dd-layer strong {
    flex-shrink: 0;
    min-width: 120px;
    font-weight: 700;
}
.dd-layer span {
    color: var(--text-color-secondary);
    font-size: 0.78rem;
}
.dd-layer--page {
    background: color-mix(in srgb, var(--primary-color) 10%, transparent);
}
.dd-layer--composable {
    background: color-mix(in srgb, var(--purple-500, #8b5cf6) 10%, transparent);
}
.dd-layer--service {
    background: color-mix(in srgb, var(--teal-500, #14b8a6) 10%, transparent);
}
.dd-layer--db {
    background: color-mix(in srgb, var(--orange-500, #f97316) 10%, transparent);
}
.dd-layer-arrow {
    text-align: center;
    color: var(--text-color-secondary);
    opacity: 0.4;
    line-height: 1.4;
    font-size: 0.75rem;
}

/* RPC cards */
.dd-rpc-card {
    background: var(--surface-ground);
    border: 1px solid var(--surface-border);
    border-left: 4px solid var(--primary-color);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.dd-rpc-name {
    font-weight: 700;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.88rem;
    color: var(--primary-color);
}
.dd-rpc-desc {
    color: var(--text-color-secondary);
    font-size: 0.8rem;
    line-height: 1.5;
}
.dd-rpc-row {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    font-size: 0.78rem;
}
.dd-rpc-label {
    font-weight: 700;
    min-width: 90px;
    color: var(--text-color-secondary);
    flex-shrink: 0;
}
.dd-rpc-row code {
    font-family: 'JetBrains Mono', monospace;
    background: var(--surface-card);
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 0.77rem;
}

/* Steps */
.dd-steps {
    margin: 0;
    padding-left: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    color: var(--text-color-secondary);
    line-height: 1.5;
}
.dd-steps code {
    background: var(--surface-ground);
    padding: 1px 5px;
    border-radius: 4px;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.77rem;
}

/* Code block */
.dd-code {
    background: #0f172a;
    color: #cbd5e1;
    border-radius: 8px;
    padding: 1rem 1.1rem;
    font-family: 'JetBrains Mono', 'Fira Code', monospace;
    font-size: 0.75rem;
    overflow-x: auto;
    white-space: pre;
    line-height: 1.6;
    margin: 0;
}
</style>
