feat: add schedule data model (PracticeSchedule, Event, EventType) #234

Merged
forgejo_admin merged 1 commit from 232-schedule-data-model into main 2026-03-28 23:07:15 +00:00

Summary

Adds the data layer for schedule management: EventType enum, PracticeSchedule model (recurring weekly slots), and Event model (date-specific tournaments/games/camps/tryouts) with self-referencing FK for tournament-to-game nesting. Includes migration, seed script (8 Kings practices, 3 Kings tournaments, 5 Queens tournaments), and comprehensive tests.

Changes

  • src/basketball_api/models.py -- Added EventType enum (tournament, game, camp, tryout, other), PracticeSchedule model, Event model with self-referencing parent_event_id FK, and practice_schedules/events relationships on Tenant
  • alembic/env.py -- Added Event and PracticeSchedule imports for migration metadata
  • alembic/versions/029_add_schedule_tables.py -- Migration creating practice_schedules and events tables with indexes, eventtype enum, and clean downgrade
  • scripts/seed_schedule.py -- Idempotent seed script populating current hardcoded schedule data
  • tests/test_schedule.py -- 15 tests covering enum values, model CRUD, nullable fields, self-referencing FK, tenant relationships, table existence, and seed idempotency

Test Plan

  • pytest tests/ -v -- 655 tests pass (15 new schedule tests + all existing)
  • Seed idempotency verified: running seed twice produces no duplicates
  • All EventType values persist and round-trip correctly
  • Self-referencing parent_event_id tested (tournament -> game nesting)

Review Checklist

  • Models follow Mapped[type] = mapped_column() pattern
  • server_default=func.now() for created_at
  • server_default=text("true") for is_active (matches is_public on Player)
  • tenant_id FK with index=True on both tables
  • Tenant relationships added for both models
  • Migration tested (upgrade creates tables, downgrade drops them + enum)
  • Seed script is idempotent
  • ruff format + ruff check pass
  • All 655 tests pass
  • No unrelated changes
  • No pal-e-docs notes modified
## Summary Adds the data layer for schedule management: `EventType` enum, `PracticeSchedule` model (recurring weekly slots), and `Event` model (date-specific tournaments/games/camps/tryouts) with self-referencing FK for tournament-to-game nesting. Includes migration, seed script (8 Kings practices, 3 Kings tournaments, 5 Queens tournaments), and comprehensive tests. ## Changes - `src/basketball_api/models.py` -- Added `EventType` enum (tournament, game, camp, tryout, other), `PracticeSchedule` model, `Event` model with self-referencing `parent_event_id` FK, and `practice_schedules`/`events` relationships on `Tenant` - `alembic/env.py` -- Added `Event` and `PracticeSchedule` imports for migration metadata - `alembic/versions/029_add_schedule_tables.py` -- Migration creating `practice_schedules` and `events` tables with indexes, `eventtype` enum, and clean downgrade - `scripts/seed_schedule.py` -- Idempotent seed script populating current hardcoded schedule data - `tests/test_schedule.py` -- 15 tests covering enum values, model CRUD, nullable fields, self-referencing FK, tenant relationships, table existence, and seed idempotency ## Test Plan - `pytest tests/ -v` -- 655 tests pass (15 new schedule tests + all existing) - Seed idempotency verified: running seed twice produces no duplicates - All EventType values persist and round-trip correctly - Self-referencing parent_event_id tested (tournament -> game nesting) ## Review Checklist - [x] Models follow `Mapped[type] = mapped_column()` pattern - [x] `server_default=func.now()` for created_at - [x] `server_default=text("true")` for is_active (matches is_public on Player) - [x] tenant_id FK with `index=True` on both tables - [x] Tenant relationships added for both models - [x] Migration tested (upgrade creates tables, downgrade drops them + enum) - [x] Seed script is idempotent - [x] ruff format + ruff check pass - [x] All 655 tests pass - [x] No unrelated changes ## Related Notes - No pal-e-docs notes modified ## Related - Parent: forgejo_admin/basketball-api#230 - Sibling: #233 (API endpoints, separate ticket) - Closes #232
feat: add schedule data model (PracticeSchedule, Event, EventType)
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ca0db72a5b
Add EventType enum, PracticeSchedule and Event models with migration,
seed script, and tests for the schedule data layer (issue #232).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author
Owner

QA Review -- PR #234

Acceptance Criteria Verification

Criterion Status
EventType enum with values: tournament, game, camp, tryout, other PASS
PracticeSchedule model with all specified columns PASS
Event model with all specified columns PASS
Alembic migration runs cleanly (upgrade and downgrade) PASS
Seed script populates: 8 Kings practices, 3 Kings tournaments, 5 Queens tournaments PASS
Existing tests still pass (655 passed) PASS

Constraint Compliance

Constraint Status
Mapped[type] = mapped_column() pattern PASS
server_default=func.now() for created_at PASS
server_default=text("true") for is_active PASS
Tenant FK with index=True on both tables PASS
practice_schedules and events relationships on Tenant PASS
No changes to routes or schemas PASS

Test Coverage

  • 15 new tests in test_schedule.py
  • EventType enum values verified
  • PracticeSchedule: required fields, all fields, nullable optionals, tenant relationship
  • Event: required fields, all fields, nullable optionals, self-referencing FK, tenant relationship, all event types round-trip
  • Migration table existence verified
  • Seed idempotency verified (insert twice, count once)

Migration Review

  • Revision 029, down_revision 028 -- chain is correct
  • eventtype enum created with checkfirst=True in upgrade
  • eventtype enum dropped with checkfirst=True in downgrade
  • Reuses existing division enum with create_constraint=False -- correct
  • Indexes created for tenant_id, team_id, parent_event_id -- matches model definitions

Findings

No issues found. Implementation matches the issue spec (#232) exactly across all acceptance criteria and constraints.

VERDICT: APPROVED

## QA Review -- PR #234 ### Acceptance Criteria Verification | Criterion | Status | |-----------|--------| | `EventType` enum with values: tournament, game, camp, tryout, other | PASS | | `PracticeSchedule` model with all specified columns | PASS | | `Event` model with all specified columns | PASS | | Alembic migration runs cleanly (upgrade and downgrade) | PASS | | Seed script populates: 8 Kings practices, 3 Kings tournaments, 5 Queens tournaments | PASS | | Existing tests still pass (655 passed) | PASS | ### Constraint Compliance | Constraint | Status | |------------|--------| | `Mapped[type] = mapped_column()` pattern | PASS | | `server_default=func.now()` for created_at | PASS | | `server_default=text("true")` for is_active | PASS | | Tenant FK with `index=True` on both tables | PASS | | `practice_schedules` and `events` relationships on Tenant | PASS | | No changes to routes or schemas | PASS | ### Test Coverage - 15 new tests in `test_schedule.py` - EventType enum values verified - PracticeSchedule: required fields, all fields, nullable optionals, tenant relationship - Event: required fields, all fields, nullable optionals, self-referencing FK, tenant relationship, all event types round-trip - Migration table existence verified - Seed idempotency verified (insert twice, count once) ### Migration Review - Revision 029, down_revision 028 -- chain is correct - `eventtype` enum created with `checkfirst=True` in upgrade - `eventtype` enum dropped with `checkfirst=True` in downgrade - Reuses existing `division` enum with `create_constraint=False` -- correct - Indexes created for tenant_id, team_id, parent_event_id -- matches model definitions ### Findings No issues found. Implementation matches the issue spec (#232) exactly across all acceptance criteria and constraints. VERDICT: APPROVED
forgejo_admin deleted branch 232-schedule-data-model 2026-03-28 23:07:15 +00:00
Sign in to join this conversation.
No description provided.