feat(protese): Fase 1 — clínica de origem na OS + blindagem de CPF (LGPD)

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>
This commit is contained in:
VPS 4 Builder
2026-06-24 04:20:53 +02:00
parent 9f103be397
commit 7ae6993c4b
3 changed files with 92 additions and 4 deletions
+8
View File
@@ -296,6 +296,10 @@ const OSDetailModal: React.FC<{ id: string; modo: 'bancada' | 'clinica'; onClose
<div className="flex-1 overflow-y-auto p-5">
{tab === 'etapas' && (
<div className="space-y-5">
{/* Clínica de origem — crítico no multi-clínica (de qual clínica veio a OS). */}
{modo === 'bancada' && os.clinica_nome && (
<div className="bg-blue-50 rounded-xl px-3 py-2 flex items-center gap-2 text-xs font-black text-blue-700 uppercase"><Building2 size={14} /> Clínica: {os.clinica_nome}</div>
)}
<div className="flex items-center gap-2 flex-wrap">
{os.tipo_os === 'garantia' && <span className="text-[9px] font-black px-2 py-0.5 rounded-full bg-emerald-100 text-emerald-700 uppercase flex items-center gap-1"><ShieldCheck size={10} /> Garantia</span>}
{os.atrasada && <span className="text-[9px] font-black px-2 py-0.5 rounded-full bg-red-100 text-red-600 uppercase flex items-center gap-1"><AlertTriangle size={10} /> Atrasada</span>}
@@ -804,6 +808,10 @@ export const ProteseView: React.FC = () => {
{modo === 'bancada' ? (os.paciente_nome || 'Sem paciente') : (os.protetico_nome || 'Laboratório')}
{os.prazo_entrega ? ` · entrega ${dataBR(os.prazo_entrega)}` : ''}
</p>
{/* Clínica de origem: essencial quando o lab atende várias clínicas. */}
{modo === 'bancada' && os.clinica_nome && (
<p className="text-[10px] font-black text-blue-600 uppercase truncate flex items-center gap-1"><Building2 size={10} /> {os.clinica_nome}</p>
)}
</div>
<div className="flex items-center gap-2 shrink-0">
{os.atrasada && <AlertTriangle size={14} className="text-red-500" />}