Brainstorm Session 7: Mobile Strategy¶
Date: 2026-04-15 Objective: Decide mobile companion app approach for Finnest Depends on: Sessions 1-6
Techniques Used¶
- Reverse Brainstorming — "How would mobile strategy guarantee failure?"
- Six Thinking Hats — Evaluate all options
- 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¶
- Existing Flutter app (v5.0.4) proves NFC, GPS, push, BLoC architecture
- Bounded polyglot cost (~5-10K LOC of Dart vs 150K+ LOC Elixir backend)
- All native features supported and mature (NFC, QR, GPS, offline SQLite, camera, biometrics)
- Cross-platform iOS + Android from single codebase
- 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
Recommended Next Steps¶
→ 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