# Phase Recon-5 — Hospital Config + Seed Data

**Status:** ⬜ Pending
**Duration:** Weeks 8–9
**Depends on:** Phase Recon-4
**Goal:** All 7 hospital configurations loaded from DB. Location mappings, column overrides, and enabled recon types are configurable per hospital through the admin UI — no code changes needed to onboard a new hospital.

---

## New Context: `infra_repo/recon_configs.ex`

```elixir
defmodule InfraRepo.ReconConfigs do
  import Ecto.Query
  alias InfraRepo.Repo
  alias InfraRepo.Schemas.{ReconConfig, ReconLocationMap}

  def list_enabled_for_tenant(tenant_id) do
    ReconConfig
    |> where([c], c.tenant_id == ^tenant_id and c.enabled == true)
    |> order_by([c], c.display_name)
    |> Repo.all()
  end

  def get_config!(id), do: Repo.get!(ReconConfig, id) |> Repo.preload(:location_maps)

  def create_config(attrs), do: %ReconConfig{} |> ReconConfig.changeset(attrs) |> Repo.insert()

  def update_config(%ReconConfig{} = c, attrs),
    do: c |> ReconConfig.changeset(attrs) |> Repo.update()

  def upsert_location_map(config_id, full_name, short_code) do
    Repo.insert(
      %ReconLocationMap{config_id: config_id, full_name: full_name, short_code: short_code},
      on_conflict: [set: [short_code: short_code]],
      conflict_target: [:config_id, :full_name]
    )
  end
end
```

---

## Seed Data (`infra_repo/priv/repo/seeds.exs`)

Add to the end of the existing seeds file:

```elixir
alias InfraRepo.Repo
alias InfraRepo.Schemas.{Tenant, ReconConfig, ReconLocationMap}
alias InfraRepo.ReconConfigs

IO.puts("Seeding Recon configurations...")

# ── Sahyadri ──────────────────────────────────────────────────────────────────
sahyadri = Repo.get_by!(Tenant, name: "Sahyadri") ||
           Repo.insert!(%Tenant{name: "Sahyadri", slug: "sahyadri"})

sahyadri_location_map = %{
  "SHL Bibwewadi-Hospital"                         => "BBW",
  "SSL CC Sinhgad Road"                            => "Lab",
  "SSL CC Wakad"                                   => "Lab",
  "SSL Labs"                                       => "Lab",
  "SSL-CC-Pimple Saudagar"                         => "Lab",
  "SSL-CC-SKDC"                                    => "Lab",
  "SSL CC Baner"                                   => "Lab",
  "SSL CC Karve Nagar"                             => "Lab",
  "Sahyadri Super Speciality Hospital, Deccan"     => "Deccan",
  "Sahyadri Super Speciality Hospital, Hadapsar"   => "HDP",
  "Sahyadri Super Speciality Hospital, Nagar Road" => "NGR",
  "Sahyadri Super Speciality Hospital, Nashik"     => "NSK",
  "SHL Kothrud-Hospital"                           => "Koth",
  "SSL CC Kondhwa"                                 => "Lab",
  "SSL CC Magarpatta"                              => "Lab",
  "SSL-CC-Koregaon Park"                           => "Lab",
  "SSL-CC-New Kalyani Nagar"                       => "Lab",
  "LAB HADAPSAR"                                   => "Lab",
  "LAB NAGAR ROAD"                                 => "Lab",
  "SSL-CC-Lohegaon"                                => "Lab",
  "SSL-CC-Fatima Nagar"                            => "Lab",
  "Sahyadri Super Speciality Hospital, Shivajinagar" => "Shiv"
}

sahyadri_configs = [
  %{
    recon_type:   "bank_card_vs_momentspay",
    display_name: "Bank Card vs MomentsPay",
    match_keys:   Jason.encode!([
      ["Last4_CARDNBR", "TERMINAL_NO", "AUTH_AMOUNT", "APPROVAL_CODE"],
      ["Last4_CARDNBR", "TERMINAL_NO", "AUTH_AMOUNT"]
    ]),
    payment_modes: Jason.encode!(["Debit Card", "Credit Card"])
  },
  %{
    recon_type:   "bank_upi_vs_momentspay",
    display_name: "Bank UPI vs MomentsPay",
    match_keys:   Jason.encode!([
      ["CARDNBR", "TERMINAL_NO", "AUTH_AMOUNT", "RRN_NO"]
    ]),
    payment_modes: Jason.encode!(["QR CODE"])
  },
  %{
    recon_type:   "his_bank_card",
    display_name: "HIS vs Bank Card",
    match_keys:   Jason.encode!([
      ["Last4_card_num", "Amount", "Approval No"]
    ]),
    payment_modes: Jason.encode!(["Debit Card", "Credit Card"])
  },
  %{
    recon_type:   "his_bank_upi",
    display_name: "HIS vs Bank UPI",
    match_keys:   Jason.encode!([["Amount"]]),
    payment_modes: Jason.encode!(["QR CODE"])
  },
  %{
    recon_type:   "his_momentspay_card",
    display_name: "HIS vs MomentsPay (Card + Bank)",
    match_keys:   Jason.encode!([
      ["Last4_card_num", "Amount", "Approval No"],
      ["Last4_card_num", "Amount"]
    ]),
    payment_modes: Jason.encode!(["Debit Card", "Credit Card"])
  },
  %{
    recon_type:   "amex",
    display_name: "AMEX vs HIS",
    match_keys:   Jason.encode!([["Amount", "approval_code"]]),
    payment_modes: Jason.encode!(["AMEX", "American Express"])
  }
]

Enum.each(sahyadri_configs, fn attrs ->
  location_map_json = Jason.encode!(sahyadri_location_map)
  full_attrs = Map.merge(attrs, %{
    tenant_id:    sahyadri.id,
    enabled:      true,
    location_map: location_map_json
  })
  case Repo.get_by(ReconConfig, tenant_id: sahyadri.id, recon_type: attrs.recon_type) do
    nil    -> Repo.insert!(struct(ReconConfig, full_attrs))
    config -> Repo.update!(ReconConfig.changeset(config, full_attrs))
  end
end)

# Seed location map rows for Sahyadri (for the UI editor)
sahyadri_configs_in_db = Repo.all(
  from c in ReconConfig, where: c.tenant_id == ^sahyadri.id
)
Enum.each(sahyadri_configs_in_db, fn config ->
  Enum.each(sahyadri_location_map, fn {full, short} ->
    ReconConfigs.upsert_location_map(config.id, full, short)
  end)
end)

# ── Anderson ──────────────────────────────────────────────────────────────────
anderson = Repo.get_by(Tenant, name: "Anderson") ||
           Repo.insert!(%Tenant{name: "Anderson", slug: "anderson"})

anderson_location_map = %{
  # Add Anderson-specific location mappings here (from Anderson python files)
  # Currently using same pattern — update when Anderson location names are confirmed
}

anderson_configs = [
  %{recon_type: "bank_card_vs_momentspay", display_name: "Bank Card vs MomentsPay"},
  %{recon_type: "bank_upi_vs_momentspay",  display_name: "Bank UPI vs MomentsPay"},
  %{recon_type: "his_bank_card",           display_name: "HIS vs Bank Card"},
  %{recon_type: "his_momentspay_card",     display_name: "HIS vs MomentsPay (Card)"}
]
# (same upsert pattern as Sahyadri)

# ── Continental, Rela, Srikara, Trustwell, DRMOHAN ───────────────────────────
# Follow the same pattern — configs extracted from the respective Python files.
# Each hospital's column_mappings and location_map will differ.
# See python files in D:\moment\recon\<Hospital> Python Files\ for the exact values.

IO.puts("Recon seed complete.")
```

---

## Admin Config UI: `ReconConfigLive` (brief)

```elixir
defmodule GatewayWebWeb.ReconConfigLive do
  use GatewayWebWeb, :live_view

  alias InfraRepo.{ReconConfigs, Repo}
  alias InfraRepo.Schemas.ReconConfig

  def mount(_params, _session, socket) do
    configs = Repo.all(ReconConfig) |> Repo.preload([:tenant, :location_maps])
    {:ok, assign(socket, page_title: "Recon Config", active_nav: "recon_config",
                          configs: configs, editing_id: nil, editing_location: nil)}
  end

  # Events: edit_config, save_config, add_location, remove_location, toggle_enabled
  # ...
end
```

Template features:
- Table of all hospitals and their enabled recon types
- Click to expand a config and see/edit: column_mappings JSON, payment_modes, match_keys
- Location map editor: add/remove location-to-code entries inline
- Toggle enabled/disabled per recon type

---

## How to Add a New Hospital (after Phase 5)

1. Create a `Tenant` record in the DB (or via the existing Tenants admin UI at `/admin/tenants`)
2. Go to `/admin/recon/config`
3. Click "Add Config" for the new tenant
4. Select recon types, enter column mappings (copy from bank's file headers), add location codes
5. Save — the hospital immediately appears in the Recon Wizard hospital dropdown

**No code deployment required.**

---

## Acceptance Criteria

- [ ] All 7 hospitals (Sahyadri, Anderson, Continental, Rela, Srikara, Trustwell, DRMOHAN) appear in the Step 1 hospital dropdown after running `mix run priv/repo/seeds.exs`
- [ ] Sahyadri location map produces correct short codes in the Summary sheet
- [ ] Selecting a hospital only shows recon types configured as `enabled: true` for that hospital
- [ ] Admin can toggle a recon type on/off at `/admin/recon/config` — change is immediate
- [ ] Admin can add a new location mapping via UI — appears in next recon run's Summary sheet
- [ ] New hospital can be onboarded via UI only (no code change)
