2026-07-03 — Chat por salas y soporte por orden
Para front-end, mobile e integradores de
/api/v1.
Summary
El chat se reorganiza en torno a salas (chat rooms). Cada sala pertenece a una orden y
tiene un type: ORDER_CLIENT_DRIVER (cliente ↔ conductor) o ORDER_ADMIN_SUPPORT
(conductor ↔ soporte). El flujo antiguo /chat/{orderId} deja de existir: ahora se
resuelve la sala una vez y luego se lee y escribe por roomId. Además se estrena el chat
de soporte por orden, con bandeja y modelo de claim para el panel admin.
Breaking changes
GET/POST /chat/{orderId} se eliminan
El chat cliente ↔ conductor ya no se accede por orden directa. Primero conviene resolver
la sala y luego operar por roomId.
- Afecta:
GET /chat/{orderId}yPOST /chat/{orderId}(cliente/conductor). Ambos removidos. - Migración: llamar
POST /orders/{orderId}/chat-roomscon{"type": "ORDER_CLIENT_DRIVER"}para obtenerid,channely los últimos mensajes; luego usarGET/POST /chat-rooms/{roomId}/messages. El envío exigecontentde 1–500 caracteres.
El canal en tiempo real del chat cambia a chat.rooms.{id}
El evento chat.message ya no viaja por orders.{id}.client / orders.{id}.driver, sino
por el canal dedicado de la sala.
- Afecta: suscriptores del evento
chat.message. - Migración: suscribirse al
channelque devuelven las respuestas de resolver/listar la sala (chat.rooms.{id}), en vez de construir el nombre desde elorderId.
New
Chat cliente ↔ conductor por salas
| Método | Endpoint | Rol | Para qué sirve |
|---|---|---|---|
| POST | /orders/{orderId}/chat-rooms |
cliente/conductor | Resuelve (crea si hace falta) la sala de un type; devuelve id, channel y mensajes |
| GET | /chat-rooms/{roomId}/messages |
miembro | Últimos 50 mensajes de la sala |
| POST | /chat-rooms/{roomId}/messages |
miembro | Envía un mensaje (content 1–500) |
| POST | /chat-rooms/{roomId}/read |
miembro | Marca la sala como leída |
Cada mensaje incluye sender_role (CLIENT, DRIVER o ADMIN). La sala cliente ↔
conductor se abre con la orden pagada (CONFIRMED hasta DELIVERED).
Soporte por orden (conductor ↔ admin)
El conductor abre la sala de soporte con POST /orders/{orderId}/chat-rooms y
{"type": "ORDER_ADMIN_SUPPORT"}, disponible mientras la orden está activa. Del lado del
panel, el soporte es global (sin scoping por ciudad) y usa un modelo de claim.
| Método | Endpoint | Rol | Para qué sirve |
|---|---|---|---|
| GET | /admin/order-support |
admin | Bandeja de soporte (bucket=pool o mine) |
| GET | /admin/chat-rooms/{roomId} |
admin | Lee una sala de soporte |
| POST | /admin/chat-rooms/{roomId}/claim |
admin | Reclama una sala del pool |
| POST | /admin/chat-rooms/{roomId}/messages |
admin | Responde (reclama si estaba en el pool) |
| POST | /admin/chat-rooms/{roomId}/release |
admin | Devuelve la sala al pool |
| POST | /admin/chat-rooms/{roomId}/read |
admin | Marca la sala como leída |
Los errores del lado admin usan { "error": "SupportError", "message": "…" }; los del
lado cliente/conductor, { "error": "ChatError", "message": "…" }.
WebSocket
| Evento | Canal | Rol |
|---|---|---|
order-support.queue |
admin.order-support |
admin |
chat.message |
chat.rooms.{id} |
cliente/conductor/admin |
order-support.queue avisa a todos los admins activos que una sala entró al pool, fue
reclamada o liberada, para refrescar la bandeja en vivo. Los mensajes en sí siguen yendo
por chat.rooms.{id} (solo miembros activos de la sala).