Frotamais — Fleet platform with D1, real auth, roles and live tracking
- 8
- Vehicles in demo
- 11
- Active modules
- 3
- Roles with permissions
Client
Frotamais
Sector
Fleet Management and Logistics
Timeline
6 dias de implementação · 2026-08
Live product
Use nowResults
Client-reported results during rollout
Baseline: D1 + KV + Durable Object
Baseline: illustrative data in D1
Baseline: functional dashboard with auth
Baseline: base for safety score
Baseline: Cloudflare edge
Baseline: Nearest Neighbor + 2-opt
Client-reported data
The challenge
The challenge
Frotamais is a fleet management SaaS platform demonstration evolved from static mock to an honest functional MVP. The landing page communicates product value while the logged-in area requires real authentication with roles and shows a dashboard with live map, VRP routing, D1 database KPIs, vehicle and driver detail pages, full CRUD, reports with dynamic charts, DVIR inspections, geofences and driver safety score calculated in real time.
Transportadoras e gestores de frota perdem visibilidade quando controlam tudo em planilhas desatualizadas. Falta uma visao unica de veiculos, motoristas, rotas, manutencao, combustivel, inspecoes e geofences para decidir com agilidade.
The approach
The approach
We implemented Astro with SSR, Hono for REST API with full CRUD (POST/PUT/DELETE), Cloudflare D1 with Drizzle ORM for real persistence, Better Auth for authentication with roles (admin, manager, driver) and granular permissions, Durable Objects with SSE for real-time tracking, VRP algorithm (Nearest Neighbor + 2-opt with haversine distance) for routing, Leaflet for maps with geofences, safety score calculated from telemetry events, vehicle and driver detail pages, reports with dynamic charts (bar and donut in pure SVG) and CSV export, DVIR inspections and in-app notification bell.
The solution
The solution
- Landing page with photographic hero and CTA to access the demo
- Real authentication with Better Auth (email/password) and KV session
- Roles and permissions system (admin, manager, driver) with access middleware
- Cloudflare D1 database with Drizzle ORM and migrations applied in production
- Dashboard with D1-sourced KPIs, Leaflet map and dynamic consumption chart
- Vehicle detail page with history, map, financials, trips, maintenance and inspections
- Driver detail page with detailed score, telemetry events and trips
- Full CRUD in the UI: add and remove vehicles and drivers with form modal
- Filters and search on vehicles, drivers and alerts
- Real VRP routing with Nearest Neighbor + 2-opt and haversine distance
- Real-time tracking via SSE with Durable Object (telemetry simulation)
- Safety score calculated in real time from telemetry events
- DVIR inspections (pre/post trip checklist) with approval and defects
- Geofences with control areas visualized on Leaflet map
- Reports with dynamic charts (bar and donut in pure SVG) from D1
- CSV export for fuel, maintenance and trips
- In-app notification bell with pending alerts counter
- Auth middleware protecting /app/* routes with role-based redirect
- Modules: dashboard, vehicles, drivers, routes, maintenance, fuel, alerts, inspections, geofences, reports and users
- Hono API with full CRUD (GET/POST/PUT/DELETE) reading from D1
- Deploy on Cloudflare Workers with D1, KV and Durable Object bindings
- Accessible tables with th scope and status badges
- Clear disclaimers that no real fiscal documents are issued
Timeline
Como o projeto foi conduzido, do mapeamento ao deploy. How the project was conducted, from mapping to deploy.
1 dia
Discovery
- Research of fleet management benchmarks
- Analysis of Brazilian freight company operational flows
- Definition of modules and architecture
1 dia
Design
- Landing page with photographic hero
- Deep blue + orange CTA palette
- Dashboard sidebar and top bar
2 dias
Dev base
- Astro + Hono + Tailwind scaffold
- Brazilian illustrative data seed
- Landing page and dashboard modules
- Deploy on Cloudflare Workers
2 dias
Dev funcional
- Real D1 with Drizzle migrations
- Better Auth with session and middleware
- Durable Object + SSE for tracking
- VRP Nearest Neighbor + 2-opt
- Leaflet on dashboard
- Calculated safety score
2 dias
Evolucao MVP
- Roles and permissions system (admin, manager, driver)
- Vehicle and driver detail pages
- Full CRUD in the UI with modals
- DVIR inspections with pre/post trip checklist
- Geofences with map areas
- Reports with dynamic charts and CSV export
- In-app notification bell
- Filters and search on all modules
Methodology
Como o projeto foi conduzido, do mapeamento ao deploy. How the project was conducted, from mapping to deploy.
Benchmark research
Edge-first architecture
Mobile-first
Accessibility first
Honest content
Custom algorithms
Real-time at the edge
Continuous deploy
Architecture
- → Astro SSR with Cloudflare Workers adapter and custom worker entry point
- → Hono handling /api/* routes reading from D1 via Drizzle ORM
- → Cloudflare D1 with Drizzle migrations applied in production
- → Better Auth with factory function (D1 binding only exists in request context)
- → Astro middleware protecting /app/* routes with session verification
- → FleetTracker Durable Object with SSE for real-time tracking
- → Durable Object uses alarm() to simulate telemetry every 3 seconds
- → VRP algorithm (Nearest Neighbor + 2-opt) runs at the edge with haversine
- → Leaflet with client:only to avoid SSR issues with window
- → KV Namespace for auth session at the edge
- → Build and deploy via GitHub Actions with automatic D1 migrations
- → Subdomain frotamais.expostacker.com.br managed by Cloudflare
Conceptual diagram — does not reflect real implementation
Tech stack
Technical choices and what was left out.
systems
Why: Lightweight SSR and islands for selective interactivity.
Rejected alternative: Next.js
Why: SSR compatibility on Workers.
Rejected alternative: React 19
Why: Lightweight interactive map with markers and polylines.
Rejected alternative: MapLibre GL
Why: Design tokens and responsiveness.
Rejected alternative: Custom CSS
systems
Why: Small API compatible with Workers.
Rejected alternative: Express
Why: Real auth with session and Drizzle adapter.
Rejected alternative: Mocked auth
Why: Type-safe SQL queries on D1.
Rejected alternative: Raw SQL
systems
Why: Serverless SQLite database at the edge.
Rejected alternative: Supabase
Why: Shared state and SSE for realtime.
Rejected alternative: WebSocket service
Why: Auth session at the edge.
Rejected alternative: Redis
systems
Why: Lightweight VRP with haversine, works on Workers.
Rejected alternative: OR-Tools WASM
Why: Real calculation from telemetry events.
Rejected alternative: Mocked static score
systems
Why: Global edge, SSL and custom domain.
Rejected alternative: Vercel
Decision log
What I chose, what I rejected, and why.
Real D1 instead of in-memory data
Why: D1 with Drizzle ORM demonstrates real persistence capability, migrations and SQL queries at the edge. Shows serverless database mastery at no extra cost on Cloudflare plan.
Rejected alternatives: In-memory seed — rejected for not demonstrating real database capability.
Better Auth instead of mocked auth
Why: Better Auth with Drizzle adapter + D1 shows real authentication with session, secure cookies and middleware. Demonstrates security mastery for B2B prospects.
Rejected alternatives: Mocked auth without persistence — rejected for not demonstrating real auth capability.
Durable Objects + SSE instead of polling
Why: Durable Objects maintain shared state between connections and broadcast positions via SSE. Demonstrates real-time architecture at the edge without external service.
Rejected alternatives: Polling with setInterval — rejected for not being real-time and generating unnecessary load.
Custom VRP (Nearest Neighbor + 2-opt) instead of OR-Tools
Why: Custom Nearest Neighbor + 2-opt with haversine is lightweight, works on Workers and demonstrates algorithm mastery. OR-Tools WASM weighs 58MB and exceeds Workers limits.
Rejected alternatives: OR-Tools WASM — rejected for 58MB size exceeding Workers limit.
Leaflet instead of MapLibre GL
Why: Leaflet weighs 40KB gzipped vs 200KB for MapLibre GL. For markers and route polylines, Leaflet is sufficient and lighter. Uses client:only to avoid SSR issues.
Rejected alternatives: MapLibre GL — rejected for size and unnecessary complexity for the use case.
React 18 instead of React 19
Why: React 19 triggers a MessageChannel error in the Cloudflare Workers environment. React 18 is stable for SSR in this runtime.
Rejected alternatives: React 19 — rejected for incompatibility with Workers runtime.
Fixed roles instead of customizable RBAC
Why: Three fixed roles (admin, manager, driver) with code-defined permissions cover portfolio scenarios without adding RBAC CRUD complexity. Middleware checks role access and sidebar filters items automatically.
Rejected alternatives: Customizable RBAC with permission CRUD — rejected for excessive scope for a portfolio.
Pure SVG charts instead of Chart.js
Why: Bar and donut charts in pure SVG weigh less than 3KB vs 60KB+ for Chart.js. For portfolio charts, SVG is sufficient and keeps the bundle light.
Rejected alternatives: Chart.js — rejected for size and unnecessary complexity.
Security and access
Security and privacy
-
Real authentication with Better Auth (email/password)
-
Session persisted in KV with secure cookies
-
Roles system (admin, manager, driver) with granular permissions
-
Middleware protects /app/* routes with role-based redirect
-
Sidebar filters menu items based on user permissions
-
D1 database with persisted illustrative data
-
CRUD with server-side validation via Hono
-
SSL deployment via Cloudflare
-
No real fiscal documents are issued
-
Secrets managed via wrangler secret put
Lessons learned
Not everything went as planned.
— Evolving from mock to honest functional MVP was the right decision. Real D1, Better Auth, Durable Objects with SSE, custom VRP and Leaflet demonstrate deep technical capability without becoming a commercial product. Wrangler v4 changed Durable Objects configuration from exports to migrations. Better Auth requires a factory function because D1 bindings only exist in request context. Leaflet needs client:only in Astro because it accesses window on import.
See also other products
NutriX
Plataforma de saúde adaptativa em produção: nutrição calculada, treino ao vivo, coach de IA, análise por foto e portal de profissionais.
View case →
VulnStrike
Scanner de vulnerabilidades SaaS: digite um domínio e receba nota de segurança A+–F com achados explicados e correção passo a passo — scan grátis sem cadastro.
View case →
Medellin RP
Loja VIP do servidor Medellin RP onde o jogador escolhe itens, paga via Mercado Pago e recebe tudo automaticamente no jogo.
View case →Want a product like this?
I can do the same for your business. Let's talk.