arbret/backend/routes/counter.py

65 lines
2 KiB
Python
Raw Normal View History

2025-12-20 22:18:14 +01:00
"""Counter routes."""
from fastapi import APIRouter, Depends, HTTPException
2025-12-20 22:18:14 +01:00
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
2025-12-20 22:18:14 +01:00
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."""
2025-12-20 22:18:14 +01:00
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
2025-12-20 22:18:14 +01:00
await db.commit()
return {"value": counter.value}