# Integration Guide: Elixir Umbrella Extraction

## Overview

This document describes the umbrella project layout introduced in
`feature/extract-tms-umbrella` and how to build and run the system locally.

## Repository Layout

```
/
├── mix.exs                  # Umbrella root (TmsUmbrella.MixProject)
├── mix.lock                 # Shared lock file
├── config/                  # Shared configuration (all apps share this)
│   ├── config.exs
│   ├── dev.exs
│   ├── test.exs
│   ├── prod.exs
│   └── runtime.exs
├── apps/
│   ├── da_product_app/      # Existing Phoenix app (full-stack, transitional)
│   │   ├── mix.exs
│   │   ├── lib/             # All existing application code
│   │   ├── test/
│   │   ├── priv/
│   │   └── assets/
│   ├── platform_core/       # Scaffold: shared infrastructure (future)
│   │   ├── mix.exs
│   │   └── lib/
│   │       └── platform_core/
│   │           ├── application.ex
│   │           └── repo.ex          # PlatformCore.Repo (future home of DaProductApp.Repo)
│   ├── tms_core/            # Scaffold: Terminal Management domain
│   │   ├── mix.exs
│   │   └── lib/
│   │       ├── tms_core.ex
│   │       └── tms_core/
│   │           ├── application.ex
│   │           └── terminal.ex      # TmsCore.Terminal public API
│   │           └── terminal/
│   │               └── adapter.ex   # TmsCore.Terminal.Adapter behaviour
│   └── platform_web/        # Scaffold: Phoenix web layer (future)
│       ├── mix.exs
│       └── lib/
│           ├── platform_web.ex
│           └── platform_web/
│               └── application.ex
└── docs/
    └── INTEGRATION.md       # This file
```

## Extraction Phase Summary

This PR performs **Phase 1 (Scaffold)**, **Phase 2 (Settlements Extraction)**, and **Phase 3 (Risk Extraction)** of an incremental extraction:

| Component                | Current Location              | New Location               | Status      |
|--------------------------|-------------------------------|----------------------------|-------------|
| Terminal Management      | `da_product_app`              | `tms_core`                 | 🟡 Scaffolded |
| Shared Repo              | `DaProductApp.Repo`           | `PlatformCore.Repo`        | ✅ Live      |
| Settlements              | `da_product_app`              | `settlement_core`          | ✅ Extracted  |
| Risk Management          | `da_product_app`              | `risk_core`                | ✅ Extracted  |
| Phoenix Web Layer        | `da_product_app`              | `platform_web`             | 🟡 Scaffolded |

## How to Run Locally

### First-time Setup

```bash
# From the repository root
mix deps.get
mix ecto.setup
mix assets.setup
mix assets.build
```

### Start the Development Server

```bash
# From the repository root (umbrella root)
mix phx.server
```

Or with an IEx console:

```bash
iex -S mix phx.server
```

The application starts on **http://localhost:14002** (development).

### Running Tests

```bash
# From the repository root
mix test

# To run tests for a specific umbrella app only:
cd apps/da_product_app && mix test
cd apps/tms_core && mix test
```

## TmsCore Public API

Once `tms_core` has been fully populated (Phase 2), use the public API instead
of calling `DaProductApp.TerminalManagement` directly:

```elixir
# List terminals
TmsCore.Terminal.list_terminals(%{status: "online"})

# Get a terminal
TmsCore.Terminal.get_terminal(terminal_id)

# Create a terminal
TmsCore.Terminal.create_terminal(%{serial_number: "SN001", ...})

# Subscribe to device updates
TmsCore.subscribe_to_device_updates()
```

### Adapter Configuration

The `TmsCore.Terminal` API is backed by an adapter. During the extraction phase,
the `DaProductApp.TmsAdapter` delegates to `DaProductApp.TerminalManagement`:

```elixir
# config/config.exs (already set)
config :tms_core, TmsCore.Terminal, adapter: DaProductApp.TmsAdapter
```

When the code is fully migrated to `tms_core`, change the adapter to the native
implementation.

## Enabling / Disabling TmsCore

The `tms_core` application can be enabled or disabled at runtime:

```elixir
# config/config.exs (or environment-specific config)
config :tms_core, :enabled, true   # default: true

# To disable TMS in a specific release:
config :tms_core, :enabled, false
```

When disabled, `TmsCore.Application.start/2` returns `:ignore` and no
TMS-related processes are started.

## Building Releases

Four release configurations are defined in the umbrella root `mix.exs`:

| Release            | Apps Included                                                          | Use Case                          |
|--------------------|------------------------------------------------------------------------|-----------------------------------|
| `full`             | `platform_core`, `tms_core`, `settlement_core`, `risk_core`, `platform_web`, `da_product_app` | Complete system |
| `tms_release`      | `platform_core`, `tms_core`                                            | TMS-only headless release         |
| `settlement_release` | `platform_core`, `settlement_core`                                   | Settlement-only headless release  |
| `risk_release`     | `platform_core`, `risk_core`                                           | Risk monitoring headless release  |

```bash
# Build the full release
MIX_ENV=prod mix release full

# Build the TMS-only release
MIX_ENV=prod mix release tms_release

# Build the settlement-only release
MIX_ENV=prod mix release settlement_release

# Build the risk monitoring release
MIX_ENV=prod mix release risk_release
```

## Enabling / Disabling SettlementCore

```elixir
# config/config.exs (or environment-specific config)
config :settlement_core, :enabled, true   # default: true

# To disable settlements in a specific release (e.g. tms_release):
config :settlement_core, :enabled, false
```

When disabled, `SettlementCore.Application.start/2` returns `:ignore` and no
settlement-related processes (e.g. AlipayPlus scheduler) are started.

## Enabling / Disabling RiskCore

```elixir
# config/config.exs (or environment-specific config)
config :risk_core, :enabled, true              # default: true
config :risk_core, :adapter, RiskCore.LocalAdapter  # default adapter

# To disable risk evaluation in a specific release:
config :risk_core, :enabled, false
```

When disabled, `RiskCore.Application.start/2` returns `:ignore`.

### Switching the Risk Adapter

To use a remote or custom risk evaluation service, implement `RiskCore.RiskBehaviour`
and configure the adapter:

```elixir
# config/prod.exs (example)
config :risk_core, :adapter, MyApp.RemoteRiskAdapter
```

## Module Mapping (Old → New)

### Settlements (Phase 2 — complete)

| Old Module                                          | New Module                                    |
|-----------------------------------------------------|-----------------------------------------------|
| `DaProductApp.Settlements` (context)                | `SettlementCore.Context` (+ `DaProductApp.Settlements` shim) |
| `DaProductApp.Settlements.Settlement`               | `SettlementCore.Settlement`                   |
| `DaProductApp.Settlements.SettlementTransaction`    | `SettlementCore.SettlementTransaction`        |
| `DaProductApp.Settlements.SettlementFile`           | `SettlementCore.SettlementFile`               |
| `DaProductApp.Settlements.SettlementFileAudit`      | `SettlementCore.SettlementFileAudit`          |
| `DaProductApp.Settlements.AaniSettlementAudit`      | `SettlementCore.AaniSettlementAudit`          |
| `DaProductApp.Settlements.MerchantBatchNumber`      | `SettlementCore.MerchantBatchNumber`          |
| `DaProductApp.Settlements.YspSummary`               | `SettlementCore.YspSummary`                   |
| `DaProductApp.Settlements.SettlementManagement`     | `SettlementCore.SettlementManagement`         |
| `DaProductApp.Settlements.EodFileGenerator`         | `SettlementCore.EodFileGenerator`             |
| `DaProductApp.Settlements.TransactionEodGenerator`  | `SettlementCore.TransactionEodGenerator`      |
| `DaProductApp.Settlements.AlipayPlus.Scheduler`     | `SettlementCore.AlipayPlus.Scheduler`         |
| `DaProductApp.Settlements.AlipayPlus.Processor`     | `SettlementCore.AlipayPlus.Processor`         |
| `DaProductApp.Settlements.AlipayPlus.CsvParser`     | `SettlementCore.AlipayPlus.CsvParser`         |
| `DaProductApp.Settlements.AlipayPlus.SftpClient`    | `SettlementCore.AlipayPlus.SftpClient`        |
| `DaProductApp.Settlements.AlipayPlus.SftpFetcher`   | `SettlementCore.AlipayPlus.SftpFetcher`       |
| `DaProductApp.Settlements.AlipayPlus.Jobs.*`        | `SettlementCore.AlipayPlus.Jobs.*`            |
| `DaProductApp.Settlements.Refund.CsvParser`         | `SettlementCore.Refund.CsvParser`             |
| `DaProductApp.Settlements.Refund.Processor`         | `SettlementCore.Refund.Processor`             |
| `DaProductApp.Workers.EodFileGenerationWorker`      | `SettlementCore.Workers.EodFileGenerationWorker` |

### Risk Management (Phase 3 — complete)

| Old Module                                          | New Module                                    |
|-----------------------------------------------------|-----------------------------------------------|
| `DaProductApp.RiskManagement` (context)             | `RiskCore.Context` (+ `DaProductApp.RiskManagement` shim) |
| `DaProductApp.RiskManagement.RiskRule`              | `RiskCore.RiskRule`                           |
| `DaProductApp.RiskManagement.RiskRuleHit`           | `RiskCore.RiskRuleHit`                        |
| `DaProductApp.RiskManagement.RiskAuditLog`          | `RiskCore.RiskAuditLog`                       |
| `DaProductApp.RiskManagement.PosTransaction`        | `RiskCore.PosTransaction`                     |
| `DaProductApp.RiskManagement.SupervisorLastChecked` | `RiskCore.SupervisorLastChecked`              |
| `DaProductApp.RiskManagement.Seeds`                 | `RiskCore.Seeds`                              |
| `DaProductApp.Workers.TransactionRiskEvaluator`     | `RiskCore.Workers.TransactionRiskEvaluator`   |
| N/A (new)                                           | `RiskCore.RiskBehaviour` (callback behaviour) |
| N/A (new)                                           | `RiskCore.LocalAdapter` (local evaluation)    |
| N/A (new)                                           | `RiskCore.Adapter` (dispatching adapter)      |

### Terminal Management (Phase 4 — scaffolded)

| Old Module                                        | New Module (Phase 4)              |
|---------------------------------------------------|-----------------------------------|
| `DaProductApp.TerminalManagement`                 | `TmsCore.TerminalManagement`      |
| `DaProductApp.TerminalManagement.TmsTerminal`     | `TmsCore.TmsTerminal`             |
| `DaProductApp.TerminalManagement.OfflineMonitor`  | `TmsCore.OfflineMonitor`          |
| `DaProductApp.TerminalManagement.TerminalEventSupervisor` | `TmsCore.TerminalEventSupervisor` |
| `DaProductApp.TerminalManagement.FilterCacheService` | `TmsCore.FilterCacheService`   |
| `DaProductApp.Repo`                               | `PlatformCore.Repo`               |

## Next Steps

After this PR is merged, create issues for:

1. **Phase 4 – TMS Code Migration**: Move all `DaProductApp.TerminalManagement.*`
   modules into `apps/tms_core/lib/tms_core/` with the `TmsCore.*` namespace.
   Update `DaProductApp.TmsAdapter` to call the native `TmsCore` context.

2. **Phase 5 – Platform Core Migration**: Move `DaProductApp.Repo`,
   `DaProductApp.DeviceRegistry`, `DaProductApp.MQTT.*`, and the Oban
   configuration into `apps/platform_core/`. Update all dependent apps.

3. **Phase 6 – Platform Web Migration**: Move the Phoenix endpoint, router,
   LiveViews, and controllers into `apps/platform_web/`. Update the web layer
   to call `TmsCore.Terminal`, `SettlementCore.*`, and `RiskCore.*` APIs.


