Skip to content

Brainstorm Session 7: Mobile Strategy

Date: 2026-04-15 Objective: Decide mobile companion app approach for Finnest Depends on: Sessions 1-6

Techniques Used

  1. Reverse Brainstorming — "How would mobile strategy guarantee failure?"
  2. Six Thinking Hats — Evaluate all options
  3. SCAMPER — Challenge "4 separate apps" assumption

Decision: Flutter (adapt existing) + Agent Chat + One App

One App Replaces Four

Old Plan New Plan
aCMS (employee companion) Finnest — Field Worker role
aAMS (asset management) Finnest — Asset Manager role
aTask (task management) Finnest — Supervisor role
aTeam (team management) Finnest — Supervisor role

One codebase, one App Store listing, role-based feature visibility.

Why Flutter

  1. Existing Flutter app (v5.0.4) proves NFC, GPS, push, BLoC architecture
  2. Bounded polyglot cost (~5-10K LOC of Dart vs 150K+ LOC Elixir backend)
  3. All native features supported and mature (NFC, QR, GPS, offline SQLite, camera, biometrics)
  4. Cross-platform iOS + Android from single codebase
  5. Adapt existing code rather than rewrite from scratch

Why NOT Others

Framework Disqualifier
LiveView Native Can't handle NFC, offline SQLite, background location reliably. Experimental.
React Native Ecosystem churn risk. Bridge architecture. Fourth language (JS).
KMP + Compose No code sharing with Elixir backend. iOS compose still maturing.
PWA Can't do NFC. Weak App Store presence for enterprise MDM.

App Architecture

FINNEST MOBILE APP (Flutter)
├── Agent Chat (primary interaction)
│   └── "Clock me in" → NFC/GPS → recorded
│   └── "My roster?" → roster card
│   └── "Leave request" → creates + routes for approval
│   └── "Approve timesheets" → batch processing
├── Native Features
│   ├── Clock In/Out (NFC tag, QR code, GPS geofencing)
│   ├── Background Location streaming
│   ├── Camera (document upload, incident photos)
│   ├── Push Notifications (Firebase)
│   ├── Biometric Auth (fingerprint, face)
│   └── Offline Queue (SQLite event store)
├── Role-Based Screens
│   ├── Field Worker: roster, time cards, leave, notifications, profile
│   ├── Supervisor: + team view, approvals, shift assignment, tasks
│   ├── Asset Manager: + equipment status, maintenance, vehicle tracking
│   └── Client Contact: assigned workers, roster view, placement requests
└── Offline Sync Engine
    ├── SQLite event queue (actions stored as events)
    ├── Automatic sync when online
    ├── Conflict resolution (server wins roster/approval, client wins clock)
    └── Last-sync timestamp per entity type

Connection to Backend

  • REST API: Phoenix JSON API (/api/v1/*) for CRUD operations
  • WebSocket: Phoenix Channel for real-time (notifications, roster updates, location)
  • Agent API: Same orchestrator as web, consumed via REST
  • Auth: JWT token with refresh, biometric unlock for stored token

Offline Strategy

What Works Offline

Feature Offline Support Notes
Clock in/out Yes Stored in SQLite, synced when online
View roster Yes (cached) Last-synced roster data
Time card entry Yes Queued for sync
Leave request Yes Queued for sync
View notifications Yes (cached) Cached list, no new ones offline
Agent chat No Requires backend connection
Approvals No Requires server state
Document upload Queued Photo taken, upload queued

Sync Protocol

Online → Offline:
  Cache: current roster, employee profile, recent notifications
  Store to: SQLite local database

Offline → Online (sync):
  POST /api/v1/sync
  Body: { events: [ordered list of offline events with timestamps] }
  Response: { 
    confirmations: [event_ids confirmed],
    conflicts: [{ event_id, resolution, server_state }],
    updates: [new server events since last_sync]
  }

Conflict Resolution:
  Clock events: CLIENT wins (timestamp is authoritative — worker was there)
  Roster changes: SERVER wins (supervisor may have changed roster while worker offline)
  Leave requests: SERVER decides (may already be approved/rejected)
  Time card entries: MERGE (client data + server validation)

Event Queue (SQLite)

CREATE TABLE offline_events (
  id TEXT PRIMARY KEY,
  event_type TEXT NOT NULL,     -- clock_in, timecard_entry, leave_request
  payload TEXT NOT NULL,        -- JSON
  created_at TEXT NOT NULL,     -- ISO 8601
  synced_at TEXT,               -- NULL until synced
  sync_status TEXT DEFAULT 'pending'  -- pending/synced/conflict/failed
);

Agent Chat on Mobile

Primary Interaction Pattern

Agent chat is the HOME SCREEN. Traditional screens are one tap away.

┌──────────────────────────┐
│  Finnest                 │
│  Good morning, John      │
│                          │
│  Your shift: 6AM-2PM     │
│  Woolworths Minchinbury  │
│  [Clock In]              │
│                          │
│  ─────────────────────   │
│                          │
│  💬 Ask me anything...   │
│                          │
│  Quick actions:          │
│  [Roster] [Leave] [Time] │
│                          │
└──────────────────────────┘

Example Interactions

"Clock me in"
  → Agent: checks NFC → "Scan your tag" → clock recorded
  → "Clocked in at 6:02 AM. Shift ends 2:00 PM."

"Swap Thursday with Sarah"
  → Agent: checks Sarah's availability, both rosters, compliance
  → "Sarah is available Thursday. I'll request the swap."
  → Creates swap request, notifies supervisor

"I had an incident on site"
  → Agent: "What happened? I'll start an incident report."
  → Guides through: what, when, where, who, injury?, photos?
  → Creates safety.incident record, notifies safety officer

"My forklift cert expires soon"
  → Agent: "Your forklift license expires June 15. I can help schedule renewal."
  → Links to training provider or notifies compliance team

Fallback to Screens

Agent can't handle everything. Complex interactions fall back: - Multi-field time card entry (multiple lines, allowances) → TimeCard screen - Detailed roster calendar view → Roster screen - Profile editing (address, bank details, emergency contact) → Profile screen - Document upload with metadata → Upload screen


Migration from Current Flutter App

What to Keep

  • BLoC state management architecture
  • GoRouter navigation pattern
  • NFC implementation (nfc_manager)
  • GPS/Location service (geolocator)
  • Push notification setup (Firebase)
  • Dio HTTP client pattern

What to Change

  • API endpoints: v2 CodeIgniter → Finnest Phoenix API (/api/v1/*)
  • Auth: custom token → JWT with refresh
  • Add: SQLite offline event queue (drift or sqflite)
  • Add: Agent chat interface (new)
  • Add: Role-based navigation (replace static menu)
  • Add: Asset management screens (new)
  • UI: Update to match Finnest design system (DaisyUI-inspired)
  • Remove: v2-specific workarounds and legacy patterns

Estimated Effort

  • API migration: 2 weeks
  • Offline sync engine: 2 weeks
  • Agent chat interface: 1 week
  • Role-based navigation: 1 week
  • Asset management screens: 1 week
  • UI refresh: 1 week
  • Testing + App Store submission: 1 week
  • Total: ~8-10 weeks

IRAP Mobile Considerations

IRAP deployment mobile restrictions: - No Google OAuth (Microsoft Entra ID only) - No Firebase Analytics (use privacy-safe alternative or disable) - FCM for push is acceptable (notification payload encrypted, no PII in push content) - App must enforce: PIN/biometric lock, 5-min idle timeout, remote wipe capability - MDM (Mobile Device Management) deployment via Intune - Separate app build with IRAP feature flags (same codebase, different build config)


Key Insights

Insight 1: One App, Four Roles Replaces Four Apps

4x reduction in maintenance. Role-based visibility + org module flags. Impact: High | Effort: Low

Insight 2: Flutter Is Pragmatic — Adapt, Don't Rewrite

Existing code proves NFC, GPS, push. Bounded polyglot cost. Impact: High | Effort: Medium (~8-10 weeks)

Insight 3: Offline Event Queue Maps to Backend Events

Mobile SQLite events → sync → backend domain events. Same mental model. Impact: High | Effort: Medium

Insight 4: Agent Chat Is the Mobile Differentiator

No HR app has an agent as the primary mobile interface. Traditional screens as fallback. Impact: High | Effort: Medium

Insight 5: Mobile Collects, Web Manages

Field workers capture (clock, photos, incidents). Managers manage (approve, schedule, report). Don't replicate web on mobile. Impact: Medium | Effort: Low

Insight 6: LiveView Native Is Future Option

If it matures for NFC/offline, migration possible. Clean API layer keeps mobile client swappable. Impact: Low | Effort: Low


Statistics

  • Total ideas: 25+
  • Categories: 5 (Framework, App Structure, Offline, Agent Chat, Migration)
  • Key insights: 6
  • Techniques applied: 3

→ Session 8: Integration Strategy (what the mobile app connects to) → Design Phoenix API contract for mobile (/api/v1/* endpoints) → Prototype offline sync engine in Flutter → Build agent chat UI component


Generated by BMAD Method v6 - Creative Intelligence