# Device-Specific MQTT Command Architecture

## System Architecture Diagram

```
┌─────────────────────────────────────────────────────────────────┐
│                         UI LAYER                                 │
│  (lib/da_product_app_web/live/terminal_live/index.html.heex)    │
├─────────────────────────────────────────────────────────────────┤
│                                                                   │
│  Terminal Details Slide-Over                                     │
│  ├─ Details Tab                                                  │
│  ├─ History Tab                                                  │
│  └─ File Download Tab ◄─── CONDITIONAL RENDERING                │
│     │                                                             │
│     ├── IF model == "MF919" ──► MF919 Form                      │
│     │   ├─ Command Type Dropdown                                 │
│     │   │   └─ UPDATE_PARAMS, UPDATE_L3_CONFIG, LOAD_KEYS       │
│     │   ├─ Download URL                                          │
│     │   └─ Helper Box (URL hints)                                │
│     │                                                             │
│     └── ELSE (SR600/Kozen) ──► SR600 Form                       │
│         ├─ Download URL                                          │
│         ├─ File Name                                             │
│         ├─ Local Save Path                                       │
│         ├─ File Category (7 options)                             │
│         │   └─ + Keys, Parameters, EMV (NEW)                    │
│         └─ Merchant Config Checkbox                              │
│                                                                   │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
                    [User Submits Form]
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                      HANDLER LAYER                               │
│    (lib/da_product_app_web/live/terminal_live/index.ex)         │
├─────────────────────────────────────────────────────────────────┤
│                                                                   │
│  handle_event("send_file_download", params, socket)             │
│  │                                                               │
│  ├─ Extract: terminal (model, serial)                           │
│  ├─ Validate: params against model requirements                 │
│  ├─ Generate: unique request_id                                 │
│  ├─ Build: device-specific payload                              │
│  │   └─ Calls: MQTTCommandBuilder.build_command()               │
│  ├─ Publish: to MQTT broker                                     │
│  └─ Respond: success/error message                              │
│                                                                   │
│  send_mqtt_command/4 helper                                      │
│  ├─ Constructs MQTT topic                                       │
│  ├─ Publishes payload                                           │
│  └─ Handles MQTT response                                       │
│                                                                   │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    BUILDER LAYER (NEW)                           │
│  (lib/da_product_app/terminal_management/mqtt_command_builder)  │
├─────────────────────────────────────────────────────────────────┤
│                                                                   │
│  MQTTCommandBuilder (Router)                                     │
│  │                                                               │
│  build_command(device_model, params)                             │
│  │                                                               │
│  ├─ "mf919" ───► build_mf919_command(params)                   │
│  │               │                                               │
│  │               ├─ Extract: command_type, url                  │
│  │               ├─ Generate: request_id                        │
│  │               ├─ Build: TMS payload                          │
│  │               │   {                                           │
│  │               │     "type": "tms_command",                    │
│  │               │     "command": "UPDATE_PARAMS|...",          │
│  │               │     "requestId": "req-...",                  │
│  │               │     "downloadUrl": "http://..."              │
│  │               │   }                                           │
│  │               └─ Return: {:ok, json}                         │
│  │                                                               │
│  ├─ "sr600" ───► build_sr600_command(params)                   │
│  │               │                                               │
│  │               ├─ Extract: path, url, name, category         │
│  │               ├─ Merge: defaults (retry_count, etc)         │
│  │               ├─ Build: file_download payload                │
│  │               │   {                                           │
│  │               │     "command": "file_download",              │
│  │               │     "local_path_to_save": "...",             │
│  │               │     "url_path_from_download": "...",         │
│  │               │     "file_name": "...",                      │
│  │               │     "file_category": "...",                  │
│  │               │     "merchant_config": "...",                │
│  │               │     "retry_count": "3",                      │
│  │               │     "request_id": "req-..."                  │
│  │               │   }                                           │
│  │               └─ Return: {:ok, json}                         │
│  │                                                               │
│  ├─ "kozen" ────► build_kozen_command(params)                  │
│  │               └─ Routes to build_sr600_command()             │
│  │                                                               │
│  └─ other ─────► build_sr600_command(params)  [DEFAULT]        │
│                                                                   │
│  Helper Functions:                                               │
│  ├─ generate_request_id() ────────► "req-{ts}-{random}"        │
│  ├─ validate_device_params() ─────► {:ok, params}|{:error}     │
│  ├─ get_file_categories() ────────► [categories]               │
│  ├─ get_command_types() ──────────► [types]                    │
│  └─ get_url_hint() ───────────────► hint_url                   │
│                                                                   │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼ (return payload)
                    [Handler sends to MQTT]
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                      MQTT LAYER                                  │
├─────────────────────────────────────────────────────────────────┤
│                                                                   │
│  DaProductApp.MQTT.publish(topic, payload, qos: 1)              │
│  │                                                               │
│  ├─ Topic: /ota/{product_key}/{device_serial}/update           │
│  ├─ Payload: JSON (device-specific)                             │
│  ├─ QoS: 1 (At least once delivery)                             │
│  │                                                               │
│  └─ Broker: localhost:1883                                      │
│                                                                   │
│  MF919 Subscribed Topics:                                        │
│  └─ /ota/pFppbioOCKlo5c8E/*/update                              │
│     (Receives TMS commands)                                      │
│                                                                   │
│  SR600 Subscribed Topics:                                        │
│  └─ /ota/pFppbioOCKlo5c8E/*/update                              │
│     (Receives file_download commands)                            │
│                                                                   │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
                    [Device Receives Command]
                              │
                              ▼
        ┌───────────────────┴───────────────────┐
        │                                       │
        ▼                                       ▼
    MF919 Device                            SR600 Device
    (TMS Handler)                        (File Download Handler)
    │                                       │
    ├─ Parse command type                  ├─ Parse local_path
    ├─ Validate requestId                  ├─ Validate url
    ├─ Download config                     ├─ Download file
    ├─ Apply updates                       ├─ Save to path
    │  ├─ UPDATE_PARAMS                    ├─ Verify checksum
    │  ├─ UPDATE_L3_CONFIG                 └─ Send ACK
    │  └─ LOAD_KEYS                        
    └─ Send ACK                            
```

---

## Data Flow Diagram

```
┌──────────────┐
│ User Opens  │
│ Terminal     │
└──────┬───────┘
       │
       ▼
┌──────────────────────────┐
│ UI Renders Conditionally │
│ Based on Model           │
├──────────────────────────┤
│ MF919? ─► Show TMS Form  │
│ SR600? ─► Show DL Form   │
│ Other? ─► Show DL Form   │
└──────┬───────────────────┘
       │
       ▼
┌──────────────────────────┐
│ User Fills Device Form   │
│ & Submits                │
└──────┬───────────────────┘
       │
       ▼
┌──────────────────────────────────┐
│ handler: send_file_download      │
├──────────────────────────────────┤
│ 1. Extract terminal.model        │
│ 2. Validate params by model      │
│ 3. Generate request_id           │
│ 4. Call build_command(model, ..) │
└──────┬───────────────────────────┘
       │
       ▼
┌────────────────────────────────────┐
│ MQTTCommandBuilder routes to:       │
├────────────────────────────────────┤
│ model == "mf919" ?                  │
│ ├─ YES ─► build_mf919_command()    │
│ │         Returns: TMS JSON format  │
│ │                                   │
│ └─ NO ─► build_sr600_command()     │
│          Returns: File DL format    │
│                                     │
│ Both return: {:ok, json_payload}   │
└──────┬───────────────────────────────┘
       │
       ▼
┌──────────────────────────────────┐
│ Publish to MQTT                  │
├──────────────────────────────────┤
│ Topic: /ota/{product_key}/       │
│        {serial}/update           │
│                                  │
│ Payload: Device-specific JSON    │
│ QoS: 1                           │
└──────┬───────────────────────────┘
       │
       ▼
┌──────────────────────────────────┐
│ MQTT Broker Delivers             │
│ (mosquitto on localhost:1883)    │
└──────┬───────────────────────────┘
       │
       ▼
┌──────────────────────────────────┐
│ Device Receives & Processes      │
├──────────────────────────────────┤
│ MF919: TMS Command Handler       │
│ SR600: File Download Handler     │
│ Kozen: File Download Handler     │
└──────┬───────────────────────────┘
       │
       ▼
┌──────────────────────────────────┐
│ Device Sends Acknowledgment      │
│ (optional response topic)        │
└──────────────────────────────────┘
```

---

## File Category Hierarchy

```
📁 File Categories (7 Total)
├─ 🖼️ Logo Image
├─ 🔧 Firmware
├─ 📱 Application
├─ ⚙️ Configuration
├─ 🔑 Keys (NEW - Enhanced)
├─ 📦 Parameters (NEW - Enhanced)
└─ 💳 EMV (NEW - Enhanced)

MF919 Specific Categories:
├─ 📦 Parameters (params.zip)
├─ ⚙️ L3 Config (l3config.zip)
└─ 🔑 Keys (keys.json)

SR600 Standard Categories:
├─ 🖼️ Logo Image
├─ 🔧 Firmware
├─ 📱 Application
└─ ⚙️ Configuration

Now Shared by Both:
├─ 🔑 Keys
├─ 📦 Parameters
└─ 💳 EMV
```

---

## State Management

```
Socket Assignment State
├─ @selected_terminal
│  ├─ id
│  ├─ serial_number
│  ├─ model ◄─── KEY: Used for routing
│  ├─ vendor
│  ├─ status
│  └─ ... other fields
├─ @tab
│  └─ "file_download" ◄─── When user navigates here
├─ @show_panel
│  └─ true ◄─── Terminal details visible
└─ ... other state

Form State (In HTML):
├─ name="download_params[...]"
│  ├─ command_type (MF919 only)
│  ├─ url_path_from_download (both)
│  ├─ file_name (SR600 only)
│  ├─ local_path_to_save (SR600 only)
│  ├─ file_category (SR600 only)
│  └─ merchant_config (SR600 only)
```

---

## Device Model Comparison

```
┌─────────────────┬────────────────┬──────────────────┐
│ Feature         │ MF919          │ SR600            │
├─────────────────┼────────────────┼──────────────────┤
│ Command Format  │ TMS Command    │ File Download    │
│ Payload Type    │ tms_command    │ file_download    │
│ Command Field   │ command        │ command          │
│ URL Field       │ downloadUrl    │ url_path_from... │
│ Categories      │ 3 predefined   │ 7 flexible       │
│ Command Types   │ 3 (specific)   │ 1 (file_download)│
│ Retry Logic     │ Device-side    │ Configurable     │
│ File Saving     │ Auto           │ Path-based       │
├─────────────────┼────────────────┼──────────────────┤
│ UPDATE_PARAMS   │ ✓              │ ✗               │
│ UPDATE_L3_CFG   │ ✓              │ ✗               │
│ LOAD_KEYS       │ ✓              │ ✗               │
│ File Download   │ N/A            │ ✓               │
│ Merchant Config │ N/A            │ ✓               │
└─────────────────┴────────────────┴──────────────────┘
```

---

## Request ID Generation

```
Request ID: "req-{timestamp}-{random}"

Example: "req-1705945627-847263"
         └──┬────────────────┴─
            │
            ├─ "req-" prefix (constant)
            ├─ "1705945627" (System.os_time(:second))
            └─ "847263" (:rand.uniform(1_000_000))

Usage:
- Unique per command
- Timestamp-based ordering
- Device response correlation
- Logging & debugging
```

---

## MQTT Topic Structure

```
Topic Format: /ota/{product_key}/{device_serial}/update

Example for MF919:
/ota/pFppbioOCKlo5c8E/DEVICE001234/update

Breakdown:
├─ /ota/ (root topic)
├─ pFppbioOCKlo5c8E (product key - org/instance identifier)
├─ DEVICE001234 (device serial number)
└─ /update (operation type)

Device Subscriptions:
├─ MF919 listens to: /ota/pFppbioOCKlo5c8E/*/update
├─ SR600 listens to: /ota/pFppbioOCKlo5c8E/*/update
└─ Kozen listens to: /ota/pFppbioOCKlo5c8E/*/update

Wildcard (* ) = All device serial numbers
```

---

## Error Handling Flow

```
┌─ Validation Error ─────────────────┐
│ Missing required field             │
│ e.g., "command_type" for MF919     │
│                                    │
└─► {:error, "Missing required..."}  │
    ► Flash: error message           │
    ► UI: form remains with input    │
                                    
┌─ Build Error ──────────────────────┐
│ JSON encoding failure              │
│ Invalid parameters                 │
│                                    │
└─► {:error, "Failed to build..."}   │
    ► Flash: build error message     │
                                    
┌─ MQTT Publish Error ───────────────┐
│ Broker connection lost             │
│ Topic publish failed               │
│                                    │
└─► {:error, "MQTT publish failed"}  │
    ► Flash: MQTT error message      │
                                    
┌─ Success ──────────────────────────┐
│ Command sent successfully          │
│                                    │
└─► {:ok, message}                   │
    ► Flash: "MF919 command sent..."
```

---

## Testing Matrix

```
Test Category    │ MF919        │ SR600        │ Result
─────────────────┼──────────────┼──────────────┼─────────
Parameter Validation
├─ command_type  │ REQUIRED     │ N/A          │ ✓ or ✗
├─ url_path      │ REQUIRED     │ REQUIRED     │ ✓ or ✗
├─ local_path    │ N/A          │ REQUIRED     │ ✓ or ✗
└─ file_name     │ N/A          │ REQUIRED     │ ✓ or ✗

Payload Generation
├─ TMS format    │ ✓            │ ✗            │ Valid JSON
├─ DL format     │ ✗            │ ✓            │ Valid JSON
├─ Request ID    │ Generated    │ Generated    │ Unique
└─ Encoding      │ UTF-8        │ UTF-8        │ No errors

MQTT Publishing
├─ Topic         │ Correct      │ Correct      │ Delivered
├─ QoS           │ 1            │ 1            │ ✓
└─ Broker        │ Connected    │ Connected    │ ✓

Device Response
├─ Command       │ Parsed       │ Parsed       │ Understood
├─ Execution     │ Applied      │ Applied      │ Success
└─ ACK           │ Sent         │ Sent         │ Received
```
