Agenda do Médico — Especificação (v1.8)
Documentos desta funcionalidade: 01 - Definição (v1.9) · 02 - Especificação (v1.8) · 03 - Protótipo (v1.7, código executável em 03 - Protótipo v1.7.html) · Mapeamento de Banco de Dados (Seção 4): pendente.
SEÇÃO 2 — ESPECIFICAÇÃO
Premissa de design: toda decisão de design nesta especificação é justificada pelo workflow documentado na Seção 1 — o médico chega aqui a partir da Central do Médico (título do painel “Consultas” ou indicador “Consultas Hoje”) quando precisa da visão completa do dia, não só dos próximos atendimentos. A tela é somente leitura (RN-AGM-001). Layout mobile-first (Seção 1, “Premissas”): uma coluna única de lista em qualquer largura; em telas largas, a coluna fica centralizada com largura máxima de leitura. A área fixa no topo (cabeçalho do sistema + barra do dia) é mantida no mínimo — cerca de 116px no celular, nunca mais que 120px — para que a lista, que é o conteúdo, ocupe a maior parte da tela. Todo alvo de toque (botões, dias do calendário, itens de consulta) tem no mínimo 44×44px.
Tema claro e escuro: a tela segue o Design System (Para IA/Design System.md, seções 1 a 6) — tema claro por padrão, tema escuro pela preferência do sistema do aparelho (“Automático”) ou fixado pelo usuário no menu do avatar (“Tema”: Automático, Claro, Escuro). Nenhuma cor desta especificação é específica de um tema: todos os valores de cor citados aqui são tokens do Design System, que trocam de valor no tema escuro pelas regras C1–C7; cores de status usam os tokens --color-status-* e cores de tag usam o padrão .chip-tag com a cor do cadastro. Onde esta especificação cita um valor literal herdado da Central do Médico (ex.: ff8a80, cores de status de RN-CM-005), ele corresponde ao token de status equivalente no tema claro.
Referência de tempo: “hoje”, “agora”, “dia passado” e “horário já decorrido” são sempre avaliados no fuso horário da clínica e pelo relógio do servidor, não do dispositivo — GET /day devolve serverNow (data e hora atuais no fuso da clínica), usado pelo front para o estado “Hoje”, a linha “AGORA” e o sinalizador de atraso; entre duas atualizações, o front avança esse horário pelo próprio relógio.
Histórias de Usuário
- US-AGM-001: Como médico, quero ver minha agenda do dia em lista, com os mesmos elementos de identificação de paciente já usados na Central do Médico, para organizar meu trabalho do dia.
- US-AGM-002: Como médico, quero navegar entre dias — dia a dia ou pulando direto para o próximo dia com consulta — para checar minha agenda com agilidade, mesmo em dias sem nenhum compromisso.
- US-AGM-005: Como médico, quero que consultas já realizadas e consultas canceladas fiquem resumidas, separadamente, e fora do caminho, para manter o foco nas consultas pendentes sem perder a visão de que o dia inteiro está ali.
- US-AGM-008: Como médico que atende em mais de uma clínica ou unidade, quero ver em cada consulta onde ela acontece, o convênio do paciente e a classificação da consulta, para me preparar para cada atendimento sem abrir o prontuário.
- US-CM-000 (Central do Médico, Seção 2.1 — “Buscar pacientes rapidamente”) aplica-se também a esta tela (RN-AGM-014), sem redefinição.
Descrição Funcional Detalhada
Cabeçalho do Sistema (RN-AGM-014)
A tela usa o mesmo cabeçalho da Central do Médico (Central do Médico, Seção 2.1): nome da clínica à esquerda, campo de busca de pacientes ao centro e menu do usuário (avatar com dropdown) à direita. Comportamento da busca (disparo após 2 caracteres e 1 segundo de pausa, busca aproximada, interpretação por dígito/letra, campos mínimos do resultado, abertura do PEP ao selecionar), do menu do usuário, critérios de aceitação e mensagens (MSG_searchPac, MSG_searchFoot, MSG_searchMin, MSG_searchNone) são os da Central do Médico, Seção 2.1 — referenciados, não repetidos aqui. Mesmo endpoint: GET /api/v1/patients/search (Central do Médico, Seção 2.9). Em telas estreitas (celular), o nome da clínica é ocultado e o logotipo é reduzido para dar largura ao campo de busca; busca e avatar continuam sempre visíveis; a altura do cabeçalho (64px) é a mesma da Central.
Justificativa de workflow: o médico que está conferindo a agenda do dia pode precisar de um paciente que não está nela (ex.: um resultado de exame chegou para um paciente de outro dia) — a busca no cabeçalho evita voltar à Central só para isso.
Barra de Navegação do Dia (RN-AGM-003)
Barra fixa logo abaixo do cabeçalho do sistema, em uma única linha (52px no celular, 56px em telas largas), com, da esquerda para a direita:
- Seta “dia anterior” (‹) — retrocede um dia.
- Data exibida, como botão — no celular, forma curta (“Hoje, Ter, 29 set” quando é hoje; “Qua, 30 set” nos demais dias); em telas largas, forma longa (“Terça-feira, 29 de setembro”), com um indicador de seta para baixo. Tocar na data abre o seletor de calendário (ver abaixo) — não há um botão de calendário separado. Quando uma atualização automática falha, um ícone discreto de “sem conexão” aparece dentro deste botão (EX-AGM-09).
- Seta “próximo dia” (›) — avança um dia.
- Botão “Hoje” — sempre visível. Quando o dia exibido é hoje, fica no estado ativo (destacado,
aria-current="date", sem ação) — esse estado substitui um rótulo “Hoje” separado; nos demais dias, retorna ao dia atual em um toque. - Telas largas: os atalhos “dia anterior com consulta” («) e “próximo dia com consulta” (») ficam também ao lado das setas.
- Menu “Mais opções” (⋮), à direita, em qualquer largura de tela, com dois itens: “Próximo dia com consulta” e “Dia anterior com consulta”, cada um com a data de destino escrita abaixo (ex.: “qua, 07/10”), ou “Nenhum” quando não há dia naquela direção (item indisponível).
Atalhos de dia com consulta: pulam direto para o próximo/anterior dia que tenha ao menos uma consulta agendada não cancelada — dias só com consultas canceladas são ignorados (RN-AGM-003). Ficam indisponíveis quando não há nenhum dia com consulta naquela direção.
Seletor de calendário — abre como bottom sheet no celular e como painel sobre a lista em telas largas, com: no topo, os dois atalhos com rótulo e data de destino (“Próximo dia com consulta · qua, 07/10” / “Dia anterior com consulta · ter, 23/09”); abaixo, o mini-calendário mensal com navegação entre meses, o dia de hoje e o dia exibido destacados, e um ponto sob os dias com ao menos uma consulta não cancelada (mesmo critério dos atalhos). Selecionar um dia fecha o seletor e carrega a agenda daquele dia; o foco vai para o dia exibido ao abrir.
Motivador: a revisão com um médico mostrou que, na barra, o uso frequente é a data, “Hoje” e as setas dia a dia; os atalhos de dia com consulta são de uso eventual — no celular, ficam a um toque a mais, com rótulo explícito (o ícone de seta dupla, sozinho, não é entendido), liberando a linha para o que se usa sempre. Em telas largas, onde há espaço, os atalhos « » também ficam visíveis.
Lista do Dia
Consultas do médico logado no dia exibido, de todas as clínicas do cliente (RN-AGM-002), em ordem cronológica pelo horário de início, numa única lista — sem separação por clínica —, com a linha “AGORA” no dia de hoje. Todo item tem, à esquerda, uma coluna de horário de largura fixa: horário de início em destaque e horário de término abaixo, menor. A coluna fixa cria um eixo de leitura estável — agenda se lê pela hora.
Item de consulta (RN-AGM-009, elementos herdados da Central do Médico — mesma origem e lógica já especificadas em Central do Médico, Seção 2.3). Nenhum texto do item é truncado: o que não cabe na linha quebra para a linha de baixo — o médico vê a informação completa sem precisar passar o mouse ou abrir o item. A disposição busca 2 linhas por item em telas largas, com linhas adicionais só para o complemento, para as tags que não cabem na segunda linha e para as informações complementares.
Telas largas (≥640px):
- Linha 1: nome do paciente (preferido, com o nome legal como alternativa), seguido do(s) diagnóstico(s) oncológico(s) em texto secundário (“Ana Paula Costa · Ca. Mama, Ca. Ovário”), e, à direita, o status (chip colorido, mesma paleta e rótulos da Central — Agendado, Aguardando Recepção, Recepcionado, Em Atendimento, Finalizado — mais Cancelado, exclusivo desta tela). O status é sempre exibido, inclusive “Agendado”.
- Linha 2: tipo de consulta (RN-AGM-008, quando a clínica configurou; como texto) e modo de atendimento — só quando não é o presencial (padrão, omitido): “Teleatendimento” e “Customizado” aparecem sempre, em cor de destaque —, separados por ”·”; em seguida, o ícone de 1ª Consulta (RN-CM-028, ver abaixo) e as tags do paciente, pelo critério de RN-AGM-006 (mesmo da Central, RN-CM-025); à direita, o sinalizador de atraso, quando houver. As tags que não couberem na linha 2 continuam na linha seguinte, alinhadas com as demais. A linha 2 não aparece quando não há nenhum desses elementos.
- Linha 3 (só quando houver): complemento (RN-AGM-007), em texto secundário.
- Última linha — informações complementares (RN-AGM-017): ver abaixo.
Celular (<640px), onde a largura não comporta nome, diagnóstico e status numa linha:
- Linha 1: nome e, à direita, o status.
- Linha 2: diagnóstico(s), tipo de consulta e modo de atendimento (mesma regra de omissão do presencial), separados por ”·”; à direita, o sinalizador de atraso.
- Linha 3 (só quando houver): ícone de 1ª Consulta e tags; abaixo, o complemento.
- Última linha — informações complementares (RN-AGM-017): igual às telas largas.
Ícone de 1ª Consulta (RN-CM-028): a primeira consulta do paciente é sinalizada por um ícone, não pelo texto “1ª Consulta”: ícone circle-number-1 da biblioteca Tabler Icons (em react-icons: TbCircleNumber1), 18px, sem fundo, na cor --color-first-visit do Design System, antes das tags. Tem rótulo acessível “1ª Consulta” (role="img" + aria-label) e dica com o mesmo texto ao passar o mouse; o rótulo acessível do item de consulta também inclui “1ª consulta”. Motivador: o número “1” no círculo se lê diretamente como “primeira”, ocupa menos espaço que o chip de texto e não se confunde com ação (alternativas avaliadas na exploração Ícone 1ª Consulta — opções (exploração).html).
Informações complementares (RN-AGM-017): última linha do item, com o menor destaque do item — texto de 12px em color-neutral-pure, sem chips nem cores —, porque são informações secundárias: menos importantes que tudo o que já está no item. Até quatro informações, nesta ordem, cada uma precedida de um ícone Lucide de 14px na mesma cor, que substitui o rótulo escrito:
building-2— clínica, pelo nome curto. Só quando o médico tem acesso a mais de uma clínica do cliente.map-pin— unidade de atendimento. Só quando a clínica daquela consulta tem mais de uma unidade ativa para consultas, e a consulta tem unidade definida.id-card— convênio, pelo nome curto. Sempre, inclusive “Particular”. O plano não aparece.folder— classificação, seguida da subclassificação quando houver (“Quimioterapia › Ciclo 2”). Só quando a consulta tem classificação (recurso opcional da clínica).
Cada informação aparece de forma independente; o espaçamento entre elas (12px) separa os itens, sem ”·”, para não se confundir com a linha 2. A linha quebra se não couber, sem truncar, como o resto do item. Como o convênio sempre existe, a linha aparece em todas as consultas. Ao passar o mouse sobre cada informação, uma dica mostra o rótulo (“Clínica”, “Unidade de atendimento”, “Convênio”, “Classificação”); os ícones são decorativos (aria-hidden), e o rótulo acessível do item de consulta inclui as informações com seus rótulos (ex.: “clínica Oncocentro Sul, convênio Unimed”). As condições de exibição da clínica e da unidade são aplicadas pelo back-end (campos null quando não devem aparecer — ver GET /day). Motivador: ícones no lugar de rótulos mantêm a linha curta; o médico aprende a ler a linha depois de poucas consultas, e a dica cobre a primeira vez.
- Destaque visual por status: borda lateral esquerda de 3px para “Recepcionado” (secondary-pure) e “Aguardando Recepção” (#FF8A80) — mesmo padrão da Central.
- Foto do paciente / avatar: em telas largas, entre a coluna de horário e o conteúdo (foto, ou iniciais do primeiro e do último nome, texto
color-neutral-darkersobre a cor do status); no celular, o avatar não é exibido — a coluna de horário ocupa o seu lugar, e o status já está no chip.
Sinalizador de atraso (RN-AGM-009) — somente quando o dia exibido é hoje, para consultas cujo horário de início já passou e que ainda não foram iniciadas nem finalizadas, em duas variantes:
- “Esperando · Xmin” — status Aguardando Recepção ou Recepcionado (o paciente já está na clínica; quem está atrasado é o atendimento): badge pulsante, fundo
color-error-pure(mesmo componente do badge de atraso da Central). - “Não chegou · Xmin” — status Agendado (o paciente ainda não chegou): badge neutro, fundo
color-neutral-lighter, textocolor-neutral-dark, sem animação.
X = minutos desde o horário de início (delayMinutes). Em dias passados ou futuros, o sinalizador não aparece. Esta distinção é exclusiva desta tela; a Central do Médico mantém um único sinalizador “Atrasado”.
Nota de nomenclatura: “Modo de atendimento” (campo attendanceMode na API — presencial, teleatendimento, customizado) e “Tipo de consulta” (campo appointmentType, RN-AGM-008) são dois campos distintos, apesar do nome parecido — o primeiro descreve o canal do atendimento, o segundo é um domínio configurável pela clínica (ex.: retorno, revisão). A classificação (RN-AGM-017) é um terceiro domínio, também configurável pela clínica.
Status “Cancelado”: consultas canceladas por qualquer motivo (inclusive falta do paciente) aparecem com o chip “Cancelado” com contorno — fundo transparente, texto color-neutral-dark, contorno de 1px color-neutral-light (tokens --color-status-canceled-* do Design System, seção 4), o único status sem fundo preenchido, para se distinguir de “Finalizado” pela forma e não só pela cor; rótulo: termo status-cancelado já catalogado na Central do Médico, Seção 2.6. Só aparecem dentro do grupo de canceladas (ver abaixo).
Toque em qualquer parte do item de consulta abre o PEP do paciente (RN-AGM-009) — inclusive consultas realizadas e canceladas, dentro dos grupos expandidos.
Dia sem nenhuma consulta: estado vazio (EX-AGM-03) com MSG-TAGM-01.
Resumo de Consultas Realizadas e Canceladas (RN-AGM-010)
Consultas com status finished e com status canceled não aparecem como itens individuais na lista principal. No topo da lista, uma única linha com até dois botões lado a lado, nesta ordem:
- “N realizadas” (singular: “1 realizada”), com o ícone Lucide
circle-checkna cor--color-status-finished-fg— consultasfinisheddo dia. - “N canceladas” (singular: “1 cancelada”), com o ícone Lucide
circle-xemcolor-neutral-pure— consultascanceleddo dia (qualquer motivo, inclusive falta).
Os ícones são decorativos (aria-hidden); o texto do botão já diz o que ele resume.
Cada botão só aparece quando N ≥ 1 (a linha some quando os dois são zero). Tocar num botão expande, logo abaixo da linha, só aquele grupo, com as consultas individuais em ordem cronológica, no mesmo formato de item da lista, esmaecidas (mesmo tratamento das consultas finalizadas da Central do Médico, Seção 2.3) e diferenciadas entre si: realizadas com opacidade 0,8; canceladas com opacidade 0,6, horário de início e término riscados (a consulta não ocupou a agenda) e nome em color-neutral-pure. Tocar de novo recolhe. Os dois grupos se expandem e recolhem de forma independente (aria-expanded) e começam recolhidos a cada carregamento de dia. Quando uma consulta muda de status durante a atualização automática, ela simplesmente passa da lista principal para o grupo correspondente.
Linha “AGORA”: somente quando o dia exibido é hoje, uma linha fina marca o horário atual na lista principal, com o horário (“10:07”) em vermelho na própria coluna de horário e um traço atravessando a largura — inserida depois de todos os itens com horário de início anterior ou igual ao momento atual e antes do próximo. É reposicionada a cada atualização automática (RN-AGM-013), sem mover a rolagem.
Posição inicial da rolagem (dia de hoje): a tela abre rolada até a primeira consulta que ainda exige ação — a de horário mais cedo entre as de status Agendado, Aguardando Recepção, Recepcionado ou Em Atendimento — quando o horário dela já passou (ex.: uma consulta atrasada); caso contrário, até a linha “AGORA”. O deslocamento considera a altura real do cabeçalho e da barra do dia. Em qualquer outro dia, a linha “AGORA” não aparece e a tela abre no topo da lista.
Atualização Automática e Conexão (RN-AGM-013)
A agenda do dia exibido é recarregada em segundo plano a cada 1 minuto (polling do GET /api/v1/agenda/doctor/day, mesmo intervalo do painel de Consultas da Central, Central do Médico, Seção 2.9), sem perder o estado de expansão dos grupos, a posição de rolagem nem o foco do teclado. A mesma atualização reavalia os sinalizadores de atraso e a linha “AGORA”. O polling só roda quando o dia exibido foi carregado com sucesso — não durante o carregamento (skeleton) nem no estado de erro de EX-AGM-02, em que a recuperação é pelo “Tentar novamente”. A cada troca de dia e a cada atualização, os atalhos de próximo/anterior dia com consulta são reavaliados (GET /next-appointment-date). Leitores de tela não recebem o anúncio da lista inteira a cada atualização: só o aviso de “sem conexão” é região anunciada.
Se uma atualização em segundo plano falhar (queda de conexão ou erro do back-end) depois de a agenda já ter sido carregada, os últimos dados continuam na tela e um ícone discreto de “sem conexão” aparece dentro do botão da data, com o texto MSG-TAGM-03 como rótulo acessível e dica — mesmo princípio da Central do Médico, Seção 2.7 (EX-AGM-09); o ícone some na próxima atualização bem-sucedida.
Virada do dia: a tela não muda sozinha de dia. Se o dia exibido era hoje e a meia-noite passa (no fuso da clínica), na atualização seguinte ele passa a ser tratado como dia passado — o botão “Hoje” sai do estado ativo e somem a linha “AGORA” e os sinalizadores de atraso; o botão “Hoje” leva ao novo dia.
Critérios de Aceitação
CA-001.1: Dado que o médico abre a Agenda a partir da Central do Médico (título do painel “Consultas” ou indicador “Consultas Hoje”), quando a tela carrega, então exibe a agenda do dia atual, em formato de lista, em ordem cronológica, com o botão “Hoje” no estado ativo.
CA-001.2: Dado que uma consulta tem tags do paciente cadastradas, quando o item é exibido, então aparecem apenas as tags permitidas pelo critério de RN-CM-025 (habilitadas para agendas e dentro da vigência da própria tag) mais a tag VIP, quando o paciente a tiver.
CA-001.3: Dado que uma consulta tem o campo de complemento preenchido, quando o item é exibido, então o complemento aparece completo, em texto secundário, logo acima da linha de informações complementares.
CA-001.4: Dado que a clínica não configurou tipos de consulta, quando os itens são exibidos, então nenhum tipo de consulta aparece em nenhum item.
CA-001.5: Dado que o médico toca em um item de consulta (inclusive dentro de um grupo expandido), então o sistema abre o PEP do paciente correspondente.
CA-001.6: Dado que ocorre erro de rede ou falha do back-end ao carregar a agenda de um dia (carregamento inicial ou troca de dia), então a tela exibe o estado de erro (EX-AGM-02) com MSG-EAGM-03 e a ação “Tentar novamente”, sem nenhum item exibido.
CA-001.7: Dado que o médico navega para um dia sem nenhuma consulta, então a tela exibe o estado vazio (EX-AGM-03) com MSG-TAGM-01.
CA-001.8: Dado que uma consulta é a primeira consulta do paciente, quando o item é exibido, então o ícone circle-number-1 aparece antes das tags — na linha 2 em telas largas, na linha 3 no celular (RN-CM-028) —, com a dica “1ª Consulta” ao passar o mouse, e um leitor de tela anuncia “1ª Consulta”. Dado que não é a primeira consulta, então o ícone não aparece.
CA-001.9: Dado que o dia exibido é hoje, são 10:07 e uma consulta das 09:45 com status Recepcionado ainda não foi iniciada, então o item exibe o sinalizador forte “Esperando · 22min”. Dado que uma consulta das 09:15 com status Agendado ainda não teve chegada registrada, então o item exibe o sinalizador neutro “Não chegou · 52min”. Dado que o dia exibido não é hoje, então nenhum item exibe sinalizador de atraso.
CA-001.10: Dado que uma consulta tem status “Recepcionado” (ou “Aguardando Recepção”), então o item exibe a borda lateral esquerda na cor secondary-pure (ou ff8a80), como na Central do Médico.
CA-001.11: Dado que a tela está aberta com o dia carregado, quando passa 1 minuto, então a agenda do dia exibido é recarregada em segundo plano, refletindo mudanças de status, sem recolher grupos expandidos, sem perder a posição de rolagem e sem tirar o foco do elemento focado. Dado que a tela está no estado de erro de EX-AGM-02, então nenhuma atualização automática substitui esse estado.
CA-001.12: Dado que a agenda já está carregada e uma atualização automática falha, então os últimos dados permanecem visíveis e o ícone de “sem conexão” aparece no botão da data (EX-AGM-09); na próxima atualização bem-sucedida, o ícone some.
CA-001.13: Dado que o médico digita no campo de busca do cabeçalho, então o comportamento é o da Central do Médico, Seção 2.1 (critérios de aceitação de US-CM-000), e selecionar um paciente abre o PEP.
CA-001.14: Dado que uma consulta tem modo de atendimento presencial, então nenhum modo de atendimento aparece no item. Dado que o modo é teleatendimento ou customizado, então “Teleatendimento” ou “Customizado” aparece na segunda linha do item.
CA-001.15: Dado que uma consulta tem status Agendado, então o chip “Agendado” é exibido na primeira linha do item, como os demais status.
CA-001.16: Dado que a tela é exibida num celular (largura abaixo de 640px), então a área fixa do topo (cabeçalho + barra do dia) tem no máximo 120px de altura, a barra do dia ocupa uma única linha e os itens de consulta não exibem avatar.
CA-001.17: Dado que a tela é exibida em largura ≥640px, uma consulta sem complemento, com tipo, modo e tags que cabem na linha, e cujas informações complementares cabem numa linha, então o item tem exatamente 3 linhas: “nome · diagnóstico” + status; tipo · modo + tags + sinalizador de atraso; informações complementares.
CA-001.18: Dado que o paciente tem três diagnósticos, o ícone de 1ª Consulta, duas tags, um complemento longo e as quatro informações complementares, então todos aparecem completos no item, sem reticências — o que não cabe numa linha continua na linha de baixo.
CA-001.19: Dado que o aparelho do médico está em modo escuro e o tema está em “Automático”, quando a tela abre, então ela aparece no tema escuro; dado que o médico escolhe “Claro” no menu do avatar, então a tela passa ao tema claro imediatamente e continua clara nas próximas aberturas no mesmo aparelho, mesmo com o aparelho em modo escuro.
CA-001.20: Dado que a tela está no tema escuro, então todo texto tem contraste mínimo de 4,5:1 com o seu fundo (3:1 para elementos não textuais), incluindo chips de status, tags, sinalizadores de atraso e informações complementares (verificação: Design System, seção 3).
CA-002.1: Dado que o médico toca na seta “próximo dia”, então a tela recarrega mostrando o dia seguinte ao atualmente exibido, independentemente de haver ou não consulta nele.
CA-002.2: Dado que o médico aciona “Próximo dia com consulta” (menu ⋮, atalho » em telas largas ou atalho no topo do calendário), então a tela pula diretamente para a data da próxima consulta não cancelada do médico, ignorando dias vazios e dias só com consultas canceladas.
CA-002.3: Dado que não existe nenhuma consulta futura não cancelada para o médico, então o atalho “Próximo dia com consulta” aparece indisponível em todos os pontos de entrada, com “Nenhum” no lugar da data de destino no menu.
CA-002.4: Dado que o médico toca na data da barra, então o seletor de calendário abre com os dois atalhos rotulados com a data de destino no topo e, no mini-calendário, os dias com ao menos uma consulta não cancelada marcados.
CA-002.5: Dado que o médico está em qualquer dia diferente de hoje, quando toca em “Hoje”, então a tela recarrega mostrando o dia atual, com a rolagem na posição inicial descrita em “Linha AGORA”. Dado que o dia exibido já é hoje, então o botão “Hoje” está no estado ativo e tocar nele não faz nada.
CA-002.6: Dado que a consulta de dias com consulta falha (EX-AGM-06), então os atalhos de dia com consulta aparecem indisponíveis (no menu, com MSG-TAGM-06 no lugar da data) e o calendário abre sem os dias marcados, enquanto as setas dia a dia e o botão “Hoje” continuam funcionando, sem mensagem de erro na tela.
CA-005.1: Dado que existem consultas com status finished no dia, quando a tela carrega, então o botão “N realizadas” (ícone circle-check) aparece na linha de resumo, no topo da lista, com a contagem correta, e as consultas não aparecem individualmente na lista principal.
CA-005.2: Dado que existem consultas com status canceled no dia (qualquer motivo, inclusive falta), quando a tela carrega, então o botão “N canceladas” (ícone circle-x) aparece ao lado do de realizadas, e as consultas expandidas exibem o chip “Cancelado” com contorno, com o horário riscado.
CA-005.3: Dado que o médico toca em um dos botões do resumo, então só aquele grupo expande, logo abaixo da linha de resumo, com os itens esmaecidos; tocar de novo recolhe.
CA-005.4: Dado que nenhuma consulta do dia tem status finished (ou canceled), então o botão correspondente não aparece; sem nenhuma das duas, a linha de resumo não aparece.
CA-005.5: Dado que o dia exibido é hoje, são 10:07 e há uma consulta Agendada das 09:15 ainda sem chegada, quando a tela carrega, então a linha “AGORA” aparece com “10:07” na coluna de horário, na posição cronológica do horário atual, e a rolagem deixa visível, abaixo das barras fixas, a consulta das 09:15. Dado que o dia exibido não é hoje, então a linha não aparece e a rolagem fica no topo.
CA-005.7: Dado que o dia exibido é hoje e passa da meia-noite com a tela aberta, quando ocorre a próxima atualização automática, então o dia continua exibido, agora com o botão “Hoje” fora do estado ativo, sem a linha “AGORA” e sem sinalizadores de atraso.
CA-008.1: Dado que o médico tem acesso a mais de uma clínica do cliente, então cada consulta mostra, na linha de informações complementares, o nome curto da clínica em que ela acontece, com o ícone building-2. Dado que ele tem acesso a uma única clínica, então nenhuma consulta mostra a clínica.
CA-008.2: Dado que o médico tem acesso a duas clínicas e tem consultas nas duas no mesmo dia, então a lista mostra as consultas das duas clínicas juntas, em ordem cronológica.
CA-008.3: Dado que a clínica de uma consulta tem duas ou mais unidades ativas para consultas e a consulta tem unidade definida, então a consulta mostra a unidade, com o ícone map-pin. Dado que a clínica tem uma única unidade ativa para consultas, ou a consulta não tem unidade, então a unidade não aparece.
CA-008.4: Dado qualquer consulta, então o nome curto do convênio aparece, com o ícone id-card — inclusive “Particular” —, e o plano não aparece.
CA-008.5: Dado que a consulta tem classificação e subclassificação, então aparece “Classificação › Subclassificação”, com o ícone folder; dado que tem só classificação, então aparece só a classificação; dado que não tem classificação, então nada aparece no lugar.
CA-008.6: Dado que o médico passa o mouse sobre uma informação complementar, então uma dica mostra o rótulo correspondente (MSG-BAGM-18); dado que um leitor de tela lê o item, então as informações complementares são anunciadas com o rótulo de cada uma.
CA-008.7: Dado qualquer consulta, então a linha de informações complementares tem menos destaque visual que todos os demais textos do item: tamanho 12px, cor color-neutral-pure, sem chips.
Fluxos de Exceção
EX-AGM-02 — Falha ao carregar a agenda do dia
Gatilho: erro de rede ou falha do back-end ao buscar a agenda do dia solicitado, no carregamento inicial ou ao trocar de dia. Comportamento: estado de erro na tela (mensagem MSG-EAGM-03 + ação “Tentar novamente”), sem nenhum item exibido. Recuperação: o médico aciona “Tentar novamente”; se persistir, orientação a contatar o suporte. (Falha numa atualização automática, com a agenda já carregada, segue EX-AGM-09.)
EX-AGM-03 — Dia sem nenhuma consulta
Gatilho: o médico navega para um dia sem nenhuma consulta. Comportamento: estado vazio com MSG-TAGM-01. Não é um erro — é um estado esperado.
EX-AGM-06 — Falha ao carregar dias com consulta (atalhos/calendário)
Gatilho: erro de rede ou falha do back-end ao consultar quais dias têm consulta. Comportamento: degradação silenciosa — atalhos de dia com consulta indisponíveis (no menu, MSG-TAGM-06 no lugar da data) e calendário sem os dias marcados, sem interromper nem exibir erro na tela principal. Recuperação: o recurso volta ao normal na próxima tentativa de abrir o calendário ou de carregar um dia.
EX-AGM-09 — Falha na atualização automática
Gatilho: erro de rede ou falha do back-end numa atualização automática (RN-AGM-013), com a agenda do dia já carregada. Comportamento: os últimos dados permanecem na tela, com o ícone discreto de “sem conexão” no botão da data (MSG-TAGM-03 como rótulo acessível); nenhuma mensagem de erro em tela cheia. Recuperação: automática, na próxima atualização bem-sucedida.
Validações de Campos
Não se aplica: a tela é somente leitura (RN-AGM-001) e não tem campos de entrada próprios. O único campo de entrada é a busca do cabeçalho, com as validações da Central do Médico, Seção 2.1.
Mapeamento de Componentes de Interface
| Componente | Variante | Estados | Tokens aplicados | Uso nesta tela |
|---|---|---|---|---|
| Cabeçalho do sistema | Clínica + busca + menu do usuário | — | Mesmo componente da Central do Médico, Seção 2.1/2.8; no celular, nome da clínica oculto e logotipo de 28px | Topo da tela (RN-AGM-014) |
| Barra do dia | Linha única | — | Altura 52px (celular) / 56px (telas largas); fundo color-base-pure, borda inferior color-neutral-lighter | Navegação por dia |
| Button | Data (abre calendário) | default, hover, offline | Texto color-neutral-darker, 16px (celular) / 18px; ícone Lucide chevron-down; offline: ícone wifi-off em color-highlight-dark | Barra do dia |
| Button | Ícone (setas, atalhos, ⋮) | default, hover, disabled | 44×44px, ícones Lucide chevron-left/right, chevrons-left/right, more-vertical | Barra do dia |
| Button | ”Hoje” (pill) | default, hover, active | active: bg color-secondary-light, texto color-secondary-dark — mesmo par do Toggle Pill ativo da Central | Barra do dia |
| Menu | Overflow (⋮) | fechado, aberto; item indisponível | bg color-base-pure, shadow-medium, radius-m; itens 44px com subtítulo color-neutral-pure | Qualquer largura: atalhos de dia com consulta |
| Linha de consulta | Coluna de horário + 2 linhas + informações complementares (mais linhas só com complemento ou com tags/informações que não cabem); sem truncamento | default, hover, focus, recepcionado, aguardando, realizada (grupo, opacidade 0,8), cancelada (grupo, opacidade 0,6, horário riscado, nome color-neutral-pure) | Coluna 52px: início 14px color-neutral-darker, término 12px color-neutral-pure; bordas por status da Central (Seção 2.3/2.8) | Cada consulta do dia |
| Texto com ícone | Informações complementares | default, hover (dica) | 12px, color-neutral-pure; ícones Lucide 14px na mesma cor — building-2 (clínica), map-pin (unidade), id-card (convênio), folder (classificação); 12px entre os itens | Última linha de cada consulta (RN-AGM-017) |
| Avatar | Iniciais na cor do status | default | bg --color-status-{status}-bg, texto --color-status-{status}-fg (mesmo par do chip); Cancelado com contorno --color-status-canceled-border; só em telas largas | Consulta sem foto do paciente |
| Chip | Status (consulta) | default | --color-status-{status}-bg / -fg (Design System, seção 4 — valores claros = paleta da Central, RN-CM-005; Cancelado: --color-status-canceled-*, com contorno de 1px --color-status-canceled-border e sem fundo); 11px | Status de cada consulta |
| Badge | Atraso — “Esperando” | default (pulsante) | bg color-error-pure, texto color-base-pure (mesmo componente do badge de atraso da Central) | Paciente na clínica, horário vencido, só hoje |
| Badge | Atraso — “Não chegou” | default | bg color-neutral-lighter, texto color-neutral-dark, sem animação | Paciente não chegou, horário vencido, só hoje |
| Texto | Modo de atendimento | default | color-secondary-dark | Só teleatendimento/customizado |
| Chip | Tag do paciente | default | Padrão .chip-tag do Design System (seção 5) com a cor da tag do cadastro | Linha 2 (telas largas) / linha 3 (celular) |
| Ícone | 1ª Consulta | default, hover (dica) | Tabler circle-number-1 (react-icons TbCircleNumber1), 18px, cor --color-first-visit, sem fundo | Antes das tags |
| Button | Pill de resumo (realizadas / canceladas) | recolhido, expandido | 44px; borda color-neutral-lighter; expandido: bg color-neutral-lighter; ícone 18px — realizadas: Lucide circle-check em --color-status-finished-fg; canceladas: circle-x em color-neutral-pure | Resumo de RN-AGM-010 |
| Divider com rótulo | Linha “AGORA” | default | color-error-pure (horário na coluna de horário, ponto e traço) | Horário atual, só hoje |
| Bottom Sheet / Painel | Seletor de calendário | default | Mesma anatomia de modal do Design System; no celular, bottom sheet com alça de arrasto | Escolha de dia |
| Date Picker | Mini-calendário mensal + atalhos rotulados | default, dia-com-consulta, hoje, selecionado | Ponto color-primary-dark sob o dia com consulta; dias de 44px | Seletor de data |
| Menu do usuário | Seletor de tema | Automático, Claro, Escuro (menuitemradio) | Opção ativa: bg color-secondary-light, texto color-secondary-dark; ícones Lucide monitor, sun, moon | Menu do avatar, acima de “Sair” |
| Empty/Error State | Tela cheia (sem itens) | error, empty | color-error-pure ícone e texto, botão “Tentar novamente” (erro) | EX-AGM-02, EX-AGM-03 |
| Skeleton | Lista | loading | color-neutral-lighter | Carregamento de um dia |
Integração com Backend
GET /api/v1/patients/search — endpoint da Central do Médico (Seção 2.9), reutilizado sem mudança pela busca do cabeçalho.
GET /api/v1/agenda/doctor/day
Função: retorna as consultas do médico logado para um dia específico, de qualquer status (inclusive canceladas), de todas as clínicas do cliente (RN-AGM-002). Critério de seleção: o mesmo do endpoint de consultas da Central do Médico (Mapeamento de Banco de Dados da Central, Seção 4.1), sem o filtro de “hoje” (substituído por date) e sem o filtro de situação.
Query params: date (obrigatório, YYYY-MM-DD).
Polling: a cada 1 minuto, para o dia exibido (RN-AGM-013).
Códigos: 200 (sucesso); 400 (date ausente ou inválida); 500 (falha — EX-AGM-02 no carregamento, EX-AGM-09 no polling).
Response 200: { "date": "2026-09-29", "serverNow": "2026-09-29T10:07:00-03:00", "appointments": [ { "id": "uuid", "patient": { "id": "uuid", "preferredName": "", "legalName": "Maria da Silva", "photo": "url|null", "diagnosis": ["Ca. Mama"] }, "startTime": "08:00", "endTime": "08:30", "status": "finished", "attendanceMode": { "code": "P", "label": "Presencial" }, "delayMinutes": 0, "firstTime": false, "tags": ["vip"], "complement": "string|null", "appointmentType": "string|null", "clinic": "string|null", "unit": "string|null", "insurance": "string", "classification": { "name": "string", "subName": "string|null" } } ] }
serverNow: data e hora atuais do servidor, no fuso da clínica (ISO 8601 com deslocamento) — referência de tempo da tela.status: um dos valores deAppointmentStatus()da Central do Médico (Seção 4.1):scheduled | waiting | checked | consultation | finished | canceled.attendanceMode:code(Ppresencial — padrão, omitido na tela;Tteleatendimento;Ccustomizado) elabel, termo já traduzido para o idioma da clínica (mesma origem do campo da Central do Médico, Seção 4.1). O código existe nesta tela porque a regra de omitir o valor padrão não pode depender de comparar o rótulo traduzido.delayMinutes: mesma regra do campo homônimo da Central do Médico (Seção 2.9/4.1) — minutos desde o início, positivo só quando o horário de início já passou e a consulta não foi iniciada nem finalizada; sempre0quandodatenão é hoje. O front escolhe a variante do sinalizador pelostatus:waiting/checked→ “Esperando”;scheduled→ “Não chegou”.tags: já filtradas pelo back-end pelo critério de RN-CM-025 (RN-AGM-006). Nunca contém “1ª Consulta”: ela é derivada defirstTime(boolean) (RN-CM-028). Cor e descrição de cada tag: mesmo contrato do endpoint de consultas da Central do Médico — lacuna registrada no Histórico de Versões (v1.1), a resolver na Seção 4.clinic: nome curto da clínica da consulta, ounullquando o médico tem acesso a uma única clínica do cliente (RN-AGM-017, a) — a condição é aplicada pelo back-end, para o front não precisar saber quantas clínicas o usuário acessa.unit: unidade de atendimento da consulta, ounullquando a clínica tem no máximo uma unidade ativa para consultas, ou quando a consulta não tem unidade (RN-AGM-017, b) — condição aplicada pelo back-end.insurance: nome curto do convênio da consulta, sempre presente, inclusive particular (RN-AGM-017, c). O plano não faz parte do contrato.classification:nullquando a consulta não tem classificação; senãonameesubName(nullquando não há subclassificação) (RN-AGM-017, d).startTime/endTime:HH:MMno fuso da clínica;endTime = "24:00"indica o fim exato do dia.- Mapeamento de BD: Seção 4 (a escrever).
GET /api/v1/agenda/doctor/days-with-appointments
Função: retorna as datas, dentro de um intervalo limitado, que têm ao menos uma consulta não cancelada do médico logado (mesmo critério de seleção de GET /day) — usado pelo marcador do calendário (RN-AGM-003). Consultas canceladas não contam.
Query params: from (obrigatório, YYYY-MM-DD), to (obrigatório, YYYY-MM-DD; intervalo máximo de 62 dias).
Códigos: 200; 400 (datas inválidas ou intervalo acima do máximo); 500 (EX-AGM-06).
Response 200: { "dates": ["2026-10-01", "2026-10-03", "2026-10-08"] }
GET /api/v1/agenda/doctor/next-appointment-date
Função: retorna a data da próxima (ou anterior) consulta não cancelada do médico logado (mesmo critério de seleção de GET /day), sem limite de horizonte — usado pelos atalhos de dia com consulta (menu ⋮, atalhos « » e topo do calendário, que exibem a data de destino). Consultas canceladas não contam.
Query params: direction (obrigatório, next ou previous), from (obrigatório, YYYY-MM-DD — normalmente o dia exibido; a própria data não é considerada).
Chamado a cada carregamento de dia e a cada atualização automática, uma vez por direção.
Códigos: 200; 400 (parâmetros inválidos); 500 (EX-AGM-06).
Response 200: { "date": "2026-10-07" } ou { "date": null } quando não há nenhuma consulta naquela direção.
Catálogo de Mensagens do Sistema e Termos de Interface (i18n)
Mensagens da busca do cabeçalho: ver Central do Médico, Seção 2.1 (MSG_searchPac, MSG_searchFoot, MSG_searchMin, MSG_searchNone). Rótulos de status: ver Central do Médico, Seção 2.3 — o rótulo “Cancelado” é o termo status-cancelado da Central do Médico, Seção 2.6. Rótulos de modo de atendimento: termos traduzidos do próprio domínio (attendanceMode.label). Nomes de clínica, unidade, convênio e classificação: dados do cadastro, exibidos como estão.
| ID | Contexto | pt-BR | en-US | es-419 |
|---|---|---|---|---|
| MSG-EAGM-03 | Falha ao carregar a agenda do dia (EX-AGM-02) | “Não foi possível carregar a agenda. Tente novamente." | "Could not load the schedule. Please try again." | "No fue posible cargar la agenda. Inténtelo de nuevo.” |
| MSG-TAGM-01 | Dia sem consulta (EX-AGM-03) | “Nenhuma consulta neste dia." | "No appointments on this day." | "Ninguna consulta en este día.” |
| MSG-TAGM-03 | Atualização com falha (EX-AGM-09) — rótulo acessível do ícone | ”Offline — dados podem estar desatualizados" | "Offline — data may be out of date" | "Sin conexión — los datos pueden estar desactualizados” |
| MSG-TAGM-05 | Legenda do calendário | ”Dia com consulta" | "Day with appointments" | "Día con consultas” |
| MSG-TAGM-06 | Atalhos/calendário sem dados (EX-AGM-06) | “Indisponível no momento” / “Marcadores indisponíveis no momento." | "Unavailable right now” / “Markers are unavailable right now." | "No disponible en este momento” / “Marcadores no disponibles en este momento.” |
| MSG-BAGM-03 | Botão de voltar para hoje / prefixo da data de hoje | ”Hoje" | "Today" | "Hoy” |
| MSG-BAGM-07 | Resumo de realizadas (singular / plural) | “1 realizada” / “{n} realizadas" | "1 completed” / “{n} completed" | "1 realizada” / “{n} realizadas” |
| MSG-BAGM-08 | Resumo de canceladas (singular / plural) | “1 cancelada” / “{n} canceladas" | "1 canceled” / “{n} canceled" | "1 cancelada” / “{n} canceladas” |
| MSG-BAGM-09 | Linha do horário atual (rótulo acessível) | “Agora, {hh:mm}" | "Now, {hh:mm}" | "Ahora, {hh:mm}“ |
| MSG-BAGM-12 | Botão do estado de erro | ”Tentar novamente" | "Try again" | "Intentar de nuevo” |
| MSG-BAGM-14 | Sinalizadores de atraso | ”Esperando · {n}min” / “Não chegou · {n}min" | "Waiting · {n}min” / “Not arrived · {n}min" | "Esperando · {n}min” / “No llegó · {n}min” |
| MSG-BAGM-16 | Menu e atalhos de dia com consulta | ”Mais opções” / “Próximo dia com consulta” / “Dia anterior com consulta” / “Nenhum” / “Escolher dia" | "More options” / “Next day with appointments” / “Previous day with appointments” / “None” / “Choose day" | "Más opciones” / “Próximo día con consultas” / “Día anterior con consultas” / “Ninguno” / “Elegir día” |
| MSG-BAGM-17 | Seletor de tema no menu do usuário | ”Tema” / “Automático” / “Segue o sistema do aparelho” / “Claro” / “Escuro" | "Theme” / “Automatic” / “Follows the device setting” / “Light” / “Dark" | "Tema” / “Automático” / “Sigue la configuración del dispositivo” / “Claro” / “Oscuro” |
| MSG-BAGM-18 | Rótulos das informações complementares (dica e leitor de tela) | “Clínica” / “Unidade de atendimento” / “Convênio” / “Classificação" | "Clinic” / “Care unit” / “Health plan” / “Classification" | "Clínica” / “Unidad de atención” / “Convenio” / “Clasificación” |
Conformidade SBIS (detalhamento)
ECF.05.04 — Especificação do tipo de consulta (estágio 2, recomendado) — atendido pela exibição do tipo de consulta em cada item da lista, quando configurado pela clínica (RN-AGM-008).
ECF.05.01 / ECF.05.02 / ECF.05.03 — Parametrização de agendas, parametrização de bloqueios em dias específicos e agendamento de consultas (estágios 2 / 2 / 1) — fora de escopo desta tela, que é somente leitura (RN-AGM-001); pertencem ao Agendamento (Recepção). ECF.05.03 é obrigatório no estágio 1 e precisa ser coberto por aquela funcionalidade (ver Definição, tabela SBIS).
ECF.03.11 / ECF.03.14 — Busca simples de pacientes / Dados da lista de pacientes para seleção de prontuários (estágio 1, obrigatórios) — atendidos pela busca do cabeçalho, reutilizada da Central do Médico (RN-AGM-014); detalhamento na Central do Médico, Seção 2.10.
NGS1.07.03 / NGS1.07.04 — Eventos registrados na trilha de auditoria (estágio 1 / 2) — a leitura da agenda de um dia (GET /day no carregamento de um dia — a lista expõe nome e diagnóstico de pacientes; o polling não gera novo evento para o mesmo dia) e a abertura do PEP a partir dela devem gerar evento de auditoria, mesmo padrão já usado em outras funcionalidades assistenciais deste projeto.
ECF.17.19 — Mensagens do sistema (estágio 1, obrigatório) — todas as mensagens exibidas ao médico estão catalogadas acima (ou na Central do Médico, para os elementos reutilizados), em linguagem não técnica, em português do Brasil, com suporte multilíngue para en-US e es-419.
Histórico de Versões
- v1.0 (31/08/2026) — Arquivo criado. Especificação completa a partir das RNs fechadas na Seção 1 (v1.5): cabeçalho de navegação (RN-AGM-003, com os dois mecanismos de atalho confirmados pelo solicitante — setas de atalho e seletor de calendário), lista de consultas com os elementos herdados e os dois campos novos (RN-AGM-006/007/008/009), bloco de consultas já realizadas (RN-AGM-010), e o fluxo completo de bloqueio de horário (RN-AGM-004), incluindo a confirmação do solicitante de que o próprio médico pode desfazer um bloqueio e que o complemento é opcional nesse fluxo. Duas decisões de UI ainda não pedidas ao solicitante ficaram marcadas [PROPOSTA] no corpo (granularidade de horário do formulário de bloqueio; confirmação leve inline ao desfazer) — a confirmar antes do Protótipo (Seção 3). Deixado [A DEFINIR] se um bloqueio já ocorrido também deveria entrar no bloco recolhido de RN-AGM-010, por não estar coberto pela redação literal da regra.
- v1.0 (revisão) (01/09/2026) — Submetido ao subagente crítico técnico antes de fechar a fase (Lição #20). Achados verificados contra o texto e corrigidos: (1) campo
typerenomeado paraattendanceModeno JSON de exemplo, com nota de nomenclatura no corpo distinguindo-o deappointmentType— nomes muito parecidos, campos diferentes; (2) removido o campodelayMinutesdo JSON de exemplo — não estava descrito em nenhuma regra nem na lista de elementos exibidos, ficou como campo “fantasma”; (3) resposta doDELETE /blocks/{id}renomeada destatuspararesult, evitando colisão de nome com ostatusde atendimento clínico usado noGET /day; (4) adicionado"kind": "block"na resposta doPOST /blocks, alinhando com o formato do item de bloqueio já usado noGET /day; (5) adicionadas CA-001.6, CA-001.7, CA-003.4 e CA-004.3, cobrindo os quatro Fluxos de Exceção (EX-AGM-02/03/04/05) que não tinham nenhum Critério de Aceitação correspondente; (6) corrigida a tabela de Mapeamento de Componentes — EX-AGM-02 estava listado como “Toast”, mas o texto do próprio fluxo descreve um estado de erro em tela cheia; criadas linhas próprias para os estados de erro/vazio de tela cheia (EX-AGM-02, EX-AGM-03), mantendo Toast só para EX-AGM-04/05; (7) qualificada a linha “AGORA” (RN-AGM-010) como exclusiva do dia de hoje — em outro dia a lista abre no topo, sem a linha; (8) identificada e resolvida a tensão entre RN-AGM-003 (“sem limite de horizonte”) e o endpointdays-with-appointments, que exigefrom/tolimitados: criado um segundo endpoint,GET /next-appointment-date, sem limite de intervalo, dedicado ao atalho sequencial —days-with-appointmentspassa a servir só o marcador visual do calendário (mês exibido); (9) criado EX-AGM-06 (falha ao consultar dias com consulta), cobrindo um cenário de erro que não tinha nenhum tratamento especificado, com degradação silenciosa por não ser caminho crítico; (10) removido o código 403 doDELETE /blocks/{id}— como o endpoint já é escopado ao médico logado (RN-AGM-002), um bloqueio de outro médico não é alcançável nesse escopo; consolidado em 404, evitando revelar a existência de bloqueios de outros médicos; (11) adicionada validação [PROPOSTA] impedindo bloqueio de horário já no passado — não pedida ao solicitante, a confirmar. Nenhum achado do crítico foi descartado como falso positivo nesta rodada. - v1.1 (29/09/2026) — Acompanha 01-Definição v1.6 (alinhamento com a Central do Médico e decisões do solicitante desta rodada). Pedidos/decisões do solicitante: (1) cabeçalho com a mesma busca de pacientes da Central do Médico — nova subseção “Cabeçalho do Sistema”, reutilizando por referência a Seção 2.1 da Central (US-CM-000, mensagens
MSG_search*,GET /api/v1/patients/search), e a barra de navegação do dia passa a ficar abaixo dele; (2) bloqueio já ocorrido permanece como item individual — resolvido o [A DEFINIR] da v1.0, com CA-005.6; (3) bloqueio no passado proibido — [PROPOSTA] da v1.0 confirmada (RN-AGM-012): botão desabilitado em dias passados (CA-001.7 ajustado, CA-003.5 novo), opções de início só futuras no dia de hoje (CA-003.6), revalidação ao confirmar (EX-AGM-07, MSG-EAGM-06, CA-003.7, código 422 noPOST); extensão ao desfazer — só antes de o bloqueio começar (EX-AGM-08, MSG-EAGM-07, CA-004.4/004.5, código 422 noDELETE); (4) selo de atraso como na Central —delayMinutesvolta ao JSON deGET /day(tinha sido removido na revisão técnica da v1.0 como campo “fantasma”, mas é um elemento herdado da Central), exibido só no dia de hoje (CA-001.9); (5) consultas realizadas e canceladas em dois blocos separados, não num bloco único “já realizadas” (que misturava canceladas e faltas sob um rótulo de “realizadas”) — subseção reescrita, CA-005.1 a 005.4, MSG-BAGM-07/08; (6) as duas [PROPOSTA] de UI da v1.0 confirmadas: formulário com intervalos de 15 minutos e durações 15/30/45/60/Outro (detalhado: campo de data somente leitura, término calculado, limite no fim do dia, validação de “Outro” — MSG-EAGM-08, CA-003.9, código 400) e desfazer com confirmação rápida inline — o intervalo de “alguns segundos” da v1.0 foi fixado em 5 segundos, valor escolhido pelo Designer nesta versão, sujeito a ajuste. Alinhamento com a Central do Médico (aprovado pelo solicitante): tags pelo critério de RN-CM-025 (CA-001.2 reescrito — antes citava só o bit de agendas) e tag “1ª Consulta” por RN-CM-028 (CA-001.8); statuscanceledcom chip “Cancelado” em token neutro (color-neutral-light/color-neutral-dark) — a paleta da Central não tinha esse status porque a Central não exibe canceladas; destaque por borda lateral de “Recepcionado”/“Aguardando Recepção” (CA-001.10); lista de valores destatusexplicitada como a deAppointmentStatus()da Central (Seção 4.1); atualização automática a cada 1 minuto e indicador “Offline” (RN-AGM-013 — CA-001.11/001.12, EX-AGM-09, MSG-TAGM-03); indicador “Consultas Hoje” da Central como segundo ponto de entrada (CA-001.1); bloqueios fora do painel e do KPI da Central (RN-AGM-011 — CA-006.1, detalhe na Central do Médico, Especificação v4.37). Outros ajustes desta versão: (a) a linha “AGORA” passa a ser posicionada cronologicamente entre os itens individuais, não mais “logo abaixo do bloco” — ajuste necessário porque, com bloqueios já ocorridos e consultas atrasadas permanecendo como itens individuais, a descrição anterior colocaria a linha acima de itens anteriores ao horário atual (esclarecimento de comportamento, proposto pelo Designer); (b) atalho “próximo dia com consulta”, marcador do calendário e endpointsdays-with-appointments/next-appointment-datepassam a ignorar bloqueios (consequência de RN-AGM-011) e consultas canceladas (proposta do Designer, ver Histórico da Definição v1.6); (c) mecanismo do registro de bloqueio (paciente/convênio reservados,TipoAgenda = 'C'como default, decidido pelo solicitante) deixa de ser citado no corpo doPOST— fica para a Seção 4; (d) layout mobile-first explicitado (premissa da Definição v1.6), com comportamento do cabeçalho e da barra em telas estreitas; (e) formulário de bloqueio como modal / bottom sheet (a v1.0 deixava “modal ou tela dedicada” para a Seção 3); (f) nova linha de componentes: cabeçalho do sistema, badge de atraso, pill de duração, indicador offline; estado “past” do item bloqueado; (g) nova subseção de conformidade ECF.03.11/03.14 (por referência). Acompanha 03-Protótipo v1.0. - v1.1 — Revisão por Dois Críticos (29/09/2026, mesma versão, antes da entrega ao solicitante) — Crítico técnico (subagente independente, com execução do protótipo no Playwright em 360px e 1280px) sobre esta Especificação e o Protótipo v1.0; 30 achados, cada um verificado contra o texto/código antes de aplicar. Aplicados nesta Especificação: (1) posição inicial da rolagem escondia consultas atrasadas ainda pendentes atrás das barras fixas (medido) — rolagem passa a ir para a primeira consulta que ainda exige ação, com deslocamento pela altura real das barras (CA-005.5 reescrito; mesmo achado do crítico de negócio); (2) referência de tempo ambígua (relógio do dispositivo × fuso da clínica) — novo campo
serverNowemGET /daye parágrafo “Referência de tempo”; regra de virada do dia (CA-005.7); (3) polling podia substituir o estado de erro de EX-AGM-02 e o skeleton (medido) — polling só com o dia carregado (CA-001.11 ampliado), sem perda de foco e sem anunciar a lista inteira a leitores de tela; (4) estado “Confirmar?” sofria condição de corrida com re-renderizações (reproduzido) — explicitado que o estado pertence ao item; (5)DELETE404 sem tratamento — novo EX-AGM-10, MSG-IAGM-01, CA-004.6;POST400 mapeado para MSG-EAGM-08/02; (6) EX-AGM-06 era o único fluxo de exceção sem CA — novo CA-002.6; (7) textos exibidos fora do catálogo — incluídos MSG-TAGM-04/05/06, MSG-SAGM-01/02, MSG-BAGM-12 e novos rótulos em MSG-BAGM-11; “Cancelado” passa a reutilizar o termostatus-canceladoda Central do Médico, Seção 2.6 (MSG-BAGM-10 removida — tinha es-419 divergente, “Cancelada”); (8) dica do botão desabilitado viatitlenão chega ao toque nem ao teclado — botão passa aaria-disabled, com toast ao acionar (CA-003.5 reescrito); (9) contraste do avatar com texto branco sobre as cores claras de status (1,27:1 a 1,66:1) — textocolor-neutral-darker; nova linha “Avatar” nos componentes; (10)attendanceModetinha três representações (código no JSON, termo traduzido no Mapeamento da Central, rótulo no protótipo) — declarado como termo já traduzido, igual à Central 4.1, exemplo corrigido; (11)firstTimeboolean etagsnunca contém “1ª Consulta” (evita duplicidade com a Central, que lista1a_consultacomo valor detags); (12) “24:00” declarado explicitamente emendTime; (13) códigos 400/500 dos GETs, intervalo máximo de 62 dias emdays-with-appointments(valor escolhido pelo Designer — dois meses de calendário) e momento de chamada denext-appointment-date; (14) auditoria da leitura da agenda (GET /day) e da abertura do PEP; (15) acessibilidade do formulário (foco preso,aria-invalid), alvos de toque de 44px em telas estreitas, itens dos blocos expandidos esmaecidos como na Central, complemento validado sem espaços nas pontas com o contador contando o mesmo valor; (16) ECF.05.02 como atendimento parcial e títulos/estágios corretos de ECF.03.11/03.14 (conferidos na planilha SBIS — ver Definição v1.6). Registrados como pendência, sem mudança: o contrato detags(strings) não traz cor nem descrição, embora a cor venha do cadastro da tag (RN-CM-025) — o endpoint de consultas da Central tem a mesma lacuna; a resolver junto com a Seção 4 das duas funcionalidades. Não aplicados: contraste de textos secundários (color-neutral-medium/neutral-pure) e da tag de quimioterapia, e divergência do par de cores do chip “Finalizado” — padrões pré-existentes da Central/Design System, fora do escopo desta revisão; prefixo AGM nos IDs de CA — o padrão atualCA-00X.Yé o mesmo da v1.0 e de outros documentos; padrão combobox completo da busca — comportamento da Central, registrado como achado para aquele documento. - v1.2 (29/09/2026) — Acompanha 01-Definição v1.7. Redesenho de layout a pedido do solicitante (“a parte fixa com a data e os botões de navegação ocupa muito espaço; no celular ocuparia metade da tela”), a partir de uma revisão por dois subagentes independentes — um médico oncologista (uso real entre consultas, no celular) e um especialista em UX mobile — que mediram o protótipo v1.0: área fixa de 181px (28% da tela útil num Android, 33% num iPhone SE) e, somando os grupos recolhidos e o bloqueio passado, primeira consulta que exige ação só depois de 55–64% da tela. Aplicado o que os dois recomendaram em comum e o solicitante aprovou (“pode seguir”): (1) barra do dia em uma linha — a data vira o botão que abre o calendário (sai o botão de calendário separado), o rótulo “Hoje” separado dá lugar ao estado ativo do botão “Hoje”, e no celular os atalhos de dia com consulta saem da barra para o menu ⋮ e para o topo do calendário, com a data de destino escrita (o ícone de seta dupla, sozinho, não foi entendido pelo médico-crítico); em telas largas continuam ao lado das setas; área fixa-alvo ~116px; (2) coluna de horário à esquerda (início em destaque, término abaixo) — o horário ficava pequeno, cinza e à direita; (3) anatomia fixa do card em 2 linhas (+1 opcional para tags/complemento) — o card quebrava de 2 a 4 linhas de forma imprevisível; avatar removido no celular (a coluna de horário ocupa o lugar; em telas largas continua); (4) grupos de realizadas/canceladas viram uma linha de resumo com dois botões lado a lado; bloqueio terminado vira linha fina; (5) snackbar na base da tela, não no topo; ícone de “sem conexão” dentro do botão da data; formulário de bloqueio mais compacto (data no título, durações numa linha, complemento de uma linha que cresce, rodapé fixo). Decisões do solicitante nesta rodada: (a) “Bloquear horário”: entre o botão flutuante (proposta do UX) e o menu ⋮ + toque num horário livre (proposta do médico), o solicitante escolheu a segunda para ver no protótipo — novas linhas de horário livre (RN-AGM-016, US-AGM-007), tocáveis, que abrem o formulário pré-preenchido com o intervalo; em telas largas o botão continua na barra; (b) sinalizador de atraso separado em “Esperando” (forte) e “Não chegou” (neutro), só nesta tela — a Central do Médico está congelada para fechar a versão (achado do médico-crítico: o mesmo selo vermelho servia para “o paciente está me esperando” e “o paciente não chegou”); (c) status “Agendado” continua sempre exibido, por consistência (o médico-crítico propôs escondê-lo); o modo de atendimento presencial (padrão) é omitido e teleatendimento/customizado aparecem sempre — o JSON de
GET /daypassa a trazerattendanceModecomo{ code, label }, porque a omissão não pode depender do rótulo traduzido (na v1.1 era só o termo traduzido); (d) horário de trabalho (RN-AGM-015): o bloqueio só pode ser criado dentro dele — opções de início limitadas, término limitado ao fim do intervalo de trabalho, novo EX-AGM-11 / MSG-EAGM-09 / CA-003.10 / CA-003.11 e MSG-TAGM-07; aviso de ausência no dia (MSG-TAGM-08, CA-007.4);GET /dayganhaworkWindows,absenceefreeSlots(horários livres calculados pelo back-end — escolha do Designer, para uma única fonte de verdade com o futuro Agendamento); (e) quem desfaz: qualquer bloqueio da agenda do médico, criado por ele ou pela Recepção — o critério éAgenda.IdChRecurso, sem saber quem criou (esclarecimento do solicitante) — US-AGM-004 e textos ajustados; (f) encerrar antes do fim um bloqueio em andamento — nova US-AGM-006, novo endpointPATCH /blocks/{id}/end(término definido pelo servidor, no minuto exato — escolha do Designer; o solicitante não definiu arredondamento), EX-AGM-12, MSG-EAGM-10/11, MSG-SAGM-03, MSG-BAGM-13, CA-004.7/004.8; EX-AGM-08 e MSG-EAGM-07 passam a orientar para “Encerrar agora”. Não aplicado, registrado: coluna lateral com mini-calendário fixo em telas largas (proposta opcional dos dois críticos) — deixada para avaliação depois de o solicitante ver o novo layout; gesto de deslizar entre dias (proposta do médico) — não implementado (o UX alertou para conflito com o gesto de voltar do sistema); resumo numérico do dia (“2 esperando · 5 restantes”) proposto pelo médico — não incluído, para não somar uma linha à área fixa. Mensagens renumeradas/ajustadas: MSG-BAGM-02 passa a “Desfazer” (antes “Desfazer bloqueio”), MSG-BAGM-07/08 com ”✓”/”✕”, MSG-BAGM-09 passa a rótulo acessível, novas MSG-BAGM-14/15/16. Acompanha 03-Protótipo v1.1. - v1.3 (29/09/2026) — Acompanha 01-Definição v1.8. Decisões do solicitante ao avaliar o Protótipo v1.1: (1) início do bloqueio só entre os horários livres, em fatias de 15 minutos (antes: qualquer horário dentro do horário de trabalho, com a sobreposição validada só ao confirmar) — descrição do formulário, CA-003.6 reescrito com a lista exata de opções, validações; o término passa a ser limitado pelo fim do horário livre, não mais do intervalo de trabalho — EX-AGM-11 e MSG-EAGM-09 reescritos, durações que não cabem ficam indisponíveis (CA-003.10 reescrito, novo CA-003.13); EX-AGM-01 passa a cobrir só a condição de corrida no envio (CA-003.2 reescrito); MSG-TAGM-04 generalizada para “nenhum horário livre no dia”; (2) duração inicial de 15 minutos ao abrir o formulário, por qualquer entrada (antes, a partir de um horário livre, o intervalo inteiro — escolha do Designer na v1.2) — CA-003.1 reescrito, novo CA-003.12; (3) “Bloquear horário” sai da barra em telas largas e fica no menu ⋮ em qualquer largura — o solicitante achou o botão destacado demais para uma ação de uso eventual; os atalhos « » continuam visíveis em telas largas — novo CA-003.14, linha do botão removida da tabela de componentes; (4) “Encerrar agora” e troca de layout em 640px aprovados, sem mudança. Acompanha 03-Protótipo v1.2.
- v1.4 (30/09/2026) — Pedido do solicitante: “fazer o possível para cada card (em desktop) ficar com 2 linhas”. Uma primeira proposta do Designer (complemento na linha 1 e tags na linha 2, truncando o excedente com reticências e “+N”, com o texto completo ao passar o mouse) foi recusada pelo solicitante — “melhor ter as informações completas do que exigir que o usuário passe o mouse ou clique”. Adotado o arranjo definido pelo solicitante para telas largas: linha 1 = nome + diagnóstico + status; linha 2 = tipo, modo, tags e sinalizador de atraso; linha 3 = complemento (se houver); tags que não couberem na linha 2 continuam na linha de baixo. Nenhum texto do item é truncado — regra estendida pelo Designer a toda a anatomia (a v1.2/v1.3 truncava nome, linha 2 e complemento do bloqueio com reticências), em coerência com o princípio dado pelo solicitante. Celular: mantida a anatomia da v1.3 (nome + status / diagnóstico, tipo, modo + atraso / tags e complemento), só sem truncamento — escolha do Designer, porque em 360px nome, diagnóstico e status numa linha quebrariam quase sempre; a confirmar pelo solicitante. Novos CA-001.17/001.18; CA-001.3/001.8 ajustados; item de bloqueio sem truncamento. Acompanha 03-Protótipo v1.3; Definição inalterada (só cabeçalho).
- v1.5 (30/09/2026) — Pedido do solicitante (lembrado pelos stakeholders): tema escuro com regras claras de conversão de cores, valendo para todo o sistema. As regras foram definidas no Design System (seções 1 a 6: papéis dos tokens, regras de conversão C1–C7 com contraste verificado, tokens de status, padrão de tag com cor do cadastro, seleção de tema), não nesta especificação; aqui entram apenas: parágrafo “Tema claro e escuro” no início da Seção 2, CA-001.19/001.20, linhas de componente de avatar, chip de status, chip de tag, snackbar e novo seletor de tema no menu do usuário, e MSG-BAGM-17. Escolha do Designer: o seletor de tema fica no menu do avatar (Automático como padrão), e a escolha é guardada no aparelho — [PROPOSTA] no Design System (guardar no perfil do usuário depende de campo inexistente). O avatar de iniciais passa a usar o mesmo par de cores do chip de status (antes, no tema claro, a cor de referência do status — ex.: roxo 9679e1 em Finalizado), para que o texto das iniciais tenha contraste nos dois temas. A Central do Médico, congelada, não foi alterada. Acompanha 03-Protótipo v1.4.
- v1.6 (30/09/2026) — Pedido do solicitante: representar a 1ª Consulta por um ícone em vez do termo escrito. Seis candidatos das bibliotecas permitidas (Lucide e react-icons) foram comparados no card, nos dois temas (
Ícone 1ª Consulta — opções (exploração).html); o solicitante escolheucircle-number-1(Tabler, react-iconsTbCircleNumber1), a recomendação do Designer. Detalhes de apresentação escolhidos pelo Designer: ícone sem fundo (a versão dentro de um chip redondo ficou apertada na exploração), 18px, antes das tags, dica e rótulo acessível “1ª Consulta”; cor pelo novo token--color-first-visitdo Design System (#5E35B1 no claro, 8,0:1 sobre branco; 9e86d0 no escuro pela regra C5, 5,5:1 sobre a superfície) — a cor usada até aqui no chip (#EDE7F6/#4527A0) nunca tinha sido token. Atualizados: anatomia do item (telas largas e celular), novo parágrafo do ícone, CA-001.8/001.18, tabela de componentes. A Central do Médico (congelada) continua com a tag em texto — levar o ícone para lá junto com o tema escuro. Acompanha 03-Protótipo v1.5. - v1.7 (01/10/2026) — Pedido do solicitante: no tema escuro, consultas realizadas e canceladas tinham pouca diferenciação. Diagnóstico do Designer: as duas pills de resumo eram idênticas (só o caractere ✓/✕ mudava); pela regra C6, o fundo escuro de Finalizado (#302F52) e o de Cancelado (#383F51) ficavam com saturação parecida; e a opacidade de 0,6 aplicada a todos os itens expandidos apagava o que restava de cor. Propostas do Designer aprovadas pelo solicitante (“ok, faça as alterações”), resolvendo pela forma e não só pela cor (WCAG 1.4.1): (1) pills com ícone Lucide —
circle-checkna cor--color-status-finished-fgpara realizadas,circle-xemcolor-neutral-purepara canceladas —, que substitui os caracteres ✓/✕ dos textos (MSG-BAGM-07/08 sem o símbolo); (2) chip e avatar Cancelado com contorno (fundo transparente, textocolor-neutral-dark, contorno de 1pxcolor-neutral-light), por novos valores dos tokens--color-status-canceled-*e o novo--color-status-canceled-borderdo Design System — Cancelado deixa de seguir C6; (3) no grupo de canceladas, horário de início e término riscados e nome emcolor-neutral-pure, mantendo a opacidade de 0,6; no grupo de realizadas, opacidade passa a 0,8. Contraste do texto do chip Cancelado: 14,6:1 (claro) e 11,2:1 (escuro) sobre a superfície; o contorno (1,7:1 / 1,8:1) é decorativo — o rótulo identifica o status. Mantida sem mudança a regra C6 dos demais status (alternativa de aumentar a mistura de Finalizado descartada pelo Designer, por abrir exceção de cor). Atualizados: Status “Cancelado”, Resumo de Consultas Realizadas e Canceladas, CA-005.1/005.2, tabela de componentes (Linha de consulta, Avatar, Chip de status, Pill de resumo) e MSG-BAGM-07/08. Acompanha 03-Protótipo v1.6. - v1.8 (01/10/2026) — Acompanha 01-Definição v1.9. (1) Retirada do bloqueio de horários pelo médico, pedida pelo solicitante, com a instrução de retirar toda referência ao conceito de bloqueio e de remover também os horários livres. Saem do corpo: US-AGM-003/004/006/007; item do menu ⋮ “Bloquear horário” (o menu fica só com os atalhos de dia com consulta); itens de bloqueio, horários livres e aviso de ausência na lista; subseções “Fluxo de Bloqueio de Horário”, “Fluxo de Desfazer e de Encerrar Bloqueio” e “Snackbar” (a tela não tem mais ações que confirmem ou falhem); CA-003.x, CA-004.x, CA-005.6, CA-006.1 e CA-007.x; EX-AGM-01/04/05/07/08/10/11/12; validações do formulário (a seção passa a “não se aplica”); componentes de bloqueio, horário livre, aviso de ausência, botão terciário, opções de duração e snackbar;
POST/DELETE/PATCHde/blocks;workWindows,absence,freeSlotse itenskind = "block"deGET /day, que passa a devolverappointments; mensagens MSG-EAGM-01/02/04–11, MSG-TAGM-02/04/07/08, MSG-SAGM-01–03, MSG-IAGM-01, MSG-BAGM-01/02/04/05/06/11/13/15 (“Cancelar”/“Salvando…” saem de MSG-BAGM-12); ECF.05.02 passa a fora de escopo e a auditoria deixa de ter eventos de bloqueio. Os IDs retirados não são reaproveitados. MSG-TAGM-01 passa a “Nenhuma consulta neste dia.”; CA-001.7, CA-002.2, CA-005.7, EX-AGM-03 e a virada do dia ajustados. A seleção das consultas passa a ser descrita como “o mesmo critério do endpoint de consultas da Central do Médico” — que já exclui os registros que não são consultas (RN-CM-030) —, sem regra própria nesta tela. (2) Informações complementares (RN-AGM-017, US-AGM-008), pedidas pelo solicitante como informações secundárias: nova última linha do item de consulta, igual no celular e em telas largas. Decisões do Designer, não pedidas pelo solicitante: linha sempre por último, abaixo do complemento (o complemento é uma observação da Recepção sobre aquela consulta, mais importante para o médico); 12px emcolor-neutral-pure, sem chips, para ficar com o menor destaque do item; ícones Lucide no lugar de rótulos escritos (building-2,map-pin,id-card,folder), com dica e rótulo acessível (MSG-BAGM-18); itens separados por espaço, não por ”·”, para não se confundir com a linha 2; subclassificação depois da classificação com ”›”; condições de exibição da clínica e da unidade aplicadas pelo back-end (clinic/unitnull), para o front não depender de saber quantas clínicas o usuário acessa nem quantas unidades a clínica tem. Novos camposclinic,unit,insuranceeclassificationemGET /day; CA-008.1 a 008.7; CA-001.3, CA-001.17 (o item típico passa a ter 3 linhas em telas largas, porque o convênio sempre aparece) e CA-001.18 ajustados. A lista reúne as consultas de todas as clínicas do cliente, em ordem cronológica, sem separação por clínica (RN-AGM-002). Limite conhecido: no tema claro,color-neutral-puretem contraste de 3,8:1 sobre a superfície, abaixo de 4,5:1 — mesmo achado já registrado para os demais textos secundários (Histórico v1.1 e Design System); no tema escuro, 7,1:1. Acompanha 03-Protótipo v1.7.