Files
KisStock/backend/app/api/endpoints/watchlist.py

96 lines
3.1 KiB
Python

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("/groups", 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"}