Files
bot_palmas/API-ERP-PALMAS360.md
Lizandro GuarnizoandClaude Sonnet 4.6 fb28140e23 docs: API spec for ERP Palmas360 — all 16 endpoints documented
Complete endpoint specification for the ERP team:
- 10 GET (download) endpoints returning PDF/Excel files
- 6 POST (upload) endpoints receiving WhatsApp form data
- Auth headers, request/response schemas, and endpoint_key mapping table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 09:03:01 -05:00

498 lines
14 KiB
Markdown

# Especificación de Endpoints — ERP Palmas360 ↔ Bot WhatsApp
> **Para el equipo de Palmas360:** Este documento describe todos los endpoints que el ERP debe implementar para que el bot de WhatsApp funcione correctamente. Los endpoints marcados con ⚠️ actualmente apuntan a URLs de prueba (`httpbin.org/post`) y deben ser reemplazados con las URLs reales del ERP.
---
## Autenticación
Todas las llamadas del bot al ERP incluyen dos headers de autenticación:
```
Authorization: Bearer {api_key}
X-API-Key: {api_key}
```
El `api_key` es la clave configurada para Palmas360 en el bot. Validar cualquiera de los dos headers es suficiente.
---
## Resumen de endpoints
| # | Tipo | Endpoint ERP | Descripción | Estado |
|---|------|--------------|-------------|--------|
| 1 | GET | `/fincas` | Lista de fincas activas | Pendiente |
| 2 | GET | `/ciclos/cosecha` | Informe ciclos cosecha | Pendiente |
| 3 | GET | `/ciclos/sanidad/censo` | Informe ciclos censo | Pendiente |
| 4 | GET | `/ciclos/sanidad/plagas` | Informe ciclos plagas | Pendiente |
| 5 | GET | `/ciclos/sanidad/palm` | Informe RHYN. PALM. | Pendiente |
| 6 | GET | `/ciclos/sanidad/tratamientos` | Informe ciclos tratamientos | Pendiente |
| 7 | GET | `/ciclos/polinizacion` | Informe ciclos polinización | Pendiente |
| 8 | GET | `/produccion/kilos-finca` | Kilos facturados por finca | Pendiente |
| 9 | GET | `/produccion/kilos-lotes` | Kilos por lotes (rango fechas) | Pendiente |
| 10 | GET | `/mantenimiento` | Ciclos mantenimiento a la fecha | Pendiente |
| 11 | POST | `/ciclos/cosecha` | Registrar ciclo cosecha | ⚠️ Test |
| 12 | POST | `/ciclos/sanidad` | Registrar ciclo sanidad | ⚠️ Test |
| 13 | POST | `/ciclos/polinizacion` | Registrar ciclo polinización | ⚠️ Test |
| 14 | POST | `/tiquetes` | Registrar tiquete báscula | ⚠️ Test |
| 15 | POST | `/ausentismos` | Registrar ausentismo | ⚠️ Test |
| 16 | POST | `/pluviometria` | Registrar lecturas pluviometría | ⚠️ Test |
---
## Endpoints de DESCARGA (GET) — Bot consulta, ERP responde con archivo
El bot llama estos endpoints y reenvía la respuesta como documento al usuario de WhatsApp. **La respuesta debe ser un archivo descargable** (PDF o Excel).
### 1. Lista de fincas
Usado para mostrar la lista de fincas en flujos dinámicos (Producción kilos por finca, Pluviometría).
```
GET {url_base}/fincas
Headers:
Authorization: Bearer {api_key}
X-API-Key: {api_key}
```
**Respuesta esperada (JSON, 200):**
```json
[
{ "id": "finca_001", "label": "Finca La Palma" },
{ "id": "finca_002", "label": "Finca El Diamante" },
{ "id": "finca_003", "label": "Finca Los Almendros" }
]
```
> El campo `id` es el valor que el bot usará internamente; `label` es lo que ve el usuario en WhatsApp.
---
### 2. Ciclos cosecha
```
GET {url_base}/ciclos/cosecha
Headers:
Authorization: Bearer {api_key}
X-API-Key: {api_key}
Query params:
fecha_desde (YYYY-MM-DD) — fecha inicio del período
fecha_hasta (YYYY-MM-DD) — fecha fin del período
```
El bot envía automáticamente:
- **"Día actual"** → `fecha_desde` y `fecha_hasta` = hoy
- **"Histórico 30 días"** → `fecha_desde` = hace 30 días, `fecha_hasta` = hoy
**Respuesta esperada:** Archivo binario (PDF o Excel)
```
Content-Type: application/pdf
Content-Disposition: attachment; filename="ciclos_cosecha.pdf"
[bytes del archivo]
```
---
### 3. Ciclos sanidad — Censo
```
GET {url_base}/ciclos/sanidad/censo
Headers:
Authorization: Bearer {api_key}
X-API-Key: {api_key}
Query params:
fecha_desde (YYYY-MM-DD)
fecha_hasta (YYYY-MM-DD)
```
**Respuesta:** Archivo PDF o Excel.
---
### 4. Ciclos sanidad — Plagas
```
GET {url_base}/ciclos/sanidad/plagas
Headers:
Authorization: Bearer {api_key}
X-API-Key: {api_key}
Query params:
fecha_desde (YYYY-MM-DD)
fecha_hasta (YYYY-MM-DD)
```
**Respuesta:** Archivo PDF o Excel.
---
### 5. Ciclos sanidad — RHYN. PALM.
```
GET {url_base}/ciclos/sanidad/palm
Headers:
Authorization: Bearer {api_key}
X-API-Key: {api_key}
Query params:
fecha_desde (YYYY-MM-DD)
fecha_hasta (YYYY-MM-DD)
```
**Respuesta:** Archivo PDF o Excel.
---
### 6. Ciclos sanidad — Tratamientos
```
GET {url_base}/ciclos/sanidad/tratamientos
Headers:
Authorization: Bearer {api_key}
X-API-Key: {api_key}
Query params:
fecha_desde (YYYY-MM-DD)
fecha_hasta (YYYY-MM-DD)
```
**Respuesta:** Archivo PDF o Excel.
---
### 7. Ciclos polinización
```
GET {url_base}/ciclos/polinizacion
Headers:
Authorization: Bearer {api_key}
X-API-Key: {api_key}
Query params:
fecha_desde (YYYY-MM-DD)
fecha_hasta (YYYY-MM-DD)
```
**Respuesta:** Archivo PDF o Excel.
---
### 8. Producción kilos por finca
```
GET {url_base}/produccion/kilos-finca
Headers:
Authorization: Bearer {api_key}
X-API-Key: {api_key}
Query params:
finca_id — ID de la finca seleccionada por el usuario (viene de /fincas)
fecha_desde (YYYY-MM-DD)
fecha_hasta (YYYY-MM-DD)
```
**Respuesta:** Archivo PDF o Excel con kilos facturados para esa finca.
---
### 9. Producción kilos por lotes
```
GET {url_base}/produccion/kilos-lotes
Headers:
Authorization: Bearer {api_key}
X-API-Key: {api_key}
Query params:
fecha_desde (YYYY-MM-DD) — ingresada por el usuario
fecha_hasta (YYYY-MM-DD) — ingresada por el usuario
```
**Respuesta:** Archivo PDF o Excel con kilos por lote en el rango de fechas.
---
### 10. Mantenimiento
```
GET {url_base}/mantenimiento
Headers:
Authorization: Bearer {api_key}
X-API-Key: {api_key}
Query params:
fecha_desde (YYYY-MM-DD)
fecha_hasta (YYYY-MM-DD)
```
**Respuesta:** Archivo PDF o Excel con ciclos de mantenimiento.
---
## Endpoints de SUBIDA (POST) — Bot envía datos capturados del usuario ⚠️
El bot guía al usuario campo por campo, muestra un resumen, pide confirmación, y luego hace un POST al ERP con los datos. El usuario que envía incluye siempre su número de teléfono y nombre de perfil de WhatsApp.
**Headers en todos los POST:**
```
Content-Type: application/json
Authorization: Bearer {api_key}
X-API-Key: {api_key}
```
**Respuesta esperada en todos los POST (200):**
```json
{
"status": "ok",
"message": "Registro guardado correctamente"
}
```
Si hay error (400/500):
```json
{
"status": "error",
"message": "Descripción del error"
}
```
---
### 11. ⚠️ Registrar ciclo cosecha
```
POST {url_base}/ciclos/cosecha
```
**Body JSON:**
```json
{
"fecha": "2026-06-30",
"finca": "La Palma",
"lote": "Lote 3A",
"racimos": "120",
"telefono": "573168950803",
"nombre": "Juan Pérez"
}
```
| Campo | Tipo | Descripción |
|-------|------|-------------|
| `fecha` | string (YYYY-MM-DD o texto libre) | Fecha del ciclo ingresada por el usuario |
| `finca` | string | Nombre de la finca |
| `lote` | string | Identificador del lote |
| `racimos` | string | Cantidad de racimos |
| `telefono` | string | Número WhatsApp del usuario que reporta |
| `nombre` | string | Nombre del perfil WhatsApp del usuario |
---
### 12. ⚠️ Registrar ciclo sanidad
```
POST {url_base}/ciclos/sanidad
```
**Body JSON:**
```json
{
"fecha": "2026-06-30",
"finca": "La Palma",
"tipo_ciclo": "Censo",
"observaciones":"Sin novedades",
"telefono": "573168950803",
"nombre": "Juan Pérez"
}
```
| Campo | Tipo | Descripción |
|-------|------|-------------|
| `fecha` | string | Fecha del ciclo |
| `finca` | string | Nombre de la finca |
| `tipo_ciclo` | string | Tipo de ciclo (Censo, Plagas, RHYN, Tratamiento…) |
| `observaciones` | string | Observaciones libres del usuario |
| `telefono` | string | Número WhatsApp |
| `nombre` | string | Nombre perfil WhatsApp |
---
### 13. ⚠️ Registrar ciclo polinización
```
POST {url_base}/ciclos/polinizacion
```
**Body JSON:**
```json
{
"fecha": "2026-06-30",
"finca": "La Palma",
"lote": "Lote 2B",
"palmas_polinizadas": "85",
"telefono": "573168950803",
"nombre": "Juan Pérez"
}
```
| Campo | Tipo | Descripción |
|-------|------|-------------|
| `fecha` | string | Fecha del ciclo |
| `finca` | string | Nombre de la finca |
| `lote` | string | Lote trabajado |
| `palmas_polinizadas` | string | Número de palmas polinizadas |
| `telefono` | string | Número WhatsApp |
| `nombre` | string | Nombre perfil WhatsApp |
---
### 14. ⚠️ Registrar tiquete báscula
```
POST {url_base}/tiquetes
```
**Body JSON:**
```json
{
"fecha": "2026-06-30",
"numero_tiquete": "T-00452",
"finca": "El Diamante",
"kilos": "3450",
"telefono": "573168950803",
"nombre": "Juan Pérez"
}
```
| Campo | Tipo | Descripción |
|-------|------|-------------|
| `fecha` | string | Fecha del tiquete |
| `numero_tiquete` | string | Número del tiquete de báscula |
| `finca` | string | Finca de origen |
| `kilos` | string | Kilos registrados en báscula |
| `telefono` | string | Número WhatsApp |
| `nombre` | string | Nombre perfil WhatsApp |
---
### 15. ⚠️ Registrar ausentismo
```
POST {url_base}/ausentismos
```
**Body JSON:**
```json
{
"fecha": "2026-06-30",
"empleado": "Carlos Ramírez",
"motivo": "Incapacidad médica",
"dias": "3",
"telefono": "573168950803",
"nombre": "Juan Pérez"
}
```
| Campo | Tipo | Descripción |
|-------|------|-------------|
| `fecha` | string | Fecha de inicio del ausentismo |
| `empleado` | string | Nombre del empleado ausente |
| `motivo` | string | Motivo del ausentismo |
| `dias` | string | Días de ausentismo |
| `telefono` | string | Número WhatsApp |
| `nombre` | string | Nombre perfil WhatsApp |
---
### 16. ⚠️ Registrar pluviometría
Este endpoint es diferente: el bot pregunta el valor por cada finca (usando la lista de `/fincas`) y envía **un array** con todas las lecturas en una sola llamada.
```
POST {url_base}/pluviometria
```
**Body JSON:**
```json
{
"fecha": "2026-06-30",
"telefono": "573168950803",
"nombre": "Juan Pérez",
"lecturas": [
{ "id": "finca_001", "label": "Finca La Palma", "valor": "45" },
{ "id": "finca_002", "label": "Finca El Diamante", "valor": "38" },
{ "id": "finca_003", "label": "Finca Los Almendros", "valor": "52" }
]
}
```
| Campo | Tipo | Descripción |
|-------|------|-------------|
| `fecha` | string | Fecha de la medición |
| `telefono` | string | Número WhatsApp |
| `nombre` | string | Nombre perfil WhatsApp |
| `lecturas[].id` | string | ID de la finca (viene de `/fincas`) |
| `lecturas[].label` | string | Nombre de la finca |
| `lecturas[].valor` | string | Milímetros registrados (texto libre del usuario) |
---
## Formato de respuesta para archivos (endpoints GET)
El bot espera recibir el archivo directamente en la respuesta HTTP. Formatos soportados:
| Content-Type | Extensión | Notas |
|---|---|---|
| `application/pdf` | `.pdf` | Preferido para informes |
| `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` | `.xlsx` | Excel moderno |
| `application/vnd.ms-excel` | `.xls` | Excel legacy |
**Headers recomendados en la respuesta:**
```
Content-Type: application/pdf
Content-Disposition: attachment; filename="reporte_cosecha_2026-06-30.pdf"
Content-Length: {tamaño en bytes}
```
> Si el archivo pesa más de **16 MB**, WhatsApp rechazará el envío. Para reportes grandes, considerar dividirlos por período o reducir el rango de fechas.
---
## Configuración en el bot
Una vez que el ERP tenga los endpoints listos, hay que actualizar las URLs en:
**Admin → Bot Config → Endpoints** (`https://admin.palmas360.com/admin/bot-config?id=2`)
Los `endpoint_key` que debe buscar y actualizar son:
| endpoint_key | URL actual (test) | URL real a colocar |
|---|---|---|
| `fincas_list_dn` | — | `{url_base}/fincas` |
| `cosecha_dn` | — | `{url_base}/ciclos/cosecha` |
| `ciclo_censo_dn` | — | `{url_base}/ciclos/sanidad/censo` |
| `ciclo_plagas_dn` | — | `{url_base}/ciclos/sanidad/plagas` |
| `ciclo_palm_dn` | — | `{url_base}/ciclos/sanidad/palm` |
| `ciclo_tratamiento_dn` | — | `{url_base}/ciclos/sanidad/tratamientos` |
| `ciclo_polinizacion_dn` | — | `{url_base}/ciclos/polinizacion` |
| `kilos_finca_dn` | — | `{url_base}/produccion/kilos-finca` |
| `produccion_lotes_dn` | — | `{url_base}/produccion/kilos-lotes` |
| `mantenimiento_dn` | — | `{url_base}/mantenimiento` |
| `ciclos_cosecha_up` | `https://httpbin.org/post` | `{url_base}/ciclos/cosecha` |
| `ciclos_sanidad_up` | `https://httpbin.org/post` | `{url_base}/ciclos/sanidad` |
| `ciclos_polinizacion_up` | `https://httpbin.org/post` | `{url_base}/ciclos/polinizacion` |
| `tiquetes_up` | `https://httpbin.org/post` | `{url_base}/tiquetes` |
| `ausentismos_up` | `https://httpbin.org/post` | `{url_base}/ausentismos` |
| `pluvio_upload` | `https://httpbin.org/post` | `{url_base}/pluviometria` |
---
## Preguntas frecuentes
**¿Los valores numéricos (kilos, días, racimos) vienen como número o texto?**
Vienen como `string` (texto libre que escribió el usuario). El ERP debe convertirlos al tipo necesario.
**¿El campo `fecha` está en formato ISO?**
El usuario la escribe libremente (puede ser "30/06/2026", "hoy", "30 de junio"...). Se recomienda que el ERP acepte texto y aplique parsing, o el bot puede configurarse para validar el formato antes de enviar (a coordinar).
**¿Qué pasa si el ERP responde un error?**
Si el ERP devuelve HTTP 4xx o 5xx, el bot muestra al usuario: *"Hubo un error al enviar los datos. Intenta nuevamente."*
**¿Cómo se prueba antes de tener el ERP listo?**
Los endpoints de upload actualmente apuntan a `https://httpbin.org/post`, que devuelve el body recibido. Sirve para confirmar que el bot está enviando los datos correctamente.
**¿Con qué frecuencia llaman los informes?**
Solo cuando el usuario lo solicita manualmente vía WhatsApp. No hay llamadas automáticas o en segundo plano.