RADIA — Radiología + IA
Plataforma de imagen médica con asistencia de inteligencia artificial.
URL: radia.cadences.app
Qué es RADIA
RADIA es un visor DICOM completo con IA integrada que permite a profesionales médicos subir estudios de imagen, visualizarlos en 2D/3D/MPR, y obtener análisis automatizado con modelos de visión multimodal.
Capacidades principales
- Visor DICOM — Navegación por cortes, zoom, pan, window/level, anotaciones DICOM
- Reconstrucción 3D — Volume rendering WebGL2 con ray marching (CBCT dental, TAC)
- MPR — Vista multiplanar axial/coronal/sagital sincronizada
- Captura 3D / LiDAR — Subida de mesh (USDZ/GLB/OBJ) desde iPhone/iPad Pro con sensor LiDAR, renders generados en cliente, fotos clínicas complementarias y overlay AR con rejilla de alineación (
MeshAROverlay) - Diff 3D longitudinal — Comparación entre dos capturas LiDAR del mismo sujeto con métricas Δ vol y colorización del mesh
- Scan 360° — Análisis automatizado de todo el estudio por lotes
- Diálogo de Pre-análisis — Modos: complementar, revisar, borrar y re-analizar. Incluye toggle Asteroide y campo de razón.
- Modo Asteroide — Multi-modelo paralelo (Gemini + Groq Specialist) con consenso cruzado
- Deep Analysis — Profundización por hallazgo con ±10 cortes de contexto
- Deep Filter — Filtro rápido para mostrar solo hallazgos con deep analysis
- Point-Ask — Click en cualquier punto → análisis localizado
- Modo Navegar — Click en el visor navega al hallazgo más cercano por distancia euclídea
- Gestión de hallazgos — Eliminar hallazgos individuales o grupos, ocultar/mostrar del informe
- Hallazgos agrupados — Deduplicación automática de hallazgos en cortes adyacentes con misma categoría/ubicación
- Chat IA — Conversación multimodal en tiempo real sobre el estudio
- Sujetos — Gestión de pacientes/animales/plantas (
radia_subjects) reutilizables entre estudios, con flujo dedicado en/subjects - RADS — Clasificaciones estructuradas (Lung-RADS, BI-RADS, Bone-RADS, etc.) por hallazgo y agregadas por estudio
- Modo Paciente — Visor compartido para paciente (
PatientSharedViewer) con explicación en lenguaje natural y preferencias de tono - Modo Médico / Colaborador — Enlaces compartidos con o sin autenticación, telemetría de visualización (
radia_share_view_tracking) - Informes PDF — A4 profesional + formato móvil 105×185 mm con miniaturas viewport, fotos clínicas y mesh renders. Toggle de tamaño de papel
- Implant Planner — Planificación de implantes dentales con
ImplantPlannerModal+ chart FDI interactivo - Onboarding y ayuda contextual —
OnboardingWizard+HelpSystemcon tooltips por panel
Modalidades soportadas
30+ tipos de estudio en 8 sectores: Dental (CBCT, Panorámica, Periapical), Radiología (Rx Tórax, Rx Ósea, TAC, Mamografía), RM (Cerebral, MSK, Columna, Abdomen), Ecografía (genérica + 6 subtipos), Foto Clínica (Dermatología, Podología, Oftalmología, Heridas, General), Veterinaria (genérica + 7 subtipos), Botánica, y Superficie 3D LiDAR (surface3d_lidar, surface3d_diff).
Ver docs/modalities.md para detalle completo.
Stack técnico
| Capa | Tecnología |
|---|---|
| Frontend | Astro 4.16 + React 18 + TypeScript + Tailwind CSS 3.4 |
| Backend | Cloudflare Workers (Functions) |
| Base de datos | Cloudflare D1 (SQLite) |
| Almacenamiento | Cloudflare R2 (S3-compatible) |
| IA primaria | Google Gemini 2.5 Flash (visión multimodal) |
| IA segunda opinión | Groq Llama 4 Scout (rol especialista) |
| IA fallback | Groq Llama 4 Scout 17B |
| Auth | Google OAuth 2.0 + JWT HS256 |
| DICOM parsing | dicom-parser + OpenJPEG WASM (JPEG 2000) |
| Hosting | Cloudflare Pages |
Roadmap — MedGemma 4B-IT: Modelo médico especializado de Google pendiente de integración como tercer proveedor IA. Dos vías previstas: (1) Vertex AI con GPUs bajo suscripción (~$500/mes por L4), o (2) ML Trainer local (app Electron de Cadences) ejecutando el modelo en hardware propio del usuario. La infraestructura JWT/SA ya está preparada (
vertex-auth.jsarchivado). Ver docs/asteroid-mode.md.
Estructura del proyecto
storefronts/radia/
├── src/
│ ├── components/ # ~25 componentes React
│ │ ├── StudyExplorer.tsx # Orquestador principal (visor + chat + IA)
│ │ ├── DicomViewer.tsx # Visor DICOM 2D (PACS-style)
│ │ ├── Volume3DViewer.tsx # Renderer 3D WebGL2 (volumen DICOM)
│ │ ├── MPRViewer.tsx # Vista multiplanar 2×2
│ │ ├── MeshViewer.tsx # Visor mesh 3D (model-viewer 3.5) — LiDAR
│ │ ├── MeshAROverlay.tsx # Cámara + mesh + rejilla AR de alineación
│ │ ├── CrossSectionPanel.tsx # Cortes oblicuos sobre volumen
│ │ ├── PanoramicPanel.tsx # Reconstrucción panorámica dental
│ │ ├── DentalSlotPreviews.tsx # Mini-previews por diente
│ │ ├── FDIToothChart.tsx # Chart FDI interactivo
│ │ ├── ToothPicker.tsx # Selector de diente
│ │ ├── ImplantPlannerModal.tsx # Planificador de implantes
│ │ ├── MeasurementOverlay.tsx # Medidas sobre el visor
│ │ ├── FindingsHeatStrip.tsx # Tira de hallazgos por corte
│ │ ├── FindingsHeatStrip2D.tsx # Tira para estudios 2D
│ │ ├── RadsModule.tsx # Clasificación RADS por hallazgo / estudio
│ │ ├── ReportViewer.tsx # Lectura inline de informes
│ │ ├── SignaturePad.tsx # Firma del informe
│ │ ├── ChatPanel.tsx # Chat IA conversacional
│ │ ├── DicomUploader.tsx # Subida de archivos DICOM / mesh
│ │ ├── SharedViewer.tsx # Visor compartido modo médico
│ │ ├── PatientSharedViewer.tsx # Visor compartido modo paciente
│ │ ├── PatientPresentationMode.tsx # Modo presentación clínica
│ │ ├── PatientPreferencesModal.tsx # Tono / idioma para explicación
│ │ ├── OnboardingWizard.tsx # Onboarding inicial
│ │ └── HelpSystem.tsx # Tooltips + ayuda contextual
│ ├── services/ # Servicios cliente
│ │ ├── dicomParser.ts # Parsing DICOM + JPEG 2000 (OpenJPEG WASM)
│ │ ├── sliceCache.ts # Cache API para thumbnails PNG
│ │ ├── volumeCache.ts # IndexedDB para volúmenes 3D
│ │ └── pdfReport.ts # `generateRadiaReport` (A4) + `generateMobilePatientReport` (105×185 mm)
│ ├── lib/
│ │ └── studyTypes.ts # Labels/iconos study_type + categorías (mirror frontend)
│ ├── config/storefront.config.ts
│ ├── types/index.ts # Interfaces TypeScript
│ ├── pages/ # Rutas Astro
│ │ ├── index.astro # Landing page
│ │ ├── study.astro # Visor de estudio
│ │ ├── dashboard.astro # Mis estudios (con modal "Nuevo estudio")
│ │ ├── shared.astro # Visor compartido (médico)
│ │ ├── collab.astro # Visor colaborador autenticado
│ │ ├── report.astro # Informe imprimible
│ │ ├── profile.astro # Perfil + preferencias
│ │ ├── upgrade.astro # Planes y suscripción
│ │ ├── lidar/upload.astro # Subida de captura LiDAR
│ │ ├── lidar/view.astro # Visor mesh
│ │ ├── lidar/diff/upload.astro # Crear diff longitudinal
│ │ ├── lidar/diff/view.astro # Visor diff coloreado
│ │ ├── subjects/index.astro # Lista de sujetos
│ │ ├── subjects/[id].astro # Detalle del sujeto
│ │ ├── admin/... # Panel interno
│ │ └── ayuda/... # Centro de ayuda
│ └── layouts/Layout.astro
├── functions/ # API Cloudflare Workers
│ ├── api/
│ │ ├── auth/google.js # OAuth2
│ │ ├── studies/ # CRUD estudios + finalize + comments
│ │ ├── analysis/ # scan360, deep, pointask, viewport, suggestions,
│ │ │ # surface3d, surface3d-diff, classify, whynot, explain-to-patient
│ │ ├── lidar/ # upload, file, list, diff/* (mesh + fotos + renders)
│ │ ├── subjects/ # CRUD sujetos
│ │ ├── chat.js # Chat multimodal
│ │ ├── share.js # Compartir (médico / paciente)
│ │ ├── dicom/ # Proxy DICOM autenticado
│ │ ├── public/ # Acceso por share token
│ │ ├── collab/ # Acceso colaborador
│ │ ├── admin/ # Endpoints internos
│ │ ├── profile.js # Preferencias usuario
│ │ └── upgrade-lead.js # Lead de upgrade
│ └── lib/ # Utilidades compartidas
│ ├── auth.js # requireAuth + nanoid
│ ├── jwt.js # JWT HS256
│ ├── response.js # Helpers HTTP
│ └── prompts.js # Prompts IA + STUDY_TYPES (mirror backend)
├── migrations/ # 015 migraciones D1 acumuladas
│ ├── 001_radia_schema.sql # users, studies, findings, chat, jobs
│ ├── 002_analysis_runs.sql
│ ├── 003_patient_explanations.sql
│ ├── 004_vet_animal_owner.sql
│ ├── 005_patient_preferences.sql
│ ├── 006_share_view_tracking.sql
│ ├── 007_structured_patient.sql
│ ├── 008_measurements.sql
│ ├── 009_rads_classifications.sql
│ ├── 010_rads_telemetry.sql
│ ├── 011_rads_backfill_telemetry.sql
│ ├── 012_finding_tooth_fdi.sql
│ ├── 013_study_instances.sql
│ ├── 014_surface3d_lidar.sql # viewport_image_key + tipo surface3d_*
│ └── 015_radia_subjects.sql # Sujetos reutilizables
├── docs/ # Documentación
│ ├── modalities.md
│ ├── architecture.md
│ ├── api-reference.md
│ ├── asteroid-mode.md
│ ├── deployment.md
│ └── STRATEGY.md
├── astro.config.mjs
├── wrangler.toml
├── tailwind.config.mjs
├── tsconfig.json
└── package.json
Inicio rápido
# Instalar dependencias
npm install
# Desarrollo local
npm run dev
# Preview con Workers locales (requiere wrangler)
npm run preview
# Build + deploy
npm run deploy
Variables de entorno requeridas
Configurar en el dashboard de Cloudflare Pages:
| Variable | Descripción |
|---|---|
GEMINI_API_KEY |
API key de Google Gemini |
GOOGLE_CLIENT_ID |
Client ID de Google OAuth |
JWT_SECRET |
Secreto para firmar tokens JWT |
GROQ_API_KEY |
API key de Groq (fallback + Asteroid specialist) |
Los bindings DB (D1) y DICOM_STORAGE (R2) se configuran automáticamente vía wrangler.toml.
Documentación
- Arquitectura — Componentes, flujos de datos, decisiones técnicas
- Referencia API — Todos los endpoints con ejemplos
- Modo Asteroide — Multi-modelo paralelo con consenso
- Modalidades — 16 tipos de estudio soportados
- Despliegue — Build, deploy, configuración Cloudflare
Planes
| Plan | Estudios | Upload máx | Características |
|---|---|---|---|
| Free | 5 | 500 MB | Visor + Scan 360° + Chat |
| Pro | 50 | 2 GB | + Deep Analysis + Asteroide + Sugerencias + LiDAR + Modo Paciente |
| Clinic | Ilimitado | 10 GB | + Colaboración + Informes A4 + RADS + Diff longitudinal + API |
Licencia
Proyecto propietario — Cadences