Skip to content

refactor: remove legacy Podcast.is_subscribed field#86

Merged
allenhutchison merged 2 commits intomainfrom
refactor/remove-is-subscribed-field
Jan 16, 2026
Merged

refactor: remove legacy Podcast.is_subscribed field#86
allenhutchison merged 2 commits intomainfrom
refactor/remove-is-subscribed-field

Conversation

@allenhutchison
Copy link
Owner

@allenhutchison allenhutchison commented Jan 16, 2026

Summary

  • Remove the legacy is_subscribed field from the Podcast model
  • Replace with UserSubscription-based logic for determining which podcasts to sync
  • The field was redundant now that the system has per-user subscriptions

Changes

Repository (src/db/repository.py)

  • Add list_podcasts_with_subscribers() method - returns podcasts with at least one UserSubscription
  • Remove subscribed_only parameter from list_podcasts()
  • Update get_overall_stats() to count "subscribed_podcasts" based on UserSubscription table

Model (src/db/models.py)

  • Remove is_subscribed field from Podcast model

SyncWorker (src/workflow/workers/sync.py)

  • Update to use list_podcasts_with_subscribers() for determining which podcasts to sync

FeedSyncService (src/podcast/feed_sync.py)

  • Add sync_podcasts_with_subscribers() method for pipeline use
  • Remove subscribed_only parameter from sync_all_podcasts()

CLI (src/cli/podcast_commands.py)

  • Update list command to show subscriber counts instead of "Subscribed/Unsubscribed" status

Migration

  • Add migration to drop the is_subscribed column from podcasts table

Test plan

  • All existing tests pass (1079 passed, 8 skipped)
  • Run alembic upgrade head to apply migration
  • Verify CLI podcast list shows subscriber counts
  • Verify pipeline only syncs podcasts with subscribers

Summary by CodeRabbit

  • New Features

    • Added feed-management fields for podcasts (last-checked, last-new-episode, check frequency).
    • New capability to sync/list only podcasts that have subscribers.
  • Bug Fixes / Improvements

    • Podcast list and CLI now show subscriber counts (bulk retrieval) instead of a per-item subscribed flag.
    • Feed sync and worker flows updated to target podcasts with active subscribers.
  • Tests

    • Updated tests and fixtures to reflect subscriber-focused behavior and new outputs.

✏️ Tip: You can customize this high-level summary in your review settings.

Replace system-level is_subscribed field with UserSubscription-based logic.
The field was redundant now that the system has per-user subscriptions.

Changes:
- Add list_podcasts_with_subscribers() repository method
- Update SyncWorker and FeedSyncService to use subscriber-based filtering
- Update get_overall_stats() to count podcasts by UserSubscription
- Update CLI to show subscriber counts instead of subscription status
- Remove subscribed_only parameter from list_podcasts()
- Add database migration to drop the column
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 16, 2026

Caution

Review failed

The pull request is closed.

Walkthrough

Removes the Podcast.model boolean is_subscribed and corresponding DB column; replaces subscription filtering with subscriber-count based APIs and behavior. Updates repository, feed-sync, CLI, worker codepaths, tests, and adds feed-management fields to the Podcast model and an Alembic migration.

Changes

Cohort / File(s) Summary
Database Schema & Models
alembic/versions/20260116_1000_f6a7b8c9d0e1_remove_is_subscribed_field.py, src/db/models.py
Adds migration to drop is_subscribed; removes Podcast.is_subscribed and adds last_checked, last_new_episode, check_frequency_hours.
Repository Layer
src/db/repository.py
Removes subscribed_only param from list_podcasts(); adds list_podcasts_with_subscribers() and get_podcast_subscriber_counts(); get_overall_stats() now counts distinct subscribers via UserSubscription.
Feed Synchronization
src/podcast/feed_sync.py
sync_all_podcasts() no longer takes subscribed_only; adds sync_podcasts_with_subscribers() and internal _sync_podcasts() to consolidate iteration/aggregation.
CLI
src/cli/podcast_commands.py
list_podcasts now prints a Subscribers column and uses bulk get_podcast_subscriber_counts(); changed calls to repository listing APIs.
Workers / Workflow
src/workflow/workers/sync.py
Worker now queries list_podcasts_with_subscribers() and calls sync_podcasts_with_subscribers(); adjusted pending-count and batch processing wording.
Tests
tests/*.py (e.g., tests/test_cli_commands.py, tests/test_feed_sync.py, tests/test_repository.py, tests/test_workers.py, tests/test_workflow.py)
Updated fixtures and expectations: removed is_subscribed assertions, added sample_user/subscribed_podcast fixtures, adapted tests to new repository and feed-sync methods and subscriber-count outputs.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Worker
participant FeedSyncService
participant Repository
participant Database

Worker->>FeedSyncService: request sync_podcasts_with_subscribers()
FeedSyncService->>Repository: list_podcasts_with_subscribers(limit?)
Repository->>Database: SQL: fetch podcasts with at least one subscriber
Database-->>Repository: podcast rows
Repository-->>FeedSyncService: list of podcasts
FeedSyncService->>Repository: get_podcast_subscriber_counts(podcast_ids)
Repository->>Database: SQL: count subscribers per podcast
Database-->>Repository: subscriber counts
Repository-->>FeedSyncService: counts map
FeedSyncService->>FeedSyncService: _sync_podcasts(podcasts + counts)
FeedSyncService->>Repository: (per-podcast) update last_checked / last_new_episode
FeedSyncService-->>Worker: aggregated results (synced/failed/new_episodes, results[])

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 Hop, hop — the boolean's gone,
Counts now lead the subscriber song.
Feeds check in, timestamps in tune,
Bounced from flags to counts so soon.
This rabbit cheers: new flow, new dawn! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately describes the main change: removing the legacy is_subscribed field from the Podcast model, which is the central refactoring across all modified files.
Docstring Coverage ✅ Passed Docstring coverage is 95.12% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/remove-is-subscribed-field

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d3b04f and 305aa3c.

📒 Files selected for processing (1)
  • tests/test_repository.py

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@tests/test_repository.py`:
- Around line 98-118: In test_list_podcasts_with_subscribers, remove the unused
local variable by changing the second podcast creation from an assigned variable
to a plain call; update the line that currently assigns podcast2 =
repository.create_podcast(...) to just
repository.create_podcast(feed_url="https://example.com/feed2.xml",
title="Podcast 2") so the second podcast still exists for list_podcasts() but
the unused symbol podcast2 is not defined (target function:
test_list_podcasts_with_subscribers, symbol: podcast2).
🧹 Nitpick comments (2)
src/workflow/workers/sync.py (1)

62-74: Consider suppressing the unused limit argument lint warning.

The limit parameter is intentionally ignored (as documented in the docstring), likely to comply with the WorkerInterface.process_batch signature. Consider using an underscore prefix or adding a # noqa: ARG002 comment to suppress the lint warning explicitly.

♻️ Suggested fix
-    def process_batch(self, limit: int = 0) -> WorkerResult:
+    def process_batch(self, limit: int = 0) -> WorkerResult:  # noqa: ARG002

Or alternatively, prefix with underscore if the interface allows:

-    def process_batch(self, limit: int = 0) -> WorkerResult:
+    def process_batch(self, _limit: int = 0) -> WorkerResult:
src/cli/podcast_commands.py (1)

249-265: Consider batching episode counts to avoid per-podcast queries.
You already have podcast_ids; using the bulk API keeps list output fast for large datasets.

♻️ Proposed refactor
-        # Get subscriber counts for all podcasts in one query
+        # Get subscriber/episode counts for all podcasts in one query each
         podcast_ids = [p.id for p in podcasts]
         subscriber_counts = repository.get_podcast_subscriber_counts(podcast_ids)
+        episode_counts = repository.get_podcast_episode_counts(podcast_ids)
@@
-            # Get episode count
-            episodes = repository.list_episodes(podcast_id=podcast.id)
-            sub_count = subscriber_counts.get(podcast.id, 0)
+            episode_count = episode_counts.get(podcast.id, 0)
+            sub_count = subscriber_counts.get(podcast.id, 0)
             print(
                 f"{podcast.id:<36}  "
                 f"{podcast.title[:40]:<40}  "
-                f"{len(episodes):<10}  "
+                f"{episode_count:<10}  "
                 f"{sub_count}"
             )

@allenhutchison allenhutchison merged commit d7874a1 into main Jan 16, 2026
2 of 3 checks passed
@allenhutchison allenhutchison deleted the refactor/remove-is-subscribed-field branch January 16, 2026 20:19
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