""" 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. Utvidet profil (ADR-017): kontakt-/identitetsfelt brukt til å matche en selvregistrerende spiller mot en allerede organisator-opprettet rad på e-post (se app/routers/registration.py), og senere til å koble app_user.id på (app/routers/auth.py sin verify_magic_link). """ from datetime import date from fastapi import APIRouter, Depends from pydantic import BaseModel, EmailStr, 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]$") mobile: str | None = None email: EmailStr | None = None birth_date: date | None = None nickname: str | None = None country: str | None = None club: str | None = None club_member_number: str | None = None class Player(BaseModel): id: str display_name: str handicap_index: float | None gender: str | None mobile: str | None email: str | None birth_date: date | None nickname: str | None country: str | None club: str | None club_member_number: str | None _PLAYER_COLUMNS = """ id::text, display_name, handicap_index::float AS handicap_index, gender, mobile, email, birth_date, nickname, country, club, club_member_number """ @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( f"SELECT {_PLAYER_COLUMNS} 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( f""" INSERT INTO player (organization_id, display_name, handicap_index, gender, mobile, email, birth_date, nickname, country, club, club_member_number) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING {_PLAYER_COLUMNS} """, organization_id, body.display_name, body.handicap_index, body.gender, body.mobile, body.email.lower() if body.email else None, body.birth_date, body.nickname, body.country, body.club, body.club_member_number, ) return Player(**dict(row))