@company-semantics/contracts 1.14.0 → 1.15.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@company-semantics/contracts",
3
- "version": "1.14.0",
3
+ "version": "1.15.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,3 +1,3 @@
1
1
  // AUTO-GENERATED — do not edit. Run pnpm generate:spec-hash to regenerate.
2
- export const SPEC_HASH = '508bfa08f5fd' as const;
3
- export const SPEC_HASH_FULL = '508bfa08f5fdd3ae4f8d472fa9a6fd9a7dbfca1bb4b63f86c24cc1dbc2fc4cf3' as const;
2
+ export const SPEC_HASH = 'b15100bf7771' as const;
3
+ export const SPEC_HASH_FULL = 'b15100bf7771682644b63942432a672ffee7d4fdb1237201f491b4d8d3c6b238' as const;
@@ -636,7 +636,8 @@ export interface paths {
636
636
  path?: never;
637
637
  cookie?: never;
638
638
  };
639
- get?: never;
639
+ /** Get workspace member detail (roles, units, effective scopes, recent actions) */
640
+ get: operations["getWorkspaceMemberDetail"];
640
641
  put?: never;
641
642
  post?: never;
642
643
  /** Remove workspace member */
@@ -646,6 +647,23 @@ export interface paths {
646
647
  patch?: never;
647
648
  trace?: never;
648
649
  };
650
+ "/api/rbac/roles": {
651
+ parameters: {
652
+ query?: never;
653
+ header?: never;
654
+ path?: never;
655
+ cookie?: never;
656
+ };
657
+ /** List RBAC roles catalog (system + custom) with scopes and member counts */
658
+ get: operations["getRbacRoles"];
659
+ put?: never;
660
+ post?: never;
661
+ delete?: never;
662
+ options?: never;
663
+ head?: never;
664
+ patch?: never;
665
+ trace?: never;
666
+ };
649
667
  "/api/workspace/members/{id}/role": {
650
668
  parameters: {
651
669
  query?: never;
@@ -2337,15 +2355,49 @@ export interface components {
2337
2355
  WorkspaceHandleRequest: {
2338
2356
  handle: string;
2339
2357
  };
2358
+ WorkspaceMemberUnitSummary: {
2359
+ unitId: string;
2360
+ unitName: string;
2361
+ unitPath: string;
2362
+ /** @enum {string} */
2363
+ role: "owner" | "manager" | "member";
2364
+ };
2365
+ WorkspaceMember: {
2366
+ id: string;
2367
+ name: string;
2368
+ email: string;
2369
+ /** @enum {string} */
2370
+ role: "owner" | "admin" | "member" | "auditor";
2371
+ roleNames: string[];
2372
+ joinedAt: string;
2373
+ lastActiveAt: string | null;
2374
+ unitMemberships: components["schemas"]["WorkspaceMemberUnitSummary"][];
2375
+ unitMembershipsTruncated: boolean;
2376
+ inviteStatus: ("active" | "pending" | "expired") | null;
2377
+ };
2378
+ MemberRecentAction: {
2379
+ id: string;
2380
+ timestamp: string;
2381
+ action: string;
2382
+ summary: string;
2383
+ };
2384
+ WorkspaceMemberDetail: components["schemas"]["WorkspaceMember"] & {
2385
+ effectiveScopes: string[];
2386
+ recentActions: components["schemas"]["MemberRecentAction"][];
2387
+ };
2388
+ RoleCatalogEntry: {
2389
+ name: string;
2390
+ /** @enum {string} */
2391
+ type: "system" | "custom";
2392
+ description: string;
2393
+ scopes: string[];
2394
+ memberCount: number;
2395
+ };
2396
+ RoleCatalogResponse: {
2397
+ roles: components["schemas"]["RoleCatalogEntry"][];
2398
+ };
2340
2399
  WorkspaceMembersResponse: {
2341
- items: {
2342
- id: string;
2343
- name: string;
2344
- email: string;
2345
- /** @enum {string} */
2346
- role: "owner" | "admin" | "member" | "auditor";
2347
- joinedAt: string;
2348
- }[];
2400
+ items: components["schemas"]["WorkspaceMember"][];
2349
2401
  nextCursor: string | null;
2350
2402
  hasMore: boolean;
2351
2403
  };
@@ -4371,6 +4423,28 @@ export interface operations {
4371
4423
  };
4372
4424
  };
4373
4425
  };
4426
+ getWorkspaceMemberDetail: {
4427
+ parameters: {
4428
+ query?: never;
4429
+ header?: never;
4430
+ path: {
4431
+ id: string;
4432
+ };
4433
+ cookie?: never;
4434
+ };
4435
+ requestBody?: never;
4436
+ responses: {
4437
+ /** @description Workspace member detail */
4438
+ 200: {
4439
+ headers: {
4440
+ [name: string]: unknown;
4441
+ };
4442
+ content: {
4443
+ "application/json": components["schemas"]["WorkspaceMemberDetail"];
4444
+ };
4445
+ };
4446
+ };
4447
+ };
4374
4448
  removeMember: {
4375
4449
  parameters: {
4376
4450
  query?: never;
@@ -4393,6 +4467,26 @@ export interface operations {
4393
4467
  };
4394
4468
  };
4395
4469
  };
4470
+ getRbacRoles: {
4471
+ parameters: {
4472
+ query?: never;
4473
+ header?: never;
4474
+ path?: never;
4475
+ cookie?: never;
4476
+ };
4477
+ requestBody?: never;
4478
+ responses: {
4479
+ /** @description Role catalog */
4480
+ 200: {
4481
+ headers: {
4482
+ [name: string]: unknown;
4483
+ };
4484
+ content: {
4485
+ "application/json": components["schemas"]["RoleCatalogResponse"];
4486
+ };
4487
+ };
4488
+ };
4489
+ };
4396
4490
  changeMemberRole: {
4397
4491
  parameters: {
4398
4492
  query?: never;
package/src/org/index.ts CHANGED
@@ -15,6 +15,11 @@ export type {
15
15
  WorkspaceRole,
16
16
  WorkspaceOverview,
17
17
  WorkspaceMember,
18
+ WorkspaceMemberUnitSummary,
19
+ WorkspaceMemberInviteStatus,
20
+ WorkspaceMemberDetail,
21
+ MemberRecentAction,
22
+ RoleCatalogEntry,
18
23
  AuthMethodConfig,
19
24
  WorkspaceAuthConfig,
20
25
  // SSO self-service setup types (PRD-00193)
@@ -120,6 +125,9 @@ export {
120
125
  WorkspaceAccessResponseSchema,
121
126
  WorkspaceOverviewSchema,
122
127
  WorkspaceMembersResponseSchema,
128
+ WorkspaceMemberDetailSchema,
129
+ RoleCatalogEntrySchema,
130
+ RoleCatalogResponseSchema,
123
131
  WorkspaceAuthConfigSchema,
124
132
  WorkspaceAuditEventSchema,
125
133
  WorkspaceAuditResponseSchema,
@@ -17,12 +17,48 @@ import { CursorPageSchema } from '../api/primitives';
17
17
  // Sub-schemas
18
18
  // ---------------------------------------------------------------------------
19
19
 
20
+ const WorkspaceMemberUnitSummarySchema = z.object({
21
+ unitId: z.string(),
22
+ unitName: z.string(),
23
+ unitPath: z.string(),
24
+ role: z.enum(['owner', 'manager', 'member']),
25
+ });
26
+
20
27
  const WorkspaceMemberSchema = z.object({
21
28
  id: z.string(),
22
29
  name: z.string(),
23
30
  email: z.string(),
24
31
  role: z.enum(['owner', 'admin', 'member', 'auditor']),
32
+ roleNames: z.array(z.string()),
25
33
  joinedAt: z.string(),
34
+ lastActiveAt: z.string().nullable(),
35
+ unitMemberships: z.array(WorkspaceMemberUnitSummarySchema),
36
+ unitMembershipsTruncated: z.boolean(),
37
+ inviteStatus: z.enum(['active', 'pending', 'expired']).nullable(),
38
+ });
39
+
40
+ const MemberRecentActionSchema = z.object({
41
+ id: z.string(),
42
+ timestamp: z.string(),
43
+ action: z.string(),
44
+ summary: z.string(),
45
+ });
46
+
47
+ export const WorkspaceMemberDetailSchema = WorkspaceMemberSchema.extend({
48
+ effectiveScopes: z.array(z.string()),
49
+ recentActions: z.array(MemberRecentActionSchema),
50
+ });
51
+
52
+ export const RoleCatalogEntrySchema = z.object({
53
+ name: z.string(),
54
+ type: z.enum(['system', 'custom']),
55
+ description: z.string(),
56
+ scopes: z.array(z.string()),
57
+ memberCount: z.number().int().nonnegative(),
58
+ });
59
+
60
+ export const RoleCatalogResponseSchema = z.object({
61
+ roles: z.array(RoleCatalogEntrySchema),
26
62
  });
27
63
 
28
64
  const WorkspaceOwnerSchema = z.object({
package/src/org/types.ts CHANGED
@@ -92,6 +92,24 @@ export interface WorkspaceOverview {
92
92
  claimable: boolean;
93
93
  }
94
94
 
95
+ /**
96
+ * Single OrgUnit membership summary attached to a WorkspaceMember row.
97
+ * See ADR-BE-120 for the canonical OrgUnit tree model.
98
+ */
99
+ export interface WorkspaceMemberUnitSummary {
100
+ unitId: string;
101
+ unitName: string;
102
+ /** Human-readable path from the OrgUnit tree (e.g. "Sales / Enterprise"). */
103
+ unitPath: string;
104
+ role: 'owner' | 'manager' | 'member';
105
+ }
106
+
107
+ /**
108
+ * Invite status for a workspace member row. `null` for members that have no
109
+ * associated invite record (joined pre-invite system).
110
+ */
111
+ export type WorkspaceMemberInviteStatus = 'active' | 'pending' | 'expired';
112
+
95
113
  /**
96
114
  * Workspace member for the members list.
97
115
  * Human users only (no agent actors).
@@ -100,8 +118,56 @@ export interface WorkspaceMember {
100
118
  id: string;
101
119
  name: string;
102
120
  email: string;
121
+ /** Display role — derived collapse of RBAC into {owner,admin,member,auditor}. */
103
122
  role: WorkspaceRole;
123
+ /** Raw RBAC role names (e.g. 'org_owner', 'org_admin', 'auditor'). Superset of `role`. */
124
+ roleNames: string[];
104
125
  joinedAt: string;
126
+ /** ISO timestamp of last activity; null if never recorded. */
127
+ lastActiveAt: string | null;
128
+ /** OrgUnit memberships for this member, capped at a small number server-side. */
129
+ unitMemberships: WorkspaceMemberUnitSummary[];
130
+ /** True when server truncated `unitMemberships`; detail endpoint returns the full list. */
131
+ unitMembershipsTruncated: boolean;
132
+ /** Invite lifecycle status. `null` for members without an invite record. */
133
+ inviteStatus: WorkspaceMemberInviteStatus | null;
134
+ }
135
+
136
+ /**
137
+ * Recent audit action attached to a member-detail response.
138
+ * Lighter projection than WorkspaceAuditEvent — no actor block (implied by caller).
139
+ */
140
+ export interface MemberRecentAction {
141
+ id: string;
142
+ timestamp: string;
143
+ action: string;
144
+ summary: string;
145
+ }
146
+
147
+ /**
148
+ * Full member detail, returned by GET /api/workspace/members/:userId and also
149
+ * the shape projected from /api/me for self-view.
150
+ */
151
+ export interface WorkspaceMemberDetail extends WorkspaceMember {
152
+ /** Full resolved scope patterns — union of grants from all assigned roles. */
153
+ effectiveScopes: string[];
154
+ /** Up to N most recent audit actions attributed to this member. */
155
+ recentActions: MemberRecentAction[];
156
+ }
157
+
158
+ /**
159
+ * Entry in the RBAC roles catalog (GET /api/rbac/roles).
160
+ */
161
+ export interface RoleCatalogEntry {
162
+ /** Canonical role name, e.g. 'org_owner'. */
163
+ name: string;
164
+ type: 'system' | 'custom';
165
+ /** One-line description sourced from system-roles.ts (or org-provided for custom). */
166
+ description: string;
167
+ /** Scope patterns granted by this role. May contain wildcards (e.g. 'org.view_*'). */
168
+ scopes: string[];
169
+ /** Number of active assignments in the current org. */
170
+ memberCount: number;
105
171
  }
106
172
 
107
173
  /**