- Added new modules for advisor compliance, KYC sessions, and script templates, enhancing the advisor agent's capabilities. - Implemented a comprehensive API structure under the `/api/advisor-agent` prefix, ensuring clear organization and access to new features. - Established database models and repositories for compliance rules and KYC sessions, facilitating robust data management. - Integrated exception handling and response models to improve error management and user feedback. - Updated settings to include new configurations for compliance and KYC features, ensuring flexibility and adaptability. This update significantly expands the advisor agent's functionality, providing essential tools for compliance and customer interaction while maintaining a structured API design.
107 lines
3.9 KiB
Python
107 lines
3.9 KiB
Python
"""Market alert and market data APIs."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import date
|
|
|
|
from fastapi import APIRouter, Depends, Query, Request
|
|
|
|
from app.api.advisor_auth_adapter import AdvisorAuthContext, get_advisor_auth, require_advisor_permission
|
|
from app.model.advisor_schemas import (
|
|
MarketAlertFeedbackRequest,
|
|
MarketAlertGenerationRequest,
|
|
MarketAlertList,
|
|
MarketAlertScanRequest,
|
|
MarketAlertView,
|
|
)
|
|
from app.repository.market_alert_repository import MarketAlertRepository
|
|
from app.service.market_alert_feedback_service import MarketAlertFeedbackService
|
|
from app.service.market_alert_generation_service import MarketAlertGenerationService
|
|
from app.service.market_data_service import MarketDataService
|
|
from app.service.market_scan_service import MarketScanService
|
|
from app.api.advisor_http import advisor_ok as _advisor_ok
|
|
|
|
router = APIRouter(prefix="/api/advisor-agent/market-alerts", tags=["advisor-agent-market-alerts"])
|
|
fund_router = APIRouter(prefix="/api/advisor-agent/market", tags=["advisor-agent-market"])
|
|
AUTH_CONTEXT_DEP = Depends(get_advisor_auth)
|
|
MARKET_READ_DEP = Depends(require_advisor_permission("market_alert:read"))
|
|
MARKET_GENERATE_DEP = Depends(require_advisor_permission("market_alert:generate"))
|
|
MARKET_FEEDBACK_DEP = Depends(require_advisor_permission("market_alert:feedback"))
|
|
market_data_service = MarketDataService()
|
|
market_alert_repository = MarketAlertRepository()
|
|
market_scan_service = MarketScanService(repository=market_alert_repository)
|
|
market_alert_generation_service = MarketAlertGenerationService(repository=market_alert_repository)
|
|
market_alert_feedback_service = MarketAlertFeedbackService(repository=market_alert_repository)
|
|
|
|
|
|
@router.get("/ping")
|
|
def ping(request: Request, auth: AdvisorAuthContext = AUTH_CONTEXT_DEP):
|
|
return _advisor_ok(request, {"module": "market", "status": "ready"})
|
|
|
|
|
|
@router.get("")
|
|
def list_market_alerts(
|
|
request: Request,
|
|
auth: AdvisorAuthContext = MARKET_READ_DEP,
|
|
date: date | None = None,
|
|
status: str | None = None,
|
|
alert_type: str | None = None,
|
|
):
|
|
rows = market_alert_repository.list_alerts(nav_date=date, status=status, alert_type=alert_type)
|
|
result = MarketAlertList(items=[MarketAlertView.model_validate(row) for row in rows])
|
|
return _advisor_ok(request, result.model_dump(mode="json"))
|
|
|
|
|
|
@router.post("/scan")
|
|
def scan_market_alerts(
|
|
request: Request,
|
|
payload: MarketAlertScanRequest,
|
|
auth: AdvisorAuthContext = MARKET_GENERATE_DEP,
|
|
):
|
|
result = market_scan_service.scan(
|
|
nav_date=payload.nav_date,
|
|
threshold_pct=payload.threshold_pct,
|
|
trace_id=request.state.trace_id,
|
|
)
|
|
return _advisor_ok(request, result.model_dump(mode="json"))
|
|
|
|
|
|
@router.post("/generate")
|
|
def generate_market_alert(
|
|
request: Request,
|
|
payload: MarketAlertGenerationRequest,
|
|
auth: AdvisorAuthContext = MARKET_GENERATE_DEP,
|
|
):
|
|
result = market_alert_generation_service.generate(
|
|
fund_code=payload.fund_code,
|
|
trace_id=request.state.trace_id,
|
|
advisor_id=auth.advisor_id or auth.user_id,
|
|
)
|
|
return _advisor_ok(request, result.model_dump(mode="json"))
|
|
|
|
|
|
@router.put("/{alert_id}/feedback")
|
|
def feedback_market_alert(
|
|
alert_id: str,
|
|
request: Request,
|
|
payload: MarketAlertFeedbackRequest,
|
|
auth: AdvisorAuthContext = MARKET_FEEDBACK_DEP,
|
|
):
|
|
result = market_alert_feedback_service.feedback(
|
|
alert_id=alert_id,
|
|
payload=payload,
|
|
auth=auth,
|
|
trace_id=request.state.trace_id,
|
|
)
|
|
return _advisor_ok(request, result.model_dump(mode="json"))
|
|
|
|
|
|
@fund_router.get("/fund/{fund_code}")
|
|
def get_fund_quote(
|
|
fund_code: str,
|
|
request: Request,
|
|
auth: AdvisorAuthContext = MARKET_READ_DEP,
|
|
history_limit: int = Query(default=30, ge=1, le=365),
|
|
):
|
|
result = market_data_service.get_fund_quote(fund_code, history_limit=history_limit)
|
|
return _advisor_ok(request, result.model_dump(mode="json")) |