Goal: SSRM Direct Backend Query
Lifecycle: In progress — Phase 1 (exploration and design) complete, implementation not started.
Tickets: PDEV-244 (parent) · PDEV-1308 ✅ · PDEV-1309 ✅ (one gap: PDEV-1335) · PDEV-1315 (/distinct requirements) · PDEV-1335 (lookupPage last-page signal)
Repositories: arda-frontend-app, operations and/or common-module, documentation
Predecessor: Spike #855 — Item List Filter & Sort, which built the SSRM + BFF cache this project replaces.
Summary
Section titled “Summary”The /items grid uses AG Grid’s Server-Side Row Model, but the “server” is a
Next.js BFF holding a per-tenant cache of every item (unstable_cache, 5-minute
TTL, capped at 15 000 rows). Filtering, sorting and paging are evaluated in
Lambda memory over that cache; the backend sees one unfiltered fan-out per cache
fill and no Query DSL filter at all.
This project moves that evaluation to operations: property and enum filters,
sort and pagination become Query DSL requests against POST /v1/item/item/query,
and free-text search becomes POST /v1/item/item/lookup against the indexed
search_text document. The cache, its 15 000-row ceiling, and the
cross-Lambda freshAfter freshness mechanism all retire with it.
Why now
Section titled “Why now”PDEV-244 was written before either half of this existed. Since then:
- The SSRM machinery landed (spike #855), so the grid already speaks a block-request protocol — what is missing is a backend behind it.
- PDEV-1251 landed
/lookup,/by-code, thesearch_textgenerated column and its GIN trigram index, giving the backend a real search capability. This delivered what the earlier analysis had filed as a future follow-up, and made the original plan (a hand-curated six-field regex OR) obsolete.
The ticket as originally written targeted entity-data-grid in ux-prototype
with a searchMode: 'client' | 'server' toggle. That framing no longer matches
the system; see Scope.
In scope
Section titled “In scope”arda-frontend-app— replace the cached SSRM route with a translator that compiles CloudScape filter tokens, the AG Grid sort model and the block range into Query DSL, routes to/queryor/lookupby request shape, and removes the cache and its freshness plumbing.operations/common-module— a distinct-values capability for the filter dropdowns (PDEV-1315), which the cache removal otherwise takes away. Shape, hosting and performance are open design decisions bounded by seven stated consumer requirements.documentation— this goal, and the completion-phase updates listed under Deliverables.
Out of scope
Section titled “Out of scope”- The kanban grid and any other SSRM surface. Verified independent: the BFF
cache exists only in
src/app/api/arda/items/_lib/cachedItems.ts. ux-prototype. Components that ought to be shared get follow-up tickets to promote them, rather than moving in this project.- Backend row counting. No
withTotal, no COUNT aggregation — see Accepted losses.
Approach
Section titled “Approach”Single-pass replacement, verified on the Amplify PR preview
(pr-<N>.d38w5m1ngjza76.amplifyapp.com, dev backend) before merge. One PR
carries the translator, the search routing, the count rework, the dropdowns and
the cache removal together. A preview deployment exercises the whole page
against real data, which a feature flag would only have offered after merge, and
a single PR reverts cleanly.
Two consequences: the search-behavior decision could not be deferred to a later increment (it is settled — see below), and MSW mock fidelity becomes the automated safety net, since e2e runs in mock mode and a stale handler would keep the suite green while the real path is broken.
Settled design
Section titled “Settled design”Filtering/sorting and free-text search are specified as two distinct capabilities:
- Case I — no search string. CloudScape terms compose into the Query DSL
filter; ordering is the user’s column sort, with
eIdappended for stable paging. - Case II — search string present. The same filter composes, AND-ed with the
fuzzy predicate by
/lookup; ordering is relevance, and the UI says so.
Both are servable by operations as it stands — the AND composition is what the
endpoint hardwires. Seven sub-decisions (token grouping, single search token,
whitespace normalization, NO_SORT in Case II, no backend counting, sort-state
preservation, a 3-character minimum) are settled and recorded in the workbook
thread.
Accepted losses
Section titled “Accepted losses”Deliberate, not deferred:
- The unfiltered total is gone.
"X of Y items"cannot return in any form. The filtered count is exact once the last block is reached and immediately when a result set fits one block; otherwise it is qualified ("100+ items"). An occasional extra page request is accepted as preferable to aCOUNTquery on every filter change. - Free-text reach changes. Search gains
descriptionand the secondary-supply fields; it loses numerics, dates,cardNotesDefault,additionalQrs, the presentation fields, andnotesbeyond 256 characters. Disclosed rather than engineered away. - Option lists narrow for two fields.
supplierandmanufacturerresolve through the business-affiliate lookup, which requires typed input.
Success criteria
Section titled “Success criteria”- The
/itemsgrid filters, sorts, pages and searches entirely againstoperations, with no per-tenant cache in the BFF and no 15 000-row ceiling. - Case I and Case II behave as specified above, including the UI indication that relevance ordering is in effect.
- Filter dropdowns are populated for the nine open-set fields, with a type-ahead fallback wherever the value set is truncated.
- No column can 500 the grid: every filterable and sortable
colIdresolves to a verified backend locator, guarded by a coverage test. - Verified on the Amplify preview against a dev tenant of more than 1 000 items, seeded through the system API as part of this project’s test setup.
- Mock-mode handlers and e2e coverage match the new contract.
Deliverables
Section titled “Deliverables”Beyond the code:
- Update the Spike #855 project, whose
architecture this project replaces, and whose status is still
in-progress. - Review the current-system documentation for descriptions of the items BFF cache or SSRM flow that go stale on merge.
- Set this document’s
statustocompleted.
Reference
Section titled “Reference”- Workbook (design, decisions, task specifications):
workbooks/notebooks/ssrm-direct-be-query/ - Query DSL
- Predecessor spike
Copyright: (c) Arda Systems 2025-2026, All rights reserved
Copyright: © Arda Systems 2025-2026, All rights reserved