348 lines
12 KiB
Markdown
348 lines
12 KiB
Markdown
# RIPS Manager — Documentación Técnica
|
|
|
|
Sistema web para generar y enviar JSON de RIPS (Res. 2275/2023) a una API, conectándose a una base de datos Firebird.
|
|
|
|
---
|
|
|
|
## Arquitectura
|
|
|
|
```
|
|
┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
|
|
│ Navegador │────▶│ FastAPI (8080) │────▶│ Firebird BD │
|
|
│ (Tailwind) │◀────│ + Jinja2 │◀────│ (datos) │
|
|
└─────────────┘ └──────────────────┘ └──────────────┘
|
|
│
|
|
▼
|
|
┌──────────────┐
|
|
│ SQLite │
|
|
│ (app.db) │
|
|
└──────────────┘
|
|
│
|
|
▼
|
|
┌──────────────┐
|
|
│ API externa │
|
|
│ (envío RIPS)│
|
|
└──────────────┘
|
|
```
|
|
|
|
## Stack técnico
|
|
|
|
| Componente | Tecnología |
|
|
|---|---|
|
|
| Backend | Python 3.9+ / FastAPI |
|
|
| Frontend | Jinja2 + Tailwind CSS (CDN) + FontAwesome |
|
|
| Base de datos app | SQLite (usuarios, config, logs, queries) |
|
|
| Base de datos datos | Firebird (vía `fdb`) |
|
|
| Autenticación | JWT + bcrypt + HttpOnly cookies |
|
|
| Cliente HTTP | httpx (async) |
|
|
| Servidor | uvicorn |
|
|
|
|
---
|
|
|
|
## Endpoints (20 totales)
|
|
|
|
### Autenticación (6 endpoints)
|
|
|
|
| Método | Ruta | Descripción | Autenticación |
|
|
|---|---|---|---|
|
|
| GET | `/auth/login` | Página de inicio de sesión | Pública |
|
|
| POST | `/auth/login` | Procesa login, devuelve cookie JWT | Pública |
|
|
| GET | `/auth/register` | Página de registro | Pública |
|
|
| POST | `/auth/register` | Registra nuevo usuario | Pública |
|
|
| GET | `/auth/logout` | Cierra sesión (elimina cookie) | Pública |
|
|
| POST | `/auth/api/login` | Login vía API (devuelve token JSON) | Pública |
|
|
|
|
### Dashboard (1 endpoint)
|
|
|
|
| Método | Ruta | Descripción | Autenticación |
|
|
|---|---|---|---|
|
|
| GET | `/dashboard` | Estadísticas de envíos, últimos registros | Requerida |
|
|
|
|
### Configuración (2 endpoints)
|
|
|
|
| Método | Ruta | Descripción | Autenticación |
|
|
|---|---|---|---|
|
|
| GET | `/config` | Página de configuración (Firebird + API + prestador) | Requerida |
|
|
| POST | `/config/save` | Guarda toda la configuración | Requerida |
|
|
|
|
### Consultas SQL (3 endpoints)
|
|
|
|
| Método | Ruta | Descripción | Autenticación |
|
|
|---|---|---|---|
|
|
| GET | `/queries` | Página de gestión de consultas SQL | Requerida |
|
|
| POST | `/queries/create` | Crea nueva consulta SQL | Requerida |
|
|
| POST | `/queries/delete/{id}` | Elimina consulta SQL | Requerida |
|
|
| POST | `/queries/update/{id}` | Actualiza consulta SQL | Requerida |
|
|
|
|
### Terceros (3 endpoints)
|
|
|
|
| Método | Ruta | Descripción | Autenticación |
|
|
|---|---|---|---|
|
|
| GET | `/terceros` | Página de envío de terceros | Requerida |
|
|
| POST | `/terceros/test-connection` | Prueba conexión Firebird | Requerida |
|
|
| POST | `/terceros/preview` | Vista previa del JSON de terceros | Requerida |
|
|
| POST | `/terceros/send` | Genera y envía JSON de terceros a la API | Requerida |
|
|
|
|
### Transacción RIPS (3 endpoints)
|
|
|
|
| Método | Ruta | Descripción | Autenticación |
|
|
|---|---|---|---|
|
|
| GET | `/transaccion` | Página de envío de transacción RIPS | Requerida |
|
|
| POST | `/transaccion/preview` | Vista previa del JSON de transacción | Requerida |
|
|
| POST | `/transaccion/send` | Genera y envía JSON de transacción a la API | Requerida |
|
|
|
|
### Automatización (2 endpoints)
|
|
|
|
| Método | Ruta | Descripción | Autenticación |
|
|
|---|---|---|---|
|
|
| GET | `/automation` | Página de automatización 2 pasos | Requerida |
|
|
| POST | `/automation/run` | Ejecuta Paso 1 (terceros) + Paso 2 (transacción) | Requerida |
|
|
|
|
### Logs (1 endpoint)
|
|
|
|
| Método | Ruta | Descripción | Autenticación |
|
|
|---|---|---|---|
|
|
| GET | `/logs` | Historial de envíos con filtros | Requerida |
|
|
|
|
---
|
|
|
|
## Flujo de autenticación
|
|
|
|
```
|
|
Navegador Servidor
|
|
│ │
|
|
│── GET /auth/login ───────▶│
|
|
│◀──── HTML login page ─────│
|
|
│ │
|
|
│── POST /auth/login ───────▶│ (username + password)
|
|
│ │── verifica credenciales
|
|
│ │── genera JWT
|
|
│◀── 302 /dashboard ────────│ (Set-Cookie: token=JWT; HttpOnly)
|
|
│ │
|
|
│── GET /dashboard ────────▶│ (Cookie: token=JWT)
|
|
│ │── middleware verifica JWT
|
|
│ │── setea request.state.user
|
|
│◀──── HTML dashboard ──────│
|
|
```
|
|
|
|
- **Cookie HttpOnly**: no accesible desde JavaScript (seguridad XSS)
|
|
- **JWT expira en 12 horas**
|
|
- **Bearer token** también soportado para llamadas API (`Authorization: Bearer <token>`)
|
|
|
|
---
|
|
|
|
## Flujo de envío de RIPS
|
|
|
|
### Manual (página Terceros + Transacción)
|
|
|
|
```
|
|
1. Configurar conexión Firebird y API (una vez)
|
|
2. Definir consultas SQL en "Consultas SQL"
|
|
3. Ir a "Terceros" → seleccionar consulta → "Vista Previa" → "Enviar a API"
|
|
4. Ir a "Transacción RIPS" → seleccionar consulta + fechas → "Enviar a API"
|
|
```
|
|
|
|
### Automatizado (página Automatización)
|
|
|
|
```
|
|
1. Seleccionar consulta de terceros (Paso 1)
|
|
2. Seleccionar consulta de transacción (Paso 2)
|
|
3. Definir rango de fechas
|
|
4. "Ejecutar Automatización Completa"
|
|
└── Paso 1: Envía todos los terceros del período
|
|
└── Paso 2: Envía todas las transacciones del período
|
|
```
|
|
|
|
### Estructura de los JSON generados
|
|
|
|
#### JSON Terceros
|
|
```json
|
|
{
|
|
"tipoDocumentoIdentificacion": "CC",
|
|
"numDocumentoIdentificacion": "27765610",
|
|
"primerNombre": "MARIA",
|
|
"segundoNombre": "ELENA",
|
|
"primerApellido": "GOMEZ",
|
|
"segundoApellido": "RUIZ",
|
|
"fechaNacimiento": "1954-01-19",
|
|
"codSexo": "F",
|
|
"codEntidadAdministradora": "EPS010",
|
|
"tipoUsuario": "12",
|
|
"codPaisResidencia": "170",
|
|
"codMunicipioResidencia": "54001",
|
|
"codZonaTerritorialResidencia": "02",
|
|
"incapacidad": "NO",
|
|
"codPaisOrigen": "170",
|
|
"direccionResidencia": "CRA 5 #10-20",
|
|
"codZonaResidencia": "02"
|
|
}
|
|
```
|
|
|
|
#### JSON Transacción RIPS
|
|
```json
|
|
{
|
|
"numDocumentoIdObligado": "900278729",
|
|
"numFactura": "LHXC03404",
|
|
"tipoNota": null,
|
|
"numNota": null,
|
|
"usuarios": [{
|
|
"tipoDocumentoIdentificacion": "CC",
|
|
"numDocumentoIdentificacion": "27765610",
|
|
"codEntidadAdministradora": "EPS010",
|
|
"tipoUsuario": "12",
|
|
"fechaNacimiento": "1954-01-19",
|
|
"codSexo": "F",
|
|
"codPaisResidencia": "170",
|
|
"codMunicipioResidencia": "54001",
|
|
"codZonaTerritorialResidencia": "02",
|
|
"incapacidad": "NO",
|
|
"consecutivo": 1,
|
|
"codPaisOrigen": "170",
|
|
"servicios": {
|
|
"procedimientos": [{
|
|
"consecutivo": 1,
|
|
"codProcedimiento": "903841",
|
|
"fechaInicioAtencion": "2026-06-11 00:00",
|
|
"codDiagnosticoPrincipal": "R790",
|
|
"codDiagnosticoRelacionado": null,
|
|
"finalidadTecnologiaSalud": "23",
|
|
"viaIngresoServicioSalud": "02",
|
|
"modalidadGrupoServicioTecSal": "01",
|
|
"grupoServicios": "02",
|
|
"codServicio": 706,
|
|
"codPrestador": "540010152002",
|
|
"tipoDocumentoIdentificacion": "CC",
|
|
"numDocumentoIdentificacion": "27898369",
|
|
"vrServicio": 8000,
|
|
"valorPagoModerador": 0,
|
|
"conceptoRecaudo": "05",
|
|
"numAutorizacion": null,
|
|
"idMIPRES": null,
|
|
"codComplicacion": null,
|
|
"numFEVPagoModerador": null
|
|
}]
|
|
}
|
|
}]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Base de datos SQLite (app)
|
|
|
|
### Tabla `users`
|
|
| Columna | Tipo | Descripción |
|
|
|---|---|---|
|
|
| id | INTEGER PK | Auto-incrementable |
|
|
| username | TEXT UNIQUE | Nombre de usuario |
|
|
| email | TEXT UNIQUE | Correo electrónico |
|
|
| password_hash | TEXT | Hash bcrypt de la contraseña |
|
|
| created_at | TEXT | Fecha de creación |
|
|
|
|
### Tabla `config`
|
|
| Columna | Tipo | Descripción |
|
|
|---|---|---|
|
|
| id | INTEGER PK | Auto-incrementable |
|
|
| key | TEXT UNIQUE | Clave de configuración |
|
|
| value | TEXT | Valor |
|
|
|
|
Claves predefinidas:
|
|
- `firebird_host`, `firebird_port`, `firebird_database`, `firebird_user`, `firebird_password`
|
|
- `api_url`, `api_method`, `api_key`, `api_timeout`
|
|
- `num_documento_obligado`, `cod_prestador`
|
|
|
|
### Tabla `queries`
|
|
| Columna | Tipo | Descripción |
|
|
|---|---|---|
|
|
| id | INTEGER PK | Auto-incrementable |
|
|
| name | TEXT | Nombre descriptivo |
|
|
| query_type | TEXT | `terceros` o `transaccion` |
|
|
| query_text | TEXT | Sentencia SQL con parámetros |
|
|
| description | TEXT | Descripción |
|
|
| created_at | TEXT | Fecha de creación |
|
|
|
|
### Tabla `envios`
|
|
| Columna | Tipo | Descripción |
|
|
|---|---|---|
|
|
| id | INTEGER PK | Auto-incrementable |
|
|
| user_id | INTEGER FK | Usuario que realizó el envío |
|
|
| tipo | TEXT | `terceros` o `transaccion` |
|
|
| factura | TEXT | Número de factura |
|
|
| fecha_inicio / fecha_fin | TEXT | Rango de fechas del envío |
|
|
| pacientes_count / servicios_count | INTEGER | Cantidades |
|
|
| status | TEXT | `success` o `error` |
|
|
| json_enviado | TEXT | JSON completo enviado |
|
|
| respuesta_api | TEXT | Respuesta de la API |
|
|
| codigo_cuv | TEXT | Código CUV (si aplica) |
|
|
| created_at | TEXT | Fecha del envío |
|
|
|
|
---
|
|
|
|
## Parámetros en consultas SQL
|
|
|
|
Las consultas pueden usar estos parámetros que el sistema reemplaza automáticamente:
|
|
|
|
| Parámetro | Ejemplo | Uso |
|
|
|---|---|---|
|
|
| `:doc_num` | `WHERE doc = :doc_num` | Filtrar por documento de paciente |
|
|
| `:factura` | `WHERE fact = :factura` | Filtrar por número de factura |
|
|
| `:fecha_ini` | `WHERE fecha >= :fecha_ini` | Fecha inicio del rango |
|
|
| `:fecha_fin` | `WHERE fecha <= :fecha_fin` | Fecha fin del rango |
|
|
|
|
---
|
|
|
|
## Estructura del proyecto
|
|
|
|
```
|
|
rips_manager/
|
|
├── main.py # Entry point, middleware, rutas
|
|
├── requirements.txt # Dependencias Python
|
|
├── rips_manager.db # SQLite (autogenerado)
|
|
├── DOCUMENTACION.md # Este archivo
|
|
├── README.md # Documentación de RIPS
|
|
├── ejemplo_terceros.json # JSON de ejemplo terceros
|
|
├── ejemplo_transaccion_rips.json # JSON de ejemplo transacción
|
|
├── app/
|
|
│ ├── __init__.py
|
|
│ ├── auth.py # JWT, bcrypt, get_current_user
|
|
│ ├── database.py # SQLite init y conexión
|
|
│ ├── models.py # Pydantic models
|
|
│ ├── routes/
|
|
│ │ ├── auth.py # Login, register, logout
|
|
│ │ ├── dashboard.py # Página principal con stats
|
|
│ │ ├── config.py # Configuración Firebird + API
|
|
│ │ ├── queries.py # CRUD de consultas SQL
|
|
│ │ ├── terceros.py # Generar y enviar JSON terceros
|
|
│ │ ├── transaccion.py # Generar y enviar JSON transacción
|
|
│ │ ├── automation.py # Paso 1 + Paso 2 automático
|
|
│ │ └── logs.py # Historial de envíos
|
|
│ ├── services/
|
|
│ │ ├── firebird_service.py # Conexión y consultas Firebird
|
|
│ │ ├── json_generator.py # Construcción de JSON RIPS
|
|
│ │ └── api_client.py # Envío HTTP a API externa
|
|
│ └── templates/ # 10 plantillas Jinja2 + Tailwind
|
|
```
|
|
|
|
---
|
|
|
|
## Cómo ejecutar
|
|
|
|
```bash
|
|
cd /Users/lizandro/Documents/proyectos/rips_manager
|
|
pip3 install -r requirements.txt
|
|
python3 main.py
|
|
```
|
|
|
|
Abrir en el navegador: **http://localhost:8080**
|
|
|
|
---
|
|
|
|
## Secuencia para primer uso
|
|
|
|
1. Abrir http://localhost:8080/auth/register
|
|
2. Crear usuario y contraseña
|
|
3. Iniciar sesión
|
|
4. Ir a **Configuración** → configurar Firebird, API, datos del prestador
|
|
5. Ir a **Consultas SQL** → ajustar las queries a los nombres reales de tablas
|
|
6. Usar **Terceros**, **Transacción RIPS** o **Automatización**
|