# UCall Flutter App — Product Requirements Document (PRD) & Technical Architecture

**Version:** 2.0 (Local-First Architecture)  
**Status:** Approved for Implementation  
**Platforms:** Android and iOS  
**Frontend Framework:** Flutter + Dart  
**Backend:** Existing UCall Rust Control Plane, MySQL/MariaDB & Redis  
**Calling Engine:** Native Cellular Fallback (`tel:`) + In-App VoIP (WebRTC / STUN / TURN)  
**Messaging Engine:** Carrier SMS + UCall Internet Chat (E2EE)  
**Local Database:** SQLite with Drift & SQLCipher (Local-First Source of Truth)  
**Design Reference:** UCall Design Specification & Brand Assets  

---

## Executive Summary & Product Goal

Build a **WhatsApp-like communication application** that opens instantly, feels as responsive as the native phone dialer and contacts app, and remains fully functional and responsive when the internet is slow, degraded, or completely disconnected.

### The Core Architectural Principle: Local-First, Not API-First
The app must render entirely from local storage immediately upon launch. Live APIs and WebSockets synchronize data in the background; they **must never block** the initial screen, contact list, recent calls, conversation views, or locally cached messages.

```
┌─────────────────────────────────────────────────────────────┐
│                         Flutter UI                          │
│        Instant Screens · Local State · Zero API Wait        │
└──────────────────────────────┬──────────────────────────────┘
                               │ Reads/Observes (Streams)
                               ▼
┌─────────────────────────────────────────────────────────────┐
│                 Repository / Domain Layer                   │
│        Local Reads · Outbox Engine · Conflict Resolver      │
└──────────────┬──────────────────────────────┬───────────────┘
               │ Write/Read                   │ Queue/Sync
               ▼                              ▼
┌─────────────────────────────┐┌──────────────────────────────┐
│       Local Database        ││         Sync Workers         │
│   SQLite · Drift · Indexed  ││  REST APIs · WebSocket       │
│      SQLCipher Encrypted    ││  Durable Outbox & Retry      │
└─────────────────────────────┘└──────────────┬───────────────┘
                                              │ TLS / WSS
                                              ▼
                               ┌──────────────────────────────┐
                               │     UCall Rust Backend       │
                               │   MariaDB/MySQL + Redis      │
                               └──────────────────────────────┘
```

---

## 1. Product Objectives

1. **Instant Launch:**  
   Show the usable app shell and cached content without waiting for network requests, tokens, or profile handshakes.
2. **Local-First Data:**  
   Contacts, recent calls, conversations, messages, settings, drafts, and pending actions are stored durably in the local database.
3. **Offline Operation:**  
   Cached data remains fully readable and searchable offline. Supported actions (messages, drafts, read receipts) are queued locally until connectivity returns.
4. **Background Synchronization:**  
   WebSocket events and background APIs update local storage incrementally without blocking or rebuilding the UI.

---

## 2. Mandatory Performance Requirements

| Operation | Acceptance Target |
|---|---|
| **Display app shell after process launch** | Within **300 ms** |
| **Display cached home screen and navigation** | Within **500 ms** |
| **Display cached recent calls or conversations** | Within **500 ms** after opening the section |
| **Open a locally cached conversation** | Within **200 ms** |
| **Search locally indexed contacts/messages** | Within **300 ms** for typical datasets |
| **Initial usable UI with no internet** | **Zero network dependency** |
| **Background synchronization** | **Never blocks initial rendering or scroll performance** |
| **Pending outgoing messages** | **Persist locally in outbox before sending** |

*Note: Cold start and warm start must be measured and validated on low-, mid-, and high-tier Android and iOS physical devices.*

---

## 3. Technology Stack & Component Requirements

| Component | Technology Choice | Requirement / Rule |
|---|---|---|
| **Frontend Framework** | Flutter (Dart 3.x) | Android (minSdk 24) and iOS (13.0+) |
| **Local Database** | SQLite via **Drift** | Type-safe queries, schema migrations, indexed access |
| **Local Data Protection** | **SQLCipher** / Platform Keystore | Encrypted database on device |
| **Key Storage** | Android Keystore / iOS Keychain | `flutter_secure_storage` for cryptographic tokens |
| **State Management** | **flutter_riverpod** | Reactive, predictable state separated from UI |
| **Navigation** | **go_router** | Declarative navigation with persistent bottom navigation shell |
| **API Transport** | **REST over HTTPS** (`dio`) | Authenticated, idempotent with retry policies |
| **Live Updates** | **Authenticated WebSocket** | Real-time events, presence, receipts, typing indicators |
| **Background Retry** | **Durable Database Outbox** | WorkManager / BGAppRefresh background tasks |
| **Media Calling** | **WebRTC + STUN/TURN** | Low latency, crystal-clear audio, dynamic bitrate |
| **Backend System** | **UCall Rust Control Plane** | MySQL/MariaDB durable store, Redis transient cache |

> [!IMPORTANT]
> **Database Rule:** SQLite is the user's durable local application state. Redis remains a transient backend caching service and must never be treated as the sole store for messages or durable state.

---

## 4. Instant-Launch Sequence & Startup Rules

### Startup Sequence
```
1. Render App Shell
   └── Load theme, navigation structure, icons, and cached layout.
       (Do not wait for login refresh, contact sync, or WebSocket)
2. Open Local Database
   └── Lightweight, indexed initialization without full-table scans.
3. Render Cached Data
   └── Show recent calls, conversation previews, unread badges, contacts.
4. Start Background Synchronization
   └── Validate session, connect WebSocket, refresh cursors, drain outbox.
5. Apply Updates Incrementally
   └── Update affected UI items via reactive streams. Never clear the screen during refresh.
```

### Startup Rules
- **No blocking splash screen:** Do not wait for a live API response before displaying the main shell.
- **No blocking spinners:** Render cached data immediately; show subtle background sync indicators if needed.
- **No full database downloads on launch:** Use paginated, cursor-based delta sync.
- **No remote avatar dependencies:** Use cached image thumbnails or initial letter fallback badges.
- **No synchronous network calls in UI init:** All API calls are decoupled and asynchronous.
- **No forced logout when offline:** Preserve local data and show an offline banner.
- **Session expiration policy:** Preserve accessible local data and request reauthentication only for server-dependent actions.

---

## 5. Local Data Storage Specification

The local SQLite database is the immediate source of truth for rendering.

### Database Schema (Collections / Tables)

| Table | Purpose & Key Columns |
|---|---|
| `local_profile` | User profile, UCall ID, phone number, display name, preferences, status. |
| `contacts` | `contact_id`, `name`, `phone_number`, `ucall_id`, `is_favorite`, `avatar_local_path`, `updated_at`. |
| `conversations` | `conversation_id`, `title`, `channel` (ucall/sms), `last_message_preview`, `last_timestamp`, `unread_count`, `is_pinned`. |
| `messages` | `message_id` (UUID), `conversation_id`, `sender_id`, `ciphertext`, `delivery_status`, `created_at`, `server_timestamp`. |
| `recent_calls` | `call_id`, `caller_name`, `phone_number`, `call_type` (cellular/voip), `direction` (incoming/outgoing/missed), `duration_sec`, `timestamp`. |
| `message_outbox` | `outbox_id`, `client_message_id`, `conversation_id`, `payload`, `retry_count`, `next_retry_at`, `status`. |
| `operation_outbox`| `op_id`, `op_type` (read_receipt/call_log/profile_update), `payload`, `created_at`. |
| `sync_state` | `stream_id`, `last_synced_cursor`, `last_sync_timestamp`, `recovery_state`. |
| `device_keys` | Cryptographic public identity keys, prekey references (private keys held in Secure Hardware). |
| `attachments` | `attachment_id`, `local_path`, `mime_type`, `file_size`, `encryption_key`, `download_status`. |
| `app_settings` | Theme mode, notification preferences, audio routing defaults, onboarding flag. |

### Database Integrity & Performance Rules
- **Indexing:** Indexes on `conversation_id`, `message_id`, `created_at`, `contact_name`, and normalized `phone_number`.
- **Transactions:** Atomic transactions for message insertion + outbox insertion + cursor advancement.
- **Pagination:** Message history and call logs must load in bounded slices (e.g., 30 items per page).
- **Sensitive Data:** Tokens and private keys stored strictly in Android Keystore / iOS Keychain.

---

## 6. Offline & Online Behavioral Matrix

| Feature | Offline Behavior | Online Behavior |
|---|---|---|
| **App Launch** | Opens immediately (<300ms) with cached data | Opens immediately (<300ms); syncs delta in background |
| **Dialer Keypad** | Fully interactive; searches local contacts | Fully interactive; searches contacts and resolves UCall IDs |
| **Cellular Calls** | Hands off number to native phone dialer via `tel:` | Hands off to native dialer via `tel:` |
| **VoIP Calls** | Informs user internet connection is required | Initiates WebRTC signaling and media connection |
| **Chat Inbox** | Browse cached chats and search messages | Real-time message streaming and delivery badges |
| **Compose Message** | Saved to SQLite `messages` + `message_outbox` (marked `queued`) | Saved to local DB and sent immediately via WebSocket/REST |
| **Carrier SMS** | Opens system SMS composer with pre-filled content | Opens system SMS composer with pre-filled content |
| **Contacts** | View, edit, favorite, and search local contacts | Syncs with device and resolves UCall network status |

---

## 7. Messaging & Durable Outbox Architecture

When a user taps **Send**, the message is saved immediately to local storage and the outbox before any network attempt. Even if the application crashes or the device reboots, the message is guaranteed never to be lost.

### Message Send Flowchart
```mermaid
flowchart TD
    A[User presses Send] --> B[Generate Stable UUID client_message_id]
    B --> C[Encrypt Payload on Device E2EE]
    C --> D[Database Transaction: Insert message & outbox item]
    D --> E[Update UI Immediately: Status = queued]
    E --> F{Network Available?}
    F -- No --> G[Keep queued in Outbox: Await connectivity]
    F -- Yes --> H[Send via WebSocket / REST with Idempotency Key]
    H --> I{Server Acknowledged?}
    I -- Yes --> J[Persist Server Ack: Update status to sent]
    J --> K[Remove from Outbox Transactionally]
    I -- No / Timeout --> L[Schedule Exponential Backoff Retry with Same UUID]
    L --> F
```

### Message Status Lifecycle
```
[queued]  ──(Network ready)──► [sending] ──(Server Ack)──► [sent]
                                   │                           │
                            (Network Error)              (Recipient Ack)
                                   │                           ▼
                            [queued (retry)]              [delivered]
                                                               │
                                                         (User Opened)
                                                               ▼
                                                            [read]
```

### Outbox Reliability Rules
1. **Single Transaction:** Message insertion and outbox entry occur in a single local database transaction.
2. **Idempotency:** The client-generated `client_message_id` (UUID v4) prevents duplicate messages on the server.
3. **Graceful Retry:** Exponential backoff with jitter (1s, 2s, 4s, 8s, up to 60s) avoids server stampedes.
4. **Outbox Durability:** The outbox persists across app restarts, background kills, and device reboots.

---

## 8. Live Synchronization & Recovery Architecture

WebSockets deliver real-time events. If a connection drops, the app recovers missed data cleanly using persisted cursor tokens.

### Reconnect & Catch-Up Sequence
```mermaid
sequenceDiagram
    autonumber
    actor Client as UCall Mobile App
    participant LocalDB as SQLite (Local DB)
    participant SyncMgr as Sync & Outbox Worker
    participant Backend as UCall Rust Server

    Note over Client,Backend: Connectivity Restored / App Foregrounded
    SyncMgr->>Backend: Authenticate & Establish WebSocket
    Backend-->>SyncMgr: Connection Accepted
    SyncMgr->>LocalDB: Read last_synced_cursor
    LocalDB-->>SyncMgr: cursor_token_xyz
    SyncMgr->>Backend: GET /api/v1/sync?cursor=cursor_token_xyz
    Backend-->>SyncMgr: Return Missing Events (Paged Delta)
    SyncMgr->>LocalDB: Transaction: Persist events + Update last_synced_cursor
    LocalDB-->>Client: Reactive Stream updates visible UI components
    SyncMgr->>LocalDB: Fetch pending outbox records
    LocalDB-->>SyncMgr: Unsent messages & receipts
    SyncMgr->>Backend: Transmit outbox batch with idempotency IDs
    Backend-->>SyncMgr: Batch Acknowledgements
    SyncMgr->>LocalDB: Mark sent / delivered & prune outbox
```

---

## 9. Screens & Navigation Specifications

The application uses a persistent **StatefulShellRoute** with four primary tabs:

```
┌────────────────────────────────────────────────────────┐
│                      Top App Bar                       │
│  [Logo/Title]                   [Search] [Action Menu] │
├────────────────────────────────────────────────────────┤
│                                                        │
│                    Active Tab Body                     │
│               (Calls / Messages / Contacts / More)     │
│                                                        │
├────────────────────────────────────────────────────────┤
│                 Bottom Navigation Bar                  │
│   [📞 Calls]     [💬 Messages]   [👤 Contacts]  [⚙️ More] │
└────────────────────────────────────────────────────────┘
```

### A. Calls (Dialer & Recents)
- **Top Segmented Filter:** All Calls, Missed, Incoming, Outgoing.
- **Dialer Pad:** Responsive numeric keypad with instant DTMF feedback and backspace toggle.
- **Dual Call CTA:**
  - **Cellular Call:** Dispatches `tel:<number>` to the native phone dialer.
  - **UCall Internet Call:** Starts WebRTC call signaling via UCall servers.
- **Recent Calls List:** Cached in SQLite, displaying avatar direction badge, timestamp, duration, and tap-to-redial.

### B. Messages (Unified Inbox)
- **Unified List:** Chat conversations and SMS threads clearly distinguished with badges (`UCall Chat` vs `SMS`).
- **Instant Search:** Full-text search of cached conversations.
- **Chat Details:** Bubbles with sent/delivered/read status ticks, media support, and voice note recorder.

### C. Contacts & Favorites
- **Fast Indexed List:** A-Z fast scroller with real-time local search.
- **Favorites Bar:** Quick-dial avatars at top.
- **Identity Resolution:** Distinguishes contacts registered on UCall with a verified badge.

### D. More & Settings
- **Profile Card:** Avatar, display name, UCall phone number.
- **Settings Tiles:** Audio & Call routing, Notifications, Privacy & E2EE keys, Storage & Cache management, About UCall.

---

## 10. Visual Design Tokens & UI Guidelines

### Brand Colors
```
Primary Navy:       #061A3D   (Main background for Splash & Active Call)
Primary Blue:       #0866E8   (Primary CTA buttons, active tabs, highlights)
Deep Blue:          #00358F   (Gradients and dark accent elements)
Cyan Accent:        #00CFC8   (Glow elements, soundwave graphics, badges)
Success Green:      #21C878   (Call connect, online status, delivered ticks)
End Call Red:       #FF4545   (End call button, missed call indicator)
Background Light:   #F8FAFD   (Main screen background)
Surface Card:       #FFFFFF   (Cards, modals, elevated surfaces)
Text Primary:       #071A3D   (Headings, primary labels)
Text Secondary:     #697B99   (Subtitles, timestamps, placeholders)
Border Light:       #E3EAF4   (Dividers, card outlines)
```

### Component Guidelines
- **Modern Geometry:** 20px-24px rounded corners for cards; 28px pill buttons.
- **Micro-interactions:** Smooth animations (`Curves.easeInOutCubic`), spring floating badges, glowing ambient mesh backgrounds.
- **Safe Area Insets:** Comprehensive handling of notches, navigation gestures, and keyboards.

---

## 11. Universal Calling System (UCall): Architecture & Requirements

UCall operates like a familiar phone dialer while protecting users' real phone numbers and automatically choosing between internet VoIP calling and native cellular calling.

### Core Identity & Privacy Principles
1. **Unique 12-Digit UCall ID:** Every UCall account is assigned a unique, numeric 12-digit UCall ID starting with a non-zero digit (1-9).
2. **Indian Mobile Registration:** Users register using a verified Indian mobile number starting with 6, 7, 8, or 9.
3. **Dual-Input Dialer:** Users can dial either a 10-digit mobile number or a 12-digit UCall ID directly in the dialer.
4. **Automatic Routing:**
   - If recipient is a registered & reachable UCall user: UCall initiates an end-to-end encrypted internet call.
   - If recipient is not registered with UCall: UCall offers or initiates the native cellular calling flow (`tel:`).
5. **Absolute Privacy Guarantee:** The recipient's real mobile number is strictly private and **must never be exposed** in another user's UCall profile, dialer, or call screen when dialed via UCall ID.
6. **Legitimate SIM Handling:** SIM information is handled exclusively through permitted OS interfaces (`SubscriptionManager` / system defaults), never by secretly sniffing SIM data in the background. IMEI is never used as an account identifier.

---

### 1. Registration & SIM Setup

```mermaid
flowchart TD
    A[Open UCall] --> B[Enter Mobile Number starting with 6, 7, 8, 9]
    B --> C[Verify Number using SMS OTP]
    C --> D[Create Account & Assign Unique 12-Digit UCall ID]
    D --> E[Set Profile & Privacy Options]
    E --> F[Request Contact and Call-Related Permissions when needed]
    F --> G[Detect Supported SIM Subscriptions where permitted]
    G --> H{Multiple SIMs Available?}
    H -- Yes --> I[Offer SIM 1 / SIM 2 / SIM 3 Selection]
    I --> J[User Selects Preferred SIM]
    J --> K[Finish Setup]
    H -- No --> L[Use Available SIM or System Default]
    L --> K
```

#### Detailed Registration Rules
- **OTP Verification:** Verify user identity via carrier SMS OTP.
- **12-Digit Numeric UCall ID:** Generated deterministically on the backend, starting with 1-9 (e.g., `9845 1234 5678`), decoupled from the user's real phone number.
- **Privacy Separation:** The user's mobile number is encrypted at rest, access-controlled, and excluded from public directory lookups.
- **Preferred SIM Selection:** For dual-SIM devices on supported platforms (Android), allow the user to select their preferred outgoing cellular SIM. Users can change this preference anytime in Settings.
- **Internet-Only Mode:** If the user only intends to make UCall internet calls, SIM selection is optional and never blocks onboarding.
- **No IMEI As Identity:** An IMEI identifies hardware, not a person. UCall binds identity to verified phone numbers and 12-digit UCall IDs.

---

### 2. Dialer Behavior: Phone Numbers & 12-Digit UCall IDs

The dialer automatically identifies what the user entered without forcing manual mode switching:

```mermaid
flowchart TD
    A[User taps Call] --> B[Validate input]
    B --> C{12-digit UCall ID?}
    C -- Yes --> D[Resolve account privately]
    D --> E{Verified account and status?}
    E -- No --> F[Show unavailable or retry]
    E -- Yes --> G[Initiate UCall signaling]
    G --> H{Call session established?}
    H -- Yes --> I[Show active call]
    H -- No --> J[Privacy-safe fallback]
    C -- No --> K[Normalize full phone number]
    K --> L[Check verified local mapping]
    L --> M{Registered UCall user?}
    M -- Yes --> N{May cellular fallback reveal private number?}
    N -- Yes --> O[Block cellular fallback]
    N -- No --> P[Ask permission before cellular fallback]
    M -- No --> Q[Request native cellular call]
```

#### Input Resolution & Fallback Matrix
- **10-Digit Indian Mobile Number:**
  1. Check local SQLite identity mappings first (< 50ms).
  2. Resolve whether number belongs to a UCall account via backend batch lookup.
  3. If registered and reachable: launch **UCall Internet Call**.
  4. If registered but offline: present **Cellular Fallback Sheet**.
  5. If not registered: launch **Native Cellular Call** (`tel:<number>`).
- **12-Digit UCall ID:**
  1. Resolve public profile and call availability using only the UCall ID.
  2. **Never expose the account's registered phone number.**
  3. If online: launch **UCall Internet Call**.
  4. If offline: **Privacy Protected.** Do not reveal the underlying number or dial cellular. Offer a **Call Alert / Push Notification** or callback request.
- **Network Outage / Offline Dialer:**
  1. Use locally cached UCall mapping if fresh (< 24h).
  2. If unknown and offline, notify user and provide immediate cellular fallback.
- **Abuse Prevention & Privacy Controls:** Phone number lookups are strictly rate-limited, salted, and audited to prevent directory enumeration attacks.

---

### 3. Protecting Private Mobile Numbers

To preserve privacy during UCall-to-UCall communication:
- **Caller dials UCall ID:** Caller enters `123456789012`. Backend resolves destination device keys. Signaling occurs over WebSocket / WebRTC. The caller only sees the recipient's UCall display name, avatar, and 12-digit UCall ID.
- **Real Phone Number Isolation:** Real phone numbers are never included in profile payloads or WebSockets.
- **Offline UCall ID Protection:** Because cellular calls originate through the caller's own carrier SIM, an app cannot secretly route a cellular call to a hidden phone number without either exposing that number to the native OS dialer or using a costly third-party bridge service. Therefore, if a user dials an offline recipient's UCall ID, UCall **never exposes the private number**; instead, it delivers a high-priority call notification.

---

### 4. Automatic SIM Detection & Indian Telecom (CNAP) Standards

- **Android Platform:** Android exposes subscription IDs via `SubscriptionManager`. The SIM's actual phone number is frequently blank or restricted; subscription IDs are used to route cellular calls through the preferred SIM.
- **iOS Platform:** iOS strictly restricts programmatic SIM selection and SIM number reading. Calls hand off cleanly via `tel:` URLs to the iOS system phone app.
- **Indian Calling Name Presentation (CNAP):** The Department of Telecommunications (DoT) has scheduled CNAP rollout for supported 4G/5G mobile networks from November 1, 2026. This is a telecom carrier network feature, not a third-party API. UCall respects network-provided CNAP identities when available and never collects SIM data covertly.

---

### 5. Final Call-Routing Decision Matrix

| Dialed Destination | Recipient Status | Connection Type | Displayed Identifier | Privacy Action |
|---|---|---|---|---|
| **12-Digit UCall ID** | Online & Reachable | **UCall Internet Call (VoIP)** | `UCall ID: XXXX XXXX XXXX` | Registered mobile number is 100% hidden |
| **12-Digit UCall ID** | Offline / Unavailable | **Call Alert Push / Notification** | `UCall ID: XXXX XXXX XXXX` | **Never** dial cellular; number remains private |
| **Indian Mobile Number** | Registered & Online | **UCall Internet Call (VoIP)** | Contact Name + Phone | Direct HD VoIP with E2EE |
| **Indian Mobile Number** | Registered & Offline | **Cellular Fallback Sheet** | Contact Name + Phone | User authorized cellular carrier call |
| **Non-UCall Mobile Number** | Any | **Native Cellular Call (`tel:`)** | Carrier Phone Number | Dispatches to native phone dialer via SIM |
| **Emergency Number (112, etc.)** | Any | **Native Cellular Emergency** | Emergency Service | Immediate native bypass to carrier network |
- **Media Engine:** WebRTC PeerConnection with STUN/TURN traversal.
- **Active Call Screen:** Dedicated full-screen dark navy interface with live call duration timer, mute, speakerphone, hold, add participant, and end-call controls.

---

## 12. Security, E2EE & Platform Keystore

1. **End-to-End Encryption:** Messages and media encrypted on-device before transmission. Server stores only ciphertext.
2. **Key Protection:** Private identity keys and session ratchets are stored in Android Keystore / iOS Keychain.
3. **Local Database Encryption:** SQLCipher protects SQLite files against unauthorized local extraction.
4. **Zero Sensitive Logging:** Phone numbers, tokens, private keys, and message plaintext are strictly redacted from logs.

---

## 13. Backend Integration Contract (UCall Rust Control Plane)

| Endpoint | Method | Purpose |
|---|---|---|
| `/api/v1/auth/login` | POST | Authenticate device and issue access/refresh token pair |
| `/api/v1/auth/ws-ticket` | POST | Issue short-lived, single-use ticket for WebSocket authentication |
| `/api/v1/users/me` | GET | Retrieve authenticated user profile and settings |
| `/api/v1/contacts/sync` | POST | Match phone numbers against registered UCall identities |
| `/api/v1/conversations` | GET | Retrieve user conversations with cursor pagination |
| `/api/v1/messages/send` | POST | Idempotent message submission fallback (if WS disconnected) |
| `/api/v1/sync` | GET | Fetch incremental changes after specified `cursor` |
| `/api/v1/e2ee/keys/bundle` | GET/POST| Publish and retrieve prekey bundles |
| `/api/v1/calls/session` | POST | Request VoIP session authorization and TURN credentials |
| `/api/v1/turn-credentials` | GET | Temporary STUN/TURN relay credentials |

---

## 14. Testing & Release Validation Checklist

### 1. Launch & Local Storage (5/5)
- [ ] Cold start displays the app shell in **< 300 ms** without network access.
- [ ] Cached contacts, calls, and chats appear in **< 500 ms** with zero API dependency.
- [ ] Opening a cached conversation loads in **< 200 ms**.
- [ ] Force-stop and relaunch preserve all local records and message drafts.
- [ ] Database schema migrations preserve existing user data without data loss.

### 2. Messaging & Synchronization (6/6)
- [ ] Offline messages are committed to SQLite outbox before UI marks them queued.
- [ ] Device reboot preserves unsent messages in the outbox.
- [ ] Repeated retry attempts with idempotency IDs never create duplicate server messages.
- [ ] Concurrent sync and reconnection do not drop or skip committed events.
- [ ] Duplicate WebSocket events are processed idempotently.
- [ ] Read receipts and delivery states reconcile accurately across devices.

### 3. Calling & Platform Integration (5/5)
- [ ] Dialer opens instantly with airplane mode enabled.
- [ ] Native cellular fallback launches the system phone dialer with the correct number.
- [ ] VoIP audio calls establish through restrictive NAT using TURN relay.
- [ ] Incoming calls trigger proper platform notifications and audio focus.
- [ ] Microphone permission denial and network degradation are gracefully handled.

### 4. Security & Privacy (5/5)
- [ ] Private keys and access tokens are never printed to console logs.
- [ ] Local database is encrypted with SQLCipher using keys in Hardware Keystore.
- [ ] Unauthorized access to cached records from external apps is blocked.
- [ ] E2EE ciphertexts can only be decrypted by the intended recipient.
- [ ] Account logout cleanly purges local sensitive decryption material.

### 5. Performance & Stability (5/5)
- [ ] Cold-start and warm-start performance meet targets on entry-level Android devices.
- [ ] Large contact lists (1,000+ items) scroll smoothly at 60/120 FPS.
- [ ] Repeated navigation between tabs does not increase memory or trigger UI rebuilds.
- [ ] Background sync never interrupts smooth scrolling or text composition.
- [ ] Storage-full and battery-saver conditions fail safely without corrupting data.

---

## 15. Implementation Phases & Milestones

```
Phase 1: Local-First Foundation
├── SQLite / Drift database setup with indexed schemas
├── Instant-launch App Shell with zero network dependency
└── Cached repositories for Calls, Messages, and Contacts

Phase 2: Durable Messaging & Outbox
├── Outbox worker with exponential backoff & idempotency
├── Optimistic UI state updates (queued -> sending -> sent)
└── Local message search and draft persistence

Phase 3: Live Sync Engine
├── Authenticated WebSocket connection with ticket handshake
├── Cursor-based delta synchronization
└── Real-time delivery and read receipt reconciliation

Phase 4: Calling & Platform Native Integration
├── Native cellular dialer handoff (`tel:`)
├── WebRTC VoIP audio signaling & active call screen
└── STUN/TURN network traversal & CallKit/ConnectionService

Phase 5: Security & E2EE
├── Platform Keystore integration (Hardware-backed)
├── Signal protocol / Double Ratchet implementation
└── Encrypted media attachment storage

Phase 6: QA, Benchmarking & Release
├── Cold start profiling on low-tier test devices
├── Offline resilience endurance testing
└── Production hardening and store release
```

---

## 16. Production Readiness, Behavioral Verification & Device Test Matrix

Static analysis (`flutter analyze`) confirms code cleanliness and type safety; it does not prove that live calls, privacy controls, or SIM selection behave correctly on physical devices. Production acceptance requires strict behavioral verification across physical devices.

### A. Final Verification Checklist

| Area | Production Requirement & Verification Criteria | Pass/Fail |
|---|---|---|
| **Automatic Routing** | Online, reachable UCall users connect directly via encrypted VoIP without displaying an unnecessary modal sheet. | [ ] |
| **Offline UCall IDs** | High-priority Call Alert / Push Notification is triggered. The recipient's private mobile number remains **100% hidden**; cellular fallback is strictly blocked. | [ ] |
| **Ordinary Phone Numbers** | Native cellular calling flow (`tel:`) opens correctly in the system dialer with the target number. | [ ] |
| **Failed VoIP Calls** | If WebRTC session setup fails or times out, cellular fallback requires **explicit user authorization** via an interactive alert dialog. | [ ] |
| **SIM Selection** | Default SIM, Always Ask, and supported dual-SIM behavior reflect actual OS subscription IDs on physical Android devices. | [ ] |
| **iOS Behavior** | Native calling handoff respects iOS system sandboxing and uses the platform phone application. | [ ] |
| **Local-First Behavior** | Cached identity lookups resolve offline in < 50ms without blocking the dialer or keypad inputs. | [ ] |
| **Identity Privacy** | Public profiles, console logs, API responses, error traces, and WebSockets never leak raw phone numbers for UCall ID calls. | [ ] |
| **Reachability** | Stale online statuses, abrupt socket drops, and ICE negotiation timeouts are caught gracefully without freezing the UI. | [ ] |
| **Security** | End-to-End Encryption (E2EE) verification is based on cryptographic prekey bundle and session validation, not a superficial UI badge. | [ ] |

---

### B. Five Critical Issues to Check Before Release

1. **Real SIM Information vs. Mock Labels:**  
   In production builds, SIM labels (e.g., `SIM 1 Jio 5G`, `SIM 2 Airtel 4G`) must be dynamically populated from the Android `SubscriptionManager` API under permitted runtime permissions (`READ_PHONE_STATE`). Mock or placeholder SIM strings must never be displayed to users as live SIM information.
2. **Native Cellular Handoff Limitations:**  
   `url_launcher` with `tel:<number>` hands the destination number to the operating system dialer. It does **not** grant the third-party app programmatic control to force a specific carrier SIM on Android without system telephony roles, nor does it dial silently on iOS. The app must transparently prepare the number in the OS dialer for user confirmation.
3. **Cryptographic UCall ID Validation:**  
   A 12-digit numeric input is only syntactically valid; it does not guarantee that the UCall ID is an existing, registered account. The client must verify the ID against the local SQLite identity cache and, if unindexed, issue an authenticated backend check before classifying the destination as a UCall account.
4. **Strict Offline Privacy Guarantee:**  
   If a user dials a 12-digit UCall ID and the recipient is offline, the app **must never fall back to cellular calling** using the recipient's underlying number. Because cellular calls originate through the caller's carrier SIM, passing the hidden number to the dialer breaks the privacy guarantee. Only out-of-band push notifications or call requests are permitted.
5. **Verified Reachability & E2EE Ratchet:**  
   A cached `online` boolean flag or a green shield icon is never proof of reachability. Real-time reachability requires an active WebSocket ping/ack or PushKit/FCM high-priority wake-up. Media encryption must verify device identity keys using the Signal Protocol / Double Ratchet before transmitting audio packets.

---

### C. End-to-End Physical Device Test Matrix

| Test Scenario | Test Conditions | Expected Behavioral Outcome | Verified |
|---|---|---|---|
| **Android Single-SIM** | Physical Android 12+ device with 1 active SIM | Dialing mobile number launches native dialer; UCall ID triggers VoIP directly. | [ ] |
| **Android Dual-SIM** | Physical Android device with 2 active SIM cards | Dialer respects user's Preferred SIM setting or invokes OS SIM picker. | [ ] |
| **iOS Platform** | Physical iPhone running iOS 16+ | Clean handoff via `tel:` URL scheme without crash or malformed URI errors. | [ ] |
| **Offline Airplane Mode** | Device with Wi-Fi & Cellular turned off | Keypad opens instantly; cached identities resolve; explains offline state gracefully. | [ ] |
| **Stale Presence** | Recipient force-closed app 10 minutes prior | VoIP setup triggers high-priority FCM/APNs wake-up; falls back to Call Alert if unreachable. | [ ] |
| **Failed VoIP Setup** | Restricted NAT / UDP blocked (Firewall) | Times out after 10s; presents explicit Cellular Fallback modal dialog. | [ ] |
| **App Process Kill** | OS kills app during active dialer input | Relaunches in < 300ms; restored state without data corruption or blank screens. | [ ] |

---

## 17. UCall Registration — Automatic SIM Verification Architecture

### A. Principles & Core Requirements
1. **Zero Manual Phone Number Entry:**  
   Users cannot type arbitrary phone numbers into the registration field. The registration phone number is bound to the physical hardware SIM or eSIM installed in the device and detected via the operating system's telephony/subscription APIs (`SubscriptionManager` on Android, CoreTelephony on iOS).
2. **Automatic Country Code Detection:**  
   Country code and ISO prefix (`IN +91`, `US +1`, `GB +44`, etc.) are automatically derived from the device locale, carrier MNC/MCC, or network location.
3. **No OTP Code Entry Screen:**  
   Traditional SMS OTP codes can be intercepted or forwarded. UCall employs direct carrier-backed network verification (e.g., GSMA Open Gateway / Carrier Verification API) or silent SMS network tokens.
4. **Multi-SIM Support:**  
   When dual-SIM or multiple active subscriptions are present, the app renders detected SIM cards (e.g. `SIM 1 (Jio 5G)`, `SIM 2 (Airtel 4G)`). Selecting a SIM immediately reflects its associated number and binds that specific subscription to the account.
5. **Supported Fallback Protocol:**  
   If automatic network verification is unsupported by a specific MVNO or restricted network, the app explicitly communicates the issue and offers a verified alternative (such as carrier silent SMS verification) rather than silently trusting an unverified number.
6. **Unique 12-Digit UCall ID Generation:**  
   Upon successful carrier verification, the backend issues a cryptographically authenticated, unique 12-digit UCall ID (`XXXX XXXX XXXX`) and activates the Zero Number Exposure Shield.

---

## Definition of Done (DoD)

The UCall mobile application is accepted for production release when:
1. All core screens open immediately from local SQLite storage without waiting for network responses.
2. Outgoing messages and call records survive abrupt application termination and device reboot.
3. Sync recovers smoothly after network disruption without data loss or duplicate messages.
4. Cellular and VoIP calling workflows function as specified across physical Android and iOS devices.
5. All 26 release acceptance criteria and the 10-point Behavioral Verification Checklist are verified on real hardware and signed off.


