from fastapi import APIRouter, Depends from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from typing import List from pydantic import BaseModel from app.db.database import get_db from app.db.models import MasterStock, DiscoveryRankingCache, StockItem router = APIRouter() class StockItemSchema(BaseModel): code: str name: str market: str class Config: from_attributes = True class RankingItemSchema(BaseModel): code: str name: str price: float change: float changePercent: float class Config: from_attributes = True @router.get("/rankings", response_model=List[RankingItemSchema]) async def get_rankings(type: str = "rise", limit: int = 10, db: AsyncSession = Depends(get_db)): """ Get Top Rankings based on cached StockItem data. type: 'rise' (Top Gainers), 'fall' (Top Losers), 'volume' (Not impl yet) """ stmt = select(StockItem) if type == "fall": stmt = stmt.order_by(StockItem.changePercent.asc()) else: stmt = stmt.order_by(StockItem.changePercent.desc()) stmt = stmt.limit(limit) res = await db.execute(stmt) items = res.scalars().all() return items @router.get("/stocks/search", response_model=List[StockItemSchema]) async def search_stocks(query: str, db: AsyncSession = Depends(get_db)): # Search by name or code stmt = select(MasterStock).where( (MasterStock.name.like(f"%{query}%")) | (MasterStock.code.like(f"%{query}%")) ).limit(20) result = await db.execute(stmt) stocks = result.scalars().all() return stocks from app.services.master_service import master_service @router.get("/kis/master-stocks") async def sync_master_stocks(db: AsyncSession = Depends(get_db)): # Trigger Sync # Ideally should be BackgroundTasks, but for now await to show result await master_service.sync_master_data(db) # Return count stmt = select(MasterStock).limit(1) # Just return status return {"status": "Sync Complete"}