@objectstack/platform-objects 12.6.0 → 14.3.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.
Files changed (41) hide show
  1. package/dist/apps/index.d.mts +1 -1
  2. package/dist/apps/index.d.ts +1 -1
  3. package/dist/apps/index.js +38 -17
  4. package/dist/apps/index.js.map +1 -1
  5. package/dist/apps/index.mjs +38 -17
  6. package/dist/apps/index.mjs.map +1 -1
  7. package/dist/audit/index.d.mts +90 -30
  8. package/dist/audit/index.d.ts +90 -30
  9. package/dist/identity/index.d.mts +1057 -280
  10. package/dist/identity/index.d.ts +1057 -280
  11. package/dist/identity/index.js +184 -29
  12. package/dist/identity/index.js.map +1 -1
  13. package/dist/identity/index.mjs +184 -29
  14. package/dist/identity/index.mjs.map +1 -1
  15. package/dist/index.d.mts +1 -1
  16. package/dist/index.d.ts +1 -1
  17. package/dist/index.js +362 -335
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +362 -336
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/metadata-translations/index.js +20 -288
  22. package/dist/metadata-translations/index.js.map +1 -1
  23. package/dist/metadata-translations/index.mjs +20 -288
  24. package/dist/metadata-translations/index.mjs.map +1 -1
  25. package/dist/pages/index.d.mts +35 -4
  26. package/dist/pages/index.d.ts +35 -4
  27. package/dist/pages/index.js +112 -1
  28. package/dist/pages/index.js.map +1 -1
  29. package/dist/pages/index.mjs +112 -2
  30. package/dist/pages/index.mjs.map +1 -1
  31. package/dist/plugin.js +37 -300
  32. package/dist/plugin.js.map +1 -1
  33. package/dist/plugin.mjs +37 -300
  34. package/dist/plugin.mjs.map +1 -1
  35. package/dist/system/index.d.mts +30 -9
  36. package/dist/system/index.d.ts +30 -9
  37. package/dist/system/index.js +8 -0
  38. package/dist/system/index.js.map +1 -1
  39. package/dist/system/index.mjs +8 -0
  40. package/dist/system/index.mjs.map +1 -1
  41. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -39,13 +39,14 @@ var SysUser = data.ObjectSchema.create({
39
39
  locations: ["list_toolbar"],
40
40
  type: "api",
41
41
  target: "/api/v1/auth/organization/invite-member",
42
- // Org invitations are a multi-org-only flow (the endpoint resolves
43
- // an active org that does not exist in single-org mode). Hide the
44
- // affordance unless multi-org is enabled matching the
45
- // `create_organization` gate on sys_organization. This action is the
46
- // most exposed of the set because the Users list is always reachable
47
- // in single-org, unlike the org/membership lists.
48
- visible: "features.multiOrgEnabled != false",
42
+ // Gated on the org CAPABILITY, not multi-org (ADR-0081 D1): the
43
+ // better-auth organization plugin is always mounted, and single-org
44
+ // mode now bootstraps a Default Organization (plugin-auth) so the
45
+ // endpoint's active-org resolution works there too. This is THE
46
+ // "add a teammate" affordance the Users list is always reachable
47
+ // and every add flows through better-auth invitations, never bespoke
48
+ // sys_user CRUD.
49
+ visible: "features.organization != false",
49
50
  successMessage: "Invitation sent",
50
51
  refreshAfter: true,
51
52
  params: [
@@ -104,6 +105,62 @@ var SysUser = data.ObjectSchema.create({
104
105
  successMessage: "Account unlocked",
105
106
  refreshAfter: true
106
107
  },
108
+ {
109
+ // #2766 V1 — a platform admin can add a login-capable teammate without
110
+ // the email-dependent invite flow. Hits the plugin-auth wrapper route
111
+ // (NOT better-auth's stock /admin/create-user): the wrapper runs the
112
+ // ADR-0068 admin gate, drives the better-auth pipeline (scrypt hash +
113
+ // credential sys_account), stamps must_change_password, and — when
114
+ // "Generate temporary password" is picked — returns the password ONCE
115
+ // in the response for the result dialog. It is never persisted or logged.
116
+ name: "create_user",
117
+ label: "Create User",
118
+ icon: "user-plus",
119
+ variant: "secondary",
120
+ locations: ["list_toolbar"],
121
+ type: "api",
122
+ target: "/api/v1/auth/admin/create-user",
123
+ visible: "features.admin == true",
124
+ successMessage: "User created",
125
+ refreshAfter: true,
126
+ params: [
127
+ // The endpoint requires email OR phone (phone-only users get a
128
+ // placeholder address; requires auth.plugins.phoneNumber).
129
+ { field: "email", required: false },
130
+ {
131
+ name: "phoneNumber",
132
+ label: "Phone Number",
133
+ type: "text",
134
+ required: false,
135
+ helpText: "Sign-in phone number (E.164, e.g. +8613800000000). Required when no email is given."
136
+ },
137
+ { field: "name", required: false },
138
+ {
139
+ name: "generatePassword",
140
+ label: "Generate Temporary Password",
141
+ type: "boolean",
142
+ required: false,
143
+ defaultValue: true
144
+ },
145
+ { name: "password", label: "Password (leave empty to generate)", type: "text", required: false },
146
+ {
147
+ name: "mustChangePassword",
148
+ label: "Require Password Change On First Login",
149
+ type: "boolean",
150
+ required: false,
151
+ defaultValue: true
152
+ }
153
+ ],
154
+ resultDialog: {
155
+ title: "User Created",
156
+ description: "Copy the temporary password now \u2014 it is shown only once and never stored.",
157
+ acknowledge: "I have saved this password",
158
+ fields: [
159
+ { path: "user.email", label: "Email", format: "text" },
160
+ { path: "temporaryPassword", label: "Temporary Password", format: "secret" }
161
+ ]
162
+ }
163
+ },
107
164
  {
108
165
  name: "set_user_password",
109
166
  label: "Set Password",
@@ -111,13 +168,40 @@ var SysUser = data.ObjectSchema.create({
111
168
  variant: "secondary",
112
169
  locations: ["list_item"],
113
170
  type: "api",
171
+ // #2766 V1 — same path as better-auth's stock route, but served by the
172
+ // plugin-auth wrapper registered ahead of the catch-all: it accepts the
173
+ // ADR-0068 platform-admin signals (the stock handler only honors the
174
+ // legacy role scalar), can mint a temporary password, and stamps
175
+ // must_change_password.
114
176
  target: "/api/v1/auth/admin/set-user-password",
115
177
  recordIdParam: "userId",
116
178
  successMessage: "Password updated",
117
179
  refreshAfter: false,
118
180
  params: [
119
- { name: "newPassword", label: "New Password", type: "text", required: true }
120
- ]
181
+ {
182
+ name: "generatePassword",
183
+ label: "Generate Temporary Password",
184
+ type: "boolean",
185
+ required: false,
186
+ defaultValue: false
187
+ },
188
+ { name: "newPassword", label: "New Password (leave empty to generate)", type: "text", required: false },
189
+ {
190
+ name: "mustChangePassword",
191
+ label: "Require Password Change On Next Login",
192
+ type: "boolean",
193
+ required: false,
194
+ defaultValue: true
195
+ }
196
+ ],
197
+ resultDialog: {
198
+ title: "Password Updated",
199
+ description: "If a temporary password was generated, copy it now \u2014 it is shown only once and never stored.",
200
+ acknowledge: "Done",
201
+ fields: [
202
+ { path: "temporaryPassword", label: "Temporary Password", format: "secret" }
203
+ ]
204
+ }
121
205
  },
122
206
  {
123
207
  name: "set_user_role",
@@ -436,6 +520,37 @@ var SysUser = data.ObjectSchema.create({
436
520
  group: "Admin",
437
521
  description: "Timestamp of the last password change. Backs password_expiry_days; system-managed."
438
522
  }),
523
+ // #2766 V1.5 — phone-number sign-in identifier (better-auth phoneNumber
524
+ // plugin, mapped via buildPhoneNumberPluginSchema). Unique when present;
525
+ // null for email-only accounts. Written through better-auth, not CRUD.
526
+ phone_number: data.Field.text({
527
+ label: "Phone Number",
528
+ required: false,
529
+ readonly: true,
530
+ searchable: true,
531
+ maxLength: 32,
532
+ group: "Account",
533
+ description: "Sign-in phone number (E.164 recommended). Unique per user; managed by better-auth when the phoneNumber plugin is enabled."
534
+ }),
535
+ phone_number_verified: data.Field.boolean({
536
+ label: "Phone Verified",
537
+ defaultValue: false,
538
+ readonly: true,
539
+ group: "Account",
540
+ description: "Whether the phone number has been verified (OTP verification requires SMS infrastructure; false until that ships). System-managed."
541
+ }),
542
+ // #2766 V1 — admin-issued "must change password on next sign-in" flag.
543
+ // Set by the /admin/create-user and /admin/set-user-password routes when
544
+ // a temporary password is issued; enforced through the ADR-0069 authGate
545
+ // (surfaces as PASSWORD_EXPIRED); cleared by stampPasswordChangedAt once
546
+ // the user completes a password change.
547
+ must_change_password: data.Field.boolean({
548
+ label: "Must Change Password",
549
+ defaultValue: false,
550
+ readonly: true,
551
+ group: "Admin",
552
+ description: "When true, the user is blocked (403 PASSWORD_EXPIRED) until they change their password. Stamped by the admin user-management routes; system-managed."
553
+ }),
439
554
  // ADR-0069 D3 — when enforced MFA first applied to this user; starts the
440
555
  // grace clock. Stamped lazily at session validation; system-managed.
441
556
  mfa_required_at: data.Field.datetime({
@@ -533,7 +648,10 @@ var SysUser = data.ObjectSchema.create({
533
648
  },
534
649
  indexes: [
535
650
  { fields: ["email"], unique: true },
536
- { fields: ["created_at"], unique: false }
651
+ { fields: ["created_at"], unique: false },
652
+ // #2766 V1.5 — phone sign-in identifier; unique when present (null for
653
+ // email-only accounts), also the upsert match key for identity import.
654
+ { fields: ["phone_number"], unique: true }
537
655
  ],
538
656
  enable: {
539
657
  trackHistory: true,
@@ -934,6 +1052,12 @@ var SysVerification = data.ObjectSchema.create({
934
1052
  icon: "shield-check",
935
1053
  isSystem: true,
936
1054
  managedBy: "better-auth",
1055
+ // [ADR-0066 D2/④] Secure-by-default: rows are LIVE one-time credentials
1056
+ // (email/phone verification + password-reset tokens) — reading one is
1057
+ // account takeover. Not covered by the wildcard `'*'` grant; admins retain
1058
+ // access via the superuser bypass; better-auth reads via its adapter
1059
+ // (system context), so verification flows are unaffected.
1060
+ access: { default: "private" },
937
1061
  // ADR-0010 §3.7 — managed by better-auth; tenants may not edit schema,
938
1062
  // but may add overlay row-level config. Use `no-overlay` if you need to
939
1063
  // forbid sys_metadata overlays entirely.
@@ -1267,11 +1391,11 @@ var SysMember = data.ObjectSchema.create({
1267
1391
  locations: ["list_toolbar"],
1268
1392
  type: "api",
1269
1393
  target: "/api/v1/auth/organization/add-member",
1270
- // Org-membership mutations are multi-org-only: the better-auth
1271
- // endpoints resolve an active org that does not exist in single-org
1272
- // mode, so these actions would fail at the API. Gate every one on
1273
- // the multi-org flag (mirrors sys_organization.create_organization).
1274
- visible: "features.multiOrgEnabled != false",
1394
+ // Gated on the org CAPABILITY, not multi-org (ADR-0081 D1): the
1395
+ // better-auth endpoints resolve the session's active org, which
1396
+ // single-org mode now guarantees via plugin-auth's default-org
1397
+ // bootstrap. Same gate on every membership mutation below.
1398
+ visible: "features.organization != false",
1275
1399
  successMessage: "Member added",
1276
1400
  refreshAfter: true,
1277
1401
  params: [
@@ -1289,7 +1413,7 @@ var SysMember = data.ObjectSchema.create({
1289
1413
  type: "api",
1290
1414
  target: "/api/v1/auth/organization/update-member-role",
1291
1415
  recordIdParam: "memberId",
1292
- visible: "features.multiOrgEnabled != false",
1416
+ visible: "features.organization != false",
1293
1417
  successMessage: "Member role updated",
1294
1418
  refreshAfter: true,
1295
1419
  params: [
@@ -1306,7 +1430,7 @@ var SysMember = data.ObjectSchema.create({
1306
1430
  type: "api",
1307
1431
  target: "/api/v1/auth/organization/remove-member",
1308
1432
  recordIdParam: "memberIdOrEmail",
1309
- visible: "features.multiOrgEnabled != false",
1433
+ visible: "features.organization != false",
1310
1434
  confirmText: "Remove this member from the organization? They will lose access to all org resources.",
1311
1435
  successMessage: "Member removed",
1312
1436
  refreshAfter: true
@@ -1328,7 +1452,7 @@ var SysMember = data.ObjectSchema.create({
1328
1452
  target: "/api/v1/auth/organization/update-member-role",
1329
1453
  recordIdParam: "memberId",
1330
1454
  bodyExtra: { role: "owner" },
1331
- visible: "record.role != 'owner' && features.multiOrgEnabled != false",
1455
+ visible: "record.role != 'owner' && features.organization != false",
1332
1456
  confirmText: "Transfer ownership of this organization to the selected member? You will be demoted to admin and lose owner-only privileges.",
1333
1457
  successMessage: "Ownership transferred",
1334
1458
  refreshAfter: true
@@ -1436,7 +1560,7 @@ var SysInvitation = data.ObjectSchema.create({
1436
1560
  // sys_organization.create_organization). The recipient-side
1437
1561
  // accept/reject actions below stay record-gated — they are
1438
1562
  // unreachable in single-org anyway (no invitation rows exist).
1439
- visible: "features.multiOrgEnabled != false",
1563
+ visible: "features.organization != false",
1440
1564
  successMessage: "Invitation sent",
1441
1565
  refreshAfter: true,
1442
1566
  params: [
@@ -1454,7 +1578,7 @@ var SysInvitation = data.ObjectSchema.create({
1454
1578
  type: "api",
1455
1579
  target: "/api/v1/auth/organization/cancel-invitation",
1456
1580
  recordIdParam: "invitationId",
1457
- visible: "features.multiOrgEnabled != false",
1581
+ visible: "features.organization != false",
1458
1582
  confirmText: "Cancel this invitation? The recipient will no longer be able to accept it.",
1459
1583
  successMessage: "Invitation canceled",
1460
1584
  refreshAfter: true
@@ -1468,7 +1592,7 @@ var SysInvitation = data.ObjectSchema.create({
1468
1592
  type: "api",
1469
1593
  target: "/api/v1/auth/organization/invite-member",
1470
1594
  bodyExtra: { resend: true },
1471
- visible: "features.multiOrgEnabled != false",
1595
+ visible: "features.organization != false",
1472
1596
  successMessage: "Invitation resent",
1473
1597
  refreshAfter: true,
1474
1598
  params: [
@@ -1658,7 +1782,7 @@ var SysTeam = data.ObjectSchema.create({
1658
1782
  // Teams are nested inside organizations — a multi-org-only concept.
1659
1783
  // Gate every team mutation on the multi-org flag so the affordances
1660
1784
  // disappear in single-org (mirrors sys_organization.create_organization).
1661
- visible: "features.multiOrgEnabled != false",
1785
+ visible: "features.organization != false",
1662
1786
  successMessage: "Team created",
1663
1787
  refreshAfter: true,
1664
1788
  params: [
@@ -1679,7 +1803,7 @@ var SysTeam = data.ObjectSchema.create({
1679
1803
  target: "/api/v1/auth/organization/update-team",
1680
1804
  recordIdParam: "teamId",
1681
1805
  bodyShape: { wrap: "data" },
1682
- visible: "features.multiOrgEnabled != false",
1806
+ visible: "features.organization != false",
1683
1807
  successMessage: "Team updated",
1684
1808
  refreshAfter: true,
1685
1809
  params: [
@@ -1698,7 +1822,7 @@ var SysTeam = data.ObjectSchema.create({
1698
1822
  type: "api",
1699
1823
  target: "/api/v1/auth/organization/remove-team",
1700
1824
  recordIdParam: "teamId",
1701
- visible: "features.multiOrgEnabled != false",
1825
+ visible: "features.organization != false",
1702
1826
  confirmText: "Delete this team? Members will lose any team-scoped access. This cannot be undone.",
1703
1827
  successMessage: "Team deleted",
1704
1828
  refreshAfter: true
@@ -1812,7 +1936,7 @@ var SysTeamMember = data.ObjectSchema.create({
1812
1936
  // Team membership lives under organizations — multi-org-only. Gate
1813
1937
  // both mutations so they vanish in single-org (mirrors
1814
1938
  // sys_organization.create_organization).
1815
- visible: "features.multiOrgEnabled != false",
1939
+ visible: "features.organization != false",
1816
1940
  successMessage: "Team member added",
1817
1941
  refreshAfter: true,
1818
1942
  params: [
@@ -1833,7 +1957,7 @@ var SysTeamMember = data.ObjectSchema.create({
1833
1957
  locations: ["list_item"],
1834
1958
  type: "api",
1835
1959
  target: "/api/v1/auth/organization/remove-team-member",
1836
- visible: "features.multiOrgEnabled != false",
1960
+ visible: "features.organization != false",
1837
1961
  confirmText: "Remove this user from the team? They will lose any team-scoped access.",
1838
1962
  successMessage: "Team member removed",
1839
1963
  refreshAfter: true,
@@ -2071,7 +2195,7 @@ var SysBusinessUnitMember = data.ObjectSchema.create({
2071
2195
  managedBy: "platform",
2072
2196
  description: "User assignment to a business unit (matrix-org friendly, effective-dated).",
2073
2197
  titleFormat: "{user_id} in {business_unit_id}",
2074
- highlightFields: ["user_id", "business_unit_id", "role_in_business_unit", "is_primary"],
2198
+ highlightFields: ["user_id", "business_unit_id", "function_in_business_unit", "is_primary"],
2075
2199
  fields: {
2076
2200
  id: data.Field.text({
2077
2201
  label: "Member ID",
@@ -2089,10 +2213,10 @@ var SysBusinessUnitMember = data.ObjectSchema.create({
2089
2213
  required: true,
2090
2214
  group: "Assignment"
2091
2215
  }),
2092
- role_in_business_unit: data.Field.select(
2216
+ function_in_business_unit: data.Field.select(
2093
2217
  ["member", "lead", "deputy"],
2094
2218
  {
2095
- label: "Role in Business Unit",
2219
+ label: "Function in Business Unit",
2096
2220
  required: false,
2097
2221
  defaultValue: "member",
2098
2222
  description: "`lead` is the day-to-day head; `deputy` may stand in for the lead in approval routing.",
@@ -2496,6 +2620,12 @@ var SysDeviceCode = data.ObjectSchema.create({
2496
2620
  icon: "key-round",
2497
2621
  isSystem: true,
2498
2622
  managedBy: "better-auth",
2623
+ // [ADR-0066 D2/④] Secure-by-default: rows are LIVE pending device-grant
2624
+ // codes — reading `user_code`/`device_code` lets an attacker hijack a
2625
+ // pending CLI login. Not covered by the wildcard `'*'` grant; admins retain
2626
+ // access via the superuser bypass; better-auth reads via its adapter
2627
+ // (system context), so the device-grant flow is unaffected.
2628
+ access: { default: "private" },
2499
2629
  // ADR-0010 §3.7 — managed by better-auth; tenants may not edit schema,
2500
2630
  // but may add overlay row-level config. Use `no-overlay` if you need to
2501
2631
  // forbid sys_metadata overlays entirely.
@@ -3091,6 +3221,11 @@ var SysOauthAccessToken = data.ObjectSchema.create({
3091
3221
  icon: "ticket",
3092
3222
  isSystem: true,
3093
3223
  managedBy: "better-auth",
3224
+ // [ADR-0066 D2/④] Secure-by-default: rows are LIVE bearer credentials —
3225
+ // reading one is session hijack. Not covered by the wildcard `'*'` grant;
3226
+ // admins retain access via the superuser bypass; better-auth reads via its
3227
+ // adapter (system context), so OAuth flows are unaffected.
3228
+ access: { default: "private" },
3094
3229
  // ADR-0010 §3.7 — managed by better-auth; tenants may not edit schema,
3095
3230
  // but may add overlay row-level config. Use `no-overlay` if you need to
3096
3231
  // forbid sys_metadata overlays entirely.
@@ -3177,6 +3312,11 @@ var SysOauthRefreshToken = data.ObjectSchema.create({
3177
3312
  icon: "refresh-cw",
3178
3313
  isSystem: true,
3179
3314
  managedBy: "better-auth",
3315
+ // [ADR-0066 D2/④] Secure-by-default: rows are LIVE long-lived credentials —
3316
+ // a refresh token mints new access tokens. Not covered by the wildcard `'*'`
3317
+ // grant; admins retain access via the superuser bypass; better-auth reads
3318
+ // via its adapter (system context), so OAuth flows are unaffected.
3319
+ access: { default: "private" },
3180
3320
  // ADR-0010 §3.7 — managed by better-auth; tenants may not edit schema,
3181
3321
  // but may add overlay row-level config. Use `no-overlay` if you need to
3182
3322
  // forbid sys_metadata overlays entirely.
@@ -3335,6 +3475,13 @@ var SysJwks = data.ObjectSchema.create({
3335
3475
  icon: "key",
3336
3476
  isSystem: true,
3337
3477
  managedBy: "better-auth",
3478
+ // [ADR-0066 D2/④] Secure-by-default: rows are the environment's JWT SIGNING
3479
+ // KEYS (private key material). Not covered by the wildcard `'*'` grant — an
3480
+ // ordinary member gets 403 from the generic data layer. Platform admins
3481
+ // (viewAllRecords/modifyAllRecords) retain access via the posture-gated
3482
+ // superuser bypass; better-auth itself reads via its adapter (system
3483
+ // context), so token signing/verification is unaffected.
3484
+ access: { default: "private" },
3338
3485
  // ADR-0010 §3.7 — managed by better-auth; tenants may not edit schema,
3339
3486
  // but may add overlay row-level config. Use `no-overlay` if you need to
3340
3487
  // forbid sys_metadata overlays entirely.
@@ -3648,6 +3795,14 @@ var SysScimProvider = data.ObjectSchema.create({
3648
3795
  icon: "users",
3649
3796
  isSystem: true,
3650
3797
  managedBy: "better-auth",
3798
+ // [ADR-0066 D3/④] Admin-only identity config carrying a live credential
3799
+ // (`scim_token` — the bearer external IdPs authenticate provisioning calls
3800
+ // with). Object-level capability gate, mirroring the sibling
3801
+ // `sys_sso_provider`: ordinary members are denied entirely (without it, the
3802
+ // `member_default` wildcard `'*': allowRead` would expose SCIM connections
3803
+ // to every authenticated user). better-auth's own endpoints read via a
3804
+ // system context, so SCIM provisioning is unaffected.
3805
+ requiredPermissions: ["manage_platform_settings"],
3651
3806
  // ADR-0010 §3.7 — managed by better-auth; tenants may not edit schema.
3652
3807
  protection: {
3653
3808
  lock: "full",
@@ -4936,6 +5091,14 @@ var SysSecret = data.ObjectSchema.create({
4936
5091
  icon: "key",
4937
5092
  isSystem: true,
4938
5093
  managedBy: "system",
5094
+ // [ADR-0066 D2/④] Secure-by-default: the environment's encrypted-secrets
5095
+ // store (settings/datasource credentials). Not covered by the wildcard `'*'`
5096
+ // grant — ordinary members get 403 from the generic data layer. Platform
5097
+ // admins retain access via the posture-gated superuser bypass. Internal
5098
+ // readers are unaffected: `engine.resolveSecret` reads at DRIVER level,
5099
+ // SettingsService / the datasource secret-binder read with no principal
5100
+ // (middleware falls open for principal-less internal calls).
5101
+ access: { default: "private" },
4939
5102
  description: "Cipher store referenced by sys_setting handles. Never holds plaintext.",
4940
5103
  highlightFields: ["namespace", "key", "kms_key_id", "version", "rotated_at"],
4941
5104
  listViews: {
@@ -5283,21 +5446,33 @@ var SETUP_NAV_CONTRIBUTIONS = [
5283
5446
  priority: BASE_PRIORITY,
5284
5447
  items: [
5285
5448
  { id: "nav_users", type: "object", label: "Users", objectName: "sys_user", icon: "user" },
5449
+ // The ACTIVE organization's record page (Members / Invitations / Teams
5450
+ // tabs with the better-auth row actions), rendered inside the app shell
5451
+ // (ADR-0081). `{current_org_id}` resolves from the session's active
5452
+ // organization; unresolved (e.g. org-less admin before bootstrap) it
5453
+ // falls back to the sys_organization list — one row in single-org.
5454
+ { id: "nav_organization", type: "object", label: "Organization", objectName: "sys_organization", recordId: "{current_org_id}", icon: "building-2" },
5286
5455
  { id: "nav_business_units", type: "object", label: "Business Units", objectName: "sys_business_unit", icon: "building", requiresObject: "sys_business_unit" },
5287
- { id: "nav_teams", type: "object", label: "Teams", objectName: "sys_team", icon: "users-round", requiresService: "org-scoping" },
5456
+ // Teams / Invitations no longer gate on `org-scoping` (ADR-0081 D1):
5457
+ // the better-auth organization capability is always mounted, and
5458
+ // plugin-auth's single-org default-org bootstrap guarantees an org to
5459
+ // invite into — these are the OPEN member-management basics. Only the
5460
+ // org LIST below keeps the gate: browsing organizations is meaningful
5461
+ // only when more than one can exist (enterprise multi-org).
5462
+ { id: "nav_teams", type: "object", label: "Teams", objectName: "sys_team", icon: "users-round" },
5288
5463
  { id: "nav_organizations", type: "object", label: "Organizations", objectName: "sys_organization", icon: "building-2", requiresService: "org-scoping" },
5289
- { id: "nav_invitations", type: "object", label: "Invitations", objectName: "sys_invitation", icon: "mail", requiresService: "org-scoping" }
5464
+ { id: "nav_invitations", type: "object", label: "Invitations", objectName: "sys_invitation", icon: "mail" }
5290
5465
  ]
5291
5466
  },
5292
5467
  {
5293
5468
  app: "setup",
5294
5469
  group: "group_access_control",
5295
- // Priority 300 keeps API Keys after plugin-security's Roles / Permission
5470
+ // Priority 300 keeps API Keys after plugin-security's Positions / Permission
5296
5471
  // Sets (100) and plugin-sharing's Sharing Rules / Record Shares (200),
5297
5472
  // preserving the original menu order.
5298
5473
  priority: 300,
5299
5474
  items: [
5300
- // Roles / Permission Sets are contributed by @objectstack/plugin-security
5475
+ // Positions / Permission Sets are contributed by @objectstack/plugin-security
5301
5476
  // and Sharing Rules / Record Shares by @objectstack/plugin-sharing
5302
5477
  // (ADR-0029 K2). Only API Keys (sys_api_key, an identity object owned by
5303
5478
  // plugin-auth) remains a platform-objects base entry here.
@@ -5348,7 +5523,11 @@ var SETUP_NAV_CONTRIBUTIONS = [
5348
5523
  priority: BASE_PRIORITY,
5349
5524
  items: [
5350
5525
  { id: "nav_oauth_apps", type: "object", label: "OAuth Applications", objectName: "sys_oauth_application", icon: "app-window" },
5351
- { id: "nav_jwks", type: "object", label: "Signing Keys (JWKS)", objectName: "sys_jwks", icon: "key-round" },
5526
+ // nav_jwks is capability-gated (like nav_api_keys): sys_jwks is
5527
+ // `access.default:'private'` (ADR-0066 ④ — signing keys), so a
5528
+ // non-admin's list request 403s server-side; gating the nav item keeps
5529
+ // the menu honest instead of showing an entry that can only error.
5530
+ { id: "nav_jwks", type: "object", label: "Signing Keys (JWKS)", objectName: "sys_jwks", icon: "key-round", requiredPermissions: ["manage_platform_settings"] },
5352
5531
  // `sys_verification` (email/phone tokens) and `sys_device_code` (OAuth
5353
5532
  // device-grant codes) deliberately omit `list` from their `apiMethods`
5354
5533
  // (sensitive, ephemeral secrets — not browsable), so an object/list-view
@@ -6687,8 +6866,8 @@ var enObjects = {
6687
6866
  user_id: {
6688
6867
  label: "User"
6689
6868
  },
6690
- role_in_business_unit: {
6691
- label: "Role in Business Unit",
6869
+ function_in_business_unit: {
6870
+ label: "Function in Business Unit",
6692
6871
  help: "`lead` is the day-to-day head; `deputy` may stand in for the lead in approval routing.",
6693
6872
  options: {
6694
6873
  member: "member",
@@ -8640,12 +8819,13 @@ var en = {
8640
8819
  nav_marketplace_installed: { label: "Installed Apps" },
8641
8820
  // People & Organization
8642
8821
  nav_users: { label: "Users" },
8822
+ nav_organization: { label: "Organization" },
8643
8823
  nav_business_units: { label: "Business Units" },
8644
8824
  nav_teams: { label: "Teams" },
8645
8825
  nav_organizations: { label: "Organizations" },
8646
8826
  nav_invitations: { label: "Invitations" },
8647
8827
  // Access Control
8648
- nav_roles: { label: "Roles" },
8828
+ nav_positions: { label: "Positions" },
8649
8829
  nav_permission_sets: { label: "Permission Sets" },
8650
8830
  nav_sharing_rules: { label: "Sharing Rules" },
8651
8831
  nav_record_shares: { label: "Record Shares" },
@@ -9433,8 +9613,8 @@ var zhCNObjects = {
9433
9613
  user_id: {
9434
9614
  label: "\u7528\u6237"
9435
9615
  },
9436
- role_in_business_unit: {
9437
- label: "\u4E1A\u52A1\u5355\u5143\u5185\u89D2\u8272",
9616
+ function_in_business_unit: {
9617
+ label: "\u4E1A\u52A1\u5355\u5143\u5185\u804C\u80FD",
9438
9618
  help: "`lead` \u8868\u793A\u65E5\u5E38\u8D1F\u8D23\u4EBA\uFF1B`deputy` \u53EF\u5728\u5BA1\u6279\u8DEF\u7531\u4E2D\u4EE3\u66FF\u8D1F\u8D23\u4EBA\u3002",
9439
9619
  options: {
9440
9620
  member: "\u6210\u5458",
@@ -11383,16 +11563,18 @@ var zhCN = {
11383
11563
  group_advanced: { label: "\u9AD8\u7EA7" },
11384
11564
  nav_system_overview: { label: "\u7CFB\u7EDF\u6982\u89C8" },
11385
11565
  nav_users: { label: "\u7528\u6237" },
11566
+ nav_organization: { label: "\u7EC4\u7EC7" },
11386
11567
  nav_business_units: { label: "\u4E1A\u52A1\u5355\u5143" },
11387
11568
  nav_teams: { label: "\u56E2\u961F" },
11388
11569
  nav_organizations: { label: "\u7EC4\u7EC7" },
11389
11570
  nav_invitations: { label: "\u9080\u8BF7" },
11390
- nav_roles: { label: "\u89D2\u8272" },
11571
+ nav_positions: { label: "\u5C97\u4F4D" },
11391
11572
  nav_capabilities: { label: "\u80FD\u529B" },
11392
11573
  nav_permission_sets: { label: "\u6743\u9650\u96C6" },
11393
11574
  nav_sharing_rules: { label: "\u5171\u4EAB\u89C4\u5219" },
11394
11575
  nav_record_shares: { label: "\u8BB0\u5F55\u5171\u4EAB" },
11395
11576
  nav_api_keys: { label: "API \u5BC6\u94A5" },
11577
+ nav_connect_agent: { label: "\u8FDE\u63A5\u667A\u80FD\u4F53" },
11396
11578
  nav_approval_processes: { label: "\u5BA1\u6279\u6D41\u7A0B" },
11397
11579
  nav_approval_requests: { label: "\u5BA1\u6279\u7533\u8BF7" },
11398
11580
  nav_approval_actions: { label: "\u5BA1\u6279\u5386\u53F2" },
@@ -12142,8 +12324,8 @@ var jaJPObjects = {
12142
12324
  user_id: {
12143
12325
  label: "\u30E6\u30FC\u30B6\u30FC"
12144
12326
  },
12145
- role_in_business_unit: {
12146
- label: "\u30D3\u30B8\u30CD\u30B9\u30E6\u30CB\u30C3\u30C8\u5185\u30ED\u30FC\u30EB",
12327
+ function_in_business_unit: {
12328
+ label: "\u30D3\u30B8\u30CD\u30B9\u30E6\u30CB\u30C3\u30C8\u5185\u306E\u8077\u80FD",
12147
12329
  help: "`lead` \u306F\u65E5\u5E38\u306E\u8CAC\u4EFB\u8005\u3001`deputy` \u306F\u627F\u8A8D\u30EB\u30FC\u30C6\u30A3\u30F3\u30B0\u3067\u30EA\u30FC\u30C9\u306E\u4EE3\u7406\u3092\u52D9\u3081\u308B\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002",
12148
12330
  options: {
12149
12331
  member: "\u30E1\u30F3\u30D0\u30FC",
@@ -14091,11 +14273,12 @@ var jaJP = {
14091
14273
  group_advanced: { label: "\u8A73\u7D30" },
14092
14274
  nav_system_overview: { label: "\u30B7\u30B9\u30C6\u30E0\u6982\u8981" },
14093
14275
  nav_users: { label: "\u30E6\u30FC\u30B6\u30FC" },
14276
+ nav_organization: { label: "\u7D44\u7E54" },
14094
14277
  nav_business_units: { label: "\u30D3\u30B8\u30CD\u30B9\u30E6\u30CB\u30C3\u30C8" },
14095
14278
  nav_teams: { label: "\u30C1\u30FC\u30E0" },
14096
14279
  nav_organizations: { label: "\u7D44\u7E54" },
14097
14280
  nav_invitations: { label: "\u62DB\u5F85" },
14098
- nav_roles: { label: "\u30ED\u30FC\u30EB" },
14281
+ nav_positions: { label: "\u30DD\u30B8\u30B7\u30E7\u30F3" },
14099
14282
  nav_permission_sets: { label: "\u6A29\u9650\u30BB\u30C3\u30C8" },
14100
14283
  nav_sharing_rules: { label: "\u5171\u6709\u30EB\u30FC\u30EB" },
14101
14284
  nav_record_shares: { label: "\u30EC\u30B3\u30FC\u30C9\u5171\u6709" },
@@ -14848,8 +15031,8 @@ var esESObjects = {
14848
15031
  user_id: {
14849
15032
  label: "Usuario"
14850
15033
  },
14851
- role_in_business_unit: {
14852
- label: "Rol en el departamento",
15034
+ function_in_business_unit: {
15035
+ label: "Funci\xF3n en la unidad de negocio",
14853
15036
  help: "`lead` es el responsable del d\xEDa a d\xEDa; `deputy` puede sustituir al responsable en el enrutamiento de aprobaciones.",
14854
15037
  options: {
14855
15038
  member: "Miembro",
@@ -16797,11 +16980,12 @@ var esES = {
16797
16980
  group_advanced: { label: "Avanzado" },
16798
16981
  nav_system_overview: { label: "Resumen del Sistema" },
16799
16982
  nav_users: { label: "Usuarios" },
16983
+ nav_organization: { label: "Organizaci\xF3n" },
16800
16984
  nav_business_units: { label: "Unidades de negocio" },
16801
16985
  nav_teams: { label: "Equipos" },
16802
16986
  nav_organizations: { label: "Organizaciones" },
16803
16987
  nav_invitations: { label: "Invitaciones" },
16804
- nav_roles: { label: "Roles" },
16988
+ nav_positions: { label: "Posiciones" },
16805
16989
  nav_permission_sets: { label: "Conjuntos de Permisos" },
16806
16990
  nav_sharing_rules: { label: "Reglas de Compartici\xF3n" },
16807
16991
  nav_record_shares: { label: "Registros Compartidos" },
@@ -17046,7 +17230,7 @@ var SysUserDetailPage = {
17046
17230
  },
17047
17231
  // ── Tabs: curated related lists ───────────────────────────────
17048
17232
  // Only the 4 lists that are semantically about THIS user account.
17049
- // Everything else (sys_role created_by, sys_email_template
17233
+ // Everything else (sys_position created_by, sys_email_template
17050
17234
  // updated_by, …) is incidental authorship metadata and would only
17051
17235
  // create noise.
17052
17236
  tabs: {
@@ -17055,6 +17239,38 @@ var SysUserDetailPage = {
17055
17239
  type: "line",
17056
17240
  position: "top",
17057
17241
  items: [
17242
+ {
17243
+ label: "Positions",
17244
+ icon: "shield-check",
17245
+ children: [
17246
+ {
17247
+ // [ADR-0090 D3] Position assignments (岗位分派) — pure SDUI:
17248
+ // the Add picker creates sys_user_position rows storing the
17249
+ // position's MACHINE NAME (valueField: 'name'), and every
17250
+ // server-side rule (the D12 delegated-admin gate, audience-
17251
+ // anchor rejection) surfaces its error in the dialog.
17252
+ type: "record:related_list",
17253
+ properties: {
17254
+ objectName: "sys_user_position",
17255
+ relationshipField: "user_id",
17256
+ columns: ["position", "business_unit_id", "granted_by", "created_at"],
17257
+ sort: [{ field: "created_at", order: "desc" }],
17258
+ limit: 25,
17259
+ showViewAll: true,
17260
+ title: "Positions",
17261
+ add: {
17262
+ picker: {
17263
+ object: "sys_position",
17264
+ valueField: "name",
17265
+ labelField: "label"
17266
+ },
17267
+ linkField: "position",
17268
+ label: "Assign position"
17269
+ }
17270
+ }
17271
+ }
17272
+ ]
17273
+ },
17058
17274
  {
17059
17275
  label: "Sessions",
17060
17276
  icon: "monitor",
@@ -17261,6 +17477,84 @@ var SysUserDetailPage = {
17261
17477
  }
17262
17478
  };
17263
17479
 
17480
+ // src/pages/sys-position.page.ts
17481
+ var SysPositionDetailPage = {
17482
+ name: "sys_position_detail",
17483
+ label: "Position",
17484
+ type: "record",
17485
+ object: "sys_position",
17486
+ template: "default",
17487
+ kind: "slotted",
17488
+ isDefault: true,
17489
+ regions: [],
17490
+ slots: {
17491
+ tabs: {
17492
+ type: "page:tabs",
17493
+ properties: {
17494
+ type: "line",
17495
+ position: "top",
17496
+ items: [
17497
+ {
17498
+ label: "Holders",
17499
+ icon: "users",
17500
+ children: [
17501
+ {
17502
+ type: "record:related_list",
17503
+ properties: {
17504
+ objectName: "sys_user_position",
17505
+ relationshipField: "position",
17506
+ relationshipValueField: "name",
17507
+ columns: ["user_id", "business_unit_id", "granted_by", "created_at"],
17508
+ sort: [{ field: "created_at", order: "desc" }],
17509
+ limit: 25,
17510
+ showViewAll: true,
17511
+ title: "Holders",
17512
+ add: {
17513
+ picker: {
17514
+ object: "sys_user",
17515
+ labelField: "name"
17516
+ },
17517
+ linkField: "user_id",
17518
+ label: "Assign user"
17519
+ }
17520
+ }
17521
+ }
17522
+ ]
17523
+ },
17524
+ {
17525
+ label: "Permission Sets",
17526
+ icon: "lock",
17527
+ children: [
17528
+ {
17529
+ type: "record:related_list",
17530
+ properties: {
17531
+ objectName: "sys_position_permission_set",
17532
+ relationshipField: "position_id",
17533
+ columns: ["permission_set_id", "created_at"],
17534
+ sort: [{ field: "created_at", order: "desc" }],
17535
+ limit: 25,
17536
+ showViewAll: true,
17537
+ title: "Permission Sets",
17538
+ add: {
17539
+ picker: {
17540
+ object: "sys_permission_set",
17541
+ labelField: "label"
17542
+ },
17543
+ linkField: "permission_set_id",
17544
+ label: "Bind permission set"
17545
+ }
17546
+ }
17547
+ }
17548
+ ]
17549
+ }
17550
+ ]
17551
+ }
17552
+ },
17553
+ // No Chatter feed on an RBAC primitive.
17554
+ discussion: []
17555
+ }
17556
+ };
17557
+
17264
17558
  // src/apps/translations/en.metadata-forms.generated.ts
17265
17559
  var enMetadataForms = {
17266
17560
  object: {
@@ -18566,69 +18860,6 @@ var enMetadataForms = {
18566
18860
  label: "Label",
18567
18861
  helpText: "Display label for admins"
18568
18862
  },
18569
- isProfile: {
18570
- label: "Is Profile",
18571
- helpText: "Profile = base set assigned to users. Permission Set = additive grant."
18572
- },
18573
- systemPermissions: {
18574
- label: "System Permissions",
18575
- helpText: "List of system capability keys"
18576
- },
18577
- objects: {
18578
- label: "Objects",
18579
- helpText: '{ "account": { allowRead: true, allowEdit: true, ... } }'
18580
- },
18581
- fields: {
18582
- label: "Fields",
18583
- helpText: '{ "account.amount": { readable: true, editable: false } }'
18584
- },
18585
- tabPermissions: {
18586
- label: "Tab Permissions",
18587
- helpText: '{ "app_crm": "visible", "app_admin": "hidden" }'
18588
- },
18589
- rowLevelSecurity: {
18590
- label: "Row Level Security",
18591
- helpText: "Array of RLS policies (see rls.zod.ts)"
18592
- },
18593
- contextVariables: {
18594
- label: "Context Variables",
18595
- helpText: "Custom variables referenced in RLS predicates"
18596
- }
18597
- }
18598
- },
18599
- profile: {
18600
- label: "Profile",
18601
- sections: {
18602
- identity: {
18603
- label: "Identity",
18604
- description: "Permission Sets stack on top of a Profile to grant additional access. Profiles are the base set assigned 1:1 to each user."
18605
- },
18606
- system_permissions: {
18607
- label: "System Permissions",
18608
- description: "High-level capabilities not tied to a specific object \u2014 e.g. manage_users, view_audit_logs."
18609
- },
18610
- object_and_field_permissions: {
18611
- label: "Object & Field Permissions",
18612
- description: "Per-object CRUD + per-field FLS. Edit via the matrix editor or paste JSON here."
18613
- },
18614
- tab_and_row_level_security: {
18615
- label: "Tab & Row-Level Security",
18616
- description: "Tab visibility, RLS policies, and custom context variables for predicate evaluation."
18617
- }
18618
- },
18619
- fields: {
18620
- name: {
18621
- label: "Name",
18622
- helpText: "Machine name (snake_case)"
18623
- },
18624
- label: {
18625
- label: "Label",
18626
- helpText: "Display label for admins"
18627
- },
18628
- isProfile: {
18629
- label: "Is Profile",
18630
- helpText: "Profile = base set assigned to users. Permission Set = additive grant."
18631
- },
18632
18863
  systemPermissions: {
18633
18864
  label: "System Permissions",
18634
18865
  helpText: "List of system capability keys"
@@ -18655,12 +18886,12 @@ var enMetadataForms = {
18655
18886
  }
18656
18887
  }
18657
18888
  },
18658
- role: {
18659
- label: "Role",
18889
+ position: {
18890
+ label: "Position",
18660
18891
  sections: {
18661
- role: {
18662
- label: "Role",
18663
- description: "Roles compose a hierarchy used for record sharing (sales VP \u2192 sales mgr \u2192 sales rep). Permissions themselves live on Permission Sets and Profiles."
18892
+ position: {
18893
+ label: "Position",
18894
+ description: "A position is a flat, assignable bundle of permission sets (e.g. sales_rep, sales_manager). Capability lives on permission sets; visibility depth lives on the business-unit tree."
18664
18895
  }
18665
18896
  },
18666
18897
  fields: {
@@ -18671,10 +18902,6 @@ var enMetadataForms = {
18671
18902
  label: {
18672
18903
  label: "Label"
18673
18904
  },
18674
- parent: {
18675
- label: "Parent",
18676
- helpText: "Parent role machine name (Reports To)"
18677
- },
18678
18905
  description: {
18679
18906
  label: "Description"
18680
18907
  }
@@ -20204,10 +20431,6 @@ var zhCNMetadataForms = {
20204
20431
  label: "\u663E\u793A\u540D\u79F0",
20205
20432
  helpText: "\u9762\u5411\u7BA1\u7406\u5458\u7684\u663E\u793A\u6807\u7B7E"
20206
20433
  },
20207
- isProfile: {
20208
- label: "\u662F\u5426\u914D\u7F6E\u6587\u4EF6",
20209
- helpText: "\u52FE\u9009\u540E\u4F5C\u4E3A\u5B8C\u6574\u914D\u7F6E\u6587\u4EF6\uFF08\u800C\u975E\u9644\u52A0\u6743\u9650\u96C6\uFF09"
20210
- },
20211
20434
  systemPermissions: {
20212
20435
  label: "\u7CFB\u7EDF\u6743\u9650",
20213
20436
  helpText: "\u5E94\u7528\u8BBF\u95EE\u3001API\u3001\u7BA1\u7406\u64CD\u4F5C"
@@ -20234,71 +20457,12 @@ var zhCNMetadataForms = {
20234
20457
  }
20235
20458
  }
20236
20459
  },
20237
- profile: {
20238
- label: "\u914D\u7F6E\u6587\u4EF6",
20460
+ position: {
20461
+ label: "\u5C97\u4F4D",
20239
20462
  sections: {
20240
- identity: {
20241
- label: "\u6807\u8BC6",
20242
- description: "\u6743\u9650\u96C6\u53E0\u52A0\u5728\u914D\u7F6E\u6587\u4EF6\u4E4B\u4E0A\u4EE5\u6388\u4E88\u989D\u5916\u7684\u8BBF\u95EE\u6743\u9650\u3002\u914D\u7F6E\u6587\u4EF6\u662F\u6309 1:1 \u5206\u914D\u7ED9\u6BCF\u4E2A\u7528\u6237\u7684\u57FA\u7840\u96C6\u5408\u3002"
20243
- },
20244
- system_permissions: {
20245
- label: "\u7CFB\u7EDF\u6743\u9650",
20246
- description: "\u4E0E\u7279\u5B9A\u5BF9\u8C61\u65E0\u5173\u7684\u9AD8\u7EA7\u80FD\u529B\u2014\u2014\u4F8B\u5982 manage_users\u3001view_audit_logs\u3002"
20247
- },
20248
- object_and_field_permissions: {
20249
- label: "\u5BF9\u8C61\u4E0E\u5B57\u6BB5\u6743\u9650",
20250
- description: "\u6309\u5BF9\u8C61\u7684\u589E\u5220\u6539\u67E5 + \u6309\u5B57\u6BB5\u7684\u5B57\u6BB5\u7EA7\u5B89\u5168\uFF08FLS\uFF09\u3002\u53EF\u901A\u8FC7\u77E9\u9635\u7F16\u8F91\u5668\u7F16\u8F91\uFF0C\u6216\u5728\u6B64\u5904\u7C98\u8D34 JSON\u3002"
20251
- },
20252
- tab_and_row_level_security: {
20253
- label: "\u6807\u7B7E\u9875\u4E0E\u884C\u7EA7\u5B89\u5168",
20254
- description: "\u6807\u7B7E\u9875\u53EF\u89C1\u6027\u3001RLS \u7B56\u7565\uFF0C\u4EE5\u53CA\u7528\u4E8E\u8C13\u8BCD\u6C42\u503C\u7684\u81EA\u5B9A\u4E49\u4E0A\u4E0B\u6587\u53D8\u91CF\u3002"
20255
- }
20256
- },
20257
- fields: {
20258
- name: {
20259
- label: "\u540D\u79F0",
20260
- helpText: "\u673A\u5668\u540D\uFF08snake_case\uFF09"
20261
- },
20262
- label: {
20263
- label: "\u663E\u793A\u540D\u79F0",
20264
- helpText: "\u9762\u5411\u7BA1\u7406\u5458\u663E\u793A\u7684\u6807\u7B7E"
20265
- },
20266
- isProfile: {
20267
- label: "\u662F\u5426\u914D\u7F6E\u6587\u4EF6",
20268
- helpText: "\u914D\u7F6E\u6587\u4EF6 = \u5206\u914D\u7ED9\u7528\u6237\u7684\u57FA\u7840\u96C6\u5408\u3002\u6743\u9650\u96C6 = \u9644\u52A0\u6388\u4E88\u3002"
20269
- },
20270
- systemPermissions: {
20271
- label: "\u7CFB\u7EDF\u6743\u9650",
20272
- helpText: "\u7CFB\u7EDF\u80FD\u529B\u952E\u5217\u8868"
20273
- },
20274
- objects: {
20275
- label: "\u5BF9\u8C61\u6743\u9650",
20276
- helpText: '\u793A\u4F8B\uFF1A{ "account": { allowRead: true, allowEdit: true, ... } }'
20277
- },
20278
- fields: {
20279
- label: "\u5B57\u6BB5",
20280
- helpText: '\u793A\u4F8B\uFF1A{ "account.amount": { readable: true, editable: false } }'
20281
- },
20282
- tabPermissions: {
20283
- label: "\u6807\u7B7E\u9875\u6743\u9650",
20284
- helpText: '\u793A\u4F8B\uFF1A{ "app_crm": "visible", "app_admin": "hidden" }'
20285
- },
20286
- rowLevelSecurity: {
20287
- label: "\u884C\u7EA7\u5B89\u5168",
20288
- helpText: "RLS \u7B56\u7565\u6570\u7EC4\uFF08\u53C2\u89C1 rls.zod.ts\uFF09"
20289
- },
20290
- contextVariables: {
20291
- label: "\u4E0A\u4E0B\u6587\u53D8\u91CF",
20292
- helpText: "RLS \u8C13\u8BCD\u4E2D\u5F15\u7528\u7684\u81EA\u5B9A\u4E49\u53D8\u91CF"
20293
- }
20294
- }
20295
- },
20296
- role: {
20297
- label: "\u89D2\u8272",
20298
- sections: {
20299
- role: {
20300
- label: "\u89D2\u8272\u5B9A\u4E49",
20301
- description: "\u89D2\u8272\u540D\u79F0\u4E0E\u7EE7\u627F\u5173\u7CFB"
20463
+ position: {
20464
+ label: "\u5C97\u4F4D",
20465
+ description: "\u5C97\u4F4D\u662F\u6241\u5E73\u7684\u3001\u53EF\u5206\u914D\u7684\u6743\u9650\u96C6\u7EC4\u5408(\u5982 sales_rep\u3001sales_manager)\u3002\u80FD\u529B\u5728\u6743\u9650\u96C6\u4E0A;\u53EF\u89C1\u8303\u56F4\u6DF1\u5EA6\u5728\u4E1A\u52A1\u5355\u5143\u6811\u4E0A\u3002"
20302
20466
  }
20303
20467
  },
20304
20468
  fields: {
@@ -20309,10 +20473,6 @@ var zhCNMetadataForms = {
20309
20473
  label: {
20310
20474
  label: "\u663E\u793A\u540D\u79F0"
20311
20475
  },
20312
- parent: {
20313
- label: "\u7236\u7EA7",
20314
- helpText: "\u7EE7\u627F\u7236\u89D2\u8272\u7684\u6743\u9650"
20315
- },
20316
20476
  description: {
20317
20477
  label: "\u63CF\u8FF0"
20318
20478
  }
@@ -21842,10 +22002,6 @@ var jaJPMetadataForms = {
21842
22002
  label: "\u8868\u793A\u540D",
21843
22003
  helpText: "\u7BA1\u7406\u8005\u5411\u3051\u8868\u793A\u30E9\u30D9\u30EB"
21844
22004
  },
21845
- isProfile: {
21846
- label: "\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u304B",
21847
- helpText: "Profile = \u30E6\u30FC\u30B6\u30FC\u306B\u5272\u308A\u5F53\u3066\u308B\u57FA\u672C\u30BB\u30C3\u30C8\u3002Permission Set = \u8FFD\u52A0\u6A29\u9650\u3002"
21848
- },
21849
22005
  systemPermissions: {
21850
22006
  label: "\u30B7\u30B9\u30C6\u30E0\u6A29\u9650",
21851
22007
  helpText: "\u30B7\u30B9\u30C6\u30E0\u6A5F\u80FD\u30AD\u30FC\u306E\u30EA\u30B9\u30C8"
@@ -21872,71 +22028,12 @@ var jaJPMetadataForms = {
21872
22028
  }
21873
22029
  }
21874
22030
  },
21875
- profile: {
21876
- label: "\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB",
22031
+ position: {
22032
+ label: "\u30DD\u30B8\u30B7\u30E7\u30F3",
21877
22033
  sections: {
21878
- identity: {
21879
- label: "ID",
21880
- description: "\u6A29\u9650\u30BB\u30C3\u30C8\u306F\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306B\u8FFD\u52A0\u30A2\u30AF\u30BB\u30B9\u6A29\u3092\u91CD\u306D\u308B\u3002\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306F\u5404\u30E6\u30FC\u30B6\u30FC\u306B 1:1 \u3067\u5272\u308A\u5F53\u3066\u308B\u57FA\u672C\u30BB\u30C3\u30C8\u3002"
21881
- },
21882
- system_permissions: {
21883
- label: "\u30B7\u30B9\u30C6\u30E0\u6A29\u9650",
21884
- description: "\u7279\u5B9A\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306B\u7D10\u3065\u304B\u306A\u3044\u9AD8\u30EC\u30D9\u30EB\u6A5F\u80FD \u2014 \u4F8B: manage_users, view_audit_logs\u3002"
21885
- },
21886
- object_and_field_permissions: {
21887
- label: "\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3068\u30D5\u30A3\u30FC\u30EB\u30C9\u6A29\u9650",
21888
- description: "\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u5358\u4F4D\u306E CRUD + \u30D5\u30A3\u30FC\u30EB\u30C9\u5358\u4F4D\u306E FLS\u3002\u30DE\u30C8\u30EA\u30C3\u30AF\u30B9\u30A8\u30C7\u30A3\u30BF\u30FC\u3067\u7DE8\u96C6\u3001\u307E\u305F\u306F\u3053\u3053\u306B JSON \u3092\u8CBC\u308A\u4ED8\u3051\u3002"
21889
- },
21890
- tab_and_row_level_security: {
21891
- label: "\u30BF\u30D6\u3068\u884C\u30EC\u30D9\u30EB\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3",
21892
- description: "\u30BF\u30D6\u8868\u793A\u3001RLS \u30DD\u30EA\u30B7\u30FC\u3001\u8FF0\u8A9E\u8A55\u4FA1\u7528\u30AB\u30B9\u30BF\u30E0\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u5909\u6570\u3002"
21893
- }
21894
- },
21895
- fields: {
21896
- name: {
21897
- label: "\u540D\u524D",
21898
- helpText: "\u30DE\u30B7\u30F3\u540D\uFF08snake_case\uFF09"
21899
- },
21900
- label: {
21901
- label: "\u8868\u793A\u540D",
21902
- helpText: "\u7BA1\u7406\u8005\u5411\u3051\u8868\u793A\u30E9\u30D9\u30EB"
21903
- },
21904
- isProfile: {
21905
- label: "\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u304B",
21906
- helpText: "Profile = \u30E6\u30FC\u30B6\u30FC\u306B\u5272\u308A\u5F53\u3066\u308B\u57FA\u672C\u30BB\u30C3\u30C8\u3002Permission Set = \u8FFD\u52A0\u6A29\u9650\u3002"
21907
- },
21908
- systemPermissions: {
21909
- label: "\u30B7\u30B9\u30C6\u30E0\u6A29\u9650",
21910
- helpText: "\u30B7\u30B9\u30C6\u30E0\u6A5F\u80FD\u30AD\u30FC\u306E\u30EA\u30B9\u30C8"
21911
- },
21912
- objects: {
21913
- label: "\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u6A29\u9650",
21914
- helpText: '\u4F8B: { "account": { allowRead: true, allowEdit: true, ... } }'
21915
- },
21916
- fields: {
21917
- label: "\u30D5\u30A3\u30FC\u30EB\u30C9",
21918
- helpText: '\u4F8B: { "account.amount": { readable: true, editable: false } }'
21919
- },
21920
- tabPermissions: {
21921
- label: "\u30BF\u30D6\u6A29\u9650",
21922
- helpText: '\u4F8B: { "app_crm": "visible", "app_admin": "hidden" }'
21923
- },
21924
- rowLevelSecurity: {
21925
- label: "\u884C\u30EC\u30D9\u30EB\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3",
21926
- helpText: "RLS \u30DD\u30EA\u30B7\u30FC\u306E\u914D\u5217\uFF08rls.zod.ts \u53C2\u7167\uFF09"
21927
- },
21928
- contextVariables: {
21929
- label: "\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u5909\u6570",
21930
- helpText: "RLS \u8FF0\u8A9E\u3067\u53C2\u7167\u3059\u308B\u30AB\u30B9\u30BF\u30E0\u5909\u6570"
21931
- }
21932
- }
21933
- },
21934
- role: {
21935
- label: "\u30ED\u30FC\u30EB",
21936
- sections: {
21937
- role: {
21938
- label: "\u30ED\u30FC\u30EB",
21939
- description: "\u30ED\u30FC\u30EB\u306F\u30EC\u30B3\u30FC\u30C9\u5171\u6709\u306B\u4F7F\u3046\u968E\u5C64\u3092\u69CB\u6210\uFF08sales VP \u2192 sales mgr \u2192 sales rep\uFF09\u3002\u6A29\u9650\u81EA\u4F53\u306F Permission Sets \u3068 Profiles \u306B\u5B58\u5728\u3002"
22034
+ position: {
22035
+ label: "\u30DD\u30B8\u30B7\u30E7\u30F3",
22036
+ description: "\u30DD\u30B8\u30B7\u30E7\u30F3\u306F\u6A29\u9650\u30BB\u30C3\u30C8\u3092\u307E\u3068\u3081\u3066\u5272\u308A\u5F53\u3066\u308B\u30D5\u30E9\u30C3\u30C8\u306A\u5358\u4F4D(\u4F8B: sales_rep\u3001sales_manager)\u3002\u80FD\u529B\u306F\u6A29\u9650\u30BB\u30C3\u30C8\u306B\u3001\u53EF\u8996\u7BC4\u56F2\u306E\u6DF1\u3055\u306F\u30D3\u30B8\u30CD\u30B9\u30E6\u30CB\u30C3\u30C8\u30C4\u30EA\u30FC\u306B\u3042\u308A\u307E\u3059\u3002"
21940
22037
  }
21941
22038
  },
21942
22039
  fields: {
@@ -21947,10 +22044,6 @@ var jaJPMetadataForms = {
21947
22044
  label: {
21948
22045
  label: "\u8868\u793A\u540D"
21949
22046
  },
21950
- parent: {
21951
- label: "\u89AA",
21952
- helpText: "\u89AA\u30ED\u30FC\u30EB\u306E\u30DE\u30B7\u30F3\u540D\uFF08Reports To\uFF09"
21953
- },
21954
22047
  description: {
21955
22048
  label: "\u8AAC\u660E"
21956
22049
  }
@@ -23480,69 +23573,6 @@ var esESMetadataForms = {
23480
23573
  label: "Etiqueta",
23481
23574
  helpText: "Etiqueta mostrada para administradores"
23482
23575
  },
23483
- isProfile: {
23484
- label: "Es perfil",
23485
- helpText: "Profile = conjunto base asignado a usuarios. Permission Set = concesi\xF3n adicional."
23486
- },
23487
- systemPermissions: {
23488
- label: "Permisos del sistema",
23489
- helpText: "Lista de claves de capacidades del sistema"
23490
- },
23491
- objects: {
23492
- label: "Permisos de objeto",
23493
- helpText: 'Ejemplo: { "account": { allowRead: true, allowEdit: true, ... } }'
23494
- },
23495
- fields: {
23496
- label: "Campos",
23497
- helpText: 'Ejemplo: { "account.amount": { readable: true, editable: false } }'
23498
- },
23499
- tabPermissions: {
23500
- label: "Permisos de pesta\xF1a",
23501
- helpText: 'Ejemplo: { "app_crm": "visible", "app_admin": "hidden" }'
23502
- },
23503
- rowLevelSecurity: {
23504
- label: "Seguridad a nivel de fila",
23505
- helpText: "Array de pol\xEDticas RLS (ver rls.zod.ts)"
23506
- },
23507
- contextVariables: {
23508
- label: "Variables de contexto",
23509
- helpText: "Variables personalizadas referenciadas en predicados RLS"
23510
- }
23511
- }
23512
- },
23513
- profile: {
23514
- label: "Perfil",
23515
- sections: {
23516
- identity: {
23517
- label: "Identidad",
23518
- description: "Los conjuntos de permisos se apilan sobre un perfil para conceder acceso adicional. Los perfiles son el conjunto base asignado 1:1 a cada usuario."
23519
- },
23520
- system_permissions: {
23521
- label: "Permisos del sistema",
23522
- description: "Capacidades de alto nivel no vinculadas a un objeto espec\xEDfico \u2014 p. ej. manage_users, view_audit_logs."
23523
- },
23524
- object_and_field_permissions: {
23525
- label: "Permisos de objeto y campo",
23526
- description: "CRUD por objeto + FLS por campo. Edita mediante el editor matricial o pega JSON aqu\xED."
23527
- },
23528
- tab_and_row_level_security: {
23529
- label: "Pesta\xF1a y seguridad a nivel de fila",
23530
- description: "Visibilidad de pesta\xF1as, pol\xEDticas RLS y variables de contexto personalizadas para evaluar predicados."
23531
- }
23532
- },
23533
- fields: {
23534
- name: {
23535
- label: "Nombre",
23536
- helpText: "Nombre de m\xE1quina (snake_case)"
23537
- },
23538
- label: {
23539
- label: "Etiqueta",
23540
- helpText: "Etiqueta mostrada para administradores"
23541
- },
23542
- isProfile: {
23543
- label: "Es perfil",
23544
- helpText: "Profile = conjunto base asignado a usuarios. Permission Set = concesi\xF3n adicional."
23545
- },
23546
23576
  systemPermissions: {
23547
23577
  label: "Permisos del sistema",
23548
23578
  helpText: "Lista de claves de capacidades del sistema"
@@ -23569,12 +23599,12 @@ var esESMetadataForms = {
23569
23599
  }
23570
23600
  }
23571
23601
  },
23572
- role: {
23573
- label: "Rol",
23602
+ position: {
23603
+ label: "Posici\xF3n",
23574
23604
  sections: {
23575
- role: {
23576
- label: "Rol",
23577
- description: "Los roles componen una jerarqu\xEDa usada para compartir registros (sales VP \u2192 sales mgr \u2192 sales rep). Los permisos en s\xED residen en Permission Sets y Profiles."
23605
+ position: {
23606
+ label: "Posici\xF3n",
23607
+ description: "Una posici\xF3n es un conjunto plano y asignable de permission sets (p. ej. sales_rep, sales_manager). La capacidad reside en los permission sets; la profundidad de visibilidad en el \xE1rbol de unidades de negocio."
23578
23608
  }
23579
23609
  },
23580
23610
  fields: {
@@ -23585,10 +23615,6 @@ var esESMetadataForms = {
23585
23615
  label: {
23586
23616
  label: "Etiqueta"
23587
23617
  },
23588
- parent: {
23589
- label: "Padre",
23590
- helpText: "Nombre de m\xE1quina del rol padre (Reports To)"
23591
- },
23592
23618
  description: {
23593
23619
  label: "Descripci\xF3n"
23594
23620
  }
@@ -23919,6 +23945,7 @@ exports.SysOauthConsent = SysOauthConsent;
23919
23945
  exports.SysOauthRefreshToken = SysOauthRefreshToken;
23920
23946
  exports.SysOrganization = SysOrganization;
23921
23947
  exports.SysOrganizationDetailPage = SysOrganizationDetailPage;
23948
+ exports.SysPositionDetailPage = SysPositionDetailPage;
23922
23949
  exports.SysReportSchedule = SysReportSchedule;
23923
23950
  exports.SysSavedReport = SysSavedReport;
23924
23951
  exports.SysScimProvider = SysScimProvider;