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]: async def get_analytics(self, period_type: str = "daily") -> dict[str, Any]:
"""Get marketplace analytics""" """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 { return {
"period_type": period_type, "period_type": period_type,
"total_offers": 0, "total_offers": total_offers,
"total_transactions": 0, "total_bids": total_bids,
"total_volume": 0.0, "total_capacity": total_capacity,
"average_price": 0.0, "average_price": round(float(avg_price), 2),
} }

View File

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

View File

@@ -4,16 +4,19 @@ Trading service for managing trading operations
from typing import Any 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 from ..domain.trading import TradeRequest, TradeMatch, TradeAgreement
class TradingService: class TradingService:
def __init__(self, session: Session): def __init__(self, session: AsyncSession):
self.session = session self.session = session
def list_requests( async def list_requests(
self, self,
status: str | None = None, status: str | None = None,
buyer_agent_id: 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) stmt = stmt.where(TradeRequest.buyer_agent_id == buyer_agent_id)
if trade_type: if trade_type:
stmt = stmt.where(TradeRequest.trade_type == 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""" """Get a specific trade request"""
stmt = select(TradeRequest).where(TradeRequest.request_id == request_id) stmt = select(TradeRequest).where(TradeRequest.request_id == request_id)
result = self.session.execute(stmt).first() result = await self.session.execute(stmt)
return result[0] if result else None 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""" """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) request = TradeRequest(**request_data)
self.session.add(request) self.session.add(request)
self.session.commit() await self.session.commit()
self.session.refresh(request) await self.session.refresh(request)
return request return request
def list_matches( async def list_matches(
self, self,
status: str | None = None, status: str | None = None,
buyer_agent_id: 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) stmt = stmt.where(TradeMatch.buyer_agent_id == buyer_agent_id)
if seller_agent_id: if seller_agent_id:
stmt = stmt.where(TradeMatch.seller_agent_id == 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""" """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) match = TradeMatch(**match_data)
self.session.add(match) self.session.add(match)
self.session.commit() await self.session.commit()
self.session.refresh(match) await self.session.refresh(match)
return match return match
def list_agreements( async def list_agreements(
self, self,
status: str | None = None, status: str | None = None,
buyer_agent_id: 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) stmt = stmt.where(TradeAgreement.buyer_agent_id == buyer_agent_id)
if seller_agent_id: if seller_agent_id:
stmt = stmt.where(TradeAgreement.seller_agent_id == 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""" """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) agreement = TradeAgreement(**agreement_data)
self.session.add(agreement) self.session.add(agreement)
self.session.commit() await self.session.commit()
self.session.refresh(agreement) await self.session.refresh(agreement)
return agreement return agreement
async def get_analytics(self, period_type: str = "daily") -> dict[str, Any]: async def get_analytics(self, period_type: str = "daily") -> dict[str, Any]:
"""Get trading analytics""" """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 { return {
"period_type": period_type, "period_type": period_type,
"total_trades": 0, "total_requests": total_requests,
"completed_trades": 0, "total_matches": total_matches,
"total_agreements": total_agreements,
"total_trades": total_requests,
"completed_trades": total_agreements,
"total_trade_volume": 0.0, "total_trade_volume": 0.0,
"average_trade_value": 0.0, "average_trade_value": 0.0,
} }