LunarScan es una aplicacion de orientacion temprana de lesiones cutaneas. El proyecto combina una app movil para pacientes, un dashboard web, una base de datos Supabase y un microservicio de IA que evalua imagenes de lesiones junto con informacion ingresada en un formulario.
El sistema entrega una orientacion preliminar, no un diagnostico medico.
El repositorio ya contiene una base funcional para el PMV:
- API FastAPI con endpoints para crear casos, evaluar lesiones y consultar resultados.
- Modelo de clasificacion en
ml/, consumido por la API. - Reglas de interpretacion en backend para transformar la salida del modelo en categorias comprensibles para el usuario.
- Migraciones Supabase para perfiles, casos, imagenes, control de calidad y resultados de evaluacion.
- Estructura base para dashboard web y app movil.
api/ Backend FastAPI. Crea casos con imagen, ejecuta el modelo,
interpreta resultados y guarda evaluaciones en Supabase.
ml/ Codigo del modelo, scripts de entrenamiento/inferencia, dataset,
artefactos y resultados asociados.
web/ Dashboard web en SvelteKit.
mobile/ Aplicacion movil Flutter.
supabase/ Configuracion local, migraciones SQL y estructura de base de datos.
docs/ Documentacion del proyecto e historias de usuario.
mockups/ Referencias visuales del flujo esperado.
- Backend: FastAPI, Pydantic, Supabase Python, PyTorch.
- Modelo IA: PyTorch, torchvision, ResNet50 multimodal.
- Base de datos y storage: Supabase, PostgreSQL, Storage, RLS.
- Web: SvelteKit, TypeScript, Tailwind.
- Mobile: Flutter, Riverpod, go_router, Supabase Flutter.
- Gestion de dependencias: uv, pnpm, Flutter pub.
La arquitectura formal del sistema esta documentada en:
docs/architecture.md
La API usa una arquitectura modular por dominio con Clean Architecture simplificada:
api/app/
main.py
core/
shared/
infrastructure/
supabase/
model/
modules/
auth/
evaluations/
images/
lesion_cases/
image_quality/
profiles/
Dentro de cada modulo complejo se usa este criterio:
presentation/ Endpoints HTTP y schemas Pydantic.
application/ Casos de uso y coordinacion de flujos.
domain/ Reglas propias del negocio.
infrastructure/ Implementaciones concretas especificas del modulo.
Flujo del endpoint principal:
lesion_cases/presentation/router.py
-> evaluations/application/evaluate_lesion_case.py
-> images/application/image_storage.py
-> shared/infrastructure/model/lesion_classifier.py
-> evaluations/domain/risk_interpreter.py
-> evaluations/infrastructure/supabase_evaluation_repository.py
-> lesion_cases/infrastructure/supabase_lesion_case_repository.py
Antes de levantar el proyecto, instalar:
- Python 3.12
- uv
- Node.js 22 o superior
- pnpm
- Flutter
- Supabase CLI
Desde la raiz del repositorio:
.\scripts\setup.ps1El script instala las dependencias de api/, web/ y mobile/. Tambien crea
los archivos locales de ambiente desde sus plantillas si todavia no existen.
Opciones utiles:
.\scripts\setup.ps1 -SkipMobile
.\scripts\setup.ps1 -SkipWeb
.\scripts\setup.ps1 -SkipApiLuego de instalar, completar:
api/.env
web/.env
La API necesita:
SUPABASE_URL=https://<project-ref>.supabase.co
SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
MODEL_PATH=../ml/artifacts/lunarscan_multimodal_padufes.pt
La web necesita:
PUBLIC_SUPABASE_URL=https://<project-ref>.supabase.co
PUBLIC_SUPABASE_ANON_KEY=
Las credenciales se obtienen desde el dashboard del proyecto Supabase remoto.
La API usa la clave service_role porque guarda casos, imagenes y resultados
desde el backend. La web usa la clave publica anon.
El proyecto esta pensado para trabajar contra Supabase remoto. Para enlazar el repositorio con el proyecto remoto y aplicar migraciones:
supabase link --project-ref <project-ref>
supabase db pushLas migraciones estan en:
supabase/migrations/
Supabase local es opcional para pruebas aisladas. En ese caso tambien se requiere Docker:
supabase start
supabase db resetcd api
.venv\Scripts\fastapi.exe dev app\main.pyURLs:
http://localhost:8000/health
http://localhost:8000/docs
cd web
pnpm devURL:
http://localhost:5173
cd mobile
flutter run- El usuario captura o sube una imagen desde el celular.
- La API crea un caso de lesion en estado
draft. - El usuario completa el formulario.
- La API evalua el caso usando la imagen guardada y las respuestas del formulario.
- El backend interpreta la salida del modelo junto con el formulario.
- Se guarda el resultado en Supabase.
- Se devuelve una respuesta con categoria, explicacion y orientacion.
La probabilidad principal viene del modelo multimodal. El formulario genera un puntaje de senales clinicas que se usa para explicar el resultado y como regla de seguridad cuando las senales son relevantes.
Endpoints principales:
POST /auth/register
POST /auth/login
GET /auth/me
GET /lesion-cases
POST /lesion-cases
POST /lesion-cases/{case_id}/evaluations
GET /lesion-cases/{case_id}
GET /evaluations/{result_id}
Formatos esperados:
POST /lesion-cases
multipart/form-data
image: JPEG, PNG o WEBP
Authorization: Bearer <access_token> opcional para pruebas anonimas
POST /lesion-cases/{case_id}/evaluations
application/json
formulario de lesion
Authorization: Bearer <access_token> si el caso pertenece a un usuario
GET /lesion-cases
Authorization: Bearer <access_token>
lista el historial de casos del perfil autenticado
El inicio de sesion del PMV usa Supabase Auth. La contrasena queda gestionada
por Supabase; el usuario ingresa con correo y contrasena. profiles guarda
correo, username interno generado desde nombre/apellido, nombre, apellido y
rol. Los casos se asocian al usuario mediante lesion_cases.patient_id.
API:
cd api
.venv\Scripts\python.exe -m pytest
.venv\Scripts\python.exe -m ruff check appWeb:
cd web
pnpm lintMobile:
cd mobile
flutter analyze