Skip to content

feat(stats): refresh stale dashboard charts on visit#1932

Merged
riderx merged 13 commits into
mainfrom
codex/stale-chart-refresh
Apr 22, 2026
Merged

feat(stats): refresh stale dashboard charts on visit#1932
riderx merged 13 commits into
mainfrom
codex/stale-chart-refresh

Conversation

@riderx
Copy link
Copy Markdown
Member

@riderx riderx commented Apr 22, 2026

Summary (AI generated)

  • add app and org chart refresh state so stale dashboard data can auto-refresh on visit
  • reuse the existing cron stats queue with 5-minute throttling to avoid duplicate refresh spam
  • keep old chart data visible while fresh stats are generated, then reload once the refreshed org cache is ready
  • add backend and frontend test coverage for refresh helpers and cron follow-up behavior

Motivation (AI generated)

Dashboard charts were always showing stale data until the next scheduled stats cycle. This change lets the app request fresher data on demand while keeping the existing cron generation path and rate limits intact.

Business Impact (AI generated)

This reduces confusion on the dashboard, improves trust in usage reporting, and avoids turning page reloads into an unbounded background load problem. It gives users fresher metrics without changing the hot-path stats API contract.

Test Plan (AI generated)

  • bunx eslint src/components/dashboard/Usage.vue 'src/pages/app/[app].vue' src/services/dashboardRefresh.ts tests/dashboard-refresh.unit.test.ts tests/chart-refresh-rpc.test.ts tests/cron_stat_refresh_completion.test.ts tests/cron_stat_app_followup.unit.test.ts tests/organization-api.test.ts tests/organization-put-stripe-sync.unit.test.ts supabase/functions/_backend/triggers/cron_stat_app.ts
  • bun typecheck
  • bunx vitest run tests/dashboard-refresh.unit.test.ts tests/cron_stat_app_followup.unit.test.ts tests/organization-put-stripe-sync.unit.test.ts
  • bun run supabase:start and DB-backed tests (tests/chart-refresh-rpc.test.ts, tests/cron_stat_refresh_completion.test.ts) once Docker is available locally
  • GitHub Actions

Generated with AI

Summary by CodeRabbit

  • New Features

    • Per-scope "last updated" and refresh-request markers; charts accept a reload trigger and reload in sync. Reload button disables/spins while a scope refresh is in progress.
  • Behavior

    • Reloads now request scoped refreshes, poll refresh state, and only reload charts once caches are ready; auto-refresh is scope-aware and deduplicated.
  • Bug Fixes

    • Background polling/timers are cleaned up when leaving the dashboard; reload UI reflects polling state.
  • Chores

    • Database columns, RPCs and API types added to support scoped refresh coordination and cache orchestration; migration applied.
  • Tests

    • New unit and integration tests covering refresh helpers, RPCs, cron completion, and polling.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 22, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds scope-aware chart refresh orchestration: new per-app/org timestamps, Supabase RPCs and DB migration to enqueue/track refreshes, backend trigger updates to coordinate completion, a dashboardRefresh service for polling/decision logic, UI wiring for scoped refresh requests and polling, and tests validating RPCs and cron behavior.

Changes

Cohort / File(s) Summary
Frontend Dashboard
src/components/dashboard/Usage.vue, src/pages/app/[app].vue
Usage accepts app-scoped timestamps, keeps per-scope timestamp state, implements scope-aware request/poll/reload flow via new helpers, exposes reloadTrigger to child cards, replaces reload click with scoped handleReloadClick, and cleans up polling on unmount.
Dashboard Refresh Service
src/services/dashboardRefresh.ts
New helpers/constants for timestamp parsing, staleness/in-progress detection, poll/timeouts, Supabase RPC callers (requestAppChartRefresh/requestOrgChartRefresh) and fetchers (fetchAppChartRefreshState/fetchOrgChartRefreshState).
Supabase Types & Migrations
src/types/supabase.types.ts, supabase/functions/_backend/utils/supabase.types.ts, supabase/migrations/20260422104849_stale_chart_refresh_state.sql
Adds stats_refresh_requested_at and nullable stats_updated_at columns/types, backfills app timestamps, updates get_orgs_v7 return schema, and introduces DB functions for queuing/requesting app/org chart refreshes and cache-aware get_app_metrics.
Cron Trigger Logic
supabase/functions/_backend/triggers/cron_stat_app.ts
Adds timestamp-normalization helpers, pending-app inspection, RPC call to mark_app_stats_refreshed, and gates org-level sync/plan enqueueing until pending app refreshes are cleared (with retry/error paths).
Backend Function Types
supabase/functions/_backend/utils/supabase.types.ts
Mirrors DB type changes and adds RPC signatures: mark_app_stats_refreshed, request_app_chart_refresh, request_org_chart_refresh.
Tests
tests/chart-refresh-rpc.test.ts, tests/cron_stat_refresh_completion.test.ts, tests/dashboard-refresh.unit.test.ts, tests/cron_stat_app_followup.unit.test.ts, tests/organization-api.test.ts, tests/organization-put-stripe-sync.unit.test.ts
Adds unit/integration tests for RPC queueing, permission handling, polling helpers, cron-trigger completion, pending-refresh coordination, and updated fixtures/assertions.
Misc (types)
src/types/supabase.types.ts
Added RPC typings and adjusted apps/orgs Row/Insert/Update types to include the new nullable refresh/update timestamp fields.

Sequence Diagram

sequenceDiagram
    participant UI as Usage Component
    participant Service as dashboardRefresh Service
    participant Supabase as Supabase API
    participant DB as DB Stored Procs
    participant Cron as cron_stat_app Worker

    UI->>UI: User clicks reload
    UI->>Service: handleReloadClick(scope)
    alt scope stale & should request refresh
        Service->>Supabase: request_app_chart_refresh / request_org_chart_refresh
        Supabase->>DB: RPC sets stats_refresh_requested_at, returns requested_at + queued ids
        DB->>Cron: enqueue cron_stat_app jobs for queued apps
        Service-->>UI: start polling (CHART_REFRESH_POLL_MS)
        loop poll until settled or timeout
            UI->>Service: fetch*ChartRefreshState()
            Service->>Supabase: select stats_refresh_requested_at & stats_updated_at
            Supabase-->>Service: refresh state
            Service-->>UI: evaluate isChartRefreshInProgress / isOrgCacheReadyForRefresh
            alt refresh complete and cache ready
                UI->>UI: clear caches & reloadAllCharts()
                UI->>Service: stop polling
            end
        end
    else scope fresh or demo
        UI->>UI: reloadAllCharts() immediately
    end
    UI->>UI: update button disabled/spinning state
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

codex

Poem

🐇 I nibbled timestamps, queued the run,

I polled till midnight, chasing sun,
I ticked the apps, then told the org,
Charts woke up bright from sleepy fog,
Hop—fresh graphs, crunchy and fun! 🥕

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description includes a summary, motivation, and business impact. However, the required template sections (Summary, Test plan, Screenshots, Checklist) are not properly filled—only an AI-generated summary is provided without completing the official template. Complete the official PR description template: explicitly fill the Summary, Test plan (with manual testing steps), and Checklist sections. Include screenshots if frontend behavior changed and confirm documentation updates if needed.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: enabling auto-refresh of stale dashboard charts on user visits, which aligns with the core feature being implemented.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/stale-chart-refresh

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

@riderx riderx marked this pull request as ready for review April 22, 2026 11:25
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ece36195ad

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/services/dashboardRefresh.ts
Comment thread supabase/migrations/20260422104849_stale_chart_refresh_state.sql Outdated
Copy link
Copy Markdown
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: 4

🧹 Nitpick comments (2)
tests/dashboard-refresh.unit.test.ts (1)

7-35: Use it.concurrent() for these isolated helper specs.

These cases only exercise pure functions and don't share mutable test state, so they can run concurrently. As per coding guidelines, "Use it.concurrent() instead of it() when possible to run tests in parallel within the same file, maximizing parallelism for faster CI/CD".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/dashboard-refresh.unit.test.ts` around lines 7 - 35, Replace the two
synchronous test cases in the "dashboard refresh helpers" suite to run
concurrently by changing the test declarations from it(...) to
it.concurrent(...); update the first test that imports and asserts
isChartDataStale, isChartRefreshInProgress, parseDashboardRefreshTimestamp, and
shouldAutoRequestChartRefresh, and the second test that imports and asserts
isOrgCacheReadyForRefresh to use it.concurrent so these pure-function specs run
in parallel.
tests/organization-api.test.ts (1)

1056-1058: Assert stats_updated_at in this RPC contract too.

src/components/dashboard/Usage.vue now reads both stats_refresh_requested_at and stats_updated_at to decide staleness and refresh completion. This test only guards one half of that contract, so a missing stats_updated_at field from get_orgs_v7 would still slip through here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/organization-api.test.ts` around lines 1056 - 1058, The test currently
asserts presence of stats_refresh_requested_at but not stats_updated_at, leaving
the RPC contract incomplete; update the test that inspects testOrg (result of
get_orgs_v7) to also assert testOrg has the 'stats_updated_at' property and, if
the fixture provides an rpcStatsUpdatedAt (or similarly named) value, assert
testOrg.stats_updated_at equals that RPC value so Usage.vue’s staleness checks
remain covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/pages/app/`[app].vue:
- Around line 201-208: The three sibling chart components (BundleUploadsCard,
UpdateStatsCard, DeploymentStatsCard) can remain stale because Usage.vue handles
the stale-refresh polling and only triggers reloads for its children via its
internal reloadTrigger; on this page they are siblings so they never see that
trigger. Fix by exposing a shared reload signal from Usage (e.g., a reactive
property or emitted event on the usageComponent ref like emitReload or public
method triggerReload) or by moving the refresh orchestration up into this page:
when Usage completes refresh, call the exposed method or emit an event on
usageComponent and pass a shared prop (e.g., reloadSignal or refreshToken) down
into BundleUploadsCard, UpdateStatsCard, and DeploymentStatsCard so they watch
that prop and reload when it changes.

In `@src/services/dashboardRefresh.ts`:
- Around line 3-5: CHART_REFRESH_TIMEOUT_MS is shorter than the dedupe/throttle
window (CHART_REFRESH_STALE_MS), which can cause the UI to stop polling while
backend retries are still throttled; change the timeout so it is derived from or
at least as long as CHART_REFRESH_STALE_MS (e.g., set CHART_REFRESH_TIMEOUT_MS =
CHART_REFRESH_STALE_MS or CHART_REFRESH_STALE_MS + safety margin) and update any
references relying on CHART_REFRESH_TIMEOUT_MS accordingly to ensure the client
keeps polling through the backend throttle window.

In `@supabase/migrations/20260422104849_stale_chart_refresh_state.sql`:
- Around line 593-627: The org-level stats_refresh_requested_at is being set
before any apps are actually queued; move that update so it only happens when
v_queued_count > 0 (or restore the previous/null timestamp when nothing was
queued) to avoid marking an org as "refresh requested" if no app was enqueued.
Concretely, remove or delay the UPDATE public.orgs ... SET
stats_refresh_requested_at = v_request_started_at that occurs prior to the FOR
loop and instead perform that UPDATE after the loop only when v_queued_count > 0
(or, if v_queued_count = 0, ensure the RETURN QUERY returns the prior value or
NULL for the org's request timestamp). Ensure this change touches the code
around queue_cron_stat_app_for_app, v_queued_count, v_request_started_at and the
RETURN QUERY so the returned timestamp reflects whether any apps were actually
queued.
- Around line 391-435: The code currently acquires a session-level advisory lock
via pg_advisory_lock (v_lock_key) and explicitly calls pg_advisory_unlock before
the transaction commits, allowing another session to see inconsistent state;
replace the session lock with a transaction-scoped lock or hold the lock until
commit by using pg_advisory_xact_lock(v_lock_key) (or remove the
pg_advisory_unlock calls) so the lock is released only at transaction end,
ensuring the UPDATE to public.apps (stats_refresh_requested_at) and the
pgmq.send('cron_stat_app', ...) happen atomically while the lock is held.

---

Nitpick comments:
In `@tests/dashboard-refresh.unit.test.ts`:
- Around line 7-35: Replace the two synchronous test cases in the "dashboard
refresh helpers" suite to run concurrently by changing the test declarations
from it(...) to it.concurrent(...); update the first test that imports and
asserts isChartDataStale, isChartRefreshInProgress,
parseDashboardRefreshTimestamp, and shouldAutoRequestChartRefresh, and the
second test that imports and asserts isOrgCacheReadyForRefresh to use
it.concurrent so these pure-function specs run in parallel.

In `@tests/organization-api.test.ts`:
- Around line 1056-1058: The test currently asserts presence of
stats_refresh_requested_at but not stats_updated_at, leaving the RPC contract
incomplete; update the test that inspects testOrg (result of get_orgs_v7) to
also assert testOrg has the 'stats_updated_at' property and, if the fixture
provides an rpcStatsUpdatedAt (or similarly named) value, assert
testOrg.stats_updated_at equals that RPC value so Usage.vue’s staleness checks
remain covered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b0fd3ec1-6349-4cf8-a0f1-9c6dd20ff603

📥 Commits

Reviewing files that changed from the base of the PR and between 99dcd2e and ece3619.

📒 Files selected for processing (13)
  • src/components/dashboard/Usage.vue
  • src/pages/app/[app].vue
  • src/services/dashboardRefresh.ts
  • src/types/supabase.types.ts
  • supabase/functions/_backend/triggers/cron_stat_app.ts
  • supabase/functions/_backend/utils/supabase.types.ts
  • supabase/migrations/20260422104849_stale_chart_refresh_state.sql
  • tests/chart-refresh-rpc.test.ts
  • tests/cron_stat_app_followup.unit.test.ts
  • tests/cron_stat_refresh_completion.test.ts
  • tests/dashboard-refresh.unit.test.ts
  • tests/organization-api.test.ts
  • tests/organization-put-stripe-sync.unit.test.ts

Comment thread src/pages/app/[app].vue
Comment thread src/services/dashboardRefresh.ts Outdated
Comment thread supabase/migrations/20260422104849_stale_chart_refresh_state.sql Outdated
Comment thread supabase/migrations/20260422104849_stale_chart_refresh_state.sql Outdated
…resh

# Conflicts:
#	supabase/functions/_backend/triggers/cron_stat_app.ts
#	tests/cron_stat_app_followup.unit.test.ts
@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq Bot commented Apr 22, 2026

Merging this PR will not alter performance

✅ 28 untouched benchmarks


Comparing codex/stale-chart-refresh (b2d4270) with main (3b4fef3)

Open in CodSpeed

Copy link
Copy Markdown
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: 2

🧹 Nitpick comments (1)
tests/chart-refresh-rpc.test.ts (1)

57-135: Prefer per-test seed data here.

These cases all mutate the same org/apps/queue rows created in beforeAll, so one leaked state change can cascade into later assertions and the suite can’t safely move to it.concurrent(). Creating fresh org/app ids per case would keep the new RPC coverage isolated.

As per coding guidelines, "When creating tests that interact with shared resources, create dedicated seed data when your test modifies resources; reuse existing seed data only when you read without modification and create your own child resources".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/chart-refresh-rpc.test.ts` around lines 57 - 135, Tests currently share
mutable org/app rows created in beforeAll (orgId, staleAppId, freshAppId) so
state leakage prevents safe concurrent tests; change to create fresh seeded org
and app IDs per test instead: move the org/apps seeding and calls to
resetAndSeedAppDataStats/clearCronStatAppMessages into beforeEach (or create a
helper used inside each it), generate unique orgId/staleAppId/freshAppId per
test (eg via uuid), use createAuthClient signIn per-test or ensure test-scoped
auth, and perform per-test cleanup in afterEach (calling resetAppDataStats,
clearCronStatAppMessages and deleting the specific rows) rather than relying on
global beforeAll/afterAll; update references to orgId, staleAppId, freshAppId,
resetAndSeedAppDataStats, clearCronStatAppMessages, resetAppDataStats,
createAuthClient and any DB inserts to use the per-test IDs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/dashboard/Usage.vue`:
- Around line 121-143: The staleness clock (refreshStateClock) only updates
during polling or prop/store changes so the computed isCurrentScopeStale never
becomes true when the page is idle; add a lightweight periodic tick that
advances refreshStateClock (e.g., setInterval updating refreshStateClock.value =
Date.now()) so computed stale/refresh logic (isCurrentScopeStale,
isCurrentScopeRefreshing, hasRefreshableScope) re-evaluates even when idle,
store the interval handle (reuse or separate from refreshPollTimer) and ensure
you start it in the component setup/onMounted and clear it on beforeUnmount to
avoid leaks; tie the interval frequency to the staleness window (e.g., 30–60s)
and ensure it respects autoRefreshScopeKey/refreshPollStartedAt semantics if
needed.

In `@supabase/functions/_backend/triggers/cron_stat_app.ts`:
- Around line 159-170: syncAppStatsRefresh currently updates
apps.stats_updated_at directly via
supabase.from(...).update(...).throwOnError(), which can fail transiently;
change it to use the existing retry wrapper runSupabaseResultWithRetry (the same
helper used for the org follow-up write) so the update is retried on
5xx/temporary errors. Replace the direct supabase.update call inside
syncAppStatsRefresh (and the analogous update at the other occurrence) with a
call that constructs the same update query and passes it to
runSupabaseResultWithRetry, preserving the app_id filter and refreshCompletedAt
payload so that stats_updated_at reliably flips even on transient failures.

---

Nitpick comments:
In `@tests/chart-refresh-rpc.test.ts`:
- Around line 57-135: Tests currently share mutable org/app rows created in
beforeAll (orgId, staleAppId, freshAppId) so state leakage prevents safe
concurrent tests; change to create fresh seeded org and app IDs per test
instead: move the org/apps seeding and calls to
resetAndSeedAppDataStats/clearCronStatAppMessages into beforeEach (or create a
helper used inside each it), generate unique orgId/staleAppId/freshAppId per
test (eg via uuid), use createAuthClient signIn per-test or ensure test-scoped
auth, and perform per-test cleanup in afterEach (calling resetAppDataStats,
clearCronStatAppMessages and deleting the specific rows) rather than relying on
global beforeAll/afterAll; update references to orgId, staleAppId, freshAppId,
resetAndSeedAppDataStats, clearCronStatAppMessages, resetAppDataStats,
createAuthClient and any DB inserts to use the per-test IDs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 656c0591-a20c-4d65-9b6e-157f57d2fd1a

📥 Commits

Reviewing files that changed from the base of the PR and between ece3619 and 3255272.

📒 Files selected for processing (9)
  • src/components/dashboard/Usage.vue
  • src/pages/app/[app].vue
  • src/services/dashboardRefresh.ts
  • supabase/functions/_backend/triggers/cron_stat_app.ts
  • supabase/migrations/20260422104849_stale_chart_refresh_state.sql
  • tests/chart-refresh-rpc.test.ts
  • tests/cron_stat_app_followup.unit.test.ts
  • tests/dashboard-refresh.unit.test.ts
  • tests/organization-api.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/dashboard-refresh.unit.test.ts
  • supabase/migrations/20260422104849_stale_chart_refresh_state.sql

Comment thread src/components/dashboard/Usage.vue
Comment thread supabase/functions/_backend/triggers/cron_stat_app.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 32552725d7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread supabase/migrations/20260422104849_stale_chart_refresh_state.sql Outdated
Copy link
Copy Markdown
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.

🧹 Nitpick comments (1)
src/components/dashboard/Usage.vue (1)

244-253: Consider using store actions instead of direct mutation.

syncLocalOrgRefreshState directly mutates effectiveOrganization.value.stats_updated_at and stats_refresh_requested_at. Since effectiveOrganization is derived from organizationStore, this bypasses the store's update mechanism.

While this works for keeping the UI in sync during polling, consider whether the organization store should expose a mutation action for these fields to maintain consistency with the store pattern used elsewhere.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/dashboard/Usage.vue` around lines 244 - 253,
syncLocalOrgRefreshState currently mutates
effectiveOrganization.value.stats_updated_at and stats_refresh_requested_at
directly; instead add or use an organizationStore action (e.g.,
updateOrgStatsTimestamps or setStatsTimestamps) to apply those two fields and
call that action from syncLocalOrgRefreshState after updating
localOrgStatsUpdatedAt/localOrgStatsRefreshRequestedAt; update the code to stop
writing to effectiveOrganization.value directly and invoke organizationStore's
action (create the action if missing) so all org updates go through the store
API.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/components/dashboard/Usage.vue`:
- Around line 244-253: syncLocalOrgRefreshState currently mutates
effectiveOrganization.value.stats_updated_at and stats_refresh_requested_at
directly; instead add or use an organizationStore action (e.g.,
updateOrgStatsTimestamps or setStatsTimestamps) to apply those two fields and
call that action from syncLocalOrgRefreshState after updating
localOrgStatsUpdatedAt/localOrgStatsRefreshRequestedAt; update the code to stop
writing to effectiveOrganization.value directly and invoke organizationStore's
action (create the action if missing) so all org updates go through the store
API.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bdb04d72-b262-4986-936c-d975785e60d9

📥 Commits

Reviewing files that changed from the base of the PR and between 3255272 and 74336ba.

📒 Files selected for processing (4)
  • src/components/dashboard/Usage.vue
  • supabase/functions/_backend/triggers/cron_stat_app.ts
  • supabase/migrations/20260422104849_stale_chart_refresh_state.sql
  • tests/cron_stat_app_followup.unit.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/cron_stat_app_followup.unit.test.ts

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 74336ba37b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread supabase/functions/_backend/triggers/cron_stat_app.ts Outdated
Comment thread supabase/migrations/20260422104849_stale_chart_refresh_state.sql Outdated
Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@supabase/functions/_backend/triggers/cron_stat_app.ts`:
- Around line 190-200: The read in hasPendingAppStatsRefresh can fail
transiently and leave pendingAppRefreshes true; wrap the Supabase query in
hasPendingAppStatsRefresh in a small retry-with-backoff loop (e.g., 3 attempts,
short delay, retry on 5xx/network errors) and only throw after retries are
exhausted so callers can make a correct decision; also update the caller's catch
(where pendingAppRefreshes is set) to set pendingAppRefreshes = true only if
hasPendingAppStatsRefresh ultimately failed after retries (or if the error is
non-transient), referencing hasPendingAppStatsRefresh and the
pendingAppRefreshes variable so the orgs.stats_updated_at advancement is not
blocked by transient PostgREST 5xxs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 67bb5a41-09e9-4d20-b0a1-d55614db643a

📥 Commits

Reviewing files that changed from the base of the PR and between 74336ba and b3224f2.

📒 Files selected for processing (5)
  • src/types/supabase.types.ts
  • supabase/functions/_backend/triggers/cron_stat_app.ts
  • supabase/functions/_backend/utils/supabase.types.ts
  • supabase/migrations/20260422104849_stale_chart_refresh_state.sql
  • tests/cron_stat_app_followup.unit.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/cron_stat_app_followup.unit.test.ts
  • src/types/supabase.types.ts
  • supabase/migrations/20260422104849_stale_chart_refresh_state.sql

Comment thread supabase/functions/_backend/triggers/cron_stat_app.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b3224f2c87

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread supabase/functions/_backend/triggers/cron_stat_app.ts Outdated
Comment thread supabase/functions/_backend/triggers/cron_stat_app.ts Outdated
@riderx riderx marked this pull request as draft April 22, 2026 18:18
Comment thread supabase/functions/_backend/triggers/cron_stat_app.ts Fixed
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7b9249e62a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread supabase/migrations/20260422104849_stale_chart_refresh_state.sql
Comment thread src/components/dashboard/Usage.vue
@riderx riderx marked this pull request as ready for review April 22, 2026 18:49
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 67e26534bd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/dashboard/Usage.vue
Comment thread supabase/functions/_backend/triggers/cron_stat_app.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 43f4724dd3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread supabase/functions/_backend/triggers/cron_stat_app.ts Outdated
@sonarqubecloud
Copy link
Copy Markdown

@riderx riderx merged commit b7bb70d into main Apr 22, 2026
15 checks passed
@riderx riderx deleted the codex/stale-chart-refresh branch April 22, 2026 20:10
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