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

13 KiB

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)

# 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)

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)

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

GET /skeen/frontend/v1/health

Respuesta:

{
  "status": "ok",
  "service": "skeen-frontend-api",
  "version": "1.1.0"
}

3.2 Auth

Login

POST /skeen/frontend/v1/auth/login

Body:

{
  "login": "admin",
  "password": "SkeenAdmin2026!"
}

Respuesta:

{
  "status": "success",
  "token": "eyJ...",
  "user": {
    "id": 1,
    "login": "admin",
    "name": "Administrador SKEEN",
    "role": "admin",
    "must_change_password": false
  }
}

Me

GET /skeen/frontend/v1/auth/me
Authorization: Bearer <token>

Logout

POST /skeen/frontend/v1/auth/logout
Authorization: Bearer <token>

Listar Usuarios (admin)

GET /skeen/frontend/v1/auth/users
Authorization: Bearer <token>

Crear Usuario (admin)

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)

PUT /skeen/frontend/v1/auth/users/<user_id>
Authorization: Bearer <token>

3.3 Citas

Listar Citas

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:

{
  "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

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:

{
  "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

GET /skeen/frontend/v1/appointments/<appointment_id>
Authorization: Bearer <token>

Actualizar Cita

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

DELETE /skeen/frontend/v1/appointments/<appointment_id>
Authorization: Bearer <token>

3.4 Servicios

Listar Servicios

GET /skeen/frontend/v1/services
Authorization: Bearer <token>

Respuesta:

{
  "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)

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)

PUT /skeen/frontend/v1/services/<service_id>
Authorization: Bearer <token>

3.5 Pacientes

Listar Pacientes

GET /skeen/frontend/v1/patients?page=1&page_size=50&search=Nombre
Authorization: Bearer <token>

Crear Paciente

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

GET /skeen/frontend/v1/patients/<patient_id>
Authorization: Bearer <token>

Actualizar Paciente

PUT /skeen/frontend/v1/patients/<patient_id>
Authorization: Bearer <token>

3.6 Monedero

Listar Monederos

GET /skeen/frontend/v1/wallets
Authorization: Bearer <token>

Respuesta:

{
  "status": "success",
  "wallets": [
    {
      "id": 1,
      "patient_id": 45044,
      "patient": "Negrete Ca Mou Cecile",
      "points": 450,
      "equivalent_mxn": 450,
      "transactions": []
    }
  ]
}

3.7 Ventas

Listar Ventas

GET /skeen/frontend/v1/sales?date_from=2026-07-01&date_to=2026-07-31
Authorization: Bearer <token>

Crear Venta

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

GET /skeen/frontend/v1/inventory
Authorization: Bearer <token>

3.9 WACRM Proxy

Listar Contactos

GET /skeen/frontend/v1/wacrm/contacts?page=1&page_size=50&search=Nombre
Authorization: Bearer <token>

Listar Conversaciones

GET /skeen/frontend/v1/wacrm/conversations?page=1&page_size=50
Authorization: Bearer <token>

Listar Mensajes

GET /skeen/frontend/v1/wacrm/messages?conversation_id=123
Authorization: Bearer <token>

Listar Deals

GET /skeen/frontend/v1/wacrm/deals
Authorization: Bearer <token>

Sincronizar WACRM → Odoo

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

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:

{
  "status": "success",
  "slots": [
    {
      "date": "2026-07-17",
      "time": "09:00",
      "datetime": "2026-07-17 09:00"
    }
  ]
}

4.2 Crear Cita

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

POST /skeen/api/v1/patient_balance
Content-Type: application/json
Authorization: Bearer <api_key>

{
  "phone": "526641234567"
}

Respuesta:

{
  "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

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

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

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)

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

GET /api/v1/contacts
Authorization: Bearer <api_key>

5.4 Webhooks

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

GET /health

6.2 Webhook WACRM

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:

{
  "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:

{
  "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.