from datetime import date from typing import Literal from fastapi import APIRouter, Depends from pydantic import BaseModel from sqlalchemy.orm import Session from app.core.database import get_db from app.core.background.task_queue.market import enqueue_market_report from app.core.security import ApiPrincipal, require_api_key from app.modules.market.service import MarketService router = APIRouter(dependencies=[Depends(require_api_key)]) class WatchlistRequest(BaseModel): symbol: str class MarketReportRequest(BaseModel): report_type: Literal["premarket", "close", "weekly"] reference_date: date | None = None force: bool = False @router.get("/overview") def overview( trade_date: date | None = None, include_ai: bool = False, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: return MarketService(db).market_overview(trade_date, include_ai, principal.actor) @router.get("/stocks/{symbol}/analysis") def stock_analysis( symbol: str, include_ai: bool = False, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: return MarketService(db).stock_analysis(symbol, include_ai, principal.actor) @router.get("/weekly") def weekly_overview( reference_date: date | None = None, include_ai: bool = False, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: return MarketService(db).weekly_overview(reference_date, include_ai, principal.actor) @router.get("/industries/{industry}/analysis") def industry_analysis(industry: str, db: Session = Depends(get_db)) -> dict: return MarketService(db).industry_analysis(industry) @router.get("/stocks/compare/{first}/{second}") def compare_stocks(first: str, second: str, db: Session = Depends(get_db)) -> dict: return MarketService(db).compare_stocks([first, second]) @router.get("/macro") def macro_overview( include_ai: bool = False, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: service = MarketService(db) return ( service.macro_analysis(include_ai=True, actor=principal.actor) if include_ai else service.macro_overview() ) @router.get("/announcements") def announcements( symbol: str | None = None, start_date: date | None = None, limit: int = 50, db: Session = Depends(get_db), ) -> dict: return MarketService(db).announcements(symbol, start_date, limit) @router.post("/sync/daily") def sync_daily(trade_date: date, db: Session = Depends(get_db)) -> dict: return MarketService(db).sync_daily(trade_date) @router.post("/sync/macro") def sync_macro(reference_date: date | None = None, db: Session = Depends(get_db)) -> dict: return MarketService(db).sync_macro(reference_date) @router.post("/sync/announcements") def sync_announcements( start_date: date, end_date: date, db: Session = Depends(get_db) ) -> dict: return {"processed": MarketService(db).sync_announcements(start_date, end_date)} @router.post("/reports/enqueue") def enqueue_report(payload: MarketReportRequest) -> dict: return enqueue_market_report(payload.report_type, payload.reference_date, payload.force) @router.post("/watchlist") def add_watchlist( payload: WatchlistRequest, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: return MarketService(db).add_watchlist(principal.actor, payload.symbol) @router.get("/watchlist") def watchlist( db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key) ) -> dict: return {"items": MarketService(db).watchlist(principal.actor)}