"""Votes & engagement router.""" from uuid import UUID from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from app.database import get_db from app.models import User, Shader, Vote, EngagementEvent from app.schemas import VoteCreate from app.middleware.auth import get_current_user, get_optional_user router = APIRouter() @router.post("/shaders/{shader_id}/vote", status_code=status.HTTP_200_OK) async def vote_shader( shader_id: UUID, body: VoteCreate, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ): # Verify shader exists shader = (await db.execute(select(Shader).where(Shader.id == shader_id))).scalar_one_or_none() if not shader: raise HTTPException(status_code=404, detail="Shader not found") # Upsert vote existing = (await db.execute( select(Vote).where(Vote.user_id == user.id, Vote.shader_id == shader_id) )).scalar_one_or_none() if existing: existing.value = body.value else: db.add(Vote(user_id=user.id, shader_id=shader_id, value=body.value)) # TODO: Recalculate hot score (Track F) return {"status": "ok", "value": body.value} @router.delete("/shaders/{shader_id}/vote", status_code=status.HTTP_204_NO_CONTENT) async def remove_vote( shader_id: UUID, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ): existing = (await db.execute( select(Vote).where(Vote.user_id == user.id, Vote.shader_id == shader_id) )).scalar_one_or_none() if existing: await db.delete(existing) # TODO: Recalculate hot score (Track F) @router.post("/shaders/{shader_id}/replay", status_code=status.HTTP_204_NO_CONTENT) async def report_replay( shader_id: UUID, db: AsyncSession = Depends(get_db), user: User | None = Depends(get_optional_user), ): event = EngagementEvent( user_id=user.id if user else None, shader_id=shader_id, event_type="replay", ) db.add(event)