# Supabase setup guide — HeavyHaul Agent

Supabase is used for **Postgres (database)** and **private Storage (files)**
only. **Authentication is NOT Supabase Auth** — users are defined in `.env`
(see §4). Total setup: ~10 minutes.

## 1. Create the project

1. Go to [supabase.com](https://supabase.com) → sign in → **New project**.
2. Organization: yours · Name: `heavyhaul-agent` · Database password: generate
   and save it somewhere safe · Region: closest to your users (e.g. `us-east-1`).
3. Wait for provisioning (~2 min).

## 2. Get your API keys

Dashboard → **Project Settings → API**:

| Key on that page | Goes into `.env.local` as |
|---|---|
| Project URL | `NEXT_PUBLIC_SUPABASE_URL` |
| `service_role` key | `SUPABASE_SERVICE_ROLE_KEY` |

> ⚠️ The `service_role` key is the ONLY key the app uses, and it lives strictly
> on the server (`server-only` imports enforce this). The anon key is not used —
> after migration 0002, anon/authenticated API keys can read/write **nothing**
> (RLS enabled with zero policies).

## 3. Apply the database migrations (in order)

**Option A — SQL Editor (fastest):**
1. Dashboard → **SQL Editor** → **New query**.
2. Paste the full contents of `supabase/migrations/0001_init.sql` → **Run**.
3. New query → paste `supabase/migrations/0002_env_auth.sql` → **Run**.

**Option B — Supabase CLI (recommended for a team):**
```bash
npm install -g supabase
supabase login
supabase link --project-ref YOUR-PROJECT-REF   # ref is in the project URL
supabase db push                               # applies supabase/migrations/* in order
```

What the migrations create:
- `0001` — all tables (`profiles`, `broker_pages`, `trips`, `trip_participants`,
  `trip_invitations`, `documents`, `permits`, `warnings`, `service_requests`,
  `chat_messages`, `trip_events`, `intake_submissions`), enums, and the private
  storage bucket `trip-documents`.
- `0002` — removes the Supabase Auth coupling (no `auth.users` trigger/FK) and
  drops all client-key policies. Result: **service-role-only database**;
  authorization is enforced in the app server layer
  (`src/lib/data/trips.ts`, `src/lib/api-guard.ts`), and files are served only
  through 30-minute signed URLs after a participant check.

## 4. Configure authentication (in `.env.local`, not in Supabase)

```bash
cp .env.example .env.local
```

Fill in:

- `AUTH_SECRET` — random string for signing session cookies:
  `openssl rand -hex 32`
- `AUTH_USERS` — JSON array of accounts. Login is by **username**. Example:

```json
[
  {"username":"Nash_Turcan","password":"change-me","role":"broker","company":"Nash Turcan"}
]
```

Rules:
- Roles: `broker` | `dispatcher` | `driver` | `admin` (default `broker`).
- `company` is required for brokers — it names their public intake page slug.
- Optional `email` field: add it so trip invitations sent to that address
  auto-link to the account when the person signs in.
- There is **no self-serve signup**: to onboard someone (including people you
  invite to trips), add them here and restart/redeploy the app.
- Usernames are matched case-insensitively; passwords are case-sensitive.

## 5. Run the app

```bash
npm install
npm run dev
# open http://localhost:3000
```

Smoke test the vertical flow:
1. **Sign in** as the broker from `AUTH_USERS` → the dashboard shows the
   personal intake link `/intake/<company-slug>` (created on first sign-in).
2. Open the intake link in a **private/incognito window** (no login) → submit a
   rate confirmation + choose *upload permits* or *request from Synchron*.
3. Back in the broker dashboard the trip appears under **Waiting for Permits**
   (or **Active** if permits were uploaded and extraction is connected).
4. Open the invite link from the success screen → **sign in** (any provisioned
   account) → accept → shared Trip Workspace.
5. Upload a permit in **Documents** → warnings/permit data appear (needs
   `FLASK_API_BASE_URL`; otherwise the permit shows `pending`).
6. Invite the **driver** from the People tab → sign in as the driver in another
   browser → mobile-first trip view.
7. Ask a question in **Ask Agent** → the whole trip sees the conversation.
8. **Mark completed** → the trip moves to **History** and is searchable.

## 6. Production notes

- Set `AUTH_SECRET`, `AUTH_USERS`, `NEXT_PUBLIC_SUPABASE_URL`,
  `SUPABASE_SERVICE_ROLE_KEY` (+ optional `FLASK_API_*`) in your host
  (e.g. Vercel → Settings → Environment Variables), all server-side.
- Rotate `AUTH_SECRET` to log everyone out; change a password in `AUTH_USERS`
  and redeploy to lock a single user out after their session expires (max 7 days).
- Storage: bucket is private; nothing is downloadable without a signed URL
  minted server-side for a verified participant.
- Backups: Dashboard → Database → Backups.
- New migrations: keep numbering (`0003_...sql`) and apply with
  `supabase db push` so all environments stay in sync.
