refactor(server): extract MetadataDB into lib/metadata_db.py (R3) - #830
Merged
Conversation
Move-only. The library metadata cache -- the `MetadataDB` class (4,018 lines) plus the query helpers it owns (keyset paging cursors, the tuning grouping key, smart-arrangement naming, tag normalisation, the startup DB-restore swap) -- moves out of server.py into a flat `lib/` module. Every moved block is byte-identical to its server.py original; server.py is exactly origin/main minus the six cut ranges, minus the now-dead `import contextlib`, plus the import-back block and the constructor call site. server.py: 14,037 -> 9,705 lines. The one non-verbatim change is the seam that lets the class leave server.py: `MetadataDB.__init__` now takes `config_dir` explicitly instead of reading the module-level CONFIG_DIR, so `lib/metadata_db.py` does no IO at import (Principle V). The `meta_db` singleton stays in server.py, so `server.meta_db` (282 refs) and `server.app` (67 refs) resolve unchanged and no route moves. None of the 114 `monkeypatch.setattr(server, ...)` targets moved. Logging still goes through the `feedBack.server` logger, so log filters and caplog assertions resolve to the same logger object. `tests/test_settings_export_library_db.py` imports `_apply_pending_db_restore` from metadata_db (the test moves with its subject); no other test changed. Verified: pyflakes clean on the new module (zero undefined names, zero unused imports) and no new undefined name in server.py; pytest 2341 passed; node --test 1030 passed; eslint 0 errors; uvicorn boot smoke serves /api/version, /api/library, and all three migrated plugins' src/ module graphs (stems, studio, editor -> 200). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthrough
ChangesMetadata database implementation
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
This was referenced Jul 10, 2026
This was referenced Jul 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First step of R3 (kill the core monoliths). Move-only, backend-only, zero behaviour change.
What moves
MetadataDB(4,018 lines) and the query helpers it owns — keyset paging cursors, the tuning grouping key (_tuning_group_key_sql), smart-arrangement naming (_ensure_smart_names/_arr_smart_sort_key), tag normalisation, the startup DB-restore swap (_apply_pending_db_restore/_sqlite_file_integrity_ok) — leaveserver.pyfor a new flatlib/metadata_db.py.server.py: 14,037 → 9,705 lines.lib/needs no infra change: it is alreadyCOPY lib/in the Dockerfile, bind-mounted indocker-compose.yml, and onPYTHONPATH=/app/lib:/app.The one non-verbatim change
MetadataDB.__init__takesconfig_direxplicitly instead of reading the module-levelCONFIG_DIR:That is the seam that lets the class leave
server.py, and it meanslib/metadata_db.pyperforms no IO at import — Principle V, and the reason this file belongs inlib/rather than a future root-levelappstate.py.Everything else is byte-identical. Mechanically verified two ways:
server.pyreconstructs exactly fromorigin/mainminus the six cut ranges, minus the now-deadimport contextlib, plus the import-back block and the constructor call site.What deliberately does not move
The
meta_dbsingleton stays inserver.py, soserver.meta_db(282 refs) andserver.app(67 refs) resolve unchanged, no route moves, and none of the 114monkeypatch.setattr(server, …)targets is affected. Logging still goes through thefeedBack.serverlogger, so log filters andcaplogassertions resolve to the same logger object.Tests
tests/test_settings_export_library_db.pyimports_apply_pending_db_restorefrommetadata_db— the test moves with its subject. Four call sites; no other test changed.Verification
no-undefgate):lib/metadata_db.pyclean — zero undefined names, zero unused imports.server.pygains no new undefined name. Exactly one import (contextlib) went dead with the move and was removed.pytest— 2341 passed, 4 skipped.node --test— 1030 passed.npm run lint— 0 errors.uvicorn server:appwith a seededDLC_DIRand the three migrated plugins symlinked —/api/versionand/api/libraryanswer, andstems/studio/editorall register asscript_type=modulewith theirsrc/main.jsmodule graphs serving200over the R0 route.Pre-existing issues found, deliberately not fixed here
server.py:1014—logger.exception(...)insideTuningProviderRegistry.get_merged()'sexcepthandler, butloggeris never defined (the module logger islog). A raising tuning provider turns a swallowed error into aNameError. Present onmain; own follow-up PR._KEYSET_ROW_IDXis defined and never read. Moved verbatim rather than deleted.Register
docs/size-exemptions.mdratcheted:server.py14,037 → 9,705.lib/metadata_db.py(4,373) added to Planned, NOT exempt — the class is a monolith in its own right and wants a per-table split once the router train lands.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes