62 lines
2 KiB
Python
62 lines
2 KiB
Python
|
|
"""
|
||
|
|
Egendefinerte baner på organisasjonsnivå (ADR-001: gjenbrukbar på tvers av
|
||
|
|
turneringer, samme mønster som players.py).
|
||
|
|
|
||
|
|
`course.source = 'custom'` er den eneste veien inn her -- 'official' (ekte
|
||
|
|
teeoff-baner via ADR-004 sitt planlagte, lesende API) er fortsatt kun vedtatt,
|
||
|
|
ikke bygget (se FEATURE_BACKLOG.md), og krever uansett `external_course_ref`
|
||
|
|
satt (skjemaets CHECK-constraint), som ingen klient kan oppgi meningsfullt
|
||
|
|
ennå. Denne runden dekker KUN det organisatoren trenger for å opprette en
|
||
|
|
økt: en bane ved navn, ingen hull-/tee-/rating-detaljer ennå (session-motoren
|
||
|
|
bruker foreløpig kun course_id som fremmednøkkel, ikke banens innhold).
|
||
|
|
"""
|
||
|
|
|
||
|
|
from fastapi import APIRouter, Depends
|
||
|
|
|
||
|
|
from ..auth import get_authorized_org
|
||
|
|
from ..db import org_connection
|
||
|
|
from ..errors import translate_db_errors
|
||
|
|
from pydantic import BaseModel, Field
|
||
|
|
|
||
|
|
router = APIRouter()
|
||
|
|
|
||
|
|
|
||
|
|
class CourseCreate(BaseModel):
|
||
|
|
name: str = Field(min_length=1, max_length=200)
|
||
|
|
|
||
|
|
|
||
|
|
class Course(BaseModel):
|
||
|
|
id: str
|
||
|
|
name: str
|
||
|
|
source: str
|
||
|
|
|
||
|
|
|
||
|
|
_COURSE_COLUMNS = "id::text, name, source::text AS source"
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/orgs/{organization_id}/courses", response_model=list[Course])
|
||
|
|
async def list_courses(
|
||
|
|
organization_id: str = Depends(get_authorized_org),
|
||
|
|
) -> list[Course]:
|
||
|
|
async with org_connection(organization_id) as conn:
|
||
|
|
rows = await conn.fetch(f"SELECT {_COURSE_COLUMNS} FROM course ORDER BY name")
|
||
|
|
return [Course(**dict(r)) for r in rows]
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/orgs/{organization_id}/courses", response_model=Course, status_code=201)
|
||
|
|
async def create_course(
|
||
|
|
body: CourseCreate,
|
||
|
|
organization_id: str = Depends(get_authorized_org),
|
||
|
|
) -> Course:
|
||
|
|
async with org_connection(organization_id) as conn, translate_db_errors():
|
||
|
|
row = await conn.fetchrow(
|
||
|
|
f"""
|
||
|
|
INSERT INTO course (organization_id, name, source)
|
||
|
|
VALUES ($1, $2, 'custom')
|
||
|
|
RETURNING {_COURSE_COLUMNS}
|
||
|
|
""",
|
||
|
|
organization_id,
|
||
|
|
body.name,
|
||
|
|
)
|
||
|
|
return Course(**dict(row))
|