Validation #927 — basketball-api#422 — 16U Local Queens team
Validation: Board Item #927 — basketball-api#422
Summary
- Board item: #927 on
board-westside-basketball - Ticket: basketball-api#422 — Create 16U Local Queens team
- PR: forgejo_admin/basketball-api#427
- Merged: 2026-04-10
- Repo type: API (basketball-api)
- Environment: prod
- Verdict: PARTIAL
What Shipped
Alembic migration 040 inserts one row into the
teams table with name='16U Local Queens', division='girls', and age_group='U16'. contract_config is cloned from LOCAL_CONFIG_16U (defined in migration 034).Checks Performed
- DB row exists:
SELECT id, name FROM teams WHERE name = '16U Local Queens'returned team id 12. PASS. - Migration applied:
alembic_versiontable shows revision 040 applied cleanly on prod pod. PASS. - contract_config correct: Matches
LOCAL_CONFIG_16Ufrom migration 034. PASS. - SQLAlchemy read compatibility: FAIL on initial read — triggered latent
AgeGroupenum mismatch.
Evidence
- SQL verification:
SELECT id, name FROM teams WHERE name = '16U Local Queens'→ id 12 alembic_versionat 040
Known Issue / Debt
The migration set
age_group='U16' on the new row. This triggered a latent bug: the Python AgeGroup enum has lowercase names (u16) mapped to uppercase values (U16), and the SQLAlchemy read-side fails with LookupError when loading the row. Mitigation applied in-session by Ava:
This matches the 7 other teams on prod, which all have
age_group NULL. Core deliverable (team row exists, contract_config correct, team usable via admin contract offer endpoint) is achieved, but the NULL workaround is known debt.Follow-up Required
- File a Forgejo issue for the proper
AgeGroupenum fix (root-cause the lowercase-name/uppercase-value mismatch soage_groupcan be populated in future migrations without manual NULLing).
Verdict Rationale
PARTIAL — the ticket's core goal (team row created with correct contract_config) is achieved and usable in prod. Deducted from PASS because a hand-applied SQL UPDATE was required post-merge to work around a latent enum bug. The workaround must be tracked as a follow-up ticket before this can be considered fully clean.