Skip to content

feat(api): import-boundary guard, path-encoding, cache-invalidation, pagination (#1332 #1333 #1335 #1336) - #1454

Merged
hman38705 merged 5 commits into
solutions-plug:mainfrom
misrasamuelisiguzor-oss:feat/api-client-1332-1336
Sep 1, 2026
Merged

feat(api): import-boundary guard, path-encoding, cache-invalidation, pagination (#1332 #1333 #1335 #1336)#1454
hman38705 merged 5 commits into
solutions-plug:mainfrom
misrasamuelisiguzor-oss:feat/api-client-1332-1336

Conversation

@misrasamuelisiguzor-oss

Copy link
Copy Markdown
Contributor

API Client: import boundary guard, path-encoding, cache-invalidation, pagination

Four frontend/src/lib/api/ issues. Three are "regression trap" issues whose fix already
landed in an earlier commit - the delta here is the guard test that keeps it from
regressing, plus one missed call site. #1336 is a new helper.

What changed and why

#1332 - public/admin client split guard

The split (public-client.ts / admin-client.ts, commit 895748e) and an export
boundary test (public-client.test.ts) already exist. Added the missing import boundary
guard: client-import-boundary.test.ts statically scans src/app/** and fails if any route
outside src/app/admin/** (and the privileged markets/<id>/resolve route) imports
admin-client directly. It also re-asserts that public-client.ts never imports
admin-client and exposes no /api/v1/admin, /api/v1/audit, or /api/v1/email path.

#1333 - centralize path-parameter encoding

fillPath() was the intended single encoder (commit dd027a9) but lived in
public-client.ts and three src/lib/api/ call sites still called encodeURIComponent
directly (admin-client.ts email preview, tts-client.ts job status + audio).

  • Moved fillPath (plus a new fillPathParams for multi-segment templates) into a
    dedicated paths.ts; public-client.ts re-exports it so existing importers are
    unaffected.
  • Routed the three stray call sites through fillPath.
  • path-encoding.test.ts: (a) a market_id / tx_hash containing /, ?, #
    round-trips as a single encoded path segment (asserted against a mocked fetch);
    (b) fillPath encodes exactly once; (c) a grep guard - no src/lib/api/*.ts file
    except paths.ts calls encodeURIComponent.
  • Out of scope: raw fetch() calls in app pages/components that never used the client -
    a broader refactor with its own issues.

#1335 - invalidate cache tags only on mutation success

The succeeded guard (a 200 body with success: false must not bust the cache, commit
4a15eda) already exists in both request helpers. Added
cache-invalidation-on-success.test.ts: a POST returning { success: false } leaves the
tagged entry untouched; { success: true } and non-envelope bodies invalidate as before.
(The guard lives in the request helper, not cache.ts, because that is where the response
body is parsed.)

#1336 - offset/cursor pagination helper (new pagination.ts)

  • buildPaginationParams({ mode: 'offset' | 'cursor', limit?, offset?/cursor? }) builds the
    query params for either mode. limit defaults to 20 and throws RangeError before the
    request is sent
    when it exceeds 100, mirroring the server's documented 400 message.
  • The cursor is passed through verbatim - never parsed or mutated client-side.
  • CursorPager holds the opaque cursor for cursor-mode paging; setSort(key) drops the
    stale cursor when the sort order actually changes, so the next page restarts from the top.

How to test

cd frontend
npm ci --legacy-peer-deps
./node_modules/.bin/jest src/lib/api
  • src/lib/api Jest suite: 135 pre-existing + 21 new tests pass.
  • tsc --noEmit: the new/changed files add no errors over the repo's pre-existing count.
  • npm run build (generate-client && next build) not run here - needs the full monorepo
    build; nothing in this change touches build config.

Breaking changes

None. fillPath keeps its public-client export; the request/cache behaviour is unchanged.

Related issues

Closes #1332
Closes #1333
Closes #1335
Closes #1336

PR Checklist

  • Branch is up to date with main
  • Commit messages follow Conventional Commits
  • Tests added for the change
  • Documentation updated if behaviour changed (n/a - behaviour preserved)
  • No secrets or credentials committed

@drips-wave

drips-wave Bot commented Aug 29, 2026

Copy link
Copy Markdown

@misrasamuelisiguzor-oss Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@hman38705
hman38705 merged commit 3cb43cc into solutions-plug:main Sep 1, 2026
15 of 62 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants