Skip to content

refactor: split database.py god-object into focused repositories (#116)#138

Merged
adrunkhuman merged 1 commit intomasterfrom
refactor/split-database-116
Mar 21, 2026
Merged

refactor: split database.py god-object into focused repositories (#116)#138
adrunkhuman merged 1 commit intomasterfrom
refactor/split-database-116

Conversation

@adrunkhuman
Copy link
Owner

Summary

  • Replaces the 1094-line Database god-object with four focused repository modules (fixtures.py, predictions.py, results.py, scores.py) and a thin composition root in connection.py that delegates all CRUD and owns schema/migration on startup
  • All 11 call sites unchanged — from typer_bot.database import Database still works
  • SaveResult re-exported from __init__.py as before

Changes

File Role
connection.py Database facade + schema init + migration helpers
fixtures.py FixtureRepository (~190 lines)
predictions.py PredictionRepository + SaveResult (~270 lines)
results.py ResultsRepository (~90 lines)
scores.py ScoreRepository + module-level _fixture_has_scores_in_connection / _recalculate_scores_in_connection (~230 lines)

Cross-cutting recalculation helpers live as module-level functions in scores.py and are imported by predictions.py and results.py — no circular imports.

Additional fixes (caught in review)

  • results table schema: added CREATE UNIQUE INDEX IF NOT EXISTS after migrations so fresh installs get the constraint without relying solely on the migration path
  • Migration guard simplified: if unique_index_exists and "updated_at" in columnsif unique_index_exists:
  • _recalculate_scores_in_connection: wrapped body in try/finally to restore db.row_factory on all exit paths
  • save_scores: broadened except aiosqlite.Errorexcept Exception so non-SQLite exceptions also trigger explicit rollback and logging

Test plan

  • 305 tests pass, 1 skipped (pre-existing skip)
  • Monkeypatch targets in test_admin_service.py updated to patch module-level functions at their new locations (predictions_module._recalculate_scores_in_connection, results_module._recalculate_scores_in_connection)
  • test_database.py import updated from typer_bot.database.databasetyper_bot.database

Closes #116

🤖 Generated with Claude Code

Replaces the 1094-line Database class with four focused repository
modules (fixtures, predictions, results, scores) and a thin composition
root in connection.py that delegates all CRUD and owns schema/migration
on startup. All 11 call sites and the full test suite remain unchanged.

- connection.py: Database facade + schema init + migration helpers
- fixtures.py: FixtureRepository (~190 lines)
- predictions.py: PredictionRepository + SaveResult (~270 lines)
- results.py: ResultsRepository (~90 lines)
- scores.py: ScoreRepository + cross-cutting recalc helpers (~230 lines)

Monkeypatch targets in test_admin_service updated to patch the module-
level _recalculate_scores_in_connection function at its new location.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@railway-app railway-app bot temporarily deployed to patient-quietude / matchday-typer-pr-138 March 21, 2026 23:44 Destroyed
@railway-app
Copy link

railway-app bot commented Mar 21, 2026

🚅 Deployed to the matchday-typer-pr-138 environment in patient-quietude

Service Status Web Updated (UTC)
matchday-typer ✅ Success (View Logs) Mar 21, 2026 at 11:45 pm

@adrunkhuman adrunkhuman merged commit 775a002 into master Mar 21, 2026
2 checks passed
@adrunkhuman adrunkhuman deleted the refactor/split-database-116 branch March 21, 2026 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: split database.py god-object into focused repositories

1 participant