# Mensageria — Mapeamento de Banco de Dados (v1.16)

**Documentos desta funcionalidade:** [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.16.md) (v1.16) · [03 - Protótipo](./03%20-%20Prot%C3%B3tipo%20v1.16.md) (v1.16, código em `03 - Protótipo v1.16.html`) · 04 - Mapeamento de Banco de Dados (v1.16) · [Cenários de Teste](./Cen%C3%A1rios%20de%20Teste%20v1.16.md) (v1.16) · [05 - Registro de Decisões](./05%20-%20Registro%20de%20Decis%C3%B5es%20v1.16.md) (v1.16)

Fonte primária da estrutura: Biblioteca de Schema (DDL), arquivo do schema `mensageria` do banco do cliente (`GescomClienteAlfa`), e `IpSeguranca`. O schema `mensageria` já existe na base adaptada para o Gemed 2.1; esta funcionalidade **não cria tabelas** no schema, apenas propõe um campo e um conjunto de seeds (itens 4.5 e 4.6). A base legada (`GescomZeradoPadronizacao`) não tem este schema.

Convenções: bancos indicados em cada tabela. Datas em UTC (`datetime2(0)`); a conversão para o fuso da clínica (`ClienteEmpresa.FusoHorarioOficial`, IANA) é feita na API (RN-MSG-005). Todos os ids de usuário do schema `mensageria` são `int` (o `IdUsuario` do banco do cliente), não o identificador global do usuário.

---

## 4.1 Tabelas existentes utilizadas (GescomClienteAlfa, schema `mensageria`)

### Conversa

Uma linha por conversa. Guarda o estado compartilhado (status), o remetente, o destino, o assunto, o prazo e as associações opcionais.

| Campo | Tipo | Obrig. | Uso na funcionalidade |
| --- | --- | --- | --- |
| Id | uniqueidentifier | sim (PK) | Identificador da conversa |
| IdEmpresa | int | sim | Clínica da conversa (RN-MSG-025); guarda `SegEmpresa.IdEmpresa` (Central, D-CM-069); a troca por `IdChClinica` está adiada (P-CM-052). Compõe as chaves estrangeiras |
| ConversaAnteriorId | uniqueidentifier | não | Conversa anterior, quando o sistema abre nova conversa para a mesma anomalia (RN-MSG-016) |
| OrigemTipo | nvarchar(20) | sim | `User` ou `System` |
| IdUsuarioRemetente | int | não | Preenchido quando `OrigemTipo = User`; nulo quando `System` |
| ModuloOrigem | varchar(100) | não | Preenchido quando `OrigemTipo = System`; nulo quando `User` |
| DestinoTipo | nvarchar(20) | sim | `User` ou `Team` |
| IdUsuarioDestino | int | não | Preenchido quando `DestinoTipo = User` (pode ser o próprio remetente, RN-MSG-007) |
| EquipeId | uniqueidentifier | não | Preenchido quando `DestinoTipo = Team` |
| IdPaciente | int | não | Paciente associado (RN-MSG-020) |
| ProcessoTipo | varchar(80) | não | Tipo do processo associado (RN-MSG-021); valores em 4.4 |
| ProcessoChave | varchar(200) | não | Identificador do processo no módulo de destino |
| Assunto | nvarchar(200) | sim | Assunto (RN-MSG-028 para alertas; obrigatório também para pessoas, ver E-MSG-001) |
| PrazoEmUtc | datetime2(0) | não | Prazo para resposta (RN-MSG-004) |
| GrauUrgencia | varchar(10) | não | **[PROPOSTA, coluna nova, L-09]** Grau de urgência (RN-MSG-034), valor do domínio HL7: `routine`, `urgent`, `asap` ou `stat`; nulo = Não informado. Não muda depois da criação |
| Status | nvarchar(20) | sim | `Sent`, `Read`, `Responded`, `Resolved`, `Dismissed` (RN-MSG-016) |
| UltimaSequencia | int | sim (≥ 1) | Sequência da última mensagem; base do "não lida" (RN-MSG-017) |
| CriadoEmUtc | datetime2(0) | sim | Data e hora de criação |
| AtualizadoEmUtc | datetime2(0) | sim | Última atualização (última mensagem ou mudança de estado) |
| Versao | timestamp | sim | Controle de concorrência otimista |

Restrições vigentes: destino e origem coerentes (`CK_Conversa_DestinoCampos`, `CK_Conversa_OrigemCampos`); status restrito aos cinco valores; `UltimaSequencia ≥ 1`. Índices vigentes cobrem clínica + status + atualização, paciente, equipe e conversa anterior.

**Observações de modelagem.**
- O estado "Resolvida por X em dt" é obtido da última ação `Resolve` ou `Dismiss` em `ConversaAcao` (4.1, ConversaAcao); não há campo de finalizador na `Conversa`.
- A chave de ordenação (RN-MSG-002) é calculada na consulta: o maior entre a data da última mensagem e `PrazoEmUtc`. O índice por status e atualização cobre a seleção das abertas; a ordenação final é feita sobre as conversas do usuário já filtradas.
- **Grau de urgência [PROPOSTA].** A ordenação usa o grau (nulo conta como 0; `routine` 1, `urgent` 2, `asap` 3, `stat` 4, pela `Ordem` do cadastro) antes da chave de data. O nome do grau não fica na `Conversa`: vem de `IpTerminologia.dbo.Indicadores` (`Dominio` proposto `GrauUrgencia`, `Indicador` = a chave HL7) e de `TermoTraducao`. Não há chave estrangeira entre bancos; o `CHECK` garante os valores. A imutabilidade é regra da aplicação (a API não expõe alteração); se o solicitante quiser a garantia no banco, avaliar um gatilho.

### Mensagem

| Campo | Tipo | Obrig. | Uso |
| --- | --- | --- | --- |
| Id | uniqueidentifier | sim (PK) | Identificador |
| IdEmpresa | int | sim | Clínica |
| ConversaId | uniqueidentifier | sim | Conversa (FK com remoção em cascata) |
| Sequencia | int | sim (≥ 1) | Ordem na conversa; única por conversa |
| Tipo | nvarchar(20) | sim | Só `Response` (decisão do solicitante, 26/10/2026, Log de Mudanças). O `CHECK` da Biblioteca de Schema (DDL) ainda aceita `Initial`, `Update` e `Reply`: a alteração no banco está **a aplicar**. A primeira mensagem é a de `Sequencia` = 1 e a atualização de alerta é uma mensagem com `IdUsuarioAutor` nulo e `Sequencia` > 1 |
| IdUsuarioAutor | int | não | Autor; nulo para mensagem do sistema |
| Conteudo | nvarchar(MAX) | sim | Texto da mensagem; imutável depois de gravado (RN-MSG-022) |
| CriadoEmUtc | datetime2(0) | sim | Data e hora |

Nota: o valor `Reply` ainda consta na restrição do DDL da Biblioteca, mas foi abolido pelo Log de Mudanças Estruturais do Banco de Dados (28/08/2026); a funcionalidade grava toda resposta como `Response` (RN-MSG-019). A imutabilidade (RN-MSG-022) é garantida pela API: não existe operação de edição.

### ConversaDestinatario

Cópia dos destinatários no momento do envio (RN-MSG-015).

| Campo | Tipo | Obrig. | Uso |
| --- | --- | --- | --- |
| Id | uniqueidentifier | sim (PK) | |
| IdEmpresa | int | sim | |
| ConversaId | uniqueidentifier | sim | FK com cascata |
| IdUsuario | int | sim | Destinatário; único por conversa |
| EquipeOrigemId | uniqueidentifier | não | Equipe pela qual o usuário recebeu |
| CriadoEmUtc | datetime2(0) | sim | |

Para `DestinoTipo = User`, grava-se uma linha (o destinatário, inclusive o próprio remetente). Para `Team`, grava-se uma linha por membro ativo (`EquipeMembro.RemovidoEmUtc` nulo), **inclusive o remetente quando é membro** (RN-MSG-015).

### ConversaLeitura

| Campo | Tipo | Obrig. | Uso |
| --- | --- | --- | --- |
| Id | uniqueidentifier | sim (PK) | |
| IdEmpresa, ConversaId, IdUsuario | int / uuid / int | sim | Único por (clínica, conversa, usuário) |
| UltimaSequenciaLida | int | sim (≥ 0) | Última sequência vista pelo usuário |
| LidoEmUtc | datetime2(0) | sim | |

Regra: a conversa é "não lida" para o usuário quando `Conversa.UltimaSequencia > UltimaSequenciaLida` (ou não há linha de leitura). Ao enviar, a leitura do remetente é gravada com a sequência da própria mensagem (RN-MSG-017: quem escreve já viu). [PROPOSTA]

**Aviso de lida (`readByOthers`) [PROPOSTA].** Para uma mensagem do usuário, é verdadeiro quando existe outro participante com `UltimaSequenciaLida` maior ou igual à `Sequencia` da mensagem. É calculado na consulta, sem coluna nova, e vale para o ícone `check-check` do cartão e da conversa (Especificação 2.3 e 2.8.1).

### ConversaAcao

Histórico de ações (somente inclusão).

| Campo | Tipo | Obrig. | Uso |
| --- | --- | --- | --- |
| Id | uniqueidentifier | sim (PK) | |
| IdEmpresa, ConversaId | int / uuid | sim | FK com cascata |
| MensagemId | uniqueidentifier | não | Mensagem relacionada (envio e resposta) |
| Tipo | nvarchar(20) | sim | `Send`, `Read`, `Response`, `Resolve`, `Dismiss` (e `Reply`, ver nota acima) |
| IdUsuarioAtor | int | não | Quem executou; nulo para ação do sistema |
| StatusNovo | nvarchar(20) | sim | Status resultante |
| CriadoEmUtc | datetime2(0) | sim | |

A leitura grava uma ação `Read` só quando a posição lida avança, com `StatusNovo` igual ao status atual. Esta tabela alimenta a linha "Resolvida por X em dt" e as ações visíveis ao remetente e à equipe (RN-MSG-018). Não tem campo de endereço de origem nem de módulo gerador (ver lacunas em 4.5).

### Equipe e EquipeMembro

`Equipe` (Id, IdEmpresa, Nome nvarchar(120), Ativa, datas) e `EquipeMembro` (Id, IdEmpresa, EquipeId, IdUsuario, AdicionadoEmUtc, RemovidoEmUtc). O nome da equipe que aparece junto ao autor (RN-MSG-030) vem de `ConversaDestinatario.EquipeOrigemId`, copiado no envio; como `Mensagem` só guarda o autor, a equipe é a do destinatário-membro e não muda se ele trocar de equipe depois. Somente leitura nesta funcionalidade: o cadastro pertence a outro módulo (Escopo). Membro ativo = `RemovidoEmUtc` nulo. O número de membros exibido em "Equipe X · n membros" é a contagem de membros ativos.

### AlertaPublicacao e OutboxEvento

- `AlertaPublicacao`: garante que o mesmo alerta (clínica + módulo + chave de idempotência) não gere duas conversas (RN-MSG-029). Índice único em (IdEmpresa, ModuloOrigem, ChaveIdempotencia). Também guarda a chave do envio feito por pessoa, com `ModuloOrigem = 'User'` e a chave `{IdUsuario}:{Idempotency-Key}` **[PROPOSTA]** (L-06, opção B).
- `OutboxEvento`: fila de eventos da conversa para processamento assíncrono. Uso previsto: gravar um evento a cada criação de conversa, resposta e finalização, para entrega ao painel dos participantes; a lista de tipos de evento está em aberto (P-MSG-26). O conteúdo (`PayloadJson`) leva só identificadores, nunca o texto da mensagem nem dados do paciente (RN-MSG-023). Canais externos estão fora do escopo.

## 4.2 Tabelas existentes consultadas de outros bancos

| Banco | Tabela | Uso |
| --- | --- | --- |
| GescomClienteAlfa | Paciente (dbo) | Nome do paciente exibido no cartão (nome social, quando houver, como na Central); busca de paciente no formulário |
| GescomClienteAlfa | SegUsuario (dbo) | Liga o `IdUsuario` inteiro ao identificador global do usuário |
| IpSeguranca | Usuario | Nome do usuário (e foto, quando exibida) a partir do identificador global |
| IpSeguranca | ClienteEmpresa | Fuso horário e idioma oficiais da clínica (DT-001, DT-012) |
| IpSeguranca | Processo, ProcessoDireito, DireitoProcesso | Cadastro do processo "Mensageria" e dos direitos Visualizar e Enviar (RN-MSG-024; seeds em 4.6) |
| IpSeguranca | ClientePerfilAcessoProcesso, ClientePerfilAcessoProcessoDireito | Perfil de acesso do usuário: exibição no menu e direitos por ação |
| IpSeguranca | Log, LogComplemento | Trilha de auditoria central (Evento, IpPublico, Sessao, Componente, DataHora); ver 4.5 |

A lista de destinatários é a união de: usuários da clínica com o direito Visualizar da Mensageria (inclusive o usuário logado) e equipes ativas da clínica.

## 4.3 Estados e domínios

| Domínio | Valores no banco | Valor na API | Texto (pt-BR) |
| --- | --- | --- | --- |
| Conversa.Status | Sent | sent | Aberta (enviada, ainda não lida por ninguém) |
| | Read | read | Aberta (lida) |
| | Responded | responded | Aberta (respondida) |
| | Resolved | resolved | Resolvida |
| | Dismissed | dismissed | Descartada |
| Conversa.OrigemTipo | User / System | user / system | Pessoa / Sistema |
| Conversa.DestinoTipo | User / Team | user / team | Pessoa / Equipe |
| Conversa.GrauUrgencia | `routine`, `urgent`, `asap`, `stat`; nulo = Não informado | `urgencyLevel.key`; `null` | Rotina, Urgente, Quanto antes, Imediato (`IpTerminologia.Indicadores`, domínio proposto `GrauUrgencia`) [PROPOSTA] |
| Mensagem.Tipo | Response (único) | response | Mensagem (a inicial e a atualização do sistema se distinguem pela sequência e pelo autor) |
| ConversaAcao.Tipo | Send / Read / Response / Resolve / Dismiss | — (interno) | — |

"Aberta" na interface é o conjunto `Sent`, `Read` e `Responded` (RN-MSG-001, RN-MSG-016). "Finalizada" é `Resolved` ou `Dismissed`. A API da Central do Médico usa hoje o valor `replied` para `Responded` (Especificação da Central); o valor correto é `responded`, decisão do solicitante de 27/10/2026 (D-MSG-021), e a Central deve alinhar.

## 4.4 Valores de associação a processo [PROPOSTA]

A estrutura existente (`ProcessoTipo`, `ProcessoChave`) não traz lista de valores. Proposta, a confirmar (P-MSG-07):

| ProcessoTipo | ProcessoChave | Destino do atalho |
| --- | --- | --- |
| `Paciente` | identificador do paciente | Prontuário do paciente |
| `Prescricao` | identificador da prescrição | Prescrição |
| `RegistroClinico` | identificador do registro clínico (origem proposta em 4.4.1) | Registro clínico do paciente [PROPOSTA, P-MSG-34] |
| `Documento` | identificador do documento | Documento do paciente no módulo de origem [PROPOSTA, P-MSG-34] |


Quem valida se o usuário pode abrir o processo é o módulo de destino (RN-MSG-021). **Um só tipo por conversa** (a estrutura tem um par `ProcessoTipo`/`ProcessoChave`, D-MSG-031); a lista de tipos é aberta: novos valores de `ProcessoTipo` não exigem mudança de estrutura. O processo exige paciente (a escolha é paciente, tipo e item; D-MSG-036), mas o paciente fica no campo próprio da conversa. `Agenda` saiu da lista (D-MSG-037).

### 4.4.1 Busca e exibição do item do processo (D-MSG-050)

Campos informados pelo solicitante em 29/10/2026 e 30/10/2026 (D-MSG-050, 051). O que a Biblioteca de Schema (DDL) confirma está marcado "DDL"; o restante é **[PROPOSTA]** e precisa de confirmação (P-MSG-38). Base: `GescomClienteAlfa` (legado e 2.1).

| Tipo | Busca (filtro) | Exibição | Origem (DDL) | Situação |
| --- | --- | --- | --- | --- |
| Prescrição | `Prescricao.Identificacao` (varchar(256), NOT NULL), por qualquer parte do texto (`LIKE '%termo%'`) | `Identificacao` e, como apoio, `Prescricao.[Data]` | `Prescricao` (filtro por `IdPaciente`) | DDL; apoio com a data é [PROPOSTA] |
| Documento | Nome do documento, por qualquer parte do texto | Nome e data | `PEPDocumento` (`IdPEP`→`PEP.IdPaciente`; `IdDocumento`→`DocumentoBase`) → `DocumentoVersao` (versão atual, `DocumentoBase.IdDocumentoVersaoAtual`) → `DocumentoArquivo.Nome` (varchar(128), aceita nulo) | Nome: DDL. **Data = `DocumentoArquivo.DataHoraCriacao` [PROPOSTA]**; nome nulo [PROPOSTA]: usar `PEPModeloDocumento.Nome` do `IdModelo`. Definição **provisória**: o solicitante (30/10/2026) manteve esta definição até haver clareza sobre a implementação de documentos |
| Registro clínico | Data do evento (`PronQuestionario.DataEvento`), digitada como "dd/mm" ou "dd/mm/aaaa" (parte do texto da data formatada) | Data do evento, modelo e profissional | `PronQuestionario` (filtro por `IdPaciente`); modelo: `IdQuestionario`→`Questionario.Descricao`; profissional: `IdProfissional`→`Profissional.IdChProfissional`; `Profissional.IdUsuario`→`SegUsuario.IdUsuario`; `SegUsuario.SegurancaUsuarioId`→`IpSeguranca.Usuario.Id` (a coluna guarda o `Usuario.Id` direto, sem passar por `UsuarioCliente`; D-MSG-052); exibe `Usuario.Tratamento` + `Usuario.Apelido`, e `Usuario.Nome` quando os dois forem nulos | Definido pelo solicitante (D-MSG-051, 052). A coluna foi renomeada de `SegurancaUsuarioClienteId` para `SegurancaUsuarioId` (Log de Mudanças Estruturais, 27/08/2026); a Biblioteca de Schema (DDL) ainda mostra o nome antigo, por estar desatualizada nesse ponto |
| Paciente | `Paciente.Nome` | Nome | `Paciente` | DDL |

Observações: o filtro por `IdPaciente` vale para os três tipos (RN-MSG-021); a busca ignora acentos e maiúsculas (RN-MSG-036; a collation `Latin1_General_CI_AS` já é insensível a maiúsculas, e a insensibilidade a acentos vem de `CI_AI` ou de normalização feita pela API [PROPOSTA]); o limite de 8 resultados e `hasMore` seguem 2.8.9 da Especificação. Nenhuma tabela nova nem mudança de estrutura.

## 4.5 Lacunas e propostas de mudança de estrutura [PROPOSTA]

Todas as propostas abaixo dependem de decisão do solicitante e, se aprovadas, devem ser registradas no Log de Mudanças Estruturais do Banco de Dados antes de qualquer migração.

| # | Lacuna | Requisito SBIS | Proposta | Impacto |
| --- | --- | --- | --- | --- |
| L-01 | `ConversaAcao` não registra o endereço de origem da ação | NGS1.07.05 | **Opção A (preferida):** gravar o evento também em `IpSeguranca.dbo.Log` / `LogComplemento` (que já tem `IpPublico`, `Sessao`, `Evento`, `DataHora`), sem tocar no schema `mensageria`. **Opção B:** acrescentar `IpOrigem varchar(100) NULL` a `ConversaAcao` | A: nenhum campo novo; exige o componente de auditoria transversal. B: uma coluna e migração simples |
| L-02 | Chaves estrangeiras de `ConversaAcao`, `Mensagem`, `ConversaDestinatario`, `ConversaLeitura` e `OutboxEvento` para `Conversa` usam remoção em cascata: apagar uma conversa apaga o histórico dela (mensagens e ações). Isso não apaga a trilha de auditoria central. `AlertaPublicacao` não tem cascata, então a exclusão de uma conversa de alerta falharia, e a de uma conversa de pessoa passaria | Integridade do histórico (RN-MSG-033); relacionado a NGS1.07.02 só se `ConversaAcao` for declarada parte da trilha | Proibir exclusão física de `Conversa` pela aplicação (já é a regra: nunca se exclui, só se muda o status) e restringir o direito de exclusão no banco (por exemplo, trocar a cascata por `NO ACTION` ou negar `DELETE` ao usuário da aplicação) | Mudança de FK, sem perda de dados |
| L-03 | Trilha não identifica o módulo gerador do alerta como evento de auditoria | NGS1.07.03 | `Conversa.ModuloOrigem` já guarda o módulo; basta incluí-lo no complemento do evento de auditoria (L-01) | Nenhum campo novo |
| L-04 | Não há campo para "vista pelo remetente" além de `ConversaLeitura` | — | Sem mudança: o remetente também tem linha em `ConversaLeitura` (4.1) | — |
| L-06 | O envio por pessoa não tinha onde guardar a chave de requisição (`Idempotency-Key`) | — | **Decidido (27/10/2026, opção B):** reutilizar `AlertaPublicacao` com `ModuloOrigem = 'User'`, sem hash do conteúdo. Consequência: chave repetida com texto diferente devolve a conversa antiga e ignora o texto novo. Se `AlertaPublicacao` exigir módulo e mensagem em colunas obrigatórias (`MensagemId` NOT NULL), grava-se a primeira mensagem criada | Resolvida (D-MSG-020) |
| L-07 | Não há índice por `IdUsuarioRemetente` em `Conversa`; o remetente que não é destinatário exige varredura | — | Acrescentar índice (IdEmpresa, IdUsuarioRemetente, Status) se a medição mostrar necessidade | Avaliar |
| L-08 | O `CHECK` de `Mensagem.Tipo` na Biblioteca de Schema (DDL) ainda aceita `Initial`, `Update` e `Reply`; a decisão de 26/10/2026 é aceitar só `Response`. Qualquer rotina da Mensageria que grave outro valor falha depois da alteração | — | A Mensageria grava só `Response`. Conferir os módulos de origem dos alertas (`PublishAlert`, `AppendAlertUpdate`) antes de aplicar a alteração no banco | A aplicar (Log de Mudanças) |
| L-09 | A `Conversa` não tem onde guardar o grau de urgência (RN-MSG-034); a Biblioteca de Schema (DDL) não traz coluna de urgência ou prioridade na `GescomMensageria` | — | Acrescentar `GrauUrgencia varchar(10) NULL` com `CHECK (GrauUrgencia IS NULL OR GrauUrgencia IN ('routine','urgent','asap','stat'))` na `Conversa`; sem índice novo (a ordenação é feita sobre as conversas do usuário já filtradas); registrar no Log de Mudanças Estruturais antes da migração | Coluna anulável: as conversas existentes ficam "Não informado"; a prioridade do legado não é convertida, porque a funcionalidade será descontinuada (D-MSG-042) |
| L-10 | Os quatro valores e seus nomes precisam existir em `IpTerminologia.dbo.Indicadores` e em `TermoTraducao` (três idiomas) | ECF.17.18, 17.19 | Seeds em 4.6. A Biblioteca traz só a estrutura de `Indicadores` (`Indicador`, `Dominio`, `Nome`, `Ordem`, `Caracteristica`, `Status`); valores do HL7 (D-MSG-039); o nome do domínio `GrauUrgencia` é mantido e as chaves são os termos do HL7 (D-MSG-041); falta definir a chave de `TermoTraducao` | Seeds globais |
| L-11 | **Retirada na v1.14.** O nome `SegurancaUsuarioId` já estava no banco (renomeação de 27/08/2026, no Log de Mudanças Estruturais); o aviso da v1.13 partiu da Biblioteca de Schema (DDL), que ainda traz o nome antigo `SegurancaUsuarioClienteId`. Resta só conferir que não há FK entre bancos, então o valor depende da aplicação | — | Nenhuma mudança de banco | Nenhum para a Mensageria |
| L-05 | Não há campo para data/hora de finalização na `Conversa` | — | Sem mudança: usar a ação `Resolve`/`Dismiss` mais recente em `ConversaAcao`. Se o desempenho da aba "Finalizadas" exigir, avaliar `FinalizadaEmUtc` na `Conversa` | Avaliar após medição |

## 4.6 Seeds da Funcionalidade

| Seed | Tabela(s) | Por cliente ou global? | Status | Detalhe |
| --- | --- | --- | --- | --- |
| Processo "Mensageria" (menu "Mensagens") | IpSeguranca.Processo, ClienteProcesso | Global (cadastro) e por cliente (vínculo) | [PROPOSTA] | Prefixo, rota e ícone a definir com o Menu Lateral (já existe um grupo "Mensageria" com item "Mensagens" como espaço reservado) |
| Direitos "Visualizar" e "Enviar" da Mensageria | IpSeguranca.DireitoProcesso, ProcessoDireito | Global | [PROPOSTA] | RN-MSG-024. Os valores de `Acao` e a reutilização de direitos já cadastrados devem ser conferidos no cadastro de direitos antes da criação (P-MSG-10) |
| Atribuição dos direitos aos perfis de acesso | ClientePerfilAcessoProcesso, ClientePerfilAcessoProcessoDireito | Por cliente | [PROPOSTA] | Perfis iniciais (oncologia): todos os perfis assistenciais e administrativos com Visualizar e Enviar; a definição final é do solicitante (P-MSG-10) |
| Equipes iniciais (Farmácia, Enfermagem, Recepção) | mensageria.Equipe, EquipeMembro | Por cliente | [PROPOSTA] | Exemplos citados nos fluxos; o cadastro pertence a outro módulo. Não é obrigatório para a funcionalidade |
| Textos nos três idiomas | TermoTraducao (DT-011) | Global | [PROPOSTA] | Catálogo na Especificação, item 2.9 |
| Grau de urgência: quatro valores do domínio HL7 | `IpTerminologia.dbo.Indicadores` (`Dominio` = `GrauUrgencia`, `Indicador` = `routine`, `urgent`, `asap`, `stat`; `Nome` Rotina, Urgente, Quanto antes e Imediato; `Ordem` 1 a 4; `Status` = 'A') e `TermoTraducao` (pt-BR, en-US e es-419: Rotina/Routine/Rutina; Urgente/Urgent/Urgente; Quanto antes/ASAP/Cuanto antes; Imediato/STAT/Inmediato) | Global | [PROPOSTA] | RN-MSG-034; valores do HL7 (D-MSG-039); nome do domínio `GrauUrgencia` mantido e chaves do HL7 (D-MSG-041); chave de `TermoTraducao` ainda a definir; textos em 02, item 2.9 (MSG-IND-1 a 4) |
| Parâmetro de quantidade de cartões no painel | — | — | Nenhum seed novo necessário | O painel mostra todas as conversas abertas, com rolagem própria, sem limite e sem parâmetro (D-MSG-049) |

## 4.7 Migração e impacto em dados existentes

- Nenhuma tabela nova. Se L-01 for resolvida pela Opção B, a migração é `ALTER TABLE mensageria.ConversaAcao ADD IpOrigem varchar(100) NULL` (Down: remover a coluna). As ações já gravadas ficam com o campo nulo; não há como reconstruí-lo.
- Se L-02 for aprovada, a migração troca as chaves estrangeiras por versões sem cascata; não altera dados.
- Dados atuais de teste (conversas com prazos no passado, vindas de massa de testes) não são migrados.

---

## Histórico de Versões

- **v1.0** (22/10/2026) — Criação do Mapeamento de Banco de Dados da Mensageria, a pedido do solicitante, a partir do DDL do schema `mensageria` (Biblioteca de Schema), do IpSeguranca e das decisões de 21 e 22/10/2026. Conferido: `Assunto` é obrigatório no banco (nvarchar(200)); `Reply` ainda consta nas restrições do DDL; `ConversaAcao` não tem endereço de origem; as chaves estrangeiras de `ConversaAcao` e das tabelas filhas usam remoção em cascata; `IpSeguranca.dbo.Log` tem `IpPublico`. Propostas L-01 a L-05 e seeds são [PROPOSTA] e aguardam decisão. Revisão por Dois Críticos: ver Histórico de Versões da Especificação.

- **v1.0, revisão por Dois Críticos** (22/10/2026) — Aplicados os achados do crítico técnico: referência de seção corrigida (2.9); L-02 reclassificada como integridade do histórico da conversa; novas lacunas L-06 (idempotência do envio) e L-07 (índice por remetente); uso do `OutboxEvento` e política do conteúdo; leitura e `StatusNovo`; origem do nome da equipe (RN-MSG-030).
- **v1.1** (27/10/2026) — (1) `Mensagem.Tipo` só `Response` (Log de Mudanças, 26/10/2026) e nova lacuna L-08; (2) L-06 resolvida pela opção B, com `AlertaPublicacao` e `ModuloOrigem = 'User'`; (3) `Conversa.IdEmpresa` = `SegEmpresa.IdEmpresa` (D-CM-069, P-CM-052 adiada); (4) fuso por `ClienteEmpresa.FusoHorarioOficial`; (5) `responded` confirmado como valor correto. Nenhuma tabela nova.
- **v1.2** (27/10/2026) — Descrito o cálculo do aviso de lida a partir de `ConversaLeitura` (sem coluna nova). Nenhuma tabela nova.
- **v1.3** (28/10/2026) — Grau de urgência (D-MSG-025): coluna proposta `Conversa.GrauUrgencia` com `CHECK` de 1 a 4 (L-09), seeds dos quatro níveis em `Indicadores` e `TermoTraducao` (L-10, 4.6), domínio em 4.3 e ordenação por grau em 4.1. Conferida a Biblioteca de Schema (DDL): não existe coluna de urgência ou prioridade em `GescomMensageria`. Nenhuma tabela nova.
- **v1.4** (28/10/2026) — Tipo de processo `Documento` proposto em 4.4 e regra de um só tipo por conversa (D-MSG-031); domínio `GrauUrgencia` confirmado pelo solicitante em L-10 e 4.6 (D-MSG-034); a ação `Dismiss` do sistema usa `IdUsuarioAtor` nulo, que a tabela já aceita (D-MSG-033). Nenhuma estrutura nova além da coluna proposta em L-09.
- **v1.5** (28/10/2026) — Valores de `ProcessoTipo` em 4.4: `Paciente`, `Prescricao`, `Documento`, `RegistroClinico`; `PEP` renomeado para `Paciente` e `Agenda` retirado (D-MSG-035 a 037). Sem mudança de estrutura.
- **v1.6** (28/10/2026) — Grau de urgência no domínio HL7: `Conversa.GrauUrgencia varchar(10)` com `CHECK` nos quatro valores (L-09), seeds `Routine`, `Urgent`, `ASAP`, `STAT` em `Indicadores` e `TermoTraducao` (L-10, 4.6) (D-MSG-039). As buscas de destinatário, paciente e item não criam estrutura (D-MSG-038).
- **v1.7** (29/10/2026) — Domínio `GrauUrgencia` mantido, com as chaves do HL7 (D-MSG-041); sem conversão da prioridade do legado (D-MSG-042).
- **v1.9** (29/10/2026) — Contrato do grau com o nome `urgencyLevel` (D-MSG-048); a coluna e o domínio não mudam.
- **v1.8** (29/10/2026) — Chaves do grau em minúsculas (`routine`, `urgent`, `asap`, `stat`) em `Conversa.GrauUrgencia` (`CHECK`) e em `Indicadores.Indicador`, já aplicadas no banco pelo solicitante (D-MSG-046); com collation que não diferencia caixa, o `CHECK` não impede 'STAT', e a API valida a grafia.
- **v1.10** (29/10/2026) — Painel sem limite de cartões (D-MSG-049); sem mudança de tabela.
- **v1.11** (29/10/2026) — Nova seção 4.4.1: campos de busca e exibição do item do processo por tipo (D-MSG-050), com origem na Biblioteca de Schema (DDL) e propostas marcadas (P-MSG-38). Sem mudança de estrutura.
- **v1.12** (30/10/2026) — 4.4.1: registro clínico com data do evento (`DataEvento`), modelo (`Questionario.Descricao`) e profissional (`Usuario.Tratamento` + `Usuario.Apelido`, pelo caminho `Profissional`→`SegUsuario`→`IpSeguranca`); documento mantido como provisório (D-MSG-051; P-MSG-38 em parte).
- **v1.13** (30/10/2026) — 4.4.1: `SegurancaUsuarioClienteId` aponta direto para `Usuario.Id` (D-MSG-052); nova lacuna L-11 (nome da coluna e ausência de FK entre bancos).
- **v1.14** (30/10/2026) — 4.4.1: a coluna é `SegUsuario.SegurancaUsuarioId` (renomeada em 27/08/2026, conforme o Log de Mudanças Estruturais); L-11 retirada. A versão v1.13 usou o nome antigo da Biblioteca de Schema (DDL) por não ter consultado o Log.
- **v1.15** (05/11/2026) — Sem mudança de tabela; acompanha a série (D-MSG-053).
- **v1.16** (05/11/2026) — Sem mudança de tabela; os links usam `Conversa.IdPaciente` e `ProcessoTipo`/`ProcessoChave` já mapeados (D-MSG-054).
