# Épico 5 — Menu Lateral — Mapeamento de Banco de Dados (v1.13)

**Documentos deste épico:** [01 - Definição](./01%20-%20Defini%C3%A7%C3%A3o%20v1.16.md) (v1.16) · [02 - Especificação](./02%20-%20Especifica%C3%A7%C3%A3o%20v1.15.md) (v1.15) · [03 - Protótipo](./03%20-%20Prot%C3%B3tipo%20v1.10.md) (v1.10, código executável em `03 - Protótipo v1.10.html`) · [04 - Mapeamento de Banco de Dados](./04%20-%20Mapeamento%20de%20Banco%20de%20Dados%20v1.13.md) (v1.13). Este épico faz parte do documento guarda-chuva [Check-in de Usuários](../00%20-%20Guarda-chuva%20v2.34.md).

---

## SEÇÃO 4 — MAPEAMENTO DE BANCO DE DADOS

### 4.1 Endpoint: GET /api/v1/menu

Retorna, para o usuário autenticado, a árvore de grupos e itens de menu já filtrada pelo perfil de acesso vigente na clínica atual, com a marcação de quais itens estão favoritados (02 - Especificação, "Integração com Backend").

#### Tabelas envolvidas

| Tabela | Banco | Função no endpoint |
|---|---|---|
| ClienteProcesso | IpSeguranca | Habilitação de cada `Processo` para o `ClienteBD` (tenant) do usuário — só processos habilitados entram na consulta |
| ClientePerfilAcessoUsuario | IpSeguranca | Resolve o perfil de acesso vigente do usuário na clínica atual (`RemovidoEm` nulo) |
| ClientePerfilAcesso | IpSeguranca | Perfil de acesso resolvido a partir de `ClientePerfilAcessoUsuario` |
| ClientePerfilAcessoProcesso | IpSeguranca | Liga o perfil de acesso a um `ClienteProcesso`; `ExibeMenu` e `Ordem` decidem quais itens aparecem e em que posição (RN-CIU-027). `Nome` não é usado pelo menu desde a v1.10 (ponto a rever — 01-Definição, Lista consolidada, item 3) |
| Processo | IpSeguranca | Ícone e rota de cada item de menu; `Processo` (código) é a chave da tradução do nome. `Nome` não é usado pelo menu |
| ProcessoGrupo | IpSeguranca | Posição (`Ordem`) do grupo a que um item pertence, quando existe; `Nome` é a chave da tradução do nome do grupo |
| TermoTraducao | IpTerminologia | Nome traduzido de cada item e de cada grupo, no idioma da clínica atual (DT-011) |
| ClienteUsuarioMenuFavorito | IpSeguranca | Marca quais itens estão favoritados para este usuário/perfil/clínica (RN-CIU-028) |
| ClienteEmpresa | IpSeguranca | Nome/logo da clínica atual — campo `clinicaAtual` da resposta; `IdiomaOficial` é o idioma das traduções; `ClienteBDId` leva ao Ambiente da clínica atual |
| ClienteBD | IpSeguranca | Tipo do Ambiente da clínica atual — campo `ambienteTipo` da resposta (RN-CIU-032) |

#### Mapa de campos

| Campo | Tipo | Banco | Observação |
|---|---|---|---|
| `clinicaAtual.clienteEmpresaId` | uuid | `ClienteEmpresa.Id` (uniqueidentifier) | |
| `clinicaAtual.nome` | string | `ClienteEmpresa.Nome` (varchar(50)) | |
| `clinicaAtual.caminhoLogo` | string | `ClienteEmpresa.CaminhoLogo` (varchar(100), nullable) | |
| `ambienteTipo` | string (`"producao"` \| `"homologacao"`) | `ClienteBD.Tipo` (char(1), NOT NULL) — `P` → `"producao"`, `T` → `"homologacao"`, mesma tradução do E6 | `ClienteBD` alcançado por `ClienteEmpresa.ClienteBDId` da clínica atual (FK `ClienteEmpresa_ClienteBD_FK`); domínio abaixo |
| `grupos[].processoGrupoId` | uuid | `ProcessoGrupo.Id` (uniqueidentifier) | |
| `grupos[].nome` | string | `TermoTraducao.TermoValor` (varchar(100)) com `Termo = ProcessoGrupo.Nome`, `Origem = 'ProcessoGrupo'`, `Idioma = ClienteEmpresa.IdiomaOficial` da clínica atual; sem linha, `ProcessoGrupo.Nome` (a chave) + anomalia no log | grupo só entra em `grupos` se tiver ao menos um item que passou nos filtros abaixo (RN-CIU-026); `grupos` vem ordenado por `ProcessoGrupo.Ordem` ascendente (coluna sem campo próprio na resposta) |
| `grupos[].itens[].clientePerfilAcessoProcessoId` | uuid | `ClientePerfilAcessoProcesso.Id` (uniqueidentifier) | identifica o item já resolvido para o perfil vigente — é o id usado depois pelos endpoints de favoritar (4.2/4.3) |
| `grupos[].itens[].processoId` | uuid | `Processo.Id` (uniqueidentifier) | |
| `grupos[].itens[].nome` | string | `TermoTraducao.TermoValor` (varchar(100)) com `Termo = Processo.Processo`, `Origem = 'Processo'`, `Idioma = ClienteEmpresa.IdiomaOficial` da clínica atual | nome exibido do item (RN-CIU-027, DT-011). Sem linha correspondente: vai `Processo.Processo` (a chave) e o back-end registra anomalia no log técnico (Termo, Origem, Idioma). Sem queda para outro idioma |
| `grupos[].itens[].icone` | string | `Processo.Icone` (varchar(40), nullable) | nome de ícone de lucide.dev/icons ou react-icons.github.io, nunca um arquivo próprio |
| `grupos[].itens[].rota` | string | `Processo.Rota` (varchar(128), nullable) | nula = funcionalidade ainda em construção: o front-end não navega e mostra MSG-I5-03 (EX-E5-05) |
| `grupos[].itens[].favorito` | bool | calculado | existe linha ativa (`RemovidoEm` nulo) em `ClienteUsuarioMenuFavorito` para o par (`ClientePerfilAcessoUsuarioId` do usuário/clínica atual, `ClientePerfilAcessoProcessoId` do item) |
| `itensSemGrupo[]` | mesmos 5 campos de `grupos[].itens[]` acima | `Processo.ProcessoGrupoId IS NULL` | mesma origem, apenas sem o agrupamento; ordenado como os itens dos grupos (ver Filtros); exibido acima de todos os grupos (RN-CIU-026) |
| `favoritos[]` | mesmos 5 campos, sem `favorito` (a própria presença na lista já é o favorito) | `ClienteUsuarioMenuFavorito` filtrado por `ClientePerfilAcessoUsuarioId` do usuário/clínica atual, `RemovidoEm` nulo, **com INNER JOIN nos processos liberados do perfil vigente** (ver Filtros) | ordenado pelo nome exibido (o mesmo valor de `grupos[].itens[].nome`, já traduzido), collation `SQL_Latin1_General_CP1_CI_AS` de `TermoTraducao.TermoValor` (sem distinção de maiúsculas/minúsculas, com distinção de acentos) (RN-CIU-028) |

#### Domínios

`ExibeMenu` (domínio de `ClientePerfilAcessoProcesso.ExibeMenu`, char(1), default `'S'`):

| Valor | Significado |
|---|---|
| S | Item aparece no menu para este perfil de acesso |
| N | Item habilitado para o cliente (`ClienteProcesso`) mas oculto do menu para este perfil especificamente |

`Tipo` (domínio de `ClienteBD.Tipo`, char(1), NOT NULL, sem `CHECK` no DDL):

| Valor | Significado |
|---|---|
| P | Ambiente de produção — exatamente um por Cliente |
| T | Ambiente de teste — zero ou mais por Cliente, sem distinção entre eles além de `ClienteBD.Nome`; liga a sinalização de RN-CIU-032 |

Domínio informado pelo solicitante (ver `Log de Mudanças Estruturais do Banco de Dados`, 07/10/2026). Como o DDL não tem `CHECK`, um valor fora de `P`/`T` não é impedido pelo banco, e `ClienteEmpresa.ClienteBDId` aceita NULL. **[PROPOSTA]** o endpoint devolve `"homologacao"` apenas quando o valor gravado, sem espaços e sem diferenciar maiúsculas de minúsculas, é `T`; e `"producao"` em qualquer outro caso — valor fora do domínio ou clínica atual sem `ClienteBDId` (nenhuma linha de `ClienteBD`). Nos dois casos de dado inválido, registra um aviso no log técnico do back-end (não exibido ao usuário), para que o cadastro seja corrigido. Motivo de tratar como produção: um dado inválido é erro de cadastro, e marcar como teste (e, em documentos impressos, como "sem valor") um banco que pode ser o de produção é o erro mais grave dos dois.

#### Filtros do endpoint

- `ClienteProcesso.ClienteBDId = ClienteEmpresa.ClienteBDId` da clínica atual da sessão AND `ClienteProcesso.RemovidoEm IS NULL` — apenas processos habilitados para o Ambiente da clínica atual (mesma fonte de `ambienteTipo`; um usuário pode ter vínculos em mais de um Ambiente, por isso a fonte é a clínica, não o usuário)
- `ClientePerfilAcessoUsuario` referente ao (usuário logado, `ClienteEmpresa` atual da sessão), `RemovidoEm IS NULL` — resolve o `ClientePerfilAcessoId` vigente
- `ClientePerfilAcessoProcesso.ClientePerfilAcessoId = {perfil resolvido}` AND `ExibeMenu = 'S'` AND `RemovidoEm IS NULL` — só os itens liberados para exibição no menu (RN-CIU-027)
- Ordenação dos itens dentro de cada grupo (ou da lista sem grupo): `ClientePerfilAcessoProcesso.Ordem` ascendente; itens com `Ordem` nula vêm depois, em ordem alfabética do nome exibido (RN-CIU-027). Como o nome exibido vem de `TermoTraducao` (IpTerminologia, outro banco) e pode ser a chave quando falta tradução, essa ordenação é feita na aplicação, depois da tradução, comparando sem distinção de maiúsculas/minúsculas e com distinção de acentos, como a collation `SQL_Latin1_General_CP1_CI_AS` (o mesmo critério dos favoritos)
- Grupos: `ProcessoGrupo` só entra na resposta por INNER JOIN a partir dos itens que passaram nos filtros acima — grupo sem nenhum item liberado não é devolvido (RN-CIU-026). Ordenação dos grupos: `ProcessoGrupo.Ordem` ascendente — ordem global, igual para todos os perfis (RN-CIU-026)
- `favoritos`: `ClienteUsuarioMenuFavorito.ClientePerfilAcessoUsuarioId = {vínculo usuário/perfil/clínica atual}` AND `ClienteUsuarioMenuFavorito.RemovidoEm IS NULL`, **sempre com INNER JOIN** em `ClientePerfilAcessoProcesso` (`Id = ClienteUsuarioMenuFavorito.ClientePerfilAcessoProcessoId`, `ClientePerfilAcessoId = {perfil resolvido}`, `ExibeMenu = 'S'`, `RemovidoEm IS NULL`) e daí em `ClienteProcesso` (mesmo filtro de Ambiente e `RemovidoEm IS NULL` do primeiro item desta lista) e `Processo` — os favoritos são sempre um subconjunto dos itens da árvore (RN-CIU-028). Ordenado pelo nome exibido (tradução de `TermoTraducao`, ou a chave quando falta a tradução), conforme a collation `SQL_Latin1_General_CP1_CI_AS` (Biblioteca de Schema (DDL), `IpTerminologia.sql`). Consequência do INNER JOIN: a linha de `ClienteUsuarioMenuFavorito` de um item que deixou de ser liberado não é alterada — o favorito só deixa de ser devolvido, e volta a ser devolvido se o item for liberado de novo
- Tradução de nomes (DT-011): `TermoTraducao` (IpTerminologia), chave primária (`Termo`, `Origem`, `Idioma`). Itens: `Termo = Processo.Processo`, `Origem = 'Processo'`; grupos: `Termo = ProcessoGrupo.Nome`, `Origem = 'ProcessoGrupo'`; nos dois, `Idioma = ClienteEmpresa.IdiomaOficial` da clínica atual. As colunas usam `SQL_Latin1_General_CP1_CI_AS`, então a comparação não diferencia maiúsculas de minúsculas (a carga tem `ES-419` numa linha, que casa com `es-419`). Como as tabelas estão em bancos diferentes (IpSeguranca e IpTerminologia), a junção pode ser feita na aplicação. Sem linha para o termo no idioma: o campo recebe a própria chave e o back-end registra a anomalia no log técnico com `Termo`, `Origem` e `Idioma`; não há queda para pt-BR nem para outro idioma. `Termo` passa a `varchar(128)`, o mesmo tamanho de `Processo.Processo` (ver "Alteração de tamanho decidida", abaixo)
- `ambiente`: `ClienteBD.Id = ClienteEmpresa.ClienteBDId` da clínica atual da sessão (LEFT JOIN) — no máximo uma linha; sem linha, `ambienteTipo = "producao"` (ver Domínio acima)

---

### 4.2 Endpoint: POST /api/v1/menu/items/{clientePerfilAcessoProcessoId}/favorite

Favorita um item do menu para o usuário autenticado, na clínica atual (02 - Especificação, "Integração com Backend").

#### Tabelas envolvidas

| Tabela | Banco | Função no endpoint |
|---|---|---|
| ClientePerfilAcessoProcesso | IpSeguranca | Valida que o item existe, pertence ao perfil de acesso vigente e está com `ExibeMenu = 'S'` — senão 404 |
| ClienteUsuarioMenuFavorito | IpSeguranca | Insere (ou reativa, se já existia com `RemovidoEm` preenchido — RN-CIU-005) a linha do par usuário/item |

#### Mapa de campos

| Campo | Tipo | Banco | Observação |
|---|---|---|---|
| `clientePerfilAcessoProcessoId` (path) | uuid | `ClienteUsuarioMenuFavorito.ClientePerfilAcessoProcessoId` (uniqueidentifier) | metade da PK composta |
| — | — | `ClienteUsuarioMenuFavorito.ClientePerfilAcessoUsuarioId` (uniqueidentifier) | outra metade da PK composta — resolvido do usuário/clínica atual da sessão, não vem no request |
| `favorito` (response) | bool | fixo `true` | |

#### Filtros do endpoint

- Valida que `clientePerfilAcessoProcessoId` pertence ao perfil de acesso vigente do usuário na clínica atual, com `ExibeMenu = 'S'` (mesmo filtro do GET, 4.1) — senão 404
- Exclusão lógica (RN-CIU-005, transversal): se já existe uma linha para o par com `RemovidoEm` preenchido, o INSERT vira UPDATE limpando `RemovidoEm`, em vez de criar uma segunda linha — a PK composta (`ClientePerfilAcessoUsuarioId`, `ClientePerfilAcessoProcessoId`) não permite duplicidade

---

### 4.3 Endpoint: DELETE /api/v1/menu/items/{clientePerfilAcessoProcessoId}/favorite

Desfavorita um item do menu para o usuário autenticado, na clínica atual (02 - Especificação, "Integração com Backend").

#### Tabelas envolvidas

| Tabela | Banco | Função no endpoint |
|---|---|---|
| ClienteUsuarioMenuFavorito | IpSeguranca | Exclusão lógica (`RemovidoEm`) da linha do par usuário/item |

#### Mapa de campos

| Campo | Tipo | Banco | Observação |
|---|---|---|---|
| `clientePerfilAcessoProcessoId` (path) | uuid | `ClienteUsuarioMenuFavorito.ClientePerfilAcessoProcessoId` (uniqueidentifier) | junto de `ClientePerfilAcessoUsuarioId` (resolvido da sessão), identifica a linha a remover |
| `favorito` (response) | bool | fixo `false` | |

#### Filtros do endpoint

- `ClienteUsuarioMenuFavorito.ClientePerfilAcessoUsuarioId = {vínculo usuário/perfil/clínica atual}` AND `ClientePerfilAcessoProcessoId = {path}` AND `RemovidoEm IS NULL` — 404 se não existia favoritado
- Exclusão lógica (RN-CIU-005, transversal): marca `RemovidoEm`, nunca remove a linha fisicamente

---

### Tabelas existentes utilizadas (consolidado)

Consolidado por tabela, como referência rápida — o detalhamento de campos e uso já está nas seções de endpoint acima (4.1 a 4.3), não repetido aqui (Lição #10 da Skill Designer).

| Tabela | Banco | Endpoints que usam |
|---|---|---|
| Processo | IpSeguranca | 4.1 |
| ProcessoGrupo | IpSeguranca | 4.1 |
| ClienteProcesso | IpSeguranca | 4.1 |
| ClientePerfilAcesso | IpSeguranca | 4.1 |
| ClientePerfilAcessoUsuario | IpSeguranca | 4.1 |
| ClientePerfilAcessoProcesso | IpSeguranca | 4.1, 4.2 |
| ClienteUsuarioMenuFavorito | IpSeguranca | 4.1, 4.2, 4.3 |
| ClienteEmpresa | IpSeguranca | 4.1 |
| ClienteBD | IpSeguranca | 4.1 |
| TermoTraducao | IpTerminologia | 4.1 |

Nenhuma tabela nova. Toda a estrutura necessária — itens de menu, agrupamento, habilitação por cliente, liberação e ordem por perfil de acesso, favoritos, a identificação da clínica no cabeçalho do menu e o tipo de Ambiente da clínica atual — já existe em produção no banco IpSeguranca. Tipos e nullability confirmados na Biblioteca de Schema (DDL), `IpSeguranca.sql`, nesta versão (16/09/2026).

**Separação de bancos:** todas as tabelas utilizadas por este épico pertencem ao banco IpSeguranca, exceto `TermoTraducao`, do IpTerminologia (traduções).

### Schema legado identificado e descartado

O banco de template `GescomZeradoPadronizacao` (mesmo arquivo de origem da Biblioteca de Schema) tem uma estrutura equivalente e mais antiga para menu: `SegMenu`, `SegPastaMenu`, `SegMenuGrupo` e `SegMenuDetalhe` — esta última com um campo `PaginaInicial` que corresponde, na estrutura legada, ao mesmo papel do campo `ProcessoAbertura` de `ClienteUsuarioMenuFavorito` na estrutura atual — correspondência que ajudou a localizar o campo, com o significado hoje confirmado na Seção 1 (RN-CIU-028).

Essa estrutura legada foi identificada e descartada em favor do schema moderno acima: pertence ao banco de template pré-Clean-Architecture, chaveado por identificadores numéricos locais (`smallint`) em vez de `uniqueidentifier`, e não tem nenhum dos conceitos centrais da arquitetura atual — não existe `Cliente`, `ClienteBD` (banco por tenant) nem `ClienteEmpresa` (clínica) na cadeia de chaves de `SegMenuDetalhe`, apenas um `IdUsuario` local. Não é uma base compatível com o modelo multi-tenant deste projeto.

### Campo existente fora da Biblioteca de Schema: `ProcessoGrupo.Ordem`

A carga `CargaSegGlobal.xlsx` (19/10/2026) traz `ProcessoGrupo.Ordem` (valores inteiros: Assistencial 1, PEP 2, Recepção 3, Faturamento 4, Financeiro 5, Configurações 6, Gestão do sistema 7, Gestão dos clientes 8), coluna que não aparece na Biblioteca de Schema (DDL) extraída em 28/08/2026 (lá, `ProcessoGrupo` tem só `Id` e `Nome`). Registrada como estrutura existente, por decisão do solicitante, e usada para ordenar os grupos do menu (RN-CIU-026). Tipo exato e nullability a confirmar na próxima extração da DDL. Ver `Log de Mudanças Estruturais do Banco de Dados`, entrada de 19/10/2026.

### Campo novo proposto: `ClientePerfilAcessoUsuario.CodProfissional`

> Título mantido por histórico: o campo já foi criado (ver "Migração" abaixo).

A Seção 1 (RN-CIU-028) documenta que, na ausência de uma escolha manual de tela inicial, a tela inicial padrão do usuário é seu próprio cockpit, quando seu perfil de acesso tiver um indicado. Esse indicador não existe hoje em nenhuma base consultada (Biblioteca de Schema (DDL) nem `EsquemaGemed21.csv` — checado em 15/09/2026, reconfirmado em 16/09/2026) — confirmado pelo solicitante como campo novo a criar:

|Campo|Tabela|Tipo|Obrigatoriedade|Valor padrão|Descrição|
|---|---|---|---|---|---|
|`CodProfissional`|`ClientePerfilAcessoUsuario` (IpSeguranca)|`char(3)`|Nullable — confirmado pelo solicitante; ausência de código é o que produz "sem tela inicial" (RN-CIU-028) quando também não há escolha manual|Sem valor padrão (NULL)|Código do tipo de cockpit/central padrão do usuário nessa combinação perfil × clínica — determina qual cockpit abre como tela inicial na ausência de uma escolha manual de tela inicial (RN-CIU-028). Nome, tabela, tipo, nullability e domínio de valores confirmados pelo solicitante. Domínio: `MED`, `ENF`, `FAR`, `REC`, `ADM`, `BKO` — cada valor aponta para a central (cockpit) correspondente; `MED`/`ENF`/`FAR`/`BKO` correspondem aos fluxos por profissional já documentados no projeto (médico, enfermagem, farmácia, backoffice), `REC`/`ADM` apontam para centrais ainda não especificadas em nenhum épico consultado até aqui.|

Migração: `ALTER TABLE IPSeguranca.dbo.ClientePerfilAcessoUsuario ADD CodProfissional char(3) NULL` — **aplicada** (a carga `CargaSegGlobal.xlsx`, de 19/10/2026, já traz o campo preenchido com `MED`, `ENF` e `FAR`; registrado como aplicado por decisão do solicitante). A Biblioteca de Schema (DDL), extraída em 28/08/2026, ainda não mostra o campo — precisa de nova extração. Ver `Log de Mudanças Estruturais do Banco de Dados`, entradas de 15/09/2026 e 19/10/2026.

Nota: este campo não é consultado por nenhum dos 3 endpoints deste épico (4.1 a 4.3) — a resolução de tela inicial por `CodProfissional` acontece no roteamento pós-login (E1), não na montagem do menu em si. Permanece documentado aqui, e não numa seção de endpoint, por ser um achado de estrutura do épico como um todo.

### Alteração de tamanho decidida: `TermoTraducao.Termo`

`IpTerminologia.TermoTraducao.Termo` passa de `varchar(35)` para `varchar(128)` (decisão do solicitante, 21/10/2026), para caber qualquer `Processo.Processo` (`varchar(128)`), que é a chave da tradução do nome do item. `ProcessoGrupo.Nome` (`varchar(20)`) já cabia. A coluna faz parte da chave primária (`Termo`, `Origem`, `Idioma`), que precisa ser derrubada e recriada na alteração. **Aplicada no banco** (informado pelo solicitante em 21/10/2026); a Biblioteca de Schema (DDL) de 28/08/2026 ainda mostra `varchar(35)` até a próxima extração. Registrado no Log de Mudanças Estruturais do Banco de Dados (21/10/2026).

### Seeds da Funcionalidade

|Seed|Tabela(s)|Por cliente ou global?|Status|Detalhe completo|
|---|---|---|---|---|
|Item de menu "Suporte Gemed" (link externo à aplicação de suporte técnico da Interprocess TI)|Processo (mais ClienteProcesso e ClientePerfilAcessoProcesso, por cliente/perfil, para habilitá-lo)|Global o cadastro do Processo; a habilitação por cliente e perfil de acesso é individual|**[PROPOSTA]** — item de exemplo, existência e nome exatos a confirmar contra o mockup original do menu, hoje indisponível|01 - Definição, "Lista consolidada de itens [PROPOSTA]", item 2|
|Árvore completa de grupos e itens do menu (quais Processo existem, em quais ProcessoGrupo, com quais ícones e rotas)|Processo, ProcessoGrupo, ClienteProcesso, ClientePerfilAcessoProcesso|Processo/ProcessoGrupo globais; ClienteProcesso e ClientePerfilAcessoProcesso por cliente/perfil|**[PROPOSTA]** — pendente de um levantamento de produto que substitua o mockup perdido; sem essa árvore, nenhum cliente novo tem menu funcional além dos módulos já especificados individualmente (Central do Médico/Cockpit, Agenda do Médico)|01 - Definição, "Lista consolidada de itens [PROPOSTA]", item 1|

Nenhum parâmetro de configuração (`IpParametro`/`IpParametroChave` ou equivalente) é necessário para esta funcionalidade — o comportamento do menu (filtragem, favoritos, busca, responsividade) não depende de nenhum valor configurável por cliente além da própria estrutura de `Processo`/`ClientePerfilAcessoProcesso` já listada acima.

---

## Histórico de Versões

- **v1.0** (15/09/2026) — versão inicial do épico. Estrutura de dados localizada por completo na Biblioteca de Schema (DDL), banco IpSeguranca — nenhuma tabela nova. Schema legado equivalente (`GescomZeradoPadronizacao.dbo.SegMenu`/`SegPastaMenu`/`SegMenuGrupo`/`SegMenuDetalhe`) identificado e descartado, com a correspondência de `SegMenuDetalhe.PaginaInicial` registrada como base da interpretação [PROPOSTA] de `ClienteUsuarioMenuFavorito.ProcessoAbertura`. Dois seeds registrados como [PROPOSTA] — item "Suporte Gemed" e a árvore completa de grupos/itens do menu, ambos pendentes do mockup original perdido.
- **v1.1** (15/09/2026) — `ClienteUsuarioMenuFavorito.ProcessoAbertura` deixa de ser [PROPOSTA]: confirmado como o indicador da escolha do usuário de tela inicial do sistema (RN-CIU-028), sobrepondo o cockpit padrão quando presente. Novo achado: o campo que identifica o cockpit padrão do usuário em `ClientePerfilAcessoUsuario`, citado pelo solicitante, não foi localizado na Biblioteca de Schema (DDL) nem no `EsquemaGemed21.csv` — registrado como pendência técnica nesta seção e no `Log de Mudanças Estruturais do Banco de Dados`.
- **v1.2** (15/09/2026) — confirmada pelo solicitante a criação de `ClientePerfilAcessoUsuario.CodProfissional`, `char(3)` — a pendência técnica anterior (campo não localizado) vira proposta de estrutura: nova subseção "Campo novo proposto" substitui "Pendência técnica: campo do cockpit padrão", com a migração sugerida. Nullability e domínio de valores do campo seguem [PROPOSTA], não confirmados pelo solicitante. `Log de Mudanças Estruturais do Banco de Dados` atualizado.
- **v1.3** (15/09/2026) — confirmados pelo solicitante os dois atributos de `CodProfissional` que seguiam [PROPOSTA]: nullable; domínio `MED`, `ENF`, `FAR`, `REC`, `ADM`, `BKO` (cada código aponta para a central/cockpit correspondente). Tabela de especificação do campo e migração sugerida atualizadas para refletir a estrutura confirmada — só a execução real da migração no banco segue pendente. `Log de Mudanças Estruturais do Banco de Dados` atualizado.
- **v1.4** (15/09/2026) — pedido do solicitante ao revisar o protótipo: `ClienteEmpresa` passa de "não consultada para montar o menu" para efetivamente consultada — `Nome` e `CaminhoLogo` alimentam o novo campo `clinicaAtual` (**[PROPOSTA]**) da resposta de `GET /api/v1/menu`, para o cabeçalho do menu exibir o nome da clínica atual (Seção 2, "Cabeçalho do Menu"). Mesmos campos de `ClienteEmpresa` já usados por E3/E6 para nome/logo de clínica — nenhuma estrutura nova, nenhuma tabela nova.
- **v1.5** (16/09/2026) — Reestruturação da Seção 4, a pedido do solicitante: a antiga tabela única "Tabelas existentes utilizadas" foi substituída por 3 subseções por endpoint (4.1 `GET /api/v1/menu`, 4.2 `POST .../favorite`, 4.3 `DELETE .../favorite`), cada uma com Tabelas envolvidas, Mapa de campos, Domínios (quando aplicável) e Filtros do endpoint — mesmo padrão (mais detalhado) já usado em Central do Médico (Cockpit) e Agenda do Médico, escolhido pelo solicitante em vez do padrão mais leve usado até então neste próprio épico e no E6 (uma linha "Tabelas envolvidas" dentro do endpoint, na Seção 2). Tipos de campo (`uniqueidentifier`, `varchar(N)`, `char(1)`, `tinyint`) confirmados na Biblioteca de Schema (DDL), `IpSeguranca.sql`, nesta versão. A tabela consolidada por tabela foi mantida, ao final, como referência rápida, sem repetir o detalhamento já dado por endpoint (Lição #10). "Schema legado identificado e descartado", "Campo novo proposto: CodProfissional" e "Seeds da Funcionalidade" preservados sem alteração de conteúdo. Nenhuma tabela nova, nenhuma mudança de estrutura de dados — reorganização documental. Em consequência, a Seção 2 (02 - Especificação, v1.5) teve as linhas inline "Tabelas envolvidas: ..." de cada endpoint removidas, substituídas por uma nota única apontando para esta Seção 4 — mesma convenção de Central do Médico/Agenda do Médico, evitando repetir a mesma informação em dois lugares (Lição #10).
- **v1.6** (07/10/2026) — `ClienteBD` passa a ser consultada por `GET /api/v1/menu` (4.1): `ClienteBD.Tipo`, alcançado por `ClienteEmpresa.ClienteBDId` da clínica atual, alimenta o novo campo `ambienteTipo` (**[PROPOSTA]**, 02 - Especificação v1.6), que liga a sinalização de Ambiente de teste (RN-CIU-032, guarda-chuva v2.26). Domínio de `ClienteBD.Tipo` informado pelo solicitante: `P` (produção, único por Cliente) e `T` (teste, vários, distinguidos só pelo nome) — registrado em `Log de Mudanças Estruturais do Banco de Dados`, 07/10/2026; o DDL segue sem `CHECK`; o tratamento de um valor fora do domínio (devolvido como `"producao"`) é escolha do Designer, marcada **[PROPOSTA]** no Domínio de 4.1. FK `ClienteEmpresa_ClienteBD_FK` e tipo `char(1) NOT NULL` conferidos na Biblioteca de Schema (DDL), `IpSeguranca.sql`. Nenhuma tabela nova, nenhum campo novo; nenhum seed novo ("Seeds da Funcionalidade" inalterada).
  **Revisão por Dois Críticos** (crítico técnico, subagente independente, mesma sessão; achados conferidos contra o DDL antes de aplicar): `ClienteEmpresa.ClienteBDId` é NULL no DDL — o mapeamento dizia "uma linha só" sem tratar a ausência de `ClienteBD`; passa a LEFT JOIN, com `"producao"` e aviso em log quando não há linha (**[PROPOSTA]**); a comparação com `T` ignora espaços e maiúsculas, e valor fora do domínio também gera aviso em log; o filtro de `ClienteProcesso` dizia "ClienteBD do usuário autenticado", ambíguo para quem tem vínculos em mais de um Ambiente — passa a ser o Ambiente da clínica atual, a mesma fonte de `ambienteTipo`. Não corrigido: "Tipos e nullability confirmados ... nesta versão (16/09/2026)" na seção consolidada, frase anterior a esta versão.
- **v1.7** (07/10/2026) — acompanha 01 - Definição v1.9 (decisões do solicitante). 4.1: `favoritos` passa a fazer, sempre, INNER JOIN com os processos liberados do perfil vigente (`ClientePerfilAcessoProcesso` com `ExibeMenu = 'S'` e `RemovidoEm` nulo, `ClienteProcesso` do Ambiente da clínica atual com `RemovidoEm` nulo, `Processo`) — corrige a falha apontada pelo Cenários de Teste (CT-E5-FAV-14): até a v1.6, o filtro de favoritos usava só `ClientePerfilAcessoUsuarioId` + `RemovidoEm`, e um favorito de item retirado do perfil continuaria sendo devolvido. Grupos passam a entrar só por INNER JOIN a partir dos itens liberados (grupo sem item não aparece). Ordenação de `favoritos` documentada com a collation real de `Processo.Nome` (`SQL_Latin1_General_CP1_CI_AS`, conferida na Biblioteca de Schema (DDL) nesta versão). Nenhuma tabela, campo ou endpoint novo; 4.2 e 4.3 inalterados (o `DELETE` continua aceitando desfavoritar um item já não liberado, porque não filtra por `ExibeMenu`).
- **v1.8** (19/10/2026) — acompanha 01 - Definição v1.11 (decisões do solicitante ao analisar `CargaSegGlobal.xlsx`). 4.1: o nome do item passa a ser `ClientePerfilAcessoProcesso.Nome` quando preenchido, senão `Processo.Nome` — até a v1.7 era só `Processo.Nome`, mas a carga mostra os dois nomes diferentes para o mesmo item (ex.: "Agenda de Consultas" × "Agenda do Médico") e `Processo.Nome` vazio para alguns processos; a ordem dos favoritos usa o mesmo nome. Grupos ordenados por `ProcessoGrupo.Ordem` — coluna presente na carga e ausente da Biblioteca de Schema (DDL) de 28/08/2026, nova subseção "Campo existente fora da Biblioteca de Schema". `CodProfissional` registrado como migração aplicada (a carga já traz o campo). Nenhuma tabela nova. `Log de Mudanças Estruturais do Banco de Dados` atualizado.
- **v1.9** (20/10/2026) — acompanha 01 - Definição v1.12: notas de mapa de campos para `rota` nula (funcionalidade em construção, EX-E5-05) e para a posição de `itensSemGrupo` (acima dos grupos, ordenados por `ClientePerfilAcessoProcesso.Ordem`). Nenhuma mudança de tabela, campo ou filtro.
- **v1.10** (20/10/2026) — acompanha 01 - Definição v1.14 (retificação do solicitante): o nome de item e de grupo de `GET /api/v1/menu` vem de `TermoTraducao` (IpTerminologia) — `Termo = Processo.Processo` / `ProcessoGrupo.Nome`, `Origem = 'Processo'` / `'ProcessoGrupo'`, `Idioma = ClienteEmpresa.IdiomaOficial` da clínica atual; sem tradução, vai a chave e o back-end registra anomalia (DT-011). `ClientePerfilAcessoProcesso.Nome` e `Processo.Nome` deixam de ser usados pelo menu. Nova tabela utilizada (existente): `TermoTraducao`. Achado: `Termo` (varchar(35)) é menor que `Processo.Processo` (varchar(128)).
- **v1.11** (21/10/2026) — Decisão do solicitante: `TermoTraducao.Termo` passa a `varchar(128)`. Retirado dos Filtros o aviso de que códigos de processo com mais de 35 caracteres não teriam tradução; nova subseção "Alteração de tamanho decidida: `TermoTraducao.Termo`"; entrada no Log de Mudanças (21/10/2026). Sem mudança de contrato. Acompanha 02-Especificação v1.13 e Cenários de Teste v1.8.
- **v1.12** (21/10/2026) — acompanha 01 - Definição v1.15: ordenação de item com `ClientePerfilAcessoProcesso.Ordem` nula — alfabética pelo nome exibido, depois dos itens com ordem (**[PROPOSTA]** quanto à posição), feita na aplicação depois da tradução (Filtros; `itensSemGrupo` passa a remeter a eles). `TermoTraducao.Termo` em `varchar(128)` registrado como aplicado no banco. Sem mudança de contrato.
- **v1.13** (22/10/2026) — acompanha 01 - Definição v1.16: posição dos itens com `Ordem` nula (depois dos ordenados) aprovada pelo solicitante; sai a marca [PROPOSTA] dos Filtros. Sem mudança de contrato nem de schema.
