# Phase 7.6 — Wallet

| Field | Value |
| --- | --- |
| Identifier | `loyalty-7.6` |
| Status | Complete |
| Module | loyalty |
| Service | `loyalty-service` |
| Version | `0.7.6.0` |
| Database | `loyalty_db` |
| Depends On | Phase 7.5 |
| ADR(s) | ADR-001, ADR-003, ADR-006, ADR-011 |
| Manifest | [phase-manifest.yaml](ai-framework/phase-manifest.yaml) |

## Objective

Deliver the Wallet Engine: wallet accounts with an append-only immutable ledger as the sole balance source (credit / debit / adjust / transfer) — without gift cards, analytics, or partner APIs.

## Scope

### In Scope

- `WalletAccount` shell — **no mutable balance column**
- `WalletLedgerEntry` append-only ledger; balance = `SUM(signed amounts)`
- Credit, debit, adjust, transfer (atomic two-leg)
- Idempotency, insufficient-funds rejection, open-account-only mutations
- Permissions, events, validators, migration `0007_phase_76_wallet`
- Tests + documentation + handover + service snapshot

### Out of Scope

- Gift Card Platform (7.7)
- Analytics (7.8)
- Public / Partner / Webhook APIs (7.9)
- Final Review (7.10)

## Ledger Rules

| Rule | Detail |
| --- | --- |
| Append-only | No UPDATE/DELETE of ledger rows |
| Signed amounts | credit/transfer_in positive; debit/transfer_out negative; adjust signed |
| Open accounts only | Frozen/closed reject mutations |
| Transfer | Same currency; not same account; single commit |
| Balance | Computed from ledger only |

## APIs

| Method | Path | Permission |
| --- | --- | --- |
| POST | `/api/v1/wallets` | `loyalty.wallets.create` |
| GET | `/api/v1/wallets` | `loyalty.wallets.view` |
| GET | `/api/v1/wallets/{id}` | `loyalty.wallets.view` |
| GET | `/api/v1/wallets/{id}/balance` | `loyalty.wallets.view` |
| GET | `/api/v1/wallets/{id}/ledger` | `loyalty.wallets.view` |
| PATCH | `/api/v1/wallets/{id}` | `loyalty.wallets.manage` |
| POST | `/api/v1/wallets/{id}/credit` | `loyalty.wallets.credit` |
| POST | `/api/v1/wallets/{id}/debit` | `loyalty.wallets.debit` |
| POST | `/api/v1/wallets/{id}/adjust` | `loyalty.wallets.adjust` |
| POST | `/api/v1/wallets/{id}/transfer` | `loyalty.wallets.transfer` |
| POST | `/api/v1/wallets/{id}/delete` | `loyalty.wallets.delete` |

## Events

| Event | When |
| --- | --- |
| `loyalty.wallet.opened` | Account opened |
| `loyalty.wallet.credited` | Credit |
| `loyalty.wallet.debited` | Debit |
| `loyalty.wallet.adjusted` | Adjust |
| `loyalty.wallet.transferred` | Transfer |
| `loyalty.wallet.closed` | Soft close |

## Migration

| Item | Detail |
| --- | --- |
| Alembic | `0007_phase_76_wallet` (down_revision `0006_phase_75_referral`) |
| Breaking | None — additive tables |

## Tests

Command: `cd backend/services/loyalty && pytest -q` → **114 passed**

## Known Limitations

- No payment gateway settlement (credits are ledger-only)
- No gift-card issuance (7.7)
- No scheduled freeze/close workers

## Next Phase

Phase 7.7 — Gift Card Platform

## Related Documents

- [Handover](phase-handover/phase-7-6.md)
- [Phase 7.5](loyalty-phase-7-5.md)
- [Service Snapshot](service-snapshots/loyalty.yaml)
- [ADR-011](architecture/adr/ADR-011.md)
