from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, delete from sqlalchemy.orm import selectinload from typing import List from pydantic import BaseModel from datetime import datetime import uuid from app.db.database import get_db from app.db.models import WatchlistGroup, WatchlistItem router = APIRouter() # --- Schemas --- class WatchlistItemSchema(BaseModel): stock_code: str added_at: datetime class Config: from_attributes = True class WatchlistGroupSchema(BaseModel): id: str name: str market: str items: List[WatchlistItemSchema] = [] class Config: from_attributes = True class CreateGroupRequest(BaseModel): name: str market: str codes: List[str] = [] class UpdateGroupRequest(BaseModel): name: str | None = None codes: List[str] | None = None # --- Endpoints --- @router.get("/", response_model=List[WatchlistGroupSchema]) async def get_watchlists(db: AsyncSession = Depends(get_db)): # Load groups with items (Need relationship setup? # Current models.py WatchlistGroup doesn't have `items` relationship defined explicitly in snippet provided? # Let's assume we need to join manually or update models. # Checking models.py... WatchlistItem has foreign key. # Ideally should add `items = relationship("WatchlistItem")` to WatchlistGroup. # For now, let's just fetch items separately or via join. pass # Creating relationship on the fly or assuming simple manual join for safety. stmt = select(WatchlistGroup) result = await db.execute(stmt) groups = result.scalars().all() resp = [] for g in groups: # Fetch items stmt_items = select(WatchlistItem).where(WatchlistItem.group_id == g.id) res_items = await db.execute(stmt_items) items = res_items.scalars().all() g_schema = WatchlistGroupSchema( id=g.id, name=g.name, market=g.market, items=[WatchlistItemSchema.model_validate(i) for i in items] ) resp.append(g_schema) return resp @router.post("/", response_model=WatchlistGroupSchema) async def create_watchlist(req: CreateGroupRequest, db: AsyncSession = Depends(get_db)): gid = str(uuid.uuid4()) group = WatchlistGroup(id=gid, name=req.name, market=req.market) db.add(group) items = [] for code in req.codes: item = WatchlistItem(group_id=gid, stock_code=code) db.add(item) items.append(item) await db.commit() return WatchlistGroupSchema( id=gid, name=req.name, market=req.market, items=[WatchlistItemSchema(stock_code=i.stock_code, added_at=i.added_at) for i in items] ) @router.delete("/{group_id}") async def delete_watchlist(group_id: str, db: AsyncSession = Depends(get_db)): # Delete items first (Cascade usually handls this but explicit is safe) await db.execute(delete(WatchlistItem).where(WatchlistItem.group_id == group_id)) await db.execute(delete(WatchlistGroup).where(WatchlistGroup.id == group_id)) await db.commit() return {"status": "deleted"}