Technician App Flow
Technicians do not open the dashboard. The Levy operator-app is their entire surface, and the Tasks tab is where they spend their day. This article walks through the flow from "open the app" to "tap Resolve."
Where Tasks lives in the app
After the Phase 1 release, the operator-app's bottom navigator carries a new Tasks tab between Customers and Operations. Tapping it opens TasksScreen.tsx.
The top of the screen has three filter chips:
- Mine — tasks assigned to the logged-in tech
- Nearby — unclaimed tasks within ~5 km of the tech's location
- All — every open task in the subaccount (read-only unless assigned)
Sort options: distance, priority, age.
Each row shows the vehicle number, a type icon, the priority chip, distance to the vehicle ("0.3 mi"), and the SLA badge.
Accepting a task
If the task is on the Nearby list, the tech taps Accept on the row. This:
- Writes a new
task_assignmentsrow withis_current = true, atomically swapping the previous row tois_current = false - Moves the task from
CreatedtoAssigned - Pushes a confirmation toast and updates the local SQLite cache
If two techs tap Accept simultaneously, first-write wins. The second tech sees a 409 with the current assignee's name.
The task detail screen
Tapping any row opens TaskDetailScreen.tsx, which is a single scrollable surface:
- Header — vehicle number, title, priority chip, SLA badge
- Vehicle photo — pulled from the latest condition report
- Location card — last known GPS with a Navigate button that deep-links to Apple Maps (iOS) or Google Maps (Android)
- Description — what the rule engine or ops manager wrote
- Parts checklist — see Parts and Labor Tracking
- Photos — grouped by phase (before, during, after)
- Action buttons — Start, Resolve, Block, Decline
The photo gate
Two transitions are photo-gated:
assignedtoin_progressrequires one before photoin_progresstoresolvedrequires one after photo
The Start and Resolve buttons are disabled until the appropriate photo is attached. Tapping the camera icon opens the in-app capture screen. The app strips EXIF from the file before upload but preserves the geotag in a separate column (task_photos.geotag_lat/lng) for audit.
Photos are stored locally at ${FileSystem.documentDirectory}task-photos/<task_id>/ first, then uploaded with FileSystem.uploadAsync. Upload progress is visible per-task. If reception drops mid-upload, the file stays in the local cache and retries on reconnect.
Block — when work cannot continue
If the tech arrives and the vehicle is missing, locked behind a gate, or needs a part they don't have, they tap Block and pick a reason. The task moves to blocked and surfaces to the ops_manager on the dashboard with the block reason. Once the blocker is resolved, the manager (or the tech) moves it back to in_progress.
Decline — declining an assignment
If a task is pushed to a tech and they cannot do it (off shift, off zone), they tap Decline and pick a reason. The decline writes to task_assignments.declined_at and the task returns to the Created column for re-assignment. The ops manager sees the decline reason in the side drawer history.
Resolve and the verify gate
Tapping Resolve with an "after" photo attached moves the task to resolved. Note that the tech cannot tap Verify themselves — that's gated to ops_manager and lead_tech to prevent juniors signing off their own work.
The vehicle stays in maintenance until verify. This is intentional: a tech who quickly resolves a task they didn't actually finish should not be able to put the vehicle back into service.
Offline queue
Field techs often work in basements, parking garages, and Mexican beach towns where reception is spotty. The Tasks tab is built to keep working through it.
- Reads — the latest tasks list is cached in AsyncStorage; tapping a row works while offline using the cached detail
- Writes — Accept, Start, Resolve, photo upload, and notes all enqueue locally and replay through
/api/operator/tasks/syncwhen the app comes back online - Conflicts — server-wins on status (if the manager closed the task while the tech was offline), client-wins on photos and notes (so the tech's evidence is never lost)
The sync replay is idempotent and bounded — each queue entry is retried up to 5 times before surfacing an error to the user.
Push notifications
Three notification types land on a tech's phone:
| Trigger | Channel |
|---|---|
| Task assigned to me | Expo push |
| Nearby unclaimed task > 10 min old | Expo push |
| SLA breach on my task | Expo push + email |
Notifications respect the device's quiet hours and the tech's notification preferences in Settings → Notifications.
Train your junior techs on Block
The most common mistake junior techs make is resolving a task to "get it off the list" when they couldn't actually complete it. Train the team to tap Block early. A blocked task with a clear reason is much better data than a falsely resolved one.