@happyvertical/smrt-preferences
Saved user-interface preferences: tenant defaults and per-user overrides for overview layouts and the app frame, validated per registered kind.
What it gives you
Saved user-interface preferences: tenant defaults and per-user overrides for overview layouts and the app frame, validated per registered kind.
- 01Two built-in kinds: overview (widget layout of a customizable overview page) and shell-layout (AdminShell settings)
- 02An organization sets the default; each person keeps their own version on top; reset returns to the layer below
- 03Every kind validates its payload on save and again on load; invalid data is refused or dropped and reported
Stores, not the model
createPreferenceStore, createOverviewStore, and createShellSettingsPreferences are the application API. The UiPreferenceRecord model refuses writes that do not come from the store and never returns another person’s preferences. Saves pass the revision they loaded; a stale revision returns conflict instead of overwriting.
Permissions are per kind
overviews.customize and shell.customize change the organization default; overviews.personalize and shell.personalize keep a personal version. Owners and admins receive all four when role permissions are seeded; members and viewers receive the two personalize slugs. The store reads them from the signed-in person’s permission set in the request context.
Register more kinds
registerPreferenceKind takes a kind name, a format version, the two permission slugs, and a validate function. The table _smrt_ui_preferences is created by smrt db:migrate, never at runtime.
Package UI
No UI layer to carry
This package stays focused on models, runtime behavior, or tooling. Build its interface with smrt-ui, or use a related domain package that exposes a /svelte entry point.
Intentionally headless
Package previews
No playground module yet
This package does not currently export a ./playground module. Its component names and import path remain available in the Components tab.
Intentionally not registered
Generated interface
REST
The exact route set comes from each model's @smrt({ api }) policy
and the application manifest—not from a second controller definition.
The preference table has no generated REST, MCP, WebMCP, or CLI surface: a generated route would skip kind validation. Applications call the stores from their own server code.
Generated interface
MCP
AI tools are generated from the methods you explicitly include. Their inputs are validated against the same model metadata used by REST and CLI.
The preference table has no generated REST, MCP, WebMCP, or CLI surface: a generated route would skip kind validation. Applications call the stores from their own server code.
Browser-native agent interface
WebMCP
The generated web definitions carry the same tool names, descriptions, and JSON Schema
inputs as MCP. smrt-web registers them with document.modelContext.
The preference table has no generated REST, MCP, WebMCP, or CLI surface: a generated route would skip kind validation. Applications call the stores from their own server code.
Generated interface
CLI
The app CLI turns manifest resources into predictable operator commands while keeping package-specific actions close to their models.
The preference table has no generated REST, MCP, WebMCP, or CLI surface: a generated route would skip kind validation. Applications call the stores from their own server code.