"""Counter routes.""" from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from auth import require_permission from database import get_db from jobs import enqueue_random_number_job from models import Counter, CounterRecord, Permission, User router = APIRouter(prefix="/api/counter", tags=["counter"]) async def get_or_create_counter(db: AsyncSession) -> Counter: """Get the singleton counter, creating it if it doesn't exist.""" result = await db.execute(select(Counter).where(Counter.id == 1)) counter = result.scalar_one_or_none() if not counter: counter = Counter(id=1, value=0) db.add(counter) await db.commit() await db.refresh(counter) return counter @router.get("") async def get_counter( db: AsyncSession = Depends(get_db), _current_user: User = Depends(require_permission(Permission.VIEW_COUNTER)), ) -> dict[str, int]: """Get the current counter value.""" counter = await get_or_create_counter(db) return {"value": counter.value} @router.post("/increment") async def increment_counter( db: AsyncSession = Depends(get_db), current_user: User = Depends(require_permission(Permission.INCREMENT_COUNTER)), ) -> dict[str, int]: """Increment the counter, record the action, and enqueue a random number job.""" counter = await get_or_create_counter(db) value_before = counter.value counter.value += 1 record = CounterRecord( user_id=current_user.id, value_before=value_before, value_after=counter.value, ) db.add(record) # Enqueue random number job - if this fails, the request fails try: await enqueue_random_number_job(current_user.id) except Exception as e: await db.rollback() raise HTTPException( status_code=500, detail=f"Failed to enqueue job: {e}" ) from e await db.commit() return {"value": counter.value}