# Argus Airsoft — mobile client guide (iOS + Android) > Native apps consume the HTTP API and WebSockets only. Do not port the Next.js web app, MCP, or admin scripts. API version: **0.8.2** OpenAPI: https://argusairsoft.com/openapi/argus.openapi.yaml Health: https://argusairsoft.com/api/health SDK: `packages/argus-sdk` (TypeScript reference) Operator: MR Dula Enterprise, LLC · matt@mrdula.solutions Repository: https://github.com/mrdulasolutions/argusairsoft --- # Mobile apps (iOS + Android) — agent playbook **Read this before building native clients.** This monorepo is primarily a **Next.js web app** on Cloudflare. iOS and APK are **separate native projects** that consume the **HTTP API and WebSockets** — not the web UI, MCP server, or admin scripts. | Doc | Purpose | | --- | --- | | [README.md](README.md) | Platform overview | | [../ROADMAP.md](../ROADMAP.md) | Web vs mobile feature columns | | [features/team-field-ops.md](features/team-field-ops.md) | Future TAK-style mobile spec | | [ios/README.md](ios/README.md) | iOS-specific notes | | [android/README.md](android/README.md) | Android / APK notes | --- ## Golden rules 1. **Do not port the website.** No Next.js routes, no `src/app/` pages, no web layout components in native apps. 2. **Do not embed MCP on device.** MCP (`mcp/argus-airsoft`) is for desktop agents and ops tooling only. 3. **Use the API contract.** `openapi/argus.openapi.yaml` + `packages/argus-sdk` (TypeScript) or generate native clients from OpenAPI. 4. **Auth via Clerk mobile SDK** — same Clerk instance as web; session JWT on `Authorization: Bearer`. 5. **API paths are not locale-prefixed.** Call `/api/...` and `/ws/...` directly (not `/en/api/...`). 6. **Put native code under `platforms/mobile/`** (or a sibling package), never under `src/`. 7. **New mobile-only APIs** get spec'd in `platforms/mobile/features/` first, then added to OpenAPI. --- ## What belongs in mobile apps ### Player app (MVP — build first) | Feature | API / realtime | Notes | | --- | --- | --- | | Sign in / sign up | Clerk iOS / Android SDK | 13+ per Terms | | Field directory + search | `GET /api/fields` (`country`, `state`, `q`, `live`) | Map optional native (MapKit / Google Maps) | | Field detail | `GET /api/fields/{slug}` | Address, hours, contact, description | | Honor check-in / out | `POST /api/fields/{slug}/checkin`, `checkout` | Auth required | | Live field roster | `GET /api/fields/{slug}/presence`, `WS /ws/fields/:fieldId` | Callsigns only — never emails | | Public events | `GET /api/events`, `GET /api/fields/{slug}/events` | | | Player profile | `GET/PATCH /api/me` | Bio, class, unit, Discord, home field. Callsign / roster visibility fans out live to team rooms and the checked-in field roster. | | Check-in history | via `/api/me` | | | Gear locker | `GET/POST/PATCH/DELETE /api/me/gear` | Optional PDF export can stay web | | Teams directory | `GET /api/teams`, `GET /api/teams/{slug}` | Public team cards | | My teams / join | `GET /api/teams/mine`, `POST /api/teams/join` | | | Team HQ | `GET /api/teams/me`, messages, assignments, notifications | Alert reads are per-user (`team_notification_reads`). Mark-read no longer dismisses for the whole unit. | | Team reports | `GET/POST /api/teams/{slug}/reports`, `PATCH .../reports/{id}` | CASEVAC 9-line, SITREP, SALTA, TIC — pin required; iOS falls back to map center. Ack/Close for author or command only. GET returns `canManage` + `viewerId`. | | Packing lists | `GET/PATCH /api/teams/{slug}/lists` | Published lists download as PDF on web | | Team comms (realtime) | `WS /ws/teams/:teamId?token=` | Signed subscribe token from `GET /api/teams/{slug}/ws-token`. Reconnect/backoff is mobile-specific. | | Push notifications | Platform APNs / FCM | Stretch for MVP; poll first | ### Team field ops (later — not MVP) Spec: [features/team-field-ops.md](features/team-field-ops.md) - Live team GPS map and richer file sharing beyond comms attachments - Reports, org, packing lists, and join requests **are already in OpenAPI 0.8+** and the iOS client - TAK-style field ops still need extra location APIs — not a reason to skip shipped report endpoints --- ## Web-only — do NOT build in iOS/APK These stay in the **browser** or **agent/ops tooling**. Link out to web URLs when needed; do not reimplement. | Area | Why web-only | | --- | --- | | **Advertise / ad network** | `/advertise`, sponsor inquiries, `POST /api/ads/inquiries` — sales funnel for operators, not players | | **Ad sidebar on field pages** | `GET /api/ads/active` — web monetization; optional deep link to `/advertise` only | | **Field owner dashboard** | My Field tab: full listing editor, structured hours UI, private events management | Owners can use **mobile browser** to `/me?tab=myField` until a dedicated owner app is scoped | | **Field ownership claims** | `POST /api/fields/{slug}/claim` — review workflow is manual; web form is enough for v1 | | **Field intel / verify submissions** | Community corrections via web verify panel + agent CLI (`npm run intel:*`) | | **Admin / ops scripts** | `npm run claims:*`, `npm run ads:*`, `npm run db:*`, seed scripts — never ship in app binary | | **MCP server** | `mcp/argus-airsoft` — dev/agent tooling only | | **AI discovery pages** | `/llms.txt`, OpenAPI hosting — for agents, not end users | | **Operator display modes** | Day/night/red-light dial — web authenticated shell UX | | **Web SaaS shell layout** | Left nav + marketing pages, hero video, footer — native apps use native navigation | | **Legal hosting** | Privacy/Terms are web pages; in-app: link to `https://argusairsoft.com/en/privacy` or render WebView | | **Gear locker PDF print** | Web `window.print` flow; mobile can skip or share sheet later | **Rule of thumb:** If it is **revenue, admin, agent CLI, or web chrome**, it stays on web. If it is **something a player does at a field or with their team**, it belongs in mobile. --- ## Shared backend (consume, don't duplicate) | Asset | Location | Mobile usage | | --- | --- | --- | | OpenAPI | `openapi/argus.openapi.yaml`, `/openapi/argus.openapi.yaml` | Generate or hand-bind clients | | TypeScript SDK | `packages/argus-sdk` | Reference; use for RN shared logic or port types | | API version | `GET /api/health` | Check compatibility on app launch | | D1 schema | `migrations/` | Read-only context; never bundle SQLite from web | | Legal copy | `src/content/legal.ts` | Do not copy verbatim into app without legal review; link to web | --- ## Authentication ``` Authorization: Bearer ``` - Public reads: fields list, field detail, public events, team directory — **no token** - Mutations: check-in, profile, gear, team ops — **token required** - Refresh / session lifecycle: Clerk mobile SDK handles it --- ## Realtime | Channel | Path | Use | | --- | --- | --- | | Field presence | `wss:///ws/fields/:fieldId` | Subscribe-only. Live count + roster (including callsign updates). Writes go through HTTP check-in / `PATCH /api/me`. | | Team HQ | `wss:///ws/teams/:teamId` | Signed token required. Comms, reports, and live `{ type: "profile" }` events. Public POST /broadcast is locked. | Mobile must implement **reconnect, background pause, and battery-aware polling fallbacks** — not copied from web hooks. --- ## Internationalization Web UI uses `/{locale}/...` (en, es, de, pl). Mobile can: - Use device locale for **app strings** (native i18n) - Pass `Accept-Language` if API adds localized fields later - Field **content** (descriptions, hours) is stored in DB as provided by operators — mostly English today --- ## Suggested build order 1. **Scaffold** — `platforms/mobile/ios` or `android` (or Expo monorepo under `platforms/mobile/`) 2. **Clerk auth** + token storage (Keychain / EncryptedSharedPreferences) 3. **Field directory + detail** + check-in (core loop) 4. **Profile + gear locker** 5. **Team HQ** (read roster, post messages, assignments) 6. **WebSockets** for field presence and team comms 7. **Team field ops** when API is designed (see feature spec) --- ## Project layout (future) ``` platforms/mobile/ ├── AGENTS.md ← this file ├── README.md ├── features/ ← mobile feature specs (API design first) ├── ios/ ← Xcode / Swift / Expo ios └── android/ ← Gradle / Kotlin / Expo android ``` Optional shared package: ``` packages/argus-mobile-core/ ← shared TS types, API client (future) ``` --- ## Discovery URLs for agents When coding mobile clients, prefer these over scraping HTML: | URL | Purpose | | --- | --- | | `/llms-mobile.txt` | This guide as plain text | | `/openapi/argus.openapi.yaml` | HTTP contract | | `/llms-full.txt` | Full platform guide (includes web + MCP — filter mentally) | | `/api/health` | Live API version | Repository: `https://github.com/mrdulasolutions/argusairsoft` --- ## Checklist before opening a mobile PR - [ ] No new files under `src/app/` for native UI - [ ] No MCP or wrangler scripts in app - [ ] API calls match OpenAPI (or document divergence in feature spec) - [ ] No advertiser / field-owner admin flows unless explicitly scoped - [ ] Privacy: location and photos only when feature requires it (field ops) - [ ] Terms (13+) and Privacy linked or in-app equivalent approved by operator