GPS API
Machine-readable spec: openapi/gps.yaml (generated from the live FastAPI app — REST routes only; WebSocket routes are not representable in OpenAPI and are documented in prose below). Note: neither REST route declares a response_model, so the generated YAML's 200 response schema is empty ({}) — the JSON examples below are the only documented shape for these responses.
GPS endpoints stream and query user location data (router in server/app/api/gps.py, prefix /gps). All GPS endpoints require JWT Bearer auth (via token query param for WebSocket routes).
Endpoints at a glance
| Method | Path | Auth | Summary |
|---|---|---|---|
| WS | /gps/ws/{user_id} | token query param (JWT) | Stream live GPS coordinates from a user's device; server persists and fans out to monitoring rescuers. |
| WS | /gps/ws/monitor/rescuers/{rescuer_id} | token query param (JWT, rescuer role) | Live feed of every user's GPS updates, for rescuers. |
| GET | /gps/latest | JWT Bearer (rescuer role) | Most recent location for every user who has sent at least one ping. |
| GET | /gps/history/{user_id} | JWT Bearer (rescuer role) | Location history for a specific user, most recent first. |
WebSocket /gps/ws/{user_id}
Stream live GPS coordinates from a user's device to the server. The server persists each ping and fans out to all monitoring rescuers in real time.
Auth: token query parameter (JWT)
wss://<host>/gps/ws/<user_uuid>?token=<access_token>
Validation:
- The authenticated user must match
user_idin the path (closes with code 1008 otherwise). user_idmust correspond to an existing user (closes with code 4004 if not found).
Inbound message (client to server):
{ "lat": 14.0000, "lng": 120.0000 }
On each message the server:
- Creates a
UserLocationrecord in the database. - Broadcasts the location to all connected rescuers.
Broadcast payload (sent to rescuers):
{
"user_id": "<uuid>",
"latitude": 14.0000,
"longitude": 120.0000,
"timestamp": "2026-06-28T12:00:00+00:00",
"username": "jdoe",
"role": "user"
}
role is one of admin, rescuer, or user — the same vocabulary the chat
role badge uses. Map clients render rescuer markers distinctly from regular
users based on this field.
WebSocket /gps/ws/monitor/rescuers/{rescuer_id}
Open a live feed of all users' GPS updates. Rescuers only.
Auth: token query parameter (JWT)
wss://<host>/gps/ws/monitor/rescuers/<rescuer_uuid>?token=<access_token>
Validation:
- Authenticated user must match
rescuer_idin the path. - User must hold the
rescuerrole. - Both checks enforce code 1008 on failure.
Outbound messages: Each GPS ping from any user is forwarded to all monitoring rescuers (same payload as the broadcast above).
The connection stays open; the client does not need to send anything.
GET /gps/latest
Return the most recent location for every user who has sent at least one GPS ping. Used for the initial map load.
Auth: JWT Bearer (rescuer role required)
Response 200:
[
{
"user_id": "<uuid>",
"latitude": 14.0000,
"longitude": 120.0000,
"timestamp": "2026-06-28T12:00:00+00:00",
"username": "jdoe",
"role": "rescuer"
}
]
role is one of admin, rescuer, or user.
GET /gps/history/{user_id}
Return the location history for a specific user, most recent first.
Auth: JWT Bearer (rescuer role required)
Path params: user_id — UUID of the user
Query params: limit — integer, default 50
Response 200:
[
{
"id": "<uuid>",
"user_id": "<uuid>",
"latitude": 14.0000,
"longitude": 120.0000,
"timestamp": "2026-06-28T12:00:00+00:00"
}
]
Errors:
404— no location history found for this user