satmachineadmin/models.py
padreug c83ebf43ab 01 Refactor currency handling to store amounts in GTQ: Removed currency conversion utilities, updated models and API endpoints to directly handle GTQ amounts, and modified transaction processing logic for consistency. Enhanced frontend to reflect these changes, ensuring accurate display and submission of GTQ values across the application.
Refactor GTQ storage migration: Moved the conversion logic for centavo amounts to GTQ into a new migration function, m004_convert_to_gtq_storage, ensuring proper data type changes and updates across relevant tables. This enhances clarity and maintains the integrity of the migration process.
2025-07-06 00:13:03 +02:00

231 lines
6.7 KiB
Python

# Description: Pydantic data models dictate what is passed between frontend and backend.
from datetime import datetime
from typing import Optional
from pydantic import BaseModel, validator
# DCA Client Models
class CreateDcaClientData(BaseModel):
user_id: str
wallet_id: str
username: str
dca_mode: str = "flow" # 'flow' or 'fixed'
fixed_mode_daily_limit: Optional[float] = None
class DcaClient(BaseModel):
id: str
user_id: str
wallet_id: str
username: Optional[str]
dca_mode: str
fixed_mode_daily_limit: Optional[int]
status: str
created_at: datetime
updated_at: datetime
class UpdateDcaClientData(BaseModel):
username: Optional[str] = None
dca_mode: Optional[str] = None
fixed_mode_daily_limit: Optional[float] = None
status: Optional[str] = None
# Deposit Models (Now storing GTQ directly)
class CreateDepositData(BaseModel):
client_id: str
amount: float # Amount in GTQ (e.g., 150.75)
currency: str = "GTQ"
notes: Optional[str] = None
@validator('amount')
def round_amount_to_cents(cls, v):
"""Ensure amount is rounded to 2 decimal places for DECIMAL(10,2) storage"""
if v is not None:
return round(float(v), 2)
return v
class DcaDeposit(BaseModel):
id: str
client_id: str
amount: float # Amount in GTQ (e.g., 150.75)
currency: str
status: str # 'pending' or 'confirmed'
notes: Optional[str]
created_at: datetime
confirmed_at: Optional[datetime]
class UpdateDepositStatusData(BaseModel):
status: str
notes: Optional[str] = None
# Payment Models
class CreateDcaPaymentData(BaseModel):
client_id: str
amount_sats: int
amount_fiat: float # Amount in GTQ (e.g., 150.75)
exchange_rate: float
transaction_type: str # 'flow', 'fixed', 'manual', 'commission'
lamassu_transaction_id: Optional[str] = None
payment_hash: Optional[str] = None
transaction_time: Optional[datetime] = None # Original ATM transaction time
class DcaPayment(BaseModel):
id: str
client_id: str
amount_sats: int
amount_fiat: float # Amount in GTQ (e.g., 150.75)
exchange_rate: float
transaction_type: str
lamassu_transaction_id: Optional[str]
payment_hash: Optional[str]
status: str # 'pending', 'confirmed', 'failed'
created_at: datetime
transaction_time: Optional[datetime] = None # Original ATM transaction time
# Client Balance Summary (Now storing GTQ directly)
class ClientBalanceSummary(BaseModel):
client_id: str
total_deposits: float # Total confirmed deposits in GTQ
total_payments: float # Total payments made in GTQ
remaining_balance: float # Available balance for DCA in GTQ
currency: str
# Transaction Processing Models
class LamassuTransaction(BaseModel):
transaction_id: str
amount_fiat: float # Amount in GTQ (e.g., 150.75)
amount_crypto: int
exchange_rate: float
transaction_type: str # 'cash_in' or 'cash_out'
status: str
timestamp: datetime
# Lamassu Transaction Storage Models
class CreateLamassuTransactionData(BaseModel):
lamassu_transaction_id: str
fiat_amount: float # Amount in GTQ (e.g., 150.75)
crypto_amount: int
commission_percentage: float
discount: float = 0.0
effective_commission: float
commission_amount_sats: int
base_amount_sats: int
exchange_rate: float
crypto_code: str = "BTC"
fiat_code: str = "GTQ"
device_id: Optional[str] = None
transaction_time: datetime
class StoredLamassuTransaction(BaseModel):
id: str
lamassu_transaction_id: str
fiat_amount: float # Amount in GTQ (e.g., 150.75)
crypto_amount: int
commission_percentage: float
discount: float
effective_commission: float
commission_amount_sats: int
base_amount_sats: int
exchange_rate: float
crypto_code: str
fiat_code: str
device_id: Optional[str]
transaction_time: datetime
processed_at: datetime
clients_count: int # Number of clients who received distributions
distributions_total_sats: int # Total sats distributed to clients
# Lamassu Configuration Models
class CreateLamassuConfigData(BaseModel):
host: str
port: int = 5432
database_name: str
username: str
password: str
# Source wallet for DCA distributions
source_wallet_id: Optional[str] = None
# Commission wallet for storing commission earnings
commission_wallet_id: Optional[str] = None
# SSH Tunnel settings
use_ssh_tunnel: bool = False
ssh_host: Optional[str] = None
ssh_port: int = 22
ssh_username: Optional[str] = None
ssh_password: Optional[str] = None
ssh_private_key: Optional[str] = None # Path to private key file or key content
# DCA Client Limits
max_daily_limit_gtq: float = 2000.0 # Maximum daily limit for Fixed mode clients
@validator('max_daily_limit_gtq')
def round_max_daily_limit(cls, v):
"""Ensure max daily limit is rounded to 2 decimal places"""
if v is not None:
return round(float(v), 2)
return v
class LamassuConfig(BaseModel):
id: str
host: str
port: int
database_name: str
username: str
password: str
is_active: bool
test_connection_last: Optional[datetime]
test_connection_success: Optional[bool]
created_at: datetime
updated_at: datetime
# Source wallet for DCA distributions
source_wallet_id: Optional[str] = None
# Commission wallet for storing commission earnings
commission_wallet_id: Optional[str] = None
# SSH Tunnel settings
use_ssh_tunnel: bool = False
ssh_host: Optional[str] = None
ssh_port: int = 22
ssh_username: Optional[str] = None
ssh_password: Optional[str] = None
ssh_private_key: Optional[str] = None
# Poll tracking
last_poll_time: Optional[datetime] = None
last_successful_poll: Optional[datetime] = None
# DCA Client Limits
max_daily_limit_gtq: float = 2000.0 # Maximum daily limit for Fixed mode clients
class UpdateLamassuConfigData(BaseModel):
host: Optional[str] = None
port: Optional[int] = None
database_name: Optional[str] = None
username: Optional[str] = None
password: Optional[str] = None
is_active: Optional[bool] = None
# Source wallet for DCA distributions
source_wallet_id: Optional[str] = None
# Commission wallet for storing commission earnings
commission_wallet_id: Optional[str] = None
# SSH Tunnel settings
use_ssh_tunnel: Optional[bool] = None
ssh_host: Optional[str] = None
ssh_port: Optional[int] = None
ssh_username: Optional[str] = None
ssh_password: Optional[str] = None
ssh_private_key: Optional[str] = None
# DCA Client Limits
max_daily_limit_gtq: Optional[int] = None