CruciDrive’s Socket.io server handles 4 client-emitted events and dispatches 3 server-emitted events across two functional modules: geolocation and chat. All events require a valid authenticated connection — see the WS Overview for the handshake and authentication flow. Events emitted before authentication completes are silently dropped by the middleware.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/DavidCevallos15/Crucidrive---APP/llms.txt
Use this file to discover all available pages before exploring further.
Geolocation events
join_sector — client → server
Subscribes the authenticated client to a sector room so they receive location_updated broadcasts whenever a driver in that area moves. Call this as soon as the map screen mounts, and re-call it after any reconnect.
Access: any authenticated user (passenger or driver).
Identifier of the geographic sector to subscribe to. Must be one of:
centro, playa, las_gilces, los_arenales, san_jacinto.
The server calls socket.join('sector:${sectorId}') on receipt.update_location — client → server
Broadcasts the driver’s current GPS coordinates to every passenger subscribed to the same sector room. The server simultaneously persists the new position to the tricimotos table so the database always reflects the last known location.
Access: conductor role only. If a user with rol: 'pasajero' emits this event, the server responds with error_message: 'Acción denegada. Solo los conductores pueden actualizar geolocalización.' and takes no further action.
The sector room to broadcast the update into, e.g.
playa. Must match the
sector the driver is currently operating in.Current GPS position of the driver’s tricimoto.
Operational status of the tricimoto. One of
disponible, ocupado, or
inactivo. Written to tricimotos.estado alongside the position update.
Defaults to disponible if omitted.- Writes
ubicacion_actual(PostGIS WKT point),estado, andupdated_attopublic.tricimotoswhereconductor_id = socket.user.id. - Broadcasts
location_updatedto the sector room excluding the sender (socket.to(room).emit(...)).
location_updated — server → client
Delivered to all clients subscribed to a sector room (excluding the emitting driver) each time a driver sends a position update. Passengers use this event to move the driver pin on the map in real time.
UUID of the driver whose position changed. Matches
tricimotos.conductor_id.Display name of the driver from
public.perfiles, e.g. "Carlos Vera".Updated GPS coordinates of the driver.
Current operational status of the driver’s tricimoto:
disponible,
ocupado, or inactivo.Chat events
join_chat — client → server
Joins the private Socket.io room for a specific ride chat thread. Call this after loading message history via GET /api/chats/:threadId/mensajes so new messages arrive in real time without polling.
Access: authenticated users who are registered members of the thread. Membership is validated server-side via checkThreadMembership(threadId, socket.user.id) — the same thread_members query used by the REST endpoint.
UUID of the chat thread. Returned by the
aceptarViaje response when a
ride is accepted. The server calls socket.join('chat:${threadId}') after
the membership check passes.error_message with the value "No tienes permiso para ingresar a este chat." and does not add the socket to the room.
send_message — client → server
Sends a message to the active chat room. The server inserts the message into the messages table and then broadcasts it to all members of the room — including the sender — so both sides of the conversation receive a single authoritative event with the final persisted payload.
UUID of the target chat thread. The sender must have already joined this room
via
join_chat.Plain-text message body. Whitespace is trimmed before storage and before the
empty-string check — a message containing only spaces is rejected.
- Inserts a row into
public.messageswiththread_id,sender_id(fromsocket.user.id), and trimmedcontent. - Selects the newly inserted row with a
perfilesjoin and emitsmessage_receivedtoio.to('chat:{threadId}')— all room members, including the sender.
message_received — server → client
Delivered to every member of a chat room when any participant sends a message via send_message. This is the single source of truth for rendering new messages — do not optimistically append the message locally before this event fires, as the payload contains the final database-assigned id and created_at.
UUID of the newly inserted message row.
UUID of the chat thread this message belongs to.
UUID of the user who sent the message.
Trimmed message text as stored in the database.
ISO 8601 timestamp assigned by the database at insert time.
Sender profile resolved via the
sender_id foreign key join.Error handling
Theerror_message server event is sent exclusively to the offending client (not broadcast to the room) in the following situations:
| Trigger | Error string |
|---|---|
A pasajero emits update_location | "Acción denegada. Solo los conductores pueden actualizar geolocalización." |
update_location is missing coords, lat, lng, or sectorId | "Parámetros de ubicación incompletos." |
join_chat — user is not in thread_members | "No tienes permiso para ingresar a este chat." |
send_message — content is empty or whitespace-only | "Contenido del mensaje vacío o threadId faltante." |
send_message — Supabase insert fails | "No se pudo guardar el mensaje." |
TypeScript integration example
TheuseSocket hook exposes typed wrappers around all four client events. The example below joins a sector on mount, listens for driver updates, and cleans up the listener on unmount:
joinChat and sendMessage with the message_received listener after loading history from the REST endpoint: