@objectstack/platform-objects 5.1.0 → 6.0.0

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.mjs CHANGED
@@ -3266,6 +3266,20 @@ var defaultPermissionSets = [
3266
3266
  operation: "select",
3267
3267
  using: "id = current_user.id"
3268
3268
  },
3269
+ // Org collaborators: members can see other users in the same
3270
+ // organization. Without this, owner/assignee lookups, @-mention
3271
+ // suggestions, reviewer pickers and team-roster surfaces all
3272
+ // collapse to just the current user. `org_user_ids` is
3273
+ // pre-resolved by runtime/resolve-execution-context from
3274
+ // `sys_member` for the active organization. Sensitive credential
3275
+ // tables (`sys_account`, `sys_session`, `sys_api_key`, …) keep
3276
+ // their stricter self-only carve-outs above.
3277
+ {
3278
+ name: "sys_user_org_members",
3279
+ object: "sys_user",
3280
+ operation: "select",
3281
+ using: "id IN (current_user.org_user_ids)"
3282
+ },
3269
3283
  {
3270
3284
  name: "sys_session_self",
3271
3285
  object: "sys_session",
@@ -3363,8 +3377,14 @@ var defaultPermissionSets = [
3363
3377
  operation: "select",
3364
3378
  using: "id = current_user.id"
3365
3379
  },
3366
- // ── Per-user visibility on better-auth tables that lack
3367
- // `organization_id` (matches the `member_default` carve-outs).
3380
+ // Org collaborators (read-only): see `sys_user_org_members` in
3381
+ // `member_default` for rationale.
3382
+ {
3383
+ name: "sys_user_org_members",
3384
+ object: "sys_user",
3385
+ operation: "select",
3386
+ using: "id IN (current_user.org_user_ids)"
3387
+ },
3368
3388
  {
3369
3389
  name: "sys_session_self",
3370
3390
  object: "sys_session",
@@ -3808,12 +3828,12 @@ var SysActivity = ObjectSchema.create({
3808
3828
  group: "Target"
3809
3829
  }),
3810
3830
  // ── Context ──────────────────────────────────────────────────
3811
- project_id: Field.lookup("sys_project", {
3812
- label: "Project",
3831
+ environment_id: Field.lookup("sys_environment", {
3832
+ label: "Environment",
3813
3833
  required: false,
3814
3834
  readonly: true,
3815
3835
  searchable: true,
3816
- description: "Project context (multi-project deployments)",
3836
+ description: "Environment context (multi-environment deployments)",
3817
3837
  group: "Context"
3818
3838
  }),
3819
3839
  metadata: Field.textarea({
@@ -3829,7 +3849,7 @@ var SysActivity = ObjectSchema.create({
3829
3849
  { fields: ["actor_id"] },
3830
3850
  { fields: ["object_name", "record_id"] },
3831
3851
  { fields: ["type"] },
3832
- { fields: ["project_id"] }
3852
+ { fields: ["environment_id"] }
3833
3853
  ],
3834
3854
  enable: {
3835
3855
  trackHistory: false,
@@ -4091,13 +4111,56 @@ var SysNotification = ObjectSchema.create({
4091
4111
  displayNameField: "title",
4092
4112
  titleFormat: "{title}",
4093
4113
  compactLayout: ["title", "type", "is_read", "created_at"],
4114
+ /**
4115
+ * Row-level inbox actions. Use `visible` CEL expressions to ensure
4116
+ * `mark_read` only shows on unread rows and vice-versa, mirroring the
4117
+ * mark-as-read affordances in GitHub / Linear inboxes. The toolbar-level
4118
+ * `mark_all_read` is intentionally omitted server-side: it requires a
4119
+ * bulk update primitive that doesn't yet exist on the REST surface, and
4120
+ * the popover already handles the multi-row case client-side via N
4121
+ * single-row PATCHes (see `InboxPopover.tsx` -> AppHeader `markAllRead`).
4122
+ */
4123
+ actions: [
4124
+ {
4125
+ name: "mark_read",
4126
+ label: "Mark as Read",
4127
+ icon: "check",
4128
+ variant: "secondary",
4129
+ mode: "custom",
4130
+ locations: ["list_item"],
4131
+ type: "api",
4132
+ method: "PATCH",
4133
+ target: "/api/v1/data/sys_notification/{id}",
4134
+ bodyExtra: { is_read: true },
4135
+ visible: "!record.is_read",
4136
+ successMessage: "Notification marked as read",
4137
+ refreshAfter: true
4138
+ },
4139
+ {
4140
+ name: "mark_unread",
4141
+ label: "Mark as Unread",
4142
+ icon: "bell-dot",
4143
+ variant: "secondary",
4144
+ mode: "custom",
4145
+ locations: ["list_item"],
4146
+ type: "api",
4147
+ method: "PATCH",
4148
+ target: "/api/v1/data/sys_notification/{id}",
4149
+ bodyExtra: { is_read: false, read_at: null },
4150
+ visible: "record.is_read",
4151
+ successMessage: "Notification marked as unread",
4152
+ refreshAfter: true
4153
+ }
4154
+ ],
4094
4155
  listViews: {
4095
4156
  unread: {
4096
4157
  type: "grid",
4097
4158
  name: "unread",
4098
4159
  label: "Unread",
4099
4160
  data: { provider: "object", object: "sys_notification" },
4100
- columns: ["type", "title", "recipient_id", "created_at"],
4161
+ // Title + actor first (the "who/what" the user actually scans);
4162
+ // type stays as a categorising chip; created_at right-aligned.
4163
+ columns: ["title", "actor_name", "type", "created_at"],
4101
4164
  filter: [
4102
4165
  { field: "recipient_id", operator: "equals", value: "{current_user_id}" },
4103
4166
  { field: "is_read", operator: "equals", value: false }
@@ -4111,17 +4174,21 @@ var SysNotification = ObjectSchema.create({
4111
4174
  name: "mine",
4112
4175
  label: "Mine",
4113
4176
  data: { provider: "object", object: "sys_notification" },
4114
- columns: ["type", "title", "is_read", "created_at"],
4177
+ columns: ["title", "actor_name", "type", "is_read", "created_at"],
4115
4178
  filter: [{ field: "recipient_id", operator: "equals", value: "{current_user_id}" }],
4116
4179
  sort: [{ field: "created_at", order: "desc" }],
4117
- pagination: { pageSize: 50 }
4180
+ pagination: { pageSize: 50 },
4181
+ // Group by notification category so mention/assignment storms don't
4182
+ // hide system or task_due rows. Users still toggle to flat via the
4183
+ // toolbar Group control if they prefer chronology only.
4184
+ grouping: { fields: [{ field: "type", order: "asc", collapsed: false }] }
4118
4185
  },
4119
4186
  all_notifications: {
4120
4187
  type: "grid",
4121
4188
  name: "all_notifications",
4122
4189
  label: "All",
4123
4190
  data: { provider: "object", object: "sys_notification" },
4124
- columns: ["type", "title", "recipient_id", "is_read", "created_at"],
4191
+ columns: ["title", "recipient_id", "actor_name", "type", "is_read", "created_at"],
4125
4192
  sort: [{ field: "created_at", order: "desc" }],
4126
4193
  pagination: { pageSize: 100 }
4127
4194
  }
@@ -4974,6 +5041,14 @@ var SysApprovalRequest = ObjectSchema.create({
4974
5041
  description: "Record snapshot at submission time",
4975
5042
  group: "State"
4976
5043
  }),
5044
+ process_hash: Field.text({
5045
+ label: "Process Hash",
5046
+ required: false,
5047
+ maxLength: 80,
5048
+ readonly: true,
5049
+ description: "sha256 of the approval process body at submit time (ADR-0009 execution pinning). Resolved through sys_metadata_history so process upgrades do not affect in-flight requests.",
5050
+ group: "State"
5051
+ }),
4977
5052
  completed_at: Field.datetime({
4978
5053
  label: "Completed At",
4979
5054
  required: false,
@@ -5562,12 +5637,12 @@ var SysMetadataObject = ObjectSchema.create({
5562
5637
  }),
5563
5638
  /**
5564
5639
  * @deprecated ADR-0005 (revised 2026-05): per-env DBs replace per-project
5565
- * isolation. `project_id` is no longer written by saveMetaItem and not
5640
+ * isolation. `environment_id` is no longer written by saveMetaItem and not
5566
5641
  * consulted by overlay reads. Kept for legacy rows; new writes leave it
5567
5642
  * NULL. Will be dropped in a future schema migration.
5568
5643
  */
5569
- project_id: Field.lookup("sys_project", {
5570
- label: "Project (deprecated)",
5644
+ environment_id: Field.lookup("sys_environment", {
5645
+ label: "Environment (deprecated)",
5571
5646
  required: false,
5572
5647
  description: "DEPRECATED. Use organization_id for tenant isolation."
5573
5648
  }),
@@ -5617,7 +5692,7 @@ var SysMetadataObject = ObjectSchema.create({
5617
5692
  indexes: [
5618
5693
  // ADR-0005 (revised 2026-05): overlay uniqueness is scoped by
5619
5694
  // (type, name, organization_id), restricted to active rows so resets
5620
- // / archived versions don't collide. project_id is deprecated and
5695
+ // / archived versions don't collide. environment_id is deprecated and
5621
5696
  // not part of the discriminator. The runtime layer (protocol.ts
5622
5697
  // ensureOverlayIndex) issues a DROP-then-CREATE migration to
5623
5698
  // replace any pre-existing legacy composite index in-place.
@@ -6260,6 +6335,28 @@ var SETUP_APP = {
6260
6335
  { id: "nav_notifications", type: "object", label: "Notifications", objectName: "sys_notification", icon: "bell", requiresObject: "sys_notification" }
6261
6336
  ]
6262
6337
  },
6338
+ {
6339
+ id: "group_integrations",
6340
+ type: "group",
6341
+ label: "Integrations",
6342
+ icon: "plug",
6343
+ children: [
6344
+ // Outbound HTTP integrations. `sys_webhook` always ships with
6345
+ // platform-objects, so the Webhooks entry is always visible.
6346
+ // `sys_webhook_delivery` is the durable outbox row from
6347
+ // `@objectstack/plugin-webhooks/schema` — gated on `requiresObject`
6348
+ // so the Deliveries entry only renders when the plugin has been
6349
+ // wired into `defineStack({ objects: [SysWebhookDelivery, ...] })`.
6350
+ //
6351
+ // This is the canonical demonstration of "everything is an object":
6352
+ // managing webhooks (configuration) and inspecting deliveries
6353
+ // (operational telemetry) reuses the same generic ObjectView /
6354
+ // ObjectListView UI as any business object — no bespoke webhook
6355
+ // admin page.
6356
+ { id: "nav_webhooks", type: "object", label: "Webhooks", objectName: "sys_webhook", icon: "webhook", requiresObject: "sys_webhook" },
6357
+ { id: "nav_webhook_deliveries", type: "object", label: "Webhook Deliveries", objectName: "sys_webhook_delivery", icon: "send", requiresObject: "sys_webhook_delivery" }
6358
+ ]
6359
+ },
6263
6360
  {
6264
6361
  id: "group_advanced",
6265
6362
  type: "group",
@@ -6283,7 +6380,7 @@ var SETUP_APP = {
6283
6380
  // - The marketplace-only `sys_app` / `sys_package` /
6284
6381
  // `sys_package_installation` menus have been removed entirely;
6285
6382
  // they are contributed by `@objectstack/service-tenant`
6286
- // (control-plane) and are not present in single-project runtimes.
6383
+ // (control-plane) and are not present in single-environment runtimes.
6287
6384
  { id: "nav_oauth_apps", type: "object", label: "OAuth Applications", objectName: "sys_oauth_application", icon: "app-window" },
6288
6385
  { id: "nav_jwks", type: "object", label: "Signing Keys (JWKS)", objectName: "sys_jwks", icon: "key-round" },
6289
6386
  { id: "nav_verifications", type: "object", label: "Verifications", objectName: "sys_verification", icon: "mail-check" },
@@ -6362,7 +6459,7 @@ var SystemOverviewDashboard = Dashboard.create({
6362
6459
  type: "metric",
6363
6460
  object: "sys_package_installation",
6364
6461
  // Cloud-only object — only registered when service-tenant is loaded.
6365
- // Hide this widget gracefully in single-project runtimes.
6462
+ // Hide this widget gracefully in single-environment runtimes.
6366
6463
  requiresObject: "sys_package_installation",
6367
6464
  layout: {
6368
6465
  x: 9,
@@ -8214,9 +8311,9 @@ var enObjects = {
8214
8311
  label: "URL",
8215
8312
  help: "Optional deep-link to the activity target"
8216
8313
  },
8217
- project_id: {
8314
+ environment_id: {
8218
8315
  label: "Project",
8219
- help: "Project context (multi-project deployments)"
8316
+ help: "Environment context (multi-environment deployments)"
8220
8317
  },
8221
8318
  metadata: {
8222
8319
  label: "Metadata",
@@ -9209,7 +9306,7 @@ var enObjects = {
9209
9306
  label: "Organization",
9210
9307
  help: "Organization for multi-tenant isolation."
9211
9308
  },
9212
- project_id: {
9309
+ environment_id: {
9213
9310
  label: "Project (deprecated)",
9214
9311
  help: "DEPRECATED. Use organization_id for tenant isolation."
9215
9312
  },
@@ -9291,7 +9388,7 @@ var enObjects = {
9291
9388
  label: "Organization",
9292
9389
  help: "Organization for multi-tenant isolation."
9293
9390
  },
9294
- project_id: {
9391
+ environment_id: {
9295
9392
  label: "Environment ID",
9296
9393
  help: "Scopes this history entry to a specific environment."
9297
9394
  },
@@ -11249,7 +11346,7 @@ var zhCNObjects = {
11249
11346
  label: "URL",
11250
11347
  help: "\u6307\u5411\u6D3B\u52A8\u76EE\u6807\u7684\u53EF\u9009\u6DF1\u5EA6\u94FE\u63A5"
11251
11348
  },
11252
- project_id: {
11349
+ environment_id: {
11253
11350
  label: "\u9879\u76EE",
11254
11351
  help: "\u9879\u76EE\u4E0A\u4E0B\u6587\uFF08\u591A\u9879\u76EE\u90E8\u7F72\uFF09"
11255
11352
  },
@@ -12248,7 +12345,7 @@ var zhCNObjects = {
12248
12345
  label: "\u7EC4\u7EC7",
12249
12346
  help: "\u7528\u4E8E\u591A\u79DF\u6237\u9694\u79BB\u7684\u7EC4\u7EC7\u3002"
12250
12347
  },
12251
- project_id: {
12348
+ environment_id: {
12252
12349
  label: "\u9879\u76EE\uFF08\u5DF2\u5E9F\u5F03\uFF09",
12253
12350
  help: "\u5DF2\u5E9F\u5F03\u3002\u8BF7\u4F7F\u7528 organization_id \u8FDB\u884C\u79DF\u6237\u9694\u79BB\u3002"
12254
12351
  },
@@ -12330,7 +12427,7 @@ var zhCNObjects = {
12330
12427
  label: "\u7EC4\u7EC7",
12331
12428
  help: "\u7528\u4E8E\u591A\u79DF\u6237\u9694\u79BB\u7684\u7EC4\u7EC7\u3002"
12332
12429
  },
12333
- project_id: {
12430
+ environment_id: {
12334
12431
  label: "\u73AF\u5883 ID",
12335
12432
  help: "\u5C06\u8BE5\u5386\u53F2\u8BB0\u5F55\u9650\u5B9A\u5230\u7279\u5B9A\u73AF\u5883\u3002"
12336
12433
  },
@@ -14238,7 +14335,7 @@ var jaJPObjects = {
14238
14335
  label: "URL",
14239
14336
  help: "\u30A2\u30AF\u30C6\u30A3\u30D3\u30C6\u30A3\u30BF\u30FC\u30B2\u30C3\u30C8\u3078\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30C7\u30A3\u30FC\u30D7\u30EA\u30F3\u30AF"
14240
14337
  },
14241
- project_id: {
14338
+ environment_id: {
14242
14339
  label: "\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8",
14243
14340
  help: "\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\uFF08\u30DE\u30EB\u30C1\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u30C7\u30D7\u30ED\u30A4\u30E1\u30F3\u30C8\uFF09"
14244
14341
  },
@@ -15233,7 +15330,7 @@ var jaJPObjects = {
15233
15330
  label: "\u7D44\u7E54",
15234
15331
  help: "\u30DE\u30EB\u30C1\u30C6\u30CA\u30F3\u30C8\u5206\u96E2\u306E\u305F\u3081\u306E\u7D44\u7E54\u3002"
15235
15332
  },
15236
- project_id: {
15333
+ environment_id: {
15237
15334
  label: "\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\uFF08\u975E\u63A8\u5968\uFF09",
15238
15335
  help: "\u975E\u63A8\u5968\u3002\u30C6\u30CA\u30F3\u30C8\u5206\u96E2\u306B\u306F organization_id \u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
15239
15336
  },
@@ -15315,7 +15412,7 @@ var jaJPObjects = {
15315
15412
  label: "\u7D44\u7E54",
15316
15413
  help: "\u30DE\u30EB\u30C1\u30C6\u30CA\u30F3\u30C8\u5206\u96E2\u306E\u305F\u3081\u306E\u7D44\u7E54\u3002"
15317
15414
  },
15318
- project_id: {
15415
+ environment_id: {
15319
15416
  label: "\u74B0\u5883 ID",
15320
15417
  help: "\u3053\u306E\u5C65\u6B74\u30A8\u30F3\u30C8\u30EA\u3092\u7279\u5B9A\u306E\u74B0\u5883\u306B\u30B9\u30B3\u30FC\u30D7\u3057\u307E\u3059\u3002"
15321
15418
  },
@@ -17223,7 +17320,7 @@ var esESObjects = {
17223
17320
  label: "URL",
17224
17321
  help: "Enlace profundo opcional al destino de la actividad."
17225
17322
  },
17226
- project_id: {
17323
+ environment_id: {
17227
17324
  label: "Proyecto",
17228
17325
  help: "Contexto del proyecto (implementaciones multiproyecto)."
17229
17326
  },
@@ -18218,7 +18315,7 @@ var esESObjects = {
18218
18315
  label: "Organizaci\xF3n",
18219
18316
  help: "Organizaci\xF3n para el aislamiento multi-tenant."
18220
18317
  },
18221
- project_id: {
18318
+ environment_id: {
18222
18319
  label: "Proyecto (obsoleto)",
18223
18320
  help: "OBSOLETO. Use organization_id para el aislamiento del tenant."
18224
18321
  },
@@ -18300,7 +18397,7 @@ var esESObjects = {
18300
18397
  label: "Organizaci\xF3n",
18301
18398
  help: "Organizaci\xF3n para el aislamiento multi-tenant."
18302
18399
  },
18303
- project_id: {
18400
+ environment_id: {
18304
18401
  label: "ID del entorno",
18305
18402
  help: "Limita esta entrada de historial a un entorno espec\xEDfico."
18306
18403
  },