@happyvertical/smrt-preferences 0.57.2 → 0.57.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/smrt-knowledge.json +3 -3
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { checkOverviewOverride, diffOverview, loadOverview, optionsEqual, parseO
|
|
|
4
4
|
import { mergeShellSettingsDelta, sanitizeShellSettingsDelta } from "@happyvertical/smrt-svelte/workspace/server";
|
|
5
5
|
import { TenantIsolationError, TenantScoped, getCurrentTenant, isSuperAdminBypass, tenantId, withTenant } from "@happyvertical/smrt-tenancy";
|
|
6
6
|
//#region src/__smrt-register__.ts
|
|
7
|
-
ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-preferences","packageVersion":"0.57.
|
|
7
|
+
ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-preferences","packageVersion":"0.57.4","objects":{"@happyvertical/smrt-preferences:UiPreferenceRecordCollection":{"name":"uipreferencerecordcollection","className":"UiPreferenceRecordCollection","qualifiedName":"@happyvertical/smrt-preferences:UiPreferenceRecordCollection","collection":"uipreferencerecords","description":"Reads of UiPreferenceRecord. Not decorated: the model has no generated surface, so a decorated collection would only add a second manifest schema for the same table.","filePath":"/home/runner/work/smrt/smrt/packages/preferences/src/collections/UiPreferenceRecordCollection.ts","packageName":"@happyvertical/smrt-preferences","fields":{},"methods":{"findTier":{"name":"findTier","async":true,"parameters":[{"name":"tenantId","type":"string","optional":false},{"name":"kind","type":"string","optional":false},{"name":"surfaceId","type":"string","optional":false},{"name":"scope","type":"PreferenceScope","optional":false},{"name":"userId","type":"string","optional":true}],"returnType":"Promise<UiPreferenceRecord | null>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_ui_preferences","api":{"include":[]},"mcp":{"include":[]},"cli":false},"extends":"SmrtCollection","extendsTypeArg":"UiPreferenceRecord","exportName":"UiPreferenceRecordCollection","collectionExportName":"UiPreferenceRecordCollectionCollection","schema":{"tableName":"_smrt_ui_preferences","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_ui_preferences\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID NOT NULL,\\n \\"kind\\" TEXT NOT NULL DEFAULT '',\\n \\"surface_id\\" TEXT NOT NULL DEFAULT '',\\n \\"scope_type\\" TEXT NOT NULL DEFAULT 'tenant',\\n \\"user_id\\" UUID,\\n \\"scope_key\\" TEXT NOT NULL,\\n \\"payload_json\\" TEXT NOT NULL,\\n \\"format_version\\" INTEGER,\\n \\"updated_by\\" UUID\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":true,"unique":false},"kind":{"type":"TEXT","notNull":true,"unique":false,"default":""},"surface_id":{"type":"TEXT","notNull":true,"unique":false,"default":""},"scope_type":{"type":"TEXT","notNull":true,"unique":false,"default":"tenant"},"user_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"scope_key":{"type":"TEXT","notNull":true,"unique":false},"payload_json":{"type":"TEXT","notNull":true,"unique":false},"format_version":{"type":"INTEGER","notNull":false,"unique":false},"updated_by":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_ui_preferences_tenant_id_kind_idx","columns":["tenant_id","kind","surface_id","scope_type","scope_key"],"unique":true},{"name":"_smrt_ui_preferences_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_ui_preferences_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"_smrt_ui_preferences_user_id_idx","columns":["user_id"]},{"name":"_smrt_ui_preferences_updated_by_idx","columns":["updated_by"]}],"version":"3f9df5fd"},"importPath":"@happyvertical/smrt-preferences"},"@happyvertical/smrt-preferences:UiPreferenceRecord":{"name":"uipreferencerecord","className":"UiPreferenceRecord","qualifiedName":"@happyvertical/smrt-preferences:UiPreferenceRecord","collection":"uipreferencerecords","description":"One stored user-interface preference (#3727): the canonical payload of a registered preference kind (overview, shell-layout, ...) for one surface at one tier of one tenant.","filePath":"/home/runner/work/smrt/smrt/packages/preferences/src/models/UiPreferenceRecord.ts","packageName":"@happyvertical/smrt-preferences","fields":{"tenantId":{"type":"text","required":true,"_meta":{"sqlType":"UUID","__tenancy":{"isTenantIdField":true,"autoFilter":true,"required":true,"autoPopulate":true,"nullable":false,"mode":"required","field":"tenantId","allowSuperAdminBypass":false}}},"kind":{"type":"text","required":true,"default":"","_meta":{"required":true}},"surfaceId":{"type":"text","required":true,"default":"","_meta":{"required":true}},"scopeType":{"type":"text","required":true,"default":"tenant","_meta":{"required":true}},"userId":{"type":"crossPackageRef","required":false,"related":"@happyvertical/smrt-users:User","_meta":{"nullable":true}},"scopeKey":{"type":"text","required":true,"_meta":{"required":true}},"payloadJson":{"type":"text","required":true,"_meta":{"required":true}},"formatVersion":{"type":"integer","required":false,"_meta":{}},"updatedBy":{"type":"crossPackageRef","required":false,"related":"@happyvertical/smrt-users:User","_meta":{"nullable":true}}},"methods":{"loadFromId":{"name":"loadFromId","async":true,"parameters":[],"returnType":"Promise<void>","isStatic":false,"isPublic":true},"loadFromSlug":{"name":"loadFromSlug","async":true,"parameters":[],"returnType":"Promise<void>","isStatic":false,"isPublic":true},"getPayload":{"name":"getPayload","async":false,"parameters":[],"returnType":"unknown","isStatic":false,"isPublic":true},"setPayload":{"name":"setPayload","async":false,"parameters":[{"name":"value","type":"unknown","optional":false}],"returnType":"void","isStatic":false,"isPublic":true},"save":{"name":"save","async":true,"parameters":[{"name":"options","type":"SaveOptions","optional":true}],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"delete":{"name":"delete","async":true,"parameters":[{"name":"options","type":"DeleteOptions","optional":true}],"returnType":"Promise<void>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_ui_preferences","conflictColumns":["tenant_id","kind","surface_id","scope_type","scope_key"],"api":{"include":[]},"cli":false,"mcp":{"include":[]},"tenantScoped":{"mode":"required"}},"extends":"SmrtObject","exportName":"UiPreferenceRecord","collectionExportName":"UiPreferenceRecordCollection","validationRules":[{"field":"kind","rule":"required","fieldType":"text"},{"field":"surfaceId","rule":"required","fieldType":"text"},{"field":"scopeType","rule":"required","fieldType":"text"},{"field":"scopeKey","rule":"required","fieldType":"text"},{"field":"payloadJson","rule":"required","fieldType":"text"}],"schema":{"tableName":"_smrt_ui_preferences","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_ui_preferences\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID NOT NULL,\\n \\"kind\\" TEXT NOT NULL DEFAULT '',\\n \\"surface_id\\" TEXT NOT NULL DEFAULT '',\\n \\"scope_type\\" TEXT NOT NULL DEFAULT 'tenant',\\n \\"user_id\\" UUID,\\n \\"scope_key\\" TEXT NOT NULL,\\n \\"payload_json\\" TEXT NOT NULL,\\n \\"format_version\\" INTEGER,\\n \\"updated_by\\" UUID\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":true,"unique":false},"kind":{"type":"TEXT","notNull":true,"unique":false,"default":""},"surface_id":{"type":"TEXT","notNull":true,"unique":false,"default":""},"scope_type":{"type":"TEXT","notNull":true,"unique":false,"default":"tenant"},"user_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"scope_key":{"type":"TEXT","notNull":true,"unique":false},"payload_json":{"type":"TEXT","notNull":true,"unique":false},"format_version":{"type":"INTEGER","notNull":false,"unique":false},"updated_by":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_ui_preferences_tenant_id_kind_idx","columns":["tenant_id","kind","surface_id","scope_type","scope_key"],"unique":true},{"name":"_smrt_ui_preferences_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_ui_preferences_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"_smrt_ui_preferences_user_id_idx","columns":["user_id"]},{"name":"_smrt_ui_preferences_updated_by_idx","columns":["updated_by"]}],"version":"3f9df5fd"},"importPath":"@happyvertical/smrt-preferences"}},"moduleType":"smrt","smrtDependencies":["@happyvertical/smrt-core","@happyvertical/smrt-tenancy","@happyvertical/smrt-users"],"browser":{"status":"server-only","issues":["#3617","#3624","#3626"],"via":["@happyvertical/smrt-profiles","@happyvertical/smrt-tenancy","@happyvertical/smrt-users"]},"stampsConstructors":true}`));
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/permissions.ts
|
|
10
10
|
var CUSTOMIZE_OVERVIEW_PERMISSION = "overviews.customize";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/__smrt-register__.ts","../src/permissions.ts","../src/kinds.ts","../src/kinds/overview.ts","../src/kinds/shell-layout.ts","../src/kinds/builtin.ts","../src/context.ts","../src/read-guard.ts","../src/write-capability.ts","../src/models/UiPreferenceRecord.ts","../src/collections/UiPreferenceRecordCollection.ts","../src/store.ts","../src/overview.ts"],"sourcesContent":["// Generated by @happyvertical/smrt-core smrtPlugin at library build time.\n// The package manifest is inlined so self-registration cannot miss when a\n// downstream bundler relocates this module away from dist/manifest.json\n// (https://github.com/happyvertical/smrt/issues/1506,\n// https://github.com/happyvertical/smrt/issues/1507).\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(JSON.parse(\"{\\\"version\\\":\\\"1.0.0\\\",\\\"timestamp\\\":0,\\\"packageName\\\":\\\"@happyvertical/smrt-preferences\\\",\\\"packageVersion\\\":\\\"0.57.2\\\",\\\"objects\\\":{\\\"@happyvertical/smrt-preferences:UiPreferenceRecordCollection\\\":{\\\"name\\\":\\\"uipreferencerecordcollection\\\",\\\"className\\\":\\\"UiPreferenceRecordCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-preferences:UiPreferenceRecordCollection\\\",\\\"collection\\\":\\\"uipreferencerecords\\\",\\\"description\\\":\\\"Reads of UiPreferenceRecord. Not decorated: the model has no generated surface, so a decorated collection would only add a second manifest schema for the same table.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/preferences/src/collections/UiPreferenceRecordCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-preferences\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findTier\\\":{\\\"name\\\":\\\"findTier\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"kind\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"surfaceId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scope\\\",\\\"type\\\":\\\"PreferenceScope\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"userId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<UiPreferenceRecord | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_ui_preferences\\\",\\\"api\\\":{\\\"include\\\":[]},\\\"mcp\\\":{\\\"include\\\":[]},\\\"cli\\\":false},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"UiPreferenceRecord\\\",\\\"exportName\\\":\\\"UiPreferenceRecordCollection\\\",\\\"collectionExportName\\\":\\\"UiPreferenceRecordCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_ui_preferences\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_ui_preferences\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"kind\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"surface_id\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"scope_type\\\\\\\" TEXT NOT NULL DEFAULT 'tenant',\\\\n \\\\\\\"user_id\\\\\\\" UUID,\\\\n \\\\\\\"scope_key\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"payload_json\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"format_version\\\\\\\" INTEGER,\\\\n \\\\\\\"updated_by\\\\\\\" UUID\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"kind\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"surface_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"scope_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"tenant\\\"},\\\"user_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"scope_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"payload_json\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"format_version\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"updated_by\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_ui_preferences_tenant_id_kind_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"kind\\\",\\\"surface_id\\\",\\\"scope_type\\\",\\\"scope_key\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_ui_preferences_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"_smrt_ui_preferences_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"_smrt_ui_preferences_user_id_idx\\\",\\\"columns\\\":[\\\"user_id\\\"]},{\\\"name\\\":\\\"_smrt_ui_preferences_updated_by_idx\\\",\\\"columns\\\":[\\\"updated_by\\\"]}],\\\"version\\\":\\\"3f9df5fd\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-preferences\\\"},\\\"@happyvertical/smrt-preferences:UiPreferenceRecord\\\":{\\\"name\\\":\\\"uipreferencerecord\\\",\\\"className\\\":\\\"UiPreferenceRecord\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-preferences:UiPreferenceRecord\\\",\\\"collection\\\":\\\"uipreferencerecords\\\",\\\"description\\\":\\\"One stored user-interface preference (#3727): the canonical payload of a registered preference kind (overview, shell-layout, ...) for one surface at one tier of one tenant.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/preferences/src/models/UiPreferenceRecord.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-preferences\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":true,\\\"autoPopulate\\\":true,\\\"nullable\\\":false,\\\"mode\\\":\\\"required\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"kind\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"surfaceId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"scopeType\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"tenant\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"userId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-users:User\\\",\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"scopeKey\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}},\\\"payloadJson\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}},\\\"formatVersion\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"updatedBy\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-users:User\\\",\\\"_meta\\\":{\\\"nullable\\\":true}}},\\\"methods\\\":{\\\"loadFromId\\\":{\\\"name\\\":\\\"loadFromId\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"loadFromSlug\\\":{\\\"name\\\":\\\"loadFromSlug\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getPayload\\\":{\\\"name\\\":\\\"getPayload\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"unknown\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setPayload\\\":{\\\"name\\\":\\\"setPayload\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"value\\\",\\\"type\\\":\\\"unknown\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"SaveOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"delete\\\":{\\\"name\\\":\\\"delete\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"DeleteOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_ui_preferences\\\",\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"kind\\\",\\\"surface_id\\\",\\\"scope_type\\\",\\\"scope_key\\\"],\\\"api\\\":{\\\"include\\\":[]},\\\"cli\\\":false,\\\"mcp\\\":{\\\"include\\\":[]},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"required\\\"}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"UiPreferenceRecord\\\",\\\"collectionExportName\\\":\\\"UiPreferenceRecordCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"kind\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"surfaceId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"scopeType\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"scopeKey\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"payloadJson\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_ui_preferences\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_ui_preferences\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"kind\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"surface_id\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"scope_type\\\\\\\" TEXT NOT NULL DEFAULT 'tenant',\\\\n \\\\\\\"user_id\\\\\\\" UUID,\\\\n \\\\\\\"scope_key\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"payload_json\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"format_version\\\\\\\" INTEGER,\\\\n \\\\\\\"updated_by\\\\\\\" UUID\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"kind\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"surface_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"scope_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"tenant\\\"},\\\"user_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"scope_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"payload_json\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"format_version\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"updated_by\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_ui_preferences_tenant_id_kind_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"kind\\\",\\\"surface_id\\\",\\\"scope_type\\\",\\\"scope_key\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_ui_preferences_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"_smrt_ui_preferences_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"_smrt_ui_preferences_user_id_idx\\\",\\\"columns\\\":[\\\"user_id\\\"]},{\\\"name\\\":\\\"_smrt_ui_preferences_updated_by_idx\\\",\\\"columns\\\":[\\\"updated_by\\\"]}],\\\"version\\\":\\\"3f9df5fd\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-preferences\\\"}},\\\"moduleType\\\":\\\"smrt\\\",\\\"smrtDependencies\\\":[\\\"@happyvertical/smrt-core\\\",\\\"@happyvertical/smrt-tenancy\\\",\\\"@happyvertical/smrt-users\\\"],\\\"browser\\\":{\\\"status\\\":\\\"server-only\\\",\\\"issues\\\":[\\\"#3617\\\",\\\"#3624\\\",\\\"#3626\\\"],\\\"via\\\":[\\\"@happyvertical/smrt-profiles\\\",\\\"@happyvertical/smrt-tenancy\\\",\\\"@happyvertical/smrt-users\\\"]},\\\"stampsConstructors\\\":true}\"));\n","import {\n type PermissionDefinition,\n registerPermissionDefinitions,\n} from '@happyvertical/smrt-users';\n\n/** Authorizes changing and resetting a tenant's default overview layouts. */\nexport const CUSTOMIZE_OVERVIEW_PERMISSION = 'overviews.customize';\n\n/** Authorizes a principal to keep their own overview layouts. */\nexport const PERSONALIZE_OVERVIEW_PERMISSION = 'overviews.personalize';\n\n/** Authorizes changing and resetting a tenant's default shell layout. */\nexport const CUSTOMIZE_SHELL_PERMISSION = 'shell.customize';\n\n/** Authorizes a principal to keep their own shell layout and settings. */\nexport const PERSONALIZE_SHELL_PERMISSION = 'shell.personalize';\n\nexport const PREFERENCE_PERMISSION_DEFINITIONS: PermissionDefinition[] = [\n {\n slug: CUSTOMIZE_OVERVIEW_PERMISSION,\n category: 'preferences',\n name: 'Customize Overviews',\n description:\n 'Change the default overview layouts everyone in the tenant sees',\n },\n {\n slug: PERSONALIZE_OVERVIEW_PERMISSION,\n category: 'preferences',\n name: 'Personalize Overviews',\n description: 'Keep a personal overview layout on top of the tenant default',\n },\n {\n slug: CUSTOMIZE_SHELL_PERMISSION,\n category: 'preferences',\n name: 'Customize Shell Layout',\n description:\n 'Change the default navigation and panel layout everyone in the tenant sees',\n },\n {\n slug: PERSONALIZE_SHELL_PERMISSION,\n category: 'preferences',\n name: 'Personalize Shell Layout',\n description:\n 'Keep a personal navigation and panel layout on top of the tenant default',\n },\n];\n\nlet registered = false;\n\n/** Register the built-in preference permissions once. */\nexport function ensurePreferencePermissionsRegistered(): void {\n if (registered) {\n return;\n }\n registered = true;\n registerPermissionDefinitions(PREFERENCE_PERMISSION_DEFINITIONS);\n}\n\n/**\n * `collection.action` parts of a permission slug for the users operation\n * guards: the action is the last segment (`fields.policy.manage` is\n * collection `fields.policy`, action `manage`).\n */\nexport function splitPermissionSlug(slug: string): {\n collection: string;\n action: string;\n} {\n const dot = slug.lastIndexOf('.');\n if (dot <= 0 || dot === slug.length - 1) {\n throw new Error(`Preference permission \"${slug}\" is not collection.action`);\n }\n return { collection: slug.slice(0, dot), action: slug.slice(dot + 1) };\n}\n","/**\n * The preference kind registry (#3727).\n *\n * A kind is one family of user-interface preference (`overview`,\n * `shell-layout`, ...). It owns the validation of its payload and names the\n * permission pair for its two tiers. The store refuses a kind that is not\n * registered, so nothing reaches the table that no code can validate.\n */\nimport { splitPermissionSlug } from './permissions.js';\n\n/** The two tiers a stored preference can belong to. */\nexport const PREFERENCE_SCOPES = ['tenant', 'user'] as const;\nexport type PreferenceScope = (typeof PREFERENCE_SCOPES)[number];\n\n/** Kind ids: lowercase kebab, e.g. `shell-layout`. */\nexport const PREFERENCE_KIND_PATTERN = /^[a-z][a-z0-9-]{0,47}$/;\n\n/** Surface ids: a page id, a shell key (`events.home`, `admin`). */\nexport const PREFERENCE_SURFACE_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,95}$/;\n\n/** One dropped or rejected part of a payload, and why. */\nexport interface PreferenceIssue {\n /** Where in the payload (a widget id, a dotted path), or `null`. */\n path: string | null;\n /** Kind-defined code (`malformed`, `future_version`, `invalid_options`, ...). */\n code: string;\n /** Developer-facing detail; not localized. */\n message: string;\n /** The kind's own issue object, for kind-specific callers. */\n detail?: unknown;\n}\n\n/**\n * What a kind's `validate` returns. `canonical` is the payload to store (on\n * save) or use (on load) with every invalid part removed; `null` means \"no\n * preference\" (the tier below applies). `ok` is false whenever something was\n * removed or refused. The store refuses a save that is not `ok` and stores\n * only `canonical`; on load it uses `canonical` and reports `issues`.\n */\nexport interface PreferenceValidation {\n ok: boolean;\n canonical: unknown | null;\n issues: PreferenceIssue[];\n}\n\nexport interface PreferenceValidateContext {\n kind: string;\n surfaceId: string;\n scope: PreferenceScope;\n /** `save` (strict) or `load` (lenient). */\n phase: 'save' | 'load';\n /** The format version the payload was written at (the kind's on save). */\n formatVersion: number;\n /**\n * The tenant tier's canonical payload when validating the user tier\n * (`null` when the tenant has none); absent for the tenant tier.\n */\n tenant?: unknown | null;\n /** Host-supplied, kind-specific inputs (e.g. the overview definition). */\n options?: unknown;\n}\n\nexport interface PreferenceKindDefinition {\n kind: string;\n /** Current payload format version (a positive integer). */\n formatVersion: number;\n /** Slugs that authorize writing each tier (`collection.action`). */\n permissions: { tenant: string; user: string };\n validate(\n payload: unknown,\n ctx: PreferenceValidateContext,\n ): PreferenceValidation;\n}\n\n/** A store call named a kind no code registered. */\nexport class UnknownPreferenceKindError extends Error {\n readonly code = 'unknown_preference_kind';\n readonly status = 400;\n\n constructor(kind: string) {\n super(`Preference kind \"${kind}\" is not registered`);\n this.name = 'UnknownPreferenceKindError';\n }\n}\n\nconst kinds = new Map<string, PreferenceKindDefinition>();\n\n/**\n * Register a preference kind. Registering a kind twice throws unless\n * `{ replace: true }`; returns a disposer that removes this registration.\n */\nexport function registerPreferenceKind(\n definition: PreferenceKindDefinition,\n options: { replace?: boolean } = {},\n): () => void {\n if (!PREFERENCE_KIND_PATTERN.test(definition.kind)) {\n throw new Error(`Invalid preference kind \"${definition.kind}\"`);\n }\n if (\n !Number.isSafeInteger(definition.formatVersion) ||\n definition.formatVersion < 1\n ) {\n throw new Error(\n `Preference kind \"${definition.kind}\" needs a positive formatVersion`,\n );\n }\n splitPermissionSlug(definition.permissions.tenant);\n splitPermissionSlug(definition.permissions.user);\n if (typeof definition.validate !== 'function') {\n throw new Error(`Preference kind \"${definition.kind}\" needs validate()`);\n }\n if (kinds.has(definition.kind) && !options.replace) {\n throw new Error(\n `Preference kind \"${definition.kind}\" is already registered`,\n );\n }\n const frozen = Object.freeze({\n ...definition,\n permissions: Object.freeze({ ...definition.permissions }),\n });\n kinds.set(definition.kind, frozen);\n return () => {\n if (kinds.get(definition.kind) === frozen) kinds.delete(definition.kind);\n };\n}\n\n/** The registered kind, or `undefined`. */\nexport function getPreferenceKind(\n kind: string,\n): PreferenceKindDefinition | undefined {\n return kinds.get(kind);\n}\n\n/** The registered kind; throws {@link UnknownPreferenceKindError} otherwise. */\nexport function requirePreferenceKind(kind: string): PreferenceKindDefinition {\n const definition = kinds.get(kind);\n if (!definition) throw new UnknownPreferenceKindError(kind);\n return definition;\n}\n\n/** Registered kind ids in registration order. */\nexport function listPreferenceKinds(): string[] {\n return [...kinds.keys()];\n}\n","/**\n * The `overview` preference kind: the sparse `OverviewOverride` of a\n * customizable overview page (`@happyvertical/smrt-svelte/overview`).\n *\n * The surface id is the page's `OverviewDefinition.id`. Validation needs the\n * page definition and widget registry, which the caller passes as the kind's\n * `options` (`{ definition, registry }`); the overview layer in\n * `../overview.ts` does that for every call.\n */\nimport {\n checkOverviewOverride,\n diffOverview,\n type OverviewDefinition,\n type OverviewDocument,\n type OverviewIssue,\n resolveOverview,\n type WidgetRegistry,\n} from '@happyvertical/smrt-svelte/overview/server';\nimport type {\n PreferenceIssue,\n PreferenceKindDefinition,\n PreferenceValidation,\n} from '../kinds.js';\nimport {\n CUSTOMIZE_OVERVIEW_PERMISSION,\n PERSONALIZE_OVERVIEW_PERMISSION,\n} from '../permissions.js';\n\nexport const OVERVIEW_PREFERENCE_KIND = 'overview';\n\n/** The validation inputs of the `overview` kind. */\nexport interface OverviewKindOptions {\n definition: OverviewDefinition;\n registry: WidgetRegistry;\n}\n\n/**\n * `definition` with another tier's document as its defaults: the definition a\n * user-tier controller and save are validated against\n * (`withTenantDefaults(definition, state.tenant.document)`).\n */\nexport function withTenantDefaults(\n definition: OverviewDefinition,\n document: OverviewDocument,\n): OverviewDefinition {\n return { ...definition, defaults: document.widgets };\n}\n\nfunction toPreferenceIssue(issue: OverviewIssue): PreferenceIssue {\n return {\n path: issue.widgetId,\n code: issue.code,\n message: issue.message,\n detail: issue,\n };\n}\n\n/** The `OverviewIssue` behind a preference issue (or a generic one). */\nexport function toOverviewIssue(issue: PreferenceIssue): OverviewIssue {\n if (issue.detail && typeof issue.detail === 'object') {\n return issue.detail as OverviewIssue;\n }\n return {\n widgetId: null,\n type: null,\n code: issue.code === 'future_version' ? 'future_version' : 'malformed',\n message: issue.message,\n };\n}\n\nfunction readOptions(options: unknown): OverviewKindOptions | null {\n if (!options || typeof options !== 'object') return null;\n const { definition, registry } = options as Partial<OverviewKindOptions>;\n if (!definition || !registry) return null;\n return { definition, registry };\n}\n\n/**\n * The definition one tier validates against: the page definition for the\n * tenant tier, the tenant-merged one for the user tier.\n */\nexport function overviewTierDefinition(\n { definition, registry }: OverviewKindOptions,\n scope: 'tenant' | 'user',\n tenantOverride: unknown,\n): OverviewDefinition {\n if (scope === 'tenant') return definition;\n const tenant = resolveOverview(definition, tenantOverride ?? null, registry);\n return withTenantDefaults(definition, tenant.document);\n}\n\nexport const overviewPreferenceKind: PreferenceKindDefinition = {\n kind: OVERVIEW_PREFERENCE_KIND,\n formatVersion: 1,\n permissions: {\n tenant: CUSTOMIZE_OVERVIEW_PERMISSION,\n user: PERSONALIZE_OVERVIEW_PERMISSION,\n },\n validate(payload, ctx): PreferenceValidation {\n const options = readOptions(ctx.options);\n if (!options || options.definition.id !== ctx.surfaceId) {\n return {\n ok: false,\n canonical: null,\n issues: [\n {\n path: null,\n code: 'missing_context',\n message:\n 'the overview kind needs { definition, registry } for this surface',\n },\n ],\n };\n }\n const definition = overviewTierDefinition(options, ctx.scope, ctx.tenant);\n if (ctx.phase === 'save') {\n const checked = checkOverviewOverride(\n definition,\n payload,\n options.registry,\n );\n return checked.ok\n ? { ok: true, canonical: checked.override, issues: [] }\n : {\n ok: false,\n canonical: null,\n issues: checked.issues.map(toPreferenceIssue),\n };\n }\n const resolved = resolveOverview(definition, payload, options.registry);\n return {\n ok: resolved.overrideIssues.length === 0,\n canonical: diffOverview(resolved.base, resolved.document),\n issues: resolved.overrideIssues.map(toPreferenceIssue),\n };\n },\n};\n","/**\n * The `shell-layout` preference kind: the sparse `ShellSettingsDelta` the\n * AdminShell settings adapter reads and writes (navigation layout, panel\n * states and sizes, keymap), validated with smrt-svelte's\n * `sanitizeShellSettingsDelta` from the Node-safe `./workspace/server` entry.\n *\n * The surface id names the shell (the app's `storageKey`, e.g. `admin`).\n */\nimport {\n mergeShellSettingsDelta,\n type ShellSettingsDelta,\n type ShellSettingsIssue,\n sanitizeShellSettingsDelta,\n} from '@happyvertical/smrt-svelte/workspace/server';\nimport type {\n PreferenceIssue,\n PreferenceKindDefinition,\n PreferenceScope,\n} from '../kinds.js';\nimport {\n CUSTOMIZE_SHELL_PERMISSION,\n PERSONALIZE_SHELL_PERMISSION,\n} from '../permissions.js';\nimport type {\n PreferenceResetResult,\n PreferenceSaveResult,\n PreferenceStore,\n} from '../store.js';\n\nexport const SHELL_LAYOUT_PREFERENCE_KIND = 'shell-layout';\n\nfunction toPreferenceIssue(issue: ShellSettingsIssue): PreferenceIssue {\n return {\n path: issue.path || null,\n code: 'invalid_setting',\n message: issue.message,\n detail: issue,\n };\n}\n\nexport const shellLayoutPreferenceKind: PreferenceKindDefinition = {\n kind: SHELL_LAYOUT_PREFERENCE_KIND,\n formatVersion: 1,\n permissions: {\n tenant: CUSTOMIZE_SHELL_PERMISSION,\n user: PERSONALIZE_SHELL_PERMISSION,\n },\n validate(payload) {\n const { delta, issues } = sanitizeShellSettingsDelta(payload);\n return {\n ok: issues.length === 0,\n canonical: Object.keys(delta).length > 0 ? delta : null,\n issues: issues.map(toPreferenceIssue),\n };\n },\n};\n\n/** What a shell reads: the merged delta plus each tier for an editor. */\nexport interface ShellSettingsPreferenceRead {\n /** Tenant default merged with the user's delta (`mergeShellSettingsDelta`). */\n delta: ShellSettingsDelta;\n tenant: ShellSettingsDelta | null;\n user: ShellSettingsDelta | null;\n /** Revisions of each tier, for guarded writes. */\n revisions: { tenant: string | null; user: string | null };\n issues: PreferenceIssue[];\n canCustomize: { tenant: boolean; user: boolean };\n}\n\nexport interface ShellSettingsPreferenceWriteOptions {\n /** Default `user`. */\n scope?: PreferenceScope;\n /**\n * The revision the client loaded. Omitted, the current revision is read\n * just before the write: last-writer-wins for that call, which is what the\n * shell's `ShellSettingsAdapter.write(delta)` (no revision) gets.\n */\n revision?: string | null;\n}\n\n/**\n * The server half of a shell `ShellSettingsAdapter`. A host exposes `read`\n * and `write` as remote functions and the browser adapter calls them:\n *\n * ```ts\n * const adapter: ShellSettingsAdapter = {\n * read: async () => (await readShellSettings('admin')).delta,\n * write: (delta) => writeShellSettings('admin', delta),\n * };\n * ```\n */\nexport interface ShellSettingsPreferences {\n read(surfaceId: string): Promise<ShellSettingsPreferenceRead>;\n write(\n surfaceId: string,\n delta: unknown,\n options?: ShellSettingsPreferenceWriteOptions,\n ): Promise<PreferenceSaveResult>;\n reset(\n surfaceId: string,\n options?: ShellSettingsPreferenceWriteOptions,\n ): Promise<PreferenceResetResult>;\n}\n\nfunction compact(delta: ShellSettingsDelta): ShellSettingsDelta {\n return Object.fromEntries(\n Object.entries(delta).filter(([, value]) => value !== undefined),\n ) as ShellSettingsDelta;\n}\n\n/** Shell settings persistence over the generic preference store. */\nexport function createShellSettingsPreferences(\n store: PreferenceStore,\n): ShellSettingsPreferences {\n return {\n async read(surfaceId) {\n const state = await store.load(SHELL_LAYOUT_PREFERENCE_KIND, surfaceId);\n const tenant =\n (state.tenant.payload as ShellSettingsDelta | null) ?? null;\n const user = (state.user?.payload as ShellSettingsDelta | null) ?? null;\n return {\n delta: compact(mergeShellSettingsDelta(tenant ?? {}, user ?? {})),\n tenant,\n user,\n revisions: {\n tenant: state.tenant.revision,\n user: state.user?.revision ?? null,\n },\n issues: state.issues,\n canCustomize: state.canCustomize,\n };\n },\n\n async write(surfaceId, delta, options = {}) {\n const scope = options.scope ?? 'user';\n let revision = options.revision;\n if (revision === undefined) {\n const state = await store.load(SHELL_LAYOUT_PREFERENCE_KIND, surfaceId);\n revision =\n scope === 'tenant'\n ? state.tenant.revision\n : (state.user?.revision ?? null);\n }\n return store.save(SHELL_LAYOUT_PREFERENCE_KIND, surfaceId, {\n scope,\n payload: delta,\n revision,\n });\n },\n\n reset(surfaceId, options = {}) {\n return store.reset(SHELL_LAYOUT_PREFERENCE_KIND, surfaceId, {\n scope: options.scope ?? 'user',\n revision: options.revision,\n });\n },\n };\n}\n","/**\n * Registers the built-in preference kinds (`overview`, `shell-layout`) once.\n * Imported by the package entry and the store, so the model never meets a\n * built-in kind it does not know.\n */\nimport { getPreferenceKind, registerPreferenceKind } from '../kinds.js';\nimport { overviewPreferenceKind } from './overview.js';\nimport { shellLayoutPreferenceKind } from './shell-layout.js';\n\nexport function ensureBuiltinPreferenceKinds(): void {\n for (const kind of [overviewPreferenceKind, shellLayoutPreferenceKind]) {\n if (!getPreferenceKind(kind.kind)) registerPreferenceKind(kind);\n }\n}\n\nensureBuiltinPreferenceKinds();\n","/**\n * The request principal a preference read or write acts as.\n *\n * Identity always comes from the ambient context, never from a request body:\n * the tenancy ALS (`withTenant`, the SvelteKit/Express adapters) first, and\n * the authenticated users session-permission ALS (`createSessionHandler()`\n * without `enterTenantContext`) as the fallback, the smrt-fields precedent.\n */\nimport {\n getCurrentTenant,\n isSuperAdminBypass,\n TenantIsolationError,\n withTenant,\n} from '@happyvertical/smrt-tenancy';\nimport { getCurrentSessionPermissionContext } from '@happyvertical/smrt-users';\n\nexport interface PreferencePrincipal {\n tenantId: string;\n /** Absent for service principals, API keys and background jobs. */\n userId?: string;\n permissions: ReadonlySet<string>;\n superAdminBypass: boolean;\n /** True when the tenancy ALS already carries this principal. */\n fromTenancy: boolean;\n}\n\n/** The preference principal of the current async context, if any. */\nexport function getPreferencePrincipal(): PreferencePrincipal | undefined {\n const tenant = getCurrentTenant();\n if (tenant?.tenantId) {\n return {\n tenantId: tenant.tenantId,\n userId: tenant.userId,\n permissions: tenant.permissions,\n superAdminBypass: isSuperAdminBypass(),\n fromTenancy: true,\n };\n }\n const session = getCurrentSessionPermissionContext();\n if (!session?.tenantId) return undefined;\n return {\n tenantId: session.tenantId,\n userId: session.userId ?? undefined,\n permissions: session.permissionSet,\n superAdminBypass: session.superAdminBypass,\n fromTenancy: false,\n };\n}\n\n/** Bounded, identifier-free denial; generated transports serialize it as 403. */\nexport class PreferenceAccessError extends TenantIsolationError {\n readonly status = 403;\n readonly publicMessage: string;\n\n constructor(message: string) {\n super(message);\n this.name = 'PreferenceAccessError';\n this.publicMessage = message;\n }\n}\n\n/** The principal, or a fail-closed error when there is no tenant identity. */\nexport function requirePreferencePrincipal(): PreferencePrincipal {\n const principal = getPreferencePrincipal();\n if (!principal) {\n throw new PreferenceAccessError(\n 'User-interface preferences need an authenticated tenant context',\n );\n }\n return principal;\n}\n\n/**\n * Run `fn` with the tenancy ALS carrying `principal`. A session-only\n * principal is entered as a tenant context with the same tenant, user and\n * permissions, so the tenancy interceptor scopes the table exactly as it would\n * under the tenancy adapter. Nothing is widened.\n */\nexport async function withPrincipal<T>(\n principal: PreferencePrincipal,\n fn: () => Promise<T>,\n): Promise<T> {\n if (principal.fromTenancy) return fn();\n return withTenant(\n {\n tenantId: principal.tenantId,\n userId: principal.userId,\n permissions: new Set(principal.permissions),\n },\n fn,\n );\n}\n","/**\n * Owner-safe reads of `UiPreferenceRecord` (#3727).\n *\n * A principal must never read another user's preferences, through the\n * store or any other in-process path to the model. Tenancy already confines\n * every read to the principal's tenant; this interceptor adds the owner\n * rule to the READ PREDICATE before any SQL runs, so `list`, `get`, `count`,\n * `facets`, semantic search and every other path that runs `beforeList` /\n * `beforeGet` inherit it: only rows whose `scope_key` is `'__tenant__'` (the\n * tenant default) or the principal's own user id; with no user id, tenant\n * rows only. `scope_key` is the column the model keeps in lockstep with\n * `scope_type` / `user_id` (a user row's key is its user id). A caller's own\n * `scopeKey in` condition is intersected, never replaced. Raw `query()` SQL\n * cannot carry the predicate and is refused. The after-read hooks re-check\n * every hydrated row as defence in depth (a row whose scope cannot be told\n * is dropped), and single-row hydration is also checked by the model.\n *\n * @internal\n */\nimport {\n GlobalInterceptors,\n resolveGetStringFilter,\n type SmrtObject,\n} from '@happyvertical/smrt-core';\nimport { getPreferencePrincipal, PreferenceAccessError } from './context.js';\n\nconst GUARD_NAME = 'smrt-preferences:owner-reads';\nconst CLASS_NAME = 'UiPreferenceRecord';\nconst QUALIFIED_NAME = '@happyvertical/smrt-preferences:UiPreferenceRecord';\n\nfunction field(row: unknown, camel: string, snake: string): unknown {\n if (!row || typeof row !== 'object') return undefined;\n const record = row as Record<string, unknown>;\n return record[camel] !== undefined ? record[camel] : record[snake];\n}\n\n/** Whether the ambient principal may see `row`. */\nexport function isPreferenceRowVisible(row: unknown): boolean {\n const scope = field(row, 'scopeType', 'scope_type');\n if (scope === 'tenant') return true;\n if (scope !== 'user') return false;\n const owner = field(row, 'userId', 'user_id');\n const userId = getPreferencePrincipal()?.userId;\n return Boolean(userId) && typeof owner === 'string' && owner === userId;\n}\n\nfunction isPreferenceClass(\n className: string,\n qualifiedClassName?: string,\n): boolean {\n return qualifiedClassName === QUALIFIED_NAME || className === CLASS_NAME;\n}\n\nconst TENANT_KEY = '__tenant__';\n/** No row has an empty scope key (`scopeKey` is required and synced). */\nconst NO_ROW_KEY = '';\nconst SCOPE_KEY_IN = ['scopeKey in', 'scope_key in'] as const;\n\n/** The scope keys the ambient principal may read. */\nfunction visibleScopeKeys(): string[] {\n const userId = getPreferencePrincipal()?.userId;\n return userId ? [TENANT_KEY, userId] : [TENANT_KEY];\n}\n\n/**\n * `where` AND the owner predicate. A caller's `scopeKey in` list is\n * intersected with the visible keys (an empty intersection matches no row).\n */\nfunction withOwnerPredicate(\n where: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n const visible = visibleScopeKeys();\n const next: Record<string, unknown> = { ...(where ?? {}) };\n let keys = visible;\n for (const key of SCOPE_KEY_IN) {\n if (!(key in next)) continue;\n const requested = next[key];\n delete next[key];\n const list = Array.isArray(requested) ? requested : [requested];\n keys = keys.filter((value) => list.includes(value));\n }\n next['scopeKey in'] = keys.length > 0 ? keys : [NO_ROW_KEY];\n return next;\n}\n\nfunction filterRows<T>(\n className: string,\n rows: T[],\n qualifiedClassName?: string,\n): T[] | undefined {\n if (!isPreferenceClass(className, qualifiedClassName)) return undefined;\n return rows.filter(isPreferenceRowVisible);\n}\n\n/**\n * Register the owner-read interceptor (idempotent). Called when the model\n * module loads and again before every store read, so a cleared interceptor\n * registry (tests, `GlobalInterceptors.clear()`) cannot silently drop it.\n */\nexport function ensurePreferenceReadGuard(): void {\n if (GlobalInterceptors.getAll().some((entry) => entry.name === GUARD_NAME)) {\n return;\n }\n GlobalInterceptors.register({\n name: GUARD_NAME,\n // After tenancy (priority 100) has scoped the read to the tenant.\n priority: 90,\n beforeList(className, options, context) {\n if (!isPreferenceClass(className, context.qualifiedClassName)) return;\n const where = options.where as unknown;\n if (Array.isArray(where)) {\n // DNF: every OR branch carries the owner predicate.\n return {\n ...options,\n where: where.map((group: Record<string, unknown>[]) => [\n ...group,\n withOwnerPredicate({}),\n ]),\n } as typeof options;\n }\n return {\n ...options,\n where: withOwnerPredicate(where as Record<string, unknown>),\n };\n },\n beforeGet(className, filter, context) {\n if (!isPreferenceClass(className, context.qualifiedClassName)) return;\n const resolved =\n typeof filter === 'string' ? resolveGetStringFilter(filter) : filter;\n return withOwnerPredicate(resolved);\n },\n beforeQuery(className, _options, context) {\n if (!isPreferenceClass(className, context.qualifiedClassName)) return;\n // Raw SQL cannot carry the owner predicate: refuse it.\n throw new PreferenceAccessError(\n 'Raw queries over user-interface preferences are not allowed',\n );\n },\n afterList<T extends SmrtObject>(\n className: string,\n results: T[],\n context: { qualifiedClassName?: string },\n ) {\n return filterRows(className, results, context.qualifiedClassName);\n },\n afterQuery<T extends SmrtObject>(\n className: string,\n results: T[],\n context: { qualifiedClassName?: string },\n ) {\n return filterRows(className, results, context.qualifiedClassName);\n },\n afterGet<T extends SmrtObject>(\n className: string,\n instance: T | null,\n context: { qualifiedClassName?: string },\n ) {\n if (\n !instance ||\n !isPreferenceClass(className, context.qualifiedClassName)\n ) {\n return undefined;\n }\n return isPreferenceRowVisible(instance) ? instance : null;\n },\n });\n}\n","/**\n * Store-only write capability for `UiPreferenceRecord` (#3727).\n *\n * A preference payload is only meaningful after its kind validated it, and\n * only the store runs the validator. So the model refuses every insert,\n * update and delete that the store did not grant: an insert carries\n * {@link STORE_WRITE} as a constructor option (a symbol key never arrives\n * from JSON), and an update or delete is granted per instance just before\n * the store calls `save()` / `delete()`. A write grant is bound to the exact\n * `payloadJson` the store validated, and every grant is single-use.\n *\n * Not part of the package's public exports (the smrt-approvals\n * `write-capability.ts` pattern). This guards in-process callers of the\n * model and collection; it is not a defence against raw SQL.\n *\n * @internal\n * @packageDocumentation\n */\n\n/** Constructor-option key carrying the capability. Never exported publicly. */\nexport const STORE_WRITE = Symbol('smrt-preferences.storeWrite');\n\n/** The only value accepted under {@link STORE_WRITE}. */\nconst TOKEN = Object.freeze({ capability: 'smrt-preferences.storeWrite' });\n\n/** Granted writes: the payload the store validated for each instance. */\nconst writes = new WeakMap<object, string>();\n\n/** Granted deletes. */\nconst deletes = new WeakSet<object>();\n\n/** Constructor options fragment that grants an insert of `payloadJson`. */\nexport function storeWriteOption(): { [STORE_WRITE]: object } {\n return { [STORE_WRITE]: TOKEN };\n}\n\n/** Record an insert grant when the constructor options carry the token. */\nexport function adoptStoreWrite(instance: object, options: unknown): void {\n if (\n options &&\n typeof options === 'object' &&\n (options as Record<symbol, unknown>)[STORE_WRITE] === TOKEN &&\n typeof (options as { payloadJson?: unknown }).payloadJson === 'string'\n ) {\n writes.set(instance, (options as { payloadJson: string }).payloadJson);\n }\n}\n\n/** Grant one save of `instance` with its current, validated payload. */\nexport function grantStoreWrite(instance: { payloadJson: string }): void {\n writes.set(instance, instance.payloadJson);\n}\n\n/** Grant one delete of `instance`. */\nexport function grantStoreDelete(instance: object): void {\n deletes.add(instance);\n}\n\n/** Whether a save of `instance` with `payloadJson` was granted. */\nexport function hasStoreWrite(instance: object, payloadJson: string): boolean {\n return writes.get(instance) === payloadJson;\n}\n\n/** Spend the save grant of `instance`. */\nexport function spendStoreWrite(instance: object): void {\n writes.delete(instance);\n}\n\n/** Spend the delete grant of `instance`; false when there was none. */\nexport function takeStoreDelete(instance: object): boolean {\n return deletes.delete(instance);\n}\n","import {\n crossPackageRef,\n field,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { assertOperationPermission } from '@happyvertical/smrt-users';\nimport {\n PreferenceAccessError,\n requirePreferencePrincipal,\n} from '../context.js';\nimport {\n PREFERENCE_KIND_PATTERN,\n PREFERENCE_SCOPES,\n PREFERENCE_SURFACE_PATTERN,\n type PreferenceScope,\n requirePreferenceKind,\n} from '../kinds.js';\nimport {\n ensurePreferencePermissionsRegistered,\n splitPermissionSlug,\n} from '../permissions.js';\nimport {\n ensurePreferenceReadGuard,\n isPreferenceRowVisible,\n} from '../read-guard.js';\nimport {\n adoptStoreWrite,\n hasStoreWrite,\n spendStoreWrite,\n takeStoreDelete,\n} from '../write-capability.js';\n\n// Direct model imports (tests, server integrations) must still find the\n// built-in slugs in the shared users catalog before any guard asks for them.\nensurePreferencePermissionsRegistered();\n// Collection, query and get reads drop other users' rows (see read-guard.ts).\nensurePreferenceReadGuard();\n\ntype ConstructorOptions = ConstructorParameters<typeof SmrtObject>[0];\ntype SaveOptions = NonNullable<Parameters<SmrtObject['save']>[0]>;\ntype DeleteOptions = NonNullable<Parameters<SmrtObject['delete']>[0]>;\n\n/** `scopeKey` of a tenant-default row (user rows use the user id). */\nexport const TENANT_SCOPE_KEY = '__tenant__';\n\n/**\n * One stored user-interface preference (#3727): the canonical payload of a\n * registered preference kind (`overview`, `shell-layout`, ...) for one surface\n * at one tier of one tenant.\n *\n * - `scopeType: 'tenant'` is the tenant default (`userId` null), written with\n * the kind's tenant permission.\n * - `scopeType: 'user'` is one person's preference on top of the tenant\n * default, inside that tenant. Only that user may write it, with the kind's\n * user permission.\n *\n * Every row carries its tenant, so the table is `@TenantScoped` (required):\n * the tenancy interceptor filters reads and refuses foreign rows, and the\n * save/delete guards below re-check identity, tier ownership and the kind's\n * permission. The kind's validator (run by the store) owns the payload's\n * content; this model owns identity, scope shape and authorization, and\n * refuses any kind that is not registered.\n *\n * No generated surface: a payload is only meaningful after its kind's\n * validation, which a generated route would skip.\n */\n@TenantScoped({ mode: 'required' })\n@smrt({\n tableName: '_smrt_ui_preferences',\n conflictColumns: [\n 'tenant_id',\n 'kind',\n 'surface_id',\n 'scope_type',\n 'scope_key',\n ],\n api: { include: [] },\n cli: false,\n mcp: { include: [] },\n})\nexport class UiPreferenceRecord extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-preferences\";\n /** Owning tenant (native UUID on PostgreSQL/DuckDB). */\n @tenantId()\n tenantId: string = '';\n\n /** The registered preference kind (`overview`, `shell-layout`, ...). */\n @field({ required: true })\n kind: string = '';\n\n /** The surface within the kind (an overview id, a shell key). */\n @field({ required: true })\n surfaceId: string = '';\n\n /** `tenant` (the tenant default) or `user` (one person's preference). */\n @field({ required: true })\n scopeType: PreferenceScope = 'tenant';\n\n /** The owning user of a user-scope row; NULL on the tenant default. */\n @crossPackageRef('@happyvertical/smrt-users:User', { nullable: true })\n userId: string | null = null;\n\n /**\n * `userId ?? '__tenant__'`, set on save. Keeps the `conflictColumns`\n * unique index total while `userId` is nullable (NULLs are distinct in a\n * unique index). Kept in lockstep with\n * `scopeType` / `userId` on every write, so the owner read predicate\n * (`read-guard.ts`) can filter on it in one condition.\n */\n @field({ type: 'text', required: true })\n scopeKey: string = '';\n\n /** The kind's canonical payload as JSON text. */\n @field({ type: 'text', required: true })\n payloadJson: string = '';\n\n /** The kind's format version the payload was written at. */\n @field({ type: 'integer' })\n formatVersion: number = 1;\n\n /** Who last wrote the row; stamped from the ambient principal. */\n @crossPackageRef('@happyvertical/smrt-users:User', { nullable: true })\n updatedBy: string | null = null;\n\n constructor(options: ConstructorOptions = {}) {\n super(options);\n adoptStoreWrite(this, options);\n }\n\n /**\n * Single-row hydration (`new UiPreferenceRecord({ id }).initialize()`)\n * reads the table directly, outside the collection interceptors, so the\n * owner check runs here: another user's row is wiped and refused.\n */\n override async loadFromId(): Promise<void> {\n await super.loadFromId();\n this.assertReadable();\n }\n\n override async loadFromSlug(): Promise<void> {\n await super.loadFromSlug();\n this.assertReadable();\n }\n\n private assertReadable(): void {\n if (!this.kind || isPreferenceRowVisible(this)) return;\n this.payloadJson = '';\n throw new PreferenceAccessError(\n 'A personal preference can only be read by its owner',\n );\n }\n\n /** The stored payload, parsed. `undefined` when the text is not JSON. */\n getPayload(): unknown {\n try {\n return JSON.parse(this.payloadJson);\n } catch {\n return undefined;\n }\n }\n\n /** Store a payload; the caller passes the kind's canonical value. */\n setPayload(value: unknown): void {\n this.payloadJson = JSON.stringify(value);\n }\n\n /** The optimistic-concurrency token a client echoes back on save. */\n get revision(): string | null {\n const at = this.updated_at;\n if (!at) return null;\n const date = at instanceof Date ? at : new Date(at as string);\n return Number.isNaN(date.getTime()) ? null : date.toISOString();\n }\n\n override async save(options: SaveOptions = {}): Promise<this> {\n const principal = requirePreferencePrincipal();\n if (!this.tenantId) this.tenantId = principal.tenantId;\n this.syncScopeKey();\n await this.assertPersistedIdentityUnchanged();\n this.assertStoreWrite();\n this.validateShape();\n await this.authorize();\n this.updatedBy = principal.userId ?? null;\n try {\n return await super.save(options);\n } finally {\n spendStoreWrite(this);\n }\n }\n\n /**\n * Runs for ordinary saves and bulk creates alike, so a collection-level\n * bulk insert is refused too (`save()` checks first so callers see it).\n */\n protected override async validateBeforeSave(): Promise<void> {\n await super.validateBeforeSave();\n this.assertStoreWrite();\n }\n\n override async delete(options: DeleteOptions = {}): Promise<void> {\n if (!takeStoreDelete(this)) {\n throw new PreferenceAccessError(\n 'Preferences are reset only through the preference store',\n );\n }\n // Recomputed from the in-memory owner, so a row whose userId was edited\n // before delete() no longer matches its stored identity and is refused.\n this.syncScopeKey();\n await this.assertPersistedIdentityUnchanged();\n await this.authorize();\n return super.delete(options);\n }\n\n /**\n * Only the store, after the kind's validator accepted exactly this\n * payload, may write a row (see `write-capability.ts`).\n */\n private assertStoreWrite(): void {\n if (!hasStoreWrite(this, this.payloadJson)) {\n throw new PreferenceAccessError(\n 'Preferences are written only through the preference store, which validates them',\n );\n }\n }\n\n private syncScopeKey(): void {\n if (this.scopeType === 'tenant' && this.userId === null) {\n this.scopeKey = TENANT_SCOPE_KEY;\n } else if (this.scopeType === 'user' && this.userId) {\n this.scopeKey = this.userId;\n }\n }\n\n private validateShape(): void {\n if (!PREFERENCE_KIND_PATTERN.test(this.kind)) {\n throw new Error('UiPreferenceRecord.kind is not a valid kind id');\n }\n if (!PREFERENCE_SURFACE_PATTERN.test(this.surfaceId)) {\n throw new Error('UiPreferenceRecord.surfaceId is not a valid id');\n }\n if (!PREFERENCE_SCOPES.includes(this.scopeType)) {\n throw new Error('UiPreferenceRecord.scopeType must be tenant or user');\n }\n if (this.scopeType === 'tenant' && this.userId !== null) {\n throw new Error('A tenant-default preference row has no userId');\n }\n if (this.scopeType === 'user' && !this.userId) {\n throw new Error('A user preference row needs its userId');\n }\n if (!Number.isSafeInteger(this.formatVersion) || this.formatVersion < 1) {\n throw new Error('UiPreferenceRecord.formatVersion must be positive');\n }\n if (this.getPayload() === undefined) {\n throw new Error('UiPreferenceRecord.payloadJson must be JSON');\n }\n }\n\n /**\n * Fail-closed tier guard. The tenant must be the principal's (the\n * interceptor checks this too; a super-admin bypass does not filter reads,\n * so it is re-checked here), a user row must belong to the principal (a\n * principal with no user id may not touch the user tier), the kind must be\n * registered, and its permission for the tier must be held.\n */\n private async authorize(): Promise<void> {\n const principal = requirePreferencePrincipal();\n const kind = requirePreferenceKind(this.kind);\n if (this.tenantId !== principal.tenantId) {\n throw new PreferenceAccessError(\n 'This preference belongs to another tenant',\n );\n }\n if (this.scopeType === 'user') {\n if (!principal.userId || this.userId !== principal.userId) {\n throw new PreferenceAccessError(\n 'A personal preference can only be changed by its owner',\n );\n }\n }\n const slug =\n this.scopeType === 'user'\n ? kind.permissions.user\n : kind.permissions.tenant;\n await assertOperationPermission({\n ...splitPermissionSlug(slug),\n db: this.options.db ?? this.options.persistence,\n tenantId: principal.tenantId,\n userId: principal.userId ?? null,\n permissionSet: principal.permissions,\n });\n }\n\n /**\n * A persisted row keeps its identity: the stored tenant, kind, surface and\n * tier must be the ones in memory, so {@link authorize} always judges the\n * row as stored. Matched by predicate rather than by reading the columns\n * back, because DuckDB returns raw UUID columns as lossy HUGEINTs.\n */\n private async assertPersistedIdentityUnchanged(): Promise<void> {\n if (!this.id) return;\n const byId = await this.db.get(this.tableName, { id: this.id });\n if (!byId) return;\n const same = await this.db.get(this.tableName, {\n id: this.id,\n tenant_id: this.tenantId,\n kind: this.kind,\n surface_id: this.surfaceId,\n scope_type: this.scopeType,\n scope_key: this.scopeKey,\n });\n if (!same) {\n throw new PreferenceAccessError(\n 'A preference row cannot change its tenant, kind, surface or owner',\n );\n }\n }\n}\n","import { SmrtCollection } from '@happyvertical/smrt-core';\nimport type { PreferenceScope } from '../kinds.js';\nimport {\n TENANT_SCOPE_KEY,\n UiPreferenceRecord,\n} from '../models/UiPreferenceRecord.js';\n\n/**\n * Reads of {@link UiPreferenceRecord}. Not decorated: the model has no\n * generated surface, so a decorated collection would only add a second\n * manifest schema for the same table.\n */\nexport class UiPreferenceRecordCollection extends SmrtCollection<UiPreferenceRecord> {\n static readonly _itemClass = UiPreferenceRecord;\n\n /**\n * The row of one tier, or `null`. The tenant predicate is explicit (not\n * only the interceptor's) because a super-admin bypass context does not\n * filter reads.\n */\n async findTier(\n tenantId: string,\n kind: string,\n surfaceId: string,\n scope: PreferenceScope,\n userId?: string,\n ): Promise<UiPreferenceRecord | null> {\n const scopeKey = scope === 'tenant' ? TENANT_SCOPE_KEY : userId;\n if (!scopeKey) return null;\n const rows = await this.list({\n where: { tenantId, kind, surfaceId, scopeType: scope, scopeKey },\n limit: 1,\n });\n return rows[0] ?? null;\n }\n}\n","/**\n * The generic user-interface preference store (#3727).\n *\n * Two tiers per `(kind, surfaceId)`: the tenant default and the principal's\n * own preference. Every call names a registered kind; the kind validates the\n * payload strictly on save (only its canonical form is stored) and leniently\n * on load (invalid parts are dropped and reported, the row is never\n * rewritten), and names the permission for each tier. Identity always comes\n * from the ambient principal.\n */\nimport { RuntimeError } from '@happyvertical/smrt-core';\nimport './kinds/builtin.js';\nimport { checkOperationPermission } from '@happyvertical/smrt-users';\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport { UiPreferenceRecordCollection } from './collections/UiPreferenceRecordCollection.js';\nimport {\n type PreferencePrincipal,\n requirePreferencePrincipal,\n withPrincipal,\n} from './context.js';\nimport {\n PREFERENCE_SURFACE_PATTERN,\n type PreferenceIssue,\n type PreferenceKindDefinition,\n type PreferenceScope,\n requirePreferenceKind,\n} from './kinds.js';\nimport type { UiPreferenceRecord } from './models/UiPreferenceRecord.js';\nimport { splitPermissionSlug } from './permissions.js';\nimport { ensurePreferenceReadGuard } from './read-guard.js';\nimport {\n grantStoreDelete,\n grantStoreWrite,\n storeWriteOption,\n} from './write-capability.js';\n\n/** One stored tier, validated for use. */\nexport interface PreferenceTier {\n /** The kind's canonical payload, invalid parts removed; `null` = none. */\n payload: unknown | null;\n /** Concurrency token: echo it back on save or reset; `null` = no row. */\n revision: string | null;\n /** What was dropped from the stored payload on load, and why. */\n issues: PreferenceIssue[];\n}\n\nexport interface PreferenceState {\n kind: string;\n surfaceId: string;\n /** The tenant default. */\n tenant: PreferenceTier;\n /** The principal's own preference; `null` without a user. */\n user: PreferenceTier | null;\n /** Every tier's issues, tenant first. */\n issues: PreferenceIssue[];\n /** Whether the principal may write each tier (the kind's permission pair). */\n canCustomize: { tenant: boolean; user: boolean };\n}\n\nexport type PreferenceWriteFailure =\n | { ok: false; reason: 'not_allowed' }\n | { ok: false; reason: 'conflict' }\n | { ok: false; reason: 'invalid'; issues: PreferenceIssue[] };\n\nexport type PreferenceSaveResult =\n | { ok: true; payload: unknown | null; revision: string | null }\n | PreferenceWriteFailure;\n\nexport type PreferenceResetResult = { ok: true } | PreferenceWriteFailure;\n\nexport interface PreferenceLoadInput {\n /** Kind-specific validation inputs (passed to `validate` as `options`). */\n options?: unknown;\n}\n\nexport interface PreferenceSaveInput extends PreferenceLoadInput {\n scope: PreferenceScope;\n /** The client's payload (untrusted). `null` resets the tier. */\n payload: unknown;\n /**\n * The `revision` the client loaded for this tier (`null` when it loaded no\n * row). A stale revision fails with `conflict`, never overwrites.\n */\n revision: string | null;\n}\n\nexport interface PreferenceResetInput {\n scope: PreferenceScope;\n /**\n * The revision the client loaded: a string guards the delete, `null`\n * (\"I loaded no row\") conflicts when a row exists, and omitting it resets\n * regardless.\n */\n revision?: string | null;\n}\n\nexport interface PreferenceStoreOptions {\n db: DatabaseInterface;\n}\n\nexport interface PreferenceStore {\n /** Read and validate both tiers of `(kind, surfaceId)` for the principal. */\n load(\n kind: string,\n surfaceId: string,\n input?: PreferenceLoadInput,\n ): Promise<PreferenceState>;\n /** Validate and store one tier's payload (canonical form only). */\n save(\n kind: string,\n surfaceId: string,\n input: PreferenceSaveInput,\n ): Promise<PreferenceSaveResult>;\n /** Delete one tier's row, returning that tier to the tier below. */\n reset(\n kind: string,\n surfaceId: string,\n input: PreferenceResetInput,\n ): Promise<PreferenceResetResult>;\n}\n\nfunction isRevisionConflict(error: unknown): boolean {\n return (\n error instanceof RuntimeError && error.code === 'RUNTIME_REVISION_CONFLICT'\n );\n}\n\nfunction assertSurfaceId(surfaceId: string): void {\n if (!PREFERENCE_SURFACE_PATTERN.test(surfaceId)) {\n throw new Error(`Invalid preference surface id \"${surfaceId}\"`);\n }\n}\n\nasync function holds(\n principal: PreferencePrincipal,\n slug: string,\n db: DatabaseInterface,\n): Promise<boolean> {\n const decision = await checkOperationPermission({\n ...splitPermissionSlug(slug),\n db,\n tenantId: principal.tenantId,\n userId: principal.userId ?? null,\n permissionSet: principal.permissions,\n onDeny: 'return',\n });\n return decision.allowed;\n}\n\nasync function canWrite(\n principal: PreferencePrincipal,\n kind: PreferenceKindDefinition,\n scope: PreferenceScope,\n db: DatabaseInterface,\n): Promise<boolean> {\n if (scope === 'user') {\n return (\n Boolean(principal.userId) &&\n (await holds(principal, kind.permissions.user, db))\n );\n }\n return holds(principal, kind.permissions.tenant, db);\n}\n\n/** Validate one stored row for use (lenient). */\nfunction readTier(\n kind: PreferenceKindDefinition,\n surfaceId: string,\n scope: PreferenceScope,\n row: UiPreferenceRecord | null,\n options: unknown,\n tenant?: unknown | null,\n): PreferenceTier {\n if (!row) {\n return { payload: null, revision: null, issues: [] };\n }\n const revision = row.revision;\n const payload = row.getPayload();\n if (payload === undefined) {\n return {\n payload: null,\n revision,\n issues: [\n {\n path: null,\n code: 'malformed',\n message: 'stored payload is not JSON',\n },\n ],\n };\n }\n if (row.formatVersion > kind.formatVersion) {\n return {\n payload: null,\n revision,\n issues: [\n {\n path: null,\n code: 'future_version',\n message: 'stored payload was written by a newer format version',\n },\n ],\n };\n }\n let checked: ReturnType<PreferenceKindDefinition['validate']>;\n try {\n checked = kind.validate(payload, {\n kind: kind.kind,\n surfaceId,\n scope,\n phase: 'load',\n formatVersion: row.formatVersion,\n ...(scope === 'user' ? { tenant: tenant ?? null } : {}),\n options,\n });\n } catch {\n // A load must degrade, never fail the page or hand back a payload no\n // validator accepted: the tier is dropped and reported. (A save lets the\n // error propagate: nothing is stored.)\n return {\n payload: null,\n revision,\n issues: [\n {\n path: null,\n code: 'validator_error',\n message: 'the preference kind failed to validate the stored payload',\n },\n ],\n };\n }\n return { payload: checked.canonical, revision, issues: checked.issues };\n}\n\n/**\n * The generic preference store. One per database; every call acts as the\n * ambient principal and names a registered kind.\n */\nexport function createPreferenceStore(\n options: PreferenceStoreOptions,\n): PreferenceStore {\n const { db } = options;\n const collection = (): Promise<UiPreferenceRecordCollection> => {\n ensurePreferenceReadGuard();\n return UiPreferenceRecordCollection.create({ db });\n };\n\n async function tenantTier(\n records: UiPreferenceRecordCollection,\n principal: PreferencePrincipal,\n kind: PreferenceKindDefinition,\n surfaceId: string,\n kindOptions: unknown,\n ): Promise<PreferenceTier> {\n const row = await records.findTier(\n principal.tenantId,\n kind.kind,\n surfaceId,\n 'tenant',\n );\n return readTier(kind, surfaceId, 'tenant', row, kindOptions);\n }\n\n return {\n async load(kindId, surfaceId, input = {}) {\n const kind = requirePreferenceKind(kindId);\n assertSurfaceId(surfaceId);\n const principal = requirePreferencePrincipal();\n return withPrincipal(principal, async () => {\n const records = await collection();\n const tenant = await tenantTier(\n records,\n principal,\n kind,\n surfaceId,\n input.options,\n );\n const userRow = principal.userId\n ? await records.findTier(\n principal.tenantId,\n kind.kind,\n surfaceId,\n 'user',\n principal.userId,\n )\n : null;\n const user = principal.userId\n ? readTier(\n kind,\n surfaceId,\n 'user',\n userRow,\n input.options,\n tenant.payload,\n )\n : null;\n const [tenantWrite, userWrite] = await Promise.all([\n canWrite(principal, kind, 'tenant', db),\n canWrite(principal, kind, 'user', db),\n ]);\n return {\n kind: kind.kind,\n surfaceId,\n tenant,\n user,\n issues: [...tenant.issues, ...(user?.issues ?? [])],\n canCustomize: { tenant: tenantWrite, user: userWrite },\n };\n });\n },\n\n async save(kindId, surfaceId, input) {\n const kind = requirePreferenceKind(kindId);\n assertSurfaceId(surfaceId);\n const principal = requirePreferencePrincipal();\n return withPrincipal(principal, async () => {\n if (!(await canWrite(principal, kind, input.scope, db))) {\n return { ok: false, reason: 'not_allowed' };\n }\n const records = await collection();\n const tenant =\n input.scope === 'user'\n ? (\n await tenantTier(\n records,\n principal,\n kind,\n surfaceId,\n input.options,\n )\n ).payload\n : undefined;\n const checked = kind.validate(input.payload, {\n kind: kind.kind,\n surfaceId,\n scope: input.scope,\n phase: 'save',\n formatVersion: kind.formatVersion,\n ...(input.scope === 'user' ? { tenant: tenant ?? null } : {}),\n options: input.options,\n });\n if (!checked.ok) {\n return { ok: false, reason: 'invalid', issues: checked.issues };\n }\n const canonical = checked.canonical ?? null;\n const userId = input.scope === 'user' ? principal.userId : undefined;\n const existing = await records.findTier(\n principal.tenantId,\n kind.kind,\n surfaceId,\n input.scope,\n userId,\n );\n const revision = input.revision ?? null;\n if (canonical === null) {\n // Back on the tier below: store nothing.\n if (!existing) {\n return revision === null\n ? { ok: true, payload: null, revision: null }\n : { ok: false, reason: 'conflict' };\n }\n if (revision === null) return { ok: false, reason: 'conflict' };\n try {\n grantStoreDelete(existing);\n await existing.delete({ expectedUpdatedAt: revision });\n } catch (error) {\n if (isRevisionConflict(error)) {\n return { ok: false, reason: 'conflict' };\n }\n throw error;\n }\n return { ok: true, payload: null, revision: null };\n }\n if (existing) {\n if (revision === null) return { ok: false, reason: 'conflict' };\n existing.setPayload(canonical);\n existing.formatVersion = kind.formatVersion;\n grantStoreWrite(existing);\n try {\n await existing.save({ expectedUpdatedAt: revision });\n } catch (error) {\n if (isRevisionConflict(error)) {\n return { ok: false, reason: 'conflict' };\n }\n throw error;\n }\n return { ok: true, payload: canonical, revision: existing.revision };\n }\n if (revision !== null) return { ok: false, reason: 'conflict' };\n try {\n const created = await records.create({\n tenantId: principal.tenantId,\n kind: kind.kind,\n surfaceId,\n scopeType: input.scope,\n userId: userId ?? null,\n payloadJson: JSON.stringify(canonical),\n formatVersion: kind.formatVersion,\n _insertOnly: true,\n ...storeWriteOption(),\n } as Parameters<UiPreferenceRecordCollection['create']>[0]);\n return { ok: true, payload: canonical, revision: created.revision };\n } catch (error) {\n // A concurrent first write took the natural key: the strict insert\n // refuses instead of overwriting it.\n const raced = await records.findTier(\n principal.tenantId,\n kind.kind,\n surfaceId,\n input.scope,\n userId,\n );\n if (raced) return { ok: false, reason: 'conflict' };\n throw error;\n }\n });\n },\n\n async reset(kindId, surfaceId, input) {\n const kind = requirePreferenceKind(kindId);\n assertSurfaceId(surfaceId);\n const principal = requirePreferencePrincipal();\n return withPrincipal(principal, async () => {\n if (!(await canWrite(principal, kind, input.scope, db))) {\n return { ok: false, reason: 'not_allowed' };\n }\n const records = await collection();\n const existing = await records.findTier(\n principal.tenantId,\n kind.kind,\n surfaceId,\n input.scope,\n input.scope === 'user' ? principal.userId : undefined,\n );\n if (!existing) return { ok: true };\n // `null` means \"I loaded no row\", exactly as on save: a row that\n // exists now was written after that load, so deleting it would lose\n // a newer change. Only an omitted revision resets unguarded.\n if (input.revision === null) return { ok: false, reason: 'conflict' };\n try {\n grantStoreDelete(existing);\n await existing.delete(\n typeof input.revision === 'string'\n ? { expectedUpdatedAt: input.revision }\n : {},\n );\n } catch (error) {\n if (isRevisionConflict(error)) {\n return { ok: false, reason: 'conflict' };\n }\n throw error;\n }\n return { ok: true };\n });\n },\n };\n}\n","/**\n * The overview layer (#3727 phase 3): overview-shaped load, save, reset,\n * page load and widget load over the generic preference store, kind\n * `overview`, surface id = `OverviewDefinition.id`.\n *\n * Tiers, low to high: the page's `definition.defaults`, the tenant default,\n * then the user's override. The tenant tier merges into the defaults first\n * and the user tier applies to that result, so a user override is a delta\n * against the tenant default. Saves are strict (`checkOverviewOverride`, only\n * the canonical override is stored); loads are lenient (a bad entry is\n * dropped and reported, the rest render).\n */\nimport {\n type LoadedOverview,\n type LoadOverviewOptions,\n loadOverview,\n type OverviewDefinition,\n type OverviewDocument,\n type OverviewIssue,\n type OverviewOverride,\n optionsEqual,\n parseOverviewDocument,\n resolveOverview,\n sanitizeOverview,\n type WidgetLoadInput,\n type WidgetRegistry,\n} from '@happyvertical/smrt-svelte/overview/server';\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport {\n OVERVIEW_PREFERENCE_KIND,\n type OverviewKindOptions,\n toOverviewIssue,\n withTenantDefaults,\n} from './kinds/overview.js';\nimport type { PreferenceScope } from './kinds.js';\nimport { createPreferenceStore, type PreferenceStore } from './store.js';\n\n/** One stored tier, resolved. */\nexport interface OverviewTierState {\n /** The document this tier applies to (sanitized). */\n base: OverviewDocument;\n /** The document after this tier (sanitized). */\n document: OverviewDocument;\n /** The stored override, canonical with invalid entries removed, or `null`. */\n override: OverviewOverride | null;\n /** Concurrency token: echo it back on save or reset; `null` = no row. */\n revision: string | null;\n /** Entries of the stored override dropped on load, and why. */\n issues: OverviewIssue[];\n}\n\n/** What a page load needs to render and edit one overview. */\nexport interface OverviewState {\n overviewId: string;\n /** The tenant default over `definition.defaults`. */\n tenant: OverviewTierState;\n /** The user's override over the tenant default; `null` without a user. */\n user: OverviewTierState | null;\n /** What the principal sees: the user tier's document, else the tenant's. */\n document: OverviewDocument;\n /** Every stored-tier issue (tenant first). Page-default issues excluded. */\n issues: OverviewIssue[];\n /** Feed `createOverview({ canCustomize })` for the tier being edited. */\n canCustomize: { tenant: boolean; user: boolean };\n}\n\nexport type OverviewWriteFailure =\n | { ok: false; reason: 'not_allowed' }\n | { ok: false; reason: 'conflict' }\n | { ok: false; reason: 'invalid'; issues: OverviewIssue[] };\n\nexport type OverviewSaveResult =\n | { ok: true; override: OverviewOverride | null; revision: string | null }\n | OverviewWriteFailure;\n\nexport type OverviewResetResult = { ok: true } | OverviewWriteFailure;\n\nexport interface OverviewSaveInput {\n scope: PreferenceScope;\n /** The client's override (untrusted). `null` resets the tier. */\n override: unknown;\n /**\n * The `revision` the client loaded for this tier (`null` when it loaded no\n * row). A stale revision fails with `conflict`, never overwrites.\n */\n revision: string | null;\n}\n\nexport interface OverviewResetInput {\n scope: PreferenceScope;\n /**\n * The revision the client loaded: a string guards the delete, `null`\n * conflicts when a row exists, and omitting it resets regardless.\n */\n revision?: string | null;\n}\n\nexport interface OverviewPageOptions extends LoadOverviewOptions {\n /** Which tier's document to load: `user` (default) or `tenant` (editing defaults). */\n scope?: PreferenceScope;\n}\n\nexport type OverviewWidgetResult =\n | { ok: true; data: unknown }\n | { ok: false; reason: 'not_allowed' }\n | { ok: false; reason: 'invalid'; issues: OverviewIssue[] }\n | {\n ok: false;\n reason: 'load_failed';\n code: 'load_failed' | 'timeout' | 'invalid_data';\n };\n\nexport interface OverviewStoreOptions {\n db: DatabaseInterface;\n /** Share a generic store (default: one over `db`). */\n preferences?: PreferenceStore;\n}\n\nexport interface OverviewStore {\n /** Read both tiers for the principal and resolve the merge. */\n load(\n definition: OverviewDefinition,\n registry: WidgetRegistry,\n ): Promise<OverviewState>;\n /** Validate and store one tier's override (canonical form only). */\n save(\n definition: OverviewDefinition,\n registry: WidgetRegistry,\n input: OverviewSaveInput,\n ): Promise<OverviewSaveResult>;\n /** Delete one tier's row, returning that tier to the tier below. */\n reset(\n definition: OverviewDefinition,\n input: OverviewResetInput,\n ): Promise<OverviewResetResult>;\n /** `load` plus `loadOverview`, for a page's server load. */\n loadPage(\n definition: OverviewDefinition,\n registry: WidgetRegistry,\n ctx: WidgetLoadInput,\n options?: OverviewPageOptions,\n ): Promise<OverviewState & { loaded: LoadedOverview }>;\n /** The data of one widget, for the controller's `loadWidget` remote function. */\n loadWidget(\n definition: OverviewDefinition,\n registry: WidgetRegistry,\n widget: unknown,\n ctx: WidgetLoadInput,\n options?: LoadOverviewOptions,\n ): Promise<OverviewWidgetResult>;\n}\n\nfunction sameWidget(\n a: OverviewDocument['widgets'][number],\n b: OverviewDocument['widgets'][number],\n): boolean {\n return (\n a.id === b.id &&\n a.type === b.type &&\n (a.version ?? 1) === (b.version ?? 1) &&\n optionsEqual(a.options, b.options)\n );\n}\n\n/**\n * The persistence and server-load API of overview surfaces. Every call acts\n * as the ambient principal.\n */\nexport function createOverviewStore(\n options: OverviewStoreOptions,\n): OverviewStore {\n const preferences =\n options.preferences ?? createPreferenceStore({ db: options.db });\n const kindOptions = (\n definition: OverviewDefinition,\n registry: WidgetRegistry,\n ): OverviewKindOptions => ({ definition, registry });\n\n const store: OverviewStore = {\n async load(definition, registry) {\n const state = await preferences.load(\n OVERVIEW_PREFERENCE_KIND,\n definition.id,\n { options: kindOptions(definition, registry) },\n );\n const tenantOverride = state.tenant.payload as OverviewOverride | null;\n const tenantResolved = resolveOverview(\n definition,\n tenantOverride,\n registry,\n );\n const tenant: OverviewTierState = {\n base: tenantResolved.base,\n document: tenantResolved.document,\n override: tenantOverride,\n revision: state.tenant.revision,\n issues: state.tenant.issues.map(toOverviewIssue),\n };\n let user: OverviewTierState | null = null;\n if (state.user) {\n const userOverride = state.user.payload as OverviewOverride | null;\n const userResolved = resolveOverview(\n withTenantDefaults(definition, tenant.document),\n userOverride,\n registry,\n );\n user = {\n base: userResolved.base,\n document: userResolved.document,\n override: userOverride,\n revision: state.user.revision,\n issues: state.user.issues.map(toOverviewIssue),\n };\n }\n return {\n overviewId: definition.id,\n tenant,\n user,\n document: user?.document ?? tenant.document,\n issues: [...tenant.issues, ...(user?.issues ?? [])],\n canCustomize: state.canCustomize,\n };\n },\n\n async save(definition, registry, input) {\n const result = await preferences.save(\n OVERVIEW_PREFERENCE_KIND,\n definition.id,\n {\n scope: input.scope,\n payload: input.override,\n revision: input.revision,\n options: kindOptions(definition, registry),\n },\n );\n if (result.ok) {\n return {\n ok: true,\n override: result.payload as OverviewOverride | null,\n revision: result.revision,\n };\n }\n if (result.reason === 'invalid') {\n return {\n ok: false,\n reason: 'invalid',\n issues: result.issues.map(toOverviewIssue),\n };\n }\n return result;\n },\n\n async reset(definition, input) {\n const result = await preferences.reset(\n OVERVIEW_PREFERENCE_KIND,\n definition.id,\n input,\n );\n if (!result.ok && result.reason === 'invalid') {\n return {\n ok: false,\n reason: 'invalid',\n issues: result.issues.map(toOverviewIssue),\n };\n }\n return result as OverviewResetResult;\n },\n\n async loadPage(definition, registry, ctx, pageOptions = {}) {\n const { scope = 'user', ...loadOptions } = pageOptions;\n const state = await store.load(definition, registry);\n const document =\n scope === 'tenant' ? state.tenant.document : state.document;\n const loaded = await loadOverview(\n document,\n definition,\n registry,\n ctx,\n loadOptions,\n );\n return { ...state, loaded };\n },\n\n async loadWidget(definition, registry, widget, ctx, loadOptions = {}) {\n const state = await store.load(definition, registry);\n const parsed = parseOverviewDocument({ widgets: [widget] });\n const candidate = parsed.document.widgets[0];\n if (!candidate || parsed.issues.length > 0) {\n return { ok: false, reason: 'invalid', issues: parsed.issues };\n }\n // A viewer may reload a widget that is on their overview; loading any\n // other widget (an add or a reconfigure in progress) needs a customize\n // permission on some tier, like the save it precedes.\n const onPage = [\n ...state.document.widgets,\n ...state.tenant.document.widgets,\n ].some((existing) => sameWidget(existing, candidate));\n if (!onPage && !state.canCustomize.tenant && !state.canCustomize.user) {\n return { ok: false, reason: 'not_allowed' };\n }\n const sanitized = sanitizeOverview(\n { widgets: [candidate] },\n { registry, definition },\n );\n if (sanitized.issues.length > 0) {\n return { ok: false, reason: 'invalid', issues: sanitized.issues };\n }\n const loaded = await loadOverview(\n sanitized.document,\n definition,\n registry,\n ctx,\n loadOptions,\n );\n const result = loaded.widgets[0];\n if (!result) return { ok: false, reason: 'invalid', issues: [] };\n if (result.status === 'error') {\n return {\n ok: false,\n reason: 'load_failed',\n code: result.error?.code ?? 'load_failed',\n };\n }\n return { ok: true, data: result.data };\n },\n };\n return store;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/__smrt-register__.ts","../src/permissions.ts","../src/kinds.ts","../src/kinds/overview.ts","../src/kinds/shell-layout.ts","../src/kinds/builtin.ts","../src/context.ts","../src/read-guard.ts","../src/write-capability.ts","../src/models/UiPreferenceRecord.ts","../src/collections/UiPreferenceRecordCollection.ts","../src/store.ts","../src/overview.ts"],"sourcesContent":["// Generated by @happyvertical/smrt-core smrtPlugin at library build time.\n// The package manifest is inlined so self-registration cannot miss when a\n// downstream bundler relocates this module away from dist/manifest.json\n// (https://github.com/happyvertical/smrt/issues/1506,\n// https://github.com/happyvertical/smrt/issues/1507).\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(JSON.parse(\"{\\\"version\\\":\\\"1.0.0\\\",\\\"timestamp\\\":0,\\\"packageName\\\":\\\"@happyvertical/smrt-preferences\\\",\\\"packageVersion\\\":\\\"0.57.4\\\",\\\"objects\\\":{\\\"@happyvertical/smrt-preferences:UiPreferenceRecordCollection\\\":{\\\"name\\\":\\\"uipreferencerecordcollection\\\",\\\"className\\\":\\\"UiPreferenceRecordCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-preferences:UiPreferenceRecordCollection\\\",\\\"collection\\\":\\\"uipreferencerecords\\\",\\\"description\\\":\\\"Reads of UiPreferenceRecord. Not decorated: the model has no generated surface, so a decorated collection would only add a second manifest schema for the same table.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/preferences/src/collections/UiPreferenceRecordCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-preferences\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findTier\\\":{\\\"name\\\":\\\"findTier\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"kind\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"surfaceId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scope\\\",\\\"type\\\":\\\"PreferenceScope\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"userId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<UiPreferenceRecord | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_ui_preferences\\\",\\\"api\\\":{\\\"include\\\":[]},\\\"mcp\\\":{\\\"include\\\":[]},\\\"cli\\\":false},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"UiPreferenceRecord\\\",\\\"exportName\\\":\\\"UiPreferenceRecordCollection\\\",\\\"collectionExportName\\\":\\\"UiPreferenceRecordCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_ui_preferences\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_ui_preferences\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"kind\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"surface_id\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"scope_type\\\\\\\" TEXT NOT NULL DEFAULT 'tenant',\\\\n \\\\\\\"user_id\\\\\\\" UUID,\\\\n \\\\\\\"scope_key\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"payload_json\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"format_version\\\\\\\" INTEGER,\\\\n \\\\\\\"updated_by\\\\\\\" UUID\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"kind\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"surface_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"scope_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"tenant\\\"},\\\"user_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"scope_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"payload_json\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"format_version\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"updated_by\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_ui_preferences_tenant_id_kind_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"kind\\\",\\\"surface_id\\\",\\\"scope_type\\\",\\\"scope_key\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_ui_preferences_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"_smrt_ui_preferences_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"_smrt_ui_preferences_user_id_idx\\\",\\\"columns\\\":[\\\"user_id\\\"]},{\\\"name\\\":\\\"_smrt_ui_preferences_updated_by_idx\\\",\\\"columns\\\":[\\\"updated_by\\\"]}],\\\"version\\\":\\\"3f9df5fd\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-preferences\\\"},\\\"@happyvertical/smrt-preferences:UiPreferenceRecord\\\":{\\\"name\\\":\\\"uipreferencerecord\\\",\\\"className\\\":\\\"UiPreferenceRecord\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-preferences:UiPreferenceRecord\\\",\\\"collection\\\":\\\"uipreferencerecords\\\",\\\"description\\\":\\\"One stored user-interface preference (#3727): the canonical payload of a registered preference kind (overview, shell-layout, ...) for one surface at one tier of one tenant.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/preferences/src/models/UiPreferenceRecord.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-preferences\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":true,\\\"autoPopulate\\\":true,\\\"nullable\\\":false,\\\"mode\\\":\\\"required\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"kind\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"surfaceId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"scopeType\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"tenant\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"userId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-users:User\\\",\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"scopeKey\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}},\\\"payloadJson\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}},\\\"formatVersion\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"updatedBy\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-users:User\\\",\\\"_meta\\\":{\\\"nullable\\\":true}}},\\\"methods\\\":{\\\"loadFromId\\\":{\\\"name\\\":\\\"loadFromId\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"loadFromSlug\\\":{\\\"name\\\":\\\"loadFromSlug\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getPayload\\\":{\\\"name\\\":\\\"getPayload\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"unknown\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setPayload\\\":{\\\"name\\\":\\\"setPayload\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"value\\\",\\\"type\\\":\\\"unknown\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"SaveOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"delete\\\":{\\\"name\\\":\\\"delete\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"DeleteOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_ui_preferences\\\",\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"kind\\\",\\\"surface_id\\\",\\\"scope_type\\\",\\\"scope_key\\\"],\\\"api\\\":{\\\"include\\\":[]},\\\"cli\\\":false,\\\"mcp\\\":{\\\"include\\\":[]},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"required\\\"}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"UiPreferenceRecord\\\",\\\"collectionExportName\\\":\\\"UiPreferenceRecordCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"kind\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"surfaceId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"scopeType\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"scopeKey\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"payloadJson\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_ui_preferences\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_ui_preferences\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"kind\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"surface_id\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"scope_type\\\\\\\" TEXT NOT NULL DEFAULT 'tenant',\\\\n \\\\\\\"user_id\\\\\\\" UUID,\\\\n \\\\\\\"scope_key\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"payload_json\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"format_version\\\\\\\" INTEGER,\\\\n \\\\\\\"updated_by\\\\\\\" UUID\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"kind\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"surface_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"scope_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"tenant\\\"},\\\"user_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"scope_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"payload_json\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"format_version\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"updated_by\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_ui_preferences_tenant_id_kind_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"kind\\\",\\\"surface_id\\\",\\\"scope_type\\\",\\\"scope_key\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_ui_preferences_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"_smrt_ui_preferences_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"_smrt_ui_preferences_user_id_idx\\\",\\\"columns\\\":[\\\"user_id\\\"]},{\\\"name\\\":\\\"_smrt_ui_preferences_updated_by_idx\\\",\\\"columns\\\":[\\\"updated_by\\\"]}],\\\"version\\\":\\\"3f9df5fd\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-preferences\\\"}},\\\"moduleType\\\":\\\"smrt\\\",\\\"smrtDependencies\\\":[\\\"@happyvertical/smrt-core\\\",\\\"@happyvertical/smrt-tenancy\\\",\\\"@happyvertical/smrt-users\\\"],\\\"browser\\\":{\\\"status\\\":\\\"server-only\\\",\\\"issues\\\":[\\\"#3617\\\",\\\"#3624\\\",\\\"#3626\\\"],\\\"via\\\":[\\\"@happyvertical/smrt-profiles\\\",\\\"@happyvertical/smrt-tenancy\\\",\\\"@happyvertical/smrt-users\\\"]},\\\"stampsConstructors\\\":true}\"));\n","import {\n type PermissionDefinition,\n registerPermissionDefinitions,\n} from '@happyvertical/smrt-users';\n\n/** Authorizes changing and resetting a tenant's default overview layouts. */\nexport const CUSTOMIZE_OVERVIEW_PERMISSION = 'overviews.customize';\n\n/** Authorizes a principal to keep their own overview layouts. */\nexport const PERSONALIZE_OVERVIEW_PERMISSION = 'overviews.personalize';\n\n/** Authorizes changing and resetting a tenant's default shell layout. */\nexport const CUSTOMIZE_SHELL_PERMISSION = 'shell.customize';\n\n/** Authorizes a principal to keep their own shell layout and settings. */\nexport const PERSONALIZE_SHELL_PERMISSION = 'shell.personalize';\n\nexport const PREFERENCE_PERMISSION_DEFINITIONS: PermissionDefinition[] = [\n {\n slug: CUSTOMIZE_OVERVIEW_PERMISSION,\n category: 'preferences',\n name: 'Customize Overviews',\n description:\n 'Change the default overview layouts everyone in the tenant sees',\n },\n {\n slug: PERSONALIZE_OVERVIEW_PERMISSION,\n category: 'preferences',\n name: 'Personalize Overviews',\n description: 'Keep a personal overview layout on top of the tenant default',\n },\n {\n slug: CUSTOMIZE_SHELL_PERMISSION,\n category: 'preferences',\n name: 'Customize Shell Layout',\n description:\n 'Change the default navigation and panel layout everyone in the tenant sees',\n },\n {\n slug: PERSONALIZE_SHELL_PERMISSION,\n category: 'preferences',\n name: 'Personalize Shell Layout',\n description:\n 'Keep a personal navigation and panel layout on top of the tenant default',\n },\n];\n\nlet registered = false;\n\n/** Register the built-in preference permissions once. */\nexport function ensurePreferencePermissionsRegistered(): void {\n if (registered) {\n return;\n }\n registered = true;\n registerPermissionDefinitions(PREFERENCE_PERMISSION_DEFINITIONS);\n}\n\n/**\n * `collection.action` parts of a permission slug for the users operation\n * guards: the action is the last segment (`fields.policy.manage` is\n * collection `fields.policy`, action `manage`).\n */\nexport function splitPermissionSlug(slug: string): {\n collection: string;\n action: string;\n} {\n const dot = slug.lastIndexOf('.');\n if (dot <= 0 || dot === slug.length - 1) {\n throw new Error(`Preference permission \"${slug}\" is not collection.action`);\n }\n return { collection: slug.slice(0, dot), action: slug.slice(dot + 1) };\n}\n","/**\n * The preference kind registry (#3727).\n *\n * A kind is one family of user-interface preference (`overview`,\n * `shell-layout`, ...). It owns the validation of its payload and names the\n * permission pair for its two tiers. The store refuses a kind that is not\n * registered, so nothing reaches the table that no code can validate.\n */\nimport { splitPermissionSlug } from './permissions.js';\n\n/** The two tiers a stored preference can belong to. */\nexport const PREFERENCE_SCOPES = ['tenant', 'user'] as const;\nexport type PreferenceScope = (typeof PREFERENCE_SCOPES)[number];\n\n/** Kind ids: lowercase kebab, e.g. `shell-layout`. */\nexport const PREFERENCE_KIND_PATTERN = /^[a-z][a-z0-9-]{0,47}$/;\n\n/** Surface ids: a page id, a shell key (`events.home`, `admin`). */\nexport const PREFERENCE_SURFACE_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,95}$/;\n\n/** One dropped or rejected part of a payload, and why. */\nexport interface PreferenceIssue {\n /** Where in the payload (a widget id, a dotted path), or `null`. */\n path: string | null;\n /** Kind-defined code (`malformed`, `future_version`, `invalid_options`, ...). */\n code: string;\n /** Developer-facing detail; not localized. */\n message: string;\n /** The kind's own issue object, for kind-specific callers. */\n detail?: unknown;\n}\n\n/**\n * What a kind's `validate` returns. `canonical` is the payload to store (on\n * save) or use (on load) with every invalid part removed; `null` means \"no\n * preference\" (the tier below applies). `ok` is false whenever something was\n * removed or refused. The store refuses a save that is not `ok` and stores\n * only `canonical`; on load it uses `canonical` and reports `issues`.\n */\nexport interface PreferenceValidation {\n ok: boolean;\n canonical: unknown | null;\n issues: PreferenceIssue[];\n}\n\nexport interface PreferenceValidateContext {\n kind: string;\n surfaceId: string;\n scope: PreferenceScope;\n /** `save` (strict) or `load` (lenient). */\n phase: 'save' | 'load';\n /** The format version the payload was written at (the kind's on save). */\n formatVersion: number;\n /**\n * The tenant tier's canonical payload when validating the user tier\n * (`null` when the tenant has none); absent for the tenant tier.\n */\n tenant?: unknown | null;\n /** Host-supplied, kind-specific inputs (e.g. the overview definition). */\n options?: unknown;\n}\n\nexport interface PreferenceKindDefinition {\n kind: string;\n /** Current payload format version (a positive integer). */\n formatVersion: number;\n /** Slugs that authorize writing each tier (`collection.action`). */\n permissions: { tenant: string; user: string };\n validate(\n payload: unknown,\n ctx: PreferenceValidateContext,\n ): PreferenceValidation;\n}\n\n/** A store call named a kind no code registered. */\nexport class UnknownPreferenceKindError extends Error {\n readonly code = 'unknown_preference_kind';\n readonly status = 400;\n\n constructor(kind: string) {\n super(`Preference kind \"${kind}\" is not registered`);\n this.name = 'UnknownPreferenceKindError';\n }\n}\n\nconst kinds = new Map<string, PreferenceKindDefinition>();\n\n/**\n * Register a preference kind. Registering a kind twice throws unless\n * `{ replace: true }`; returns a disposer that removes this registration.\n */\nexport function registerPreferenceKind(\n definition: PreferenceKindDefinition,\n options: { replace?: boolean } = {},\n): () => void {\n if (!PREFERENCE_KIND_PATTERN.test(definition.kind)) {\n throw new Error(`Invalid preference kind \"${definition.kind}\"`);\n }\n if (\n !Number.isSafeInteger(definition.formatVersion) ||\n definition.formatVersion < 1\n ) {\n throw new Error(\n `Preference kind \"${definition.kind}\" needs a positive formatVersion`,\n );\n }\n splitPermissionSlug(definition.permissions.tenant);\n splitPermissionSlug(definition.permissions.user);\n if (typeof definition.validate !== 'function') {\n throw new Error(`Preference kind \"${definition.kind}\" needs validate()`);\n }\n if (kinds.has(definition.kind) && !options.replace) {\n throw new Error(\n `Preference kind \"${definition.kind}\" is already registered`,\n );\n }\n const frozen = Object.freeze({\n ...definition,\n permissions: Object.freeze({ ...definition.permissions }),\n });\n kinds.set(definition.kind, frozen);\n return () => {\n if (kinds.get(definition.kind) === frozen) kinds.delete(definition.kind);\n };\n}\n\n/** The registered kind, or `undefined`. */\nexport function getPreferenceKind(\n kind: string,\n): PreferenceKindDefinition | undefined {\n return kinds.get(kind);\n}\n\n/** The registered kind; throws {@link UnknownPreferenceKindError} otherwise. */\nexport function requirePreferenceKind(kind: string): PreferenceKindDefinition {\n const definition = kinds.get(kind);\n if (!definition) throw new UnknownPreferenceKindError(kind);\n return definition;\n}\n\n/** Registered kind ids in registration order. */\nexport function listPreferenceKinds(): string[] {\n return [...kinds.keys()];\n}\n","/**\n * The `overview` preference kind: the sparse `OverviewOverride` of a\n * customizable overview page (`@happyvertical/smrt-svelte/overview`).\n *\n * The surface id is the page's `OverviewDefinition.id`. Validation needs the\n * page definition and widget registry, which the caller passes as the kind's\n * `options` (`{ definition, registry }`); the overview layer in\n * `../overview.ts` does that for every call.\n */\nimport {\n checkOverviewOverride,\n diffOverview,\n type OverviewDefinition,\n type OverviewDocument,\n type OverviewIssue,\n resolveOverview,\n type WidgetRegistry,\n} from '@happyvertical/smrt-svelte/overview/server';\nimport type {\n PreferenceIssue,\n PreferenceKindDefinition,\n PreferenceValidation,\n} from '../kinds.js';\nimport {\n CUSTOMIZE_OVERVIEW_PERMISSION,\n PERSONALIZE_OVERVIEW_PERMISSION,\n} from '../permissions.js';\n\nexport const OVERVIEW_PREFERENCE_KIND = 'overview';\n\n/** The validation inputs of the `overview` kind. */\nexport interface OverviewKindOptions {\n definition: OverviewDefinition;\n registry: WidgetRegistry;\n}\n\n/**\n * `definition` with another tier's document as its defaults: the definition a\n * user-tier controller and save are validated against\n * (`withTenantDefaults(definition, state.tenant.document)`).\n */\nexport function withTenantDefaults(\n definition: OverviewDefinition,\n document: OverviewDocument,\n): OverviewDefinition {\n return { ...definition, defaults: document.widgets };\n}\n\nfunction toPreferenceIssue(issue: OverviewIssue): PreferenceIssue {\n return {\n path: issue.widgetId,\n code: issue.code,\n message: issue.message,\n detail: issue,\n };\n}\n\n/** The `OverviewIssue` behind a preference issue (or a generic one). */\nexport function toOverviewIssue(issue: PreferenceIssue): OverviewIssue {\n if (issue.detail && typeof issue.detail === 'object') {\n return issue.detail as OverviewIssue;\n }\n return {\n widgetId: null,\n type: null,\n code: issue.code === 'future_version' ? 'future_version' : 'malformed',\n message: issue.message,\n };\n}\n\nfunction readOptions(options: unknown): OverviewKindOptions | null {\n if (!options || typeof options !== 'object') return null;\n const { definition, registry } = options as Partial<OverviewKindOptions>;\n if (!definition || !registry) return null;\n return { definition, registry };\n}\n\n/**\n * The definition one tier validates against: the page definition for the\n * tenant tier, the tenant-merged one for the user tier.\n */\nexport function overviewTierDefinition(\n { definition, registry }: OverviewKindOptions,\n scope: 'tenant' | 'user',\n tenantOverride: unknown,\n): OverviewDefinition {\n if (scope === 'tenant') return definition;\n const tenant = resolveOverview(definition, tenantOverride ?? null, registry);\n return withTenantDefaults(definition, tenant.document);\n}\n\nexport const overviewPreferenceKind: PreferenceKindDefinition = {\n kind: OVERVIEW_PREFERENCE_KIND,\n formatVersion: 1,\n permissions: {\n tenant: CUSTOMIZE_OVERVIEW_PERMISSION,\n user: PERSONALIZE_OVERVIEW_PERMISSION,\n },\n validate(payload, ctx): PreferenceValidation {\n const options = readOptions(ctx.options);\n if (!options || options.definition.id !== ctx.surfaceId) {\n return {\n ok: false,\n canonical: null,\n issues: [\n {\n path: null,\n code: 'missing_context',\n message:\n 'the overview kind needs { definition, registry } for this surface',\n },\n ],\n };\n }\n const definition = overviewTierDefinition(options, ctx.scope, ctx.tenant);\n if (ctx.phase === 'save') {\n const checked = checkOverviewOverride(\n definition,\n payload,\n options.registry,\n );\n return checked.ok\n ? { ok: true, canonical: checked.override, issues: [] }\n : {\n ok: false,\n canonical: null,\n issues: checked.issues.map(toPreferenceIssue),\n };\n }\n const resolved = resolveOverview(definition, payload, options.registry);\n return {\n ok: resolved.overrideIssues.length === 0,\n canonical: diffOverview(resolved.base, resolved.document),\n issues: resolved.overrideIssues.map(toPreferenceIssue),\n };\n },\n};\n","/**\n * The `shell-layout` preference kind: the sparse `ShellSettingsDelta` the\n * AdminShell settings adapter reads and writes (navigation layout, panel\n * states and sizes, keymap), validated with smrt-svelte's\n * `sanitizeShellSettingsDelta` from the Node-safe `./workspace/server` entry.\n *\n * The surface id names the shell (the app's `storageKey`, e.g. `admin`).\n */\nimport {\n mergeShellSettingsDelta,\n type ShellSettingsDelta,\n type ShellSettingsIssue,\n sanitizeShellSettingsDelta,\n} from '@happyvertical/smrt-svelte/workspace/server';\nimport type {\n PreferenceIssue,\n PreferenceKindDefinition,\n PreferenceScope,\n} from '../kinds.js';\nimport {\n CUSTOMIZE_SHELL_PERMISSION,\n PERSONALIZE_SHELL_PERMISSION,\n} from '../permissions.js';\nimport type {\n PreferenceResetResult,\n PreferenceSaveResult,\n PreferenceStore,\n} from '../store.js';\n\nexport const SHELL_LAYOUT_PREFERENCE_KIND = 'shell-layout';\n\nfunction toPreferenceIssue(issue: ShellSettingsIssue): PreferenceIssue {\n return {\n path: issue.path || null,\n code: 'invalid_setting',\n message: issue.message,\n detail: issue,\n };\n}\n\nexport const shellLayoutPreferenceKind: PreferenceKindDefinition = {\n kind: SHELL_LAYOUT_PREFERENCE_KIND,\n formatVersion: 1,\n permissions: {\n tenant: CUSTOMIZE_SHELL_PERMISSION,\n user: PERSONALIZE_SHELL_PERMISSION,\n },\n validate(payload) {\n const { delta, issues } = sanitizeShellSettingsDelta(payload);\n return {\n ok: issues.length === 0,\n canonical: Object.keys(delta).length > 0 ? delta : null,\n issues: issues.map(toPreferenceIssue),\n };\n },\n};\n\n/** What a shell reads: the merged delta plus each tier for an editor. */\nexport interface ShellSettingsPreferenceRead {\n /** Tenant default merged with the user's delta (`mergeShellSettingsDelta`). */\n delta: ShellSettingsDelta;\n tenant: ShellSettingsDelta | null;\n user: ShellSettingsDelta | null;\n /** Revisions of each tier, for guarded writes. */\n revisions: { tenant: string | null; user: string | null };\n issues: PreferenceIssue[];\n canCustomize: { tenant: boolean; user: boolean };\n}\n\nexport interface ShellSettingsPreferenceWriteOptions {\n /** Default `user`. */\n scope?: PreferenceScope;\n /**\n * The revision the client loaded. Omitted, the current revision is read\n * just before the write: last-writer-wins for that call, which is what the\n * shell's `ShellSettingsAdapter.write(delta)` (no revision) gets.\n */\n revision?: string | null;\n}\n\n/**\n * The server half of a shell `ShellSettingsAdapter`. A host exposes `read`\n * and `write` as remote functions and the browser adapter calls them:\n *\n * ```ts\n * const adapter: ShellSettingsAdapter = {\n * read: async () => (await readShellSettings('admin')).delta,\n * write: (delta) => writeShellSettings('admin', delta),\n * };\n * ```\n */\nexport interface ShellSettingsPreferences {\n read(surfaceId: string): Promise<ShellSettingsPreferenceRead>;\n write(\n surfaceId: string,\n delta: unknown,\n options?: ShellSettingsPreferenceWriteOptions,\n ): Promise<PreferenceSaveResult>;\n reset(\n surfaceId: string,\n options?: ShellSettingsPreferenceWriteOptions,\n ): Promise<PreferenceResetResult>;\n}\n\nfunction compact(delta: ShellSettingsDelta): ShellSettingsDelta {\n return Object.fromEntries(\n Object.entries(delta).filter(([, value]) => value !== undefined),\n ) as ShellSettingsDelta;\n}\n\n/** Shell settings persistence over the generic preference store. */\nexport function createShellSettingsPreferences(\n store: PreferenceStore,\n): ShellSettingsPreferences {\n return {\n async read(surfaceId) {\n const state = await store.load(SHELL_LAYOUT_PREFERENCE_KIND, surfaceId);\n const tenant =\n (state.tenant.payload as ShellSettingsDelta | null) ?? null;\n const user = (state.user?.payload as ShellSettingsDelta | null) ?? null;\n return {\n delta: compact(mergeShellSettingsDelta(tenant ?? {}, user ?? {})),\n tenant,\n user,\n revisions: {\n tenant: state.tenant.revision,\n user: state.user?.revision ?? null,\n },\n issues: state.issues,\n canCustomize: state.canCustomize,\n };\n },\n\n async write(surfaceId, delta, options = {}) {\n const scope = options.scope ?? 'user';\n let revision = options.revision;\n if (revision === undefined) {\n const state = await store.load(SHELL_LAYOUT_PREFERENCE_KIND, surfaceId);\n revision =\n scope === 'tenant'\n ? state.tenant.revision\n : (state.user?.revision ?? null);\n }\n return store.save(SHELL_LAYOUT_PREFERENCE_KIND, surfaceId, {\n scope,\n payload: delta,\n revision,\n });\n },\n\n reset(surfaceId, options = {}) {\n return store.reset(SHELL_LAYOUT_PREFERENCE_KIND, surfaceId, {\n scope: options.scope ?? 'user',\n revision: options.revision,\n });\n },\n };\n}\n","/**\n * Registers the built-in preference kinds (`overview`, `shell-layout`) once.\n * Imported by the package entry and the store, so the model never meets a\n * built-in kind it does not know.\n */\nimport { getPreferenceKind, registerPreferenceKind } from '../kinds.js';\nimport { overviewPreferenceKind } from './overview.js';\nimport { shellLayoutPreferenceKind } from './shell-layout.js';\n\nexport function ensureBuiltinPreferenceKinds(): void {\n for (const kind of [overviewPreferenceKind, shellLayoutPreferenceKind]) {\n if (!getPreferenceKind(kind.kind)) registerPreferenceKind(kind);\n }\n}\n\nensureBuiltinPreferenceKinds();\n","/**\n * The request principal a preference read or write acts as.\n *\n * Identity always comes from the ambient context, never from a request body:\n * the tenancy ALS (`withTenant`, the SvelteKit/Express adapters) first, and\n * the authenticated users session-permission ALS (`createSessionHandler()`\n * without `enterTenantContext`) as the fallback, the smrt-fields precedent.\n */\nimport {\n getCurrentTenant,\n isSuperAdminBypass,\n TenantIsolationError,\n withTenant,\n} from '@happyvertical/smrt-tenancy';\nimport { getCurrentSessionPermissionContext } from '@happyvertical/smrt-users';\n\nexport interface PreferencePrincipal {\n tenantId: string;\n /** Absent for service principals, API keys and background jobs. */\n userId?: string;\n permissions: ReadonlySet<string>;\n superAdminBypass: boolean;\n /** True when the tenancy ALS already carries this principal. */\n fromTenancy: boolean;\n}\n\n/** The preference principal of the current async context, if any. */\nexport function getPreferencePrincipal(): PreferencePrincipal | undefined {\n const tenant = getCurrentTenant();\n if (tenant?.tenantId) {\n return {\n tenantId: tenant.tenantId,\n userId: tenant.userId,\n permissions: tenant.permissions,\n superAdminBypass: isSuperAdminBypass(),\n fromTenancy: true,\n };\n }\n const session = getCurrentSessionPermissionContext();\n if (!session?.tenantId) return undefined;\n return {\n tenantId: session.tenantId,\n userId: session.userId ?? undefined,\n permissions: session.permissionSet,\n superAdminBypass: session.superAdminBypass,\n fromTenancy: false,\n };\n}\n\n/** Bounded, identifier-free denial; generated transports serialize it as 403. */\nexport class PreferenceAccessError extends TenantIsolationError {\n readonly status = 403;\n readonly publicMessage: string;\n\n constructor(message: string) {\n super(message);\n this.name = 'PreferenceAccessError';\n this.publicMessage = message;\n }\n}\n\n/** The principal, or a fail-closed error when there is no tenant identity. */\nexport function requirePreferencePrincipal(): PreferencePrincipal {\n const principal = getPreferencePrincipal();\n if (!principal) {\n throw new PreferenceAccessError(\n 'User-interface preferences need an authenticated tenant context',\n );\n }\n return principal;\n}\n\n/**\n * Run `fn` with the tenancy ALS carrying `principal`. A session-only\n * principal is entered as a tenant context with the same tenant, user and\n * permissions, so the tenancy interceptor scopes the table exactly as it would\n * under the tenancy adapter. Nothing is widened.\n */\nexport async function withPrincipal<T>(\n principal: PreferencePrincipal,\n fn: () => Promise<T>,\n): Promise<T> {\n if (principal.fromTenancy) return fn();\n return withTenant(\n {\n tenantId: principal.tenantId,\n userId: principal.userId,\n permissions: new Set(principal.permissions),\n },\n fn,\n );\n}\n","/**\n * Owner-safe reads of `UiPreferenceRecord` (#3727).\n *\n * A principal must never read another user's preferences, through the\n * store or any other in-process path to the model. Tenancy already confines\n * every read to the principal's tenant; this interceptor adds the owner\n * rule to the READ PREDICATE before any SQL runs, so `list`, `get`, `count`,\n * `facets`, semantic search and every other path that runs `beforeList` /\n * `beforeGet` inherit it: only rows whose `scope_key` is `'__tenant__'` (the\n * tenant default) or the principal's own user id; with no user id, tenant\n * rows only. `scope_key` is the column the model keeps in lockstep with\n * `scope_type` / `user_id` (a user row's key is its user id). A caller's own\n * `scopeKey in` condition is intersected, never replaced. Raw `query()` SQL\n * cannot carry the predicate and is refused. The after-read hooks re-check\n * every hydrated row as defence in depth (a row whose scope cannot be told\n * is dropped), and single-row hydration is also checked by the model.\n *\n * @internal\n */\nimport {\n GlobalInterceptors,\n resolveGetStringFilter,\n type SmrtObject,\n} from '@happyvertical/smrt-core';\nimport { getPreferencePrincipal, PreferenceAccessError } from './context.js';\n\nconst GUARD_NAME = 'smrt-preferences:owner-reads';\nconst CLASS_NAME = 'UiPreferenceRecord';\nconst QUALIFIED_NAME = '@happyvertical/smrt-preferences:UiPreferenceRecord';\n\nfunction field(row: unknown, camel: string, snake: string): unknown {\n if (!row || typeof row !== 'object') return undefined;\n const record = row as Record<string, unknown>;\n return record[camel] !== undefined ? record[camel] : record[snake];\n}\n\n/** Whether the ambient principal may see `row`. */\nexport function isPreferenceRowVisible(row: unknown): boolean {\n const scope = field(row, 'scopeType', 'scope_type');\n if (scope === 'tenant') return true;\n if (scope !== 'user') return false;\n const owner = field(row, 'userId', 'user_id');\n const userId = getPreferencePrincipal()?.userId;\n return Boolean(userId) && typeof owner === 'string' && owner === userId;\n}\n\nfunction isPreferenceClass(\n className: string,\n qualifiedClassName?: string,\n): boolean {\n return qualifiedClassName === QUALIFIED_NAME || className === CLASS_NAME;\n}\n\nconst TENANT_KEY = '__tenant__';\n/** No row has an empty scope key (`scopeKey` is required and synced). */\nconst NO_ROW_KEY = '';\nconst SCOPE_KEY_IN = ['scopeKey in', 'scope_key in'] as const;\n\n/** The scope keys the ambient principal may read. */\nfunction visibleScopeKeys(): string[] {\n const userId = getPreferencePrincipal()?.userId;\n return userId ? [TENANT_KEY, userId] : [TENANT_KEY];\n}\n\n/**\n * `where` AND the owner predicate. A caller's `scopeKey in` list is\n * intersected with the visible keys (an empty intersection matches no row).\n */\nfunction withOwnerPredicate(\n where: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n const visible = visibleScopeKeys();\n const next: Record<string, unknown> = { ...(where ?? {}) };\n let keys = visible;\n for (const key of SCOPE_KEY_IN) {\n if (!(key in next)) continue;\n const requested = next[key];\n delete next[key];\n const list = Array.isArray(requested) ? requested : [requested];\n keys = keys.filter((value) => list.includes(value));\n }\n next['scopeKey in'] = keys.length > 0 ? keys : [NO_ROW_KEY];\n return next;\n}\n\nfunction filterRows<T>(\n className: string,\n rows: T[],\n qualifiedClassName?: string,\n): T[] | undefined {\n if (!isPreferenceClass(className, qualifiedClassName)) return undefined;\n return rows.filter(isPreferenceRowVisible);\n}\n\n/**\n * Register the owner-read interceptor (idempotent). Called when the model\n * module loads and again before every store read, so a cleared interceptor\n * registry (tests, `GlobalInterceptors.clear()`) cannot silently drop it.\n */\nexport function ensurePreferenceReadGuard(): void {\n if (GlobalInterceptors.getAll().some((entry) => entry.name === GUARD_NAME)) {\n return;\n }\n GlobalInterceptors.register({\n name: GUARD_NAME,\n // After tenancy (priority 100) has scoped the read to the tenant.\n priority: 90,\n beforeList(className, options, context) {\n if (!isPreferenceClass(className, context.qualifiedClassName)) return;\n const where = options.where as unknown;\n if (Array.isArray(where)) {\n // DNF: every OR branch carries the owner predicate.\n return {\n ...options,\n where: where.map((group: Record<string, unknown>[]) => [\n ...group,\n withOwnerPredicate({}),\n ]),\n } as typeof options;\n }\n return {\n ...options,\n where: withOwnerPredicate(where as Record<string, unknown>),\n };\n },\n beforeGet(className, filter, context) {\n if (!isPreferenceClass(className, context.qualifiedClassName)) return;\n const resolved =\n typeof filter === 'string' ? resolveGetStringFilter(filter) : filter;\n return withOwnerPredicate(resolved);\n },\n beforeQuery(className, _options, context) {\n if (!isPreferenceClass(className, context.qualifiedClassName)) return;\n // Raw SQL cannot carry the owner predicate: refuse it.\n throw new PreferenceAccessError(\n 'Raw queries over user-interface preferences are not allowed',\n );\n },\n afterList<T extends SmrtObject>(\n className: string,\n results: T[],\n context: { qualifiedClassName?: string },\n ) {\n return filterRows(className, results, context.qualifiedClassName);\n },\n afterQuery<T extends SmrtObject>(\n className: string,\n results: T[],\n context: { qualifiedClassName?: string },\n ) {\n return filterRows(className, results, context.qualifiedClassName);\n },\n afterGet<T extends SmrtObject>(\n className: string,\n instance: T | null,\n context: { qualifiedClassName?: string },\n ) {\n if (\n !instance ||\n !isPreferenceClass(className, context.qualifiedClassName)\n ) {\n return undefined;\n }\n return isPreferenceRowVisible(instance) ? instance : null;\n },\n });\n}\n","/**\n * Store-only write capability for `UiPreferenceRecord` (#3727).\n *\n * A preference payload is only meaningful after its kind validated it, and\n * only the store runs the validator. So the model refuses every insert,\n * update and delete that the store did not grant: an insert carries\n * {@link STORE_WRITE} as a constructor option (a symbol key never arrives\n * from JSON), and an update or delete is granted per instance just before\n * the store calls `save()` / `delete()`. A write grant is bound to the exact\n * `payloadJson` the store validated, and every grant is single-use.\n *\n * Not part of the package's public exports (the smrt-approvals\n * `write-capability.ts` pattern). This guards in-process callers of the\n * model and collection; it is not a defence against raw SQL.\n *\n * @internal\n * @packageDocumentation\n */\n\n/** Constructor-option key carrying the capability. Never exported publicly. */\nexport const STORE_WRITE = Symbol('smrt-preferences.storeWrite');\n\n/** The only value accepted under {@link STORE_WRITE}. */\nconst TOKEN = Object.freeze({ capability: 'smrt-preferences.storeWrite' });\n\n/** Granted writes: the payload the store validated for each instance. */\nconst writes = new WeakMap<object, string>();\n\n/** Granted deletes. */\nconst deletes = new WeakSet<object>();\n\n/** Constructor options fragment that grants an insert of `payloadJson`. */\nexport function storeWriteOption(): { [STORE_WRITE]: object } {\n return { [STORE_WRITE]: TOKEN };\n}\n\n/** Record an insert grant when the constructor options carry the token. */\nexport function adoptStoreWrite(instance: object, options: unknown): void {\n if (\n options &&\n typeof options === 'object' &&\n (options as Record<symbol, unknown>)[STORE_WRITE] === TOKEN &&\n typeof (options as { payloadJson?: unknown }).payloadJson === 'string'\n ) {\n writes.set(instance, (options as { payloadJson: string }).payloadJson);\n }\n}\n\n/** Grant one save of `instance` with its current, validated payload. */\nexport function grantStoreWrite(instance: { payloadJson: string }): void {\n writes.set(instance, instance.payloadJson);\n}\n\n/** Grant one delete of `instance`. */\nexport function grantStoreDelete(instance: object): void {\n deletes.add(instance);\n}\n\n/** Whether a save of `instance` with `payloadJson` was granted. */\nexport function hasStoreWrite(instance: object, payloadJson: string): boolean {\n return writes.get(instance) === payloadJson;\n}\n\n/** Spend the save grant of `instance`. */\nexport function spendStoreWrite(instance: object): void {\n writes.delete(instance);\n}\n\n/** Spend the delete grant of `instance`; false when there was none. */\nexport function takeStoreDelete(instance: object): boolean {\n return deletes.delete(instance);\n}\n","import {\n crossPackageRef,\n field,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { assertOperationPermission } from '@happyvertical/smrt-users';\nimport {\n PreferenceAccessError,\n requirePreferencePrincipal,\n} from '../context.js';\nimport {\n PREFERENCE_KIND_PATTERN,\n PREFERENCE_SCOPES,\n PREFERENCE_SURFACE_PATTERN,\n type PreferenceScope,\n requirePreferenceKind,\n} from '../kinds.js';\nimport {\n ensurePreferencePermissionsRegistered,\n splitPermissionSlug,\n} from '../permissions.js';\nimport {\n ensurePreferenceReadGuard,\n isPreferenceRowVisible,\n} from '../read-guard.js';\nimport {\n adoptStoreWrite,\n hasStoreWrite,\n spendStoreWrite,\n takeStoreDelete,\n} from '../write-capability.js';\n\n// Direct model imports (tests, server integrations) must still find the\n// built-in slugs in the shared users catalog before any guard asks for them.\nensurePreferencePermissionsRegistered();\n// Collection, query and get reads drop other users' rows (see read-guard.ts).\nensurePreferenceReadGuard();\n\ntype ConstructorOptions = ConstructorParameters<typeof SmrtObject>[0];\ntype SaveOptions = NonNullable<Parameters<SmrtObject['save']>[0]>;\ntype DeleteOptions = NonNullable<Parameters<SmrtObject['delete']>[0]>;\n\n/** `scopeKey` of a tenant-default row (user rows use the user id). */\nexport const TENANT_SCOPE_KEY = '__tenant__';\n\n/**\n * One stored user-interface preference (#3727): the canonical payload of a\n * registered preference kind (`overview`, `shell-layout`, ...) for one surface\n * at one tier of one tenant.\n *\n * - `scopeType: 'tenant'` is the tenant default (`userId` null), written with\n * the kind's tenant permission.\n * - `scopeType: 'user'` is one person's preference on top of the tenant\n * default, inside that tenant. Only that user may write it, with the kind's\n * user permission.\n *\n * Every row carries its tenant, so the table is `@TenantScoped` (required):\n * the tenancy interceptor filters reads and refuses foreign rows, and the\n * save/delete guards below re-check identity, tier ownership and the kind's\n * permission. The kind's validator (run by the store) owns the payload's\n * content; this model owns identity, scope shape and authorization, and\n * refuses any kind that is not registered.\n *\n * No generated surface: a payload is only meaningful after its kind's\n * validation, which a generated route would skip.\n */\n@TenantScoped({ mode: 'required' })\n@smrt({\n tableName: '_smrt_ui_preferences',\n conflictColumns: [\n 'tenant_id',\n 'kind',\n 'surface_id',\n 'scope_type',\n 'scope_key',\n ],\n api: { include: [] },\n cli: false,\n mcp: { include: [] },\n})\nexport class UiPreferenceRecord extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-preferences\";\n /** Owning tenant (native UUID on PostgreSQL/DuckDB). */\n @tenantId()\n tenantId: string = '';\n\n /** The registered preference kind (`overview`, `shell-layout`, ...). */\n @field({ required: true })\n kind: string = '';\n\n /** The surface within the kind (an overview id, a shell key). */\n @field({ required: true })\n surfaceId: string = '';\n\n /** `tenant` (the tenant default) or `user` (one person's preference). */\n @field({ required: true })\n scopeType: PreferenceScope = 'tenant';\n\n /** The owning user of a user-scope row; NULL on the tenant default. */\n @crossPackageRef('@happyvertical/smrt-users:User', { nullable: true })\n userId: string | null = null;\n\n /**\n * `userId ?? '__tenant__'`, set on save. Keeps the `conflictColumns`\n * unique index total while `userId` is nullable (NULLs are distinct in a\n * unique index). Kept in lockstep with\n * `scopeType` / `userId` on every write, so the owner read predicate\n * (`read-guard.ts`) can filter on it in one condition.\n */\n @field({ type: 'text', required: true })\n scopeKey: string = '';\n\n /** The kind's canonical payload as JSON text. */\n @field({ type: 'text', required: true })\n payloadJson: string = '';\n\n /** The kind's format version the payload was written at. */\n @field({ type: 'integer' })\n formatVersion: number = 1;\n\n /** Who last wrote the row; stamped from the ambient principal. */\n @crossPackageRef('@happyvertical/smrt-users:User', { nullable: true })\n updatedBy: string | null = null;\n\n constructor(options: ConstructorOptions = {}) {\n super(options);\n adoptStoreWrite(this, options);\n }\n\n /**\n * Single-row hydration (`new UiPreferenceRecord({ id }).initialize()`)\n * reads the table directly, outside the collection interceptors, so the\n * owner check runs here: another user's row is wiped and refused.\n */\n override async loadFromId(): Promise<void> {\n await super.loadFromId();\n this.assertReadable();\n }\n\n override async loadFromSlug(): Promise<void> {\n await super.loadFromSlug();\n this.assertReadable();\n }\n\n private assertReadable(): void {\n if (!this.kind || isPreferenceRowVisible(this)) return;\n this.payloadJson = '';\n throw new PreferenceAccessError(\n 'A personal preference can only be read by its owner',\n );\n }\n\n /** The stored payload, parsed. `undefined` when the text is not JSON. */\n getPayload(): unknown {\n try {\n return JSON.parse(this.payloadJson);\n } catch {\n return undefined;\n }\n }\n\n /** Store a payload; the caller passes the kind's canonical value. */\n setPayload(value: unknown): void {\n this.payloadJson = JSON.stringify(value);\n }\n\n /** The optimistic-concurrency token a client echoes back on save. */\n get revision(): string | null {\n const at = this.updated_at;\n if (!at) return null;\n const date = at instanceof Date ? at : new Date(at as string);\n return Number.isNaN(date.getTime()) ? null : date.toISOString();\n }\n\n override async save(options: SaveOptions = {}): Promise<this> {\n const principal = requirePreferencePrincipal();\n if (!this.tenantId) this.tenantId = principal.tenantId;\n this.syncScopeKey();\n await this.assertPersistedIdentityUnchanged();\n this.assertStoreWrite();\n this.validateShape();\n await this.authorize();\n this.updatedBy = principal.userId ?? null;\n try {\n return await super.save(options);\n } finally {\n spendStoreWrite(this);\n }\n }\n\n /**\n * Runs for ordinary saves and bulk creates alike, so a collection-level\n * bulk insert is refused too (`save()` checks first so callers see it).\n */\n protected override async validateBeforeSave(): Promise<void> {\n await super.validateBeforeSave();\n this.assertStoreWrite();\n }\n\n override async delete(options: DeleteOptions = {}): Promise<void> {\n if (!takeStoreDelete(this)) {\n throw new PreferenceAccessError(\n 'Preferences are reset only through the preference store',\n );\n }\n // Recomputed from the in-memory owner, so a row whose userId was edited\n // before delete() no longer matches its stored identity and is refused.\n this.syncScopeKey();\n await this.assertPersistedIdentityUnchanged();\n await this.authorize();\n return super.delete(options);\n }\n\n /**\n * Only the store, after the kind's validator accepted exactly this\n * payload, may write a row (see `write-capability.ts`).\n */\n private assertStoreWrite(): void {\n if (!hasStoreWrite(this, this.payloadJson)) {\n throw new PreferenceAccessError(\n 'Preferences are written only through the preference store, which validates them',\n );\n }\n }\n\n private syncScopeKey(): void {\n if (this.scopeType === 'tenant' && this.userId === null) {\n this.scopeKey = TENANT_SCOPE_KEY;\n } else if (this.scopeType === 'user' && this.userId) {\n this.scopeKey = this.userId;\n }\n }\n\n private validateShape(): void {\n if (!PREFERENCE_KIND_PATTERN.test(this.kind)) {\n throw new Error('UiPreferenceRecord.kind is not a valid kind id');\n }\n if (!PREFERENCE_SURFACE_PATTERN.test(this.surfaceId)) {\n throw new Error('UiPreferenceRecord.surfaceId is not a valid id');\n }\n if (!PREFERENCE_SCOPES.includes(this.scopeType)) {\n throw new Error('UiPreferenceRecord.scopeType must be tenant or user');\n }\n if (this.scopeType === 'tenant' && this.userId !== null) {\n throw new Error('A tenant-default preference row has no userId');\n }\n if (this.scopeType === 'user' && !this.userId) {\n throw new Error('A user preference row needs its userId');\n }\n if (!Number.isSafeInteger(this.formatVersion) || this.formatVersion < 1) {\n throw new Error('UiPreferenceRecord.formatVersion must be positive');\n }\n if (this.getPayload() === undefined) {\n throw new Error('UiPreferenceRecord.payloadJson must be JSON');\n }\n }\n\n /**\n * Fail-closed tier guard. The tenant must be the principal's (the\n * interceptor checks this too; a super-admin bypass does not filter reads,\n * so it is re-checked here), a user row must belong to the principal (a\n * principal with no user id may not touch the user tier), the kind must be\n * registered, and its permission for the tier must be held.\n */\n private async authorize(): Promise<void> {\n const principal = requirePreferencePrincipal();\n const kind = requirePreferenceKind(this.kind);\n if (this.tenantId !== principal.tenantId) {\n throw new PreferenceAccessError(\n 'This preference belongs to another tenant',\n );\n }\n if (this.scopeType === 'user') {\n if (!principal.userId || this.userId !== principal.userId) {\n throw new PreferenceAccessError(\n 'A personal preference can only be changed by its owner',\n );\n }\n }\n const slug =\n this.scopeType === 'user'\n ? kind.permissions.user\n : kind.permissions.tenant;\n await assertOperationPermission({\n ...splitPermissionSlug(slug),\n db: this.options.db ?? this.options.persistence,\n tenantId: principal.tenantId,\n userId: principal.userId ?? null,\n permissionSet: principal.permissions,\n });\n }\n\n /**\n * A persisted row keeps its identity: the stored tenant, kind, surface and\n * tier must be the ones in memory, so {@link authorize} always judges the\n * row as stored. Matched by predicate rather than by reading the columns\n * back, because DuckDB returns raw UUID columns as lossy HUGEINTs.\n */\n private async assertPersistedIdentityUnchanged(): Promise<void> {\n if (!this.id) return;\n const byId = await this.db.get(this.tableName, { id: this.id });\n if (!byId) return;\n const same = await this.db.get(this.tableName, {\n id: this.id,\n tenant_id: this.tenantId,\n kind: this.kind,\n surface_id: this.surfaceId,\n scope_type: this.scopeType,\n scope_key: this.scopeKey,\n });\n if (!same) {\n throw new PreferenceAccessError(\n 'A preference row cannot change its tenant, kind, surface or owner',\n );\n }\n }\n}\n","import { SmrtCollection } from '@happyvertical/smrt-core';\nimport type { PreferenceScope } from '../kinds.js';\nimport {\n TENANT_SCOPE_KEY,\n UiPreferenceRecord,\n} from '../models/UiPreferenceRecord.js';\n\n/**\n * Reads of {@link UiPreferenceRecord}. Not decorated: the model has no\n * generated surface, so a decorated collection would only add a second\n * manifest schema for the same table.\n */\nexport class UiPreferenceRecordCollection extends SmrtCollection<UiPreferenceRecord> {\n static readonly _itemClass = UiPreferenceRecord;\n\n /**\n * The row of one tier, or `null`. The tenant predicate is explicit (not\n * only the interceptor's) because a super-admin bypass context does not\n * filter reads.\n */\n async findTier(\n tenantId: string,\n kind: string,\n surfaceId: string,\n scope: PreferenceScope,\n userId?: string,\n ): Promise<UiPreferenceRecord | null> {\n const scopeKey = scope === 'tenant' ? TENANT_SCOPE_KEY : userId;\n if (!scopeKey) return null;\n const rows = await this.list({\n where: { tenantId, kind, surfaceId, scopeType: scope, scopeKey },\n limit: 1,\n });\n return rows[0] ?? null;\n }\n}\n","/**\n * The generic user-interface preference store (#3727).\n *\n * Two tiers per `(kind, surfaceId)`: the tenant default and the principal's\n * own preference. Every call names a registered kind; the kind validates the\n * payload strictly on save (only its canonical form is stored) and leniently\n * on load (invalid parts are dropped and reported, the row is never\n * rewritten), and names the permission for each tier. Identity always comes\n * from the ambient principal.\n */\nimport { RuntimeError } from '@happyvertical/smrt-core';\nimport './kinds/builtin.js';\nimport { checkOperationPermission } from '@happyvertical/smrt-users';\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport { UiPreferenceRecordCollection } from './collections/UiPreferenceRecordCollection.js';\nimport {\n type PreferencePrincipal,\n requirePreferencePrincipal,\n withPrincipal,\n} from './context.js';\nimport {\n PREFERENCE_SURFACE_PATTERN,\n type PreferenceIssue,\n type PreferenceKindDefinition,\n type PreferenceScope,\n requirePreferenceKind,\n} from './kinds.js';\nimport type { UiPreferenceRecord } from './models/UiPreferenceRecord.js';\nimport { splitPermissionSlug } from './permissions.js';\nimport { ensurePreferenceReadGuard } from './read-guard.js';\nimport {\n grantStoreDelete,\n grantStoreWrite,\n storeWriteOption,\n} from './write-capability.js';\n\n/** One stored tier, validated for use. */\nexport interface PreferenceTier {\n /** The kind's canonical payload, invalid parts removed; `null` = none. */\n payload: unknown | null;\n /** Concurrency token: echo it back on save or reset; `null` = no row. */\n revision: string | null;\n /** What was dropped from the stored payload on load, and why. */\n issues: PreferenceIssue[];\n}\n\nexport interface PreferenceState {\n kind: string;\n surfaceId: string;\n /** The tenant default. */\n tenant: PreferenceTier;\n /** The principal's own preference; `null` without a user. */\n user: PreferenceTier | null;\n /** Every tier's issues, tenant first. */\n issues: PreferenceIssue[];\n /** Whether the principal may write each tier (the kind's permission pair). */\n canCustomize: { tenant: boolean; user: boolean };\n}\n\nexport type PreferenceWriteFailure =\n | { ok: false; reason: 'not_allowed' }\n | { ok: false; reason: 'conflict' }\n | { ok: false; reason: 'invalid'; issues: PreferenceIssue[] };\n\nexport type PreferenceSaveResult =\n | { ok: true; payload: unknown | null; revision: string | null }\n | PreferenceWriteFailure;\n\nexport type PreferenceResetResult = { ok: true } | PreferenceWriteFailure;\n\nexport interface PreferenceLoadInput {\n /** Kind-specific validation inputs (passed to `validate` as `options`). */\n options?: unknown;\n}\n\nexport interface PreferenceSaveInput extends PreferenceLoadInput {\n scope: PreferenceScope;\n /** The client's payload (untrusted). `null` resets the tier. */\n payload: unknown;\n /**\n * The `revision` the client loaded for this tier (`null` when it loaded no\n * row). A stale revision fails with `conflict`, never overwrites.\n */\n revision: string | null;\n}\n\nexport interface PreferenceResetInput {\n scope: PreferenceScope;\n /**\n * The revision the client loaded: a string guards the delete, `null`\n * (\"I loaded no row\") conflicts when a row exists, and omitting it resets\n * regardless.\n */\n revision?: string | null;\n}\n\nexport interface PreferenceStoreOptions {\n db: DatabaseInterface;\n}\n\nexport interface PreferenceStore {\n /** Read and validate both tiers of `(kind, surfaceId)` for the principal. */\n load(\n kind: string,\n surfaceId: string,\n input?: PreferenceLoadInput,\n ): Promise<PreferenceState>;\n /** Validate and store one tier's payload (canonical form only). */\n save(\n kind: string,\n surfaceId: string,\n input: PreferenceSaveInput,\n ): Promise<PreferenceSaveResult>;\n /** Delete one tier's row, returning that tier to the tier below. */\n reset(\n kind: string,\n surfaceId: string,\n input: PreferenceResetInput,\n ): Promise<PreferenceResetResult>;\n}\n\nfunction isRevisionConflict(error: unknown): boolean {\n return (\n error instanceof RuntimeError && error.code === 'RUNTIME_REVISION_CONFLICT'\n );\n}\n\nfunction assertSurfaceId(surfaceId: string): void {\n if (!PREFERENCE_SURFACE_PATTERN.test(surfaceId)) {\n throw new Error(`Invalid preference surface id \"${surfaceId}\"`);\n }\n}\n\nasync function holds(\n principal: PreferencePrincipal,\n slug: string,\n db: DatabaseInterface,\n): Promise<boolean> {\n const decision = await checkOperationPermission({\n ...splitPermissionSlug(slug),\n db,\n tenantId: principal.tenantId,\n userId: principal.userId ?? null,\n permissionSet: principal.permissions,\n onDeny: 'return',\n });\n return decision.allowed;\n}\n\nasync function canWrite(\n principal: PreferencePrincipal,\n kind: PreferenceKindDefinition,\n scope: PreferenceScope,\n db: DatabaseInterface,\n): Promise<boolean> {\n if (scope === 'user') {\n return (\n Boolean(principal.userId) &&\n (await holds(principal, kind.permissions.user, db))\n );\n }\n return holds(principal, kind.permissions.tenant, db);\n}\n\n/** Validate one stored row for use (lenient). */\nfunction readTier(\n kind: PreferenceKindDefinition,\n surfaceId: string,\n scope: PreferenceScope,\n row: UiPreferenceRecord | null,\n options: unknown,\n tenant?: unknown | null,\n): PreferenceTier {\n if (!row) {\n return { payload: null, revision: null, issues: [] };\n }\n const revision = row.revision;\n const payload = row.getPayload();\n if (payload === undefined) {\n return {\n payload: null,\n revision,\n issues: [\n {\n path: null,\n code: 'malformed',\n message: 'stored payload is not JSON',\n },\n ],\n };\n }\n if (row.formatVersion > kind.formatVersion) {\n return {\n payload: null,\n revision,\n issues: [\n {\n path: null,\n code: 'future_version',\n message: 'stored payload was written by a newer format version',\n },\n ],\n };\n }\n let checked: ReturnType<PreferenceKindDefinition['validate']>;\n try {\n checked = kind.validate(payload, {\n kind: kind.kind,\n surfaceId,\n scope,\n phase: 'load',\n formatVersion: row.formatVersion,\n ...(scope === 'user' ? { tenant: tenant ?? null } : {}),\n options,\n });\n } catch {\n // A load must degrade, never fail the page or hand back a payload no\n // validator accepted: the tier is dropped and reported. (A save lets the\n // error propagate: nothing is stored.)\n return {\n payload: null,\n revision,\n issues: [\n {\n path: null,\n code: 'validator_error',\n message: 'the preference kind failed to validate the stored payload',\n },\n ],\n };\n }\n return { payload: checked.canonical, revision, issues: checked.issues };\n}\n\n/**\n * The generic preference store. One per database; every call acts as the\n * ambient principal and names a registered kind.\n */\nexport function createPreferenceStore(\n options: PreferenceStoreOptions,\n): PreferenceStore {\n const { db } = options;\n const collection = (): Promise<UiPreferenceRecordCollection> => {\n ensurePreferenceReadGuard();\n return UiPreferenceRecordCollection.create({ db });\n };\n\n async function tenantTier(\n records: UiPreferenceRecordCollection,\n principal: PreferencePrincipal,\n kind: PreferenceKindDefinition,\n surfaceId: string,\n kindOptions: unknown,\n ): Promise<PreferenceTier> {\n const row = await records.findTier(\n principal.tenantId,\n kind.kind,\n surfaceId,\n 'tenant',\n );\n return readTier(kind, surfaceId, 'tenant', row, kindOptions);\n }\n\n return {\n async load(kindId, surfaceId, input = {}) {\n const kind = requirePreferenceKind(kindId);\n assertSurfaceId(surfaceId);\n const principal = requirePreferencePrincipal();\n return withPrincipal(principal, async () => {\n const records = await collection();\n const tenant = await tenantTier(\n records,\n principal,\n kind,\n surfaceId,\n input.options,\n );\n const userRow = principal.userId\n ? await records.findTier(\n principal.tenantId,\n kind.kind,\n surfaceId,\n 'user',\n principal.userId,\n )\n : null;\n const user = principal.userId\n ? readTier(\n kind,\n surfaceId,\n 'user',\n userRow,\n input.options,\n tenant.payload,\n )\n : null;\n const [tenantWrite, userWrite] = await Promise.all([\n canWrite(principal, kind, 'tenant', db),\n canWrite(principal, kind, 'user', db),\n ]);\n return {\n kind: kind.kind,\n surfaceId,\n tenant,\n user,\n issues: [...tenant.issues, ...(user?.issues ?? [])],\n canCustomize: { tenant: tenantWrite, user: userWrite },\n };\n });\n },\n\n async save(kindId, surfaceId, input) {\n const kind = requirePreferenceKind(kindId);\n assertSurfaceId(surfaceId);\n const principal = requirePreferencePrincipal();\n return withPrincipal(principal, async () => {\n if (!(await canWrite(principal, kind, input.scope, db))) {\n return { ok: false, reason: 'not_allowed' };\n }\n const records = await collection();\n const tenant =\n input.scope === 'user'\n ? (\n await tenantTier(\n records,\n principal,\n kind,\n surfaceId,\n input.options,\n )\n ).payload\n : undefined;\n const checked = kind.validate(input.payload, {\n kind: kind.kind,\n surfaceId,\n scope: input.scope,\n phase: 'save',\n formatVersion: kind.formatVersion,\n ...(input.scope === 'user' ? { tenant: tenant ?? null } : {}),\n options: input.options,\n });\n if (!checked.ok) {\n return { ok: false, reason: 'invalid', issues: checked.issues };\n }\n const canonical = checked.canonical ?? null;\n const userId = input.scope === 'user' ? principal.userId : undefined;\n const existing = await records.findTier(\n principal.tenantId,\n kind.kind,\n surfaceId,\n input.scope,\n userId,\n );\n const revision = input.revision ?? null;\n if (canonical === null) {\n // Back on the tier below: store nothing.\n if (!existing) {\n return revision === null\n ? { ok: true, payload: null, revision: null }\n : { ok: false, reason: 'conflict' };\n }\n if (revision === null) return { ok: false, reason: 'conflict' };\n try {\n grantStoreDelete(existing);\n await existing.delete({ expectedUpdatedAt: revision });\n } catch (error) {\n if (isRevisionConflict(error)) {\n return { ok: false, reason: 'conflict' };\n }\n throw error;\n }\n return { ok: true, payload: null, revision: null };\n }\n if (existing) {\n if (revision === null) return { ok: false, reason: 'conflict' };\n existing.setPayload(canonical);\n existing.formatVersion = kind.formatVersion;\n grantStoreWrite(existing);\n try {\n await existing.save({ expectedUpdatedAt: revision });\n } catch (error) {\n if (isRevisionConflict(error)) {\n return { ok: false, reason: 'conflict' };\n }\n throw error;\n }\n return { ok: true, payload: canonical, revision: existing.revision };\n }\n if (revision !== null) return { ok: false, reason: 'conflict' };\n try {\n const created = await records.create({\n tenantId: principal.tenantId,\n kind: kind.kind,\n surfaceId,\n scopeType: input.scope,\n userId: userId ?? null,\n payloadJson: JSON.stringify(canonical),\n formatVersion: kind.formatVersion,\n _insertOnly: true,\n ...storeWriteOption(),\n } as Parameters<UiPreferenceRecordCollection['create']>[0]);\n return { ok: true, payload: canonical, revision: created.revision };\n } catch (error) {\n // A concurrent first write took the natural key: the strict insert\n // refuses instead of overwriting it.\n const raced = await records.findTier(\n principal.tenantId,\n kind.kind,\n surfaceId,\n input.scope,\n userId,\n );\n if (raced) return { ok: false, reason: 'conflict' };\n throw error;\n }\n });\n },\n\n async reset(kindId, surfaceId, input) {\n const kind = requirePreferenceKind(kindId);\n assertSurfaceId(surfaceId);\n const principal = requirePreferencePrincipal();\n return withPrincipal(principal, async () => {\n if (!(await canWrite(principal, kind, input.scope, db))) {\n return { ok: false, reason: 'not_allowed' };\n }\n const records = await collection();\n const existing = await records.findTier(\n principal.tenantId,\n kind.kind,\n surfaceId,\n input.scope,\n input.scope === 'user' ? principal.userId : undefined,\n );\n if (!existing) return { ok: true };\n // `null` means \"I loaded no row\", exactly as on save: a row that\n // exists now was written after that load, so deleting it would lose\n // a newer change. Only an omitted revision resets unguarded.\n if (input.revision === null) return { ok: false, reason: 'conflict' };\n try {\n grantStoreDelete(existing);\n await existing.delete(\n typeof input.revision === 'string'\n ? { expectedUpdatedAt: input.revision }\n : {},\n );\n } catch (error) {\n if (isRevisionConflict(error)) {\n return { ok: false, reason: 'conflict' };\n }\n throw error;\n }\n return { ok: true };\n });\n },\n };\n}\n","/**\n * The overview layer (#3727 phase 3): overview-shaped load, save, reset,\n * page load and widget load over the generic preference store, kind\n * `overview`, surface id = `OverviewDefinition.id`.\n *\n * Tiers, low to high: the page's `definition.defaults`, the tenant default,\n * then the user's override. The tenant tier merges into the defaults first\n * and the user tier applies to that result, so a user override is a delta\n * against the tenant default. Saves are strict (`checkOverviewOverride`, only\n * the canonical override is stored); loads are lenient (a bad entry is\n * dropped and reported, the rest render).\n */\nimport {\n type LoadedOverview,\n type LoadOverviewOptions,\n loadOverview,\n type OverviewDefinition,\n type OverviewDocument,\n type OverviewIssue,\n type OverviewOverride,\n optionsEqual,\n parseOverviewDocument,\n resolveOverview,\n sanitizeOverview,\n type WidgetLoadInput,\n type WidgetRegistry,\n} from '@happyvertical/smrt-svelte/overview/server';\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport {\n OVERVIEW_PREFERENCE_KIND,\n type OverviewKindOptions,\n toOverviewIssue,\n withTenantDefaults,\n} from './kinds/overview.js';\nimport type { PreferenceScope } from './kinds.js';\nimport { createPreferenceStore, type PreferenceStore } from './store.js';\n\n/** One stored tier, resolved. */\nexport interface OverviewTierState {\n /** The document this tier applies to (sanitized). */\n base: OverviewDocument;\n /** The document after this tier (sanitized). */\n document: OverviewDocument;\n /** The stored override, canonical with invalid entries removed, or `null`. */\n override: OverviewOverride | null;\n /** Concurrency token: echo it back on save or reset; `null` = no row. */\n revision: string | null;\n /** Entries of the stored override dropped on load, and why. */\n issues: OverviewIssue[];\n}\n\n/** What a page load needs to render and edit one overview. */\nexport interface OverviewState {\n overviewId: string;\n /** The tenant default over `definition.defaults`. */\n tenant: OverviewTierState;\n /** The user's override over the tenant default; `null` without a user. */\n user: OverviewTierState | null;\n /** What the principal sees: the user tier's document, else the tenant's. */\n document: OverviewDocument;\n /** Every stored-tier issue (tenant first). Page-default issues excluded. */\n issues: OverviewIssue[];\n /** Feed `createOverview({ canCustomize })` for the tier being edited. */\n canCustomize: { tenant: boolean; user: boolean };\n}\n\nexport type OverviewWriteFailure =\n | { ok: false; reason: 'not_allowed' }\n | { ok: false; reason: 'conflict' }\n | { ok: false; reason: 'invalid'; issues: OverviewIssue[] };\n\nexport type OverviewSaveResult =\n | { ok: true; override: OverviewOverride | null; revision: string | null }\n | OverviewWriteFailure;\n\nexport type OverviewResetResult = { ok: true } | OverviewWriteFailure;\n\nexport interface OverviewSaveInput {\n scope: PreferenceScope;\n /** The client's override (untrusted). `null` resets the tier. */\n override: unknown;\n /**\n * The `revision` the client loaded for this tier (`null` when it loaded no\n * row). A stale revision fails with `conflict`, never overwrites.\n */\n revision: string | null;\n}\n\nexport interface OverviewResetInput {\n scope: PreferenceScope;\n /**\n * The revision the client loaded: a string guards the delete, `null`\n * conflicts when a row exists, and omitting it resets regardless.\n */\n revision?: string | null;\n}\n\nexport interface OverviewPageOptions extends LoadOverviewOptions {\n /** Which tier's document to load: `user` (default) or `tenant` (editing defaults). */\n scope?: PreferenceScope;\n}\n\nexport type OverviewWidgetResult =\n | { ok: true; data: unknown }\n | { ok: false; reason: 'not_allowed' }\n | { ok: false; reason: 'invalid'; issues: OverviewIssue[] }\n | {\n ok: false;\n reason: 'load_failed';\n code: 'load_failed' | 'timeout' | 'invalid_data';\n };\n\nexport interface OverviewStoreOptions {\n db: DatabaseInterface;\n /** Share a generic store (default: one over `db`). */\n preferences?: PreferenceStore;\n}\n\nexport interface OverviewStore {\n /** Read both tiers for the principal and resolve the merge. */\n load(\n definition: OverviewDefinition,\n registry: WidgetRegistry,\n ): Promise<OverviewState>;\n /** Validate and store one tier's override (canonical form only). */\n save(\n definition: OverviewDefinition,\n registry: WidgetRegistry,\n input: OverviewSaveInput,\n ): Promise<OverviewSaveResult>;\n /** Delete one tier's row, returning that tier to the tier below. */\n reset(\n definition: OverviewDefinition,\n input: OverviewResetInput,\n ): Promise<OverviewResetResult>;\n /** `load` plus `loadOverview`, for a page's server load. */\n loadPage(\n definition: OverviewDefinition,\n registry: WidgetRegistry,\n ctx: WidgetLoadInput,\n options?: OverviewPageOptions,\n ): Promise<OverviewState & { loaded: LoadedOverview }>;\n /** The data of one widget, for the controller's `loadWidget` remote function. */\n loadWidget(\n definition: OverviewDefinition,\n registry: WidgetRegistry,\n widget: unknown,\n ctx: WidgetLoadInput,\n options?: LoadOverviewOptions,\n ): Promise<OverviewWidgetResult>;\n}\n\nfunction sameWidget(\n a: OverviewDocument['widgets'][number],\n b: OverviewDocument['widgets'][number],\n): boolean {\n return (\n a.id === b.id &&\n a.type === b.type &&\n (a.version ?? 1) === (b.version ?? 1) &&\n optionsEqual(a.options, b.options)\n );\n}\n\n/**\n * The persistence and server-load API of overview surfaces. Every call acts\n * as the ambient principal.\n */\nexport function createOverviewStore(\n options: OverviewStoreOptions,\n): OverviewStore {\n const preferences =\n options.preferences ?? createPreferenceStore({ db: options.db });\n const kindOptions = (\n definition: OverviewDefinition,\n registry: WidgetRegistry,\n ): OverviewKindOptions => ({ definition, registry });\n\n const store: OverviewStore = {\n async load(definition, registry) {\n const state = await preferences.load(\n OVERVIEW_PREFERENCE_KIND,\n definition.id,\n { options: kindOptions(definition, registry) },\n );\n const tenantOverride = state.tenant.payload as OverviewOverride | null;\n const tenantResolved = resolveOverview(\n definition,\n tenantOverride,\n registry,\n );\n const tenant: OverviewTierState = {\n base: tenantResolved.base,\n document: tenantResolved.document,\n override: tenantOverride,\n revision: state.tenant.revision,\n issues: state.tenant.issues.map(toOverviewIssue),\n };\n let user: OverviewTierState | null = null;\n if (state.user) {\n const userOverride = state.user.payload as OverviewOverride | null;\n const userResolved = resolveOverview(\n withTenantDefaults(definition, tenant.document),\n userOverride,\n registry,\n );\n user = {\n base: userResolved.base,\n document: userResolved.document,\n override: userOverride,\n revision: state.user.revision,\n issues: state.user.issues.map(toOverviewIssue),\n };\n }\n return {\n overviewId: definition.id,\n tenant,\n user,\n document: user?.document ?? tenant.document,\n issues: [...tenant.issues, ...(user?.issues ?? [])],\n canCustomize: state.canCustomize,\n };\n },\n\n async save(definition, registry, input) {\n const result = await preferences.save(\n OVERVIEW_PREFERENCE_KIND,\n definition.id,\n {\n scope: input.scope,\n payload: input.override,\n revision: input.revision,\n options: kindOptions(definition, registry),\n },\n );\n if (result.ok) {\n return {\n ok: true,\n override: result.payload as OverviewOverride | null,\n revision: result.revision,\n };\n }\n if (result.reason === 'invalid') {\n return {\n ok: false,\n reason: 'invalid',\n issues: result.issues.map(toOverviewIssue),\n };\n }\n return result;\n },\n\n async reset(definition, input) {\n const result = await preferences.reset(\n OVERVIEW_PREFERENCE_KIND,\n definition.id,\n input,\n );\n if (!result.ok && result.reason === 'invalid') {\n return {\n ok: false,\n reason: 'invalid',\n issues: result.issues.map(toOverviewIssue),\n };\n }\n return result as OverviewResetResult;\n },\n\n async loadPage(definition, registry, ctx, pageOptions = {}) {\n const { scope = 'user', ...loadOptions } = pageOptions;\n const state = await store.load(definition, registry);\n const document =\n scope === 'tenant' ? state.tenant.document : state.document;\n const loaded = await loadOverview(\n document,\n definition,\n registry,\n ctx,\n loadOptions,\n );\n return { ...state, loaded };\n },\n\n async loadWidget(definition, registry, widget, ctx, loadOptions = {}) {\n const state = await store.load(definition, registry);\n const parsed = parseOverviewDocument({ widgets: [widget] });\n const candidate = parsed.document.widgets[0];\n if (!candidate || parsed.issues.length > 0) {\n return { ok: false, reason: 'invalid', issues: parsed.issues };\n }\n // A viewer may reload a widget that is on their overview; loading any\n // other widget (an add or a reconfigure in progress) needs a customize\n // permission on some tier, like the save it precedes.\n const onPage = [\n ...state.document.widgets,\n ...state.tenant.document.widgets,\n ].some((existing) => sameWidget(existing, candidate));\n if (!onPage && !state.canCustomize.tenant && !state.canCustomize.user) {\n return { ok: false, reason: 'not_allowed' };\n }\n const sanitized = sanitizeOverview(\n { widgets: [candidate] },\n { registry, definition },\n );\n if (sanitized.issues.length > 0) {\n return { ok: false, reason: 'invalid', issues: sanitized.issues };\n }\n const loaded = await loadOverview(\n sanitized.document,\n definition,\n registry,\n ctx,\n loadOptions,\n );\n const result = loaded.widgets[0];\n if (!result) return { ok: false, reason: 'invalid', issues: [] };\n if (result.status === 'error') {\n return {\n ok: false,\n reason: 'load_failed',\n code: result.error?.code ?? 'load_failed',\n };\n }\n return { ok: true, data: result.data };\n },\n };\n return store;\n}\n"],"mappings":"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"}
|
package/dist/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": "1.0.0",
|
|
3
3
|
"timestamp": 0,
|
|
4
4
|
"packageName": "@happyvertical/smrt-preferences",
|
|
5
|
-
"packageVersion": "0.57.
|
|
5
|
+
"packageVersion": "0.57.4",
|
|
6
6
|
"objects": {
|
|
7
7
|
"@happyvertical/smrt-preferences:UiPreferenceRecordCollection": {
|
|
8
8
|
"name": "uipreferencerecordcollection",
|
package/dist/smrt-knowledge.json
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
"sensitiveFieldsExcluded": true,
|
|
4
4
|
"generatedAt": "1970-01-01T00:00:00.000Z",
|
|
5
5
|
"packageName": "@happyvertical/smrt-preferences",
|
|
6
|
-
"packageVersion": "0.57.
|
|
6
|
+
"packageVersion": "0.57.4",
|
|
7
7
|
"sourceManifestPath": "dist/manifest.json",
|
|
8
8
|
"agentDocPath": "AGENTS.md",
|
|
9
9
|
"sourceHashes": {
|
|
10
|
-
"manifest": "
|
|
11
|
-
"packageJson": "
|
|
10
|
+
"manifest": "a1e0fad122c8dc0a7d1d5011493d8b3e9627badf168207bef73a89fb51980641",
|
|
11
|
+
"packageJson": "6a2d731477a9a6a0066f0232656f36108df416edb564bd60cc2f34964d5a04ca",
|
|
12
12
|
"agents": "ff8ef8173cb499f021a99d03561d2bf50145c010e5a21c989f476caf5698ed30",
|
|
13
13
|
"moduleDoc:agents/preference-kinds.md": "b2e3301b279445a693a95494cd98b0fd791d70fb80e411e0444006c07d259f2a"
|
|
14
14
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-preferences",
|
|
3
|
-
"version": "0.57.
|
|
3
|
+
"version": "0.57.4",
|
|
4
4
|
"description": "Tenant defaults and per-user overrides for user-interface preferences (overview layouts, shell layout), validated per registered kind",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -20,14 +20,14 @@
|
|
|
20
20
|
"./manifest.json": "./dist/manifest.json"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@happyvertical/smrt-core": "0.57.
|
|
24
|
-
"@happyvertical/smrt-svelte": "0.57.
|
|
25
|
-
"@happyvertical/smrt-tenancy": "0.57.
|
|
26
|
-
"@happyvertical/smrt-users": "0.57.
|
|
27
|
-
"@happyvertical/sql": "^0.
|
|
23
|
+
"@happyvertical/smrt-core": "0.57.4",
|
|
24
|
+
"@happyvertical/smrt-svelte": "0.57.4",
|
|
25
|
+
"@happyvertical/smrt-tenancy": "0.57.4",
|
|
26
|
+
"@happyvertical/smrt-users": "0.57.4",
|
|
27
|
+
"@happyvertical/sql": "^0.105.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@happyvertical/smrt-vitest": "0.57.
|
|
30
|
+
"@happyvertical/smrt-vitest": "0.57.4",
|
|
31
31
|
"@types/node": "24.13.6",
|
|
32
32
|
"svelte": "^5.57.1",
|
|
33
33
|
"typescript": "6.0.3",
|