@company-semantics/contracts 25.0.0 → 26.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": "25.0.0",
3
+ "version": "26.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 = 'ca30049e5670' as const;
3
- export const SPEC_HASH_FULL = 'ca30049e56707141ae807a8c218d97947e9aeade592540d5e2609eb985f43480' as const;
2
+ export const SPEC_HASH = '62fe60545526' as const;
3
+ export const SPEC_HASH_FULL = '62fe605455264b2246bb353c63b3e8905e7e2e22504f193dc15cce1edd34e68f' as const;
@@ -2144,6 +2144,40 @@ export interface paths {
2144
2144
  patch?: never;
2145
2145
  trace?: never;
2146
2146
  };
2147
+ "/api/org-units/{unitId}/open-roles/{roleId}/unit": {
2148
+ parameters: {
2149
+ query?: never;
2150
+ header?: never;
2151
+ path?: never;
2152
+ cookie?: never;
2153
+ };
2154
+ get?: never;
2155
+ /** Move an open role to a different unit (set the seat's unit) */
2156
+ put: operations["setOrgUnitOpenRoleUnit"];
2157
+ post?: never;
2158
+ delete?: never;
2159
+ options?: never;
2160
+ head?: never;
2161
+ patch?: never;
2162
+ trace?: never;
2163
+ };
2164
+ "/api/org-units/{unitId}/open-roles/{roleId}/title": {
2165
+ parameters: {
2166
+ query?: never;
2167
+ header?: never;
2168
+ path?: never;
2169
+ cookie?: never;
2170
+ };
2171
+ get?: never;
2172
+ /** Set an open role's seat title */
2173
+ put: operations["setOrgUnitOpenRoleTitle"];
2174
+ post?: never;
2175
+ delete?: never;
2176
+ options?: never;
2177
+ head?: never;
2178
+ patch?: never;
2179
+ trace?: never;
2180
+ };
2147
2181
  "/api/users/org-chart": {
2148
2182
  parameters: {
2149
2183
  query?: never;
@@ -4877,6 +4911,38 @@ export interface components {
4877
4911
  };
4878
4912
  };
4879
4913
  PeopleOrgChartResponse: {
4914
+ seats: {
4915
+ /** Format: uuid */
4916
+ id: string;
4917
+ /** Format: uuid */
4918
+ unitId: string;
4919
+ title: string | null;
4920
+ /** @enum {string} */
4921
+ status: "planned" | "open" | "filled" | "closed";
4922
+ hiring: boolean;
4923
+ occupants: {
4924
+ /** Format: uuid */
4925
+ userId: string;
4926
+ fullName: string;
4927
+ avatarUrl: string | null;
4928
+ primaryUnitId: string | null;
4929
+ ownedUnits: {
4930
+ /** Format: uuid */
4931
+ id: string;
4932
+ name: string;
4933
+ /** @enum {string} */
4934
+ mutability: "derived" | "user_managed";
4935
+ }[];
4936
+ }[];
4937
+ }[];
4938
+ seatEdges: {
4939
+ /** Format: uuid */
4940
+ reportPositionId: string;
4941
+ /** Format: uuid */
4942
+ managerPositionId: string;
4943
+ /** @enum {string} */
4944
+ relationshipType: "solid" | "dotted";
4945
+ }[];
4880
4946
  nodes: {
4881
4947
  /** Format: uuid */
4882
4948
  id: string;
@@ -9109,6 +9175,65 @@ export interface operations {
9109
9175
  };
9110
9176
  };
9111
9177
  };
9178
+ setOrgUnitOpenRoleUnit: {
9179
+ parameters: {
9180
+ query?: never;
9181
+ header?: never;
9182
+ path: {
9183
+ unitId: string;
9184
+ roleId: string;
9185
+ };
9186
+ cookie?: never;
9187
+ };
9188
+ requestBody: {
9189
+ content: {
9190
+ "application/json": {
9191
+ /** Format: uuid */
9192
+ unitId: string;
9193
+ };
9194
+ };
9195
+ };
9196
+ responses: {
9197
+ /** @description Open role moved to the destination unit */
9198
+ 200: {
9199
+ headers: {
9200
+ [name: string]: unknown;
9201
+ };
9202
+ content: {
9203
+ "application/json": components["schemas"]["OpenRoleResponse"];
9204
+ };
9205
+ };
9206
+ };
9207
+ };
9208
+ setOrgUnitOpenRoleTitle: {
9209
+ parameters: {
9210
+ query?: never;
9211
+ header?: never;
9212
+ path: {
9213
+ unitId: string;
9214
+ roleId: string;
9215
+ };
9216
+ cookie?: never;
9217
+ };
9218
+ requestBody: {
9219
+ content: {
9220
+ "application/json": {
9221
+ title: string | null;
9222
+ };
9223
+ };
9224
+ };
9225
+ responses: {
9226
+ /** @description Open role with updated title */
9227
+ 200: {
9228
+ headers: {
9229
+ [name: string]: unknown;
9230
+ };
9231
+ content: {
9232
+ "application/json": components["schemas"]["OpenRoleResponse"];
9233
+ };
9234
+ };
9235
+ };
9236
+ };
9112
9237
  getPeopleOrgChart: {
9113
9238
  parameters: {
9114
9239
  query?: never;
@@ -22,6 +22,7 @@ export const openApiRoutes = {
22
22
  '/api/chats/{id}/messages/{messageId}': ['DELETE'],
23
23
  '/api/chats/{id}/pin': ['DELETE', 'POST'],
24
24
  '/api/company-md/context-bank': ['POST'],
25
+ '/api/company-md/context-bank/search': ['GET'],
25
26
  '/api/company-md/docs/{id}': ['GET'],
26
27
  '/api/company-md/docs/{id}/content': ['PUT'],
27
28
  '/api/company-md/docs/{id}/context-bank': ['GET'],
@@ -54,6 +55,7 @@ export const openApiRoutes = {
54
55
  '/api/executions/{executionId}/timeline': ['GET'],
55
56
  '/api/executions/{executionId}/undo': ['POST'],
56
57
  '/api/factory/floor': ['GET'],
58
+ '/api/factory/kpis': ['GET'],
57
59
  '/api/factory/snapshot': ['GET'],
58
60
  '/api/ingestion/operations/{id}': ['GET'],
59
61
  '/api/internal-admin/impersonate/end': ['POST'],
@@ -61,6 +61,14 @@ TypeScript types and functions for user identity and display name resolution.
61
61
  - `PeopleOrgChartOwnedUnitSchema`
62
62
  - `PeopleOrgChartResponse` _(type)_
63
63
  - `PeopleOrgChartResponseSchema`
64
+ - `PeopleOrgChartSeat` _(type)_
65
+ - `PeopleOrgChartSeatEdge` _(type)_
66
+ - `PeopleOrgChartSeatEdgeSchema`
67
+ - `PeopleOrgChartSeatOccupant` _(type)_
68
+ - `PeopleOrgChartSeatOccupantSchema`
69
+ - `PeopleOrgChartSeatSchema`
70
+ - `PeopleOrgChartSeatStatus` _(type)_
71
+ - `PeopleOrgChartSeatStatusSchema`
64
72
  - `Person` _(type)_
65
73
  - `PersonSchema`
66
74
  - `ProfileResponse` _(type)_
@@ -69,6 +69,10 @@ export {
69
69
  PeopleOrgChartOwnedUnitSchema,
70
70
  PeopleOrgChartEdgeSchema,
71
71
  PeopleOrgChartOpenRoleSchema,
72
+ PeopleOrgChartSeatStatusSchema,
73
+ PeopleOrgChartSeatOccupantSchema,
74
+ PeopleOrgChartSeatSchema,
75
+ PeopleOrgChartSeatEdgeSchema,
72
76
  PeopleOrgChartResponseSchema,
73
77
  } from "./people-org-chart";
74
78
  export type {
@@ -78,6 +82,10 @@ export type {
78
82
  PeopleOrgChartOwnedUnit,
79
83
  PeopleOrgChartEdge,
80
84
  PeopleOrgChartOpenRole,
85
+ PeopleOrgChartSeatStatus,
86
+ PeopleOrgChartSeatOccupant,
87
+ PeopleOrgChartSeat,
88
+ PeopleOrgChartSeatEdge,
81
89
  PeopleOrgChartResponse,
82
90
  } from "./people-org-chart";
83
91
 
@@ -113,6 +113,93 @@ export type PeopleOrgChartOpenRole = z.infer<
113
113
  typeof PeopleOrgChartOpenRoleSchema
114
114
  >;
115
115
 
116
+ // ---------------------------------------------------------------------------
117
+ // Seat — the position-centric unification (ADR-CONT-093)
118
+ // ---------------------------------------------------------------------------
119
+ //
120
+ // A `PeopleOrgChartSeat` is the unified chart actor: a `positions` row carrying
121
+ // its SEAT-SCOPED attributes (unit placement, title, seat-existence status,
122
+ // hiring/staffing sub-state) plus an `occupants[]` array of PERSON-SCOPED
123
+ // attributes for whoever currently holds it. The split is structural, not
124
+ // member-vs-open-role: a VACANT seat (`occupants: []`) is the old "open role";
125
+ // an OCCUPIED seat (`occupants.length >= 1`) is the old "member" (N occupants
126
+ // for a co-occupied seat — forward-compatible; live data is 0/1). Reporting is
127
+ // expressed seat→seat in `seatEdges[]`, NOT on the seat, so the edge list stays
128
+ // the single source of truth for placement (ADR-CTRL-159). `OrgChartActorRef`
129
+ // is retained write-only (set-manager request/response) and is removed from
130
+ // this read model.
131
+ //
132
+ // This pair (`seats[]` + `seatEdges[]`) is ADDITIVE alongside the legacy
133
+ // `nodes`/`edges`/`openRoles` during the transition; the projector dual-emits
134
+ // both from one position pass. A later breaking minor removes the legacy half.
135
+
136
+ export const PeopleOrgChartSeatStatusSchema = z.enum([
137
+ "planned",
138
+ "open",
139
+ "filled",
140
+ "closed",
141
+ ]);
142
+ export type PeopleOrgChartSeatStatus = z.infer<
143
+ typeof PeopleOrgChartSeatStatusSchema
144
+ >;
145
+
146
+ // Person-scoped attributes of a seat's holder — keyed by `userId`, they travel
147
+ // with the person across seats (ADR-BE-329: a vacant seat grants none of these
148
+ // by construction). Mirrors the legacy `PeopleOrgChartNode` person fields.
149
+ export const PeopleOrgChartSeatOccupantSchema = z.object({
150
+ userId: z.string().uuid(),
151
+ fullName: z.string(),
152
+ avatarUrl: z.string().nullable(),
153
+ // Stable HOME unit (home_assignments), not the seat unit — mirrors the legacy
154
+ // node's `primaryUnitId`. Null ⇒ no home assignment.
155
+ primaryUnitId: z.string().uuid().nullable(),
156
+ // Units this occupant is a local structural owner of (ADR-BE-168). Empty ⇒
157
+ // not a unit owner. Same shape + semantics as the legacy node's `ownedUnits`.
158
+ ownedUnits: z.array(PeopleOrgChartOwnedUnitSchema),
159
+ });
160
+
161
+ export type PeopleOrgChartSeatOccupant = z.infer<
162
+ typeof PeopleOrgChartSeatOccupantSchema
163
+ >;
164
+
165
+ export const PeopleOrgChartSeatSchema = z.object({
166
+ // positionId — the seat identity (stable across occupancy changes).
167
+ id: z.string().uuid(),
168
+ // positions.unit_id — the seat's placement column. The chart columns a seat by
169
+ // this unit regardless of occupancy.
170
+ unitId: z.string().uuid(),
171
+ // positions.title — '' is mapped to null to preserve the legacy nullable wire
172
+ // shape (ADR-BE-312). Seat-scoped, NOT the occupant's member-display jobTitle.
173
+ title: z.string().nullable(),
174
+ // Seat-existence lifecycle (ADR-CTRL-182).
175
+ status: PeopleOrgChartSeatStatusSchema,
176
+ // Staffing sub-state: `position_fulfillment.status != 'inactive'` (ADR-BE-312).
177
+ // Orthogonal to `status` — "are we trying to staff this seat?". An absent
178
+ // fulfillment row ⇒ false.
179
+ hiring: z.boolean(),
180
+ // The seat's current holders. [] ⇒ vacant (the old "open role"); >= 1 ⇒
181
+ // occupied (the old "member"). Only account-linked, active/interim occupants
182
+ // appear, mirroring the legacy node-keying.
183
+ occupants: z.array(PeopleOrgChartSeatOccupantSchema),
184
+ });
185
+
186
+ export type PeopleOrgChartSeat = z.infer<typeof PeopleOrgChartSeatSchema>;
187
+
188
+ // A seat→seat reporting edge — one row per `position_reporting` row (NOT a
189
+ // member cross-product). Endpoints are positionIds; resolve each to its seat in
190
+ // `seats[]`. Mirrors the legacy person-keyed `PeopleOrgChartEdge`, but keyed by
191
+ // the stable seat identity so a vacant seat's edge is expressible without an
192
+ // `OrgChartActorRef`.
193
+ export const PeopleOrgChartSeatEdgeSchema = z.object({
194
+ reportPositionId: z.string().uuid(),
195
+ managerPositionId: z.string().uuid(),
196
+ relationshipType: ReportingRelationshipTypeSchema,
197
+ });
198
+
199
+ export type PeopleOrgChartSeatEdge = z.infer<
200
+ typeof PeopleOrgChartSeatEdgeSchema
201
+ >;
202
+
116
203
  // ---------------------------------------------------------------------------
117
204
  // GET /api/users/org-chart
118
205
  // ---------------------------------------------------------------------------
@@ -123,6 +210,16 @@ export type PeopleOrgChartOpenRole = z.infer<
123
210
  // the render-time reporting heuristic.
124
211
 
125
212
  export const PeopleOrgChartResponseSchema = z.object({
213
+ // Position-centric unified view (ADR-CONT-093). `seats[]` carries every chart
214
+ // actor (occupied or vacant) and `seatEdges[]` the seat→seat reporting graph.
215
+ // ADDITIVE alongside the legacy fields below during the transition; a later
216
+ // breaking minor removes the legacy half.
217
+ seats: z.array(PeopleOrgChartSeatSchema),
218
+ seatEdges: z.array(PeopleOrgChartSeatEdgeSchema),
219
+ // Legacy, transitional (ADR-CONT-093 supersedes). Derived from the same
220
+ // position pass as `seats`/`seatEdges`; consumers should migrate to the seat
221
+ // model. `nodes` = occupied actors, `openRoles` = vacant 'open' actors,
222
+ // `edges` = the same reporting graph keyed by person/open-role actor refs.
126
223
  nodes: z.array(PeopleOrgChartNodeSchema),
127
224
  edges: z.array(PeopleOrgChartEdgeSchema),
128
225
  openRoles: z.array(PeopleOrgChartOpenRoleSchema),
package/src/index.ts CHANGED
@@ -180,6 +180,10 @@ export {
180
180
  PeopleOrgChartOwnedUnitSchema,
181
181
  PeopleOrgChartEdgeSchema,
182
182
  PeopleOrgChartOpenRoleSchema,
183
+ PeopleOrgChartSeatStatusSchema,
184
+ PeopleOrgChartSeatOccupantSchema,
185
+ PeopleOrgChartSeatSchema,
186
+ PeopleOrgChartSeatEdgeSchema,
183
187
  PeopleOrgChartResponseSchema,
184
188
  } from "./identity/index";
185
189
  export type {
@@ -189,6 +193,10 @@ export type {
189
193
  PeopleOrgChartOwnedUnit,
190
194
  PeopleOrgChartEdge,
191
195
  PeopleOrgChartOpenRole,
196
+ PeopleOrgChartSeatStatus,
197
+ PeopleOrgChartSeatOccupant,
198
+ PeopleOrgChartSeat,
199
+ PeopleOrgChartSeatEdge,
192
200
  PeopleOrgChartResponse,
193
201
  } from "./identity/index";
194
202