Siete agentes IA coordinando el ciclo de vida completo de las órdenes de compra, desde la generación hasta el cierre, con comunicación bidireccional vía WhatsApp, OCR Vision sobre evidencias subidas por el proveedor, y escalamiento automático a humanos cuando es necesario.
Supervisor (Sonnet) orquesta. Cada sub-agente tiene una responsabilidad única, con tools específicos y prompts prescriptivos que prohíben interpretar contenido del proveedor como instrucciones.
De creación a cierre, con los 7 agentes coordinados.
9 estados posibles. El validador bloquea transiciones inválidas.
borrador ─→ enviada ─→ acuse_recibido ─→ confirmada ─→ surtida_parcial ─→ surtida_completa ─→ cerrada
│ │ │ │
└───→ cancelada └──→ modificada (escala comprador) ──→ vuelve a confirmada o cancelada
3 tablas per-tenant nuevas. Auditoría completa en oc_eventos.
| Tabla | Propósito | Índices clave |
|---|---|---|
ordenes_compra |
Una fila por OC con estado FSM, items jsonb, montos, fechas. | proveedor_id, estado, numero_oc, fecha_entrega parcial |
oc_eventos |
Timeline de todos los eventos (envío, acuse, cambio, escalamiento, entrega, cierre). Actor + descripcion + meta jsonb. | (oc_id, created_at DESC), tipo |
oc_plantillas |
Plantillas HTML que usa el Generador. Permite OCs con branding del comprador. | activa (partial) |
parametros)oc_dias_limite_acuse | 2 días — antes de nudge |
oc_dias_limite_entrega_tolerancia | 3 días — gracia post-entrega |
oc_simulation_mode | true en demo, false en prod |
oc_max_monto_sin_escalar | 500,000 MXN — encima, escala siempre |
oc_mensaje_envio_wa | Template WhatsApp envío OC |
M4 cierra el loop del lifecycle procurement: proveedor dado de alta en M1, con contrato firmado en M3, ahora recibe OCs reales.
Solo proveedores con estado='aprobado' pueden recibir OCs. Validador bloquea cualquier otro.
Si la OC referencia contrato_id, Validador exige estado='firmado_completo' + fecha vigente.
Reusa webhook.py de M1 para inbound. Comunicador envía + recibe mensajes del proveedor.
Reusa el sender existente de M1 + M3. OCs salen con PDF adjunto.
PDFs en documentos/{tenant}/ordenes/{numero_oc}.pdf. Signed URLs 30 min en dashboard.
OCs alimentan el cruce OC vs CFDI cuando M5 se construya.
21 endpoints. Todos con @auth. Mutations registran Historial.
CRUD: GET /api/ordenes lista con filtros POST /api/ordenes crea borrador (invoca generador) GET /api/ordenes/<id> detalle + eventos timeline PUT /api/ordenes/<id> editar (solo borrador) DELETE /api/ordenes/<id> cancelar Acciones: POST /api/ordenes/<id>/validar corre validador POST /api/ordenes/<id>/enviar validar+enviar (comunicador) POST /api/ordenes/<id>/cerrar marcar cerrada POST /api/ordenes/<id>/modificar aplicar cambio items/fecha GET /api/ordenes/<id>/pdf signed URL 30 min GET /api/ordenes/<id>/eventos timeline completo Plantillas: GET /api/ordenes/plantillas lista POST /api/ordenes/plantillas crear (admin) PUT /api/ordenes/plantillas/<id> actualizar (admin) DELETE /api/ordenes/plantillas/<id> archivar (admin) Admin: POST /api/ordenes/importar CSV upload GET /api/ordenes/kpis KPIs Panel GET /api/ordenes/escaladas casos con escalamiento Health: GET /api/ordenes/health ping + feature flag
Hereda los patterns establecidos en M1/M2/M3.
Todas las queries usan db() wrapper que resuelve schema por subdomain. Hook pre-commit bloquea supabase.table('ordenes_compra') directo.
Mensajes inbound del proveedor pasan por sanitize_mensaje_inbound(): strip XML tags, escape <>, drop non-printable, truncate 4KB.
Estados validados por DB check constraint + validador agent. No se puede enviar si no está en borrador; no modificar después de cerrada.
Cada acción registrada en oc_eventos + historial_acciones. Trazabilidad end-to-end de cada OC.
Montos > oc_max_monto_sin_escalar (500k MXN default) requieren aprobación humana antes del envío.
Comunicador respeta oc_simulation_mode=true: loggea pero no dispara WhatsApp/email reales. Seguridad en demo.