BC Grid

Server Row Model

The query, cache, mutation, and streaming contract for database-backed BusinessCraft grids.

BusinessCraft grids often sit on top of large legacy tables. The server row model keeps those screens responsive by loading only the rows the user needs while preserving sort, filter, selection, edit, and export semantics.

When To Use It#

Use BcServerGrid when any of these are true:

  • the table is too large to load into the browser,
  • sort or filter must run in PostgreSQL or domain logic,
  • rows are lazy tree nodes,
  • export must walk the server result set,
  • edits need pending, rollback, or server reconciliation states.

Client grids are still useful for small setup tables and local projections. For core ERP lists, start with the server row model unless there is a clear reason not to.

Modes#

The row model supports three fetch shapes:

  • paged loads explicit pages and is the default fit for list screens.
  • infinite loads scroll blocks and prefetches in the scroll direction.
  • tree loads children only when a parent expands.
paged server grid
<BcServerGrid
  mode="paged"
  columns={columns}
  rowId={(row) => row.account}
  loadPage={loadAccountsPage}
  gridId="gl.accounts"
/>

Query Shape#

The grid sends the current view state to the loader: sort, filters, search text, grouping, pagination, locale, and a view key. The server responds with rows, total counts when available, diagnostics, and cache metadata.

The loader should treat the query as the source of truth. Do not read sort or filter state from URL parameters separately once the grid has built a server query.

Cache Behavior#

The server row model owns:

  • request dedupe for overlapping loads,
  • aborting superseded requests,
  • LRU block eviction,
  • retry state,
  • diagnostics for cache hit rate and queue depth,
  • invalidation when the view key changes.

This keeps BusinessCraft screens from duplicating caching logic. The screen owns only the typed loader and mutation callbacks.

Edits And Streaming#

Server-backed editing should report pending and settled mutations through the server grid API. Streaming updates use ServerRowUpdate events so loaded blocks can update without dropping scroll, selection, or current filters.

streaming bridge
useServerRowUpdates({
  subscribe: (onUpdate) => subscribeToAccountUpdates(onUpdate),
  gridApi,
});
Keep loaders pure

A loader should return rows for the requested view. Permission checks, domain validation, and persistence stay in server actions or domain packages; the grid should not know legacy business rules.

The paged, infinite, tree, streaming, and CSV export demos show the same server contract from different angles. Use them together when designing a new ERP list screen.