Central do Médico (Cockpit) — Mapeamento de Banco de Dados (v4.28)
Documentos desta funcionalidade: 01 - Definição (v4.26) · 02 - Especificação (v4.25) · 03 - Protótipo (v3.13, código executável em 03 - Protótipo v3.13.html) · 04 - Mapeamento de Banco de Dados (v4.28)
SEÇÃO 4 — MAPEAMENTO DE BANCO DE DADOS
4.1 Endpoint: GET /api/v1/cockpit/doctor/appointments
Retorna a lista de consultas do médico logado para o dia atual.
Tabelas envolvidas
| Tabela | Banco | Função no endpoint |
|---|---|---|
| Agenda | GescomClienteAlfa | Tabela principal — dados da agenda |
| Paciente | GescomClienteAlfa | Dados do paciente (nome, nome social) |
| PacienteFoto | GescomClienteAlfa | Foto do paciente |
| PEPDiagnostico | GescomClienteAlfa | Diagnóstico oncológico do paciente |
| TermoTraducao | IpTerminologia | Tradução do modo de atendimento |
| ClienteEmpresa | IpSeguranca | Idioma e fuso horário da clínica |
Mapa de campos
| Campo | Tipo | Banco | Observação |
|---|---|---|---|
id | int | Agenda.IdAgenda | |
startTime | horário | Agenda.DhAgendaIniUTC | só horário, convertido para o fuso e idioma da clínica |
endTime | horário | Agenda.DhAgendaFimUTC | só horário, convertido para o fuso e idioma da clínica |
status | string | calculado | vide AppointmentStatus() |
type | string | Agenda.Atendimento -> TermoTraducao.TermoValor | Termo = Agenda.Atendimento, Origem=“Indicadores |
firstTime | char | Agenda.PrimeiraConsulta | domínio = ‘S’=sim, ‘N’=não |
delayMinutes | int | Now(no fuso da clínica)-Agenda.DhAgendaIniUTC(no fuso da clínica) | Se o valor for negativo (horário previsto ainda não chegou), retorna 0 — só é positivo quando o horário previsto já passou e a consulta não foi iniciada |
patient.id | int | Agenda.IdPaciente | |
patient.prefferedName | string | Paciente.NomeSocial | se existir, usar este como nome principal |
patient.legalName | string | Paciente.Nome | se NomeSocial não existir, usar este como nome |
patient.photo | url | PacienteFoto.NomeArquivo, busca IdPaciente e Padrao = ‘S’, se multiplos, retorna o mais recente | url gerada pelo MinIO |
patient.diagnosis | array de string | PEPDiagnostico.Diagnostico para Tipo = ‘O’ e PEP.IdPaciente | retorna TODOS os diagnósticos oncológicos ativos do paciente (não só um) — o card exibe a lista completa |
tags | array de string | Paciente.PacienteVip (bit=1 → tag vip) UNION ProgramaApoioPaciente filtrado por IdPaciente (ativo quando DataInicio <= hoje e DataFim IS NULL ou DataFim >= hoje) join ProgramaApoio (Nome/Sigla/Cor) | Cor de cada tag vem de ProgramaApoio.Cor (exceto vip, que usa o token de destaque do Design System, Seção 2.8). Consultado no EsquemaGemed21.csv: ProgramaApoioPaciente/ProgramaApoio existem; PEPProgramaApoioPaciente (vínculo por PEP, em vez de por paciente) existe mas não é usado aqui — as tags do Cockpit são no nível do paciente, não do atendimento. |
Funções de cálculo
AppointmentStatus() — calcula o status da consulta a partir dos campos da Agenda:
| Status retornado | Condição |
|---|---|
scheduled (Agendado) | Agenda.Situacao = ‘A’ AND DhChegadaUTC IS NULL |
waiting (Aguardando recepção) | Agenda.Situacao = ‘A’ AND DhChegadaUTC IS NOT NULL |
checked (Recepcionado) | Agenda.Situacao = ‘V’ AND DhAtendimentoIniUTC IS NULL |
consultation (Em atendimento) | Agenda.Situacao = ‘V’ AND DhAtendimentoIniUTC IS NOT NULL AND DhAtendimentoFimUTC IS NULL |
| `finished’ (Finalizado) | Agenda.Situacao = ‘V’ AND DhAtendimentoFimUTC IS NOT NULL |
| ’canceled’ (Cancelado) | Agenda.Situacao IN (‘C’,‘D’,‘F’,‘I’,‘M’,‘O’,‘T’) |
Domínios
TipoAgenda (domínio de Agenda.TipoAgenda) na tabela Indicadores:
| Valor | Significado |
|---|---|
| C | Consulta |
| Q | Quimioterapia |
| R | Radioterapia |
| S | Reserva de sala para assuntos não assistenciais |
ModoAtendimento (domínio de Agenda.Atendimento) na tabela Indicadores:
| Valor | Significado |
|---|---|
| P | Padrão (Presencial) |
| T | Teleatendimento |
| C | Customizado |
| R | Reservado |
SituacaoAgenda (domínio de Agenda.Situacao) na tabela Indicadores:
| Valor | Significado |
|---|---|
| A | Aberta |
| V | Confirmada (check-in realizado) |
| C | Cancelada pelo usuário |
| D | Cancelada pelo paciente |
| M | Cancelada pelo médico |
| F | Falta |
| I | Cancelado por internação |
| O | Cancelada por óbito |
| T | Transferido (cancelado) |
TipoDiagnostico (domínio de Diagnostico.Tipo):
| Valor | Significado |
|---|---|
| C | Comorbidade |
| O | Doença oncológica |
Infraestrutura de apoio
MinIO (Storage de fotos):
- Bucket global:
gemed - Bucket por ambiente do cliente: nome = banco de dados do cliente
- 1 bucket por banco de dados (cliente pode ter múltiplos bancos)
- Pasta de fotos:
FotosPacientes/dentro do bucket do cliente - Seleção da foto:
PacienteFoto.Padrao = 'S'; se múltiplas, selecionar a mais recente (futuro: vamos usar o campoCriadoEmda infraestrutura)
Internacionalização (i18n):
- Idioma da clínica:
ClienteEmpresa.IdiomaOficial(IpSeguranca), o termo segue padrão BCP 47 - Fuso horário da clínica:
ClienteEmpresa.FusoOficial(IpSeguranca) - Traduções: tabela
TermoTraducao(IpTerminologia) usa chave composta por (Termo, Origem, Idioma)- Origem: nome da tabela de origem ou
Indicadores|<NomeIndicador>quando o domínio está na tabela Indicadores - Idioma: Idioma do cliente
- Termo: o termo usado como chave na tabela de origem
- Origem: nome da tabela de origem ou
Filtros do endpoint
Agenda.IdChRecurso = {IdChProfissional do médico logado}— apenas consultas do médicoAgenda.TipoAgenda = 'C'- Agendas de consultaAgenda.DhAgendaIniUTC(no fuso da clínica) = Hoje(no fuso da clinica)— apenas consultas do dia atual- Toggle “Pendentes”:
Agenda.Situacao IN ('A','V')ANDDhAtendimentoFimUTC IS NULL— exclui canceladas e finalizadas - Toggle “Todas”: inclui finalizadas (canceladas não aparecem no painel — apenas finalizadas esmaecidas)
4.2 Endpoint: GET /api/v1/cockpit/doctor/kpis/appointments-today
Retornar o indicador de Consultas Hoje
Tabelas envolvidas
| Tabela | Banco | Função no endpoint |
|---|---|---|
| Agenda | GescomClienteAlfa | Tabela principal — dados da agenda |
Mapa de campos
| Campo | Tipo | Banco |
|---|---|---|
total | int | count(Agenda.Situacao IN (‘A’, ‘V’)) |
finished | int | count(Agenda.Situacao=‘V’, Agenda.DhAtendimentoFimUTC<>NULL) |
pending | int | count(Agenda.Situacao IN (‘A’, ‘V’), Agenda.DhAtendimentoFimUTC=NULL) |
delayed | int | count(Agenda.Situacao IN (‘A’, ‘V’), Agenda.DhAtendimentoFimUTC=NULL, Now(no fuso da clínica)-Agenda.DhAgendaIniUTC(no fuso da clinica)>0) |
Domínios
** os mesmos do endpoint acima
Filtros do endpoint
Agenda.IdChRecurso = {IdChProfissional do médico logado}— apenas consultas do médicoAgenda.TipoAgenda = 'C'- agendas de consultaAgenda.DhAgendaIniUTC(no fuso da clínica) = Hoje(no fuso da clinica)— apenas consultas do dia atual
4.3 Endpoint: [GET] /api/v1/cockpit/doctor/procedures
`{ "procedures":
[ { "id": "uuid",
"patient":
{ "id": "uuid",
"preferredName": "",
"legalName": "Roberto Oliveira"
},
"location": "Sala de Infusão 2",
"status": "administering",
"startTime": "2026-07-22T09:30:00Z",
"progress": 65,
"mine": true,
"tags": ["quimioterapia"]
}
]
}`
Retorna a lista de pacientes em procedimentos no dia atual.
Tabelas envolvidas
| Tabela | Banco | Função no endpoint |
|---|---|---|
| Agenda | GescomClienteAlfa | Tabela principal — dados da agenda |
| Paciente | GescomClienteAlfa | Dados do paciente (nome, nome social) |
| PacienteFoto | GescomClienteAlfa | Foto do paciente |
| Prescricao | GescomClienteAlfa | Diagnóstico oncológico do paciente |
| TermoTraducao | IpTerminologia | Tradução do modo de atendimento |
| ClienteEmpresa | IpSeguranca | Idioma e fuso horário da clínica |
Mapa de campos
| Campo | Tipo | Banco | Observação | |
|---|---|---|---|---|
id | int | Prescricao.IdPrescricao | ||
prescriptionCode | string | Prescricao.Identificacao | ||
location | string | Prescricao.IdAgenda->Agenda.IdUAtendimento->UnidadeAtendimento.Descricao + Agenda.IdChRecurso->Chave.Descricao | IdUAtendimento pode ser NULL | |
startTime | horário | se Situacao=‘V’, Agenda.DhAtendimentoIniUTC(no fuso da clíncia) senão Agenda.DhAgendaIniUTC(no fuso da clínica) | só horário, convertido para o fuso e idioma da clínica | |
status | string | calculado | vide ProcedureStatus() | |
progress | int | (Now()-Agenda.DhAtendimentoIniUTC(no fuso do servidor))/Agenda.Tempo*100 | ||
mine | boolean | Prescricao.IdChProfissionalMed={IdChProfissional do médico logado} | ||
patient.id | int | Prescricao.IdPaciente | ||
patient.prefferedName | string | Paciente.NomeSocial | se existir, usar este como nome principal | |
patient.legalName | string | Paciente.Nome | se NomeSocial não existir, usar este como nome | |
patient.photo | url | PacienteFoto.NomeArquivo, busca IdPaciente e Padrao = ‘S’, se multiplos, retorna o mais recente | url gerada pelo MinIO | |
tags | array de string | mesma origem de appointments.tags, ver Seção 4.1 (Paciente.PacienteVip + ProgramaApoioPaciente/ProgramaApoio) |
Funções de cálculo
ProcedureStatus() — calcula o status do procedimento a partir dos campos da Agenda:
| Status retornado | Condição |
|---|---|
scheduled (Agendado) | Agenda.Situacao = ‘A’ AND DhChegadaUTC IS NULL |
waiting (Aguardando recepção) | Agenda.Situacao = ‘A’ AND DhChegadaUTC IS NOT NULL |
checked (Recepcionado) | Agenda.Situacao = ‘V’ AND DhAtendimentoIniUTC IS NULL |
preparation (Preparo) | Agenda.Situacao = ‘V’ AND DhAtendimentoIniUTC IS NOT NULL AND DhInfusaoIniUTC IS NULL |
administering (Em administração) | Agenda.Situacao = ‘V’ AND DhInfusaoIniUTC IS NOT NULL AND DhInfusaoFimUTC IS NULL |
administered (Completo) | Agenda.Situacao = ‘V’ AND DhInfusaoFimUTC IS NOT NULL AND DhAtendimentoFim IS NULL |
finished (Finalizado) | Agenda.Situacao = ‘V’ AND DhAtendimentoFimUTC IS NOT NULL |
canceled (Cancelado) | Agenda.Situacao IN (‘C’,‘D’,‘F’,‘I’,‘M’,‘O’,‘T’) |
Domínios
TipoAgenda (domínio de Agenda.TipoAgenda) na tabela Indicadores:
| Valor | Significado |
|---|---|
| C | Consulta |
| Q | Quimioterapia |
| R | Radioterapia |
| S | Reserva de sala para assuntos não assistenciais |
SituacaoAgenda (domínio de Agenda.Situacao) na tabela Indicadores:
| Valor | Significado |
|---|---|
| A | Aberta |
| V | Confirmada (check-in realizado) |
| C | Cancelada pelo usuário |
| D | Cancelada pelo paciente |
| M | Cancelada pelo médico |
| F | Falta |
| I | Cancelado por internação |
| O | Cancelada por óbito |
| T | Transferido (cancelado) |
Infraestrutura de apoio
MinIO (Storage de fotos):
- Bucket global:
gemed - Bucket por ambiente do cliente: nome = banco de dados do cliente
- 1 bucket por banco de dados (cliente pode ter múltiplos bancos)
- Pasta de fotos:
FotosPacientes/dentro do bucket do cliente - Seleção da foto:
PacienteFoto.Padrao = 'S'; se múltiplas, selecionar a mais recente (futuro: vamos usar o campoCriadoEmda infraestrutura)
Internacionalização (i18n):
- Idioma da clínica:
ClienteEmpresa.IdiomaOficial(IpSeguranca), o termo segue padrão BCP 47 - Fuso horário da clínica:
ClienteEmpresa.FusoOficial(IpSeguranca) - Traduções: tabela
TermoTraducao(IpTerminologia) usa chave composta por (Termo, Origem, Idioma)- Origem: nome da tabela de origem ou
Indicadores|<NomeIndicador>quando o domínio está na tabela Indicadores - Idioma: Idioma do cliente
- Termo: o termo usado como chave na tabela de origem
- Origem: nome da tabela de origem ou
Filtros do endpoint
Prescricao.IdAgenda <> NULLAgenda.TipoAgenda IN 'Q', 'R'- Agendas de quimio, radioAgenda.DhAgendaIniUTC(no fuso da clínica) = Hoje(no fuso da clinica)— apenas procedimentos do dia atual- Toggle “Meus”: Prescricao.IdChProfissionalMed={IdChProfissional do médico logado}
- Toggle “Todos”: sem restrições
4.4 Endpoint GET /api/v1/cockpit/doctor/kpis/procedures-today
GET] /api/v1/cockpit/doctor/kpis/procedures-today
{ "total": 8, "inProgress": 2, "waiting": 4, "scheduled": 2 }
Função: Retornar o indicador de Procedimentos Hoje
Tabelas envolvidas
| Tabela | Banco | Função no endpoint |
|---|---|---|
| Agenda | GescomClienteAlfa | Tabela principal — dados da agenda |
| Paciente | GescomClienteAlfa | Dados do paciente (nome, nome social) |
| PacienteFoto | GescomClienteAlfa | Foto do paciente |
| Prescricao | GescomClienteAlfa | Diagnóstico oncológico do paciente |
| TermoTraducao | IpTerminologia | Tradução do modo de atendimento |
| ClienteEmpresa | IpSeguranca | Idioma e fuso horário da clínica |
Mapa de campos
| Campo | Tipo | Banco |
|---|---|---|
total | int | count(Agenda.Situacao IN (‘A’, ‘V’)) |
inProgress | int | count(ProcedureStatus()=administering) |
waiting | int | count(ProcedureStatus()=waiting OR checked OR preparation) |
scheduled | int | count(ProcedureStatus()=scheduled) |
Funções de cálculo
ProcedureStatus() — calcula o status do procedimento a partir dos campos da Agenda:
| Status retornado | Condição | |
|---|---|---|
scheduled (Agendado) | Agenda.Situacao = ‘A’ AND DhChegadaUTC IS NULL | |
waiting (Aguardando recepção) | Agenda.Situacao = ‘A’ AND DhChegadaUTC IS NOT NULL | |
checked (Recepcionado) | Agenda.Situacao = ‘V’ AND DhAtendimentoIniUTC IS NULL | |
preparation (Preparo) | Agenda.Situacao = ‘V’ AND DhAtendimentoIniUTC IS NOT NULL AND DhInfusaoIniUTC IS NULL | |
administering (Em administração) | Agenda.Situacao = ‘V’ AND DhInfusaoIniUTC IS NOT NULL AND DhInfusaoFimUTC IS NULL | |
administered (Completo) | Agenda.Situacao = ‘V’ AND DhInfusaoFimUTC IS NOT NULL AND DhAtendimentoFim IS NULL | |
completed (Finalizado) | Agenda.Situacao = ‘V’ AND DhAtendimentoFimUTC IS NOT NULL | |
canceled (Cancelado) | Agenda.Situacao IN (‘C’,‘D’,‘F’,‘I’,‘M’,‘O’,‘T’) |
Domínios
TipoAgenda (domínio de Agenda.TipoAgenda) na tabela Indicadores:
| Valor | Significado |
|---|---|
| C | Consulta |
| Q | Quimioterapia |
| R | Radioterapia |
| S | Reserva de sala para assuntos não assistenciais |
SituacaoAgenda (domínio de Agenda.Situacao) na tabela Indicadores:
| Valor | Significado |
|---|---|
| A | Aberta |
| V | Confirmada (check-in realizado) |
| C | Cancelada pelo usuário |
| D | Cancelada pelo paciente |
| M | Cancelada pelo médico |
| F | Falta |
| I | Cancelado por internação |
| O | Cancelada por óbito |
| T | Transferido (cancelado) |
Infraestrutura de apoio
Internacionalização (i18n):
- Idioma da clínica:
ClienteEmpresa.IdiomaOficial(IpSeguranca), o termo segue padrão BCP 47 - Fuso horário da clínica:
ClienteEmpresa.FusoOficial(IpSeguranca) - Traduções: tabela
TermoTraducao(IpTerminologia) usa chave composta por (Termo, Origem, Idioma)- Origem: nome da tabela de origem ou
Indicadores|<NomeIndicador>quando o domínio está na tabela Indicadores - Idioma: Idioma do cliente
- Termo: o termo usado como chave na tabela de origem
- Origem: nome da tabela de origem ou
Filtros do endpoint
Agenda.TipoAgenda IN 'Q', 'R'- Agendas de quimio, radioAgenda.DhAgendaIniUTC(no fuso da clínica) = Hoje(no fuso da clinica)— apenas procedimentos do dia atual- `Prescricao.IdChProfissionalMed={IdChProfissional do médico logado} - só os meus pacientes
4.5 Endpoint [GET] /api/v1/cockpit/doctor/kpis/in-treatment
/api/v1/cockpit/doctor/kpis/in-treatment
`{ "inTreatment": 43,
"nonAdherent": 2 }`
Função: Retornar o indicador de Em Tratamento
Tabelas envolvidas
| Tabela | Banco | Função no endpoint |
|---|---|---|
| Agenda | GescomClienteAlfa | Tabela principal — dados da agenda |
| Paciente | GescomClienteAlfa | Dados do paciente (nome, nome social) |
| Prescricao | GescomClienteAlfa | Diagnóstico oncológico do paciente |
| TermoTraducao | IpTerminologia | Tradução do modo de atendimento |
Mapa de campos
| Campo | Tipo | Banco |
|---|---|---|
inTreatment | int | PatientInTreatmentCount() |
nonAdherent | int | TreatmentPlanAdherenceCount() |
Funções de cálculo
PatientInTreatmentCount() — calcula a quantidade de pacientes em tratamento do médico
- refere-se aos pacientes com agenda realizada há menos de 6 meses e/ou com prescrições realizadas há menos de 6 meses)
- esses 6 meses referem-se a um parâmetro da clínica que diz qual o tempo máximo de inatividade para considerar o paciente inativo:
- quanto às agendas: IpParametro.TempoPacienteAtivoAgenda -> IpParametroChave.Valor
- quanto às prescrições: IpParametroTempoPacienteAtivoPrescricao -> IpParametroChave.Valor
- Nas agendas obter as agendas com:
- Situação ‘V’
- DhAgendaIniUTC > Hoje()-IpParametroChave.Valor (onde IpParametro=TempoPacienteAtivoAgenda)
- Nas prescrições obter as prescrições com:
- Situação <> ‘C’ (canceladas)
- Data > Hoje()-IpParametroChave.Valor (onde IpParametro=TempoPacienteAtivoPrescricao)
- A query fica mais ou menos assim:
SELECT DISTINCT p.IdChProfissional, p.IdPaciente FROM paciente p INNER JOIN agenda a ON a.IdPaciente = p.IdPaciente AND a.IdChRecurso = p.IdChProfissional WHERE a.Situacao = 'V' AND a.DhAgendaIniUTC > dateadd(day,-180, getdate()) -- há 6 meses UNION SELECT DISTINCT p.IdChProfissional , p.IdPaciente FROM Paciente p INNER JOIN Prescricao p2 on p2.IdPaciente = p.IdPaciente AND p.IdChProfissional = p2.IdChProfissionalMed WHERE p2.Situacao <> 'C' AND p2.[Data] > dateadd(day,-180, getdate()) -- há 6 mesesEntão conta a quantidade de pacientes do profissional logado.
TreatmentPlanAdherenceCount() — calcula os pacientes com plano terapêutico (PEPProjetoTerapeutico) que estão em descompasso com o planejado; quem não tem plano terapêutico não entra na contagem. Um paciente conta como não aderente quando QUALQUER UMA das três condições abaixo é verdadeira (lógica OU — confirmado com o solicitante: basta uma delas estar fora do parametrizado) para algum PEPProjetoTerapeuticoProtocolo do seu plano que tenha IdPrescricao:
- A data do C1D1 realizado difere da data prevista em mais de
Protocolo.ToleranciaDiasAdesaodias [PROPOSTA] - A prescrição passada não foi realizada (
Prescricao.SituacaoIN (‘P’,‘G’,‘A’,‘C’)) - O intervalo entre sessões da prescrição diverge do intervalo programado no protocolo (
Prescricao.Sessao = Prescricao.Data - Prescricao.Data_da_prescrição_anterior, comparado aProtocolo.IntervaloCiclosEmDias— já existe no schema — com a mesma tolerânciaProtocolo.ToleranciaDiasAdesaoacima)
[PROPOSTA] Coluna nova em
Protocolo(GescomClienteAlfa):ToleranciaDiasAdesao(int, dias de tolerância para desvio de datas previstas — reaproveitada tanto para o C1D1 quanto para o intervalo entre sessões). Não existe hoje noEsquemaGemed21.csv— confirmado com o solicitante que os valores de tolerância são parâmetros do protocolo, ainda não modelados na tabelaProtocolo; a criar antes da implementação deste KPI.
Filtros do endpoint
Paciente.IdChProfissional={IdChProfissional do médico logado}- Pacientes em que o médico é o médico assistente
4.6 Endpoint: GET /api/v1/cockpit/doctor/kpis/prescription-alerts
Retorna o indicador de Alertas de Prescrição (urgentes, a revisar, a assinar nos próximos 7 dias).
Tabelas envolvidas
| Tabela | Banco | Função no endpoint |
|---|---|---|
| Prescricao | GescomClienteAlfa | Tabela principal — versão ativa (Situacao <> 'C'), médico prescritor |
| PrescricaoAssinatura | GescomClienteAlfa | Histórico de assinaturas/revisões — usada para determinar se a prescrição está revisada |
| Agenda | GescomClienteAlfa | Data/hora agendada da aplicação (via Prescricao.IdAgenda) |
Mapa de campos
| Campo | Tipo | Banco | Observação |
|---|---|---|---|
urgent | int | PrescriptionUrgentCount() | |
toReview | int | PrescriptionToReviewCount() | |
toSignNext7Days | int | PrescriptionToSignNext7DaysCount() |
Funções de cálculo
PrescriptionToReviewCount() — conta as prescrições “a revisar” do médico logado (RN-CM-020), restritas a prescrições em que o médico logado é o prescritor ou o médico assistente do paciente. Reaproveita PrescricaoAssinatura: um registro com TipoAssinatura = 'A' é a assinatura original do médico; um registro com TipoAssinatura = 'R' é uma confirmação de revisão. Qualquer um dos dois, se teve Data dentro dos últimos 7 dias, satisfaz o requisito — não é necessária uma tabela nova. Para “está assinada”, verifica tanto PrescricaoAssinatura quanto o campo legado Prescricao.IdChProfissionalAssinou, por compatibilidade com prescrições gravadas antes da adoção da tabela de assinaturas.
A janela que dispara “a revisar” (RN-CM-020) — descrita na Seção 1 como “1 dia (24h) antes da aplicação” — não é um valor fixo no código: é um parâmetro configurável por clínica, mesmo padrão já usado em 4.5 (TempoPacienteAtivoAgenda/TempoPacienteAtivoPrescricao): IpParametro.PrescricaoTempoRevisao → IpParametroChave.Valor (horas). Ver “Parâmetro de configuração — PrescricaoTempoRevisao” logo abaixo para a definição completa das duas linhas de banco necessárias.
SELECT COUNT(*)
FROM Prescricao p
INNER JOIN Agenda a ON a.IdAgenda = p.IdAgenda
WHERE p.Situacao <> 'C' -- apenas a versão ativa
AND (
EXISTS (SELECT 1 FROM PrescricaoAssinatura pa
WHERE pa.IdPrescricao = p.IdPrescricao AND pa.TipoAssinatura = 'A')
OR p.IdChProfissionalAssinou IS NOT NULL -- compatibilidade com legado
) -- já assinada, por um dos dois caminhos
AND a.DhAgendaIniUTC <= DATEADD(HOUR,
COALESCE(
(SELECT ipc.Valor FROM IpParametroChave ipc
WHERE ipc.IdParametro = 'PrescricaoTempoRevisao' AND ipc.IdChave = {IdClinica}),
24), -- default 24h se IpParametro/IpParametroChave não existir (confirmado pelo solicitante)
SYSDATETIMEOFFSET()) -- a X horas ou menos da aplicação, X = parâmetro da clínica
AND NOT EXISTS (
SELECT 1 FROM PrescricaoAssinatura pa2
WHERE pa2.IdPrescricao = p.IdPrescricao
AND pa2.TipoAssinatura IN ('A','R')
AND pa2.Data > DATEADD(DAY, -7, SYSDATETIMEOFFSET()) -- assinatura/revisão válida por 7 dias
)
AND (p.IdChProfissionalMed = {IdChProfissional do médico logado}
OR EXISTS (SELECT 1 FROM Paciente pac WHERE pac.IdPaciente = p.IdPaciente
AND pac.IdChProfissional = {IdChProfissional do médico logado}))Nota: a cláusula de escopo acima é fechada (só prescritor OU assistente) — o KPI é uma contagem pessoal de “quanto precisa da sua atenção”, diferente do toggle “Todos” do painel (Seção 4.7), que deliberadamente amplia para qualquer médico da clínica porque ali o médico está decidindo ajudar a revisar colegas. Não existe (nem deveria existir) uma permissão RBAC de “revisor geral” que amplie o KPI — isso inflaria a contagem pessoal com prescrições de pacientes sem nenhum vínculo com o médico logado.
Parâmetro de configuração — PrescricaoTempoRevisao
[PROPOSTA — pedido pelo solicitante nesta versão] A janela de disparo de “a revisar” precisa existir como parâmetro real de banco, não só como texto de regra de negócio. Não é uma tabela nova — IpParametro/IpParametroChave já existem e já hospedam parâmetros do mesmo tipo (ver 4.5). São 2 linhas novas de dado (seed), não uma mudança de schema:
IpParametro (linha nova):
| Campo | Valor |
|---|---|
IdParametro | PrescricaoTempoRevisao |
Descricao | Define o tempo em horas antes da aplicação para uma prescrição ficar em estado de "pendente de revisão" |
Dominio | NULL |
UsuarioControla | S |
Tipo | N |
IpParametroChave (linha nova, valor por clínica — exemplo com o padrão-sugerido de 24h, correspondente à regra “1 dia” da Seção 1):
| Campo | Valor |
|---|---|
IdParametro | PrescricaoTempoRevisao |
IdChave | {Id da Clínica} |
Valor | 24 |
IdChave2 | NULL |
Comportamento se o parâmetro não existir: se a linha em IpParametro ou em IpParametroChave não existir para a clínica, o sistema assume 24h como default (confirmado pelo solicitante) — ver COALESCE na query acima. O seed abaixo (Seção “Seeds da Funcionalidade”) deve ainda assim ser aplicado em todo cliente, para que o valor fique explícito e configurável desde o início, em vez de depender do default implícito do código.
Atenção Dev/DevOps: este parâmetro é um dado novo de configuração, não uma migration de schema — precisa ser adicionado à documentação de deploy/seed de cada cliente (mesma lista onde já constam TempoPacienteAtivoAgenda/TempoPacienteAtivoPrescricao). Ver a subseção “Seeds da Funcionalidade”, ao final desta Seção 4, para a lista consolidada de todos os seeds necessários para este documento.
PrescriptionUrgentCount() — soma duas contagens, ambas restritas ao médico logado (prescritor ou assistente) e filtradas por hoursRemaining < 12 (RN-CM-011): (a) PrescriptionToReviewCount() restrita a hoursRemaining < 12; (b) prescrições pendentes de assinatura do médico logado (Prescricao.IdChProfissionalMed = {médico logado}, sem PrescricaoAssinatura.TipoAssinatura = 'A' E Prescricao.IdChProfissionalAssinou IS NULL) com hoursRemaining < 12. hoursRemaining = DATEDIFF(MINUTE, SYSDATETIMEOFFSET(), a.DhAgendaIniUTC) / 60.0.
PrescriptionToSignNext7DaysCount() — prescrições com Prescricao.Situacao <> 'C', Prescricao.IdChProfissionalMed = {IdChProfissional do médico logado} (só o próprio prescritor assina, RN-CM-012 — não há equivalente de “assistente” aqui), sem PrescricaoAssinatura.TipoAssinatura = 'A' E sem Prescricao.IdChProfissionalAssinou preenchido (compatibilidade com legado), e Agenda.DhAgendaIniUTC entre agora e +7 dias.
Filtros do endpoint
- Escopo do médico logado, fechado nas 3 métricas: prescritor (
Prescricao.IdChProfissionalMed) OU médico assistente do paciente (Paciente.IdChProfissional) paratoReviewe a parcela de revisão deurgent; apenas prescritor paratoSignNext7Dayse a parcela de assinatura deurgent. O KPI nunca inclui prescrições de outros médicos sem esse vínculo — ver nota acima sobre a diferença em relação ao toggle “Todos” do painel (Seção 4.7).
4.7 Endpoint: GET /api/v1/cockpit/doctor/prescriptions
Retorna a lista de prescrições pendentes (assinatura e revisão) do médico logado, para o painel e para a tela dedicada.
Tabelas envolvidas
| Tabela | Banco | Função no endpoint |
|---|---|---|
| Prescricao | GescomClienteAlfa | Tabela principal — versão ativa (Situacao <> 'C'); Identificacao já traz protocolo + ciclo/sessão formatados |
| PrescricaoAssinatura | GescomClienteAlfa | Determina se a prescrição está assinada e/ou revisada (ver 4.6) |
| Paciente | GescomClienteAlfa | Nome social/civil do paciente e médico assistente |
| Agenda | GescomClienteAlfa | Data/hora agendada da aplicação |
Domínio — PrescricaoAssinatura.TipoAssinatura
| Valor | Significado |
|---|---|
A | Assinatura do médico (assinatura original da prescrição ou de uma nova versão gerada por edição) |
R | Confirmação de revisão sem alteração da prescrição (“Marcar como Revisada”, RN-CM-020) |
Nota: o esquema também sugere os tipos
F(farmácia) e outros, usados por outras funcionalidades fora do escopo do Cockpit — não detalhados aqui.
Mapa de campos
| Campo | Tipo | Banco | Observação |
|---|---|---|---|
id | uuid | Prescricao.IdPrescricao | identifica diretamente a versão ativa — não há campo de número de versão a considerar à parte |
patient.id | uuid | Prescricao.IdPaciente | |
patient.preferredName | string | Paciente.NomeSocial | mesmo padrão de appointments (4.1) e procedures (4.3) — enviado sempre, mesmo vazio, para o front sinalizar nome social ao médico |
patient.legalName | string | Paciente.Nome | enviado sempre, junto com preferredName |
prescriptionCode | string | Prescricao.Identificacao | substitui os antigos protocol/cycle — já vem formatado do banco (ex: “CARBO-TAXOL C3D1”), sem necessidade de montar a string a partir de Protocolo/PrescricaoProtocolo |
scheduleDate | datetime | Agenda.DhAgendaIniUTC, via Prescricao.IdAgenda | convertida para o fuso da clínica na exibição |
hoursRemaining | int | calculado: Agenda.DhAgendaIniUTC - Now() em horas | |
type | string | calculado | to_sign se não existe PrescricaoAssinatura.TipoAssinatura = 'A' E Prescricao.IdChProfissionalAssinou IS NULL (checagem dupla por compatibilidade com legado, ver 4.6); to_review se assinada por qualquer um dos dois caminhos, mas nenhum registro A/R com Data nos últimos 7 dias (ver PrescriptionToReviewCount, 4.6) |
isPreferredReviewer | bool | calculado | true se médico logado = Prescricao.IdChProfissionalMed OU = Paciente.IdChProfissional; presente somente quando type = to_review. Os campos prescriberName/attendingDoctorName cogitados antes foram removidos — o booleano basta para o front |
Filtros do endpoint
type = to_sign: (não existePrescricaoAssinatura.TipoAssinatura = 'A'EPrescricao.IdChProfissionalAssinou IS NULL) ANDPrescricao.IdChProfissionalMed= médico logado ANDAgenda.DhAgendaIniUTCaté 7 dias a partir de agora — nunca afetado porreviewScope. O corte de 7 dias evita inflar a lista com prescrições distantes no tempo, sem relevância imediata para o médico.type = to_review: condição temporal e de assinatura dePrescriptionToReviewCount()(Seção 4.6) — i.e.,Situacao <> 'C', assinada (por qualquer um dos dois caminhos), dentro da janela deIpParametro.PrescricaoTempoRevisao(parâmetro por clínica, ver 4.6 — não mais um “D-1” fixo), sem assinatura/revisão válida nos últimos 7 dias — mas com a condição de escopo de médico da 4.6 substituída peloreviewScopeabaixo (a 4.6 é sempre “mine” porque é uma contagem pessoal do KPI; o painel de prescrições permite alternar):reviewScope = mine(default): adiciona(Prescricao.IdChProfissionalMed = {médico logado} OR Paciente.IdChProfissional = {médico logado})reviewScope = all: sem restrição adicional de médico — todas as prescrições a revisar da clínica
- Sem parâmetro
type: união das duas categorias, ordenada porhoursRemainingascendente (RN-CM-011);reviewScopeaplicado apenas à parteto_reviewda união, conforme acima Prescricao.Situacao <> 'C'em ambos os casos — como há no máximo 1 prescrição ativa por cadeia de versões, este filtro já garante que apenas a versão vigente apareça na lista, sem risco de duplicidade
Nota: os endpoints de ação de prescrições (GET /prescriptions/{id}, POST /sign, PATCH /review, PUT /prescriptions/{id}) pertencem a um documento de processo de Prescrições à parte, fora do escopo deste documento. RN-CM-020 continua na Seção 2 porque alimenta o KPI/painel deste Cockpit (Seções 4.6/4.7). O esquema já suporta assinatura/revisão via
PrescricaoAssinatura.TipoAssinatura(A/R) e versionamento viaPrescricaoVersao, sem necessidade de tabela nova.
4.8 Endpoint: GET /api/v1/cockpit/doctor/conversations
Retorna as conversas não finalizadas do médico logado — lidas e não lidas (painel compacto do Cockpit — ver escopo em RN-CM-015 e Seção 2.5), com base no modelo de Conversas e Alertas (IP.Mensageria). O schema desse domínio (GescomClienteAlfa.mensageria) passou a ter DDL real na Biblioteca de Schema (DDL) do projeto (GescomMensageria.sql) a partir de 28/08/2026 — antes disso, o mapeamento abaixo era baseado só na descrição do documento externo “Conversas-e-Alertas”, sem o DDL para conferir nomes e tipos de campo exatos. Esta versão corrige os campos que o DDL real revelou estarem descritos incorretamente (ver “Resolução do nome do autor” abaixo e o changelog desta versão). Diferente das demais tabelas mapeadas neste documento, as tabelas de mensageria abaixo pertencem ao mesmo banco operacional do cliente (GescomClienteAlfa), mas são de um schema separado (mensageria), não do schema dbo assistencial.
Tabelas envolvidas
| Tabela | Banco | Função no endpoint |
|---|---|---|
| Conversa | GescomClienteAlfa | Tabela principal — thread, status, prazo, origem, paciente relacionado |
| ConversaDestinatario | GescomClienteAlfa | Snapshot de quem recebeu a conversa — usada para filtrar pelo médico logado |
| ConversaLeitura | GescomClienteAlfa | Determina se a conversa está lida para o médico logado |
| Mensagem | GescomClienteAlfa | Conteúdo e autor da última mensagem da thread (preview do card) |
| Equipe | GescomClienteAlfa | Nome de exibição da equipe (Nome) — usado no sufixo “(Equipe)” do autor quando aplicável (ver “Resolução do nome da equipe” abaixo) |
| EquipeMembro | GescomClienteAlfa | Determina se o autor da mensagem é membro da equipe destino da conversa (Conversa.EquipeId) — decide se o sufixo de equipe aparece |
| SegUsuario | GescomClienteAlfa | Ponte legada entre o identificador local (int) e o GUID do IPSeguranca (ver resolução de nome abaixo) |
| Paciente | GescomClienteAlfa | Nome social/civil do paciente relacionado, quando Conversa.PacienteId existe |
Resolução do nome do autor (corrigida nesta versão — DDL real de
mensageriadisponibilizado em 28/08/2026):Mensagem.IdUsuarioAutor,Conversa.IdUsuarioRemetente,Conversa.IdUsuarioDestino,ConversaDestinatario.IdUsuarioeEquipeMembro.IdUsuariosão todosint, não GUID — o mesmo tipo de identificador legado local já usado emProfissional.IdUsuario/Prescricao.IdUsuarioAssinatura. Versões anteriores deste documento (v4.14 a v4.23) assumiam, sem o DDL real damensageriadisponível, que esses campos já armazenavam o GUID deIPSeguranca.dbo.Usuario.Id— suposição que o DDL real desmente. A triangulação correta é:IdUsuarioAutor(int) =SegUsuario.IdUsuario(smallint, PK — join dentro do próprioGescomClienteAlfa) →SegUsuario.SegurancaUsuarioId(GUID; nome de campo conforme “Log de Mudanças Estruturais do Banco de Dados”, que prevalece sobre a Biblioteca de Schema (DDL) para este campo específico) → nome de exibição emIPSeguranca.dbo.Usuario.Apelido(mesmo GUID). A mesma triangulação vale paraIdUsuarioRemetente,IdUsuarioDestinoeConversaDestinatario.IdUsuario.
Resolução do nome da equipe (nova nesta versão): o autor de uma mensagem ganha o sufixo da equipe quando
Conversa.DestinoTipo = 'Team'E existe uma linha emEquipeMembrocomEquipeId = Conversa.EquipeIdeIdUsuarioigual aoSegUsuario.IdUsuariodo autor resolvido acima. Quando as duas condições são verdadeiras, o nome de exibição final éUsuario.Apelido+ ” (” +Equipe.Nome+ ”)” (ex.: “Sandra (Farmácia)”); caso contrário, é sóUsuario.Apelido. [PROPOSTA — a confirmar com o solicitante]: esta verificação usa o vínculo atual deEquipeMembro(RemovidoEmUtc IS NULL) no momento em que o card/thread é exibido, não o vínculo no momento em que a mensagem foi enviada —EquipeMembronão guarda um snapshot por mensagem, então alguém que já saiu da equipe deixaria de ter o sufixo em mensagens antigas dele. Alternativa não implementada aqui: checarAdicionadoEmUtc <= Mensagem.CriadoEmUtc AND (RemovidoEmUtc IS NULL OR RemovidoEmUtc > Mensagem.CriadoEmUtc)para refletir o vínculo histórico da época do envio. A escolha entre as duas abordagens fica pendente de confirmação.
O ícone continua binário: bell (Lucide) para OrigemTipo = 'System', ícone genérico de pessoa para OrigemTipo = 'User', sem variação por equipe (recepção/farmácia/enfermagem) — a identificação da equipe, quando aplicável, é resolvida como texto (acima), não como ícone. Diferente do que versões anteriores deste documento afirmavam, a tabela Equipe (e EquipeMembro) é necessária neste endpoint — não apenas no backend de roteamento — porque a exibição do sufixo “(Equipe)” no authorName depende dela (ver “Resolução do nome da equipe” acima).
Mapa de campos
| Campo | Tipo | Banco | Observação |
|---|---|---|---|
id | uuid | Conversa.Id | |
sourceType | string | calculado a partir de Conversa.OrigemTipo | system se sistema; person se usuario |
authorName | string | IPSeguranca.dbo.Usuario.Apelido do autor da mensagem de maior Sequencia, via SegUsuario (ver “Resolução do nome do autor” acima); com sufixo " (" + Equipe.Nome + ")" quando Conversa.DestinoTipo = 'Team' e o autor é membro dessa Equipe (ver “Resolução do nome da equipe” acima); ou “Sistema” quando sourceType = system | |
lastMessage | string | Mensagem.Conteudo (maior Sequencia da Conversa) | |
lastMessageAt | datetime | Mensagem.CriadoEmUtc (mesma linha) | |
deadline | datetime | Conversa.PrazoEmUtc | pode ser nulo |
status | string | Conversa.Status | mapeado para sent/read/replied (ver 2.9) |
unread | bool | calculado: Conversa.UltimaSequencia > ConversaLeitura.UltimaSequenciaLida (ou sem ConversaLeitura) | usado para destaque visual e camada de prioridade (RN-CM-015); não filtra o resultado |
patient | object | null | Paciente, via Conversa.PacienteId |
Filtros do endpoint
ConversaDestinatario.IdUsuario = {médico logado}— recebida diretamente ou via snapshot de equipe (EquipeOrigemId)Conversa.IdEmpresa = {filial da sessão validada}— nunca escolhido livremente pelo cliente da API (conforme fronteira de responsabilidade do IPSeguranca)Conversa.Status IN ('Sent', 'Read', 'Responded')— exclui'Resolved'e'Dismissed'Conversa.UltimaSequencia > ConversaLeitura.UltimaSequenciaLida, OU não existeConversaLeiturapara o médico logado — calcula o campounread, usado como critério de ordenação (não filtra o WHERE).- Ordenação:
unreaddescendente (não lidas primeiro), depoisConversa.PrazoEmUtcascendente (nulos por último), depoislastMessageAtdescendente — RN-CM-015
4.9 Endpoints de ação: GET /conversations/{id}, POST /read, POST /reply, PATCH /resolve, PATCH /discard
Tabelas envolvidas
| Tabela | Banco | Função no endpoint |
|---|---|---|
| Conversa | GescomClienteAlfa | Status atual, UltimaSequencia |
| Mensagem | GescomClienteAlfa | Thread completa (GET detalhe); nova linha inserida em POST /reply |
| ConversaLeitura | GescomClienteAlfa | Atualizada em POST /read |
| ConversaAcao | GescomClienteAlfa | Histórico append-only — nova linha em toda ação (leitura, resposta, resolução, descarte) |
| OutboxEvento | GescomClienteAlfa | Evento assíncrono gravado na mesma transação de qualquer mudança de estado (fora do escopo deste front, mencionado por completude) |
Efeitos em BD por endpoint de ação
- GET /conversations/{id}: somente leitura — retorna todas as
Mensagemda conversa ordenadas porSequencia, mais os dados deConversa(status, prazo, paciente). Para cada mensagem, resolve o sufixo de equipe do autor do mesmo jeito que o endpoint de lista (Seção 4.8, “Resolução do nome da equipe”) — a thread completa também mostra “Sandra (Farmácia)” quando aplicável, não só o card compacto. - POST /read: insere ou atualiza
ConversaLeitura(chaveConversaId+IdUsuario) comUltimaSequenciaLida = Conversa.UltimaSequencia; insere uma linha emConversaAcao(Tipo=Read); seConversa.Status = 'Sent', atualiza para'Read'— nunca regride um status já mais avançado ('Responded'permanece'Responded'). - POST /reply: insere uma nova linha em
Mensagem(Sequencia = Conversa.UltimaSequencia + 1,IdUsuarioAutor= médico logado,Conteudodo request,Tipo='Response'); atualizaConversa.UltimaSequencia; atualizaConversa.Statuspara'Responded'; insere uma linha emConversaAcao(Tipo='Response';MensagemIdda nova mensagem); gravaOutboxEvento(TipoEvento=ConversaRespondida). O valor'Reply', antes um segundo valor válido paraMensagem.Tipo/ConversaAcao.Tipono mesmoCHECK, foi abolido pelo solicitante —'Response'é o único valor usado para a ação de responder, resolvendo a pendência [A DEFINIR] da v4.24 (ver Log de Mudanças Estruturais do Banco de Dados). - PATCH /resolve: atualiza
Conversa.Statuspara'Resolved'; insere uma linha emConversaAcao(Tipo='Resolve'); gravaOutboxEvento(TipoEvento=ConversaResolvida). Não altera nem excluiMensagem. - PATCH /discard: atualiza
Conversa.Statuspara'Dismissed'; insere uma linha emConversaAcao(Tipo='Dismiss'); gravaOutboxEvento(TipoEvento=ConversaDescartada). Mesma observação — nada é excluído fisicamente.
Fora do escopo deste documento
A criação de conversas (envio inicial por um usuário) e a publicação de alertas automáticos (AlertaPublicacao, com chave de idempotência) partem de outros módulos ou telas — o Cockpit é consumidor/participante das conversas, não o ponto de origem. O cadastro e a gestão de equipes (criar/renomear/desativar uma Equipe, adicionar ou remover membros em EquipeMembro) também partem de outro módulo — o Cockpit só lê Equipe/EquipeMembro para resolver o sufixo do nome do autor (Seção 4.8), nunca escreve nelas. O processamento assíncrono via OutboxEvento pertence ao domínio do IP.Mensageria e também não é especificado aqui.
4.10 Endpoint: GET /api/v1/patients/search
Retorna pacientes que casam com o termo digitado no campo de busca do cabeçalho (RN-CM-004). A correspondência aproximada (pesos de proximidade fonológica e semântica) usa um mecanismo já existente no sistema, fora do escopo desta especificação — este mapeamento cobre apenas os campos de busca direta e de resposta que esse motor já existente consome/retorna.
Tabelas envolvidas
| Tabela | Banco | Função no endpoint |
|---|---|---|
| Paciente | GescomClienteAlfa | Tabela única consultada — todos os campos de busca e resposta vêm dela |
Mapa de campos
| Campo | Tipo | Banco | Observação |
|---|---|---|---|
id | int | Paciente.IdPaciente | |
name | string | Paciente.Nome | segue o mesmo padrão de preferredName/legalName dos demais endpoints quando Paciente.NomeSocial existir |
medicalRecordNumber | string | Paciente.NumProntuario | |
gender | char | Paciente.Sexo | domínio ‘M’/‘F’ |
birthDate | data | Paciente.Nascimento | campo de busca quando a entrada começa com dígito (RN-CM-004) |
motherName | string | Paciente.NomeMae | campo de busca quando a entrada começa com letra (RN-CM-004) |
cpf | string | Paciente.CPF | campo de busca quando a entrada começa com dígito (RN-CM-004) |
Filtros do endpoint
- Sem filtro por médico logado — diferente dos demais painéis do Cockpit, a busca do cabeçalho não é restrita aos pacientes do médico, pois ele pode precisar localizar qualquer paciente da clínica.
- Mínimo de 2 caracteres (RN-CM-004) antes de disparar a busca.
Nota sobre o motor de correspondência aproximada
O EsquemaGemed21.csv não tem uma coluna dedicada de correspondência fonética/semântica em Paciente — o motor de busca aproximada citado em RN-CM-004 já existe e está em produção fora deste documento; presume-se que ele consulta os mesmos campos mapeados acima, mas o algoritmo em si (ranking, tolerância, índice usado) não é redefinido aqui.
Seeds da Funcionalidade
Lista consolidada de todo dado (seed) que precisa existir em produção — não schema novo, mas linhas de dado que este documento pressupõe — para que a funcionalidade se comporte como especificado. Pensada como checklist de deploy para Dev/DevOps: cada linha aponta para a seção com a definição completa dos campos, não a repete (evita duplicar a mesma informação em dois lugares — Lição #10 da Skill Designer).
| Seed | Tabela(s) | Por cliente ou global? | Status | Detalhe completo |
|---|---|---|---|---|
PrescricaoTempoRevisao — janela (em horas) antes da aplicação em que uma prescrição assinada vira “a revisar” (RN-CM-020) | IpParametro (1 linha) + IpParametroChave (1 linha por clínica) | Por cliente (IpParametroChave); a linha de IpParametro é única, compartilhada entre clientes | [PROPOSTA] — pedido pelo solicitante nesta versão, ainda não aplicado em produção. Default de 24h no código se a linha de IpParametroChave (ou a de IpParametro) não existir para a clínica — confirmado pelo solicitante — mas o seed deve ser aplicado mesmo assim, para que o valor fique explícito | Seção 4.6, “Parâmetro de configuração — PrescricaoTempoRevisao” |
Nenhum outro seed novo é necessário por este documento — os demais parâmetros citados (TempoPacienteAtivoAgenda, TempoPacienteAtivoPrescricao, Seção 4.5) já existem em produção, não são propostos aqui.
METADADOS FINAIS
- Prioridade: Alta (Core do Sistema)
- Complexidade: Média/Alta (Devido às integrações em tempo real)
- Próximos Passos:
- Homologação do serviço de atualização automática.
- Teste de carga para múltiplos médicos acessando simultaneamente.
- Validação da assinatura digital em ambiente de sandbox.
- Definir ícones definitivos para os KPI cards (biblioteca Lucide Icons).
- Substituir ícones placeholder de comunicação por SVGs da biblioteca Lucide — apenas 2 ícones (bell para alertas de sistema, ícone de pessoa genérico para conversas com usuário; não há ícone por equipe/farmácia/enfermagem/recepção).
- Validar acessibilidade (WCAG, navegação por teclado) dos títulos como links e toggles pill.
- Testar usabilidade do título como link com seta no hover com médicos.
- Validar touchpoints de workflow com médicos em ambiente real (shadowing).
- Mapear touchpoints de workflows ainda não documentados (ex: workflow de alta, workflow de intercorrência).
- Especificar os demais itens do menu do usuário: autocadastro/edição de perfil, dados de faturamento e pagamento (conta bancária, PIX) e dados de especialidade (CRM, RQE) — hoje o menu só tem “Sair”.
Histórico de Versões
- v4.25 (29/08/2026) — Arquivo criado pela divisão do documento único
CM_CockPit_do_medico_v4_25.mdem 4 arquivos por seção (ver Skill Designer, “Organização Física: Pasta por Funcionalidade”, Lição #18). Conteúdo desta seção sem alteração de substância em relação à v4.25 do documento original — apenas reorganização física. O histórico de revisões anterior a esta divisão (v4.0 a v4.25, incluindo o racional de cada mudança) está preservado integralmente no documento original, arquivado emHistórico/CM_CockPit_do_medico_v4_25 (documento único, antes da divisão em 4 arquivos).md. - v4.26 (30/08/2026) — Pedido do solicitante: a janela de “1 dia (24h)” que dispara o estado “a revisar” de uma prescrição (RN-CM-020) precisa existir como parâmetro real de banco, não só como texto de regra de negócio — mesmo padrão já usado para outros parâmetros por clínica neste documento (
TempoPacienteAtivoAgenda/TempoPacienteAtivoPrescricao, Seção 4.5). Adicionado, na Seção 4.6: (1) referência ao parâmetroIpParametro.PrescricaoTempoRevisao→IpParametroChave.Valorna query dePrescriptionToReviewCount(), substituindo oDATEADD(HOUR, 24, ...)fixo; (2) nova subseção “Parâmetro de configuração — PrescricaoTempoRevisao” [PROPOSTA], com a definição completa das 2 linhas de dado necessárias (IpParametro:IdParametro='PrescricaoTempoRevisao',Descricao,Dominio=NULL,UsuarioControla='S',Tipo='N';IpParametroChave:IdParametro='PrescricaoTempoRevisao',IdChave={Id da Clínica},Valor=24,IdChave2=NULL) e um alerta explícito para Dev/DevOps sobre a necessidade de incluir esse seed na documentação de deploy de cada cliente. Não é uma tabela nova —IpParametro/IpParametroChavejá existem. Filtrotype = to_reviewdo endpoint 4.7 atualizado para referenciar o mesmo parâmetro em vez de “D-1” fixo. - v4.27 (30/08/2026) — Pedido do solicitante, resolvendo o
[A DEFINIR]da v4.26: (1) comportamento definido para quandoIpParametro/IpParametroChavedePrescricaoTempoRevisaonão existir para a clínica — default de 24h, confirmado pelo solicitante — implementado na query dePrescriptionToReviewCount()(Seção 4.6) viaCOALESCE(..., 24)em vez doSELECTdireto; parágrafo “Atenção Dev/DevOps” reescrito para descrever esse comportamento e remover a pendência; (2) nova subseção “Seeds da Funcionalidade” ao final da Seção 4, consolidando em uma tabela todo dado (não schema) que precisa existir em produção para a funcionalidade funcionar como especificado — pedido explícito do solicitante (“seria bom termos uma subseção com os seeds da funcionalidade”). Por ora contém 1 linha (PrescricaoTempoRevisao, [PROPOSTA]), apontando para a Seção 4.6 em vez de repetir a definição (Lição #10). - v4.28 (11/09/2026) — Correção pontual do solicitante: o valor de
PrescricaoAssinatura.TipoAssinaturapara a assinatura do médico está errado em todo o documento — era'M', o correto é'A'. Corrigido em todas as ocorrências da Seção 4.6 (prosa e SQL dePrescriptionToReviewCount(),PrescriptionUrgentCount(),PrescriptionToSignNext7DaysCount()) e da Seção 4.7 (tabela de domínio, mapa de campos, filtros do endpoint, nota final). Não é o mesmo valor dePrescricaoAssinaturaEnfermagem.TipoAssinatura = 'E'(tabela distinta, confirmada na Biblioteca de Schema/DDL) — apenas o'M'→'A'dePrescricaoAssinaturaestava incorreto. Nenhuma outra seção deste conjunto de documentos (01, 02, 03) referenciava esse campo — correção isolada à Seção 4.