teecup/app/routers/players.py

63 lines
2 KiB
Python

"""
Spillerpool på organisasjonsnivå (ADR-001: gjenbrukbar på tvers av turneringer).
Kun org-medlemskap kreves (get_authorized_org) — å opprette en spiller i poolen
er organisator-arbeid, ikke noe som forutsetter rostring på et lag.
"""
from fastapi import APIRouter, Depends
from pydantic import BaseModel, Field
from ..auth import get_authorized_org
from ..db import org_connection
from ..errors import translate_db_errors
router = APIRouter()
class PlayerCreate(BaseModel):
display_name: str = Field(min_length=1, max_length=200)
handicap_index: float | None = None
gender: str | None = Field(default=None, pattern="^[mfx]$")
class Player(BaseModel):
id: str
display_name: str
handicap_index: float | None
gender: str | None
@router.get("/orgs/{organization_id}/players", response_model=list[Player])
async def list_players(
organization_id: str = Depends(get_authorized_org),
) -> list[Player]:
async with org_connection(organization_id) as conn:
rows = await conn.fetch(
"""
SELECT id::text, display_name, handicap_index::float AS handicap_index, gender
FROM player
ORDER BY display_name
"""
)
return [Player(**dict(r)) for r in rows]
@router.post("/orgs/{organization_id}/players", response_model=Player, status_code=201)
async def create_player(
body: PlayerCreate,
organization_id: str = Depends(get_authorized_org),
) -> Player:
async with org_connection(organization_id) as conn, translate_db_errors():
row = await conn.fetchrow(
"""
INSERT INTO player (organization_id, display_name, handicap_index, gender)
VALUES ($1, $2, $3, $4)
RETURNING id::text, display_name, handicap_index::float AS handicap_index, gender
""",
organization_id,
body.display_name,
body.handicap_index,
body.gender,
)
return Player(**dict(row))