# Router — AppLayout Compartilhado

**Data:** 2026-03-25
**Arquivo:** `src/router/index.js` e arquivos de rota relacionados

---

## Problema

A aplicação apresentava comportamento de "reload" ao navegar entre seções distintas (ex: de `/configuracoes/agenda` para `/therapist/agenda/recorrencias`). O efeito visual era a sidebar e a topbar piscando e sendo completamente reconstruídas — mesmo sendo o mesmo layout.

Além disso, ao clicar rapidamente para trocar de página, o Vue recarregava o componente de layout inteiro, causando lentidão perceptível.

### Causa raiz

Cada área da aplicação tinha seu **próprio registro de rota com `component: AppLayout`**:

```
/therapist    → { component: AppLayout }   ← instância A
/admin        → { component: AppLayout }   ← instância B
/configuracoes→ { component: AppLayout }   ← instância C
/account      → { component: AppLayout }   ← instância D
...
```

O Vue Router trata registros de rota distintos como componentes distintos. Ao navegar de `/configuracoes` para `/therapist`, o Vue **desmontava** a instância A e **montava** a instância B do zero — sidebar, topbar, watchers, stores, tudo reiniciava. Isso é o comportamento correto do Vue Router, mas estava sendo usado de forma incorreta para uma aplicação que tem um layout único.

---

## Solução

Consolidar todas as áreas autenticadas sob **um único registro de rota pai** com `component: AppLayout`. O Vue Router reutiliza a instância do componente pai enquanto navega entre os filhos.

### Arquitetura após a mudança

```
/ → AppLayout (instância única — nunca desmontada)
  ├── therapist/     → RouterPassthrough → página
  ├── admin/         → RouterPassthrough → página
  ├── configuracoes/ → ConfiguracoesPage → sub-página
  ├── account/       → RouterPassthrough → página
  ├── upgrade/       → RouterPassthrough → página
  ├── supervisor/    → RouterPassthrough → página
  └── features/      → RouterPassthrough → página
```

**Antes:** AppLayout era desmontado/remontado ao trocar de seção.
**Depois:** Apenas o conteúdo (área central) é trocado. AppLayout nunca desmonta.

---

## Componente RouterPassthrough

Criado em `src/layout/RouterPassthrough.vue`:

```vue
<template><router-view /></template>
```

Serve como "rota de grupo com componente" para as áreas que não têm layout intermediário próprio (therapist, admin, account etc.). Ele é necessário porque o Vue Router precisa de um componente em cada nível da hierarquia para renderizar os filhos via `<router-view>`.

---

## Arquivos alterados

### `src/router/index.js`

Antes: importava cada rota e espalhava todas no nível raiz do array de rotas.
Depois: cria um único pai `{ path: '/', component: AppLayout }` e coloca todas as rotas de app como filhas.

```js
const routes = [
    // Rotas sem layout
    ...publicRoutes,
    ...authRoutes,

    // Setup wizards (fullscreen, fora do AppLayout)
    ...therapistStandalone,
    ...clinicStandalone,

    // ─── AppLayout compartilhado ───────────────────────────
    {
        path: '/',
        component: AppLayout,
        children: [
            therapistRoutes,      // path: 'therapist'
            adminRoutes,          // path: 'admin'
            accountRoutes,        // path: 'account'
            billingRoutes,        // path: 'upgrade'
            supervisorRoutes,     // path: 'supervisor'
            featuresRoutes,       // path: 'features'
            configuracoesRoutes,  // path: 'configuracoes'
        ]
    },

    // AppLayout próprio (usuários completamente distintos)
    saasRoutes,
    editorRoutes,
    portalRoutes,

    // Catch-all (sempre por último)
    ...miscRoutes,
];
```

### `src/router/routes.therapist.js` e `routes.clinic.js`

Setup wizards (tela cheia, sem layout) foram separados como `export const therapistStandalone` / `clinicStandalone` e continuam com paths absolutos (`/therapist/setup`, `/admin/setup`).

A rota principal passou de:
```js
{ path: '/therapist', component: AppLayout, children: [...] }
```
Para:
```js
{ path: 'therapist', component: RouterPassthrough, meta: {...}, children: [...] }
```

### `src/router/routes.configs.js`

Removido o double-nesting desnecessário. Antes havia:
```js
{ path: '/configuracoes', component: AppLayout,
  children: [
    { path: '', component: ConfiguracoesPage, children: [...] }
  ]
}
```

Depois, `ConfiguracoesPage` (que já tem `<router-view>` próprio) assume diretamente:
```js
{ path: 'configuracoes', component: ConfiguracoesPage,
  redirect: { name: 'ConfiguracoesAgenda' },
  meta: { requiresAuth: true, roles: [...] },
  children: [...]
}
```

### `src/router/guards.js`

`/configuracoes` adicionado ao `isTenantArea` para garantir que o tenant e entitlements são carregados corretamente ao acessar a URL diretamente:

```js
const isTenantArea =
    to.path.startsWith('/admin') ||
    to.path.startsWith('/therapist') ||
    to.path.startsWith('/supervisor') ||
    to.path.startsWith('/configuracoes');
```

### `src/App.vue`

Mesma correção no `isTenantArea` local, que controla o `checkSetupWizard`.

---

## O que foi mantido separado (e por quê)

| Área | Motivo para manter AppLayout próprio |
|---|---|
| `/saas` | Usado exclusivamente por `saas_admin`. Nunca há navegação cruzada com áreas de tenant. |
| `/editor` | Role de plataforma distinto. Área separada. |
| `/portal` | Sessão de paciente. Usuário completamente diferente. |

Mesclar essas áreas no AppLayout compartilhado não traria ganho algum e criaria acoplamento desnecessário entre contextos de usuário distintos.

---

## Debug removido na mesma sessão

Foram removidos resquícios de código de debug que estavam ativos em produção e impactavam **todos** os usuários:

- **`router/index.js`**: `console.trace()` injetado em `router.push` e `router.replace` a cada clique de navegação (gerava stack trace completo).
- **`App.vue`**: `debugSnapshot()` disparava 3 queries Supabase (`auth.getUser`, `profiles`, `rpc.my_tenants`) a **cada troca de rota**, causando o principal sintoma de lentidão.

O sistema de suporte técnico (`supportGuard` + `supportDebugStore`) **não foi afetado** — é uma feature controlada que só ativa via `?support=TOKEN` validado no banco.

---

## Meta inheritance

O Vue Router 4 mescla automaticamente o `meta` de todos os registros de rota correspondidos (`to.matched`). Isso significa que os filhos do `RouterPassthrough` herdam o `meta` do pai sem nenhuma configuração adicional.

Exemplo: ao navegar para `/therapist/agenda`, `to.meta` conterá:
```js
{
    area: 'therapist',        // herdado do pai 'therapist'
    requiresAuth: true,       // herdado do pai 'therapist'
    roles: ['therapist'],     // herdado do pai 'therapist'
    feature: 'agenda.view'    // da própria rota 'agenda'
}
```

Os guards continuam funcionando sem nenhuma mudança de lógica.
