Skip to content

fix(astro-web): page PostgREST reads and keep tracked services at 999 (RH-07bc) - #106

Merged
supertrained merged 2 commits into
mainfrom
cursor/rh-07bc-postgrest-paging-7020
Oct 6, 2026
Merged

supertrained merged 2 commits into
mainfrom
cursor/rh-07bc-postgrest-paging-7020

Conversation

@tomdmeredith

@tomdmeredith tomdmeredith commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

RH-07bc

Tom Meredith greened this for merge on 2026-10-06, about 9:30 AM PT. Bug fix on the live Astro site (vercel.json builds packages/astro-web). Not merged here.

Do not merge until this proof is read.

Public integers stay 999 services · 435 capabilities · 28 callable · 87 categories. The leaderboard headline cannot show 1000 (PostgREST max-rows cap) or 1048 (paged scores / services table size).

Production path is packages/astro-web/src/lib/api.ts. packages/web/lib/api.ts is the legacy Next app and is not the rhumb.dev build, so this change does not touch it.

What changed

  • supabaseFetchAll pages PostgREST with limit/offset until an empty page (50-page guard) for sitemap services, category counts, the unknown-category leaderboard error list, and evidence list reads.
  • Evidence filters use source_type (runtime_verified, tester_generated). evidence_records has no evidence_type column (packages/api/migrations/0011_review_evidence.sql), so the old filter 400'd and every service showed zero runtime evidence.
  • getServiceCount() reads GET /v1/services?limit=1 data.total first. A paged scores read remains only as a fallback, and displayedServiceCount() refuses 1000 and 1048. The leaderboard hub no longer falls back to the sum of Supabase category counts.

Proof

Paging past 1000. collectPagedRows is what supabaseFetchAll calls. The unit test feeds a 1000-row page, then a 48-row page, then an empty page, and asserts the calls are limit=1000&offset=0, offset=1000, offset=2000 and that 1048 rows are collected. That collected size is then passed through displayedServiceCount, which returns 999.

Count path = API 999. Happy path is getServiceCount → getServiceCountFromAPI() → GET /v1/services?limit=1 data.total. Live read on 2026-10-06:

Endpoint Result
GET /v1/services?limit=1 data.total 999
GET /v1/capabilities?limit=1 data.total 435
GET /v1/proxy/stats services_callable 28
GET /v1/leaderboard 87 categories

The public leaderboard category service_count values sum to 959, not 999. The old hub fallback (categoryServicesTotal) would have shown that sum, or ~1048 after paging the Supabase services table. Both are removed. If the API total is missing, 1000, or 1048, the headline falls back to the committed public catalog (999).

source_type. Both evidence queries are source_type=in.(runtime_verified,tester_generated) with a stable id order, and they go through supabaseFetchAll. The RH-07c note expected this to move services off "Assessed" under the existing tier rules (Tested at ≥1 runtime/tester row, Verified at ≥50). This PR does not change those thresholds and did not re-query Supabase.

Tests

The first public-truth run failed because packages/web Vitest imported packages/astro-web/src/lib/public-catalog.ts. Vitest then loaded packages/astro-web/tsconfig.json, which extends astro/tsconfigs/strict, and that package is not installed in the web job (TSConfckParseError).

Those tests no longer live in packages/web. packages/astro-web runs them with Node's test runner (npm test → node --experimental-strip-types --test tests/public-catalog.test.ts) in the astro-web-build job, which already installs Astro on Node 24. public-catalog.ts does not import other Astro modules, so the runner does not need that tsconfig. The web job is back to its previous three contract files and does not import astro-web TypeScript.

Locally: Node 22 and Node 24.21 both passed the 5 catalog tests. The three public-truth Vitest files passed (36 tests).

Out of scope

RH-09, RH-10, GSC resubmit, tickets #95–#105, #59, launch/GA, paid execute, and RH-07d link columns (base_url / docs_url on services).

Open in Web Open in Cursor 

Sitemap, category, and evidence reads stopped at the PostgREST 1000-row
cap, and evidence filters queried a column that does not exist. The
leaderboard headline now uses the public API total and refuses 1000 and
1048.

Co-authored-by: tomdmeredith <tomdmeredith@users.noreply.github.com>
@vercel

vercel Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
rhumb Ready Ready Preview Oct 6, 2026 4:47pm UTC

Request Review

@tomdmeredith
tomdmeredith marked this pull request as ready for review October 6, 2026 16:41
The public-truth job failed because Vitest imported astro-web TypeScript
and then could not resolve astro/tsconfigs/strict. Those tests now run
with Node's test runner in the astro-web job.

Co-authored-by: tomdmeredith <tomdmeredith@users.noreply.github.com>
@supertrained
supertrained merged commit a9811fc into main Oct 6, 2026
8 of 10 checks passed
@supertrained
supertrained deleted the cursor/rh-07bc-postgrest-paging-7020 branch October 6, 2026 16:50

This branch was successfully deployed

1 active deployment
Preview — e1ba1918 Deployed Oct 6, 2026 by vercel[bot]
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.

3 participants