Spike #855 — Item Filter & Sort: Summary
5-minute overview. For the authoritative reference, see architecture.md. For the deep dive, see implementation-notes.md.
Ticket: #855 · Branch: feature/filter-sort-ssrm-bff
What we built
Section titled “What we built”Per-column filtering and multi-column sorting on the /items page:
- [SPA] CloudScape PropertyFilter — toolbar above the grid. Structured filters (Type = Office, Supplier contains Acme) plus free-text search across all 26 filterable fields. AND/OR logic.
- [BFF] Filter + sort engines — apply CloudScape tokens and AG Grid sort model against a cached full-tenant dataset. 5-minute cache TTL (
CACHE_TTL_SECONDS = 300). - [SPA] AG Grid SSRM — infinite scrolling. AG Grid requests pages of ~100 items from the BFF on scroll.
Why this shape
Section titled “Why this shape”The backend supports filter/sort via the query-DSL pattern. We deferred integration to ship faster — BFF-side filtering over a cached set was buildable in one sprint with no backend coordination. The architecture transitions cleanly to query-DSL when that integration happens.
How it works
Section titled “How it works”Key design choices
Section titled “Key design choices”| Choice | Why |
|---|---|
| CloudScape PropertyFilter | Unified toolbar with AND/OR. Free-text across all columns. Clean serializable query for Redux. |
| AG Grid SSRM | Browser holds one page (~100 items). Same row model needed for query-DSL. |
| BFF filter + sort engines | Reusable. Testable. Single source of truth via shared ITEM_FIELD_ACCESSORS_TYPED. |
| 5-minute cache TTL | Protects against external API clients mutating items. Named constant (CACHE_TTL_SECONDS = 300). |
2MB unstable_cache per-entry limit | Drives stripToGridColumns() — drops secondarySupply, previous, createdBy, createdAt to fit. |
| Tenant-scoped invalidation tag | revalidateTag('items-all:' + tenantId) — busts only the mutating tenant’s entries. A global 'items-all' tag would grind the system to a halt across all tenants. |
HARD_MAX_ITEMS | BFF-memory cap per tenant. Above this, migration path is query-DSL — not raising the cap. |
| Query-DSL deferred | Backend supports it. We ship faster without it. Architecture transitions cleanly. |
Source materials
Section titled “Source materials”- architecture.md — authoritative reference (types, request flow, cache pattern)
- Query-DSL pattern
- Ticket #855
Copyright: © Arda Systems 2025-2026, All rights reserved