Skip to content

add dashboard Channel Stats page#153

Open
GauravOP-03 wants to merge 13 commits intoscriptaiapp:mainfrom
GauravOP-03:feat/dashboard-stats-page
Open

add dashboard Channel Stats page#153
GauravOP-03 wants to merge 13 commits intoscriptaiapp:mainfrom
GauravOP-03:feat/dashboard-stats-page

Conversation

@GauravOP-03
Copy link
Copy Markdown
Collaborator

📝 Description

Add the dashboard Channel Stats page and all related modified/added files. The page delivers a seamless, cost-conscious UX by showing cached channel data from the database by default; the YouTube Data API is only called when the user explicitly clicks Sync Latest Data, which is rate-limited per plan (e.g. 5 syncs/day for free, with a 60‑minute cooldown between syncs). This relies on the Supabase functions introduced in the plans_v2 migration (use_feature, get_feature_usage) to enforce limits and cooldowns in the database, keeping API costs down and responses fast. This PR includes only the stats page and its related front-end files; the migration and API usage of the functions are from a previous PR.

🎯 Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update
  • 🎨 Style/UI changes (formatting, missing semi colons, etc; no logic change)
  • ♻️ Refactoring (no functional changes, code improvements)
  • ⚡ Performance improvements
  • 🧪 Adding or updating tests
  • 🔧 Configuration changes

🧪 Testing

  • I have tested my changes locally
  • I have added tests for my changes
  • All existing tests pass
  • I have tested on different browsers/devices (if applicable)

Describe: Open /dashboard/stats; confirm cached data loads quickly. Click "Sync Latest Data" when allowed; confirm fresh data and quota bar update. When at daily limit or in cooldown, confirm button state and messaging. Confirm error state and "Try Again" when the API fails.

📋 Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have checked my code and corrected any misspellings
  • I have read the Contributing Guide

📸 Screenshots (if applicable)

image image

🔧 Technical Details

How the stats page uses the Supabase functions (from plans_v2 migration)

  • Initial load (no sync)
    The page calls fetchStats() with no argument → API requests /api/v1/youtube/channel-stats?forceSync=false. The backend:

    • Reads cached channel data from youtube_channels (top_videos, recent_videos, channel_name, counts, etc.).
    • Calls the Supabase function get_feature_usage(p_user_id) to get read-only quota state: plan, usage_count, remaining, daily_limit, cooldown_minutes, cooldown_remaining, can_use_now.
    • Returns combined channel stats + quota fields so the UI can show the quota bar, “Sync Latest Data” / “Syncing Paused” / “Limit Reached”, and “Available in X mins” without touching the YouTube API.
  • User clicks “Sync Latest Data”
    The page calls fetchStats(true) → API requests ?forceSync=true. The backend:

    • Calls use_feature(p_user_id) first. The function (from packages/supabase/migrations/20260224185424_plans_v2.sql):
      • Resolves the user’s plan (subscription → plans.daily_limit, plans.cooldown_minutes; fallback to starter).
      • Reads youtube_channels.usage_count, last_used_at, usage_reset_date and resets count when the date has rolled over.
      • If cooldown not elapsed → returns allowed: false, reason: 'cooldown', minutes_remaining, etc.
      • If daily limit reached → returns allowed: false, reason: 'daily_limit', etc.
      • If allowed → atomically increments usage_count, sets last_used_at = NOW(), usage_reset_date = CURRENT_DATE, and returns allowed: true plus updated counts.
    • If use_feature returns allowed: false, the API responds with the function’s message (e.g. daily limit or cooldown); no YouTube API call.
    • If allowed: true, the API then calls the YouTube Data API, updates youtube_channels with new top_videos, recent_videos, last_synced_at, etc., and returns the fresh stats plus updated quota info.

So: first fetch is always from DB (fast, no cost); refresh is optional, limited per day and by cooldown, and gated by the same Supabase functions used in the previous PR.

Why use Supabase functions instead of “normal” DB reads/writes in the app?

  • Atomicity and no race conditions
    Incrementing usage and checking limits in a single DB function avoids races when multiple requests or tabs hit “Sync” at once. The app does not do “read count → check → increment” in separate steps.

  • Single source of truth
    Plan resolution (subscription → plan → daily_limit, cooldown_minutes) and daily reset logic live in one place in the DB. Any client (web, future mobile or workers) that calls use_feature / get_feature_usage gets the same behavior without duplicating business rules.

  • Plan-aware limits without app config
    Limits and cooldowns come from plans (e.g. 5/day, 60 min). Changing a plan or adding a new tier is a data change, not a code deploy.

  • Security and consistency
    Functions run as SECURITY DEFINER and operate on the given user_id; the app cannot bypass or mis-implement limit checks. All enforcement is server-side in Postgres.

  • Better UX
    get_feature_usage gives can_use_now, remaining, cooldown_remaining so the UI can show accurate state (e.g. “3/5 syncs left”, “Available in 42 mins”) without mutating state on simple page loads.

Files in this PR (unchanged list)

File Change
app/dashboard/stats/page.tsx Stats page: header (channel + quota/sync), stat cards, EngagementChart, TopVideosTable, RecentVideosGrid; loading and error states.
hooks/useChannelStats.ts Fetches /api/v1/youtube/channel-stats?forceSync=${forceSync}; returns stats, loading, error, fetchStats(forceSync?).
utils/toolsUtil.ts formatCount, parseDuration, timeAgo, etc., used by stats page and components.
stats/StatCard.tsx Metric card (label, value, icon, optional sub).
stats/EngagementChart.tsx Recharts bar chart for top videos; uses formatCount, ChannelStatsVideo.
stats/TopVideosTable.tsx Top 5 videos with rank, thumbnail, stats, duration; uses parseDuration, formatCount.
stats/RecentVideosGrid.tsx Recent uploads grid; uses timeAgo.
stats/StatsPageSkeleton.tsx Loading skeleton for the stats layout.

Dependencies: Backend must use the Supabase RPCs use_feature and get_feature_usage from packages/supabase/migrations/20260224185424_plans_v2.sql (previous PR). @repo/validation (ChannelStats, ChannelStatsVideo), api-client, UI components, Recharts.

🚀 Deployment Notes

  • Depends on the migration that adds use_feature and get_feature_usage and the youtube_channels/plans columns being applied.
  • Backend /api/v1/youtube/channel-stats must be deployed and must call these Supabase functions as described above.

📚 Documentation Updates

  • README.md updated
  • CONTRIBUTING.md updated (if applicable)
  • API documentation updated (if applicable)
  • Component documentation updated (if applicable)

🔍 Review Notes

  • Confirm quota bar and sync button states match can_use_now, remaining, and cooldown_remaining from the API.
  • Confirm this PR only adds the stats UI and hook; Supabase function usage is documented here but implemented in the API/DB PR.

📊 Performance Impact

  • No performance impact
  • Performance improvement
  • Performance regression (explain below)

Details: Default path uses cached data from the DB and read-only get_feature_usage, so the stats page loads quickly and does not call the YouTube API. Sync is optional and rate-limited, reducing API cost and improving perceived performance.

🔒 Security Considerations

  • No security implications
  • Security improvement
  • Potential security concern (explain below)

Details: Stats endpoint is authenticated; quota and cooldown are enforced in the DB via use_feature (SECURITY DEFINER).

🎉 Additional Notes

  • Benefits of the Supabase-function approach for stats:
    (1) Lower API cost — YouTube is only called on explicit sync, within daily and cooldown limits.
    (2) Fast UX — Cached data and get_feature_usage make the first load instant.
    (3) Clear limits — e.g. 5 syncs/day for free users, 60‑min cooldown; configurable per plan in plans.
    (4) Consistent enforcement — Same logic for web and any future clients; no drift between app and DB.
    (5) Scalable — Atomic updates and plan-based limits in Postgres scale with traffic without app-level race conditions.

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Feb 28, 2026

@GauravOP-03 is attempting to deploy a commit to the afrin127329's projects Team on Vercel.

A member of the Team first needs to authorize it.

@GauravOP-03 GauravOP-03 changed the title feat(web): add dashboard Channel Stats page add dashboard Channel Stats page Feb 28, 2026
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