"""Wallet Engine DTOs — Phase 7.6.""" from __future__ import annotations from datetime import datetime from uuid import UUID from pydantic import BaseModel, ConfigDict, Field from app.models.types import WalletAccountStatus, WalletLedgerEntryType from app.schemas.common import ORMBase _FORBID = ConfigDict(extra="forbid") class WalletAccountCreate(BaseModel): model_config = _FORBID program_id: UUID member_id: UUID account_number: str | None = Field(default=None, max_length=50) currency_code: str = Field(default="IRR", max_length=3) status: WalletAccountStatus = WalletAccountStatus.OPEN class WalletAccountUpdate(BaseModel): model_config = _FORBID status: WalletAccountStatus | None = None class WalletAccountRead(ORMBase): id: UUID tenant_id: UUID program_id: UUID member_id: UUID account_number: str currency_code: str status: WalletAccountStatus is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class WalletCreditRequest(BaseModel): model_config = _FORBID amount: int = Field(gt=0) reason: str | None = Field(default=None, max_length=500) idempotency_key: str | None = Field(default=None, max_length=100) reference_type: str | None = Field(default=None, max_length=50) reference_id: str | None = Field(default=None, max_length=100) metadata: dict | None = None class WalletDebitRequest(BaseModel): model_config = _FORBID amount: int = Field(gt=0) reason: str | None = Field(default=None, max_length=500) idempotency_key: str | None = Field(default=None, max_length=100) reference_type: str | None = Field(default=None, max_length=50) reference_id: str | None = Field(default=None, max_length=100) metadata: dict | None = None class WalletAdjustRequest(BaseModel): model_config = _FORBID amount: int # signed reason: str = Field(max_length=500) idempotency_key: str | None = Field(default=None, max_length=100) reference_type: str | None = Field(default=None, max_length=50) reference_id: str | None = Field(default=None, max_length=100) metadata: dict | None = None class WalletTransferRequest(BaseModel): model_config = _FORBID target_wallet_id: UUID amount: int = Field(gt=0) reason: str | None = Field(default=None, max_length=500) idempotency_key: str | None = Field(default=None, max_length=100) metadata: dict | None = None class WalletLedgerEntryRead(ORMBase): id: UUID tenant_id: UUID wallet_account_id: UUID program_id: UUID member_id: UUID entry_type: WalletLedgerEntryType amount: int balance_after: int idempotency_key: str | None reference_type: str | None reference_id: str | None reason: str | None metadata_json: dict | None actor_user_id: str | None created_at: datetime class WalletBalanceRead(BaseModel): wallet_account_id: UUID member_id: UUID program_id: UUID status: WalletAccountStatus currency_code: str balance: int class WalletLedgerPage(BaseModel): items: list[WalletLedgerEntryRead] total: int offset: int limit: int class WalletTransferResult(BaseModel): source_entry: WalletLedgerEntryRead target_entry: WalletLedgerEntryRead