@company-semantics/contracts 23.0.0 → 24.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@company-semantics/contracts",
3
- "version": "23.0.0",
3
+ "version": "24.0.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 = '0294f47290c0' as const;
3
- export const SPEC_HASH_FULL = '0294f47290c059e23186e9b25f6e0a476e304947f9ead66491ef4c29118e0609' as const;
2
+ export const SPEC_HASH = 'ca30049e5670' as const;
3
+ export const SPEC_HASH_FULL = 'ca30049e56707141ae807a8c218d97947e9aeade592540d5e2609eb985f43480' as const;
@@ -3697,25 +3697,62 @@ export interface components {
3697
3697
  SetMemberManagerResponse: {
3698
3698
  success: boolean;
3699
3699
  memberId: string;
3700
- managerUserId: string | null;
3700
+ manager: ({
3701
+ /** @constant */
3702
+ kind: "member";
3703
+ /** Format: uuid */
3704
+ userId: string;
3705
+ } | {
3706
+ /** @constant */
3707
+ kind: "open-role";
3708
+ /** Format: uuid */
3709
+ openRoleId: string;
3710
+ }) | null;
3701
3711
  relationshipType: string;
3702
3712
  message: string;
3703
3713
  };
3704
3714
  SetMemberManagerRequest: {
3705
- /** Format: uuid */
3706
- managerUserId: string;
3715
+ manager: {
3716
+ /** @constant */
3717
+ kind: "member";
3718
+ /** Format: uuid */
3719
+ userId: string;
3720
+ } | {
3721
+ /** @constant */
3722
+ kind: "open-role";
3723
+ /** Format: uuid */
3724
+ openRoleId: string;
3725
+ };
3707
3726
  };
3708
3727
  BulkReparentReportingResponse: {
3709
3728
  /** @constant */
3710
3729
  success: true;
3711
3730
  movedCount: number;
3712
- /** Format: uuid */
3713
- toManagerId: string;
3731
+ toManager: {
3732
+ /** @constant */
3733
+ kind: "member";
3734
+ /** Format: uuid */
3735
+ userId: string;
3736
+ } | {
3737
+ /** @constant */
3738
+ kind: "open-role";
3739
+ /** Format: uuid */
3740
+ openRoleId: string;
3741
+ };
3714
3742
  };
3715
3743
  BulkReparentReportingRequest: {
3716
3744
  memberIds: string[];
3717
- /** Format: uuid */
3718
- toManagerId: string;
3745
+ toManager: {
3746
+ /** @constant */
3747
+ kind: "member";
3748
+ /** Format: uuid */
3749
+ userId: string;
3750
+ } | {
3751
+ /** @constant */
3752
+ kind: "open-role";
3753
+ /** Format: uuid */
3754
+ openRoleId: string;
3755
+ };
3719
3756
  idempotencyKey: string;
3720
3757
  };
3721
3758
  SubmitInteractiveTaskResponse: {
@@ -4856,10 +4893,28 @@ export interface components {
4856
4893
  }[];
4857
4894
  }[];
4858
4895
  edges: {
4859
- /** Format: uuid */
4860
- reportUserId: string;
4861
- /** Format: uuid */
4862
- managerUserId: string;
4896
+ report: {
4897
+ /** @constant */
4898
+ kind: "member";
4899
+ /** Format: uuid */
4900
+ userId: string;
4901
+ } | {
4902
+ /** @constant */
4903
+ kind: "open-role";
4904
+ /** Format: uuid */
4905
+ openRoleId: string;
4906
+ };
4907
+ manager: {
4908
+ /** @constant */
4909
+ kind: "member";
4910
+ /** Format: uuid */
4911
+ userId: string;
4912
+ } | {
4913
+ /** @constant */
4914
+ kind: "open-role";
4915
+ /** Format: uuid */
4916
+ openRoleId: string;
4917
+ };
4863
4918
  /** @enum {string} */
4864
4919
  relationshipType: "solid" | "dotted";
4865
4920
  }[];
@@ -4869,7 +4924,17 @@ export interface components {
4869
4924
  /** Format: uuid */
4870
4925
  unitId: string;
4871
4926
  title: string | null;
4872
- reportsToUserId: string | null;
4927
+ reportsTo: ({
4928
+ /** @constant */
4929
+ kind: "member";
4930
+ /** Format: uuid */
4931
+ userId: string;
4932
+ } | {
4933
+ /** @constant */
4934
+ kind: "open-role";
4935
+ /** Format: uuid */
4936
+ openRoleId: string;
4937
+ }) | null;
4873
4938
  }[];
4874
4939
  };
4875
4940
  /** @description Polling snapshot of a generic ingestion operation. */
@@ -9018,7 +9083,17 @@ export interface operations {
9018
9083
  requestBody: {
9019
9084
  content: {
9020
9085
  "application/json": {
9021
- userId: string | null;
9086
+ manager: ({
9087
+ /** @constant */
9088
+ kind: "member";
9089
+ /** Format: uuid */
9090
+ userId: string;
9091
+ } | {
9092
+ /** @constant */
9093
+ kind: "open-role";
9094
+ /** Format: uuid */
9095
+ openRoleId: string;
9096
+ }) | null;
9022
9097
  };
9023
9098
  };
9024
9099
  };
@@ -49,6 +49,8 @@ TypeScript types and functions for user identity and display name resolution.
49
49
  - `MeResponse` _(type)_
50
50
  - `MeResponseSchema` — Full identity context returned by GET /api/me.
51
51
  - `NameSource` _(type)_ — Source of the user's name data.
52
+ - `OrgChartActorRef` _(type)_
53
+ - `OrgChartActorRefSchema`
52
54
  - `PeopleOrgChartEdge` _(type)_
53
55
  - `PeopleOrgChartEdgeSchema`
54
56
  - `PeopleOrgChartNode` _(type)_
@@ -64,6 +64,7 @@ export type {
64
64
  // People Org Chart (GET /api/users/org-chart)
65
65
  export {
66
66
  ReportingRelationshipTypeSchema,
67
+ OrgChartActorRefSchema,
67
68
  PeopleOrgChartNodeSchema,
68
69
  PeopleOrgChartOwnedUnitSchema,
69
70
  PeopleOrgChartEdgeSchema,
@@ -72,6 +73,7 @@ export {
72
73
  } from "./people-org-chart";
73
74
  export type {
74
75
  ReportingRelationshipType,
76
+ OrgChartActorRef,
75
77
  PeopleOrgChartNode,
76
78
  PeopleOrgChartOwnedUnit,
77
79
  PeopleOrgChartEdge,
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Org-chart actor reference — either endpoint of a reporting edge.
3
+ *
4
+ * A node in the people chart that can sit on EITHER side of a reporting edge: a
5
+ * filled member (keyed by occupant `userId`) OR an unfilled open-role seat
6
+ * (keyed by its own `openRoleId`). A vacant seat is a first-class reporting
7
+ * actor — it can be a manager that real people report to (ADR-BE-312), not just
8
+ * a report. The discriminant lets an edge point at either kind without losing
9
+ * what the id means. Mirrors the app's `ActorIdentity` shape exactly so the app
10
+ * consumes this type directly (one common spine across wire + UI).
11
+ *
12
+ * Lives in its own zero-dependency module (zod only) so both `people-org-chart`
13
+ * (which already depends on `org/schemas` for AuthorityMutability) and
14
+ * `org/schemas` (which needs it for the set-manager request/response) can import
15
+ * it without forming a module-init cycle.
16
+ */
17
+ import { z } from "zod";
18
+
19
+ export const OrgChartActorRefSchema = z.discriminatedUnion("kind", [
20
+ z.object({ kind: z.literal("member"), userId: z.string().uuid() }),
21
+ z.object({ kind: z.literal("open-role"), openRoleId: z.string().uuid() }),
22
+ ]);
23
+
24
+ export type OrgChartActorRef = z.infer<typeof OrgChartActorRefSchema>;
@@ -23,6 +23,15 @@ export type ReportingRelationshipType = z.infer<
23
23
  typeof ReportingRelationshipTypeSchema
24
24
  >;
25
25
 
26
+ // Actor reference — either endpoint of a reporting edge (member | open-role).
27
+ // Defined in its own zero-dependency module to avoid a module-init cycle with
28
+ // `org/schemas` (which this file imports AuthorityMutabilitySchema from, and
29
+ // which needs the actor ref for the set-manager request/response). Re-exported
30
+ // here so the existing import site keeps working.
31
+ export { OrgChartActorRefSchema } from "./org-chart-actor";
32
+ export type { OrgChartActorRef } from "./org-chart-actor";
33
+ import { OrgChartActorRefSchema } from "./org-chart-actor";
34
+
26
35
  // ---------------------------------------------------------------------------
27
36
  // Node — a person in the chart
28
37
  // ---------------------------------------------------------------------------
@@ -68,8 +77,12 @@ export type PeopleOrgChartNode = z.infer<typeof PeopleOrgChartNodeSchema>;
68
77
  // ---------------------------------------------------------------------------
69
78
 
70
79
  export const PeopleOrgChartEdgeSchema = z.object({
71
- reportUserId: z.string().uuid(),
72
- managerUserId: z.string().uuid(),
80
+ // Either endpoint may be a member or an open-role seat. An edge whose
81
+ // `manager` is an open-role seat is "a person reports to a vacant role"
82
+ // (ADR-BE-312); whose `report` is an open-role seat is "an open role reports
83
+ // to someone" (ADR-BE-291) — both are now expressible symmetrically.
84
+ report: OrgChartActorRefSchema,
85
+ manager: OrgChartActorRefSchema,
73
86
  relationshipType: ReportingRelationshipTypeSchema,
74
87
  });
75
88
 
@@ -79,7 +92,7 @@ export type PeopleOrgChartEdge = z.infer<typeof PeopleOrgChartEdgeSchema>;
79
92
  // Open role — a persisted placeholder seat rendered as a dashed "Open role"
80
93
  // card in its unit's sibling column. Only active roles (open + hiring) are
81
94
  // included; filled/closed roles never appear here. `unitId` seats the card in
82
- // the right column. `reportsToUserId` is the open role's OWN reporting edge
95
+ // the right column. `reportsTo` is the open role's OWN reporting edge
83
96
  // (ADR-BE-291): it defaults to the role's creator and is editable/clearable, so
84
97
  // a person-less seat is placed by reporting like everyone else (the chart owns
85
98
  // placement, ADR-CTRL-159). Null → the role hangs in its unit's projection-only
@@ -90,7 +103,10 @@ export const PeopleOrgChartOpenRoleSchema = z.object({
90
103
  id: z.string().uuid(),
91
104
  unitId: z.string().uuid(),
92
105
  title: z.string().nullable(),
93
- reportsToUserId: z.string().uuid().nullable(),
106
+ // The open role's OWN reporting edge (ADR-BE-291). An actor ref so an open
107
+ // role can report to a person OR to another open-role seat (ADR-BE-312). Null
108
+ // → the role hangs in its unit's projection-only Unassigned bucket.
109
+ reportsTo: OrgChartActorRefSchema.nullable(),
94
110
  });
95
111
 
96
112
  export type PeopleOrgChartOpenRole = z.infer<
@@ -103,7 +119,7 @@ export type PeopleOrgChartOpenRole = z.infer<
103
119
  //
104
120
  // Person-less cards (empty-unit placeholders, ghosts, open roles) no longer
105
121
  // anchor under a stored unit-head "tether" (ADR-BE-284, retired by ADR-BE-292).
106
- // Open roles carry their own `reportsToUserId` edge; placeholders fall back to
122
+ // Open roles carry their own `reportsTo` edge; placeholders fall back to
107
123
  // the render-time reporting heuristic.
108
124
 
109
125
  export const PeopleOrgChartResponseSchema = z.object({
package/src/index.ts CHANGED
@@ -175,6 +175,7 @@ export type {
175
175
  // People Org Chart (GET /api/users/org-chart)
176
176
  export {
177
177
  ReportingRelationshipTypeSchema,
178
+ OrgChartActorRefSchema,
178
179
  PeopleOrgChartNodeSchema,
179
180
  PeopleOrgChartOwnedUnitSchema,
180
181
  PeopleOrgChartEdgeSchema,
@@ -183,6 +184,7 @@ export {
183
184
  } from "./identity/index";
184
185
  export type {
185
186
  ReportingRelationshipType,
187
+ OrgChartActorRef,
186
188
  PeopleOrgChartNode,
187
189
  PeopleOrgChartOwnedUnit,
188
190
  PeopleOrgChartEdge,
package/src/org/README.md CHANGED
@@ -247,7 +247,7 @@ Shared type vocabulary for organization ownership, type classification, and tran
247
247
  - `SetActiveOrgResponse` _(type)_
248
248
  - `SetActiveOrgResponseSchema`
249
249
  - `SetMemberManagerResponse` _(type)_
250
- - `SetMemberManagerResponseSchema` — Response for setting (PATCH) or clearing (DELETE) a member's solid-line manager — the person-to-person
250
+ - `SetMemberManagerResponseSchema` — Response for setting (PATCH) or clearing (DELETE) a member's solid-line manager — the reporting edge that the
251
251
  - `SharePolicy` _(type)_ — Document sharing policy. - restricted: Only explicit ACL + owning unit + org admins - orgread: All org…
252
252
  - `ShareState` _(type)_ — Complete sharing state for a document.
253
253
  - `SourceAuthority` _(type)_
@@ -336,6 +336,7 @@ Shared type vocabulary for organization ownership, type classification, and tran
336
336
  **Internal domains:**
337
337
 
338
338
  - `api`
339
+ - `identity`
339
340
  - `permissions`
340
341
 
341
342
  **External packages:**
@@ -13,6 +13,7 @@
13
13
  import { z } from "zod";
14
14
  import { CursorPageSchema } from "../api/primitives";
15
15
  import { OrgChartRoleSchema } from "../permissions/orgchart-roles";
16
+ import { OrgChartActorRefSchema } from "../identity/org-chart-actor";
16
17
 
17
18
  // ---------------------------------------------------------------------------
18
19
  // Sub-schemas
@@ -505,8 +506,10 @@ export type ChangeMemberRoleResponse = z.infer<
505
506
 
506
507
  /**
507
508
  * Response for setting (PATCH) or clearing (DELETE) a member's solid-line
508
- * manager — the person-to-person reporting edge (`user_reporting`) that the
509
- * org chart is built from. `managerUserId` is null after a clear.
509
+ * manager — the reporting edge that the org chart is built from. `manager` is
510
+ * the actor the member now reports to: a `member` (person→person) OR an
511
+ * `open-role` seat (person reports to a vacant role — ADR-BE-312); null after a
512
+ * clear.
510
513
  *
511
514
  * Distinct from team membership (RBAC scopes) and `primary_unit_id` (home
512
515
  * unit): neither of those places a person in the reporting hierarchy.
@@ -515,7 +518,7 @@ export type ChangeMemberRoleResponse = z.infer<
515
518
  export const SetMemberManagerResponseSchema = z.object({
516
519
  success: z.boolean(),
517
520
  memberId: z.string(),
518
- managerUserId: z.string().nullable(),
521
+ manager: OrgChartActorRefSchema.nullable(),
519
522
  relationshipType: z.string(),
520
523
  message: z.string(),
521
524
  });