diff --git a/backend/app/routes/sync.py b/backend/app/routes/sync.py index 5617f0e1..998d658b 100644 --- a/backend/app/routes/sync.py +++ b/backend/app/routes/sync.py @@ -71,7 +71,7 @@ def sync_status(user: User = Depends(current_user), db: Session = Depends(get_db def my_status(user: User = Depends(current_user), db: Session = Depends(get_db)) -> dict: """Per-user sync progress: how far the channels *this* user subscribes to have synced.""" sub_join = and_(Subscription.channel_id == Channel.id, Subscription.user_id == user.id) - total, details_synced, recent_synced, deep_done = db.execute( + total, details_synced, recent_synced, all_deep_done = db.execute( select( func.count(Channel.id), func.count(Channel.details_synced_at), @@ -82,7 +82,7 @@ def my_status(user: User = Depends(current_user), db: Session = Depends(get_db)) .join(Subscription, sub_join) ).one() total = total or 0 - deep_done = int(deep_done or 0) + all_deep_done = int(all_deep_done or 0) # Per-user full-history (deep) backfill: channels this user has opted in, and an ETA # for the still-pending ones (quota-bound estimate). @@ -97,6 +97,10 @@ def my_status(user: User = Depends(current_user), db: Session = Depends(get_db)) .all() ) deep_eta = estimate_deep_backfill(db, deep_requested_channels) + # "done / requested" is shown as one ratio, so both halves count the SAME channels: the ones this + # user asked full history for. Counting every subscribed channel whose back-catalog happens to be + # complete (another user asked, or it was short) gave "342/329". + deep_done = sum(1 for c in deep_requested_channels if c.backfill_done) my_videos = db.scalar( select(func.count(Video.id)).join( @@ -117,7 +121,7 @@ def my_status(user: User = Depends(current_user), db: Session = Depends(get_db)) "channels_recent_synced": recent_synced, "channels_deep_done": deep_done, "channels_recent_pending": total - recent_synced, - "channels_deep_pending": total - deep_done, + "channels_deep_pending": total - all_deep_done, "channels_deep_requested": len(deep_requested_channels), "deep_pending_count": deep_eta["channels_pending"], "deep_eta_seconds": deep_eta["eta_seconds"], diff --git a/backend/tests/test_my_status_deep.py b/backend/tests/test_my_status_deep.py new file mode 100644 index 00000000..891fa74d --- /dev/null +++ b/backend/tests/test_my_status_deep.py @@ -0,0 +1,33 @@ +"""The Stats page's "Full history: done / requested" ratio counts the SAME channels on both sides — the +ones this user asked full history for. The numerator used to count every subscribed channel whose +back-catalog was complete (another user had asked, or the channel was short), so the page read +"342/329". "Channels without full history yet" still counts every subscribed channel. Needs the DB.""" + +from app.models import Channel, Subscription + + +def test_full_history_ratio_counts_only_the_requested_channels(db, make_user, as_user): + user = make_user("deep@example.com") + db.add_all( + [ + Channel(id="UCreqdone", title="Requested, done", backfill_done=True), + Channel(id="UCreqopen", title="Requested, pending", backfill_done=False), + Channel(id="UCdone", title="Not requested, done anyway", backfill_done=True), + Channel(id="UCopen", title="Not requested, pending", backfill_done=False), + ] + ) + db.flush() + db.add_all( + [ + Subscription(user_id=user.id, channel_id="UCreqdone", deep_requested=True), + Subscription(user_id=user.id, channel_id="UCreqopen", deep_requested=True), + Subscription(user_id=user.id, channel_id="UCdone"), + Subscription(user_id=user.id, channel_id="UCopen"), + ] + ) + db.commit() + + body = as_user(user).get("/api/sync/my-status").json() + assert body["channels_deep_requested"] == 2 + assert body["channels_deep_done"] == 1 # never more than it is out of + assert body["channels_deep_pending"] == 2 # subscribed channels without full history yet