arbret/backend/mappers.py
2025-12-25 00:59:57 +01:00

91 lines
3.4 KiB
Python

"""Response mappers for converting models to API response schemas."""
from models import Exchange, Invite
from schemas import (
AdminExchangeResponse,
ExchangeResponse,
ExchangeUserContact,
InviteResponse,
)
class ExchangeMapper:
"""Mapper for Exchange model to response schemas."""
@staticmethod
def to_response(
exchange: Exchange,
user_email: str | None = None,
) -> ExchangeResponse:
"""Convert an Exchange model to ExchangeResponse schema."""
email = user_email if user_email is not None else exchange.user.email
return ExchangeResponse(
id=exchange.id,
public_id=str(exchange.public_id),
user_id=exchange.user_id,
user_email=email,
slot_start=exchange.slot_start,
slot_end=exchange.slot_end,
direction=exchange.direction.value,
bitcoin_transfer_method=exchange.bitcoin_transfer_method.value,
eur_amount=exchange.eur_amount,
sats_amount=exchange.sats_amount,
market_price_eur=exchange.market_price_eur,
agreed_price_eur=exchange.agreed_price_eur,
premium_percentage=exchange.premium_percentage,
status=exchange.status.value,
created_at=exchange.created_at,
cancelled_at=exchange.cancelled_at,
completed_at=exchange.completed_at,
)
@staticmethod
def to_admin_response(exchange: Exchange) -> AdminExchangeResponse:
"""Convert an Exchange model to AdminExchangeResponse with user contact."""
user = exchange.user
return AdminExchangeResponse(
id=exchange.id,
public_id=str(exchange.public_id),
user_id=exchange.user_id,
user_email=user.email,
user_contact=ExchangeUserContact(
email=user.email,
contact_email=user.contact_email,
telegram=user.telegram,
signal=user.signal,
nostr_npub=user.nostr_npub,
),
slot_start=exchange.slot_start,
slot_end=exchange.slot_end,
direction=exchange.direction.value,
bitcoin_transfer_method=exchange.bitcoin_transfer_method.value,
eur_amount=exchange.eur_amount,
sats_amount=exchange.sats_amount,
market_price_eur=exchange.market_price_eur,
agreed_price_eur=exchange.agreed_price_eur,
premium_percentage=exchange.premium_percentage,
status=exchange.status.value,
created_at=exchange.created_at,
cancelled_at=exchange.cancelled_at,
completed_at=exchange.completed_at,
)
class InviteMapper:
"""Mapper for Invite model to response schemas."""
@staticmethod
def to_response(invite: Invite) -> InviteResponse:
"""Build an InviteResponse from an Invite with loaded relationships."""
return InviteResponse(
id=invite.id,
identifier=invite.identifier,
godfather_id=invite.godfather_id,
godfather_email=invite.godfather.email,
status=invite.status.value,
used_by_id=invite.used_by_id,
used_by_email=invite.used_by.email if invite.used_by else None,
created_at=invite.created_at,
spent_at=invite.spent_at,
revoked_at=invite.revoked_at,
)