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

# FleetOS Manual Test Plan

**Version:** 1.0 **Last Updated:** March 2026 **Test Environment:** <https://fleetos.us> (Production) or <http://localhost:3000> (Local)

***

## Overview

This document provides a comprehensive manual test plan for FleetOS. Each test case includes:

* **Preconditions**: Setup required before testing
* **Steps**: Detailed actions to perform
* **Expected Results**: What should happen
* **Expected Notifications**: Email/WhatsApp notifications that should be sent
* **Verification Points**: How to confirm success

***

## Test Setup Requirements

### Accounts Needed

| Role                 | Description                                      | Setup                                              |
| -------------------- | ------------------------------------------------ | -------------------------------------------------- |
| **Fleet User**       | Fleet operator who creates service requests      | Sign up via `/become-fleet` or use test account    |
| **Supplier User**    | Service provider who receives and completes jobs | Sign up via `/become-supplier` or use test account |
| **Emergent Contact** | Team member accessed via magic link              | Created automatically when magic link is clicked   |

### Test Data Checklist

* [ ] Fleet company with at least 1 vehicle
* [ ] Supplier company with valid phone/email for notifications
* [ ] Valid VIN for scanning tests (e.g., `1HGCM82633A123456`)
* [ ] Test images for upload (JPEG/PNG, <5MB)

***

## SECTION 1: JOB MANAGEMENT

### TEST 1.1: Create Service Request (Fleet → Supplier)

**Precondition:** Logged in as Fleet user with at least one supplier relationship

| Step | Action                                                       | Expected Result                          |
| ---- | ------------------------------------------------------------ | ---------------------------------------- |
| 1    | Navigate to "My Suppliers" tab                               | Supplier list displays                   |
| 2    | Click on a supplier card                                     | Supplier details expand or modal opens   |
| 3    | Click "ADD JOB" button                                       | FleetRequestForm modal opens             |
| 4    | Select/enter vehicle identifier                              | Field accepts text or dropdown selection |
| 5    | Enter location (e.g., "123 Main St, Downtown")               | Field accepts text                       |
| 6    | Select urgency: **URGENT**                                   | Radio/dropdown selects URGENT            |
| 7    | Enter description: "Front left tire flat, needs replacement" | Text area accepts input                  |
| 8    | Click "SUBMIT" or "SEND REQUEST"                             | Modal closes, success toast appears      |

**Expected Notifications:**

| Recipient        | Channel  | Message Contains                                                                                        |
| ---------------- | -------- | ------------------------------------------------------------------------------------------------------- |
| Supplier Company | Email    | 🔴 URGENT service request from \[Fleet Name], Vehicle: \[identifier], Location: \[location], magic link |
| Supplier Company | WhatsApp | 🔴 URGENT service request from \[Fleet Name], Vehicle, Location, magic link                             |

**Verification:**

* [ ] Request appears in Fleet's "My Requests" with status "SENT" or "PENDING"
* [ ] Request appears in Supplier's "My Jobs" with status "PENDING"
* [ ] Supplier receives notification within 1-2 minutes
* [ ] Magic link in notification works (opens request view)

***

### TEST 1.2: Create Scheduled Request

**Precondition:** Logged in as Fleet user

| Step | Action                                     | Expected Result                                     |
| ---- | ------------------------------------------ | --------------------------------------------------- |
| 1-4  | Same as TEST 1.1 steps 1-4                 | -                                                   |
| 5    | Select urgency: **SCHEDULED**              | Scheduled option selected, date/time picker appears |
| 6    | Select date/time (e.g., tomorrow 10:00 AM) | Date/time picker accepts selection                  |
| 7    | Enter description                          | Field accepts text                                  |
| 8    | Submit request                             | Request created with scheduled time                 |

**Expected Notifications:**

| Recipient        | Channel  | Message Contains                                      |
| ---------------- | -------- | ----------------------------------------------------- |
| Supplier Company | Email    | 📅 SCHEDULED service request, includes scheduled time |
| Supplier Company | WhatsApp | 📅 SCHEDULED request with date/time                   |

**Verification:**

* [ ] Request shows scheduled time in both Fleet and Supplier views
* [ ] Status shows as "SCHEDULED" or "PENDING"

***

### TEST 1.3: Accept Job (Supplier)

**Precondition:** Pending request exists for supplier

| Step | Action                      | Expected Result                         |
| ---- | --------------------------- | --------------------------------------- |
| 1    | Log in as Supplier          | Dashboard shows "My Jobs" tab           |
| 2    | Find pending request        | Request card shows with "ACCEPT" button |
| 3    | Click "ACCEPT"              | Accept modal/form appears               |
| 4    | Enter quoted amount: `150`  | Field accepts numeric input             |
| 5    | Select currency: `USD`      | Dropdown shows currency options         |
| 6    | Click "CONFIRM" or "ACCEPT" | Modal closes, status updates            |

**Expected Notifications:**

| Recipient     | Channel  | Message Contains                                                           |
| ------------- | -------- | -------------------------------------------------------------------------- |
| Fleet Company | Email    | ✅ \[Supplier Name] accepted your request for \[Vehicle], 💰 Quote: USD 150 |
| Fleet Company | WhatsApp | ✅ Accepted, Quote: USD 150, magic link                                     |

**Verification:**

* [ ] Request status changes to "ACCEPTED" or "ACKNOWLEDGED"
* [ ] Quoted amount displays on request card
* [ ] acknowledged\_at timestamp is set
* [ ] Fleet user sees status update in their dashboard

***

### TEST 1.4: Accept Job via Magic Link

**Precondition:** Supplier received notification with magic link

| Step | Action                             | Expected Result                                 |
| ---- | ---------------------------------- | ----------------------------------------------- |
| 1    | Click magic link in email/WhatsApp | Opens request view (no login required)          |
| 2    | Review request details             | Vehicle, location, urgency, description visible |
| 3    | Click "ACCEPT"                     | Accept action available without login           |
| 4    | Enter quote (optional)             | Field accepts input                             |
| 5    | Confirm acceptance                 | Request accepted, confirmation shown            |

**Expected Notifications:** Same as TEST 1.3

**Verification:**

* [ ] Emergent contact created for person who clicked link
* [ ] assigned\_to\_contact\_id populated
* [ ] Contact appears in supplier's team list

***

### TEST 1.5: Decline Job

**Precondition:** Pending request exists for supplier

| Step | Action                             | Expected Result                                |
| ---- | ---------------------------------- | ---------------------------------------------- |
| 1    | Log in as Supplier                 | Dashboard shows "My Jobs"                      |
| 2    | Find pending request               | Request card visible                           |
| 3    | Click "CAN'T HELP" or "DECLINE"    | Decline modal appears                          |
| 4    | Enter reason: "Fully booked today" | Text field accepts input                       |
| 5    | Confirm decline                    | Modal closes, request removed from active view |

**Expected Notifications:**

| Recipient     | Channel  | Message Contains                                                                    |
| ------------- | -------- | ----------------------------------------------------------------------------------- |
| Fleet Company | Email    | ❌ \[Supplier Name] declined your request for \[Vehicle], Reason: Fully booked today |
| Fleet Company | WhatsApp | ❌ Declined, reason, magic link to reassign                                          |

**Verification:**

* [ ] Request status changes to "DECLINED"
* [ ] decline\_reason stored in database
* [ ] declined\_at timestamp set
* [ ] Fleet sees declined status, can reassign to another supplier

***

### TEST 1.6: Start Job (In Progress)

**Precondition:** Accepted/acknowledged request exists

| Step | Action                                         | Expected Result                  |
| ---- | ---------------------------------------------- | -------------------------------- |
| 1    | Log in as Supplier                             | Dashboard shows accepted request |
| 2    | Find accepted request                          | Status shows "ACCEPTED"          |
| 3    | Click "START"                                  | Start action triggers            |
| 4    | (Optional) Add note: "Heading to location now" | Note field accepts text          |
| 5    | Confirm start                                  | Status updates to "IN PROGRESS"  |

**Expected Notifications:**

| Recipient     | Channel  | Message Contains                                                                    |
| ------------- | -------- | ----------------------------------------------------------------------------------- |
| Fleet Company | Email    | 🔧 \[Supplier Name] started working on \[Vehicle], 💬 Note: Heading to location now |
| Fleet Company | WhatsApp | 🔧 Started working, note (if provided), magic link                                  |

**Verification:**

* [ ] Request status changes to "IN\_PROGRESS"
* [ ] started\_at timestamp set
* [ ] Fleet sees real-time status update

***

### TEST 1.7: Complete Job (Full Flow)

**Precondition:** Request is in "IN\_PROGRESS" status

| Step | Action                                                   | Expected Result                     |
| ---- | -------------------------------------------------------- | ----------------------------------- |
| 1    | Log in as Supplier                                       | Dashboard shows in-progress request |
| 2    | Click "DONE" or "COMPLETE"                               | Completion form modal opens         |
| 3    | **Final Cost**: Enter `175`                              | Numeric field accepts value         |
| 4    | **Currency**: Select `USD`                               | Dropdown selection                  |
| 5    | **VAT Type**: Select "Includes VAT"                      | Dropdown selection                  |
| 6    | **Completion Photo**: Click camera icon                  | Device camera opens                 |
| 7    | Take photo of completed work                             | Photo captured and previewed        |
| 8    | **Signature**: Draw signature on pad                     | Signature canvas accepts input      |
| 9    | **Odometer**: Enter `45230`                              | Numeric field accepts value         |
| 10   | **Invoice**: Upload invoice PDF (optional)               | File upload accepts PDF             |
| 11   | **Notes**: "Replaced front left tire, balanced all four" | Text field accepts input            |
| 12   | Click "SUBMIT COMPLETION"                                | Modal closes, status updates        |

**Expected Notifications:**

| Recipient     | Channel  | Message Contains                                                                                                                         |
| ------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| Fleet Company | Email    | ✅ \[Supplier Name] completed work on \[Vehicle], 💰 Final Cost: USD 175, 💬 Note: Replaced front left tire..., completion photo attached |
| Fleet Company | WhatsApp | ✅ Completed, Final Cost: USD 175, magic link to view details                                                                             |

**Verification:**

* [ ] Request status changes to "COMPLETED"
* [ ] completed\_at timestamp set
* [ ] final\_cost, currency stored
* [ ] completion\_photo\_url populated (photo uploaded to storage)
* [ ] signature\_url populated
* [ ] odometer\_in stored
* [ ] invoice\_attachment\_url stored (if uploaded)
* [ ] Photo visible in Fleet's request details view
* [ ] Event log shows completion with all metadata

***

### TEST 1.8: Complete Job - Photo Required Validation

**Precondition:** In-progress request, completion form open

| Step | Action                                  | Expected Result              |
| ---- | --------------------------------------- | ---------------------------- |
| 1    | Fill all fields EXCEPT completion photo | Fields populated             |
| 2    | Click "SUBMIT COMPLETION"               | **Error: Photo is required** |
| 3    | Capture completion photo                | Photo preview shows          |
| 4    | Click "SUBMIT COMPLETION"               | Submission succeeds          |

**Verification:**

* [ ] Cannot complete job without photo evidence
* [ ] Clear error message displayed
* [ ] Submission works after adding photo

***

### TEST 1.9: Reassign Job to Team Member

**Precondition:** Accepted request exists, multiple contacts in supplier company

| Step | Action                                 | Expected Result                   |
| ---- | -------------------------------------- | --------------------------------- |
| 1    | Log in as Supplier admin               | Dashboard shows request           |
| 2    | Click "ASSIGN" or team member selector | Team member dropdown/list appears |
| 3    | Select different team member           | Selection highlighted             |
| 4    | Confirm reassignment                   | Assignee updated on request       |

**Expected Notifications:**

| Recipient    | Channel          | Message Contains                                                         |
| ------------ | ---------------- | ------------------------------------------------------------------------ |
| New Assignee | Email + WhatsApp | 👤 Request assigned to you: \[Vehicle], Fleet: \[Fleet Name], magic link |

**Verification:**

* [ ] assigned\_to\_contact\_id updated
* [ ] assigned\_to\_name shows new assignee
* [ ] assigned\_at timestamp updated
* [ ] New assignee can see request in their view
* [ ] Event log records reassignment

***

## SECTION 2: VEHICLE MANAGEMENT

### TEST 2.1: Add Vehicle via VIN Scan

**Precondition:** Logged in as Fleet user, camera access enabled

| Step | Action                                              | Expected Result                  |
| ---- | --------------------------------------------------- | -------------------------------- |
| 1    | Navigate to "Vehicles" or "Assets" section          | Vehicle list displays            |
| 2    | Click "ADD VEHICLE"                                 | AddAssetModal opens              |
| 3    | Click "SCAN VIN"                                    | Camera/barcode scanner activates |
| 4    | Point camera at VIN barcode                         | VIN detected and captured        |
| 5    | VIN auto-populates: `1HGCM82633A123456`             | VIN field shows scanned value    |
| 6    | VIN decoding runs automatically                     | Make, Model, Year auto-populate  |
| 7    | Review/edit vehicle identifier: "Honda Accord 2003" | Can modify suggested name        |
| 8    | Click "SAVE"                                        | Vehicle added to list            |

**Verification:**

* [ ] VIN scanner successfully reads barcode
* [ ] VIN decoder returns make/model/year
* [ ] Vehicle appears in company vehicle list
* [ ] Vehicle available for selection when creating requests

***

### TEST 2.2: Add Vehicle Manually

**Precondition:** Logged in as Fleet user

| Step | Action                                    | Expected Result            |
| ---- | ----------------------------------------- | -------------------------- |
| 1    | Click "ADD VEHICLE"                       | AddAssetModal opens        |
| 2    | Enter VIN manually: `1HGCM82633A123456`   | Field validates format     |
| 3    | VIN decode triggered                      | Make/Model/Year fetched    |
| 4    | If decode fails, enter manually:          | Fields accept manual input |
|      | - Make: Honda                             |                            |
|      | - Model: Accord                           |                            |
|      | - Year: 2003                              |                            |
| 5    | Enter vehicle identifier: "Fleet Car #42" | Custom name accepted       |
| 6    | Click "SAVE"                              | Vehicle saved              |

**Verification:**

* [ ] VIN format validated (17 chars, no I/O/Q)
* [ ] Vehicle saved with all fields
* [ ] Vehicle appears in dropdown when creating requests

***

### TEST 2.3: VIN Validation

**Precondition:** Add vehicle modal open

| Step | Action                                           | Expected Result                          |
| ---- | ------------------------------------------------ | ---------------------------------------- |
| 1    | Enter invalid VIN: `123`                         | **Error: VIN must be 17 characters**     |
| 2    | Enter VIN with invalid char: `1HGCM82633I123456` | **Error: VIN cannot contain I, O, or Q** |
| 3    | Enter valid VIN: `1HGCM82633A123456`             | Validation passes, decode attempted      |

**Verification:**

* [ ] Invalid VINs rejected with clear error message
* [ ] Valid VINs proceed to decode/save

***

### TEST 2.4: Select Saved Vehicle for Request

**Precondition:** Fleet has at least one saved vehicle

| Step | Action                      | Expected Result                   |
| ---- | --------------------------- | --------------------------------- |
| 1    | Start creating new request  | Request form opens                |
| 2    | Click vehicle dropdown      | Saved vehicles listed             |
| 3    | Select "Fleet Car #42"      | Vehicle auto-populates            |
| 4    | Complete and submit request | Request includes vehicle\_id link |

**Verification:**

* [ ] Saved vehicles appear in dropdown
* [ ] Selected vehicle links to vehicle record
* [ ] Make/model/year available in request details

***

## SECTION 3: DOCUMENT & IMAGE MANAGEMENT

### TEST 3.1: Capture Completion Photo

**Precondition:** Completing a job, camera access enabled

| Step | Action                               | Expected Result           |
| ---- | ------------------------------------ | ------------------------- |
| 1    | Click camera icon in completion form | Device camera opens       |
| 2    | Take photo                           | Photo captured            |
| 3    | Preview displays                     | Photo visible in form     |
| 4    | Click "RETAKE" (optional)            | Camera reopens            |
| 5    | Submit completion                    | Photo uploaded to storage |

**Verification:**

* [ ] Photo captured in acceptable quality
* [ ] Preview shows correct image
* [ ] Retake functionality works
* [ ] Photo URL saved to completion\_photo\_url
* [ ] Photo accessible via URL in request details

***

### TEST 3.2: Capture Digital Signature

**Precondition:** Completion form open

| Step | Action                            | Expected Result            |
| ---- | --------------------------------- | -------------------------- |
| 1    | Click signature pad area          | Signature canvas activates |
| 2    | Draw signature with finger/stylus | Signature visible          |
| 3    | Click "CLEAR" (optional)          | Canvas clears              |
| 4    | Draw signature again              | New signature captured     |
| 5    | Submit completion                 | Signature uploaded         |

**Verification:**

* [ ] Signature canvas responsive to touch/mouse
* [ ] Clear button works
* [ ] Signature saved as image
* [ ] signature\_url populated in database

***

### TEST 3.3: Upload Invoice Attachment

**Precondition:** Completion form open

| Step | Action                  | Expected Result    |
| ---- | ----------------------- | ------------------ |
| 1    | Click "ATTACH INVOICE"  | File picker opens  |
| 2    | Select PDF file (< 5MB) | File name displays |
| 3    | Submit completion       | File uploaded      |

**Verification:**

* [ ] PDF accepted
* [ ] File size limit enforced
* [ ] invoice\_attachment\_url populated
* [ ] Fleet can download/view invoice

***

### TEST 3.4: View Job Evidence (Fleet Side)

**Precondition:** Completed job with photo/signature exists

| Step | Action                     | Expected Result                    |
| ---- | -------------------------- | ---------------------------------- |
| 1    | Log in as Fleet user       | Dashboard shows completed requests |
| 2    | Click on completed request | Request details expand             |
| 3    | View completion photo      | Photo displayed/downloadable       |
| 4    | View signature             | Signature image displayed          |
| 5    | Download invoice           | Invoice PDF downloads              |

**Verification:**

* [ ] All evidence visible to fleet
* [ ] Images load correctly
* [ ] PDFs downloadable

***

## SECTION 4: CONTACT & SUPPLIER FEATURES

### TEST 4.1: Emergent Contact Creation via Magic Link

**Precondition:** New email/phone that hasn't accessed system before

| Step | Action                                | Expected Result                   |
| ---- | ------------------------------------- | --------------------------------- |
| 1    | Send request to supplier              | Notification sent with magic link |
| 2    | Click magic link from NEW phone/email | Request view loads                |
| 3    | Perform action (accept/start)         | Action completes                  |

**Verification:**

* [ ] New emergent contact created in contacts table
* [ ] contact\_value matches email/phone from link
* [ ] company\_id links to supplier company
* [ ] first\_seen\_at timestamp set
* [ ] Contact appears in supplier's team list

***

### TEST 4.2: Contact Team Member List

**Precondition:** Supplier company has multiple contacts

| Step | Action                               | Expected Result                      |
| ---- | ------------------------------------ | ------------------------------------ |
| 1    | Log in as Supplier                   | Dashboard loads                      |
| 2    | Navigate to "TEAM" or "CONTACTS" tab | Contact list displays                |
| 3    | View contact details                 | Name, email/phone, last active shown |

**Verification:**

* [ ] All company contacts listed
* [ ] Contact info accurate
* [ ] Last activity timestamp updates

***

### TEST 4.3: Contact Supplier from Fleet Dashboard

**Precondition:** Fleet has supplier relationship

| Step | Action              | Expected Result                          |
| ---- | ------------------- | ---------------------------------------- |
| 1    | View active request | Request details visible                  |
| 2    | Click "CALL"        | Phone dialer opens with supplier number  |
| 3    | Click "WHATSAPP"    | WhatsApp opens with supplier chat        |
| 4    | Click "EMAIL"       | Email client opens with supplier address |

**Verification:**

* [ ] Contact actions use correct phone/email
* [ ] Deep links work on mobile devices
* [ ] Desktop fallbacks work appropriately

***

### TEST 4.4: Supplier Invitation Flow

**Precondition:** Fleet user logged in

| Step | Action                             | Expected Result               |
| ---- | ---------------------------------- | ----------------------------- |
| 1    | Click "INVITE SUPPLIER" or similar | Invitation form/modal opens   |
| 2    | Enter supplier email/phone         | Field accepts input           |
| 3    | Send invitation                    | Magic link generated and sent |
| 4    | Supplier clicks link               | Onboarding flow starts        |

**Verification:**

* [ ] Invitation sent via email/WhatsApp
* [ ] Magic link valid for signup
* [ ] New supplier auto-linked to inviting fleet

***

## SECTION 5: NOTIFICATION TESTING

### TEST 5.1: Notification Delivery - Email

**Precondition:** Valid email configured for supplier

| Step | Action                            | Expected Result                                  |
| ---- | --------------------------------- | ------------------------------------------------ |
| 1    | Create urgent request to supplier | Request submitted                                |
| 2    | Check supplier's email inbox      | Email received within 2 minutes                  |
| 3    | Verify email content              | Contains: urgency, vehicle, location, magic link |
| 4    | Click magic link                  | Opens request in browser                         |

**Verification:**

* [ ] Email delivered
* [ ] Subject line clear and actionable
* [ ] Body contains all required info
* [ ] Magic link works
* [ ] Sender appears as FleetOS/legitimate

***

### TEST 5.2: Notification Delivery - WhatsApp

**Precondition:** Valid WhatsApp number configured, Twilio active

| Step | Action                            | Expected Result                                  |
| ---- | --------------------------------- | ------------------------------------------------ |
| 1    | Create urgent request to supplier | Request submitted                                |
| 2    | Check supplier's WhatsApp         | Message received within 2 minutes                |
| 3    | Verify message content            | Contains: urgency emoji, vehicle, location, link |
| 4    | Tap magic link                    | Opens request in browser                         |

**Verification:**

* [ ] WhatsApp delivered
* [ ] Message properly formatted
* [ ] Magic link tappable and works
* [ ] Urgency emoji correct (🔴 URGENT, 🟡 TODAY, 📅 SCHEDULED)

***

### TEST 5.3: Activation Nudges (Pending Request)

**Precondition:** Create request and do NOT acknowledge

| Step | Action                          | Expected Result                                              |
| ---- | ------------------------------- | ------------------------------------------------------------ |
| 1    | Create request, wait 15 minutes | -                                                            |
| 2    | Check supplier's WhatsApp/email | **Nudge #1**: "Quick check: \[Fleet] is waiting..."          |
| 3    | Wait until 1 hour total         | **Nudge #2**: "\[Fleet] still waiting (1 hour)..."           |
| 4    | Wait until 4 hours total        | **Nudge #3**: "Urgent: \[Fleet] request pending 4+ hours..." |

**Verification:**

* [ ] Nudges sent at correct intervals
* [ ] Message intensity increases
* [ ] Each nudge includes magic link
* [ ] Nudges stop after request is acknowledged

***

### TEST 5.4: Notification Routing - Contact Hint

**Precondition:** Supplier has multiple team contacts

| Step | Action                                    | Expected Result                           |
| ---- | ----------------------------------------- | ----------------------------------------- |
| 1    | Create request with specific contact hint | Contact hint provided in form             |
| 2    | Check targeted contact's device           | Notification received by specific contact |
| 3    | Check other team members                  | They do NOT receive notification          |

**Verification:**

* [ ] Notification routed to hinted contact only
* [ ] Other team members unaffected
* [ ] Fallback to org works if hint invalid

***

### TEST 5.5: Notification Routing - Last Active Fallback

**Precondition:** No contact hint provided, supplier has team

| Step | Action                              | Expected Result       |
| ---- | ----------------------------------- | --------------------- |
| 1    | Create request without contact hint | Request submitted     |
| 2    | Check last-active contact's device  | Notification received |

**Verification:**

* [ ] System identifies last-active contact
* [ ] Notification sent to most recent team member
* [ ] Routing logged for audit

***

## SECTION 6: MAGIC LINK TESTING

### TEST 6.1: Magic Link - 7-Day Validity

**Precondition:** Generated magic link

| Step | Action                                 | Expected Result         |
| ---- | -------------------------------------- | ----------------------- |
| 1    | Generate magic link (via notification) | Link created            |
| 2    | Click link within 7 days               | Access granted          |
| 3    | Wait 8+ days (or simulate expiry)      | **Error: Link expired** |

**Verification:**

* [ ] Links work within validity period
* [ ] Expired links show clear error message
* [ ] Expired links offer way to request new link

***

### TEST 6.2: Magic Link - One-Click Auth

**Precondition:** Magic link received

| Step | Action                              | Expected Result                 |
| ---- | ----------------------------------- | ------------------------------- |
| 1    | Click magic link                    | Page loads without login prompt |
| 2    | View request details                | All info visible                |
| 3    | Take action (accept/start/complete) | Action succeeds without login   |

**Verification:**

* [ ] No password required
* [ ] No signup required
* [ ] Full functionality available
* [ ] Session established for continued access

***

### TEST 6.3: Public Tracking URL

**Precondition:** Request with tracking\_token exists

| Step | Action                                | Expected Result          |
| ---- | ------------------------------------- | ------------------------ |
| 1    | Navigate to `/track/{tracking_token}` | Tracking page loads      |
| 2    | View request status                   | Current status displayed |
| 3    | View timeline                         | Status history shown     |

**Verification:**

* [ ] Tracking page accessible without login
* [ ] Shows current status
* [ ] Shows status timeline
* [ ] No sensitive info exposed (no costs, internal notes)

***

## SECTION 7: AUDIT TRAIL & COMPLIANCE

### TEST 7.1: Event Log - Request Lifecycle

**Precondition:** Complete full request lifecycle

| Step | Action           | Expected Result                         |
| ---- | ---------------- | --------------------------------------- |
| 1    | Create request   | Event logged: service\_request\_created |
| 2    | Accept request   | Event logged: request\_accepted         |
| 3    | Start request    | Event logged: request\_started          |
| 4    | Complete request | Event logged: request\_completed        |

**Verification (check database/logs):**

* [ ] All events logged with timestamps
* [ ] Each event has correct event\_type
* [ ] company\_id links to acting company
* [ ] contact\_id links to person who acted
* [ ] target\_request\_id links to request
* [ ] metadata contains event-specific data (quotes, costs, etc.)

***

### TEST 7.2: Event Log - Immutability

**Precondition:** Events exist in event\_log

| Step | Action                       | Expected Result                   |
| ---- | ---------------------------- | --------------------------------- |
| 1    | Attempt to modify past event | **Should not be possible via UI** |
| 2    | Verify via database query    | All events intact                 |

**Verification:**

* [ ] No DELETE operations on event\_log
* [ ] No UPDATE operations on event\_log
* [ ] All events have immutable timestamps

***

### TEST 7.3: Compliance - Photo Evidence

**Precondition:** Completed job with photo

| Step | Action                 | Expected Result                     |
| ---- | ---------------------- | ----------------------------------- |
| 1    | View completed request | Photo visible                       |
| 2    | Check photo URL        | Points to job-evidence bucket       |
| 3    | Verify path structure  | `{requestId}/photo-{timestamp}.ext` |

**Verification:**

* [ ] Photo stored securely
* [ ] Photo linked to specific request
* [ ] Timestamp in path provides audit trail
* [ ] Photo cannot be modified after upload

***

## SECTION 8: ERROR HANDLING & EDGE CASES

### TEST 8.1: Network Failure During Request Creation

| Step | Action                          | Expected Result                |
| ---- | ------------------------------- | ------------------------------ |
| 1    | Start creating request          | Form open                      |
| 2    | Disable network (airplane mode) | -                              |
| 3    | Submit request                  | **Error: Network unavailable** |
| 4    | Re-enable network               | -                              |
| 5    | Retry submission                | Request creates successfully   |

**Verification:**

* [ ] Clear error message shown
* [ ] Form data preserved (not lost)
* [ ] Retry works without re-entering data

***

### TEST 8.2: Duplicate Request Prevention

| Step | Action                         | Expected Result                                 |
| ---- | ------------------------------ | ----------------------------------------------- |
| 1    | Submit request                 | Request created                                 |
| 2    | Immediately click submit again | **Either: prevented or second request created** |

**Verification:**

* [ ] Either double-click prevented OR
* [ ] User warned about potential duplicate OR
* [ ] Both requests tracked (edge case acceptable)

***

### TEST 8.3: Invalid Magic Link

| Step | Action                               | Expected Result              |
| ---- | ------------------------------------ | ---------------------------- |
| 1    | Modify magic link token (corrupt it) | -                            |
| 2    | Navigate to corrupted link           | **Error: Invalid link**      |
| 3    | Clear error message shown            | Suggests requesting new link |

**Verification:**

* [ ] Corrupted links don't grant access
* [ ] Clear error message
* [ ] Path to recovery (request new link)

***

### TEST 8.4: Camera Permission Denied

| Step | Action                          | Expected Result              |
| ---- | ------------------------------- | ---------------------------- |
| 1    | Click VIN scan or photo capture | Camera permission prompt     |
| 2    | Deny permission                 | **Fallback to manual input** |
| 3    | Manual entry works              | Can proceed without camera   |

**Verification:**

* [ ] Graceful fallback when camera unavailable
* [ ] Clear instructions provided
* [ ] User can complete task manually

***

### TEST 8.5: Large File Upload Rejection

| Step | Action                  | Expected Result                     |
| ---- | ----------------------- | ----------------------------------- |
| 1    | Try to upload 20MB file | -                                   |
| 2    | Select file             | **Error: File too large (max 5MB)** |

**Verification:**

* [ ] Large files rejected before upload
* [ ] Clear size limit communicated
* [ ] User can select smaller file

***

## SECTION 9: CROSS-ROLE TESTING

### TEST 9.1: Fleet Cannot Accept Own Requests

| Step | Action                 | Expected Result  |
| ---- | ---------------------- | ---------------- |
| 1    | Log in as Fleet        | Dashboard loads  |
| 2    | View sent requests     | Requests visible |
| 3    | Look for ACCEPT button | **Not present**  |

**Verification:**

* [ ] Fleet role cannot accept requests
* [ ] Only supplier-side actions available to suppliers
* [ ] Role separation enforced

***

### TEST 9.2: Supplier Cannot Create Requests for Other Suppliers

| Step | Action                               | Expected Result   |
| ---- | ------------------------------------ | ----------------- |
| 1    | Log in as Supplier                   | Dashboard loads   |
| 2    | Look for "Send to supplier" option   | **Not available** |
| 3    | Can only receive and manage own jobs | Correct scope     |

**Verification:**

* [ ] Suppliers receive, not create cross-supplier requests
* [ ] Own manual requests allowed (internal tracking)

***

## SECTION 10: PERFORMANCE & LOAD

### TEST 10.1: Dashboard Load with Many Requests

**Precondition:** 100+ requests in system

| Step | Action                  | Expected Result        |
| ---- | ----------------------- | ---------------------- |
| 1    | Log in                  | Dashboard loads        |
| 2    | Measure load time       | < 3 seconds            |
| 3    | Scroll through requests | Smooth scrolling       |
| 4    | Filter by status        | Filter applies quickly |

**Verification:**

* [ ] Dashboard loads in reasonable time
* [ ] Pagination or virtualization working
* [ ] Filters responsive

***

### TEST 10.2: Photo Upload Performance

| Step | Action                  | Expected Result               |
| ---- | ----------------------- | ----------------------------- |
| 1    | Capture high-res photo  | Photo captured                |
| 2    | Submit completion       | Upload completes < 10 seconds |
| 3    | Verify upload succeeded | Photo URL valid               |

**Verification:**

* [ ] Photos compressed appropriately
* [ ] Upload progress shown (if long)
* [ ] Timeout handling for slow connections

***

## TEST SUMMARY CHECKLIST

### Core Flows

* [ ] Create request (all urgency types)
* [ ] Accept request (with/without quote)
* [ ] Decline request (with reason)
* [ ] Start request
* [ ] Complete request (with all evidence)
* [ ] Reassign request

### Vehicle Management

* [ ] VIN scan
* [ ] Manual vehicle add
* [ ] Vehicle selection in requests

### Evidence & Documents

* [ ] Photo capture
* [ ] Signature capture
* [ ] Invoice upload
* [ ] Evidence viewing

### Notifications

* [ ] Email delivery
* [ ] WhatsApp delivery
* [ ] Activation nudges
* [ ] Magic links

### Security & Access

* [ ] Magic link authentication
* [ ] Link expiry
* [ ] Role-based access

### Audit & Compliance

* [ ] Event logging
* [ ] Evidence storage
* [ ] Immutable audit trail

***

## APPENDIX: NOTIFICATION MESSAGE REFERENCE

### Request Created (to Supplier)

```
🔴 URGENT service request from [Fleet Name]

Vehicle: [identifier]
Location: [location]
Urgency: URGENT

[Description]

View & respond: [magic-link]
```

### Request Accepted (to Fleet)

```
✅ [Supplier Name] accepted your request for [Vehicle]

💰 Quote: USD 150

View details: [magic-link]
```

### Request Declined (to Fleet)

```
❌ [Supplier Name] declined your request for [Vehicle] at [Location]

Reason: [decline_reason]

Find another supplier: [magic-link]
```

### Request Started (to Fleet)

```
🔧 [Supplier Name] started working on [Vehicle]

💬 Note: [note]

Track progress: [magic-link]
```

### Request Completed (to Fleet)

```
✅ [Supplier Name] completed work on [Vehicle]

💰 Final Cost: USD 175
💬 Note: [completion_notes]

View completion details: [magic-link]
```

### Activation Nudges (to Supplier)

```
15 min: "Quick check: [Fleet] is waiting for a response on [Vehicle]"
1 hour: "[Fleet] still waiting (1 hour) - Fast responses = more business"
4 hours: "Urgent: [Fleet] request pending 4+ hours - This affects your response rating"
```

***

**Document End**


---

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