> 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/pitstop_handoff_smoke_test.md).

# Pitstop Parts Hand-off — Smoke Test Plan

**Created:** 2026-04-21 **Last run:** 2026-04-21 **Status:** Level A passed. Level B 4/5 passed — only Twilio sandbox-join remaining. **Goal:** Prove end-to-end that a part added to a job triggers a WhatsApp alert to the assigned parts-person.

## Resume state (2026-04-21)

Smoke test was executed. All code-path layers verified:

| Layer                                                         | Status                            |
| ------------------------------------------------------------- | --------------------------------- |
| Schema — `parts_contact_id` persists, FK holds, join resolves | ✅ passing                         |
| `send-whatsapp` edge function reachable + auth accepts        | ✅ passing                         |
| Twilio credentials present in Supabase secrets                | ✅ passing                         |
| Twilio WhatsApp sender registered + recipient joined sandbox  | ❌ blocked on Twilio sandbox setup |

**Current test fixture state in prod:**

* Test contact id: `85827958-998e-409f-844b-636e7ec52604`
* Phone: `+27836775735` (real, user's own)
* Linked to request: `09f798ba-2985-43db-8ab0-dc6045c7f182`
* Old seed contact `db6ff884-...` was deleted between sessions

**Twilio error on last run:**

```
63007 — "Twilio could not find a Channel with the specified From address"
```

This means either (a) recipient phone hasn't joined the Twilio WhatsApp sandbox, or (b) `TWILIO_WHATSAPP_FROM` points to an unapproved production number.

**Twilio console was erroring when we tried to access the sandbox join page** on 2026-04-21 — retry later.

## Next time — resume from here

1. Open Twilio console → Messaging → Try it out → Send a WhatsApp message
2. Copy the `join <two-words>` keyword shown on that page
3. From WhatsApp on `+27836775735`, send that exact text to `+1 415 523 8886`
4. Wait for "Twilio Sandbox: You are all set" confirmation
5. Re-fire the test curl (anon key is in `.env.local` if needed):

```bash
curl -sS -X POST "https://bsbjwjpgiangjqqqxota.supabase.co/functions/v1/send-whatsapp" \
  -H "Authorization: Bearer <VITE_SUPABASE_ANON_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"to":"+27836775735","message":"FleetOS smoke test: Parts hand-off — New part needed for Truck #99: brake pads (BLOCKING — job on hold until received)."}'
```

Expected on success: `{"success":true,"sid":"SM..."}` and a WhatsApp on your phone within 5 seconds.

If error is different from 63007, escalate to Twilio dashboard to verify `TWILIO_WHATSAPP_FROM` value (should be `whatsapp:+14155238886` for sandbox).

***

## Context — what's already done

* Migration `20260421_pitstop_foundation.sql` applied to prod on 2026-04-21
* Added ghost columns: `service_requests.parts_contact_id`, `parts_contact_name`, `driver_contact_id`, `driver_contact_name`
* Verified schema: FK to `contacts(contact_id)` resolves correctly
* Prod supabase project ref: `bsbjwjpgiangjqqqxota`

## Test fixtures (already in prod)

| Item                            | ID / Value                                                        |
| ------------------------------- | ----------------------------------------------------------------- |
| Test parts\_person contact      | `db6ff884-90db-425d-b76d-7c98150fa745`                            |
| Test contact value (fake phone) | `TEST_PARTS_PERSON_DO_NOT_CONTACT`                                |
| Test supplier company           | `69dea31e-4bd3-43ac-94b0-6aa70f2ce427`                            |
| Test service\_request           | `09f798ba-2985-43db-8ab0-dc6045c7f182` (Swift Movers / Truck #99) |

The test contact currently has a fake phone — **no WhatsApp can actually fire against it**. Before Level B, swap in a real phone (your own) so you can receive the message.

***

## Level A — schema correctness (DONE)

Confirmed via SQL editor join on 2026-04-21. `parts_contact_id` persists, role propagates, FK enforces. No action needed unless re-validating.

***

## Level B — end-to-end WhatsApp delivery

### Pre-flight: swap fake phone for your own

Pick ONE of these two paths. Then run level B.

#### Path 1 — UI test (most realistic)

1. Put your real WhatsApp number on the test contact:

```sql
UPDATE contacts
SET contact_value = '<YOUR_E164_NUMBER_E_G_+15551234567>'
WHERE contact_id = 'db6ff884-90db-425d-b76d-7c98150fa745';
```

2. Start dev server:

```bash
npm run dev
```

3. Log in as a supplier account linked to company `69dea31e-4bd3-43ac-94b0-6aa70f2ce427`.
4. Open the job card for request `09f798ba-2985-43db-8ab0-dc6045c7f182` (Swift Movers / Truck #99).
5. Confirm the Assignment Panel shows "TEST Parts Person" as the parts-person (it should — we set this via SQL).
6. Add a part via the parts UI (description: `brake pads`, mark `is_blocking = true`).
7. **Expected:** WhatsApp arrives on your phone. Template copy: `"New part needed for Truck #99: brake pads (BLOCKING — job on hold until received)"`.
8. Source path: `services/requests/RequestSchedulingService.ts:179-200` — Notification #6.

#### Path 2 — scripted test (faster, skips UI)

Option to build later: a node script under `scripts/test-parts-handoff.ts` that imports `RequestSchedulingService` and calls `addPart()` directly against the test request. Skips dev server entirely.

Ask Claude to scaffold this script at the start of the next session if you go this route.

***

## Success criteria

* WhatsApp message received on your phone within 30 seconds of adding the part
* No console errors in browser devtools during the add-part flow
* Row visible in `notifications` table with `channel = 'whatsapp'` and `related_request_id = '09f798ba-...'`

Verify the notification record:

```sql
SELECT * FROM notifications
WHERE related_request_id = '09f798ba-2985-43db-8ab0-dc6045c7f182'
ORDER BY sent_at DESC LIMIT 5;
```

***

## Known blockers to watch for

* **Twilio credentials:** `supabase/functions/send-whatsapp` needs `TWILIO_ACCOUNT_SID`, `TWILIO_AUTH_TOKEN`, and a sending number configured in Supabase edge function secrets. If these are unset, send silently fails with a console warning.
* **WhatsApp template approval:** Twilio may require a pre-approved template for the "new part needed" message copy. If send-whatsapp fails with a template error, `manage-whatsapp-templates` edge function can register it.
* **RLS on notifications:** table has RLS disabled per migration 001 — writes work, but that's a prod hardening to revisit.

***

## Cleanup after test

```sql
-- Unlink test contact from request
UPDATE service_requests
SET parts_contact_id = NULL, parts_contact_name = NULL
WHERE request_id = '09f798ba-2985-43db-8ab0-dc6045c7f182';

-- Remove test contact
DELETE FROM contacts
WHERE contact_id = 'db6ff884-90db-425d-b76d-7c98150fa745';
```

***

## If Level B fails

Capture:

* Browser console errors from the add-part flow
* Row from `notifications` table (if one was created — shows channel, error, sent\_at)
* Any errors in Supabase edge function logs for `send-whatsapp`

Paste all three into the next Claude session — diagnosis starts from there.


---

# 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/pitstop_handoff_smoke_test.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.
