TorbatYar/backend/services/loyalty/app/schemas/wallet.py
Mortezakoohjani 071c484530 Ship Loyalty phases 7.2-7.6 (points through wallet) with production deploy.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-26 21:27:22 +03:30

126 lines
3.4 KiB
Python

"""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