Agenda do Médico — Mapeamento de Banco de Dados (v1.1)
Documentos desta funcionalidade: 01 - Definição (v1.12) · 02 - Especificação (v1.14) · 03 - Protótipo (v1.12, código executável em 03 - Protótipo v1.12.html) · 04 - Mapeamento de Banco de Dados (v1.1)
SEÇÃO 4 — MAPEAMENTO DE BANCO DE DADOS
Fonte da estrutura: Biblioteca de Schema (DDL), Para IA/Biblioteca de Schema (DDL)/catalog.json. Base de referência: GescomClienteAlfa (banco já adaptado à arquitetura do Gemed 2.1) e IpSeguranca/IpTerminologia. Nenhuma tabela nova. Campos novos: o fuso IANA da clínica (Clinica.FusoHorarioOficial) e o padrão de auditoria em UnidadeAtendimento — ver “Campos novos”.
Regras do sistema aplicadas aqui:
- Exclusão lógica: um registro excluído tem
RemovidoEmpreenchido (comUsuarioIdRemovido); toda consulta ignora registros comRemovidoEmpreenchido. O campoStatuscomA/I(ativo/inativo) do legado está sendo descontinuado e não é usado como critério de “ativo” — Log de Mudanças Estruturais do Banco de Dados, 07/10/2026. - Clínicas do cliente: as clínicas que estão no mesmo banco de cliente (
ClienteBD).
Itens ainda não confirmados estão marcados [A DEFINIR] (falta um fato) ou [PROPOSTA] (decisão do Designer a confirmar); a lista consolidada está em “Pendências”, ao final.
4.1 Endpoint: GET /api/v1/agenda/doctor/day
Retorna as consultas do médico logado num dia (date), de qualquer status, de todas as clínicas do cliente (RN-AGM-002).
Tabelas envolvidas
| Tabela | Banco | Função no endpoint |
|---|---|---|
| Agenda | GescomClienteAlfa | Tabela principal — uma linha por consulta |
| Paciente | GescomClienteAlfa | Nome, nome social e o indicador de paciente reservado (filtro) |
| PacienteFoto | GescomClienteAlfa | Foto do paciente |
| PEP / PEPDiagnostico | GescomClienteAlfa | Diagnósticos oncológicos do paciente |
| ProgramaApoio / ProgramaApoioPaciente | GescomClienteAlfa | Tags do paciente (RN-AGM-006) |
| Chave | GescomClienteAlfa | Nome curto da clínica e do convênio (RN-AGM-017) |
| Clinica | GescomClienteAlfa | Fuso horário (IANA) da clínica em que o usuário entrou (RN-AGM-018) |
| UnidadeAtendimento | GescomClienteAlfa | Nome da unidade e contagem de unidades ativas para consultas (RN-AGM-017, b) |
| AgendaClassificacao / AgendaSubClassificacao | GescomClienteAlfa | Classificação e subclassificação (RN-AGM-008) |
| TermoTraducao | IpTerminologia | Rótulo traduzido do modo de atendimento |
| ClienteEmpresa | IpSeguranca | Idioma da clínica em que o usuário entrou; contagem de clínicas acessíveis |
| ClientePerfilAcessoUsuario / UsuarioCliente | IpSeguranca | Clínicas do cliente a que o médico tem acesso (RN-AGM-017, a) |
Mapa de campos
Os campos herdados da Central do Médico têm a mesma origem do endpoint GET /api/v1/cockpit/doctor/appointments (Central do Médico, Mapeamento de Banco de Dados, Seção 4.1) — referenciados, não repetidos.
| Campo | Tipo | Origem | Observação |
|---|---|---|---|
date | data | parâmetro date | Eco do dia pedido |
timeZone | string (IANA) | Clinica.FusoHorarioOficial da clínica em que o usuário entrou | Campo novo (ver “Campos novos”); ex.: America/Sao_Paulo. Como chegar da clínica do login à linha de Clinica: ver “Pendências”, item 2 |
serverNow | data/hora | relógio do servidor, convertido para timeZone | ISO 8601 com deslocamento |
appointments[].id | int | Agenda.IdAgenda | |
startTime | horário | Agenda.DhAgendaIniUTC (NULL possível na DDL), convertido para timeZone | Consulta com DhAgendaIniUTC NULL não entra na lista (não tem dia nem posição) |
endTime | horário | Agenda.DhAgendaFimUTC (NULL possível na DDL), convertido para timeZone | [PROPOSTA] Se NULL, DhAgendaIniUTC + Agenda.Tempo minutos (Tempo, numeric(4,0) NOT NULL, é a duração gravada pela Recepção); se o fim cai no dia seguinte, "24:00" (o item termina no fim do dia exibido) |
status | string | calculado — AppointmentStatus() | Central do Médico, 4.1 (“Funções de cálculo”): scheduled, waiting, checked, consultation, finished, canceled. Ver “Funções de cálculo”, abaixo, sobre precedência |
attendanceMode.code | char | Agenda.Atendimento | Domínio ModoAtendimento (Central do Médico, 4.1, “Domínios”) |
attendanceMode.label | string | Agenda.Atendimento → TermoTraducao.TermoValor | Mesma tradução da Central: Termo = Agenda.Atendimento, Origem = Indicadores|ModoAtendimento, Idioma = ClienteEmpresa.IdiomaOficial. [PROPOSTA] Sem tradução no idioma da clínica, usar a de pt-BR |
delayMinutes | int | calculado | Minutos entre agora e DhAgendaIniUTC, calculados em UTC. Positivo só quando date é hoje (em timeZone), o horário já passou, Agenda.Situacao IN ('A','V') e DhAtendimentoIniUTC IS NULL; em qualquer outro caso, 0 — inclusive canceladas |
firstTime | boolean | Agenda.PrimeiraConsulta = 'S' | Domínio S/N |
tags[].code | string | ProgramaApoio.Sigla | Texto do chip |
tags[].description | string | ProgramaApoio.Descricao | Dica e rótulo acessível |
tags[].color | string | ProgramaApoio.Cor | Hexadecimal, fundo do chip (padrão .chip-tag) |
tags (seleção) | — | ProgramaApoioPaciente (por IdPaciente) → ProgramaApoio | Filtros de RN-CM-025 (Central do Médico, 4.1): (MostrarEm & 32) = 32, vigência da tag (ProgramaApoio.DataInicio/DataFim) e da atribuição (ProgramaApoioPaciente.DataInicio/DataFim), avaliadas no dia date (RN-AGM-006), e RemovidoEm IS NULL nas duas tabelas. Tag VIP: origem [A DEFINIR] — ver “Pendências”, item 1 |
complement | string | null | Agenda.Complemento (varchar(128), NULL) | |
patient.id | int | Agenda.IdPaciente | |
patient.preferredName / legalName | string | Paciente.NomeSocial / Paciente.Nome | Central do Médico, 4.1 (lá grafado prefferedName) |
patient.photo | url | null | PacienteFoto (Padrao = 'S', a mais recente) | Central do Médico, 4.1 e “Infraestrutura de apoio” (MinIO) |
patient.diagnosis | array | PEPDiagnostico.Diagnostico, Tipo = 'O' | Central do Médico, 4.1 — todos os diagnósticos oncológicos ativos (critério de “ativo” herdado da Central) |
clinic | string | null | Agenda.IdChClinica → Chave.IdChave → Chave.Descricao | Nome curto da clínica (Clinica.IdChClinica é FK para Portador, que é FK para Chave). null quando ClinicVisible() é falso (RN-AGM-017, a). [PROPOSTA] O nome aparece mesmo que a clínica tenha sido excluída logicamente depois — a consulta aconteceu ou acontecerá ali |
unit | string | null | Agenda.IdUAtendimento (NULL possível) → UnidadeAtendimento.Descricao (varchar(30)) | null quando Agenda.IdUAtendimento é NULL ou quando UnitVisible(Agenda.IdChClinica) é falso (RN-AGM-017, b). [PROPOSTA] Quando aparece, o nome é exibido mesmo que aquela unidade tenha sido excluída depois |
insurance | string | Agenda.IdChConvenio (NOT NULL) → Chave.IdChave → Chave.Descricao | Nome curto do convênio (Convenio.IdChConvenio é FK para Portador → Chave). Sempre preenchido; o particular é um registro de Convenio com Convenio.Convenio = 'T' e aparece pelo nome curto cadastrado. O plano (Agenda.Plano, Agenda.IdPlano → ConvenioPlano) não é usado (RN-AGM-017, c) |
classification | objeto | null | — | null quando Agenda.IdAgendaClassificacao é NULL (RN-AGM-008) |
classification.name | string | Agenda.IdAgendaClassificacao → AgendaClassificacao.Descricao (varchar(20)) | Exibida mesmo que a classificação tenha sido excluída depois (mesmo raciocínio de clinic) |
classification.subName | string | null | Agenda.IdAgendaSubClassificacao (FK) → AgendaSubClassificacao.Descricao (varchar(30)) | null quando não há subclassificação |
Campos de Agenda que existem e não são usados: TipoConsulta (char(1) NOT NULL, significado não confirmado), Plano, IdPlano, IdChClinicaFat (clínica de faturamento — a tela mostra a clínica do atendimento, IdChClinica), Data/HoraIni/HoraFim (data e horário legados; a tela usa DhAgendaIniUTC/DhAgendaFimUTC, como a Central). Clinica.FusoHorario (deslocamento, legado) também não é usado — substituído por Clinica.FusoHorarioOficial.
Funções de cálculo
AppointmentStatus() — a da Central do Médico (4.1). Precedência adotada aqui [PROPOSTA], porque as condições da Central se sobrepõem num caso: Situacao = 'V' com DhAtendimentoFimUTC preenchido e DhAtendimentoIniUTC NULL casa com checked e com finished — vale finished. As condições são avaliadas nesta ordem: canceled, finished, consultation, checked, waiting, scheduled. Agenda.Situacao é NOT NULL; um código fora do domínio SituacaoAgenda não entra na lista (filtro abaixo).
ClinicVisible() — o médico tem acesso a mais de uma clínica do cliente (RN-AGM-017, a). Calculada uma vez por sessão (pode ficar em cache — consulta outro banco e não precisa ser refeita a cada atualização automática):
-- Verdadeiro quando há mais de uma clínica (ClienteEmpresa) acessível ao usuário
-- no mesmo banco do cliente (ClienteBD) da sessão — "clínicas do cliente".
SELECT CASE WHEN COUNT(DISTINCT cpau.ClienteEmpresaId) > 1 THEN 1 ELSE 0 END
FROM IpSeguranca.dbo.ClientePerfilAcessoUsuario cpau
JOIN IpSeguranca.dbo.UsuarioCliente uc ON uc.Id = cpau.UsuarioClienteId
JOIN IpSeguranca.dbo.ClienteEmpresa ce ON ce.Id = cpau.ClienteEmpresaId
WHERE uc.UsuarioId = @UsuarioId -- usuário autenticado
AND ce.ClienteBDId = @ClienteBDId -- banco do cliente da sessão
AND uc.RemovidoEm IS NULL
AND cpau.RemovidoEm IS NULL
AND ce.RemovidoEm IS NULL;Mesmo critério de “clínica acessível” do Check-in de Usuários (RN-CIU-009, Épico 1), restrito ao banco atual. Não há caso de consulta do médico numa clínica a que ele não tem acesso: o profissional só tem horário (e, portanto, agenda) nas clínicas a que está vinculado.
UnitVisible(IdChClinica) — a clínica da consulta tem mais de uma unidade ativa para consultas (RN-AGM-017, b). Calculada uma vez por clínica presente no resultado, não por consulta:
SELECT CASE WHEN COUNT(*) > 1 THEN 1 ELSE 0 END
FROM UnidadeAtendimento
WHERE IdClinica = @IdChClinica
AND StConsulta = 'S'
AND RemovidoEm IS NULL; -- campo novo nesta tabela (ver "Campos novos")Referência de tempo (RN-AGM-018)
Tudo no fuso da clínica em que o usuário entrou: serverNow, o que é “hoje”, o dia de cada consulta (filtro de date) e os horários startTime/endTime — inclusive das consultas de outras clínicas do cliente. O fuso vem de Clinica.FusoHorarioOficial (identificador IANA, ex.: America/Sao_Paulo) e é devolvido em timeZone, para a tela informar qual fuso está exibindo. A conversão de DhAgendaIniUTC/DhAgendaFimUTC é feita na aplicação (o AT TIME ZONE do SQL Server não aceita nomes IANA). Como há um só fuso por requisição, os limites do dia viram uma faixa UTC exata: @inicioUtc = 00:00 de date em timeZone, convertido para UTC; @fimUtc = 00:00 do dia seguinte, convertido.
Domínios
SituacaoAgenda (Agenda.Situacao), ModoAtendimento (Agenda.Atendimento), TipoAgenda (Agenda.TipoAgenda), TipoDiagnostico e MostrarEm: definidos uma única vez em Central do Médico, Mapeamento de Banco de Dados, 4.1 (“Domínios”) — não repetidos aqui.
Domínios usados só por esta funcionalidade:
| Campo | Valor | Significado | Fonte |
|---|---|---|---|
UnidadeAtendimento.StConsulta | S / N | Unidade atende (ou não) consultas | Solicitante; massa de teste (CargaCMZero.xlsx) |
Convenio.Convenio | T | Convênio “Particular” | Solicitante; massa de teste |
Convenio.Convenio | B | Convênio reservado (na massa de teste, usado junto com o paciente reservado) | Massa de teste |
Convenio.Convenio | NULL | Convênio comum | Massa de teste — [A DEFINIR] se há outros valores em produção |
Paciente.Paciente | B | Paciente reservado, que não representa consulta (char(1) NOT NULL) | Central do Médico, RN-CM-030; demais valores não mapeados aqui |
Clinica.FusoHorarioOficial | identificador IANA | Fuso da clínica (ex.: America/Sao_Paulo) | Solicitante — campo novo |
Filtros do endpoint
Mesmo critério de seleção do endpoint de consultas da Central do Médico (4.1), sem o filtro de “hoje” e sem o filtro de situação:
Agenda.IdChRecurso = {IdChProfissional do médico logado}— mesmo critério da Central; sem filtro por clínica (RN-AGM-002).Agenda.TipoAgenda = 'C'— agendas de consulta.Paciente.Paciente <> 'B'(viaAgenda.IdPaciente;Paciente.PacienteéNOT NULL, então o filtro não descarta pacientes comuns) — exclui registros de agenda com o paciente reservado, que não representam consulta (mesmo filtro da Central, RN-CM-030).Agenda.RemovidoEm IS NULL— exclusão lógica, regra de todo o sistema (a Central também deve aplicá-la — ver “Pendências”, item 5).Agenda.Situacao IN ('A','V','C','D','F','I','M','O','T')— todo o domínioSituacaoAgenda; canceladas (inclusive falta) entram, comstatus = canceled(RN-AGM-009/010).Agenda.DhAgendaIniUTC >= @inicioUtc AND Agenda.DhAgendaIniUTC < @fimUtc(ver “Referência de tempo”).- Tags: filtros de
MostrarEm, vigências (no diadate) e exclusão lógica (vertagsno mapa de campos). - Ordenação:
Agenda.DhAgendaIniUTCcrescente.
4.2 Endpoint: GET /api/v1/agenda/doctor/days-with-appointments
Retorna as datas, entre from e to (máximo de 62 dias), com ao menos uma consulta não cancelada do médico (marcador do calendário — RN-AGM-003).
-- @fromUtc = 00:00 de @from em timeZone, em UTC; @toUtc = 00:00 do dia seguinte a @to, em UTC.
-- A data local de cada consulta (no fuso timeZone) é calculada na aplicação a partir de DhAgendaIniUTC.
SELECT a.DhAgendaIniUTC
FROM Agenda a
JOIN Paciente p ON p.IdPaciente = a.IdPaciente
WHERE a.IdChRecurso = @IdChProfissional
AND a.TipoAgenda = 'C'
AND p.Paciente <> 'B'
AND a.RemovidoEm IS NULL
AND a.Situacao IN ('A', 'V') -- não cancelada (domínio SituacaoAgenda)
AND a.DhAgendaIniUTC >= @fromUtc AND a.DhAgendaIniUTC < @toUtc;
-- Resposta: datas distintas (no fuso timeZone), em ordem crescente.4.3 Endpoint: GET /api/v1/agenda/doctor/next-appointment-date
Retorna a data da próxima (direction = next) ou anterior (previous) consulta não cancelada do médico, a partir de from (exclusive), sem limite de horizonte (RN-AGM-003). É chamada a cada carregamento de dia e a cada atualização automática, nas duas direções — precisa ser barata.
-- next: @limiteUtc = 00:00 do dia seguinte a @from (timeZone), em UTC.
SELECT TOP 1 a.DhAgendaIniUTC
FROM Agenda a
JOIN Paciente p ON p.IdPaciente = a.IdPaciente
WHERE a.IdChRecurso = @IdChProfissional
AND a.TipoAgenda = 'C'
AND p.Paciente <> 'B'
AND a.RemovidoEm IS NULL
AND a.Situacao IN ('A', 'V')
AND a.DhAgendaIniUTC >= @limiteUtc
ORDER BY a.DhAgendaIniUTC ASC;
-- previous: @limiteUtc = 00:00 de @from, em UTC; condição DhAgendaIniUTC < @limiteUtc e ORDER BY DESC.
-- Resposta: a data local (timeZone) do resultado, ou null.4.4 Endpoint: GET /api/v1/patients/search
Mapeamento da Central do Médico, Seção 4.10 — reutilizado sem mudança (RN-AGM-014).
Campos novos
| Tabela (banco) | Campo | Tipo | Obrigatoriedade | Motivo | Status |
|---|---|---|---|---|---|
Clinica (GescomClienteAlfa) | FusoHorarioOficial | varchar(64) [PROPOSTA] (os identificadores IANA têm até ~32 caracteres) | [PROPOSTA] NOT NULL, depois de preencher as clínicas existentes | Fuso da clínica em convenção IANA (RN-AGM-018); substitui Clinica.FusoHorario (deslocamento) | Decidido pelo solicitante; migração a criar (Log de Mudanças, 07/10/2026) |
UnidadeAtendimento (GescomClienteAlfa) | 16 campos do padrão de auditoria do framework (CriadoEm … IpRemovido, inclusive RemovidoEm e UsuarioIdRemovido) | conforme framework_pattern.md (Biblioteca de Schema) | conforme o padrão | Exclusão lógica no lugar de Status A/I (regra do sistema); usado por UnitVisible() | Regra decidida pelo solicitante; migração a criar |
Migração de dados [PROPOSTA]: FusoHorarioOficial preenchido a partir do cadastro de cada clínica (o deslocamento atual não identifica o fuso IANA de forma única — ex.: −03:00 serve a vários fusos —, então o valor é informado na implantação); em UnidadeAtendimento, registros com Status = 'I' recebem RemovidoEm = data da migração.
Índices
Os campos novos da arquitetura do Gemed 2.1 precisam de índices próprios — decisão do solicitante, registrada no Log de Mudanças Estruturais do Banco de Dados (07/10/2026). Em Agenda, os índices existentes (Biblioteca de Schema — DDL) que tocam o médico ou o tipo de agenda — IX_Agenda_IdChClinica_IdChRecurso_TipoAgenda_Data, IX_Agenda_IdChClinica_IdChRecurso_IdUAtendimento_Data_Situacao, IX_Agenda_IdChClinica_TipoAgenda_Situacao_Data, IX_Agenda_Situacao_TipoAgenda, IX_Agenda_TipoAgenda, FK_Agenda_IdChRecurso — usam a data legada Agenda.Data, não DhAgendaIniUTC, e os compostos começam por IdChClinica.
Para esta funcionalidade, [PROPOSTA] índice não único IX_Agenda_IdChRecurso_TipoAgenda_DhAgendaIniUTC (IdChRecurso, TipoAgenda, DhAgendaIniUTC) INCLUDE (Situacao, IdPaciente, DhAgendaFimUTC, RemovidoEm) — atende a faixa de GET /day, days-with-appointments e o TOP 1 de next-appointment-date. A confirmar com o time de banco, junto com o impacto em escrita (a Agenda é muito gravada pela Recepção).
Auditoria (NGS1.07.03 / NGS1.07.04)
A leitura da agenda de um dia (GET /day ao carregar um dia; o polling do mesmo dia não gera novo evento) e a abertura do PEP a partir dela geram evento de auditoria (Especificação, Conformidade SBIS). O mecanismo e a tabela da trilha de auditoria são transversais ao sistema e não estão mapeados neste documento — ver “Pendências”, item 4.
Tabelas novas
Nenhuma.
Nota sobre registros de paciente reservado
O filtro Paciente.Paciente <> 'B' vem da Central do Médico (RN-CM-030). Esta funcionalidade não cria nem altera esses registros, e não tem seed para eles. A Central (congelada) ainda remete a “mecanismo e seed a detalhar na Seção 4” da Agenda do Médico — remissão que fica sem objeto e deve ser retirada da Central quando ela for descongelada.
Seeds da Funcionalidade
| Seed | Tabela(s) | Por cliente ou global? | Status | Detalhe completo |
|---|---|---|---|---|
Traduções do domínio ModoAtendimento (Presencial, Teleatendimento, Customizado) nos idiomas pt-BR, en-US e es-419 | TermoTraducao (IpTerminologia) | Global | Já usado pela Central do Médico — conferir que as três línguas existem | 4.1, campo attendanceMode.label |
| Nome curto de cada clínica e de cada convênio, inclusive “Particular” | Chave.Descricao (GescomClienteAlfa) | Por cliente | Já em produção (cadastro de clínica e convênio) | 4.1, campos clinic e insurance |
| Fuso IANA de cada clínica | Clinica.FusoHorarioOficial (GescomClienteAlfa) | Por cliente | [PROPOSTA] — campo novo; preencher na implantação de cada clínica | ”Campos novos” |
| Sigla, descrição e cor de cada tag exibida em agendas | ProgramaApoio.Sigla/Descricao/Cor (GescomClienteAlfa) | Por cliente | Cadastro existente — conferir que as tags com MostrarEm & 32 têm os três preenchidos | 4.1, campo tags |
Nenhum parâmetro novo (IpParametro/IpParametroChave): a tela não tem limiar configurável próprio.
Pendências
- [A DEFINIR] Origem da tag VIP —
Paciente.PacienteVipouProgramaApoioPaciente(achado em aberto na Central do Médico, 4.1, campotags); também define se o VIP passa pelos filtros deMostrarEme de vigência e como evitar que apareça duas vezes. - [A DEFINIR] Como chegar da clínica em que o usuário entrou (
ClienteEmpresa, IpSeguranca) à linha deClinica(GescomClienteAlfa) que temFusoHorarioOficial— não há campo que ligue as duas tabelas na DDL. Alternativa: guardar o fuso IANA também emClienteEmpresa(que já temFusoOficial, deslocamento). - [PROPOSTA] Precedência de
AppointmentStatus()(casoVcom fim sem início =finished) — a sobreposição é herdada da Central e deve ser corrigida lá também. - Trilha de auditoria (NGS1.07.03, estágio 1) — mecanismo transversal, não mapeado aqui; precisa existir para a conformidade.
- Central do Médico (congelada): aplicar
Agenda.RemovidoEm IS NULL(e a exclusão lógica nas demais tabelas que consulta) quando for descongelada. - Divergência de tipo registrada:
Agenda.IdAgendaClassificacaoéinte não tem FK, enquanto a PK deAgendaClassificacaoésmallint. O join funciona; o risco é de integridade. Registrado no Log de Mudanças Estruturais do Banco de Dados (07/10/2026). - [PROPOSTA] Tamanho e obrigatoriedade de
Clinica.FusoHorarioOficial, migração dos dados (ver “Campos novos”) e índice novo emAgenda(ver “Índices”).
Histórico de Versões
- v1.0 (07/10/2026) — Arquivo criado. Primeira versão da Seção 4, a pedido do solicitante (“podemos ir para a próxima seção”), sobre 01-Definição v1.11, 02-Especificação v1.13 e 03-Protótipo v1.11. Estrutura conferida na Biblioteca de Schema (DDL) —
Agenda,Paciente,Chave,Portador,Clinica,Convenio,UnidadeAtendimento,AgendaClassificacao,AgendaSubClassificacao(GescomClienteAlfa);ClienteEmpresa,ClientePerfilAcessoUsuario,UsuarioCliente(IpSeguranca), incluindo nulabilidade, existência deRemovidoEme índices deAgenda— e valores de exemplo na massa de testeCargaCMZero.xlsx(nomes curtos emChave,Convenio.Convenio=T/B/NULL,UnidadeAtendimento.StConsulta, duasClienteEmpresano mesmoClienteBDcom fusos diferentes). Fatos dados pelo solicitante durante a Definição v1.9–v1.10 e usados aqui: nome curto da clínica e do convênio emChave.Descricao; status também emChave.Status; plano escrito emAgenda.Plano(não usado); acesso a mais de uma clínica porClientePerfilAcessoUsuario; unidade ativa para consultas porUnidadeAtendimento.StConsulta = 'S'; particular comConvenio.Convenio = 'T'. Campos e regras herdados da Central do Médico referenciados ao Mapeamento dela (v4.48, Seção 4.1 e 4.10), sem repetição. Achado registrado:Clinica.IdChClinicaeConvenio.IdChConveniochegam aChaveviaPortador(FKs da DDL) — é esse o caminho do nome curto. - v1.0 — Revisão por Dois Críticos (07/10/2026, mesma versão, antes da entrega ao solicitante) — Crítico técnico (subagente independente, DBA/back-end) sobre esta Seção 4 e o contrato da Especificação; 14 achados, cada um conferido contra a DDL antes de aplicar. Aplicados: (1) a proposta de fuso por clínica muda o contrato de
GET /day(linha “AGORA”, rolagem e “Hoje” comparamserverNowcomstartTime) — registrado em “Referência de tempo” e na pendência 2; (2)delayMinutespositivo para canceladas — passa a exigirSituacao IN ('A','V')e sem início de atendimento, calculado em UTC; (3) SQLs de 4.2/4.3 sem a junção do fuso e sem uso de índice — reescritos com faixa UTC com folga e filtro residual, eTOP 1em 4.3; (4) vigência das tags quando o dia exibido não é hoje — pendência 4; (5) clínica escondida quando o médico tem acesso a uma só clínica mas foi agendado em outra — pendência 6;uc.RemovidoEme cache deClinicVisible(); (6) exclusão lógica — conferido na DDL:Agenda,Paciente,ProgramaApoioeProgramaApoioPacientetêmRemovidoEm;UnidadeAtendimento,Chave,Clinica,Convenioe as tabelas de classificação não têm — filtroAgenda.RemovidoEm IS NULLacrescentado; (7) tipo dos identificadores: a Especificação davauuid, o mapeamentoint— Especificação corrigida paraint(v1.13); (8)Situacaofora do domínio e sobreposição dechecked/finishedemAppointmentStatus()— filtro pelo domínio e precedência (pendência 7); (9) índice proposto ganhouIdChClinica,DhAgendaFimUTCeRemovidoEmno INCLUDE;UnitVisible()por clínica distinta; (10)endTimecomDhAgendaFimUTCNULL (a DDL permite) ou atravessando a meia-noite — regra proposta; (11) afirmações vindas só da massa de teste ou de decisão do Designer marcadas como tal (convênioB, NULL comum, valorRdo modo de atendimento, clínica/convênio/classificação inativos); (12) pendências completadas: auditoria, origem do VIP e docodedas tags, tradução ausente do modo; (13) remissão da Central ao “mecanismo e seed” na Seção 4 da Agenda tratada em nota própria;classification.nameexplicitado. Não aplicado (verificado como não procedente): risco dePaciente.PacienteNULL descartar pacientes comuns no filtro<> 'B'— a DDL definePaciente.Pacientecomochar(1) NOT NULL. - v1.1 (07/10/2026) — Respostas do solicitante às pendências da v1.0. (1) Exclusão lógica no lugar de
Status: no legado, a maioria das tabelas usaStatusA/I; a regra está sendo descontinuada e substituída porRemovidoEm/UsuarioIdRemovido, valendo para todo o sistema —UnitVisible()passa a usarRemovidoEm IS NULL, o que exige o padrão de auditoria emUnidadeAtendimento(que não o tem na DDL — nova subseção “Campos novos”); tags passam a filtrarRemovidoEmemProgramaApoioeProgramaApoioPaciente; a Central deve aplicar a regra quando descongelada; pendência do valor ativo deStatusencerrada. (2) Fuso: tudo no fuso da clínica do login — a proposta de fuso por clínica da consulta foi recusada; campo novoClinica.FusoHorarioOficial(IANA, ex.:America/Sao_Paulo), que o solicitante informou estar sendo criado para substituirClinica.FusoHorario(deslocamento);GET /daydevolvetimeZone(RN-AGM-018) e a tela informa o fuso; SQLs de 4.2/4.3 simplificados para faixa UTC exata, com a conversão na aplicação. Nova pendência: ligação entreClienteEmpresa(clínica do login) eClinica. (3) Tags:code= sigla (ProgramaApoio.Sigla),description,color; vigências no dia exibido (confirmado); origem do VIP continua indefinida, por decisão do solicitante. (4) Clínicas do cliente = mesmoClienteBD, confirmado. (5) Risco da clínica escondida retirado: o solicitante esclareceu que a Recepção não consegue agendar o médico numa clínica a que ele não está vinculado, porque ele só tem horários nas clínicas do seu vínculo. (6) Índices: registrado que os campos novos da arquitetura do Gemed 2.1 precisam de índices (Log de Mudanças, 07/10/2026). Acompanha 01-Definição v1.12, 02-Especificação v1.14 e 03-Protótipo v1.12.