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
- Add typed filter parameters —
route, 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.
- 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.
- 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.
- Reject unknown parameters rather than ignoring them, so a typo in a filter fails loudly instead of quietly returning everything.
- Decide about
/api/routes. That route exists and may overlap with a route filter — either reuse it or say why it stays separate.
- 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
Contact & Support
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 —
paymentsandsync_state— so there is nothing to federate. Andsrc/app/api/payments/route.tsalready supportslimitand acursor, so page-level over-fetching is already handled. The real gap is narrower and worth fixing.)/api/paymentscan 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
route,payer,asset, and a date range. Reuse the existing validation style in this file:limitis already parsed, range-checked, and rejected with a specific message rather than silently clamped.WHEREclause must not let it skip or repeat rows. This is the substance of the issue — get it wrong and pagination silently loses payments.routeortswithout an index turns every dashboard query into a sequential scan of an append-only table. Include the migration./api/routes. That route exists and may overlap with a route filter — either reuse it or say why it stays separate.Related: #158 is the UI half. #142 asks for the date-range filter specifically.
Acceptance criteria
/api/paymentsacceptsroute,payer,assetand a date range.limitvalidation style./api/routesis resolved and stated.pnpm testpasses inapps/web, includingdb.integration.test.ts.pnpm lintandpnpm buildpass.Closes #167.Contact & Support
SUPPORT.md— contribution help, Wave process, and the full list of channels