diff --git a/currency_utils.py b/currency_utils.py new file mode 100644 index 0000000..426d163 --- /dev/null +++ b/currency_utils.py @@ -0,0 +1,53 @@ +# Currency conversion utilities for Client Extension API boundary +from decimal import Decimal +from typing import Union + + +def gtq_to_centavos(gtq_amount: Union[float, int, str]) -> int: + """Convert GTQ to centavos for database storage""" + return int(Decimal(str(gtq_amount)) * 100) + + +def centavos_to_gtq(centavos: int) -> float: + """Convert centavos to GTQ for API responses""" + return float(centavos) / 100 + + +def format_gtq_currency(centavos: int) -> str: + """Format centavos as GTQ currency string""" + gtq_amount = centavos_to_gtq(centavos) + return f"Q{gtq_amount:.2f}" + + +# Conversion helpers for client API responses +def dashboard_summary_db_to_api(summary_db) -> dict: + """Convert database dashboard summary to API response""" + return { + "user_id": summary_db.user_id, + "total_sats_accumulated": summary_db.total_sats_accumulated, + "total_fiat_invested_gtq": centavos_to_gtq(summary_db.total_fiat_invested), + "pending_fiat_deposits_gtq": centavos_to_gtq(summary_db.pending_fiat_deposits), + "current_sats_fiat_value_gtq": centavos_to_gtq(int(summary_db.current_sats_fiat_value)), + "average_cost_basis": summary_db.average_cost_basis, + "current_fiat_balance_gtq": centavos_to_gtq(summary_db.current_fiat_balance), + "total_transactions": summary_db.total_transactions, + "dca_mode": summary_db.dca_mode, + "dca_status": summary_db.dca_status, + "last_transaction_date": summary_db.last_transaction_date, + "currency": summary_db.currency + } + + +def transaction_db_to_api(transaction_db) -> dict: + """Convert database transaction to API response""" + return { + "id": transaction_db.id, + "amount_sats": transaction_db.amount_sats, + "amount_fiat_gtq": centavos_to_gtq(transaction_db.amount_fiat), + "exchange_rate": transaction_db.exchange_rate, + "transaction_type": transaction_db.transaction_type, + "status": transaction_db.status, + "created_at": transaction_db.created_at, + "transaction_time": transaction_db.transaction_time, + "lamassu_transaction_id": transaction_db.lamassu_transaction_id + } \ No newline at end of file diff --git a/models.py b/models.py index 267d22f..cdcb10f 100644 --- a/models.py +++ b/models.py @@ -6,9 +6,39 @@ from typing import List, Optional from pydantic import BaseModel -# Client Dashboard Data Models +# API Models for Client Dashboard (Frontend communication in GTQ) +class ClientDashboardSummaryAPI(BaseModel): + """API model - client dashboard summary in GTQ""" + user_id: str + total_sats_accumulated: int + total_fiat_invested_gtq: float # Confirmed deposits in GTQ + pending_fiat_deposits_gtq: float # Pending deposits in GTQ + current_sats_fiat_value_gtq: float # Current fiat value of total sats in GTQ + average_cost_basis: float # Average sats per GTQ + current_fiat_balance_gtq: float # Available balance for DCA in GTQ + total_transactions: int + dca_mode: str # 'flow' or 'fixed' + dca_status: str # 'active' or 'inactive' + last_transaction_date: Optional[datetime] + currency: str = "GTQ" + + +class ClientTransactionAPI(BaseModel): + """API model - client transaction in GTQ""" + id: str + amount_sats: int + amount_fiat_gtq: float # Amount in GTQ + exchange_rate: float + transaction_type: str # 'flow', 'fixed', 'manual' + status: str + created_at: datetime + transaction_time: Optional[datetime] = None # Original ATM transaction time + lamassu_transaction_id: Optional[str] = None + + +# Internal Models for Client Dashboard (Database storage in centavos) class ClientDashboardSummary(BaseModel): - """Summary metrics for client dashboard overview""" + """Internal model - client dashboard summary stored in centavos""" user_id: str total_sats_accumulated: int total_fiat_invested: int # Confirmed deposits (in centavos) @@ -24,7 +54,7 @@ class ClientDashboardSummary(BaseModel): class ClientTransaction(BaseModel): - """Read-only view of client's DCA transactions""" + """Internal model - client transaction stored in centavos""" id: str amount_sats: int amount_fiat: int # Stored in centavos (GTQ * 100) for precision