# Mobile Field Readiness

> Take a mobile app or PWA feature from "works on my laptop" to "works on a phone in the field" — camera, GPS and geofencing, permissions, install and update, poor signal, one-handed use. Use when building or reviewing anything a person uses standing up, outdoors, on their own device.

- Skill: `chinthakat/mobile-field-readiness` (Agent Skill)
- Install (CLI): `npx skillmds@latest add chinthakat/mobile-field-readiness`
- Raw SKILL.md: https://api.skillmd.com/api/skills/chinthakat/mobile-field-readiness/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: chinthakat (https://skillmd.com/u/chinthakat)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/chinthakat/mobile-field-readiness

---


# Mobile field readiness

A desktop browser at a desk on wifi is the least representative test environment
available. The failures below do not appear there at all.

## 1. Secure context first, because it silently gates everything

Camera, microphone, geolocation, service workers and notifications require
HTTPS. `localhost` is exempt, which is exactly why this gets discovered late:
everything works on the dev machine and nothing works the moment you open the
LAN address on a real phone.

```
http://localhost:5173        camera works    (localhost exemption)
http://192.168.1.42:5173     camera silently unavailable
https://<tunnel>.trycloudflare.com  camera works
```

Set up a real HTTPS path for device testing on day one — a local certificate
tool or a tunnel — and put the command in the README. Otherwise every person who
joins loses an afternoon to it.

## 2. Test on a real device early, and on a cheap one

Desktop responsive mode gets you layout and nothing else. It does not reproduce:

- Touch versus mouse, and the absence of hover.
- The on-screen keyboard covering the field being typed into, and the viewport
  resize that follows.
- Safe areas: notches, rounded corners, the home indicator, the URL bar that
  appears and disappears as you scroll.
- Real camera latency and real photo file sizes.
- Memory pressure — a mid-range Android will kill a tab that a laptop runs
  comfortably.
- Sunlight, which makes low-contrast greys invisible.

Test on the worst device your users actually have, not the newest one you own.

## 3. Every permission has a denied path, and it is permanent

Camera, location and notifications can be denied, denied permanently, or
restricted by policy. On iOS a second prompt is often not shown at all.

For each one:

- Explain **before** prompting why you need it, in context, at the moment it is
  needed. A prompt on first launch with no explanation gets denied.
- Handle denial with something usable — upload from the gallery instead of the
  camera, type an address instead of using GPS.
- When denied permanently, say so and point at the OS settings. "Location
  unavailable" leaves the user stuck; "Location is off for this site — turn it
  on in Settings > Safari > Location" does not.
- Never block the whole flow on an optional permission.

## 4. GPS is approximate, and you must decide how approximate is acceptable

A position comes with an **accuracy radius**, and it is routinely 20–50 m
outdoors and much worse indoors, near tall buildings, or on a device with wifi
positioning only.

- Read `accuracy` and use it. A check-in inside a 100 m geofence with 500 m
  accuracy has not been verified by anything.
- Size the geofence for the site, not for the map pin. Loading docks, car parks
  and multi-building sites need a bigger radius than feels right.
- Take the first fix, then watch for a better one — the first is often the
  coarse network fix, with the GPS fix arriving seconds later.
- **Verify on the server.** Coordinates from a client are a claim, not a fact;
  any of them can be spoofed. Decide whether that matters for your use, and if
  it does, treat GPS as one signal among several rather than proof.
- Provide a manual override with a reason, and log it. Otherwise a genuine
  failure leaves a worker unable to do their job.

## 5. Service worker updates are the top support issue

A cached shell that will not update produces "I see the old version" reports that
are impossible to reproduce, because the reporter's device is the only one
affected.

- Serve the entry document and the service worker with no-cache; serve hashed
  assets with long cache. Backwards, and users are pinned on a broken build.
- Have an update path: detect the new worker, then either prompt ("A new
  version is ready — reload") or skip waiting and reload, but choose one and
  test it.
- Never cache API responses in the same policy as the shell.
- Be able to answer "which build is this user on?" — put the build id in the UI
  and in error reports.
- Test the upgrade, not just the install: load the old version, deploy, reload,
  confirm the new one arrives.

## 6. Design for one hand, outdoors, in a hurry

- Primary actions in the bottom third, where a thumb reaches.
- Touch targets at least 44×44 px with real spacing. Two destructive actions
  should never be adjacent.
- High contrast; do not rely on colour alone for state.
- Never lose typed input on rotation, backgrounding, or an incoming call.
- Confirm destructive actions, and make them undoable where you can.
- Keep the primary flow reachable in as few taps as possible. Count them.

## 7. Throttle rather than disconnect

The field is rarely cleanly offline. It is 2G, a half-open connection, a
captive portal, or a connection that accepts the request and never answers.

- Test at "slow 3G" throttling, not just offline.
- Set request timeouts. A hung fetch with no timeout is an app that appears
  frozen.
- Show progress for anything over a second, and make it cancellable.
- Retry with backoff; give up and tell the user rather than spinning forever.

If the flow must survive a real loss of coverage, that is a design decision on
its own — see `offline-first-sync`.

## 8. Battery, data and storage are the user's, not yours

- Continuous GPS drains a battery in hours. Sample, do not stream, and stop
  when backgrounded.
- Downscale photos on capture. A modern phone camera produces files that are
  both slow to upload on 3G and expensive on a metered plan.
- Cap local caches and evict.
- Release the camera and any wake lock the moment the screen is left.

## Checklist

- [ ] HTTPS available for device testing, documented in the README
- [ ] Tested on a real, low-end device
- [ ] Every permission has an explanation, a denied path and a permanent-denial message
- [ ] GPS accuracy read and acted on; geofence sized for the site; server-side check; manual override logged
- [ ] Service worker update path tested by upgrading, not installing
- [ ] Build id visible in the UI
- [ ] Reachable one-handed; 44 px targets; no input lost on rotate or background
- [ ] Tested throttled, not only offline; timeouts on every request
- [ ] Photos downscaled; GPS sampled; caches capped

