Localizacao em Tempo Real
PUT /api/v1/locations/me
Motorista atualiza sua posicao GPS. Deve ser chamado periodicamente durante a entrega.
Auth: Bearer token — role driver
Rate limit: maximo 1 requisicao a cada 10 segundos por motorista.
Request body
| Campo | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
lat |
float | sim | Latitude atual |
lng |
float | sim | Longitude atual |
heading |
float | nao | Direcao em graus (0-360) |
speed_kmh |
float | nao | Velocidade em km/h |
Response 200 OK
{
"driver_id": "550e8400-e29b-41d4-a716-446655440001",
"lat": -16.6869,
"lng": -49.2648,
"heading": 180.0,
"speed_kmh": 35.5,
"updated_at": "2026-05-19T14:30:00Z"
}
import requests
import time
BASE_URL = "https://fast-deliv-backend.vercel.app"
headers = {"Authorization": f"Bearer {TOKEN}"}
def update_location(lat: float, lng: float, heading: float = None):
payload = {"lat": lat, "lng": lng}
if heading is not None:
payload["heading"] = heading
resp = requests.put(
f"{BASE_URL}/api/v1/locations/me",
headers=headers,
json=payload,
)
resp.raise_for_status()
return resp.json()
# Loop de atualizacao (respeita o rate limit de 10s)
while True:
loc = update_location(-16.6869, -49.2648, heading=90.0)
print(f"Posicao atualizada: {loc['updated_at']}")
time.sleep(10)
async function updateLocation(lat, lng, heading = null) {
const body = { lat, lng };
if (heading !== null) body.heading = heading;
const resp = await fetch(`${BASE_URL}/api/v1/locations/me`, {
method: "PUT",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify(body),
});
return resp.json();
}
// Usando Geolocation API do browser
function startTracking() {
setInterval(() => {
navigator.geolocation.getCurrentPosition(async (pos) => {
const loc = await updateLocation(
pos.coords.latitude,
pos.coords.longitude,
pos.coords.heading
);
console.log("Posicao atualizada:", loc.updated_at);
});
}, 10000); // a cada 10s
}
def update_location(token, lat, lng, heading: nil)
uri = URI("#{BASE_URL}/api/v1/locations/me")
req = Net::HTTP::Put.new(uri)
req['Authorization'] = "Bearer #{token}"
req['Content-Type'] = 'application/json'
payload = { lat: lat, lng: lng }
payload[:heading] = heading if heading
req.body = JSON.dump(payload)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
JSON.parse(http.request(req).body)
end
GET /api/v1/locations
Lista a ultima localizacao conhecida de todos os motoristas ativos.
Auth: Bearer token — role admin
Response 200 OK
Array de objetos de localizacao:
| Campo | Tipo | Descricao |
|---|---|---|
driver_id |
UUID | ID do motorista |
driver_name |
string | Nome do motorista |
lat |
float | Ultima latitude conhecida |
lng |
float | Ultima longitude conhecida |
heading |
float ou null | Direcao em graus |
speed_kmh |
float ou null | Velocidade |
updated_at |
datetime | Horario da ultima atualizacao |
const resp = await fetch(`${BASE_URL}/api/v1/locations`, { headers });
const locations = await resp.json();
locations.forEach((loc) => {
const ageMs = Date.now() - new Date(loc.updated_at).getTime();
const ageMin = Math.floor(ageMs / 60000);
console.log(`${loc.driver_name}: ${loc.lat},${loc.lng} (ha ${ageMin} min)`);
});
uri = URI("#{BASE_URL}/api/v1/locations")
req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Bearer #{TOKEN}"
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
locations = JSON.parse(http.request(req).body)
locations.each do |loc|
puts "#{loc['driver_name']}: #{loc['lat']},#{loc['lng']}"
end
Rastreamento em tempo real via Supabase Realtime
Para receber atualizacoes de posicao em tempo real sem polling, use Supabase Realtime com o canal driver_locations.
Supabase Realtime
Este canal usa o mecanismo de Broadcast do Supabase. Voce precisa da URL e da anon key do Supabase (nao do backend fast_deliv).
import { createClient } from "@supabase/supabase-js";
const supabase = createClient(
"https://<PROJECT>.supabase.co",
"<ANON_KEY>"
);
// Ouvir atualizacoes de todos os motoristas
const channel = supabase
.channel("driver_locations")
.on(
"postgres_changes",
{
event: "UPDATE",
schema: "public",
table: "driver_locations",
},
(payload) => {
const { driver_id, lat, lng, heading, updated_at } = payload.new;
console.log(`Motorista ${driver_id}: ${lat}, ${lng}`);
// Atualize o marcador no mapa aqui
}
)
.subscribe();
// Para parar de ouvir
// await supabase.removeChannel(channel);