Visão Geral da Arquitetura
Diagrama completo da arquitetura do fast_deliv e descrição dos fluxos principais.
Diagrama de Arquitetura
┌─────────────────────────────────────────────────────────────────────────┐
│ FAST_DELIV │
│ │
│ ┌─────────────────────────────┐ ┌──────────────────────────────────┐ │
│ │ FRONTEND │ │ BACKEND │ │
│ │ Next.js 16 (App Router) │ │ FastAPI + Python 3.12 │ │
│ │ TypeScript strict │ │ Pydantic v2 + uv │ │
│ │ Tailwind v4 + MapLibre │ │ Vercel Serverless │ │
│ │ PWA + Service Worker │ │ │ │
│ │ │ │ app/ │ │
│ │ app/ │ │ main.py (CORS + router) │ │
│ │ (admin)/ │ │ core/ │ │
│ │ deliveries/ ──────────────→ config.py (Settings) │ │
│ │ map/ (REST API) │ │ security.py (JWT) │ │
│ │ (driver)/ │ │ supabase.py (singleton) │ │
│ │ deliveries/ │ │ api/v1/ │ │
│ │ wallet/ │ │ deliveries.py │ │
│ │ (auth)/login │ │ wallets.py │ │
│ │ │ │ locations.py │ │
│ │ lib/supabase/ │ │ pricing.py │ │
│ │ client.ts (browser) │ │ drivers.py │ │
│ │ server.ts (RSC) │ │ webhooks.py │ │
│ │ middleware.ts │ │ services/ │ │
│ │ │ │ asaas.py │ │
│ │ types/index.ts │ │ pricing.py │ │
│ │ (Delivery, Profile, etc.) │ │ routing.py │ │
│ └──────────┬───────────────────┘ └──────────────┬───────────────────┘ │
│ │ │ │
└─────────────│───────────────────────────────────────│──────────────────────┘
│ │
│ Supabase JS SDK │ supabase-py
│ (anon key, RLS enforced) │ (service_role, full access)
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ SUPABASE │
│ │
│ PostgreSQL (RLS em todas as tabelas) │
│ ┌────────────────┐ ┌──────────────┐ ┌───────────────────────────┐ │
│ │ profiles │ │ deliveries │ │ driver_locations │ │
│ │ wallets │ │ transactions│ │ push_subscriptions │ │
│ │ withdrawals │ │pricing_config│ │ │ │
│ └────────────────┘ └──────────────┘ └───────────────────────────┘ │
│ │
│ Auth (JWT HS256) → tokens validados pelo backend │
│ Realtime (WebSocket) → driver_locations, deliveries, wallets │
│ Storage (avatares — planejado) │
└────────────────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌────────────────┐ ┌────────────────┐
│ ASAAS │ │OpenRouteService│ │ Stadia Maps │
│Pagamentos│ │ Roteamento │ │ Tiles do mapa │
│ + Pix │ │ (2000 req/dia)│ │ (gratuito) │
└──────────┘ └────────────────┘ └────────────────┘
Fluxo 1: Criação de Entrega (Admin)
Admin Frontend Backend Serviços Externos
│ │ │ │
│── preenche form ────────>│ │ │
│ │── POST /deliveries ─>│ │
│ │ (JWT admin token) │ │
│ │ │── POST /directions ──>│ ORS
│ │ │<── distance_km, poly ─│
│ │ │ │
│ │ │── compute_earning() ──┘
│ │ │ (DB: pricing_config)
│ │ │
│ │ │── INSERT deliveries ──>│ Supabase
│ │<── 201 DeliveryOut ──│<─────────────────────│
│<── entrega criada ───────│ │ │
│ │ │ │
Fluxo 2: Driver Aceita e Executa Entrega
Driver App Frontend Backend Supabase
│ │ │ │
│── lista pending ─────>│── GET /deliveries ──>│── SELECT pending ───>│
│<── lista de entregas ─│<── [DeliveryOut] ────│<─────────────────────│
│ │ │ │
│── aceita entrega ────>│── PATCH .../assign ─>│── valida transição ─>│
│ │ │ pending→assigned │
│ │ │── UPDATE status ────>│
│<── confirmado ────────│<── DeliveryOut ──────│<─────────────────────│
│ │ │ │
│── (vai buscar) │ │ │
│── atualiza GPS ──────>│── PUT /locations/me ─>│── UPSERT location ──>│
│ │ (a cada 10s) │ │
│ │ │ │
│── coletou ───────────>│── PATCH .../start ──>│── assigned→in_progress│
│ │ │── UPDATE started_at ─>│
│ │ │ │
│── entregou ──────────>│── PATCH .../complete ─>│── in_progress→completed│
│ │ │── INSERT transaction ─>│
│ │ │── RPC increment_wallet >│
│<── saldo atualizado ──│<── DeliveryOut ──────│<─────────────────────│
Fluxo 3: Saque via Pix (Driver)
Driver Frontend Backend ASAAS
│ │ │ │
│── solicita saque ──────>│── POST /withdraw ───>│ │
│ (amount, pix_key) │ │── checa saldo ──>│ Supabase
│ │ │ │
│ │ │── INSERT withdrawal ─>│ Supabase
│ │ │ │
│ │ │── POST /transfers ──>│
│ │ │ (pix_transfer) │
│ │ │<── {id: "tra_..."} ─│
│ │ │ │
│ │ │── UPDATE asaas_id ──>│ Supabase
│<── withdrawal criado ───│<── WithdrawalOut ────│ │
│ status: processing │ │ │
│ │ │ │
│ (minutos depois) │ │ │
│ │ │<── POST webhook ────│ ASAAS
│ │ │ TRANSFER_DONE │
│ │ │── valida HMAC ─────┘
│ │ │── UPDATE status ────>│ Supabase
│<── status: completed ───│ (Realtime update) │ completed │
Fluxo 4: Rastreamento GPS em Tempo Real (Admin)
Admin Map Frontend Supabase Realtime
│ │ │
│── abre mapa ──────────>│── subscribe() ─────────>│
│ │ driver_locations │
│ │ channel │
│ │ │
Driver App Backend Supabase
│── PUT /locations/me ──>│── UPSERT row ──────────>│
│ (a cada 10s) │ driver_locations │
│ │ │── Broadcast change
│ │ │──────────────────────>│
│ │ │ │ Admin Frontend
│ │ │ │ recebe update
│ │ │ │── atualiza marker
Autenticação e Autorização
Browser/App Supabase Auth Backend FastAPI
│ │ │
│── POST /auth/v1/token ──────>│ │
│ (email + password) │ │
│<── {access_token: JWT} ──────│ │
│ │ │
│── POST /api/v1/deliveries ──────────────────────────────>│
│ Authorization: Bearer JWT │
│ │── decode_token(JWT)
│ │ verifica HS256
│ │ verifica audience
│ │── extrai user_metadata.role
│ │── RequireAdmin/RequireDriver
│<─────────────────────────────────────────────────────────│
O JWT é assinado pelo Supabase com HS256 usando SUPABASE_JWT_SECRET. O backend valida localmente sem chamada de rede adicional.
Separação de Responsabilidades
| Responsabilidade | Onde Vive | Por quê |
|---|---|---|
| Auth de usuários | Supabase Auth | Gerenciamento de sessão, refresh tokens |
| Autorização (role) | Backend (JWT claims) | Central, sem depender de tabela |
| Cálculo de rota | Backend → ORS | Chave ORS não exposta ao browser |
| Cálculo de ganhos | Backend | Regra de negócio crítica |
| RLS (segurança de dados) | Supabase | Défault-deny por tabela |
| Realtime GPS | Frontend → Supabase | WebSocket direto, sem passar pelo backend |
| Pagamentos | Backend → ASAAS | Chave API nunca no browser |
| Push Notifications | Backend → Web Push | Chave VAPID privada nunca no browser |