Files
SKEEN-Proyecto/docs/api.md
Consultoría Alcaraz Salazar a718592291 Initial commit: SKEEN Derma Experts - Sistema Integral de Gestión Clínica
- Frontend React (SKEEN Brand) con Vite, TypeScript, Tailwind
- Frontend Homenest (versión alternativa)
- Módulos Odoo 17 custom (citas, pacientes, monedero, pagos, ventas, inventario, whatsapp)
- WACRM fork (Next.js 16 + Supabase)
- Hermes + Bridge + Skills (Qwen3.6 via Nan Builders)
- Scripts de migración y operación
- Documentación extensiva en docs/
2026-07-20 07:44:23 +00:00

739 lines
13 KiB
Markdown

# API Reference — SKEEN Derma Experts
**Versión:** 2.0
**Fecha:** 16 de julio de 2026
---
## 1. Introducción
Esta documentación describe todos los endpoints REST expuestos por el sistema SKEEN. Los endpoints están organizados por componente:
- **Odoo Frontend API** (`/skeen/frontend/v1/*`): Para el Frontend React.
- **Odoo Hermes API** (`/skeen/api/v1/*`): Para Hermes/skills (JSON-RPC/XML-RPC).
- **WACRM API** (`/api/v1/*`): Para WACRM público.
- **Bridge API** (`:8090/*`): Para webhooks WACRM → Hermes.
---
## 2. Autenticación
### 2.1 Frontend API (JWT)
```bash
# Login
curl -X POST http://localhost:8069/skeen/frontend/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"login":"admin","password":"SkeenAdmin2026!"}'
# Respuesta
{
"status": "success",
"token": "eyJ1aWQiOjEsImxvZ2luIjoiYWRtaW4iLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE3ODQyMzI3NDV9...",
"user": {
"id": 1,
"login": "admin",
"name": "Administrador SKEEN",
"role": "admin"
}
}
# Uso del token
curl -H "Authorization: Bearer <token>" http://localhost:8069/skeen/frontend/v1/appointments
```
### 2.2 Hermes API (API Key)
```bash
curl -X POST http://localhost:8069/skeen/api/v1/available_slots \
-H "Content-Type: application/json" \
-H "Authorization: Bearer skeen_api_key_2026" \
-d '{"service_id":1,"date_from":"2026-07-17","date_to":"2026-07-20"}'
```
### 2.3 WACRM API (Bearer Token)
```bash
curl -X POST http://localhost:3000/api/v1/messages \
-H "Authorization: Bearer wacrm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{"to":"+526641234567","type":"text","text":"Hola"}'
```
---
## 3. Odoo Frontend API
### 3.1 Health
```http
GET /skeen/frontend/v1/health
```
**Respuesta:**
```json
{
"status": "ok",
"service": "skeen-frontend-api",
"version": "1.1.0"
}
```
### 3.2 Auth
#### Login
```http
POST /skeen/frontend/v1/auth/login
```
**Body:**
```json
{
"login": "admin",
"password": "SkeenAdmin2026!"
}
```
**Respuesta:**
```json
{
"status": "success",
"token": "eyJ...",
"user": {
"id": 1,
"login": "admin",
"name": "Administrador SKEEN",
"role": "admin",
"must_change_password": false
}
}
```
#### Me
```http
GET /skeen/frontend/v1/auth/me
Authorization: Bearer <token>
```
#### Logout
```http
POST /skeen/frontend/v1/auth/logout
Authorization: Bearer <token>
```
#### Listar Usuarios (admin)
```http
GET /skeen/frontend/v1/auth/users
Authorization: Bearer <token>
```
#### Crear Usuario (admin)
```http
POST /skeen/frontend/v1/auth/users
Authorization: Bearer <token>
Content-Type: application/json
{
"login": "recepcion1",
"name": "Recepción 1",
"password": "Password123!",
"role": "recepcion"
}
```
#### Actualizar Usuario (admin)
```http
PUT /skeen/frontend/v1/auth/users/<user_id>
Authorization: Bearer <token>
```
---
### 3.3 Citas
#### Listar Citas
```http
GET /skeen/frontend/v1/appointments?page=1&page_size=50&date_from=2026-07-01&date_to=2026-07-31&state=confirmed&search=Nombre
Authorization: Bearer <token>
```
**Parámetros de query:**
- `page`: Número de página (default: 1)
- `page_size`: Items por página (default: 50, max: 200)
- `date_from`: Fecha inicio (YYYY-MM-DD)
- `date_to`: Fecha fin (YYYY-MM-DD)
- `state`: Estado (`pending`, `confirmed`, `arrived`, `in_progress`, `done`, `cancelled`, `no_show`)
- `patient_id`: ID del paciente
- `doctor_id`: ID del médico
- `search`: Búsqueda por nombre, paciente o servicio
**Respuesta:**
```json
{
"status": "success",
"appointments": [
{
"id": 1,
"reference": "CITA-001",
"patient_id": 45044,
"patient": "Negrete Ca Mou Cecile",
"phone": "526634347178",
"service_id": 1,
"service": "Consulta Dermatologica",
"service_category": "consulta",
"date": "2026-07-17",
"time": "10:00",
"state": "pending",
"payment_state": "not_paid",
"price": 800.0,
"doctor_id": null,
"doctor": null,
"branch": "rosarito",
"medium": "onsite",
"notes": "",
"package_finished": false,
"package_finished_date": null
}
],
"total": 1,
"page": 1,
"page_size": 50,
"total_pages": 1
}
```
#### Crear Cita
```http
POST /skeen/frontend/v1/appointments
Authorization: Bearer <token>
Content-Type: application/json
{
"partner_id": 45044,
"servicio_id": 1,
"date": "2026-07-17",
"time": 10.0,
"sessions": 1,
"branch": "rosarito",
"medium": "onsite",
"notes": "",
"state": "pending"
}
```
**Campos:**
- `partner_id` (required): ID del paciente
- `servicio_id` (required): ID del servicio
- `date` (required): Fecha (YYYY-MM-DD)
- `time` (required): Hora en float (10.0 = 10:00, 10.5 = 10:30)
- `sessions` (optional): Número de sesiones (default: 1). Si el servicio tiene `package_sessions > 0`, se usa ese valor por defecto.
- `branch` (optional): `rosarito` o `tijuana`
- `medium` (optional): `onsite` o `videocall`
- `notes` (optional): Notas
- `state` (optional): Estado inicial
**Respuesta:**
```json
{
"status": "success",
"appointment": { /* primera cita */ },
"appointments": [ /* todas las citas creadas */ ],
"sessions": 3
}
```
**Nota:** Si `sessions > 1`, se crean N citas separadas. La primera usa la fecha/hora proporcionada; las siguientes se programan cada 7 días a las 9:00 AM.
#### Obtener Cita
```http
GET /skeen/frontend/v1/appointments/<appointment_id>
Authorization: Bearer <token>
```
#### Actualizar Cita
```http
PUT /skeen/frontend/v1/appointments/<appointment_id>
Authorization: Bearer <token>
Content-Type: application/json
{
"date": "2026-07-18",
"time": 11.0,
"state": "confirmed",
"notes": "Paciente confirmó por teléfono"
}
```
#### Eliminar Cita
```http
DELETE /skeen/frontend/v1/appointments/<appointment_id>
Authorization: Bearer <token>
```
---
### 3.4 Servicios
#### Listar Servicios
```http
GET /skeen/frontend/v1/services
Authorization: Bearer <token>
```
**Respuesta:**
```json
{
"status": "success",
"services": [
{
"id": 1,
"code": "CONS-DERM",
"name": "Consulta Dermatologica",
"category": "consulta",
"price": 800.0,
"package_price": 0.0,
"package_sessions": 0,
"package_notes": "",
"duration_min": 30,
"description": "Evaluación completa...",
"color": "#1abc9c",
"service_group": "Consultas",
"is_favorite": true
}
]
}
```
#### Crear Servicio (admin)
```http
POST /skeen/frontend/v1/services
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "Peel Quimico",
"code": "PEEL-QUI",
"category": "tratamiento",
"price": 1500.0,
"duration_min": 30,
"package_price": 4000.0,
"package_sessions": 3,
"package_notes": "Ahorro de $500",
"description": "Exfoliación química...",
"color": "#9b59b6",
"service_group": "Faciales",
"is_favorite": false
}
```
#### Actualizar Servicio (admin)
```http
PUT /skeen/frontend/v1/services/<service_id>
Authorization: Bearer <token>
```
---
### 3.5 Pacientes
#### Listar Pacientes
```http
GET /skeen/frontend/v1/patients?page=1&page_size=50&search=Nombre
Authorization: Bearer <token>
```
#### Crear Paciente
```http
POST /skeen/frontend/v1/patients
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "Juan Pérez",
"phone": "526641234567",
"email": "juan@example.com",
"birthdate": "1990-01-15",
"gender": "male",
"blood_type": "O+",
"allergies": "Penicilina",
"notes": "Paciente nuevo"
}
```
#### Obtener Paciente
```http
GET /skeen/frontend/v1/patients/<patient_id>
Authorization: Bearer <token>
```
#### Actualizar Paciente
```http
PUT /skeen/frontend/v1/patients/<patient_id>
Authorization: Bearer <token>
```
---
### 3.6 Monedero
#### Listar Monederos
```http
GET /skeen/frontend/v1/wallets
Authorization: Bearer <token>
```
**Respuesta:**
```json
{
"status": "success",
"wallets": [
{
"id": 1,
"patient_id": 45044,
"patient": "Negrete Ca Mou Cecile",
"points": 450,
"equivalent_mxn": 450,
"transactions": []
}
]
}
```
---
### 3.7 Ventas
#### Listar Ventas
```http
GET /skeen/frontend/v1/sales?date_from=2026-07-01&date_to=2026-07-31
Authorization: Bearer <token>
```
#### Crear Venta
```http
POST /skeen/frontend/v1/sales
Authorization: Bearer <token>
Content-Type: application/json
{
"partner_id": 45044,
"lines": [
{
"service_id": 1,
"qty": 1,
"price_unit": 800.0
}
],
"payment_method": "cash",
"notes": ""
}
```
---
### 3.8 Inventario
#### Listar Inventario
```http
GET /skeen/frontend/v1/inventory
Authorization: Bearer <token>
```
---
### 3.9 WACRM Proxy
#### Listar Contactos
```http
GET /skeen/frontend/v1/wacrm/contacts?page=1&page_size=50&search=Nombre
Authorization: Bearer <token>
```
#### Listar Conversaciones
```http
GET /skeen/frontend/v1/wacrm/conversations?page=1&page_size=50
Authorization: Bearer <token>
```
#### Listar Mensajes
```http
GET /skeen/frontend/v1/wacrm/messages?conversation_id=123
Authorization: Bearer <token>
```
#### Listar Deals
```http
GET /skeen/frontend/v1/wacrm/deals
Authorization: Bearer <token>
```
#### Sincronizar WACRM → Odoo
```http
POST /skeen/frontend/v1/wacrm/sync
Authorization: Bearer <token>
Content-Type: application/json
{
"sync_contacts": true,
"sync_conversations": true,
"sync_messages": true,
"sync_deals": true
}
```
---
## 4. Odoo Hermes API
Estos endpoints usan `type='json'` y `auth='api_key'`.
### 4.1 Slots Disponibles
```http
POST /skeen/api/v1/available_slots
Content-Type: application/json
Authorization: Bearer <api_key>
{
"service_id": 1,
"date_from": "2026-07-17",
"date_to": "2026-07-20"
}
```
**Respuesta:**
```json
{
"status": "success",
"slots": [
{
"date": "2026-07-17",
"time": "09:00",
"datetime": "2026-07-17 09:00"
}
]
}
```
### 4.2 Crear Cita
```http
POST /skeen/api/v1/create_appointment
Content-Type: application/json
Authorization: Bearer <api_key>
{
"phone": "526641234567",
"name": "Juan Pérez",
"service_id": 1,
"date": "2026-07-17",
"time": "10:00"
}
```
### 4.3 Saldo del Paciente
```http
POST /skeen/api/v1/patient_balance
Content-Type: application/json
Authorization: Bearer <api_key>
{
"phone": "526641234567"
}
```
**Respuesta:**
```json
{
"status": "success",
"pending_balance": 1500.0,
"pending_invoices": [
{
"amount_residual": 1500.0,
"name": "INV/2026/0001"
}
],
"wallet_points": 450,
"wallet_mxn": 450
}
```
### 4.4 Redimir Puntos
```http
POST /skeen/api/v1/wallet_redeem
Content-Type: application/json
Authorization: Bearer <api_key>
{
"phone": "526641234567",
"points": 200,
"appointment_id": 123
}
```
### 4.5 Cancelar Cita
```http
POST /skeen/api/v1/cancel_appointment
Content-Type: application/json
Authorization: Bearer <api_key>
{
"phone": "526641234567",
"booking_id": 123
}
```
---
## 5. WACRM API
### 5.1 Enviar Mensaje
```http
POST /api/v1/messages
Authorization: Bearer <api_key>
Content-Type: application/json
{
"to": "+526641234567",
"type": "text",
"text": "Hola, tu cita está confirmada"
}
```
### 5.2 Simular Mensaje (Demo)
```http
POST /api/v1/messages/simulate
Authorization: Bearer <api_key>
Content-Type: application/json
{
"to": "+526641234567",
"type": "text",
"text": "Hola, tu cita está confirmada"
}
```
### 5.3 Contactos
```http
GET /api/v1/contacts
Authorization: Bearer <api_key>
```
### 5.4 Webhooks
```http
POST /api/v1/webhooks
Authorization: Bearer <api_key>
Content-Type: application/json
{
"url": "https://openclaw.skeen.mx/webhook/wacrm",
"events": ["message.received", "message.status_updated"]
}
```
---
## 6. Bridge API
### 6.1 Health
```http
GET /health
```
### 6.2 Webhook WACRM
```http
POST /webhook/wacrm
Content-Type: application/json
X-WACRM-Signature: t=...,v1=...
{
"from": "+526641234567",
"text": "Hola, quiero agendar una cita",
"conversation_id": "123",
"contact_id": "456"
}
```
**Respuesta:**
```json
{
"received": true,
"response": "Hola! Soy Sofia de SKEEN. Claro, ¿qué servicio te interesa?"
}
```
---
## 7. Códigos de Error
| Código | Significado |
|--------|-------------|
| 200 | OK |
| 201 | Creado |
| 400 | Bad Request — parámetros inválidos |
| 401 | Unauthorized — token inválido o faltante |
| 403 | Forbidden — permisos insuficientes |
| 404 | Not Found — recurso no encontrado |
| 409 | Conflict — conflicto (ej. usuario ya existe) |
| 500 | Internal Server Error |
**Formato de error:**
```json
{
"status": "error",
"message": "Descripción del error"
}
```
---
## 8. Rate Limiting
Actualmente no hay rate limiting implementado. Se recomienda configurar:
- **nginx:** `limit_req_zone`
- **WACRM:** Configurar en middleware
- **Odoo:** Configurar en `ir.http`
---
## 9. Versionado
La API está en versión `1.1.0`. Los cambios se documentan en el changelog de cada módulo.