Meridian Field Services: instructional example, not project evidence
Why considered: the technician app is assignment lists, confirmations, and push receipt (standard CRUD-and-notification, no high-frame-rate graphics or deep platform-extension need); native would double the build for a four-screen app one team maintains; a PWA cannot receive background push reliably on the fleet's iOS devices. Who & how: E. Sandoval with the UX owner, weighed against the capability list July 17; the Airbnb React-Native retro reviewed as the cautionary case (its friction came from a large heterogeneous surface this small app does not have) (mobile platform[1]).
Minimum versions with device-share evidence: iOS 16 and Android 11 cover 96% of the technician fleet's actual devices (the MDM inventory, attached: device inventory[2]); "latest minus two" was rejected for evidence. Distribution: enterprise distribution, not the public stores; release cadence rides the pipeline's build without the public-review wait (deployment strategy[3]), cited.
| Capability | Permission | Denial fallback | iOS / Android divergence |
|---|---|---|---|
| Location (arrival confirmation) | when-in-use | Manual "I've arrived" button, no auto-detection, explanation + Settings link; never a hard error | iOS suppresses the dialog permanently after one denial (Settings is the only recovery); Android allows re-prompt until "don't ask again" |
| Notifications (assignment push) | alert | The in-app list still polls on open (rejected-to-polling[4]); a denied push degrades to poll, not silence | iOS requires the explicit grant; Android 13+ now does too |
| Camera (proof-of-service, phase 2) | camera | Skip the photo; the assignment still completes | Standard |
Request timing: CONTEXTUAL: the location prompt fires on the first arrival confirmation with a soft pre-prompt explaining why, never at launch; a cold launch prompt burns the one iOS grant and converts far worse, the named anti-pattern.
The model is named, never left implicit for the first tunnel to reveal.
Why: a technician in a basement or a rural gap must SEE their assignment list (read cache) and confirm arrival (a queued mutation), but must NOT create or reassign work offline (dispatch authority is the board's, and an offline reassignment would race the live state the realtime spec reconciles, reconciliation[4]); offline-first's local-write model would invite exactly that conflict.
| Screen / action | Offline behavior |
|---|---|
| Assignment list | Reads from cache |
| Assignment detail | Cached |
| Arrival confirmation | Writes offline, queued |
| Reassignment / override | BLOCKED offline: a clear "requires connection" state |
Sync & conflict: the queued confirmation replays on reconnect with an optimistic version check (concurrency[5]); if the assignment was reassigned away while offline (the race the blocking rule mostly prevents), the confirmation returns stale_version and the technician sees "this job was reassigned" (error registry[6], EC-03[7]). Mutations queue-and-retry with backoff, never a silent drop.
The desktop list is the inventory (register[8]); this owns the divergence.
| Screen | Mobile treatment · rationale |
|---|---|
| SCR-001 dispatch board | NOT on mobile: dispatching is a desk activity; technicians do not dispatch |
| SCR-002 assignment list | Mobile primary: condensed thumb-zone list, secondary actions deferred behind a detail tap; touch targets at the 48dp Android minimum (the larger of the two for the cross-platform build); states cited (state machines[9]) |
| SCR-003 intake | NOT on mobile: intake is dispatcher-side |
| Arrival confirmation | A mobile-ONLY screen, no desktop analogue; a mobile addition, not a delta |
Gestures: pull-to-refresh on the list, swipe-to-confirm on an assignment (with a button fallback for the a11y contract, AT matrix[10]). Shared contracts: the mobile client consumes the same endpoints (endpoints[6]); the ONE named divergence: the list endpoint returns a trimmed payload for bandwidth (no position history), flagged here, not silently introduced. A one-to-one desktop port was flagged and rejected per screen; no shrunken board.
| Question | Owner | Answer by | Blocks |
|---|---|---|---|
| Does the phase-two proof-of-service photo need offline capture with deferred upload, or is it connection-required like reassignment (scopes the offline matrix's camera row)? | Product owner with E. Sandoval | At the phase-two scoping | The camera capability's offline treatment only |