Mesmo padrão do seletor de protético, generalizado para os demais dropdowns:
- Componente SearchSelect (modal genérico: trigger + busca + lista filtrável por rótulo/hint).
- LancarGTO: Especialidade/Área, Produto/Prótese, Procedimento, Dentista e Convênio/Credenciada
— todos os <select> convertidos (0 selects restantes).
- Nova OS (ProteseView): Produto e Dentista convertidos.
- Cotação (RFQ): input de busca na lista de laboratórios a convidar (continua multi-seleção).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
O dropdown só listava protéticos internos (vinculados) ou do diretório público — um protético com
conta fora do diretório (ex.: claudemir) não aparecia para a clínica. Reformulado:
- Componente ProteticoPicker (modal): busca por nome/e-mail; estrela de FAVORITO; marcar PADRÃO
(pré-selecionado na próxima OS/GTO, só um por clínica); e "Adicionar por e-mail", que VINCULA um
protético existente como interno — resolve o caso de não estar no diretório, sem expô-lo publicamente.
- Backend: tabela protese_protetico_pref (favorito/padrão por clínica); GET /protese/laboratorios
passa a retornar favorito/padrao e ordena padrão→favorito→interno→nota→nome; POST .../:id/pref e
POST /protese/laboratorios/vincular.
- Picker aplicado no LancarGTO (avaliação/GTO) e na NovaOSModal; ProteticoInternoInline (protético
SEM conta) mantido ao lado.
Validado em DEV na CONSULTT CLINIC: claudemir ausente → vinculado por e-mail → aparece interno e,
como favorito+padrão, no topo da lista.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
O protético identifica o trabalho pelo nome do paciente (etiqueta, sem CPF — ele não atende
paciente). Quando dois trabalhos têm o mesmo nome+sobrenome, desambigua sem expor dado sensível:
- util pacienteLabel.ts (rotulosPaciente / homonimoAtivo): comparação normalizada
(case/acento/espaço-insensitive). Em colisão: 1) diferencia pela ORIGEM (dentista, senão
clínica) → "João Silva · Dr. Carlos"; 2) se mesma origem, nº sequencial estável por data.
- Bancada (ProteseView) e Painel do lab (LabHomeView/Próximas entregas): nome exibido já
desambiguado em toda a fila — vale para OS nascidas na clínica ou no lab.
- Modal "Dar entrada": campo único trocado por Nome + Sobrenome(s); aviso em tempo real quando
há homônimo ativo ("acrescente outro sobrenome para diferenciar"), informando a origem do
conflito.
Validado em DEV (3 homônimos "João Silva": origem distinta e mesma origem → sequencial).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fecha o ciclo operacional do laboratório, antes só "receptor passivo" das OS da clínica.
1. Dar entrada em OS pelo lab — POST /api/protese/lab/os: o dono do laboratório registra um
trabalho recebido fora do app, escolhendo cliente existente OU avulso (clínica/consultório/
dentista, materializado como registro mínimo) + produto do catálogo ou tipo livre. A OS já
entra com laboratorio_id e custódia no laboratório. UI: botão "Dar entrada" + modal na LabHome.
2. Dar baixa em pagamento — já existia (lado 'lab'); mantido na PagamentosSecao.
3. Solicitar pagamento — POST /api/protese/os/:id/cobrar: calcula o saldo devedor (custo − pago)
e notifica o cliente, registrando no histórico. UI: botão "Solicitar pagamento (saldo)" na
PagamentosSecao do modo bancada.
4. Importar/vincular OS indicada — GET /api/protese/lab/os-indicadas (OS com protetico_id=me e
laboratorio_id NULL) + POST /api/protese/os/:id/vincular-lab (seta laboratorio_id, status→recebido,
notifica a clínica). Sem isso a OS só aparecia ao dono via fallback; importando, a equipe/técnicos
e o financeiro do lab passam a vê-la. UI: seção "OS indicadas a você" na LabHome.
origemDe agora reconhece cliente avulso tipo 'dentista'. Validado em DEV (todos os 4 endpoints).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Protético interno: a clínica cadastra um protético que não usa a plataforma. Cria usuário "mudo"
(e-mail placeholder @interno.local + senha-fantasma; usuarios.email é NOT NULL/UNIQUE) + vínculo
interno (fora do diretório). POST /protese/proteticos-internos; botão "Cadastrar protético interno"
na Nova OS, que recarrega o dropdown e seleciona o novo.
- Carteira no link /p/TOKEN: botão "Meus trabalhos" → trabalhos em andamento/finalizados + mini
financeiro mensal (valores pagos ao protético). GET /api/p/:token/carteira, escopo da relação
clínica↔protético do token (não vaza outras clínicas; sem dados do paciente).
Validado em DEV: interno criado e acessível no dropdown; OS+link; carteira com andamento + R$250/2026-06.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Novo módulo de logística do lab (doc/AGENDA-COLETA-LAB):
- protese_coleta: agendamento de coleta (lab busca) / entrega (lab leva), com data/hora,
endereço, responsável, status. Ligado à OS.
- POST /protese/os/:id/coleta (agendar), GET /protese/lab/agenda (cronológica),
POST /protese/coleta/:id/status. 'realizada' MOVE a custódia automaticamente
(coleta→laboratorio, entrega→clinica) — fonte única do movimento físico. GET detalhe traz coletas[].
- UI: tela AGENDA (lab-agenda) agrupada por dia com "marcar realizada"; seção Coleta/entrega na
aba Monitoramento da OS (clínica e lab).
Validado em DEV: agenda coleta → realizada → custódia=laboratorio; lab vê na agenda.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- A clínica avalia o laboratório (1-5★ + comentário) após a entrega (protese_avaliacao, 1 por OS,
reavaliável). POST /protese/os/:id/avaliar; avaliação volta no GET detalhe.
- Nota ScoreOdonto passa a combinar 0.6·operacional + 0.4·satisfação (estrelas) quando há avaliações.
Selo "Verificado" (≥5 entregas). Exposto no marketplace (★nota · nº avaliações · Verificado) e nos
indicadores do lab (KPI Satisfação). Helper notasScorePorProtetico unificado (dropdown + marketplace).
- UI: seção "Avaliar o laboratório" na OS entregue (lado clínica); selo/avaliações no card do marketplace.
- Correção de passagem: FileText/Star importados em ProteseView (FileText faltava desde a fatia 3).
Validado em DEV: 6 entregas + 5★/3★ → nota 9.2, satisfação 4★, verificado (marketplace e indicadores).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Entidades protese_rfq + protese_rfq_cotacao. A clínica descreve o trabalho e convida N labs;
cada lab cota (valor/prazo/obs); a clínica compara (ordenado por preço) e escolhe → vira OS
(custo = valor da cotação) e a RFQ fecha (demais recusadas).
- Backend: POST/GET /protese/rfq, GET /protese/rfq/recebidas, POST /protese/rfq/cotacao/:id,
POST /protese/rfq/:id/escolher (cria a OS).
- Lado lab: tela Cotações (lab-cotacoes) — RFQs recebidas + responder.
- Lado clínica: botão Cotações na tela de Prótese — pedir multi-lab + comparar + escolher.
Validado em DEV ponta a ponta: pedido → cotação R$420 → escolha → OS criada → RFQ fechada.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fecha o Modo 1 (link seguro do protético sem conta):
- GET /api/protese/os/:id/link/status: link ativo, nº de acessos, último acesso e expiração.
- UI (aba Monitoramento, modo clínica): mostra status do link com Copiar / WhatsApp / Revogar
e os contadores de acesso/expiração; gera sob demanda.
Conversão por herança é nativa (a OS já aponta para o protetico_id do destinatário). Validado em
DEV: acessos contados, expiração 60 dias, revogação → status inativo + leitura pública 404.
Modo 1 concluído (1a leitura + 1b ação + 1c gestão).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Provedor de Prótese SEM conta (doc/MODO1-LINK-SEGURO-PROTESE):
- Token por OS: tabela protese_os_link (aleatório 24B base64url, expira 60 dias, revogável,
conta acessos). POST /protese/os/:id/link (gera/recupera) + POST .../link/revogar.
- Leitura pública GET /api/p/:token (sem auth): payload curado com a mesma blindagem soLab —
SEM paciente_id (CPF) e SEM valor cobrado ao paciente; mostra trabalho, etapas, componentes,
fotos, custódia, ocorrências, histórico e custo do lab.
- Página pública ProtesePublicView (mobile-first 320px+), interceptada no index.tsx antes do
app autenticado; CTA "Criar conta grátis". Botão Gerar link / WhatsApp / Copiar na aba
Monitoramento (modo clínica).
- Validado em DEV: leitura, blindagem (CPF/valor ocultos), token inválido→404, revogação→404.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Provedor de Prótese, Fase 5 (doc/PROVEDOR-PROTESE-DECISAO.md) — sobre a captura das fases 2-4:
- Indicadores do lab (GET /protese/lab/indicadores, só dono): entregues, tempo médio, atraso %,
retrabalho % (garantia), ocorrências resolvidas %, componentes ausentes. Tela lab-indicadores.
- Nota ScoreOdonto (0-10) = 10 − (atraso%×3 + retrabalho%×4 + ocorrência%×3), só com ≥3 entregas
("score em formação" abaixo disso). Apenas ocorrências RESOLVIDAS pesam (contraditório respeitado).
- Ranking: getProteseLaboratorios devolve a nota por protético e ordena internos→nota→nome; a
clínica vê ★ nota no dropdown de Nova OS e Lançar GTO.
Roadmap do Provedor de Prótese concluído (Fases 1-5). Marketplace transacional e Modo 1 (link
seguro sem conta) ficam como evolução futura.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Provedor de Prótese, Fase 1 do roadmap (doc/PROVEDOR-PROTESE-DECISAO.md):
- Origem da OS: bancada e detalhe passam a trazer clinica_nome (subquery em clinicas);
o protético vê a clínica de origem na lista da bancada e no topo do modal. Destrava o
cenário multi-clínica (Clínica A/B/C → mesmo laboratório).
- Blindagem de CPF (LGPD): confirmado que pacientes.id É o CPF. O provedor de prótese
(lab que não é da clínica) deixa de receber paciente_id no detalhe e na bancada,
mantendo paciente_nome; a clínica continua vendo o CPF para operar.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Etapas repetíveis/puláveis: cada etapa tem ação Ir/Voltar/Repetir (não só "avançar
para a próxima"). 'entregue' segue na Linha do tempo.
- Ajustes do trabalho (aba Etapas): editar cor/material (PATCH .../os/:id); trocar o
trabalho por outro + MOTIVO obrigatório (POST .../trocar); acréscimo/redução do valor
cobrado do paciente com observação (POST .../ajuste-valor) — tudo auditado no histórico.
- Privacidade: o protético (lab que não é da clínica) NÃO vê o que o paciente paga/deve —
GET detalhe omite pagamentos do lado clínica e zera o valor cobrado; a bancada também
zera o valor. O ajuste de valor do paciente é exclusivo da clínica (403 para o lab). No
front, o modo bancada esconde "Recebido do paciente".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Aba "Linha do tempo" movida para o FINAL (entregue/cancelar continuam nela).
- Etapas agora avançáveis também pela clínica (não só pelo lab): nova lista "Etapas do
trabalho" na 1ª aba, com botão "Avançar" por etapa. Backend: avanço da produção passa
a aceitar lab OU clínica de origem (auditado por actor). 'entregue' segue na timeline
(exige foto).
- Impressão por etapa em DOIS formatos: térmica (bobina 80mm) e laser (A4), com os dados
da OS preenchidos no recibo (paciente, trabalho, dentista, lab, dentes, material/cor,
componentes, prazo, local atual + assinaturas).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reorganiza o gerenciamento da OS em ABAS (sem o scrollão único):
- Etapas: dados + stepper; substitui entregue/cancelar por "imprimir cupom" de cada
etapa (comprovante imprimível que circula com o trabalho — janela de impressão).
- Linha do tempo: histórico com data/hora/autor; AQUI ficam marcar entregue / cancelar
(e o fluxo do lab / acionar garantia).
- Itens & Valores: componentes, fotos e pagamentos.
- Monitoramento: custódia do trabalho (clínica ↔ laboratório) — "protético retirou" /
"devolveu à clínica", com local atual em destaque e histórico de movimentações.
Backend: protese_os.local_atual + tabela protese_os_custodia + POST .../custodia
(valida transição, registra movimento e evento). GET detalhe expõe local_atual + custodia.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reformula o modal de detalhe da OS de prótese, fechando os gaps de gestão:
- Etapas: stepper visual do fluxo (solicitado→…→entregue) com a etapa atual e datas.
- Fotos: agora anexáveis TAMBÉM no modo clínica (antes só na bancada — beco sem saída
para entregar), com autoria (quem anexou), data e legenda; remover foto. Toda foto
entra no histórico.
- Componentes enviados: nova tabela protese_os_componente — item, qtd, quem enviou e
quando (ex.: implante, pilar, modelo). Add/remover.
- Valores recebidos (dois lados): nova tabela protese_os_pagamento — lado='clinica'
(paciente→clínica) e lado='lab' (clínica→lab), com totais, forma, autor e data.
- Auditoria: histórico com data+HORA e autor; foto/componente/pagamento viram eventos
rastreados. Helpers carregaOSComAcesso/logEventoOS reaproveitados nos sub-recursos.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- backend: tabelas protese_os/_evento/_foto/_produtos + endpoints /api/protese/*
(laboratorios, os, bancada, status, foto/raw assinado, produtos); catálogo do protético;
custo de lab → DESPESA na entrega (idempotente, estorno no delete) + garantia com foto.
- Acesso: helper proteticoAcessivelPelaClinica (interno por vínculo OU diretório) valida o POST
e o catálogo; catálogos passam por tenantGuard; correção do label da notificação (tipo resolvido).
- Frontend: ProteseView (Bancada do protético / Minhas OS da clínica) + rota /proteses
+ item de menu PRÓTESES no Sidebar (dentista/protético/funcionário).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>