s-m-r-t
Open the s-m-r-t source on GitHub Switch to dark color scheme
← All packages
Business & operations v0.57.40

@happyvertical/smrt-reports

Materialized aggregate read models with incremental refresh, schedules, and tenant fan-out, plus runtime reports compiled per principal from a stored spec, with browser surfaces.

Source ↗

What it gives you

Materialized aggregate read models with incremental refresh, schedules, and tenant fan-out, plus runtime reports compiled per principal from a stored spec, with browser surfaces.

  1. 01Decorated groupings, measures, and time buckets
  2. 02Incremental refresh with watermarks and affected-group recomputation
  3. 03Durable scheduled refresh through smrt-jobs
  4. 04Runtime reports: a declarative spec stored as data, never a stored result
  5. 05Saved-report routes and a report chart widget on the /svelte subpath

Runtime reports are data, not code

parseRuntimeReportSpec accepts a closed grammar with no SQL, expressions, joins, tables, or tenants. compileRuntimeReportSpec resolves it against a server-owned source allow-list, the registry field policy, the live principal permissions, and a fail-closed tenant predicate. A stored RuntimeReport is recompiled for the running principal on every run, and result rows are never persisted. The assistant tools that define and run them live in smrt-chat.

Preview a spec in the browser

The /spec subpath is the browser-safe half of runtime reports. It exports parseRuntimeReportSpec, the spec grammar and time helpers, and runtimeReportSpecDigest. runRuntimeReportInMemory evaluates a spec over rows the caller already holds, with the compiler's own rules. It is a preview and test runner, never an authority boundary. Stored reports still compile per principal on the server.

Two recipes with different surfaces

reports.materialized declares the internal refresh tables: runs, watermarks, locks, schedules, and refresh tasks. An app owns its report classes, so the recipe does not list them. Those tables have no REST or MCP surface, so the recipe has no nav and no browser surface. reports.runtime brings the RuntimeReport model with nav, the /reports and /reports/:id routes, and the runtime-report-chart widget.

Server surfaces for the browser components

createRuntimeReportConfirmHandler serves the confirmation a person gives before a proposed report is saved; runRuntimeReportForPrincipal and archiveRuntimeReportForPrincipal reuse the read and create grants. Source allow-lists come from the packages.reports.runtime.sources config block; no configuration means no sources. The components take server report types as type-only imports and draw charts with smrt-ui/charts.

The adapter is the exposure boundary

buildReportAdapterDescriptor and queryReportMaterializedRows bind tenant context, projection, paging, filters, and facets before rows cross an application boundary. The adapter redacts fields that the caller is not allowed to expose.

Refresh, views, exports, and schedules retain their state

getReportLifecycle describes availability; previewReportRefresh and applyReportRefresh run through an action host. Saved views revalidate policy and migrate from v0 to v1. Exports bind to a snapshot fingerprint and page offset worker contract. SmrtReportSchedule supports cron, durable enqueue, and onChange interception.