# Implementation Plan: Config Version Management
**Branch:** `feat/config-version-management`
**Date:** 2026-03-19
**Status:** ✅ Complete (all 5 phases delivered)

---

## Problem Statement

The TMS currently has no version management for parameter configurations or EMV (L3)
configs. Specifically:

| Gap | Impact |
|-----|--------|
| `ParameterTemplate` has no `version` field | Cannot track which version of parameters a terminal has received |
| EMV/L3 config is a hardcoded static file | No version history, no rollback, no per-model differentiation |
| `parameter_push_logs.version_sent` always NULL | Audit trail is incomplete |
| MQTT autopush payload has no `version` field | Terminal cannot confirm which version it applied |
| No "target version" concept | Cannot detect compliance drift on heartbeat |

---

## Scope

This plan covers:
1. **Data model** — two migrations, one new schema
2. **Core push pipeline** — version propagated end-to-end through AutoPush → MQTT
3. **EMV versioned file lookup** — L3ConfigZipBuilder uses DB-managed file path
4. **Seed** — existing static L3 XML seeded as version `1.0.0`

UI Added:
- LiveView admin UI for ConfigFileVersion CRUD
- Version compliance dashboard
- VersionComplianceChecker (re-push on heartbeat version mismatch)

---

## Architecture Overview

```
[ParameterTemplate]          [ConfigFileVersion]
  version: "1.2.0"    ─┐      config_type: emv_config
                        │      vendor/model: Castles/MF919
                        │      version: "1.0.0"
                        │      file_path: priv/static/mf919/emv/v1.0.0/...
                        │      is_active: true
                        │
                        ▼
              [AutoPushService]  (reads version from above)
                        │
                        ▼  version included in payload
              [MQTTCommandBuilder]
                {type: tms_command, command: UPDATE_PARAMS,
                 downloadUrl: "...", version: "1.2.0"}
                        │
                        ▼
            [parameter_push_logs]
              version_sent: "1.2.0"   ← NOW POPULATED
```

---

## Phase 1 — Migrations

### 1a. `20260319000001_add_version_to_parameter_templates.exs`
- Adds `version VARCHAR(50) NOT NULL DEFAULT '1.0.0'` to `parameter_templates`
- Drops old `(vendor, model, name)` unique index
- Creates `(vendor, model, name, version)` unique index

### 1b. `20260319000002_create_config_file_versions.exs`
New table `config_file_versions`:

| Column | Type | Notes |
|--------|------|-------|
| id | int PK | |
| config_type | varchar(50) | `emv_config`, `keys_config`, `parameter` |
| vendor | varchar(100) | e.g. `Castles` |
| model | varchar(100) | e.g. `MF919` |
| version | varchar(50) | e.g. `1.0.0` |
| file_path | varchar(255) | Full path to the source config file |
| checksum | varchar(64) | SHA256 of the source file |
| is_active | tinyint(1) | Only ONE active per (type, vendor, model) |
| release_notes | text | Optional changelog entry |
| creator_id | bigint FK → users | |
| inserted_at / updated_at | datetime | |

Unique index on `(config_type, vendor, model, version)`.

---

## Phase 2 — New Schema: `ConfigFileVersion`

Module: `TmsCore.TerminalManagement.ConfigFileVersion`
Table: `config_file_versions`

Key query helpers:
- `active_for(config_type, vendor, model)` — returns the active version row
- `by_type_and_model(config_type, vendor, model)` — all versions ordered desc

---

## Phase 3 — Update `ParameterTemplate`

Add `version` field (string, default `"1.0.0"`) to schema and changeset in:
- `apps/da_product_app/lib/da_product_app/parameter_management/parameter_template.ex`

---

## Phase 4 — Update `AutoPushService`

Changes:
1. `push_mf919_params` — add `version_sent: template.version` to push log attrs;
   pass version to `send_mqtt_mf919_file_push/7`
2. `push_mf919_emv_config` — query active `ConfigFileVersion` for
   `("emv_config", vendor, model)`; use its `file_path` and `version`;
   pass version to `send_mqtt_mf919_file_push/7`
3. `push_keys_config` — query active `ConfigFileVersion` for `("keys_config", vendor, model)`;
   add `version_sent` to push log
4. `send_mqtt_mf919_file_push/6 → /7` — add `version` parameter, forward to builder

---

## Phase 5 — Update `MQTTCommandBuilder`

In `build_mf919_command/1`:
- Extract `version` from params map
- Include `"version" => version` in the JSON payload

Terminal receives:
```json
{
  "type": "tms_command",
  "command": "UPDATE_PARAMS",
  "requestId": 12345,
  "downloadUrl": "http://...",
  "version": "1.2.0"
}
```

---

## Phase 6 — Update `L3ConfigZipBuilder`

Change `build_and_store/1` to accept an optional `source_path` override:
```elixir
def build_and_store(serial_number, source_path \\ @l3_config_path)
```

This allows `AutoPushService` to pass the versioned `file_path` from `ConfigFileVersion`.
Falls back to the compile-time default (backwards compatible).

---

## Phase 7 — Seed File

`priv/repo/seeds/config_file_versions_seed.exs`

Seeds the existing `priv/static/mf919/YSDK_L3_configuration.xml` as:
- `config_type: "emv_config"`, `vendor: "Castles"`, `model: "MF919"`
- `version: "1.0.0"`, `is_active: true`
- Computes SHA256 checksum from actual file

---

## Files Modified / Created

| Action | File |
|--------|------|
| CREATE | `priv/repo/migrations/20260319000001_add_version_to_parameter_templates.exs` |
| CREATE | `priv/repo/migrations/20260319000002_create_config_file_versions.exs` |
| CREATE | `apps/tms_core/lib/tms_core/terminal_management/config_file_version.ex` |
| CREATE | `apps/tms_core/lib/tms_core/terminal_management/version_compliance_checker.ex` |
| MODIFY | `apps/da_product_app/lib/da_product_app/parameter_management/parameter_template.ex` |
| MODIFY | `apps/tms_core/lib/tms_core/terminal_management/auto_push_service.ex` |
| MODIFY | `apps/tms_core/lib/tms_core/terminal_management/mqtt_command_builder.ex` |
| MODIFY | `apps/tms_core/lib/tms_core/terminal_management/l3_config_zip_builder.ex` |
| MODIFY | `apps/da_product_app/lib/da_product_app/mqtt/handler.ex` |
| CREATE | `priv/repo/seeds/config_file_versions_seed.exs` |
| MODIFY | `apps/da_product_app/priv/repo/seeds.exs` |
| MODIFY | `apps/da_product_app/lib/da_product_app/menu_provider.ex` |
| MODIFY | `apps/platform_web/lib/platform_web/menu/registry.ex` |
| MODIFY | `apps/platform_web/lib/platform_web/router.ex` |
| CREATE | `apps/platform_web/lib/platform_web/live/config_version_live/index.ex` |
| CREATE | `apps/platform_web/lib/platform_web/live/version_compliance_live/index.ex` |

---

## Phase 5 — Admin UI (LiveView) ✅

### 5a. Config Version Manager (`/admin/config-versions`)

**Module:** `PlatformWeb.ConfigVersionLive.Index`

Features:
- Table of all `config_file_versions` with: type badge, vendor/model, version, file path,
  truncated checksum, active status, registered date
- Inline release notes row for each version entry
- Type filter tabs (All / EMV Config / Keys Config)
- **"Register New Version" modal**: config_type, vendor, model, version, file_path,
  release_notes, optional "Set Active immediately" checkbox
  — SHA-256 checksum auto-computed from file on the server
- **"Set Active" button**: calls `ConfigFileVersion.activate!/1`, deactivates siblings atomically
- Separate **Parameter Template Versions** section — shows all templates with their `version`
  field and links to the template editor for bumping

### 5b. Terminal Version Compliance Dashboard (`/admin/version-compliance`)

**Module:** `PlatformWeb.VersionComplianceLive.Index`

Features:
- **Summary cards**: Total / Compliant / Outdated / Never-pushed counts
- **Filter bar**: by overall status (All / Compliant / Outdated / Never-pushed / No-target),
  vendor, model
- **Compliance table**: per terminal shows reported + target version for
  parameter_config, emv_config, keys_config with colour-coded badges
- **Overall status column**: ✅ Compliant / ⚠️ Outdated / ❌ Never pushed / 🔵 No target
- **"Re-push" button** per terminal — triggers `AutoPushService.trigger_config_push/4`
  for each non-compliant slot
- **"Bulk Re-push Outdated" button** — applies to current filtered view
- Refresh button

### Permissions (4 new slugs)

| Slug | Description |
|------|-------------|
| `config.version.view` | View config file versions (EMV, keys) |
| `config.version.manage` | Register new config versions and set active version |
| `config.compliance.view` | View terminal version compliance dashboard |
| `config.compliance.remediate` | Trigger re-push for outdated terminals |

### Menu Entries (in "Parameter Management" group)

| Item | Route | Icon | Required Permission |
|------|-------|------|-------------------|
| Config Versions | `/admin/config-versions` | `hero-tag` | `config.version.view` |
| Version Compliance | `/admin/version-compliance` | `hero-check-badge` | `config.compliance.view` |

