> For the complete documentation index, see [llms.txt](https://t420.gitbook.io/t420/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://t420.gitbook.io/t420/production_readiness.md).

# FleetOS Production Readiness Checklist

**Created:** 2026-04-02 **Last Updated:** 2026-04-02 **Status:** Code complete — infrastructure config remaining

***

## COMPLETED (code shipped)

* [x] **B1: Email verification on signup** — CleanLanding sends Supabase OTP instead of instant localStorage login
* [x] **B2: Backend session validation** — App.tsx validates Supabase auth session on load; clears stale sessions
* [x] **B3: RLS policies tightened** — Migration 021 replaces `USING(true)` with company/user-scoped policies
* [x] **B7: Column mismatches fixed** — Migration 020 adds missing columns; InviteService uses correct field names
* [x] **B8: Server-side token signing** — `sign-token` edge function with HMAC-SHA256 created
* [x] **H1: CAN-SPAM compliance** — Email footer has physical address + unsubscribe link
* [x] **H2: WhatsApp templates** — `manage-whatsapp-templates` edge function + ContentSid support in send-whatsapp
* [x] **H3: WhatsApp opt-in tracking** — Migration 022 adds consent field + notification\_preferences table
* [x] **H4: Sentry error tracking** — @sentry/react wired into index.tsx, errorLogger.ts, ErrorBoundary.tsx
* [x] **H5: Session expiry** — 7-day TTL on localStorage sessions; Supabase auth validated on load
* [x] **H6: Input validation** — Required fields, enums, email format, length limits in QueryService
* [x] **M1: Open Graph tags** — og:title, og:description, og:image, twitter:card in index.html
* [x] **M2: sitemap.xml** — Created with all public routes
* [x] **M4: Notification preferences page** — /notification-preferences with email/WhatsApp toggles + unsubscribe
* [x] **M5: XSS sanitization** — lib/sanitize.ts; text fields sanitized before DB writes
* [x] **Mobile fixes** — Feedback widget, dashboard, landing page, JobCard, VinScanner all mobile-optimised
* [x] **Logic fixes** — Supplier null bug, stale closures, race conditions, broken technician notifications

***

## TODO — Infrastructure & Config (you need to do these manually)

### 1. Connect Twilio Account

* [ ] Log into [Twilio Console](https://console.twilio.com)
* [ ] Copy your **Account SID** (starts with `AC...`) and **Auth Token**
* [ ] If using sandbox: your WhatsApp number is `whatsapp:+14155238886`
* [ ] If going production: buy a number + register WhatsApp sender in Twilio Console
* [ ] Run:

  ```bash
  supabase secrets set TWILIO_ACCOUNT_SID="AC..."
  supabase secrets set TWILIO_AUTH_TOKEN="your-auth-token"
  supabase secrets set TWILIO_WHATSAPP_FROM="whatsapp:+14155238886"
  ```

### 2. Set Up Email (Resend)

* [ ] Sign up at [resend.com](https://resend.com) (free tier: 3,000 emails/month)
* [ ] Add and verify your domain `fleetos.us` in Resend (DNS records)
* [ ] Copy your API key (starts with `re_...`)
* [ ] Run:

  ```bash
  supabase secrets set RESEND_API_KEY="re_..."
  supabase secrets set FROM_EMAIL="FleetOS <notifications@fleetos.us>"
  ```

### 3. Deploy Edge Functions + Run Migrations

* [ ] Run all of these:

  ```bash
  supabase functions deploy send-email
  supabase functions deploy send-whatsapp
  supabase functions deploy whatsapp-webhook
  supabase functions deploy respond-to-request
  supabase functions deploy daily-report
  supabase functions deploy sign-token
  supabase functions deploy manage-whatsapp-templates
  supabase db push
  ```

### 4. Register WhatsApp Templates (after Twilio is connected)

* [ ] Deploy the template function first (step 3 above)
* [ ] Then create all 6 templates in one API call:

  ```bash
  curl -X POST https://bsbjwjpgiangjqqqxota.supabase.co/functions/v1/manage-whatsapp-templates \
    -H "Authorization: Bearer YOUR_ANON_KEY" \
    -H "Content-Type: application/json" \
    -d '{"action": "create-all"}'
  ```
* [ ] Templates go through Meta approval (usually 1-24 hours)

### 5. Set Up Sentry Error Tracking

* [ ] Sign up at [sentry.io](https://sentry.io) (free tier: 5,000 errors/month)
* [ ] Create a React project, copy the DSN
* [ ] Add to Vercel env vars:

  ```
  VITE_SENTRY_DSN=https://xxxxx@o12345.ingest.sentry.io/12345
  ```

### 6. Rotate Secrets

* [ ] Generate new `MAGIC_LINK_SECRET` (64-char hex): `openssl rand -hex 32`
* [ ] Set it server-side: `supabase secrets set MAGIC_LINK_SECRET="<new-secret>"`
* [ ] Remove `VITE_JWT_SECRET` from Vercel env vars (Development, Preview, Production) — it was leaked into the client bundle and is unused. Rotate the underlying value out of caution.
* [ ] Check git history for any committed secrets: `git log --all -p -- .env.local`

### 7. WhatsApp Production (when ready to leave sandbox)

* [ ] Create a Facebook Business Manager account at [business.facebook.com](https://business.facebook.com)
* [ ] In Twilio Console: **Messaging > WhatsApp Senders** — register your number
* [ ] Twilio handles the Meta verification process (1-7 days)
* [ ] Buy a dedicated Twilio number (\~$1/month)
* [ ] Update `TWILIO_WHATSAPP_FROM` to your production number

### 8. Remaining Code Items (nice-to-have)

* [ ] **M3: Rate limiting** — Add rate limits to edge functions to prevent abuse
* [ ] **OG image** — Create `public/fleetos-og.png` (1200x630px) for social sharing

***

## Quick Reference — Supabase Project

* **URL:** `https://bsbjwjpgiangjqqqxota.supabase.co`
* **Dashboard:** `https://supabase.com/dashboard/project/bsbjwjpgiangjqqqxota`
* **Vercel:** `fleet-os` project on Vercel, domain `fleetos.us`

***

## Session Summary (2026-04-02)

### What we shipped today:

1. **Pre-production hardening** — fixed 20+ logic bugs, notification routing, mobile responsiveness
2. **Auth hardening** — email verification via OTP, backend session validation, 7-day session TTL
3. **Security** — tightened RLS policies, XSS sanitization, input validation, server-side token signing
4. **Notifications** — CAN-SPAM compliant emails, WhatsApp consent tracking, Content API templates
5. **Monitoring** — Sentry integration, structured error logging
6. **SEO** — OG tags, sitemap.xml, canonical URL
7. **UI** — Notification preferences page, mobile-optimised feedback widget

### Commits:

* `d2c84d6` — pre-production hardening (logic, notifications, mobile)
* `bd7df3d` — mobile-optimise feedback widget
* `31047c9` — production hardening (auth, RLS, Sentry, validation)
* `a178c3b` — notification preferences page
* `7159dec` — WhatsApp template support (Content API)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://t420.gitbook.io/t420/production_readiness.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
