fix: resolve trading service async/sync mismatch and enhance analytics
Some checks failed
Cross-Node Transaction Testing / transaction-test (push) Has been cancelled
Deploy to Testnet / deploy-testnet (push) Has been cancelled
Integration Tests / test-service-integration (push) Has been cancelled
Multi-Node Stress Testing / stress-test (push) Has been cancelled
Python Tests / test-python (push) Has been cancelled
Security Scanning / security-scan (push) Has been cancelled

- Fix TradingService: convert all methods to async to match AsyncSession
- Fix router: await all async service method calls in trading main.py
- Auto-generate request_id/match_id/agreement_id in create methods
- Enhance marketplace analytics: real counts, avg price, total capacity
- Enhance trading analytics: real request/match/agreement counts
- All trading endpoints now return data instead of 500 errors
This commit is contained in:
aitbc
2026-05-14 16:20:42 +02:00
parent 3a5b80a98f
commit f77ef06b0a
3 changed files with 89 additions and 35 deletions

View File

@@ -176,11 +176,34 @@ class MarketplaceService:
async def get_analytics(self, period_type: str = "daily") -> dict[str, Any]:
"""Get marketplace analytics"""
# Placeholder for analytics logic
from sqlalchemy import func, select
# Count offers
offer_count_stmt = select(func.count()).select_from(MarketplaceOffer)
offer_count_result = await self.session.execute(offer_count_stmt)
total_offers = offer_count_result.scalar() or 0
# Count bids
bid_count_stmt = select(func.count()).select_from(MarketplaceBid)
bid_count_result = await self.session.execute(bid_count_stmt)
total_bids = bid_count_result.scalar() or 0
# Average price of offers
avg_price_stmt = select(func.avg(MarketplaceOffer.price_per_hour)).where(
MarketplaceOffer.price_per_hour.isnot(None)
)
avg_price_result = await self.session.execute(avg_price_stmt)
avg_price = avg_price_result.scalar() or 0.0
# Total capacity
capacity_stmt = select(func.sum(MarketplaceOffer.capacity))
capacity_result = await self.session.execute(capacity_stmt)
total_capacity = capacity_result.scalar() or 0
return {
"period_type": period_type,
"total_offers": 0,
"total_transactions": 0,
"total_volume": 0.0,
"average_price": 0.0,
"total_offers": total_offers,
"total_bids": total_bids,
"total_capacity": total_capacity,
"average_price": round(float(avg_price), 2),
}

View File

@@ -115,7 +115,7 @@ async def get_requests(
svc: TradingService = Depends(get_trading_service),
):
"""Get trade requests"""
return svc.list_requests(status=status, buyer_agent_id=buyer_agent_id, trade_type=trade_type)
return await svc.list_requests(status=status, buyer_agent_id=buyer_agent_id, trade_type=trade_type)
@app.get("/v1/trading/requests/{request_id}")
@@ -124,7 +124,7 @@ async def get_request(
svc: TradingService = Depends(get_trading_service),
):
"""Get a specific trade request"""
return svc.get_request(request_id)
return await svc.get_request(request_id)
@app.post("/v1/trading/requests")
@@ -133,7 +133,7 @@ async def create_request(
svc: TradingService = Depends(get_trading_service),
):
"""Create a new trade request"""
return svc.create_request(request_data)
return await svc.create_request(request_data)
@app.get("/v1/trading/matches")
@@ -144,7 +144,7 @@ async def get_matches(
svc: TradingService = Depends(get_trading_service),
):
"""Get trade matches"""
return svc.list_matches(status=status, buyer_agent_id=buyer_agent_id, seller_agent_id=seller_agent_id)
return await svc.list_matches(status=status, buyer_agent_id=buyer_agent_id, seller_agent_id=seller_agent_id)
@app.post("/v1/trading/matches")
@@ -153,7 +153,7 @@ async def create_match(
svc: TradingService = Depends(get_trading_service),
):
"""Create a new trade match"""
return svc.create_match(match_data)
return await svc.create_match(match_data)
@app.get("/v1/trading/agreements")
@@ -164,7 +164,7 @@ async def get_agreements(
svc: TradingService = Depends(get_trading_service),
):
"""Get trade agreements"""
return svc.list_agreements(status=status, buyer_agent_id=buyer_agent_id, seller_agent_id=seller_agent_id)
return await svc.list_agreements(status=status, buyer_agent_id=buyer_agent_id, seller_agent_id=seller_agent_id)
@app.post("/v1/trading/agreements")
@@ -173,7 +173,7 @@ async def create_agreement(
svc: TradingService = Depends(get_trading_service),
):
"""Create a new trade agreement"""
return svc.create_agreement(agreement_data)
return await svc.create_agreement(agreement_data)
@app.get("/v1/trading/analytics")

View File

@@ -4,16 +4,19 @@ Trading service for managing trading operations
from typing import Any
from sqlmodel import Session, select
from uuid import uuid4
from sqlalchemy.ext.asyncio import AsyncSession
from sqlmodel import select
from ..domain.trading import TradeRequest, TradeMatch, TradeAgreement
class TradingService:
def __init__(self, session: Session):
def __init__(self, session: AsyncSession):
self.session = session
def list_requests(
async def list_requests(
self,
status: str | None = None,
buyer_agent_id: str | None = None,
@@ -27,23 +30,26 @@ class TradingService:
stmt = stmt.where(TradeRequest.buyer_agent_id == buyer_agent_id)
if trade_type:
stmt = stmt.where(TradeRequest.trade_type == trade_type)
return list(self.session.execute(stmt).all())
result = await self.session.execute(stmt)
return list(result.scalars().all())
def get_request(self, request_id: str) -> TradeRequest | None:
async def get_request(self, request_id: str) -> TradeRequest | None:
"""Get a specific trade request"""
stmt = select(TradeRequest).where(TradeRequest.request_id == request_id)
result = self.session.execute(stmt).first()
return result[0] if result else None
result = await self.session.execute(stmt)
return result.scalars().first()
def create_request(self, request_data: dict) -> TradeRequest:
async def create_request(self, request_data: dict) -> TradeRequest:
"""Create a new trade request"""
if "request_id" not in request_data:
request_data["request_id"] = f"req_{uuid4().hex[:8]}"
request = TradeRequest(**request_data)
self.session.add(request)
self.session.commit()
self.session.refresh(request)
await self.session.commit()
await self.session.refresh(request)
return request
def list_matches(
async def list_matches(
self,
status: str | None = None,
buyer_agent_id: str | None = None,
@@ -57,17 +63,20 @@ class TradingService:
stmt = stmt.where(TradeMatch.buyer_agent_id == buyer_agent_id)
if seller_agent_id:
stmt = stmt.where(TradeMatch.seller_agent_id == seller_agent_id)
return list(self.session.execute(stmt).all())
result = await self.session.execute(stmt)
return list(result.scalars().all())
def create_match(self, match_data: dict) -> TradeMatch:
async def create_match(self, match_data: dict) -> TradeMatch:
"""Create a new trade match"""
if "match_id" not in match_data:
match_data["match_id"] = f"match_{uuid4().hex[:8]}"
match = TradeMatch(**match_data)
self.session.add(match)
self.session.commit()
self.session.refresh(match)
await self.session.commit()
await self.session.refresh(match)
return match
def list_agreements(
async def list_agreements(
self,
status: str | None = None,
buyer_agent_id: str | None = None,
@@ -81,23 +90,45 @@ class TradingService:
stmt = stmt.where(TradeAgreement.buyer_agent_id == buyer_agent_id)
if seller_agent_id:
stmt = stmt.where(TradeAgreement.seller_agent_id == seller_agent_id)
return list(self.session.execute(stmt).all())
result = await self.session.execute(stmt)
return list(result.scalars().all())
def create_agreement(self, agreement_data: dict) -> TradeAgreement:
async def create_agreement(self, agreement_data: dict) -> TradeAgreement:
"""Create a new trade agreement"""
if "agreement_id" not in agreement_data:
agreement_data["agreement_id"] = f"agree_{uuid4().hex[:8]}"
agreement = TradeAgreement(**agreement_data)
self.session.add(agreement)
self.session.commit()
self.session.refresh(agreement)
await self.session.commit()
await self.session.refresh(agreement)
return agreement
async def get_analytics(self, period_type: str = "daily") -> dict[str, Any]:
"""Get trading analytics"""
# Placeholder for analytics logic
from sqlalchemy import func, select
# Count requests
req_count_stmt = select(func.count()).select_from(TradeRequest)
req_count_result = await self.session.execute(req_count_stmt)
total_requests = req_count_result.scalar() or 0
# Count matches
match_count_stmt = select(func.count()).select_from(TradeMatch)
match_count_result = await self.session.execute(match_count_stmt)
total_matches = match_count_result.scalar() or 0
# Count agreements
agree_count_stmt = select(func.count()).select_from(TradeAgreement)
agree_count_result = await self.session.execute(agree_count_stmt)
total_agreements = agree_count_result.scalar() or 0
return {
"period_type": period_type,
"total_trades": 0,
"completed_trades": 0,
"total_requests": total_requests,
"total_matches": total_matches,
"total_agreements": total_agreements,
"total_trades": total_requests,
"completed_trades": total_agreements,
"total_trade_volume": 0.0,
"average_trade_value": 0.0,
}