first commit
Some checks failed
Deploy / lint (push) Failing after 7s
Deploy / test (push) Has been skipped
Deploy / deploy (push) Has been skipped

This commit is contained in:
Dennis Thiessen
2026-02-20 17:31:01 +01:00
commit 61ab24490d
160 changed files with 17034 additions and 0 deletions

75
app/routers/scores.py Normal file
View File

@@ -0,0 +1,75 @@
"""Scores router — scoring engine endpoints."""
from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from app.dependencies import get_db, require_access
from app.schemas.common import APIEnvelope
from app.schemas.score import (
DimensionScoreResponse,
RankingEntry,
RankingResponse,
ScoreResponse,
WeightUpdateRequest,
)
from app.services.scoring_service import get_rankings, get_score, update_weights
router = APIRouter(tags=["scores"])
@router.get("/scores/{symbol}", response_model=APIEnvelope)
async def read_score(
symbol: str,
_user=Depends(require_access),
db: AsyncSession = Depends(get_db),
) -> APIEnvelope:
"""Get composite + dimension scores for a symbol. Recomputes stale scores."""
result = await get_score(db, symbol)
data = ScoreResponse(
symbol=result["symbol"],
composite_score=result["composite_score"],
composite_stale=result["composite_stale"],
weights=result["weights"],
dimensions=[
DimensionScoreResponse(**d) for d in result["dimensions"]
],
missing_dimensions=result["missing_dimensions"],
computed_at=result["computed_at"],
)
return APIEnvelope(status="success", data=data.model_dump(mode="json"))
@router.get("/rankings", response_model=APIEnvelope)
async def read_rankings(
_user=Depends(require_access),
db: AsyncSession = Depends(get_db),
) -> APIEnvelope:
"""Get all tickers ranked by composite score descending."""
result = await get_rankings(db)
data = RankingResponse(
rankings=[
RankingEntry(
symbol=r["symbol"],
composite_score=r["composite_score"],
dimensions=[
DimensionScoreResponse(**d) for d in r["dimensions"]
],
)
for r in result["rankings"]
],
weights=result["weights"],
)
return APIEnvelope(status="success", data=data.model_dump(mode="json"))
@router.put("/scores/weights", response_model=APIEnvelope)
async def update_score_weights(
body: WeightUpdateRequest,
_user=Depends(require_access),
db: AsyncSession = Depends(get_db),
) -> APIEnvelope:
"""Update dimension weights and recompute all composite scores."""
new_weights = await update_weights(db, body.weights)
return APIEnvelope(status="success", data={"weights": new_weights})