Skip to content

Share account follow queries with React Query - #82

Merged
abhi1693 merged 2 commits into
masterfrom
refactor/reader-query-follows
Oct 4, 2026
Merged

abhi1693 merged 2 commits into
masterfrom
refactor/reader-query-follows

Conversation

@abhi1693

@abhi1693 abhi1693 commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

What changes and why?

Topic and source follow providers independently managed private reads, loading/error state, request controllers, save guards, concurrent-item merges and retry handling. Both now use one useFollowPreferences hook backed by TanStack React Query 5.104.1. Their existing contexts, buttons, settings forms and CSRF-protected endpoints remain compatible.

The shared cache deduplicates reads and duplicate item writes across consumers. Different-item writes merge acknowledged results; bulk saves are blocked while conflicting item writes are pending. Older reads are canceled before writes so they cannot overwrite saved state. A failed save retains confirmed follows and exposes the existing error message. Failed reads recover on visible-tab resume, reconnect or explicit retry, with repeated resume events coalesced.

UserProvider creates a client inside its existing account boundary. Private queries include the account/session revision; account changes and sign-out clear the client, while credential refresh cancels old reads/writes without remounting the reader. Late responses cannot replace current-session data. Guest browsing makes no private preference requests. Private query data is kept in memory; no browser persistence or server hydration is added. Automatic retries and offline mutation replay are disabled.

React Query fits this duplicated account-data lifecycle. Public feeds retain their generation-aware pagination, and the admin already centralizes reads with visibility-aware polling and authentication handling. Migrating those specialized paths would add scope without a demonstrated benefit. The adoption boundary and deliberate overrides of TanStack defaults, including cancellation, are documented in this PR rather than repository Markdown.

Validation

Updated against master after #81, preserving grid/list preferences, Trending routes, article-first rendering, options-error recovery, coordinated prompts and scoped runtime/touch fixtures.

  • 54 focused follow, provider, account-boundary and feed-preference tests passed. They include canceled/late reads, account/credential changes, failed writes, confirmed-state recovery and the preceding Trending/grid/list regressions.
  • npm ci installed the merged lockfile successfully and reported zero vulnerabilities.
  • The source-follow browser helper now lives under apps/web/tests/browser and remains shared with both extensions. Coverage exclusions are unchanged.
  • The added README adoption/ownership/retry-policy prose is removed; existing product and usage documentation is retained.
  • Normal commit hooks passed for frontend lint/types/unit tests, extension types/tests/builds and Codex transport checks. Current-head CI passed 42 jobs, with 13 expected skips, including CI required, all three CodeQL analyses, Sonar, dependency/secret/workflow checks, populated upgrades, real API/admin journeys, performance comparison and ARM64 image build/scan/smoke checks.
  • Hosted tests: 3,007 backend unit, all 1,137 PostgreSQL/Redis integration, 847 web and 648 admin cases passed with no skips. Backend unit coverage is 67.79% across all 273 source files against the unchanged 67.60% minimum. The coverage PR comment is updated for the current commit.
  • Actual web, Chrome and Edge browser suites passed: shared source-follow read/write/error/retry behavior, account sessions, grid/list preferences, 120-article pagination, article-first rendering, options recovery, prompt coordination, responsive layouts and touch interactions.
  • Sonar MCP confirms gate OK, zero open issues, 94.0% new-code coverage and 0.0% new duplication. No quality rule or gate is weakened.
  • GitHub’s separate managed AI findings scan remains unavailable because its monthly quota is exhausted (HTTP 402); standard CodeQL passed. No paid/account changes were made. Actual web/Chrome/Edge parity is a merge gate. Auto-merge is disabled; the backend 67.60% coverage minimum is unchanged.
  • Native GitHub screenshot attachment upload is unavailable through the configured tools. Original implementation screenshots were captured and reviewed locally; no review screenshots are committed.

Rollout notes

The dependency is pinned exactly and recorded with integrity hashes in the npm lockfile. The original implementation measured an approximately 11 KB gzip extension-entry increase from adding React Query. Current reader builds are being checked after the preceding grid/list changes; no production speed improvement is inferred from library adoption.

Existing API contracts and authentication boundaries are preserved; no database migration or configuration change is required. The change is isolated on refactor/reader-query-follows, after Grid/List PR #81 has merged. Website deployment and browser-store publication follow the normal release process.

Merge after #81 and before #83–#84, one at a time, after all current-head checks pass.

Ready for review

  • The description explains the change and validation results, including gaps.
  • Relevant regression tests are updated; technical decisions remain in this PR.

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

PR reader API performance

Result: INCONCLUSIVE

5 inconclusive · 3 within threshold. Zero request failures across all six runs.

Base 6cde7841b6856d92763fe5d1c579ee4e32f15004 → PR bfbb4842823182a5d093d87acc3cfa8f98aed822

Three independent runs per revision, each on a fresh GitHub-hosted ARM64 runner. 16 users, 60 seconds/run, 1,000 synthetic articles, cache off, five PgBouncer slots.

Latency comparison

All latency values are in milliseconds; lower is better. Values are medians of three runs.

Route Base p95 PR p95 Change Result
All requests 86 80 -6 (-7.0%) Within threshold
Latest feed 110 110 +0 (+0.0%) Within threshold
Feed pagination 79 80 +1 (+1.3%) Within threshold
Article detail 72 55 -17 (-23.6%) Inconclusive
Source feed 88 68 -20 (-22.7%) Inconclusive
Topic feed 85 76 -9 (-10.6%) Inconclusive
Feed filters 73 64 -9 (-12.3%) Within threshold
Sources 50 35 -15 (-30.0%) Inconclusive
Topics 41 40 -1 (-2.4%) Inconclusive
Additional latency and throughput metrics

Each cell shows base → PR. Latencies are in milliseconds.

Endpoint p50 p99 Requests/s
Aggregated 28 → 26 120 → 120 30.82 → 30.42
/v1/feed [latest] 41 → 42 140 → 150 9.08 → 8.73
/v1/feed [page] 25 → 24 110 → 120 3.79 → 3.60
/v1/articles/[id] 17 → 17 100 → 90 6.17 → 6.11
/v1/feed [source] 27 → 26 130 → 100 1.77 → 1.85
/v1/feed [topic] 26 → 25 130 → 97 1.68 → 1.76
/v1/feed/options 21 → 19 100 → 90 2.73 → 2.62
/v1/sources 12 → 10 80 → 63 2.73 → 2.62
/v1/topics 13 → 10 66 → 59 2.73 → 2.62
Individual runs
Run Requests Failures Exit code
Base 1 1673 0 0
Base 2 1738 0 0
Base 3 1750 0 0
PR 1 1688 0 0
PR 2 1723 0 0
PR 3 1708 0 0
How to interpret this report

Regressed / Improved: a p95 regression needs >20% and >20 ms increase in the medians and at least two head samples versus the base median. Improvements use the inverse threshold. Within threshold means the change did not meet both thresholds.

Inconclusive: a within-revision p95 range >35% of its median and >20 ms is too noisy for a confident latency verdict.

Inconclusive latency comparisons are non-blocking: the check passes without claiming an improvement. Confirmed regressions and test/report errors fail the PR gate. Throughput is descriptive: paced users do not measure maximum capacity. This uncached public API test does not establish production health, browser performance or worker capacity. Separate runners can differ in hardware or host load; repetitions and noise checks reduce but cannot eliminate that uncertainty.

Full HTML/CSV reports and logs · attempt 1

@gitar-bot

gitar-bot Bot commented Oct 4, 2026

Copy link
Copy Markdown
Code Review ✅ Approved

🟡 Medium risk · Account-scoped follow reads and writes now use a shared React Query lifecycle.

Migrates topic and source follow management to a shared useFollowPreferences hook backed by React Query, deduplicating reads and writes across consumers while preserving existing contexts, endpoints, and CSRF protection. Request cancellation, account-boundary lifecycle management, and error recovery are implemented per React Query patterns. 54 focused tests pass, dependencies are pinned with integrity hashes, and no issues were found.

Review coverage

📋 Rules No rules evaluated

🧪 Functional validation Not enabled · Set up

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Counting what did not apply, without listing it.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

Backend unit coverage

PASS · minimum combined coverage 67.60%.

Tests: 3007 passed, 0 failed, 0 skipped. Source files: 273.

Workspace Lines Branches Combined
All backend code 71.64% 53.77% 67.79%
apps/admin-api 64.78% 35.76% 59.95%
apps/aggregator 73.60% 57.18% 69.86%
apps/api 68.94% 55.88% 66.48%
apps/article-enrichment-worker 80.00% 50.00% 71.43%
apps/cli 68.76% 42.93% 64.81%
apps/images-worker 80.00% 50.00% 71.43%
apps/mcp 79.90% 73.88% 78.77%
apps/notifications 83.33% 76.67% 81.75%
apps/search-indexer 85.48% 85.71% 85.53%
apps/source-discovery-worker 80.00% 50.00% 71.43%
apps/user-api 59.19% 32.90% 54.27%
packages/core 73.81% 56.67% 69.73%
packages/http 94.43% 86.47% 92.62%

Unit coverage includes every backend workspace. PostgreSQL/Redis integration tests run separately.

Commit: bfbb484 · HTML, JSON, XML reports and job logs · attempt 1

@sonarqubecloud

sonarqubecloud Bot commented Oct 4, 2026

Copy link
Copy Markdown

@abhi1693
abhi1693 merged commit ed4bda1 into master Oct 4, 2026
57 checks passed
@abhi1693
abhi1693 deleted the refactor/reader-query-follows branch October 4, 2026 17:36
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