- sharp usa binario prebuilt (libvips embarcado) -> remove apk vips/vips-dev (camada ~400MB)
- toolchain (python3/make/g++) virtual, removido na mesma RUN
- .dockerignore exclui updates/ (196MB, servido por volume), data/, bkp/, **/node_modules
- corrige PUT 500/499 no registry (camadas grandes estouravam o limite de upload)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- .gitea/workflows/build.yml: push->build rx-scoreodonto:<sha> no registry; tag->promote+deploy
- docker-compose.prod.yml: image do registry, APP_VERSION/GIT_COMMIT em runtime
- deploy-prod.sh: VPS1 pull + up --no-build (antigo vira deploy-prod-legado-webhook.sh)
- /api/health usa APP_VERSION (tag) com fallback version.txt; badge no canto
- webhook 9003 aposentado (gatilho agora e CI/tag)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
test-db2.js usava DB_PASSWORD e machine_token hardcoded -> process.env.
EXEMPLO-ENV.txt tinha o JWT_SECRET real -> placeholder. Rotação ainda mandatória.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
JWT_SECRET real (era == produção) e DB/REDIS_PASSWORD reais estavam commitados em
docs. Substituídos por placeholder + referência ao .secrets.
ATENÇÃO: continuam no HISTÓRICO do git → rotação do JWT_SECRET e da senha do
Postgres/Redis é MANDATÓRIA (+ scrub do histórico). Ver RX_BACKLOG T5.6.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GET /api/admin/rx-health (admin): contagens por (tenant_id, clinica_id) + último
resultado do cron de storage; ?clinica_id=&checkLimit=N faz HEAD-check bounded de
objetos ausentes no Wasabi. Read-only, aditivo.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Antes do INSERT, remove linha existente com mesmo original_filename. Sem isso, o
reenvio (sync-request/Plan B) de um arquivo cujo objeto Wasabi sumiu mas a linha
existia criava DUPLICATA. Descoberto no teste de resync de 3 radiografias.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
storage.js: escrita usa key nova (tenant/clinica/paciente) quando o device tem
tenant+clinica; leitura testa existência e cai para a key legada (clinic_name/
client_name/...) e raiz — não quebra objetos antigos antes do resync. deleteImage
apaga todas as keys. getUploadPresignedUrl/saveImage recebem tenantId/clinicaId.
Verificado em dev: presigned URL -> u_…/c_…/paciente/arquivo; leitura de imagem
existente (key legada) -> HTTP 200 via fallback.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Hierarquia tenant_id (usuarios.id do dono) / clinica_id / pc / paciente, espelhando
o scoreodonto (conta multi-clínica planejada: um dono gerencia várias clínicas).
- Colunas tenant_id em clinics_devices e images (+índices); backfill device + 2776 imgs.
- Cadastro de device, socket (machine_token), JWT de client e uploads gravam tenant_id.
- Listagens (/images, /patients, /by-patient, /unique-clinics) filtram por tenant_id e/ou clinica_id.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- clinica_id (tenant do scoreodonto, clinicas.id) como eixo de isolamento em
clinics_devices e images (+índices); clinic_name vira rótulo legível.
- Cadastro de device, socket (machine_token) e uploads (direct + legado) gravam clinica_id.
- Listagens (/images, /patients, /by-patient, /unique-clinics) filtram por clinica_id.
- /clients: lista clientes Windows ativos (inclui autenticados sem client-identify),
tempo real + polling, exibe a clínica.
- send-image marcado como legado (client real usa Direct Upload).
Inclui trabalho de dev acumulado no working tree (não havia commits desde origin/main).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>