Skip to content

refactor(db): drop six verified-dead repository/bundle methods (vulture, #1136) - #1287

Merged
axisrow merged 1 commit into
mainfrom
ao/tg_content_factory_5863f66be3-65/dead-code-db
Jul 27, 2026
Merged

refactor(db): drop six verified-dead repository/bundle methods (vulture, #1136)#1287
axisrow merged 1 commit into
mainfrom
ao/tg_content_factory_5863f66be3-65/dead-code-db

Conversation

@axisrow

@axisrow axisrow commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Part of #1136 (vulture axis of epic #1130). Six methods deleted; each verified dead across all five surfaces (FastAPI/Web/CLI/agent/TUI) before removal. Per #1136, "dead by graph" ≠ "unneeded" — so every candidate passed a full grep + git-history check first.

For each: repo-wide grep (src/ tests/ scripts/ docs/ conftest.py) returned exactly 1 hit — the definition — with no string references. The codebase's dynamic repo access targets other specific names (clear_dialogs, get_recent_for_channels, get_channels, …), and the dispatcher's dynamic dispatch is f"_handle_{command}"-shaped and unrelated to any of these.

Repository methods (unused readers; the repo layer stays)

  1. ChannelsRepository.get_channels_by_tag — born in feat: RSS, tags, S3 storage, refinement pipeline, ReAct fallback, test fixes #271 (tags feature) with no caller (git grep at 2af529e: definition only). The tag feature's surfaces use list_all_tags/create_tag/delete_tag/set_channel_tags/get_channel_tags (see src/cli/commands/channel.py); this reverse reader ("channels by tag") was never wired to any surface.
  2. DialogCacheRepository.has_dialogs — born in bc2bddd (persist dialog cache) with no caller. Live dialog_cache methods (enumerated from call sites): clear_all_dialogs, clear_dialogs, count_dialogs, get_all_phones, get_cached_at, get_dialog, list_dialogs, replace_dialogshas_dialogs absent.
  3. GenerationRunsRepository.list_by_status — definition-only at every commit that touched it (feat: add 12 missing agent tools and fix ghost MODULE_GROUPS entries #292, [codex] close issue 554 audit gaps #555, feat(parity): close CLI ↔ Web ↔ Agent-tool parity gaps #780); moderation/runs surfaces use list_pending_moderation / list_runs instead.

Bundle wrappers (unused thin wrappers over LIVE repo methods that stay)

  1. AccountBundle.list_live_usable_accountsAccountsRepository.get_live_usable_accounts stays (17 live refs).
  2. AccountBundle.update_premiumAccountsRepository.update_account_premium stays (24 live refs).
  3. MessageBundle.get_message_statsMessagesRepository.get_stats stays (used via Database.get_stats → dashboard route).

No public-API/parity impact: none of the six is reachable from any of the five surfaces.

Verification (no regression guard possible — code is gone; proof = green suite + this note)

  • ruff check src/ tests/ conftest.py — clean.
  • Import smoke test for all four touched modules — OK.
  • pytest tests/repositories/ tests/test_bundles.py — 426 passed.
  • Full suite (pytest tests/ -m "not aiosqlite_serial" -n auto then -m aiosqlite_serial) — green. The only failures elsewhere are pre-existing on origin/main: tests/test_quality_scoring_service.py (7 tests fail on clean main) and the xdist-flaky tests/routes/test_debug_routes.py::test_debug_timing_page; both deselected and reproduced on clean main, unrelated to this diff.

Not deleted here (doubtful → left for owner decision)

  • "Test-only" code in the DB layer is absent from this PR; bundle wrappers like update_flood, save_stats, list_notification_queries are called only by their own unit tests and are deliberately left untouched pending owner call (test-locking vs delete-with-tests). They are flagged in the issue audit, not here.

Part of #1136 / #1130.

@axisrow
axisrow force-pushed the ao/tg_content_factory_5863f66be3-65/dead-code-db branch from ad6f390 to 67eb68a Compare July 27, 2026 14:50
…re, #1136)

Removes six methods flagged by vulture and verified dead across all five
surfaces (FastAPI/Web/CLI/agent/TUI). For each, repo-wide grep (src/ tests/
scripts/ docs/ conftest.py) returned exactly 1 hit — the definition — with
no string references. Dynamic repo access in the codebase targets other
specific names (clear_dialogs, get_recent_for_channels, get_channels, …);
the dispatcher's dynamic dispatch is f"_handle_{command}"-shaped and unrelated.

Repository methods (underlying repo layer stays — these are unused readers):
1. ChannelsRepository.get_channels_by_tag — born in #271 (tags feature) with
   no caller (git grep at 2af529e: definition only). The tag feature uses
   list_all_tags/create_tag/delete_tag/set_channel_tags/get_channel_tags
   (see src/cli/commands/channel.py); this reverse reader was never wired
   to any surface.
2. DialogCacheRepository.has_dialogs — born in bc2bddd with no caller. All
   live dialog_cache methods (enumerated from call sites): clear_all_dialogs,
   clear_dialogs, count_dialogs, get_all_phones, get_cached_at, get_dialog,
   list_dialogs, replace_dialogs — has_dialogs absent.
3. GenerationRunsRepository.list_by_status — definition-only at every commit
   that touched it (#292, #555, #780); moderation/runs surfaces use
   list_pending_moderation / list_runs instead.

Bundle wrappers (unused thin wrappers over LIVE repo methods that stay):
4. AccountBundle.list_live_usable_accounts — AccountsRepository.
   get_live_usable_accounts stays (17 live refs).
5. AccountBundle.update_premium — AccountsRepository.update_account_premium
   stays (24 live refs).
6. MessageBundle.get_message_stats — MessagesRepository.get_stats stays (used
   via Database.get_stats -> dashboard route).

No public-API/parity impact: none of the six is reachable from any of the
five surfaces.

Part of #1136 / #1130.

Co-Authored-By: Claude <noreply@anthropic.com>
@axisrow
axisrow force-pushed the ao/tg_content_factory_5863f66be3-65/dead-code-db branch from 67eb68a to cc101ad Compare July 27, 2026 14:53
@axisrow

axisrow commented Jul 27, 2026

Copy link
Copy Markdown
Owner Author

🔍 Local review (cycle 1)

Reviewed locally (/review + Codex companion sol/high), no bots pinged. Rebased onto fresh main (5300114) → head cc101ad.

Both reviewers: clean — 0 findings, Codex verdict approve.

Step 1.5 (dead-code re-verification on fresh main) — all 6 deleted methods show 0 references:

  • ChannelsRepository.get_channels_by_tag, DialogCacheRepository.has_dialogs, GenerationRunsRepository.list_by_status
  • AccountBundle.list_live_usable_accounts, AccountBundle.update_premium, MessageBundle.get_message_stats

Underlying repo methods stay live: get_live_usable_accounts (12 refs), update_account_premium (19), MessagesRepository.get_stats (56, via Database.get_stats→dashboard).

One self-found cosmetic issue fixed in this commit (cc101ad): removing update_premium left 4 consecutive blank lines in bundles.py (PEP8 wants 2) — collapsed to 2, ruff clean. (First Codex run on the pre-fix head hit a 600s turn budget on xhigh; reran on the amended head at high — clean.)

Codex exhaustive search confirmed: base had only the 6 definitions, diff deletes only those, 0 remaining refs across db.repos.* call sites / bundle access / dynamic getattr / migrations / seeds / tests / mocks / web·CLI·agent·TUI. Codex env is read-only so it couldn't run pytest itself — I ran the focused suite locally: 430 repos+bundles tests green, all 4 modules import OK.

No FIX, no UNVERIFIED on the final head → final cycle. Local mode does not merge — merge is yours to trigger.

@axisrow
axisrow merged commit ded7918 into main Jul 27, 2026
4 checks passed
axisrow added a commit that referenced this pull request Jul 27, 2026
bundles.py duplicated identical repository pass-through methods across
bundles (ChannelBundle/CollectionBundle channel+task ops, get_setting/
set_setting in four bundles, account reads in three, message search/batch
insert in two, scheduler task reads). jscpd flagged the top clone cluster
of issue #1135.

Consolidate each duplicated wrapper group into a repo-scoped plain-class
mixin (_ChannelOps, _CollectionTaskCreateOps, _CollectionTaskReadOps,
_SettingsOps, _NotificationQueriesOps, _MessageOps, _AccountReadOps,
_SearchLogReadOps). Mixins are deliberately NOT dataclasses: their
attribute annotations do not become dataclass fields, so every bundle's
positional constructor order is unchanged.

Rebased onto a main where #1287 (vulture #1136) already dropped three
dead bundle methods (list_live_usable_accounts, update_premium,
get_message_stats) — those were unique to their bundles, so the dedup
groups are unaffected; the rebase just no longer carries them. The
set_active name collision is handled by resolution: ChannelBundle/
CollectionBundle get _ChannelOps.set_active(pk), while AccountBundle
(account_id), SearchQueryBundle (sq_id), PipelineBundle (pipeline_id)
keep their own class-body definitions.

Public API verified equivalent by inspect.signature over MRO: identical
method set per bundle, identical fields, set_active resolves to the
correct definition per bundle. Bundle method count 135 -> 108; the
test_db_access_conventions ratchet baseline is lowered accordingly.

Part of #1135 (axis 5 of #1130).

Co-Authored-By: Claude <noreply@anthropic.com>
axisrow added a commit that referenced this pull request Jul 27, 2026
…#1283)

bundles.py duplicated identical repository pass-through methods across
bundles (ChannelBundle/CollectionBundle channel+task ops, get_setting/
set_setting in four bundles, account reads in three, message search/batch
insert in two, scheduler task reads). jscpd flagged the top clone cluster
of issue #1135.

Consolidate each duplicated wrapper group into a repo-scoped plain-class
mixin (_ChannelOps, _CollectionTaskCreateOps, _CollectionTaskReadOps,
_SettingsOps, _NotificationQueriesOps, _MessageOps, _AccountReadOps,
_SearchLogReadOps). Mixins are deliberately NOT dataclasses: their
attribute annotations do not become dataclass fields, so every bundle's
positional constructor order is unchanged.

Rebased onto a main where #1287 (vulture #1136) already dropped three
dead bundle methods (list_live_usable_accounts, update_premium,
get_message_stats) — those were unique to their bundles, so the dedup
groups are unaffected; the rebase just no longer carries them. The
set_active name collision is handled by resolution: ChannelBundle/
CollectionBundle get _ChannelOps.set_active(pk), while AccountBundle
(account_id), SearchQueryBundle (sq_id), PipelineBundle (pipeline_id)
keep their own class-body definitions.

Public API verified equivalent by inspect.signature over MRO: identical
method set per bundle, identical fields, set_active resolves to the
correct definition per bundle. Bundle method count 135 -> 108; the
test_db_access_conventions ratchet baseline is lowered accordingly.

Part of #1135 (axis 5 of #1130).

Co-authored-by: axisrow <axisrow@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
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