For the complete documentation index, see llms.txt. This page is also available as Markdown.

FleetOS Pre-Production Build — March 26, 2026

Overview

Production-ready build for FleetOS (fleetos.us) — a B2B fleet-supplier coordination platform. This document covers all changes made during the pre-production sprint.


Status Flow (Corrected)

The service request lifecycle now follows the correct business flow:

Fleet requests     → pending        Supplier sees: ACTION NEEDED
Supplier responds  → acknowledged   Fleet sees: QUOTED (Review Quote)
Fleet approves     → accepted       Supplier sees: ACCEPTED (Start Work)
Supplier starts    → in_progress    Both see: IN PROGRESS
Supplier completes → completed      Both see: COMPLETED

Alternate paths:

  • Supplier declines with note → declined

  • Fleet declines quote → declined

  • Supplier adds own job → enters flow at pending

Key fix: Previously "Accept" jumped straight to in_progress, skipping fleet approval. Now the supplier "Responds" (with optional quote), fleet reviews and approves, then supplier starts work.


Dashboard UX Changes

Header Layout (Both Views)

  • Logo + action buttons on top row (inline)

  • Title + company name on second row (same baseline)

  • Share button removed (redundant with Contact)

  • Date moved to audit trail header

Tabs

  • Supplier: JOBS (6) | FLEET CLIENTS (6)

  • Fleet: WORK ORDERS (6) | MY SUPPLIERS (3)

KPI Cards (4 metrics, computed from filtered/visible jobs)

Supplier:

Needs Reply

Quoted

In Progress

Revenue

Fleet:

Awaiting Reply

Review Quote

In Progress

Spend

KPIs update when any dropdown filter changes (status, urgency, date, assignment).

Filter Dropdowns (Single row, no redundant pills)

  • Status dropdown: All / Needs Reply / Quoted / In Progress / Completed / Declined

  • Urgency dropdown: All / Urgent / Today / Scheduled

  • Each dropdown owns one dimension — no overlap

Job Cards

  • QUOTE and INVOICE labels aligned left with other fields (FLEET, VEHICLE, TECH, etc.)

  • WO number (WO-XXXXX) shown next to "AUDIT TRAIL" header in light grey monospace

  • Date shown on right side of audit trail header

  • Cards do not jump when status changes — sorted by urgency + creation date only

  • 3 secondary buttons: Contact | Assign | Collapse (Print Report for completed)

Urgency Colors

  • URGENT: Red #ef4444

  • TODAY: Yellow #eab308

  • SCHEDULED: Green #22c55e


Supplier Respond Panel

  • No enforcement on technician or bay at respond stage

  • Quote is optional (tech may need to inspect vehicle first)

  • Note field wired to separate respondNote state (not shared with completion note)

  • "Respond" button (not "Accept" or "Send Quote")


Mark Complete Panel

  • All fields optional — only Complete Job button required

  • Invoice attachment positioned next to cost field (not below photo)

  • Photo uses object-fit: contain (no random cropping), click to view fullscreen modal

  • Signature optional


Success Feedback Popup

All status-change actions (respond, approve, start, complete, decline) trigger a centered modal overlay:

  • Green tick (or red X for decline)

  • Confirmation message

  • Auto-dismisses after 4 seconds or tap anywhere

  • Replaces the old inline banner


Contact Cards (Fleet Clients / My Suppliers)

  • Contact person name shown under company name

  • WhatsApp chip (green icon, clickable → opens wa.me)

  • Email chip (clickable → opens mailto)

  • 4-column stats grid: Work Orders | Vehicles | Revenue | Last Active

  • Button label: "+ ADD CLIENT" (not "+ ADD FLEET")


Production Security Fixes

Email (Resend)

  • FROM_EMAIL env var required — no sandbox fallback

  • Email validation before API call

  • Error responses return HTTP 502 (not 200)

WhatsApp (Twilio)

  • TWILIO_WHATSAPP_FROM env var required — no sandbox number fallback

  • E.164 phone normalization (auto-prepends +, strips formatting)

  • Descriptive error messages for invalid numbers

  • DJBX33A hash replaced with SipHash-inspired keyed mixer (128-bit signature)

  • VITE_MAGIC_LINK_SECRET logs CRITICAL error if missing in production

  • Token format: base64(payload).128bit_hex_signature

WhatsApp Service

  • Broken settings table lookup replaced with contacts table queries

  • BIBLE-compliant: queries by company_id, prefers primary contact, falls back to most recent

CORS

  • Added http://localhost:3001 to both edge functions


Required Env Vars for Production

Supabase Secrets

Vercel / .env


Test Suite

File: tests/fleetos/07-preproduction.spec.ts

Category
Tests
What's Covered

1. Business Logic

9

KPIs, roles, status flow, quoted state, urgency colors

2. Data Flow

6

Signup, routing, WO numbers, quote/invoice labels

3. Email/WhatsApp/Links

4

Security, wa.me format, token encoding

4. Forms & Data

8

Signup fields, respond panel, contact cards, enriched data

5. UI Labels

10

Header, tabs, buttons, footer, dropdowns, audit trail

6. Code Review

6

Console errors, JS exceptions, viewport, success popup

7. TypeScript & Build

4

tsc, vite build, deps, localhost

Total

47

Run: npx playwright test tests/fleetos/07-preproduction.spec.ts --project=chromium


Files Modified

File
Changes

components/fleetos/pages/UnifiedDashboard.tsx

Header layout, tabs, filters, success popup

components/fleetos/components/JobCard.tsx

Respond/complete panels, buttons, WO ref, quote/invoice layout

components/fleetos/components/ContactCard.tsx

Enriched cards with contact person, email, stats grid

components/fleetos/components/PhotoCapture.tsx

object-fit contain, click-to-enlarge modal

components/fleetos/components/dashboard/TimelineView.tsx

WO ref, date positioning

components/fleetos/types/dashboard.ts

QUOTED status, sort by urgency only, SCHEDULED green

hooks/useFleetOSDashboard.ts

handleAccept→quoted, handleApproveQuote, KPIs from filtered, respondNote

services/shared/MagicLinkService.ts

Keyed hash signature, secret enforcement

services/shared/QueryService.ts

acceptQuote method

services/WhatsAppService.ts

contacts table lookup (replaces broken settings table)

supabase/functions/send-email/index.ts

FROM_EMAIL required, email validation, 502 errors

supabase/functions/send-whatsapp/index.ts

FROM required, E.164 normalization

.gitignore

Added screenshots, .claude

Last updated

Was this helpful?