Skip to content

Give /api/payments filter parameters, and index for them #167

Description

@wagmiiii

Repo context. accensa-app is the off-chain half of Accensa — the merchant back-office for x402 sellers on Stellar. Three workspace packages matter: apps/web (Next.js dashboard and the indexer at src/app/api/sync), packages/sdk (@accensa/sdk), and apps/demo-merchant. The Soroban contracts live in accensa-contracts.

🟢 Unblocked. Additive query parameters on an existing route.

Problem

(Refiled. This issue previously proposed an Apollo Federation gateway for "multi-chain analytics", on the premise that the API is monolithic REST causing "multiple roundtrips and excessive over-fetching". Two corrections. There is one chain, and the schema is two tables — payments and sync_state — so there is nothing to federate. And src/app/api/payments/route.ts already supports limit and a cursor, so page-level over-fetching is already handled. The real gap is narrower and worth fixing.)

/api/payments can page, but it cannot filter. Every query returns the most recent payments and nothing else. A caller wanting one route's payments, or one payer's, or last week's, must fetch pages until it finds them.

That is the API half of the dashboard filtering in #158, and it is also what any merchant integrating against this API rather than the UI will hit first. And because the table is append-only and grows with every payment, "fetch pages until you find it" gets steadily worse.

What to build

  1. Add typed filter parametersroute, payer, asset, and a date range. Reuse the existing validation style in this file: limit is already parsed, range-checked, and rejected with a specific message rather than silently clamped.
  2. Keep the cursor correct under filters. The cursor encodes a position in an ordering; adding a WHERE clause must not let it skip or repeat rows. This is the substance of the issue — get it wrong and pagination silently loses payments.
  3. Add the indexes. Filtering on route or ts without an index turns every dashboard query into a sequential scan of an append-only table. Include the migration.
  4. Reject unknown parameters rather than ignoring them, so a typo in a filter fails loudly instead of quietly returning everything.
  5. Decide about /api/routes. That route exists and may overlap with a route filter — either reuse it or say why it stays separate.
  6. Document the parameters wherever the API is described, and keep the error shapes consistent with what the route already returns.

Related: #158 is the UI half. #142 asks for the date-range filter specifically.

Acceptance criteria

  • /api/payments accepts route, payer, asset and a date range.
  • Invalid or unknown parameters are rejected with a specific message, matching the existing limit validation style.
  • Cursor pagination is correct under every filter — a test walks all pages of a filtered result and asserts no row is skipped or repeated.
  • A migration adds indexes covering the filterable columns.
  • The relationship to /api/routes is resolved and stated.
  • The parameters are documented alongside the rest of the API.
  • pnpm test passes in apps/web, including db.integration.test.ts.
  • pnpm lint and pnpm build pass.
  • PR description includes Closes #167.

Contact & Support

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions