feat(clubs): enhance co-trainer ID handling for training groups
All checks were successful
Deploy Development / deploy (push) Successful in 37s
Test Suite / pytest-backend (push) Successful in 25s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 8s
Test Suite / playwright-tests (push) Successful in 23s
Test Suite / pytest-backend (pull_request) Successful in 23s
Test Suite / lint-backend (pull_request) Successful in 0s
Test Suite / build-frontend (pull_request) Successful in 7s
Test Suite / playwright-tests (pull_request) Successful in 26s
All checks were successful
Deploy Development / deploy (push) Successful in 37s
Test Suite / pytest-backend (push) Successful in 25s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 8s
Test Suite / playwright-tests (push) Successful in 23s
Test Suite / pytest-backend (pull_request) Successful in 23s
Test Suite / lint-backend (pull_request) Successful in 0s
Test Suite / build-frontend (pull_request) Successful in 7s
Test Suite / playwright-tests (pull_request) Successful in 26s
- Introduced new functions to normalize and convert co-trainer IDs for JSONB storage. - Updated `create_training_group` and `update_training_group` methods to utilize the new JSONB handling for co-trainer IDs. - Ensured invalid entries are discarded and only unique, positive integers are stored.
This commit is contained in:
parent
bab9b178a4
commit
a7cecca36f
|
|
@ -5,6 +5,7 @@ Handles CRUD operations for clubs, divisions, and training groups.
|
||||||
"""
|
"""
|
||||||
from typing import Any, List, Optional
|
from typing import Any, List, Optional
|
||||||
from fastapi import APIRouter, HTTPException, Depends, Query
|
from fastapi import APIRouter, HTTPException, Depends, Query
|
||||||
|
from psycopg2.extras import Json
|
||||||
|
|
||||||
from db import get_db, get_cursor, r2d
|
from db import get_db, get_cursor, r2d
|
||||||
from tenant_context import TenantContext, get_tenant_context
|
from tenant_context import TenantContext, get_tenant_context
|
||||||
|
|
@ -39,6 +40,33 @@ def _optional_int(value: Any) -> Optional[int]:
|
||||||
return i if i > 0 else None
|
return i if i > 0 else None
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_co_trainer_ids(val: Any) -> List[int]:
|
||||||
|
"""Listen von Profil-IDs für JSONB; ungültige Einträge werden verworfen."""
|
||||||
|
if val is None:
|
||||||
|
raw: List[Any] = []
|
||||||
|
elif isinstance(val, list):
|
||||||
|
raw = val
|
||||||
|
else:
|
||||||
|
raw = []
|
||||||
|
out: List[int] = []
|
||||||
|
seen = set()
|
||||||
|
for x in raw:
|
||||||
|
try:
|
||||||
|
i = int(x)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
continue
|
||||||
|
if i <= 0 or i in seen:
|
||||||
|
continue
|
||||||
|
seen.add(i)
|
||||||
|
out.append(i)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def _co_trainer_ids_jsonb(val: Any) -> Json:
|
||||||
|
"""psycopg2: reine list/dict für JSONB → ProgrammingError ohne Json()."""
|
||||||
|
return Json(_normalize_co_trainer_ids(val))
|
||||||
|
|
||||||
|
|
||||||
# ── List Clubs ────────────────────────────────────────────────────────
|
# ── List Clubs ────────────────────────────────────────────────────────
|
||||||
@router.get("/clubs")
|
@router.get("/clubs")
|
||||||
def list_clubs(
|
def list_clubs(
|
||||||
|
|
@ -609,8 +637,7 @@ def create_training_group(data: dict, tenant: TenantContext = Depends(get_tenant
|
||||||
trainer_id = _optional_int(raw_tid)
|
trainer_id = _optional_int(raw_tid)
|
||||||
|
|
||||||
division_id = _optional_int(data.get("division_id"))
|
division_id = _optional_int(data.get("division_id"))
|
||||||
co_raw = data.get("co_trainer_ids")
|
co_json = _co_trainer_ids_jsonb(data.get("co_trainer_ids"))
|
||||||
co_trainer_ids = [] if co_raw is None else co_raw
|
|
||||||
|
|
||||||
with get_db() as conn:
|
with get_db() as conn:
|
||||||
cur = get_cursor(conn)
|
cur = get_cursor(conn)
|
||||||
|
|
@ -633,7 +660,7 @@ def create_training_group(data: dict, tenant: TenantContext = Depends(get_tenant
|
||||||
) VALUES (
|
) VALUES (
|
||||||
%s, %s, %s, %s, %s, %s,
|
%s, %s, %s, %s, %s, %s,
|
||||||
%s, %s, %s, %s,
|
%s, %s, %s, %s,
|
||||||
%s, %s, %s
|
%s, %s::jsonb, %s
|
||||||
) RETURNING id
|
) RETURNING id
|
||||||
""",
|
""",
|
||||||
(
|
(
|
||||||
|
|
@ -648,7 +675,7 @@ def create_training_group(data: dict, tenant: TenantContext = Depends(get_tenant
|
||||||
_blank_to_none(data.get("time_end")),
|
_blank_to_none(data.get("time_end")),
|
||||||
_blank_to_none(data.get("location")),
|
_blank_to_none(data.get("location")),
|
||||||
trainer_id,
|
trainer_id,
|
||||||
co_trainer_ids,
|
co_json,
|
||||||
data.get("status") or "active",
|
data.get("status") or "active",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -689,9 +716,7 @@ def update_training_group(group_id: int, data: dict, tenant: TenantContext = Dep
|
||||||
if not allowed:
|
if not allowed:
|
||||||
raise HTTPException(403, "Keine Berechtigung")
|
raise HTTPException(403, "Keine Berechtigung")
|
||||||
|
|
||||||
co_upd = data.get("co_trainer_ids")
|
co_json = _co_trainer_ids_jsonb(data.get("co_trainer_ids"))
|
||||||
if co_upd is None:
|
|
||||||
co_upd = []
|
|
||||||
|
|
||||||
cur.execute(
|
cur.execute(
|
||||||
"""
|
"""
|
||||||
|
|
@ -706,7 +731,7 @@ def update_training_group(group_id: int, data: dict, tenant: TenantContext = Dep
|
||||||
time_end = %s,
|
time_end = %s,
|
||||||
location = %s,
|
location = %s,
|
||||||
trainer_id = %s,
|
trainer_id = %s,
|
||||||
co_trainer_ids = %s,
|
co_trainer_ids = %s::jsonb,
|
||||||
status = %s,
|
status = %s,
|
||||||
updated_at = NOW()
|
updated_at = NOW()
|
||||||
WHERE id = %s
|
WHERE id = %s
|
||||||
|
|
@ -722,7 +747,7 @@ def update_training_group(group_id: int, data: dict, tenant: TenantContext = Dep
|
||||||
_blank_to_none(data.get("time_end")),
|
_blank_to_none(data.get("time_end")),
|
||||||
_blank_to_none(data.get("location")),
|
_blank_to_none(data.get("location")),
|
||||||
_optional_int(data.get("trainer_id")),
|
_optional_int(data.get("trainer_id")),
|
||||||
co_upd,
|
co_json,
|
||||||
data.get("status") or "active",
|
data.get("status") or "active",
|
||||||
group_id,
|
group_id,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user