DICOM Operations
Status: planejamento — nenhum código escrito
Criado em: 2026-04-17
Categoria: Roadmap > DICOM
Relação com outros docs: feature de power-user do super admin (ver SUPER_ADMIN_REDESIGN.md), mas com complexidades técnicas próprias que justificam doc separado
1. Por que fazer
O sistema hoje trata DICOM como imutável: chega, indexa, exibe, laudam. Nenhuma operação de manipulação de conteúdo. Na prática, clínicas precisam dessas operações com alguma frequência:- Paciente cadastrado errado no aparelho — nome “MARIA SIVLA” em vez de “MARIA SILVA”. Precisa corrigir.
- Paciente duplicado — mesmo paciente entrou como
João Ana Unidade Centro eJoão A.na Zona Sul. Estudos não aparecem juntos no histórico. Precisa merge. - Estudo em outro PACS — clínica quer puxar estudo de outro hospital (referência) para comparar. Hoje precisa enviar manualmente.
- Enviar estudo para outro PACS — médico pede para enviar estudo para RIS externo. Hoje precisa download manual + upload.
2. Operações propostas (MVP)
2.1 Modify
Alterar tags DICOM de um estudo, série ou instância. Casos típicos:- Corrigir
PatientName,PatientID,PatientBirthDate - Corrigir
StudyDescription,StudyDate - Anonimizar estudo (remover tags identificáveis — já tem endpoint Orthanc
/anonymize)
StudyInstanceUID,SeriesInstanceUID,SOPInstanceUID— quebra referências internasPixelData— não é uso de modify, é outra coisa (pós-processamento)
2.2 Merge de pacientes
Consolidar dois ou maisPatientIDs no sistema, quando são a mesma pessoa cadastrada com dados diferentes.
Fluxo:
- Usuário aponta “paciente A = paciente B”
- Sistema atualiza todos os estudos do paciente B para apontar para paciente A
- Paciente B é desativado (soft delete) ou removido
- Estudos modificam tag
PatientIDePatientNamenos DICOMs (via Orthanc modify)
2.3 C-GET / Query-Retrieve (pull de outro PACS)
Pedir estudo específico de outro PACS (pareamento DICOM via Orthanc SCU). Fluxo:- Operador informa: AET do PACS destino + StudyInstanceUID ou dados do paciente
- Orthanc executa C-FIND para localizar, depois C-MOVE (ou C-GET) para puxar
- Estudo chega via Orthanc e é indexado normalmente pelo nosso pipeline
2.4 C-MOVE (push para outro PACS)
Enviar estudo do nosso Orthanc para outro PACS externo. Fluxo:- Operador seleciona estudo + AET de destino
- Orthanc executa C-MOVE
- Log de sucesso/erro
3. Escopo — o que NÃO entra no MVP
- Alterar PixelData — requer ferramenta de desenho, anotação, blur. Outra feature.
- Segmentação / AI overlays — produto separado.
- Worklist (MWL) — gerenciar lista de trabalho do aparelho. Outra feature.
- Forward automático — “todo estudo da modality X replica para PACS Y” automaticamente. Fase posterior.
4. Decisões pendentes
4.1 Quem pode executar cada operação?
Proposta inicial:| Operação | Super Admin | Tenant Admin | Doutor |
|---|---|---|---|
| Modify (corrigir tag) | ✅ | ✅ (do tenant dele) | ❌ |
| Merge pacientes | ✅ | ✅ (aprova) | ❌ |
| Anonymize | ✅ | ✅ | ❌ |
| C-GET (pull externo) | ✅ | ✅ | ❌ |
| C-MOVE (push externo) | ✅ | ✅ | ❌ |
4.2 Reversibilidade — preservar original?
Opção A — Preservar: antes de modify/merge, Orthanc copia o estudo original para “trash” ou anonimiza criando novo. Reversível. Ocupa 2x storage. Opção B — Sobrescrever: modify altera in-place (Orthanc reescreve o DICOM). Não reversível. 1x storage. Opção C — Híbrida: preserva apenas se operador marcar “sensível”; default é sobrescrever. Proposta: A (preservar) — storage é barato, erro é caro. Retenção de 90 dias antes de hard-delete do original. Decisão pendente.4.3 Audit trail — nível de detalhe?
Mínimo: quem, quando, o quê (op type), estudo afetado. Médio: + diff de tags (antes/depois) em JSON. Completo: + quem autorizou (caso de workflow de aprovação), + motivo (text field obrigatório), + IP do operador. Proposta: completo — medicina exige alta rastreabilidade. Tabela nova:dicom_operations_audit (id, user_id, tenant_id, operation_type, study_id, series_id?, instance_id?, changes_json, reason, authorized_by_user_id?, ip_address, created_at).
Decisão pendente.
4.4 Sincronização com PostgreSQL após modify
Quando o DICOM muda (ex.:PatientName corrigido), nossos metadados em PG ficam stale:
studies.patient_namepatients.name- talvez
studies.patient_uuid(se oPatientIDmudou)
pacs:requeue --study-id X). Worker reindexa tudo.
Problema: se a operação modificou o PatientID, cria novo patients em vez de atualizar o existente. Precisa de merge explícito antes.
Decisão pendente: ordem das operações (merge de pacientes → depois modify das tags nos DICOMs vs tudo em uma transação).
4.5 C-GET vs C-MOVE: qual o mecanismo primário?
- C-GET: mais simples. Cliente inicia, servidor envia de volta na mesma conexão. Não precisa que o servidor remoto saiba como nos chamar.
- C-MOVE: servidor remoto precisa saber o AET de quem pede (nosso Orthanc) + nosso IP + porta. Mais setup, mas é o padrão da indústria.
4.6 Pareamento com PACS externos: por tenant ou global?
Se a Clínica Alfa tem acordo com Hospital X (C-MOVE entre eles), a configuração (AET do Hospital X, IP, porta) vai:- Por tenant: cada clínica gerencia seus pares. Mais autonomia, mais flexível.
- Global: pareamentos são cadastrados pelo super admin, tenants apenas usam. Mais controle, menos risco.
4.7 Operações assíncronas — UX
C-GET/C-MOVE podem demorar (estudo com 2000 imagens). Modify de estudo grande também.
- Síncrona com loading: UI trava até terminar. Simples, mas ruim com estudos grandes.
- Async com polling: UI dispara e volta; job ID retornado; frontend pollinga a cada 5s.
- Async com WebSocket: UI dispara; notificação em tempo real quando termina.
4.8 Recuperação de operações falhas
O que acontece se:- Modify falha no meio (algumas tags alteradas, outras não)?
- C-MOVE envia 500 de 2000 imagens e cai?
failed + rollback automático onde possível (modify com cópia do original), retry manual para network ops (C-MOVE/C-GET).
Decisão pendente.
4.9 Workflow de aprovação — tenant admin solicita, super admin aprova?
Para ops sensíveis (merge, modify de tags “fortes” como PatientID):- Sem workflow: tenant admin executa direto (se tiver permissão)
- Com workflow: tenant admin cria “pedido” → fica pendente → super admin aprova/rejeita
4.10 Limites de tags modificáveis
Lista positiva (whitelist) de tags que podem ser alteradas:- ✅ PatientName, PatientID, PatientBirthDate, PatientSex
- ✅ StudyDescription, StudyDate, AccessionNumber
- ✅ SeriesDescription, Modality (controverso)
- ❌ UIDs (quebram referências)
- ❌ PixelData (não é “modify”, é outra coisa)
- ❓ SOPClassUID, SOPInstanceUID, Manufacturer, etc.
5. Dependências
| Depende de | Por quê |
|---|---|
SUPER_ADMIN_REDESIGN.md | A UI dessas operações vive no painel super admin |
Orthanc com REST API /studies/{id}/modify, /merge, /move, /query | Já disponível |
| Worker Python capaz de reindexar 1 estudo | Comando pacs:requeue --study-id X |
| Storage com retenção configurável | Para “preservar original” por N dias (§4.2) |
| Pareamento DICOM — AETitles de outros PACS | Precisa cadastro + teste |
6. Riscos e considerações
6.1 Implicação médico-legal
Alterar tags de laudo/estudo é tema sensível. Qualquer operação precisa de:- Identificação do operador (user_id)
- Motivo obrigatório (text field)
- Log imutável
- Backup do original (pelo menos temporário)
ReportRevision).
6.2 Conflito com ingestão
Se um estudo está sendo processado pelo worker (primeira indexação) e um modify acontece nele simultaneamente, comportamento indefinido. Precisa:- Lock de estudo durante operação
- Ou política “não permitir modify em estudos com indexação pendente”
6.3 Consistência multi-tenant
Modify de um estudo do Tenant A não pode afetar Tenant B. Validação de scope em toda operação.6.4 Performance em estudos grandes
C-MOVE de estudo com 2000 imagens (ex.: CT torax-abdomen) pode demorar 5-10 minutos. UX precisa suportar isso.7. Plano de fases
Fase 0 — Decisões (AGORA)
Fechar §4.Fase 1 — Modify (simples)
Alteração de tags “fracas” (PatientName, StudyDescription) com whitelist limitada. Audit + reindexação.Fase 2 — Merge de pacientes
Combinar PatientIDs + modify dos DICOMs em batch.Fase 3 — C-MOVE para PACS externos
Pareamento + send. Estudos cadastrados manualmente.Fase 4 — C-GET / Query-Retrieve (pull)
Buscar estudos em PACS externo e puxar para o nosso.Fase 5 — Modify avançado
Tags “fortes” (PatientID, etc.) com workflow de aprovação e preservação do original.8. Discussões abertas
- Precisa de hardware especial para SCU? — C-MOVE/C-GET exige que nosso Orthanc seja SCU configurado. Performance em NVMe vs HDD?
- TLS DICOM — alguns PACS externos exigem DICOM sobre TLS. Orthanc suporta via plugin. Entra no MVP ou deixa pra quem pedir?
- Rate limiting — quantos C-MOVE simultâneos por tenant?
- Dry-run — antes de executar merge de pacientes, mostrar preview (“X estudos serão afetados”)? Sempre ou opt-in?
- “Desfazer” modify — janela de 24h para reverter via UI? Ou só restauração manual via script de DB?
- Histórico de operações por estudo — ao abrir um estudo, aba “Operações DICOM” mostra tudo que foi feito ali?
