feat(backend): complete modular monolith with ledger, fastapi and websocket

This commit is contained in:
Bot
2026-08-31 01:02:16 +08:00
parent 9f6ecf33f9
commit 30dc22a989
16 changed files with 706 additions and 17 deletions
+76
View File
@@ -0,0 +1,76 @@
import pytest
import pytest_asyncio
from decimal import Decimal
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
from app.models.entities import Base, LedgerEntryType
from app.domains.ledger.service import LedgerService, InsufficientBalanceError
TEST_DATABASE_URL = "sqlite+aiosqlite:///:memory:"
@pytest_asyncio.fixture
async def test_session():
engine = create_async_engine(TEST_DATABASE_URL, echo=False)
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
session_maker = async_sessionmaker(engine, expire_on_commit=False, class_=AsyncSession)
async with session_maker() as session:
yield session
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.drop_all)
await engine.dispose()
@pytest.mark.asyncio
async def test_ledger_deposit_flow(test_session: AsyncSession):
ledger = LedgerService(test_session)
user = "0x6cddF384792C77219fc25C454Cfe264757842830"
# 1. 初始余额为 0
bal = await ledger.get_or_create_balance(user)
assert bal.available_balance == Decimal("0")
# 2. 存入 1000 WUSD
entry = await ledger.record_deposit(user, Decimal("1000"), "0xtx1")
assert entry.entry_type == LedgerEntryType.DEPOSIT
assert entry.amount == Decimal("1000")
assert entry.balance_after == Decimal("1000")
bal = await ledger.get_or_create_balance(user)
assert bal.available_balance == Decimal("1000")
@pytest.mark.asyncio
async def test_ledger_trade_and_insufficient_balance(test_session: AsyncSession):
ledger = LedgerService(test_session)
user = "0x6cddF384792C77219fc25C454Cfe264757842830"
# 充值 500 WUSD
await ledger.record_deposit(user, Decimal("500"), "0xtx1")
# 尝试买入 600 WUSD (超额报错)
with pytest.raises(InsufficientBalanceError):
await ledger.record_trade(
address=user,
market_address="0xmarket1",
order_id="order_1",
side="BUY",
amount=Decimal("600"),
fee=Decimal("3.6")
)
# 成功买入 100 WUSD (扣除 100 + 0.6 手续费)
entry = await ledger.record_trade(
address=user,
market_address="0xmarket1",
order_id="order_2",
side="BUY",
amount=Decimal("100"),
fee=Decimal("0.6")
)
assert entry.entry_type == LedgerEntryType.TRADE_BUY
assert entry.amount == Decimal("-100.6")
assert entry.balance_after == Decimal("399.4")
# 验证不可变流水历史条数
history = await ledger.list_user_ledger(user)
assert len(history) == 2