Skip to content

perf(importers): paginate surety_admin importer list, inline bond/metrics via JOIN - #1261

Open
omarima-10 wants to merge 1 commit into
vjuliaife:mainfrom
omarima-10:fix/tariffshield-hillwisdom-250-n-plus-one
Open

omarima-10 wants to merge 1 commit into
vjuliaife:mainfrom
omarima-10:fix/tariffshield-hillwisdom-250-n-plus-one

Conversation

@omarima-10

Copy link
Copy Markdown
Contributor

closes #250

What changed

GET /importers for surety_admin already ran as a single JOIN query (not the N+1 described in the issue's premise, confirmed via git blame: it was written this way from the start). What was actually missing against the acceptance criteria:

  • No pagination at all (now ?page=&limit=, max 100, default 50, via listSuretyAdminImporters in db.ts)
  • No bond/metrics data inlined (now resolved per-row via LEFT JOIN LATERAL against the importer's most recent bond_records row, plus a LEFT JOIN against the importer_metrics materialized view)

Also fixed along the way: the admin branch was returning raw snake_case Postgres column names (legal_name, bond_id, ...) while the frontend's Importer type and every other field the surety dashboard reads is camelCase, so the admin importer list was silently rendering blank for legalName/bondId/stellarAddress. Same object construction site as the pagination fix, so fixed together rather than as a separate PR.

Testing

Added apps/api/src/__tests__/integration/surety-admin-importers-list.test.ts (5 cases): correct page size/total, no overlap across pages, picks the newest bond_records row per importer, includes the users JOIN email, includes metrics fields. All 5 pass against a locally seeded Postgres instance.

Disclosure: the repo's committed migration chain (apps/api/src/migrations/) currently has pre-existing, unrelated breaks unconnected to this change: duplicate migration version numbers at 12 and 13 (three 0012_*.ts files, two 0013_*.ts files), and 0008_dev_usage_and_onboarding_drip.ts referencing api_keys before 0015_importer_api_keys.ts creates it. Reproduced against a clean clone of main, not introduced here. Worked around it locally for this PR's own test run by seeding directly from the schema embedded in db.ts.

…st (vjuliaife#250)

Replaces the unpaginated surety_admin importer list with a single JOIN
query that resolves each importer's most recent bond_records row (via
LEFT JOIN LATERAL) and its importer_metrics row inline, instead of
requiring a separate request per importer for that data. Adds
?page=&limit= (max 100, default 50) query params backed by
listSuretyAdminImporters in db.ts, and fixes the admin branch's
response keys, which were being returned as raw snake_case Postgres
column names while the frontend's Importer type, and every other
importer field the dashboard reads, is camelCase.

Verified against a fresh local Postgres instance seeded directly from
the schema in db.ts (the committed migration chain currently has
several pre-existing, unrelated breaks: duplicate migration version
numbers at 12 and 13, and 0008 referencing api_keys before 0015
creates it, not touched here).
@vercel

vercel Bot commented Oct 20, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
tariff-shield-web Error Error Oct 20, 2026 8:20pm UTC

@vercel

vercel Bot commented Oct 20, 2026

Copy link
Copy Markdown

Deployment failed for project tariff-shield-web with the following error:

The `vercel.json` schema validation failed with the following message: should NOT have additional property `rootDirectory`

Learn More: https://vercel.com/docs/concepts/projects/project-configuration

This branch had an error being deployed

1 failed deployment
Preview — 525b6e55 Deployed Oct 20, 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.

Optimize GET /importers surety_admin Query with JOIN to Eliminate N+1

1 participant