"""Point ledger DTOs — Phase 7.2.""" from __future__ import annotations from datetime import datetime from uuid import UUID from pydantic import BaseModel, ConfigDict, Field from app.models.types import LedgerEntryType, PointAccountStatus from app.schemas.common import ORMBase _FORBID = ConfigDict(extra="forbid") class PointEarnRequest(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) expires_at: datetime | None = None metadata_json: dict | None = None class PointRedeemRequest(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_json: dict | None = None class PointAdjustRequest(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_json: dict | None = None class PointExpireRequest(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_json: dict | None = None class PointLedgerEntryRead(ORMBase): id: UUID tenant_id: UUID point_account_id: UUID program_id: UUID member_id: UUID entry_type: LedgerEntryType amount: int balance_after: int idempotency_key: str | None reference_type: str | None reference_id: str | None reason: str | None metadata_json: dict | None expires_at: datetime | None actor_user_id: str | None created_at: datetime class PointBalanceRead(BaseModel): point_account_id: UUID member_id: UUID program_id: UUID status: PointAccountStatus balance: int currency_name: str class PointLedgerPage(BaseModel): items: list[PointLedgerEntryRead] total: int offset: int limit: int