# Phase 1 Architecture & Data Flow

## System Architecture

```
┌─────────────────┐
│  MQTT Broker    │
│  (Device)       │
└────────┬────────┘
         │
         │ Publishes Status Message
         │ (with vendor, model, versions)
         │
         ▼
┌──────────────────────────────┐
│  MQTT Handler                │
│  handle_message/3            │
│  Topic: tms/status/+         │
└──────────┬───────────────────┘
           │
           ├─ Extract vendor, model
           ├─ Extract versions from org.device items
           ├─ Check: has_missing_versions?()
           │
           └─ IF yes:
              ▼
      ┌──────────────────────────┐
      │ AutoPushService          │
      │ trigger_missing_version_ │
      │ push/3                   │
      └──────────┬───────────────┘
                 │
                 ├─ Find template (Active→Default)
                 │  by vendor+model
                 │
                 ├─ Push Parameters
                 │  ├─ Get template values
                 │  ├─ Create push_log entry
                 │  └─ Send MQTT command
                 │
                 └─ Push Device Configs
                    For: EMV, Keys, Application
                    ├─ Create push_log entries
                    └─ Send MQTT commands
                 │
           ▼─────▼──────────────────────────┐
           │  Updated Terminal State         │
           │  - vendor, model               │
           │  - parameter_config_version    │
           │  - emv_config_version          │
           │  - keys_config_version         │
           │  - updated_at                  │
           └────────────────────────────────┘
           │
           ▼──────────────────────────────┐
           │  Push Operation Logs          │
           │  parameter_push_logs          │
           │  (4 entries per device)       │
           │  - 1x parameter               │
           │  - 1x emv_config              │
           │  - 1x keys_config             │
           │  - 1x application             │
           └──────────────────────────────┘
```

---

## Data Flow - Scenario 1 (Missing Versions)

### Input: MQTT Status Message
```json
{
  "oid": "org_123",
  "sn": "61250904380091",
  "vendor": "MoreFun",
  "model": "MF919",
  "uploadTime": "2025-01-31T15:00:00Z",
  "org.device": [
    {
      "itemkey": "parameter_config",
      "value": "",                    // ← EMPTY/NULL = Missing
      "timestamp": "2025-01-31T15:00:00Z",
      "message": "Parameter Config"
    },
    {
      "itemkey": "emv_config",
      "value": null,                  // ← NULL = Missing
      "timestamp": "2025-01-31T15:00:00Z",
      "message": "EMV Config"
    },
    {
      "itemkey": "keys_config",
      "value": "",                    // ← EMPTY = Missing
      "timestamp": "2025-01-31T15:00:00Z",
      "message": "Keys Config"
    },
    {
      "itemkey": "application",
      "value": null,                  // ← NULL = Missing
      "timestamp": "2025-01-31T15:00:00Z",
      "message": "Application"
    }
  ]
}
```

### Processing Steps

#### Step 1: Handler Extraction
```elixir
vendor = "MoreFun"
model = "MF919"

versions = %{
  parameter_config: nil,    # ← Missing!
  emv_config: nil,          # ← Missing!
  keys_config: nil,         # ← Missing!
  application: nil          # ← Missing!
}

has_missing_versions?(versions) => true
```

#### Step 2: AutoPushService Trigger
```elixir
AutoPushService.trigger_missing_version_push(
  "61250904380091",
  "MoreFun",
  "MF919"
)
```

#### Step 3: Template Lookup
```
Find Template for (vendor="MoreFun", model="MF919")
├─ Priority 1: is_active=true AND is_default=false
│  └─ Example: "Communication SR600mini" (Active)
│
└─ Priority 2: is_default=true
   └─ Example: "Ingenico Default Configuration" (Default)
```

#### Step 4: Push Parameters from Template
```elixir
# From parameter_template_values for selected template:
template_values = [
  {parameter_key: "merchant_id", value: "900890089008000"},
  {parameter_key: "terminal_id", value: "61250904380091"},
  {parameter_key: "MQTT_HOST_IP", value: "demo.ctrmv.com"},
  # ... more parameters
]

# Create parameter_push_logs entry:
%ParameterPushLog{
  terminal_id: 123,
  template_id: 45,
  config_type: "parameter",
  device_vendor: "MoreFun",
  device_model: "MF919",
  trigger_reason: "missing_version",
  status: "pending",
  parameters_sent: %{
    "merchant_id" => "900890089008000",
    "terminal_id" => "61250904380091",
    "MQTT_HOST_IP" => "demo.ctrmv.com",
    # ...
  }
}

# Send MQTT command:
Topic: /ota/pFppbioOCKlo5c8E/61250904380091/update
Payload: {
  "command": "push_parameters",
  "request_id": 1234567,
  "config_type": "parameter",
  "parameters": {...},
  "timestamp": "2025-01-31T15:00:00Z"
}
```

#### Step 5: Push Device Setup Configs
For each config type in ["emv_config", "keys_config", "application"]:

```elixir
%ParameterPushLog{
  terminal_id: 123,
  config_type: "emv_config",           # or keys_config, application
  device_vendor: "MoreFun",
  device_model: "MF919",
  trigger_reason: "missing_version",
  status: "pending",
  request_id: 1234568
}

# Send MQTT command:
Payload: {
  "command": "push_config",
  "request_id": 1234568,
  "config_type": "emv_config",
  "timestamp": "2025-01-31T15:00:00Z"
}
```

#### Step 6: Terminal State Update
```sql
UPDATE tms_terminals SET
  vendor = "MoreFun",
  model = "MF919",
  parameter_config_version = NULL,     -- Stays NULL until device confirms
  emv_config_version = NULL,           -- Stays NULL until device confirms
  keys_config_version = NULL,          -- Stays NULL until device confirms
  updated_at = NOW()
WHERE serial_number = "61250904380091"
```

### Output: Database State

#### tms_terminals
```
serial_number: 61250904380091
vendor: MoreFun
model: MF919
parameter_config_version: NULL
emv_config_version: NULL
keys_config_version: NULL
status: connected
updated_at: 2025-01-31 15:00:05
```

#### parameter_push_logs (4 entries)
```
#1 - Parameters
config_type: "parameter"
trigger_reason: "missing_version"
device_vendor: "MoreFun"
device_model: "MF919"
status: "pending"
request_id: 1234567

#2 - EMV Config
config_type: "emv_config"
trigger_reason: "missing_version"
device_vendor: "MoreFun"
device_model: "MF919"
status: "pending"
request_id: 1234568

#3 - Keys Config
config_type: "keys_config"
trigger_reason: "missing_version"
device_vendor: "MoreFun"
device_model: "MF919"
status: "pending"
request_id: 1234569

#4 - Application
config_type: "application"
trigger_reason: "missing_version"
device_vendor: "MoreFun"
device_model: "MF919"
status: "pending"
request_id: 1234570
```

---

## Database Changes

### tms_terminals (3 new columns)
```sql
ALTER TABLE tms_terminals
ADD COLUMN parameter_config_version VARCHAR(255);
ADD COLUMN emv_config_version VARCHAR(255);
ADD COLUMN keys_config_version VARCHAR(255);

CREATE INDEX idx_tms_terminals_parameter_config_version 
ON tms_terminals(parameter_config_version);
```

### parameter_push_logs (8 new columns)
```sql
ALTER TABLE parameter_push_logs
ADD COLUMN config_type VARCHAR(50) DEFAULT 'parameter';
ADD COLUMN file_path VARCHAR(500);
ADD COLUMN file_size INTEGER;
ADD COLUMN checksum VARCHAR(255);
ADD COLUMN version_sent VARCHAR(255);
ADD COLUMN device_vendor VARCHAR(255);
ADD COLUMN device_model VARCHAR(255);
ADD COLUMN trigger_reason VARCHAR(100);

CREATE INDEX idx_parameter_push_logs_config_type 
ON parameter_push_logs(config_type);
CREATE INDEX idx_parameter_push_logs_device_vendor_model 
ON parameter_push_logs(device_vendor, device_model);
CREATE INDEX idx_parameter_push_logs_trigger_reason 
ON parameter_push_logs(trigger_reason);
```

### parameter_categories (new data)
```sql
INSERT INTO parameter_categories (name, code, description, is_active)
VALUES ('Device Setup', 'device_setup', 'Device configuration parameters', 1);
```

### parameter_definitions (3 new rows)
```sql
INSERT INTO parameter_definitions 
(key, name, description, data_type, default_value, is_active, category_id)
VALUES
  ('emv_config_version', 'EMV Config Version', '...', 'string', '1.6', 1, device_setup_id),
  ('keys_config_version', 'Keys Config Version', '...', 'string', '1.7', 1, device_setup_id),
  ('application_version', 'Application Version', '...', 'string', '3.7', 1, device_setup_id);
```

---

## Key Design Decisions

### 1. Template Matching Strategy
- **Why Active first, then Default?**
  - Active templates are current configurations
  - Default is fallback for new or unsupported devices
  - Ensures most recent config is pushed

### 2. Immediate Push vs Delayed Push
- **Why immediate?**
  - Devices with missing versions are incomplete
  - Faster time to operational readiness
  - Can be queued if needed in future

### 3. Separate Push Log Entries
- **Why 4 entries per device?**
  - Tracks each config type independently
  - Allows different retry/ack handling per config
  - Better auditability and analytics

### 4. Version Extracted vs Auto-assigned
- **Why versions stored null initially?**
  - Versions represent actual device state
  - Only update when device confirms application
  - Phase 2 will compare with scheduled versions

---

## Future Enhancements (Phase 2+)

### Phase 2: Version Mismatch Detection
- Compare device versions with latest available
- Auto-push outdated versions
- Scheduled version management

### Phase 3: Push Acknowledgment Handling
- Monitor MQTT responses from devices
- Update push log status (pending → success/failed)
- Retry failed pushes

### Phase 4: Admin Dashboard
- View push status per device
- Manual push triggers
- Rollback/fallback options

---

**Architecture Version:** 1.0  
**Last Updated:** 2025-01-31  
**Status:** Phase 1 Complete ✅
