Épico 6 — Seleção de Clínica — Especificação (v2.0)
Documentos deste épico: 01 - Definição (v2.0) · 02 - Especificação (v2.0) · 03 - Protótipo (v2.0, código executável em 03 - Protótipo v2.0.html) · 04 - Mapeamento de Banco de Dados (v2.0). Este épico faz parte do documento guarda-chuva Check-in de Usuários.
SEÇÃO 2 — ESPECIFICAÇÃO
Histórias de Usuário
- US-CIU-006: Como profissional com acesso a mais de uma clínica, quero escolher em qual clínica vou trabalhar logo após o login, para acessar rapidamente o contexto certo.
- US-CIU-007: Como profissional com um convite pendente de uma nova clínica, quero aceitar esse convite na mesma tela onde escolho minha clínica, sem repetir a leitura de regras que já conheço, para agilizar meu acesso sem uma tela extra.
Descrição Funcional Detalhada
Lista de Clínicas
Exibe um item por clínica acessível (ClienteEmpresa ativa, RemovidoEm nulo) do profissional autenticado — agregando todos os vínculos ativos (UsuarioCliente.Situacao = 'V') e, para cada um, todas as ClienteEmpresa associadas via ClientePerfilAcessoUsuario — nome da clínica (ClienteEmpresa.Nome) e logo (ClienteEmpresa.CaminhoLogo, quando presente). Uma ClienteEmpresa desativada some da lista, mesmo com Perfil de acesso associado — confirmado pelo solicitante. Cada item é clicável e dispara a seleção daquela clínica específica (RN-CIU-015).
A lista não é mais uma sequência plana: reflete visualmente o agrupamento por Cliente contratante e por Ambiente de trabalho definido em RN-CIU-031 (01 - Definição), sem exigir que o profissional entenda esses dois conceitos:
- Grupo por Cliente: clínicas do mesmo
Clienteficam visualmente próximas, com o nome do Cliente (Cliente.Nome) exibido de forma discreta acima do grupo — um pequeno rótulo de texto, sem card ou borda própria. Quando o profissional está vinculado a um únicoCliente, esse rótulo não é exibido em nenhum grupo (item 1 de RN-CIU-031). - Container por Ambiente: dentro de cada grupo de Cliente, as clínicas de um mesmo Ambiente (
ClienteBD) ficam agrupadas visualmente num container. Um container de Ambiente de produção (ClienteBD.Tipo) não recebe nenhuma marca — é o caso comum, silencioso. Um container de Ambiente de testes recebe um cabeçalho com o nome do Ambiente (ClienteBD.Nome) e um tratamento visual próprio, discreto porém sempre presente em toda clínica daquele Ambiente (item 3 de RN-CIU-031) — nunca uma cor ou ícone de alerta/erro. - Clínica principal primeiro: dentro de um container de Ambiente, a clínica marcada como principal do profissional naquele Ambiente aparece antes das demais — usa uma marcação já existente, mantida fora deste épico (ver 01 - Definição, Escopo); esta tela apenas lê essa marcação para posicionar o item (item 2 de RN-CIU-031).
- Último acesso, exibido e usado para ordenar: cada item mostra, de forma discreta, há quanto tempo essa clínica foi acessada pela última vez pelo profissional (texto relativo — “hoje”, “há 3 dias”, “há 2 semanas”) — a mesma informação usada para decidir a ordem entre os grupos de Ambiente e entre os grupos de Cliente: o grupo cuja clínica foi acessada mais recentemente aparece primeiro (item 4 de RN-CIU-031). [PROPOSTA] — janela de tempo considerada e o desempate entre clínicas com frequência de acesso equivalente ainda não foram validados com usuários reais; ver 04 - Mapeamento de Banco de Dados para a fonte de dado candidata.
- Ambiente vazio desaparece: se a última clínica de um Ambiente deixar de estar acessível ao profissional, o container inteiro desse Ambiente sai da lista — não fica um grupo vazio (item 5 de RN-CIU-031; ver também EX-E6-05, mais abaixo). Como consequência direta, e não uma regra à parte: se isso esvaziar também o último Ambiente de um Cliente, o rótulo daquele Cliente deixa de ter o que agrupar e também não é mais exibido.
Por construção, todo item que entra nesta lista já tem, no momento em que a lista é carregada, um registro em ClientePerfilAcessoUsuario — ou seja, já tinha Perfil de acesso associado. A seleção sem Perfil de acesso descrita em CA-006.3/EX-E6-01 abaixo não é, portanto, o caso comum: é uma condição de corrida — o administrador removeu o Perfil de acesso daquela clínica (via gestão de usuários da clínica, fora do escopo deste épico) no intervalo entre a lista ser carregada e o profissional clicar no item. O mesmo tipo de condição de corrida já é tratado, para a clínica inteira ser removida, em EX-E6-05; CA-006.3/EX-E6-01 é o equivalente para a associação de Perfil de acesso especificamente.
Motivador: é a lista normal de navegação do profissional que atende em mais de uma clínica — existia antes deste épico (E1, roteamento por múltiplos vínculos) e ganha, nesta revisão, um agrupamento visual que evita a confusão entre clínicas de contratantes diferentes e entre Ambientes de produção e de testes (RN-CIU-031, redação completa e motivador em 01 - Definição).
Card de Convite Pendente
Um card por convite pendente (UsuarioCliente.Situacao = 'C'), visualmente destacado da lista de clínicas (RN-CIU-025) — borda ou fundo diferenciado (token --color-highlight-*, reservado para estados que pedem atenção, não para navegação normal), nome da(s) clínica(s) já associadas ao Perfil de acesso do convite (ou do Cliente convidante, como fallback, enquanto nenhuma ClienteEmpresa está associada — CIU-E3), botão primário “Aceitar”. Fica acima ou separado da lista, nunca misturado aos itens de seleção.
Motivador: o card representa uma ação pendente do profissional (decisão a tomar), não uma opção de navegação — misturá-lo à lista faria o profissional confundir “aceitar convite” com “selecionar clínica” (mesmo motivador já registrado em RN-CIU-025 / Seção 1).
Ao clicar em “Aceitar”: chama o endpoint de aceite (Seção “Integração com Backend”), atualiza Situacao para ‘V’, remove o card da área de destaque e insere a(s) clínica(s) associada(s) ao Perfil de acesso do convite na lista normal — sem selecionar nenhuma delas. Cada linha de UsuarioCliente (o vínculo/convite) tem um único valor de ClienteBDId, por ser uma coluna de chave estrangeira escalar — logo a(s) clínica(s) aceita(s) num mesmo convite pertencem sempre a um único Cliente e um único Ambiente (ver 04 - Mapeamento de Banco de Dados): se esse grupo já existir na lista (o profissional já tinha outra clínica ali), a(s) clínica(s) nova(s) entram no container existente; se for a primeira clínica desse Cliente/Ambiente para o profissional, um novo grupo e um novo container são criados na lista, na posição que a ordenação (RN-CIU-031, item 4) indicar. Quando o convite não tinha nenhuma ClienteEmpresa associada (RN-CIU-011, em CIU-E3, permite deixar essa seleção pendente), nenhum item novo entra na lista — o card de convite dá lugar, na mesma área de destaque, a um banner informativo persistente (MSG-I6-02) explicando que o acesso ainda depende de o administrador liberar uma clínica; quando há clínica(s) associada(s), a confirmação do aceite aparece como um toast informativo transitório (MSG-I6-03), não um banner — ver “Mapeamento de Componentes de Interface”.
Seleção de Clínica
Clicar num item da lista dispara a verificação de Perfil de acesso (RN-CIU-015) para aquela clínica. Dois desfechos:
- Perfil de acesso encontrado: navega para a tela inicial do profissional naquela clínica (cockpit — CM_CockPit_do_medico, ou equivalente de cada perfil profissional).
- Perfil de acesso ausente: permanece nesta tela, exibindo mensagem orientativa (MSG-I6-01) — mesmo texto e tratamento usados no E3 para o caso equivalente pós-aceite do vínculo (RN-CIU-015). Como descrito em “Lista de Clínicas” acima, este desfecho só ocorre por condição de corrida (Perfil de acesso removido entre o carregamento da lista e o clique) — todo item chega à lista já com Perfil de acesso associado.
Motivador: a verificação de Perfil de acesso é sempre a mesma, o momento em que roda é que muda — antes (E3, aceite via tela cheia) ou aqui (na seleção) (ver RN-CIU-025).
Critérios de Aceitação
CA-006.1: Dado que estou autenticado e tenho acesso a mais de uma clínica, quando o roteamento pós-login me traz a esta tela, então vejo a lista de clínicas acessíveis, agrupada por Cliente e por Ambiente conforme RN-CIU-031.
CA-006.2: Dado que estou nesta tela, quando seleciono uma clínica da lista e tenho Perfil de acesso associado a ela, então sou levado à tela inicial do meu perfil profissional naquela clínica.
CA-006.3: Dado que estou nesta tela, quando seleciono uma clínica da lista cujo Perfil de acesso foi removido depois que a lista foi carregada (condição de corrida — ver “Lista de Clínicas”, Descrição Funcional), então permaneço na tela e vejo a mensagem orientativa MSG-I6-01.
CA-006.4: Dado que tenho acesso a exatamente 1 clínica e nenhum convite pendente, quando faço login, então não vejo esta tela — vou direto ao cockpit (RN-CIU-009).
CA-006.5: Dado que tenho clínicas acessíveis em mais de um Cliente contratante, quando vejo a lista, então as clínicas de cada Cliente aparecem visualmente agrupadas, com o nome do Cliente indicado de forma discreta acima do grupo, sem repetir esse nome em cada clínica.
CA-006.6: Dado que tenho vínculo com um único Cliente contratante, quando vejo a lista, então nenhum rótulo de Cliente é exibido em nenhum grupo.
CA-006.7: Dado que tenho acesso a mais de uma clínica dentro de um mesmo Ambiente, quando vejo a lista, então a clínica marcada como principal daquele Ambiente aparece antes das demais clínicas do mesmo container.
CA-006.8: Dado que tenho acesso a uma clínica num Ambiente de testes, quando vejo a lista, então o container desse Ambiente exibe um sinal visual discreto e constante (nome do Ambiente + tratamento visual próprio), ausente nos containers de Ambientes de produção.
CA-006.9: Dado que estou com a lista carregada, quando seleciono uma clínica cujo registro foi removido nesse meio tempo e essa era a única clínica do seu Ambiente (EX-E6-05), então esse item some e o container do Ambiente inteiro é removido junto — não fica um grupo vazio na tela.
CA-006.10: Dado que tenho acesso a clínicas de mais de um Ambiente ou Cliente, quando vejo a lista, então a ordem dos grupos aproxima do topo a clínica que acessei mais recentemente (critério exato de janela de tempo e desempate ainda [PROPOSTA], a validar com usuários reais).
CA-007.1: Dado que tenho ao menos um vínculo ativo e um convite pendente de outra clínica, quando chego a esta tela, então vejo um card em destaque com o nome da clínica convidante e um botão “Aceitar”, separado da lista normal.
CA-007.2: Dado que vejo o card de convite pendente, quando clico em “Aceitar”, então o vínculo passa a Situacao = 'V', o card sai da área de destaque e a(s) clínica(s) associada(s) ao Perfil de acesso do convite passam a constar na lista normal — no grupo de Cliente/Ambiente correspondente, criando um novo grupo quando for a primeira clínica desse Cliente/Ambiente para o profissional.
CA-007.3: Dado que acabei de aceitar um convite pelo card, quando a ação é concluída, então não sou levado automaticamente para nenhuma das clínicas recém-aceitas — preciso selecionar uma delas na lista, como qualquer outra.
CA-007.4: Dado que tenho exatamente 1 vínculo ativo e um convite pendente simultâneo, quando faço login, então vejo esta tela (não o cockpit direto) — com a clínica do vínculo ativo na lista e o card do convite em destaque.
CA-007.5: Dado que o card de convite pendente ainda não foi aceito, quando verifico meu Perfil de acesso para a clínica em vias de aceitar, então nenhuma verificação de Perfil de acesso é feita — ela só ocorre depois, quando eu selecionar essa clínica já aceita na lista.
CA-007.6: Dado que aceito um convite cujo Perfil de acesso não tinha nenhuma clínica associada (RN-CIU-011, em CIU-E3), quando a ação é concluída, então nenhum item novo entra na lista e vejo a mensagem informativa MSG-I6-02.
Fluxos de Exceção
EX-E6-01 — Seleção sem Perfil de acesso associado
Gatilho: profissional seleciona uma clínica da lista para a qual não existe registro em ClientePerfilAcessoUsuario (mesma verificação de RN-CIU-015, reaproveitada do E3) — na prática, uma condição de corrida: todo item chega à lista já com Perfil de acesso associado (ver “Lista de Clínicas”, Descrição Funcional), então isso só acontece se o administrador removeu essa associação depois de a lista ter sido carregada. Comportamento: permanece na tela de seleção, exibe mensagem orientativa MSG-I6-01 associada ao item da lista. Recuperação: profissional aguarda o administrador da clínica configurar seu Perfil de acesso, ou seleciona outra clínica da lista.
EX-E6-02 — Falha ao aceitar convite pelo card
Gatilho: back-end retorna erro ao tentar atualizar Situacao de ‘C’ para ‘V’ no aceite do card. Comportamento: toast de erro MSG-E6-01; o card permanece na área de destaque, inalterado. Recuperação: profissional tenta “Aceitar” novamente.
EX-E6-03 — Convite expira enquanto o profissional está na tela
Gatilho: profissional tenta aceitar um card cujo convite expirou (RN-CIU-024, em CIU-E3) entre o carregamento da tela e o clique em “Aceitar”. Comportamento: toast de erro MSG-E6-02; o card sai da área de destaque (o convite não existe mais como pendente). Recuperação: profissional contata o administrador da clínica convidante para receber um novo convite — mesma orientação do E3 (RN-CIU-024).
EX-E6-04 — Falha ao carregar a lista de clínicas e convites
Gatilho: erro de rede ou falha do back-end ao buscar vínculos ativos e convites pendentes do profissional autenticado. Comportamento: estado de erro na tela (mensagem MSG-E6-03 + ação “Tentar novamente”), sem lista nem cards exibidos. Recuperação: profissional aciona “Tentar novamente”; se persistir, orientação a contatar o suporte.
EX-E6-05 — Clínica removida entre o carregamento da lista e a seleção
Gatilho: profissional seleciona uma clínica cujo registro em ClienteEmpresa foi removido (RemovidoEm preenchido) no intervalo entre carregar a lista e clicar no item. Comportamento: toast de erro MSG-E6-04; o item sai da lista e, seguindo RN-CIU-031 (item 5), o container do Ambiente inteiro é removido junto se essa era a única clínica dele — não fica um grupo vazio. Recuperação: profissional seleciona outra clínica da lista atualizada. Confirmado pelo solicitante como tratamento definitivo desta versão (antes proposto como cenário de borda a confirmar).
Validações de Campos
Esta tela não tem campos de entrada de dados — apenas seleção de itens de lista e um botão de aceite por card. Não há, portanto, validações de campo a documentar (diferente de E2/E3, que têm formulários).
Mapeamento de Componentes de Interface
| Componente | Variante | Estados | Tokens aplicados | Uso nesta tela |
|---|---|---|---|---|
| Rótulo de Cliente | Texto discreto | default | --font-size-xs, --color-neutral-light, uppercase, letter-spacing 0.5px | Acima de cada grupo de Cliente; ausente quando há apenas 1 Cliente |
| Container de Ambiente | Produção (silencioso) | default | --radius-l (12px), --shadow-level-light, --color-base-pure bg | Agrupa as clínicas de um Ambiente de produção — sem cabeçalho nem borda diferenciada |
| Container de Ambiente | Testes (canhoto de ingresso) | default | --radius-l (12px) no topo, cabeçalho --color-highlight-light bg / --color-highlight-dark texto, borda tracejada --color-highlight-pure, recortes circulares nas laterais inferiores do cabeçalho | Agrupa as clínicas de um Ambiente de testes — cabeçalho exibe o nome do Ambiente; sinal discreto porém sempre presente (RN-CIU-031, item 3) |
| Linha de clínica | Seleção (clínica), dentro de um container | default, hover, focus, loading | --radius-m (8px) no hover, --spacing-sm padding, peso de fonte --font-weight-bold quando é a principal do Ambiente | Uma por clínica acessível, dentro do container do seu Ambiente; separada por linha divisória (--border-regular) das demais do mesmo container |
| Card | Destaque (convite pendente) | default, loading (durante aceite) | --radius-l (12px), borda --border-medium em --color-highlight-pure (#FFC400), --color-highlight-light bg (#FFF8E1) | Um por convite pendente, separado da lista, fora de qualquer container de Ambiente |
| Button | Primary | default, hover, loading, disabled | --btn-height (40px), --color-primary-pure bg (#00E676), --color-base-pure texto, --radius-m (8px) | Botão “Aceitar” no card de convite (MSG-B6-01) |
| Banner/Ícone informativo | Info | default | --color-secondary-pure (#40C4FF) | Mensagem de bloqueio sem Perfil de acesso (MSG-I6-01), inline junto ao item; e de convite aceito sem clínica associada (MSG-I6-02), persistente, no lugar do card na área de destaque |
| Toast | Error | default | --color-error-pure (#F44336) | Falhas de aceite de convite, expiração, carregamento, clínica removida (MSG-E6-01 a 04) |
| Toast | Info | default | --color-neutral-darker (variante escura do toast, sem vermelho) | Confirmação transitória de aceite de convite com clínica associada (MSG-I6-03) |
| Skeleton | Lista | loading | --color-neutral-lighter (#E5EAF0) | Estado de carregamento inicial da tela, antes da lista e dos cards chegarem |
Integração com Backend
GET /api/v1/checkin/clinic-selection
Função: retorna, para o profissional autenticado, a lista de clínicas acessíveis — já agrupada por Cliente e Ambiente e ordenada conforme RN-CIU-031 — e os convites pendentes.
Request: nenhum parâmetro (usuário identificado pelo token de sessão).
Response: { grupos: [{ clienteId, clienteNome, ambientes: [{ clienteBDId, ambienteNome, ambienteTipo, clinicas: [{ usuarioClienteId, clienteEmpresaId, nome, caminhoLogo, principal, ultimoAcesso }] }] }], convites: [{ usuarioClienteId, clienteBDId, clienteNome, clienteLogo, clienteEmpresas: [{ clienteEmpresaId, nome, caminhoLogo }] }] }.
grupos já vem na ordem de exibição definida por RN-CIU-031, item 4 (clínica acessada mais recentemente primeiro) — critério aplicado tanto entre os grupos de grupos[] (Cliente) quanto entre os itens de ambientes[] dentro de um mesmo grupo (Ambiente), não apenas no nível mais externo. Dentro de cada ambientes[].clinicas, o item principal: true já vem primeiro. ambienteTipo é uma string de negócio ("producao" | "homologacao") traduzida a partir de ClienteBD.Tipo no back-end — mapeamento exato [PROPOSTA], ver 04 - Mapeamento de Banco de Dados (domínio do campo não catalogado até esta revisão). ultimoAcesso vem como data/hora ISO 8601 ou null quando não há registro de acesso anterior; o front-end formata como texto relativo (“hoje”, “há 3 dias”). clienteEmpresas (dentro de convites) vem vazio enquanto o convite ainda não tem Perfil de acesso/clínica associados (CIU-E3); nesse caso o front-end usa clienteNome/clienteLogo (Cliente) como fallback no card. O campo é chamado convites (não convitesPendentes) de propósito — no login (E1, /api/auth/login) convitesPendentes é um número (contagem), usado só para decidir o desvio de roteamento; aqui é uma lista completa de objetos, e reaproveitar o mesmo nome para um formato diferente criaria ambiguidade entre os dois documentos.
Códigos: 200 (sucesso, grupos e convites podem vir vazios — convites é o caso comum vazio; grupos vazio não deveria ocorrer nesta tela, já que o roteamento só chega aqui com ao menos 1 clínica acessível ou 1 convite pendente, RN-CIU-022); 401 (não autenticado); 500 (falha ao carregar — EX-E6-04).
Tabelas envolvidas: UsuarioCliente, ClientePerfilAcessoUsuario, ClienteEmpresa, ClienteBD, Cliente (IpSeguranca) — ver 04 - Mapeamento de Banco de Dados para o detalhamento por campo, incluindo a fonte candidata de ultimoAcesso.
POST /api/v1/checkin/clinic-selection/{usuarioClienteId}/accept-invite
Função: aceita o convite pendente de um card, sem selecionar nenhuma clínica.
Request: nenhum corpo — usuarioClienteId no path identifica o vínculo.
Response: { usuarioClienteId, clienteId, clienteNome, clienteBDId, ambienteNome, ambienteTipo, clinicas: [{ clienteEmpresaId, nome, caminhoLogo, principal }] } — cada linha de UsuarioCliente tem um único valor de ClienteBDId (coluna de chave estrangeira escalar, ver 04 - Mapeamento de Banco de Dados), logo todo vínculo/convite pertence a exatamente um Ambiente: a resposta representa sempre um único Cliente e um único Ambiente, com uma ou mais clínicas dentro dele; clinicas vem vazio quando o convite não tinha nenhuma ClienteEmpresa associada (RN-CIU-011, em CIU-E3), disparando o banner MSG-I6-02 no front-end em vez de inserir um item na lista (quando clinicas vem preenchido, o front-end exibe o toast informativo MSG-I6-03).
Códigos: 200 (sucesso); 404 (convite não encontrado ou já resolvido); 409 (convite expirado — EX-E6-03, retorna MSG-E6-02); 500 (falha ao atualizar — EX-E6-02).
Tabelas envolvidas: UsuarioCliente (atualiza Situacao), ClientePerfilAcessoUsuario, ClienteEmpresa, ClienteBD e Cliente (para montar a resposta com o agrupamento), UsuarioClienteConvite (deleta o registro — mesma tabela e mecanismo do E3, RN-CIU-024).
POST /api/v1/checkin/clinic-selection/{usuarioClienteId}/{clienteEmpresaId}/select
Função: seleciona a clínica específica para a sessão de trabalho, rodando a verificação de Perfil de acesso.
Request: nenhum corpo — usuarioClienteId e clienteEmpresaId no path.
Response, com Perfil de acesso: { perfilEncontrado: true, redirecionarPara: "<rota do cockpit do perfil>" }. Sem Perfil de acesso: { perfilEncontrado: false, mensagem: "MSG-I6-01" }.
Códigos: 200 (sucesso, com ou sem perfil — o corpo diferencia); 404 (clínica removida ou vínculo inválido — EX-E6-05); 401 (não autenticado).
Tabelas envolvidas: UsuarioCliente, ClientePerfilAcesso, ClientePerfilAcessoUsuario (filtrado também por ClienteEmpresaId) (IpSeguranca) — mesma verificação de RN-CIU-015, em CIU-E3.
Nota sobre padronização de nomes: os três endpoints acima e o E3 (GET /api/convites/validar, 02 - Especificação) usam o mesmo par de nomes para o mesmo conceito — array clienteEmpresas (quando presente) ou clinicas (quando já dentro de um grupo/Ambiente específico), item com campo clienteEmpresaId.
Catálogo de Mensagens do Sistema e Termos de Interface (i18n)
Erros:
| ID | Contexto | pt-BR | en-US | es-419 |
|---|---|---|---|---|
| MSG-E6-01 | Falha ao aceitar convite pelo card | ”Não foi possível aceitar o convite. Tente novamente." | "Could not accept the invitation. Please try again." | "No fue posible aceptar la invitación. Inténtelo de nuevo.” |
| MSG-E6-02 | Convite expirado ao tentar aceitar | ”Este convite expirou. Entre em contato com o administrador da clínica para receber um novo convite." | "This invitation has expired. Contact the clinic’s administrator to receive a new invitation." | "Esta invitación ha expirado. Comuníquese con el administrador de la clínica para recibir una nueva invitación.” |
| MSG-E6-03 | Falha ao carregar lista de clínicas e convites | ”Não foi possível carregar suas clínicas. Tente novamente." | "Could not load your clinics. Please try again." | "No fue posible cargar sus clínicas. Inténtelo de nuevo.” |
| MSG-E6-04 | Clínica removida entre carregar a lista e selecionar | ”Esta clínica não está mais disponível." | "This clinic is no longer available." | "Esta clínica ya no está disponible.” |
Informativas:
| ID | Contexto | pt-BR | en-US | es-419 |
|---|---|---|---|---|
| MSG-I6-01 | Perfil de acesso ausente na clínica selecionada | ”Você ainda não tem um perfil de acesso configurado nesta clínica. Aguarde ou entre em contato com o administrador." | "You don’t have an access profile configured at this clinic yet. Wait or contact the administrator." | "Aún no tiene un perfil de acceso configurado en esta clínica. Espere o comuníquese con el administrador.” |
| MSG-I6-02 | Convite aceito sem nenhuma clínica associada ao Perfil de acesso (RN-CIU-025, item 2) — banner persistente | ”Convite aceito! Seu acesso ainda depende de o administrador liberar uma clínica para você. Você será avisado quando isso acontecer." | "Invitation accepted! Your access still depends on the administrator granting you a clinic. You’ll be notified when that happens." | "¡Invitación aceptada! Su acceso todavía depende de que el administrador le asigne una clínica. Se le avisará cuando eso ocurra.” |
| MSG-I6-03 | Convite aceito com clínica(s) associada(s) — toast informativo transitório | ”Convite aceito. Selecione a clínica na lista para entrar." | "Invitation accepted. Select the clinic from the list to sign in." | "Invitación aceptada. Seleccione la clínica en la lista para ingresar.” |
Textos orientadores:
| ID | Contexto | pt-BR | en-US | es-419 |
|---|---|---|---|---|
| MSG-T6-01 | Título da área de destaque de convites | ”Convite pendente" | "Pending invitation" | "Invitación pendiente” |
| MSG-T6-02 | Título da tela (H1) | “Selecione uma clínica" | "Select a clinic" | "Seleccione una clínica” |
| MSG-T6-03 | Título da seção de lista, acima dos grupos de Cliente/Ambiente | ”Suas clínicas" | "Your clinics" | "Sus clínicas” |
Botões/links:
| ID | Contexto | pt-BR | en-US | es-419 |
|---|---|---|---|---|
| MSG-B6-01 | Botão (card de convite) | “Aceitar" | "Accept" | "Aceptar” |
| MSG-B6-02 | Ação de recuperação (erro de carregamento) | “Tentar novamente" | "Try again" | "Intentar de nuevo” |
Conformidade SBIS (detalhamento)
NGS1.03.01 — Impedir acesso por pessoas não autorizadas (estágio 1, obrigatório) — a seleção de clínica só concede acesso à tela inicial do profissional quando há Perfil de acesso associado (RN-CIU-015); sem ele, o profissional permanece bloqueado nesta tela, com orientação (MSG-I6-01). O agrupamento e a sinalização de Ambiente de testes (RN-CIU-031) reforçam esse mesmo requisito de outro ângulo — reduzem o risco de o profissional entrar, por engano, num Ambiente que não é o de produção.
NGS1.03.03 — Gerenciamento de perfis (estágio 1, obrigatório) — este épico consome a verificação de Perfil de acesso a cada seleção de clínica, não apenas uma vez no aceite do vínculo (E3) — reforça o controle a cada troca de contexto de trabalho.
ECF.17.19 — Mensagens do sistema (estágio 1, obrigatório) — todas as mensagens exibidas ao profissional estão catalogadas acima, 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 (29/08/2026) — Arquivo criado pela divisão do documento único
(CIU-E6) Seleção de Clínica v1.0.mdem arquivos por seção (ver Skill Designer, “Organização Física: Pasta por Funcionalidade”, Lição #18). Conteúdo sem alteração de substância em relação à v1.0 original — apenas reorganização física (o protótipo HTML já era um arquivo separado desde a v1.0 original, só foi renomeado para a convenção nova). Histórico de revisões anterior a esta divisão (v0.1 a v1.0) preservado integralmente no documento original arquivado. - v1.1 (14/09/2026) — Lista de Clínicas e card de convite pendente passam a operar por
ClienteEmpresa(clínica), não porCliente(tenant): cada item da lista é uma clínica acessível, e o aceite de um convite pode inserir mais de um item de uma vez, conforme a quantidade deClienteEmpresaassociadas ao Perfil de acesso do convite. Endpoints atualizados (GET .../clinic-selection,.../accept-invite,.../select— este último agora recebeclienteEmpresaIdno path). Ver RN-CIU-009 (CIU-E1) e RN-CIU-011/015 (CIU-E3) para a regra completa. - v1.2 (14/09/2026) — quatro correções sobre a v1.1: (1) esclarecida a aparente contradição entre “Lista de Clínicas” (todo item já tem Perfil de acesso por construção) e CA-006.3/EX-E6-01 (seleção sem Perfil de acesso): o segundo caso é uma condição de corrida — Perfil de acesso removido entre carregar a lista e selecionar — mesmo padrão já usado em EX-E6-05 para a clínica inteira ser removida; texto de ambos os pontos explicitado; (2)
Tabelas envolvidasdo endpointaccept-inviteestava incompleta — incluía apenasUsuarioClienteeUsuarioClienteConvite, mas a resposta monta um array deClienteEmpresaque depende deClientePerfilAcessoUsuarioeClienteEmpresa; ambas adicionadas; (3) padronização de nomes entre E3 e E6: o array de clínicas de um convite agora se chamaclienteEmpresascom campoclienteEmpresaIdnos três lugares onde aparece (E3GET /convites/validar, esteGET .../clinic-selection, estePOST .../accept-invite— que usavaclinicas, renomeado); (4) o array de convites pendentes deGET .../clinic-selection, antesconvitesPendentes, renomeado paraconvites— no login (E1)convitesPendentesé um número, e reaproveitar o nome aqui para uma lista de objetos criava um conflito de tipos entre os dois documentos. RN-CIU-025 (01 - Definição) também ganhou, nesta mesma revisão, uma nota sobre o caso de borda de convite aceito sem nenhumaClienteEmpresaassociada — refletida aqui na Descrição Funcional e no endpointaccept-invite. - v1.3 (14/09/2026) — “Lista de Clínicas” passa a filtrar apenas
ClienteEmpresaativas (RemovidoEmnulo) — consequência da confirmação do solicitante de que uma clínica desativada tira o acesso de todos os usuários hoje associados a ela. Ver RN-CIU-025 (Seção 1) para a regra completa. - v2.0 (18/09/2026) — atualização completa desta seção para refletir RN-CIU-031 (01 - Definição v2.0), pendência registrada desde a revisão anterior da Seção 1. “Lista de Clínicas” reescrita: agrupamento por Cliente (rótulo discreto, suprimido com 1 único Cliente), container por Ambiente (produção silencioso, testes com cabeçalho e tratamento visual próprio e constante), clínica principal primeiro dentro do Ambiente, exibição do último acesso (também usado para ordenar) e desaparecimento do container de um Ambiente esvaziado.
GET .../clinic-selectionpassa a devolver a lista já pré-agrupada (grupos[].ambientes[].clinicas[]) e ordenada pelo back-end, em vez de uma lista plana — decisão de manter a lógica de ordenação num só lugar (Lição #10 da Skill Designer), evitando reimplementar o critério de “acesso mais recente” no front-end;accept-invitepassa a devolver o grupo/Ambiente da(s) clínica(s) aceita(s), usando o fato de que um vínculo (UsuarioCliente) pertence a exatamente um Ambiente (achado técnico já registrado no Histórico de 01 - Definição v2.0). Adicionados 6 novos Critérios de Aceitação (CA-006.5 a CA-006.10) para o agrupamento, a principal primeiro, o sinal de Ambiente de testes, o desaparecimento de Ambiente vazio e a ordenação por acesso recente — este último redigido de forma hedged, refletindo o[PROPOSTA]da própria RN-CIU-031; e CA-007.6, cobrindo o caso de convite aceito sem clínica associada. EX-E6-05, antes um cenário de borda [PROPOSTA], passa a tratamento confirmado (RN-CIU-031, item 5) — texto reescrito em termos de container de Ambiente, não mais “lista recarregada”. Nova mensagem informativa MSG-I6-02, resolvendo a pendência de texto deixada em aberto pela 01 - Definição v2.0 para o caso de convite aceito sem clínica associada (RN-CIU-025, item 2). Mapeamento de Componentes de Interface reescrito: o “Card” avulso por clínica dá lugar a uma “Linha de clínica” dentro de um “Container de Ambiente” (com a variante de cabeçalho tipo canhoto de ingresso para Ambientes de testes) e a um “Rótulo de Cliente” textual — nomes de componente alinhados ao vocabulário usado nas explorações visuais de UX realizadas junto com o solicitante (ver Histórico de 01 - Definição v2.0). Conformidade SBIS (NGS1.03.01) ganhou uma frase adicional relacionando o sinal de Ambiente de testes à prevenção de acesso indevido. Revisão de crítico técnico (Skill Designer, “Revisão por Dois Críticos”) rodada como subagente independente sobre esta seção junto das Seções 3 e 4, encontrando 17 problemas, verificados individualmente contra o schema e os documentos-fonte antes de decidir a correção de cada um — lista completa e desfecho de cada achado registrados no Histórico de 04 - Mapeamento de Banco de Dados v2.0. Desta seção especificamente, a revisão corrigiu: a justificativa técnica do Card de Convite Pendente e do endpointaccept-invite, que atribuía a “um vínculo pertence a exatamente um Ambiente” à restriçãoUNIQUE(UsuarioId, ClienteBDId)— a causa correta éClienteBDIdser uma coluna de chave estrangeira escalar, não a restrição de unicidade (que é uma regra de negócio à parte); a descrição de MSG-I6-02, alinhada ao texto efetivamente exibido e reclassificada como banner persistente (estado contínuo), distinta da nova MSG-I6-03 (toast transiente, caso “convite aceito com clínica”); a rotulagem de MSG-T6-02 (era descrita como título da lista, é o H1 da tela) e a adição de MSG-T6-03 para o título real da seção de lista; a redação de CA-006.9, ajustada ao mecanismo reativo de remoção (EX-E6-05); e a confirmação explícita de queambientes[], não sóclinicas[], também segue a ordenação de RN-CIU-031 item 4.