Skip to content

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


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.

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.


PlantUML diagram


ChoiceWhy
CloudScape PropertyFilterUnified toolbar with AND/OR. Free-text across all columns. Clean serializable query for Redux.
AG Grid SSRMBrowser holds one page (~100 items). Same row model needed for query-DSL.
BFF filter + sort enginesReusable. Testable. Single source of truth via shared ITEM_FIELD_ACCESSORS_TYPED.
5-minute cache TTLProtects against external API clients mutating items. Named constant (CACHE_TTL_SECONDS = 300).
2MB unstable_cache per-entry limitDrives stripToGridColumns() — drops secondarySupply, previous, createdBy, createdAt to fit.
Tenant-scoped invalidation tagrevalidateTag('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_ITEMSBFF-memory cap per tenant. Above this, migration path is query-DSL — not raising the cap.
Query-DSL deferredBackend supports it. We ship faster without it. Architecture transitions cleanly.