Skip to content

refactor: wave 3 — split db/queries.py (1363 LOC) into a package#50

Merged
ty13r merged 1 commit intomainfrom
refactor/wave-3-db-queries
Apr 19, 2026
Merged

refactor: wave 3 — split db/queries.py (1363 LOC) into a package#50
ty13r merged 1 commit intomainfrom
refactor/wave-3-db-queries

Conversation

@ty13r
Copy link
Copy Markdown
Owner

@ty13r ty13r commented Apr 19, 2026

Summary

Wave 3 of the clean-code overhaul — decomposes the single biggest non-seed file in the backend.

db/queries.py was 1363 LOC / 46 functions. Every change forced a reviewer to re-scan the whole file. Now a package with one submodule per entity cluster:

Submodule LOC Owns
__init__.py 126 Barrel re-exporting every public name for backwards compat with 38 import sites
_helpers.py 53 _connect, _int_or_none, _row_get
challenges.py 63 Challenge CRUD
genomes.py 302 SkillGenome + CompetitionResult + Generation (the three row kinds a Generation owns)
runs.py 318 EvolutionRun + lineage + leaked skills + zombies
seeds.py 109 Candidate-seed registry
taxonomy.py 416 TaxonomyNode + SkillFamily + Variant + VariantEvolution
transcripts.py 125 Dispatch transcripts (v2.1.3 audit trail)

Largest submodule is now 416 LOC — under the 500-LOC ceiling in docs/clean-code.md §2. No behavior changes — every public name is still importable from skillforge.db.queries.

Why grouping, not one-file-per-entity

Generation, SkillGenome, and CompetitionResult are tightly coupled (a Generation owns a list of each). Splitting further would scatter related serialization code without clarifying anything. Same rationale for TaxonomyNode / SkillFamily / Variant / VariantEvolution — they're one v2.0 classification system. Runs + lineage + leaked + zombies are all top-level run-state operations.

Test plan

  • uv run ruff check skillforge — clean
  • uv run mypy skillforge — 61 files pass
  • uv run pytest tests/ — 403 passed, 2 skipped, 0 failed
  • cd frontend && npm run build / lint / format:check / test — untouched, still green

Follow-ups (future waves)

api/routes.py (707 LOC) and agents/spawner.py (805 LOC) are the remaining backend hotspots. Both are being held for their own PRs because:

  • routes.py touches many test fixtures and deserves a careful per-resource split
  • spawner.py is LLM logic that needs more care than a mechanical move

🤖 Generated with Claude Code

db/queries.py was the largest non-seed file in the backend at 1363 LOC
and 46 functions. Every change forced a reviewer to re-scan the whole
module. Splits it into a package with one submodule per entity:

  queries/
    __init__.py        barrel re-exporting every public name for
                       backward compatibility with the 38 import sites
    _helpers.py  (53)  _connect, _int_or_none, _row_get
    challenges.py (63) Challenge CRUD
    genomes.py   (302) SkillGenome + CompetitionResult + Generation —
                       the three row kinds a Generation owns
    runs.py      (318) EvolutionRun + lineage + leaked skills + zombies
    seeds.py     (109) candidate-seed registry
    taxonomy.py  (416) TaxonomyNode + SkillFamily + Variant +
                       VariantEvolution (related v2.0 entities)
    transcripts.py (125) dispatch transcripts (v2.1.3 audit trail)

Largest submodule is now 416 LOC, under the 500-LOC ceiling in
docs/clean-code.md §2. No behavior changes — every public name is
still importable from the same path.

QA
--
  ruff check skillforge      - clean
  mypy skillforge            - 61 files pass
  pytest tests/              - 403 passed, 2 skipped, 0 failed

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ty13r ty13r merged commit 591fad8 into main Apr 19, 2026
2 checks passed
@ty13r ty13r deleted the refactor/wave-3-db-queries branch April 19, 2026 18:12
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.

1 participant