# WalletDatabase

OTP application providing shared database infrastructure for all domain apps in the MercuryPay umbrella.

This is a **cross-cutting infrastructure layer** — it owns no domain logic. All domain apps depend on it for persistence; it depends on no domain app.

## Public Interface

```elixir
# Ecto repo (direct use by write-through modules only)
WalletDatabase.Repo.insert!/2
WalletDatabase.Repo.get/3
WalletDatabase.Repo.all/2

# WriteThrough behaviour — implemented by every persistence module
@behaviour WalletDatabase.WriteThrough
@callback persist(struct()) :: :ok | {:error, term()}

# Domain-specific persistence modules (used by their owning domain app)
WalletDatabase.WriteThrough.AccountPersistence.persist(account)
WalletDatabase.WriteThrough.CardPersistence.persist(card)
WalletDatabase.WriteThrough.LoanPersistence.persist(loan)
# ... (one module per persisted entity; see write_through/ directory)
```

## Responsibilities
- Hosts `WalletDatabase.Repo` (MyXQL / Ecto).
- Defines the `WalletDatabase.WriteThrough` behaviour.
- Provides one `*Persistence` module per entity across all domain apps (75+ modules).
- Owns all Ecto schemas grouped by domain namespace.
- Owns all Ecto migrations under `priv/repo/migrations/`.
- Provides `WalletDatabase.AdminConfig` for runtime DB configuration.

## Forbidden Dependencies
- Any domain app (`wallet_accounts`, `wallet_cards`, …) — this layer must not depend upward.

## Dependencies
- `wallet_shared_kernel` — shared types (TypedId, Money).
- `ecto_sql` — Ecto SQL adapter.
- `myxql` — MySQL driver.
- `jason` — JSON encoding for JSONB-style fields.

## Schemas
All schemas live under `lib/wallet_database/schemas/<domain>/`. Naming convention: `<domain>_<entity>_record.ex`.

## Migrations
All migrations live under `priv/repo/migrations/`. Timestamps follow the `20260401NNNNNN` convention. Run with:

```bash
mix ecto.migrate
```

## Write-Through Modules
All persistence modules live under `lib/wallet_database/write_through/` and follow the pattern:

```elixir
defmodule WalletDatabase.WriteThrough.FooPersistence do
  @behaviour WalletDatabase.WriteThrough
  alias WalletDatabase.{Repo, Schemas.Domain.FooRecord}

  @impl true
  def persist(%Foo{} = foo) do
    # upsert via WalletDatabase.WriteThrough.upsert/3
  end
end
```
