@company-semantics/contracts 25.0.0 → 26.1.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 +1 -1
- package/src/api/generated-spec-hash.ts +2 -2
- package/src/api/generated.ts +321 -0
- package/src/generated/openapi-routes.ts +6 -0
- package/src/identity/README.md +8 -0
- package/src/identity/index.ts +8 -0
- package/src/identity/people-org-chart.ts +97 -0
- package/src/index.ts +8 -0
package/package.json
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// AUTO-GENERATED — do not edit. Run pnpm generate:spec-hash to regenerate.
|
|
2
|
-
export const SPEC_HASH = '
|
|
3
|
-
export const SPEC_HASH_FULL = '
|
|
2
|
+
export const SPEC_HASH = 'eb984ad65268' as const;
|
|
3
|
+
export const SPEC_HASH_FULL = 'eb984ad65268ce0b6877c26b331bef135bab04876e6fe9aa732844cd52f29353' as const;
|
package/src/api/generated.ts
CHANGED
|
@@ -1593,6 +1593,58 @@ export interface paths {
|
|
|
1593
1593
|
patch?: never;
|
|
1594
1594
|
trace?: never;
|
|
1595
1595
|
};
|
|
1596
|
+
"/api/company-md/docs/{id}/access-requests": {
|
|
1597
|
+
parameters: {
|
|
1598
|
+
query?: never;
|
|
1599
|
+
header?: never;
|
|
1600
|
+
path?: never;
|
|
1601
|
+
cookie?: never;
|
|
1602
|
+
};
|
|
1603
|
+
/** List a node’s access requests (owner inbox) */
|
|
1604
|
+
get: operations["listCompanyMdAccessRequests"];
|
|
1605
|
+
put?: never;
|
|
1606
|
+
/** Request access to a locked company.md node */
|
|
1607
|
+
post: operations["createCompanyMdAccessRequest"];
|
|
1608
|
+
delete?: never;
|
|
1609
|
+
options?: never;
|
|
1610
|
+
head?: never;
|
|
1611
|
+
patch?: never;
|
|
1612
|
+
trace?: never;
|
|
1613
|
+
};
|
|
1614
|
+
"/api/company-md/access-requests/{id}/approve": {
|
|
1615
|
+
parameters: {
|
|
1616
|
+
query?: never;
|
|
1617
|
+
header?: never;
|
|
1618
|
+
path?: never;
|
|
1619
|
+
cookie?: never;
|
|
1620
|
+
};
|
|
1621
|
+
get?: never;
|
|
1622
|
+
put?: never;
|
|
1623
|
+
/** Approve an access request (first owner wins; mints a grant) */
|
|
1624
|
+
post: operations["approveCompanyMdAccessRequest"];
|
|
1625
|
+
delete?: never;
|
|
1626
|
+
options?: never;
|
|
1627
|
+
head?: never;
|
|
1628
|
+
patch?: never;
|
|
1629
|
+
trace?: never;
|
|
1630
|
+
};
|
|
1631
|
+
"/api/company-md/access-requests/{id}/deny": {
|
|
1632
|
+
parameters: {
|
|
1633
|
+
query?: never;
|
|
1634
|
+
header?: never;
|
|
1635
|
+
path?: never;
|
|
1636
|
+
cookie?: never;
|
|
1637
|
+
};
|
|
1638
|
+
get?: never;
|
|
1639
|
+
put?: never;
|
|
1640
|
+
/** Deny an access request (first owner wins) */
|
|
1641
|
+
post: operations["denyCompanyMdAccessRequest"];
|
|
1642
|
+
delete?: never;
|
|
1643
|
+
options?: never;
|
|
1644
|
+
head?: never;
|
|
1645
|
+
patch?: never;
|
|
1646
|
+
trace?: never;
|
|
1647
|
+
};
|
|
1596
1648
|
"/api/company-md/search": {
|
|
1597
1649
|
parameters: {
|
|
1598
1650
|
query?: never;
|
|
@@ -2144,6 +2196,40 @@ export interface paths {
|
|
|
2144
2196
|
patch?: never;
|
|
2145
2197
|
trace?: never;
|
|
2146
2198
|
};
|
|
2199
|
+
"/api/org-units/{unitId}/open-roles/{roleId}/unit": {
|
|
2200
|
+
parameters: {
|
|
2201
|
+
query?: never;
|
|
2202
|
+
header?: never;
|
|
2203
|
+
path?: never;
|
|
2204
|
+
cookie?: never;
|
|
2205
|
+
};
|
|
2206
|
+
get?: never;
|
|
2207
|
+
/** Move an open role to a different unit (set the seat's unit) */
|
|
2208
|
+
put: operations["setOrgUnitOpenRoleUnit"];
|
|
2209
|
+
post?: never;
|
|
2210
|
+
delete?: never;
|
|
2211
|
+
options?: never;
|
|
2212
|
+
head?: never;
|
|
2213
|
+
patch?: never;
|
|
2214
|
+
trace?: never;
|
|
2215
|
+
};
|
|
2216
|
+
"/api/org-units/{unitId}/open-roles/{roleId}/title": {
|
|
2217
|
+
parameters: {
|
|
2218
|
+
query?: never;
|
|
2219
|
+
header?: never;
|
|
2220
|
+
path?: never;
|
|
2221
|
+
cookie?: never;
|
|
2222
|
+
};
|
|
2223
|
+
get?: never;
|
|
2224
|
+
/** Set an open role's seat title */
|
|
2225
|
+
put: operations["setOrgUnitOpenRoleTitle"];
|
|
2226
|
+
post?: never;
|
|
2227
|
+
delete?: never;
|
|
2228
|
+
options?: never;
|
|
2229
|
+
head?: never;
|
|
2230
|
+
patch?: never;
|
|
2231
|
+
trace?: never;
|
|
2232
|
+
};
|
|
2147
2233
|
"/api/users/org-chart": {
|
|
2148
2234
|
parameters: {
|
|
2149
2235
|
query?: never;
|
|
@@ -4341,6 +4427,16 @@ export interface components {
|
|
|
4341
4427
|
/** Format: uuid */
|
|
4342
4428
|
toUserId: string;
|
|
4343
4429
|
};
|
|
4430
|
+
AccessRequestCreate: {
|
|
4431
|
+
message?: string;
|
|
4432
|
+
};
|
|
4433
|
+
ApproveAccessRequest: {
|
|
4434
|
+
/** @enum {string} */
|
|
4435
|
+
accessLevel: "editor" | "commenter" | "viewer";
|
|
4436
|
+
};
|
|
4437
|
+
DenyAccessRequest: {
|
|
4438
|
+
reason?: string;
|
|
4439
|
+
};
|
|
4344
4440
|
/** @description Ranked retrieval hits plus the source kinds actually searched. */
|
|
4345
4441
|
CompanyMdSearchResponse: {
|
|
4346
4442
|
hits: {
|
|
@@ -4877,6 +4973,38 @@ export interface components {
|
|
|
4877
4973
|
};
|
|
4878
4974
|
};
|
|
4879
4975
|
PeopleOrgChartResponse: {
|
|
4976
|
+
seats: {
|
|
4977
|
+
/** Format: uuid */
|
|
4978
|
+
id: string;
|
|
4979
|
+
/** Format: uuid */
|
|
4980
|
+
unitId: string;
|
|
4981
|
+
title: string | null;
|
|
4982
|
+
/** @enum {string} */
|
|
4983
|
+
status: "planned" | "open" | "filled" | "closed";
|
|
4984
|
+
hiring: boolean;
|
|
4985
|
+
occupants: {
|
|
4986
|
+
/** Format: uuid */
|
|
4987
|
+
userId: string;
|
|
4988
|
+
fullName: string;
|
|
4989
|
+
avatarUrl: string | null;
|
|
4990
|
+
primaryUnitId: string | null;
|
|
4991
|
+
ownedUnits: {
|
|
4992
|
+
/** Format: uuid */
|
|
4993
|
+
id: string;
|
|
4994
|
+
name: string;
|
|
4995
|
+
/** @enum {string} */
|
|
4996
|
+
mutability: "derived" | "user_managed";
|
|
4997
|
+
}[];
|
|
4998
|
+
}[];
|
|
4999
|
+
}[];
|
|
5000
|
+
seatEdges: {
|
|
5001
|
+
/** Format: uuid */
|
|
5002
|
+
reportPositionId: string;
|
|
5003
|
+
/** Format: uuid */
|
|
5004
|
+
managerPositionId: string;
|
|
5005
|
+
/** @enum {string} */
|
|
5006
|
+
relationshipType: "solid" | "dotted";
|
|
5007
|
+
}[];
|
|
4880
5008
|
nodes: {
|
|
4881
5009
|
/** Format: uuid */
|
|
4882
5010
|
id: string;
|
|
@@ -8063,6 +8191,140 @@ export interface operations {
|
|
|
8063
8191
|
};
|
|
8064
8192
|
};
|
|
8065
8193
|
};
|
|
8194
|
+
listCompanyMdAccessRequests: {
|
|
8195
|
+
parameters: {
|
|
8196
|
+
query?: never;
|
|
8197
|
+
header?: never;
|
|
8198
|
+
path: {
|
|
8199
|
+
id: string;
|
|
8200
|
+
};
|
|
8201
|
+
cookie?: never;
|
|
8202
|
+
};
|
|
8203
|
+
requestBody?: never;
|
|
8204
|
+
responses: {
|
|
8205
|
+
/** @description Access requests for the node, with requestor identity */
|
|
8206
|
+
200: {
|
|
8207
|
+
headers: {
|
|
8208
|
+
[name: string]: unknown;
|
|
8209
|
+
};
|
|
8210
|
+
content?: never;
|
|
8211
|
+
};
|
|
8212
|
+
/** @description Caller cannot manage sharing for this node */
|
|
8213
|
+
403: {
|
|
8214
|
+
headers: {
|
|
8215
|
+
[name: string]: unknown;
|
|
8216
|
+
};
|
|
8217
|
+
content?: never;
|
|
8218
|
+
};
|
|
8219
|
+
};
|
|
8220
|
+
};
|
|
8221
|
+
createCompanyMdAccessRequest: {
|
|
8222
|
+
parameters: {
|
|
8223
|
+
query?: never;
|
|
8224
|
+
header?: never;
|
|
8225
|
+
path: {
|
|
8226
|
+
id: string;
|
|
8227
|
+
};
|
|
8228
|
+
cookie?: never;
|
|
8229
|
+
};
|
|
8230
|
+
requestBody: {
|
|
8231
|
+
content: {
|
|
8232
|
+
"application/json": components["schemas"]["AccessRequestCreate"];
|
|
8233
|
+
};
|
|
8234
|
+
};
|
|
8235
|
+
responses: {
|
|
8236
|
+
/** @description Pending access request created (or the existing pending request) */
|
|
8237
|
+
201: {
|
|
8238
|
+
headers: {
|
|
8239
|
+
[name: string]: unknown;
|
|
8240
|
+
};
|
|
8241
|
+
content?: never;
|
|
8242
|
+
};
|
|
8243
|
+
/** @description Cannot request access (already a reader, or no-leak node) */
|
|
8244
|
+
403: {
|
|
8245
|
+
headers: {
|
|
8246
|
+
[name: string]: unknown;
|
|
8247
|
+
};
|
|
8248
|
+
content?: never;
|
|
8249
|
+
};
|
|
8250
|
+
};
|
|
8251
|
+
};
|
|
8252
|
+
approveCompanyMdAccessRequest: {
|
|
8253
|
+
parameters: {
|
|
8254
|
+
query?: never;
|
|
8255
|
+
header?: never;
|
|
8256
|
+
path: {
|
|
8257
|
+
id: string;
|
|
8258
|
+
};
|
|
8259
|
+
cookie?: never;
|
|
8260
|
+
};
|
|
8261
|
+
requestBody: {
|
|
8262
|
+
content: {
|
|
8263
|
+
"application/json": components["schemas"]["ApproveAccessRequest"];
|
|
8264
|
+
};
|
|
8265
|
+
};
|
|
8266
|
+
responses: {
|
|
8267
|
+
/** @description Approved; the requester gains a normal grant */
|
|
8268
|
+
200: {
|
|
8269
|
+
headers: {
|
|
8270
|
+
[name: string]: unknown;
|
|
8271
|
+
};
|
|
8272
|
+
content?: never;
|
|
8273
|
+
};
|
|
8274
|
+
/** @description Request not found */
|
|
8275
|
+
404: {
|
|
8276
|
+
headers: {
|
|
8277
|
+
[name: string]: unknown;
|
|
8278
|
+
};
|
|
8279
|
+
content?: never;
|
|
8280
|
+
};
|
|
8281
|
+
/** @description Already resolved by another owner */
|
|
8282
|
+
409: {
|
|
8283
|
+
headers: {
|
|
8284
|
+
[name: string]: unknown;
|
|
8285
|
+
};
|
|
8286
|
+
content?: never;
|
|
8287
|
+
};
|
|
8288
|
+
};
|
|
8289
|
+
};
|
|
8290
|
+
denyCompanyMdAccessRequest: {
|
|
8291
|
+
parameters: {
|
|
8292
|
+
query?: never;
|
|
8293
|
+
header?: never;
|
|
8294
|
+
path: {
|
|
8295
|
+
id: string;
|
|
8296
|
+
};
|
|
8297
|
+
cookie?: never;
|
|
8298
|
+
};
|
|
8299
|
+
requestBody: {
|
|
8300
|
+
content: {
|
|
8301
|
+
"application/json": components["schemas"]["DenyAccessRequest"];
|
|
8302
|
+
};
|
|
8303
|
+
};
|
|
8304
|
+
responses: {
|
|
8305
|
+
/** @description Denied */
|
|
8306
|
+
200: {
|
|
8307
|
+
headers: {
|
|
8308
|
+
[name: string]: unknown;
|
|
8309
|
+
};
|
|
8310
|
+
content?: never;
|
|
8311
|
+
};
|
|
8312
|
+
/** @description Request not found */
|
|
8313
|
+
404: {
|
|
8314
|
+
headers: {
|
|
8315
|
+
[name: string]: unknown;
|
|
8316
|
+
};
|
|
8317
|
+
content?: never;
|
|
8318
|
+
};
|
|
8319
|
+
/** @description Already resolved by another owner */
|
|
8320
|
+
409: {
|
|
8321
|
+
headers: {
|
|
8322
|
+
[name: string]: unknown;
|
|
8323
|
+
};
|
|
8324
|
+
content?: never;
|
|
8325
|
+
};
|
|
8326
|
+
};
|
|
8327
|
+
};
|
|
8066
8328
|
searchCompanyMd: {
|
|
8067
8329
|
parameters: {
|
|
8068
8330
|
query?: never;
|
|
@@ -9109,6 +9371,65 @@ export interface operations {
|
|
|
9109
9371
|
};
|
|
9110
9372
|
};
|
|
9111
9373
|
};
|
|
9374
|
+
setOrgUnitOpenRoleUnit: {
|
|
9375
|
+
parameters: {
|
|
9376
|
+
query?: never;
|
|
9377
|
+
header?: never;
|
|
9378
|
+
path: {
|
|
9379
|
+
unitId: string;
|
|
9380
|
+
roleId: string;
|
|
9381
|
+
};
|
|
9382
|
+
cookie?: never;
|
|
9383
|
+
};
|
|
9384
|
+
requestBody: {
|
|
9385
|
+
content: {
|
|
9386
|
+
"application/json": {
|
|
9387
|
+
/** Format: uuid */
|
|
9388
|
+
unitId: string;
|
|
9389
|
+
};
|
|
9390
|
+
};
|
|
9391
|
+
};
|
|
9392
|
+
responses: {
|
|
9393
|
+
/** @description Open role moved to the destination unit */
|
|
9394
|
+
200: {
|
|
9395
|
+
headers: {
|
|
9396
|
+
[name: string]: unknown;
|
|
9397
|
+
};
|
|
9398
|
+
content: {
|
|
9399
|
+
"application/json": components["schemas"]["OpenRoleResponse"];
|
|
9400
|
+
};
|
|
9401
|
+
};
|
|
9402
|
+
};
|
|
9403
|
+
};
|
|
9404
|
+
setOrgUnitOpenRoleTitle: {
|
|
9405
|
+
parameters: {
|
|
9406
|
+
query?: never;
|
|
9407
|
+
header?: never;
|
|
9408
|
+
path: {
|
|
9409
|
+
unitId: string;
|
|
9410
|
+
roleId: string;
|
|
9411
|
+
};
|
|
9412
|
+
cookie?: never;
|
|
9413
|
+
};
|
|
9414
|
+
requestBody: {
|
|
9415
|
+
content: {
|
|
9416
|
+
"application/json": {
|
|
9417
|
+
title: string | null;
|
|
9418
|
+
};
|
|
9419
|
+
};
|
|
9420
|
+
};
|
|
9421
|
+
responses: {
|
|
9422
|
+
/** @description Open role with updated title */
|
|
9423
|
+
200: {
|
|
9424
|
+
headers: {
|
|
9425
|
+
[name: string]: unknown;
|
|
9426
|
+
};
|
|
9427
|
+
content: {
|
|
9428
|
+
"application/json": components["schemas"]["OpenRoleResponse"];
|
|
9429
|
+
};
|
|
9430
|
+
};
|
|
9431
|
+
};
|
|
9432
|
+
};
|
|
9112
9433
|
getPeopleOrgChart: {
|
|
9113
9434
|
parameters: {
|
|
9114
9435
|
query?: never;
|
|
@@ -21,8 +21,11 @@ export const openApiRoutes = {
|
|
|
21
21
|
'/api/chats/{id}/messages': ['POST'],
|
|
22
22
|
'/api/chats/{id}/messages/{messageId}': ['DELETE'],
|
|
23
23
|
'/api/chats/{id}/pin': ['DELETE', 'POST'],
|
|
24
|
+
'/api/company-md/access-requests/{id}/approve': ['POST'],
|
|
25
|
+
'/api/company-md/access-requests/{id}/deny': ['POST'],
|
|
24
26
|
'/api/company-md/context-bank': ['POST'],
|
|
25
27
|
'/api/company-md/docs/{id}': ['GET'],
|
|
28
|
+
'/api/company-md/docs/{id}/access-requests': ['GET', 'POST'],
|
|
26
29
|
'/api/company-md/docs/{id}/content': ['PUT'],
|
|
27
30
|
'/api/company-md/docs/{id}/context-bank': ['GET'],
|
|
28
31
|
'/api/company-md/docs/{id}/context-bank/associate': ['POST'],
|
|
@@ -54,6 +57,7 @@ export const openApiRoutes = {
|
|
|
54
57
|
'/api/executions/{executionId}/timeline': ['GET'],
|
|
55
58
|
'/api/executions/{executionId}/undo': ['POST'],
|
|
56
59
|
'/api/factory/floor': ['GET'],
|
|
60
|
+
'/api/factory/kpis': ['GET'],
|
|
57
61
|
'/api/factory/snapshot': ['GET'],
|
|
58
62
|
'/api/ingestion/operations/{id}': ['GET'],
|
|
59
63
|
'/api/internal-admin/impersonate/end': ['POST'],
|
|
@@ -91,6 +95,8 @@ export const openApiRoutes = {
|
|
|
91
95
|
'/api/org-units/{unitId}/open-roles/{roleId}': ['PATCH'],
|
|
92
96
|
'/api/org-units/{unitId}/open-roles/{roleId}/fill': ['POST'],
|
|
93
97
|
'/api/org-units/{unitId}/open-roles/{roleId}/reports-to': ['PUT'],
|
|
98
|
+
'/api/org-units/{unitId}/open-roles/{roleId}/title': ['PUT'],
|
|
99
|
+
'/api/org-units/{unitId}/open-roles/{roleId}/unit': ['PUT'],
|
|
94
100
|
'/api/org-units/{unitId}/owners': ['GET'],
|
|
95
101
|
'/api/org-units/{unitId}/permissions': ['GET'],
|
|
96
102
|
'/api/org-units/{unitId}/relationships': ['GET', 'POST'],
|
package/src/identity/README.md
CHANGED
|
@@ -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)_
|
package/src/identity/index.ts
CHANGED
|
@@ -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
|
|