Files
signal-platform/app/routers/watchlist.py
Dennis Thiessen 61ab24490d
Some checks failed
Deploy / lint (push) Failing after 7s
Deploy / test (push) Has been skipped
Deploy / deploy (push) Has been skipped
first commit
2026-02-20 17:31:01 +01:00

60 lines
1.9 KiB
Python

"""Watchlist router — manage user's curated watchlist."""
from fastapi import APIRouter, Depends, Query
from sqlalchemy.ext.asyncio import AsyncSession
from app.dependencies import get_db, require_access
from app.models.user import User
from app.schemas.common import APIEnvelope
from app.schemas.watchlist import WatchlistEntryResponse
from app.services.watchlist_service import (
add_manual_entry,
get_watchlist,
remove_entry,
)
router = APIRouter(tags=["watchlist"])
@router.get("/watchlist", response_model=APIEnvelope)
async def list_watchlist(
sort_by: str = Query(
"composite",
description=(
"Sort by: composite, rr, or a dimension name "
"(technical, sr_quality, sentiment, fundamental, momentum)"
),
),
user: User = Depends(require_access),
db: AsyncSession = Depends(get_db),
) -> APIEnvelope:
"""Get current user's watchlist with enriched data."""
rows = await get_watchlist(db, user.id, sort_by=sort_by)
data = [WatchlistEntryResponse(**r).model_dump(mode="json") for r in rows]
return APIEnvelope(status="success", data=data)
@router.post("/watchlist/{symbol}", response_model=APIEnvelope)
async def add_to_watchlist(
symbol: str,
user: User = Depends(require_access),
db: AsyncSession = Depends(get_db),
) -> APIEnvelope:
"""Add a manual entry to the watchlist."""
entry = await add_manual_entry(db, user.id, symbol)
return APIEnvelope(
status="success",
data={"symbol": symbol.strip().upper(), "entry_type": entry.entry_type},
)
@router.delete("/watchlist/{symbol}", response_model=APIEnvelope)
async def remove_from_watchlist(
symbol: str,
user: User = Depends(require_access),
db: AsyncSession = Depends(get_db),
) -> APIEnvelope:
"""Remove an entry from the watchlist."""
await remove_entry(db, user.id, symbol)
return APIEnvelope(status="success", data=None)