Skip to content

refactor: dedupe service/collector helper twins (#1135) - #1285

Merged
axisrow merged 1 commit into
mainfrom
ao/tg_content_factory_5863f66be3-63/dedup-services-telegram
Jul 27, 2026
Merged

refactor: dedupe service/collector helper twins (#1135)#1285
axisrow merged 1 commit into
mainfrom
ao/tg_content_factory_5863f66be3-63/dedup-services-telegram

Conversation

@axisrow

@axisrow axisrow commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Part of #1135 (axis 5 of #1130). Five genuine (non-parity) clones across services/ and telegram/.

Clones & extraction

Clone Extracted helper Notes
channel_analytics_service._calc_err_calc_err24 _engagement_rate(channel_id, rows) Engagement formula sum / (rows*subs) * 100. Each caller keeps its own data fetch (get_err_data vs get_err24_data).
pipeline_nodes/handlers source block (LlmGenerate + AgentLoop) module-level _build_source_messages(messages) Identical [header] text (id:.. date:..) rendering, blank-joined; blank texts dropped. The AgentLoop user_message truthiness guard is preserved (joined string empty ⟺ parts list empty).
telegram_actions.download_mediadownload_media_sized lookup _fetch_message_with_flood_wait(...) Resolve-entity + iter_messages(ids=) under flood-wait + MessageNotFoundError raise.
photo_task_service.send_nowschedule_send batch+item ctor _create_send_batch_item(..., status, schedule_at)(batch_id, item_id) Parameterized by status + started_at vs schedule_at.
collector_mixins/stats stats_*worker_count + available_stats_*worker_count (2 pairs) _configured_worker_count, _available_worker_count Twins differed only by config attr / default / log label.

Verification

  • ruff clean on all five files.
  • 1359 targeted tests pass (analytics/err/pipeline_node/telegram_action/download_media/photo_task/collector_stats/worker_count/source_messages).

jscpd

  • Removed: the five clones above.
  • Total: 0.67% (49 clones) — flat vs. the PR-2 state. The remaining services/telegram_actions.py:575↔594 and collector_mixins/cancellation↔stats hits are parity-style Telegram-error-handling blocks and the shared TYPE_CHECKING Collector Protocol (see tech-debt: дедуп кода (jscpd 0.56%, не-parity клоны) #1135 parity notes), intentionally untouched.

Part of #1135 / #1130. Not for merge — review requested.

🤖 Generated with Claude Code

Five genuine (non-parity) clones across services/ and telegram/:

* channel_analytics_service._calc_err / _calc_err24 duplicated the
  engagement-rate formula (sum / rows*subs * 100); extracted
  _engagement_rate(rows) — each caller keeps its own data fetch.
* pipeline_nodes/handlers duplicated the context_messages -> source block
  in LlmGenerateHandler and AgentLoopHandler; extracted module-level
  _build_source_messages(messages). Behaviour identical: blank texts
  dropped, same [header] text (id:.. date:..) format, blank-joined; the
  truthiness guard on the agent-loop user_message is preserved (the joined
  string is empty iff the parts list was empty).
* telegram_actions.download_media / download_media_sized duplicated the
  resolve-entity + iter_messages(ids=) lookup + MessageNotFoundError raise;
  extracted _fetch_message_with_flood_wait(client, phone, entity, id).
* photo_task_service.send_now / schedule_send duplicated the PhotoBatch +
  PhotoBatchItem construction (parameterized by status + started_at vs
  schedule_at); extracted _create_send_batch_item returning (batch_id,
  item_id).
* collector_mixins/stats stats_*worker_count and available_stats_*_worker_count
  were two pairs of twins differing only by config attr / default / log label;
  extracted _configured_worker_count and _available_worker_count.

1359 targeted tests pass. jscpd total holds at 0.67% (clones from these
files removed; remaining clones are parity/declarative — see PR #1135 notes).

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@axisrow
axisrow force-pushed the ao/tg_content_factory_5863f66be3-63/dedup-services-telegram branch from c9be6f9 to 36cfaca Compare July 27, 2026 14:53
@axisrow

axisrow commented Jul 27, 2026

Copy link
Copy Markdown
Owner Author

🔍 Local review — cycle 1/3 (clean)

Reviewed locally via built-in /review + Codex companion (sol/high — the first xhigh run exceeded the turn budget on this 5-file diff and was retried at high), no GitHub bots pinged. Reviewed head 36cfacab against base 53001148.

Five MOVE/extraction refactors — both reviewers confirmed semantic equivalence of each:

Reviewer Verdict Findings
Codex (sol/high) approve 0 — "All five extractions preserve the relevant formulas, guards, exception behavior, timestamps, clamps, and fallbacks. The AgentLoop condition is equivalent because every appended source part is necessarily non-empty."
/review (Claude) clean 0 — verified each: ERR formula + None-guards; _build_source_messages rendering identical (AgentLoop truthiness guard preserved — joined string empty ⟺ parts list empty); _fetch_message_with_flood_wait body 1:1; _create_send_batch_item field set matches (RUNNING→started_at, SCHEDULED→schedule_at); worker-count clamp + fallback identical.

The subtle point both flagged and cleared: the AgentLoop user_message guard changed from if source_parts (list) to if source_messages (joined string). Equivalent because the helper drops blank texts before joining, so every appended part is non-empty → the joined string is empty iff the parts list was empty.

No FIX, no UNVERIFIED, no SKIP — nothing to apply in cleanup. Round bound to 36cfacab; PR snapshot intact (author + head + base unchanged since round start).

Tests: 1373 targeted tests green after rebase. ruff clean.

Totals: 0 FIX, 0 SKIP, 0 UNVERIFIED. Review cycle complete — merge is yours to trigger (local mode does not auto-merge).

@axisrow
axisrow merged commit d1796e4 into main Jul 27, 2026
4 checks passed
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