@company-semantics/contracts 60.0.0 → 62.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,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 = '5b50d2608eb0' as const;
|
|
3
|
+
export const SPEC_HASH_FULL = '5b50d2608eb090a8a020d1219d8f3ba9d99f825c72fd5f5695f9d2542f32b8a3' as const;
|
package/src/api/generated.ts
CHANGED
|
@@ -4263,8 +4263,28 @@ export interface components {
|
|
|
4263
4263
|
reason: "external-mutation" | "bulk-operation" | "sync-required";
|
|
4264
4264
|
};
|
|
4265
4265
|
AiChatRequest: {
|
|
4266
|
+
/**
|
|
4267
|
+
* @default submit-message
|
|
4268
|
+
* @constant
|
|
4269
|
+
*/
|
|
4270
|
+
trigger: "submit-message";
|
|
4271
|
+
id?: string;
|
|
4272
|
+
messageId?: string;
|
|
4273
|
+
message?: {
|
|
4274
|
+
id: string;
|
|
4275
|
+
/** @constant */
|
|
4276
|
+
role: "user";
|
|
4277
|
+
parts: unknown[];
|
|
4278
|
+
};
|
|
4266
4279
|
messages: unknown[];
|
|
4280
|
+
runtimeProfile?: string;
|
|
4281
|
+
} | {
|
|
4282
|
+
/** @constant */
|
|
4283
|
+
trigger: "regenerate-message";
|
|
4267
4284
|
id?: string;
|
|
4285
|
+
messageId?: string;
|
|
4286
|
+
message?: unknown;
|
|
4287
|
+
messages: unknown[];
|
|
4268
4288
|
runtimeProfile?: string;
|
|
4269
4289
|
};
|
|
4270
4290
|
ProactiveChatResolution: {
|
|
@@ -5628,6 +5648,7 @@ export interface components {
|
|
|
5628
5648
|
hasChildren: boolean;
|
|
5629
5649
|
memberCount: number;
|
|
5630
5650
|
openRoleCount: number;
|
|
5651
|
+
placedPeopleCount: number;
|
|
5631
5652
|
missingAtNextLevel: {
|
|
5632
5653
|
count: number;
|
|
5633
5654
|
userIds: string[];
|
|
@@ -5776,6 +5797,7 @@ export interface components {
|
|
|
5776
5797
|
hasChildren: boolean;
|
|
5777
5798
|
memberCount: number;
|
|
5778
5799
|
openRoleCount: number;
|
|
5800
|
+
placedPeopleCount: number;
|
|
5779
5801
|
missingAtNextLevel: {
|
|
5780
5802
|
count: number;
|
|
5781
5803
|
userIds: string[];
|
package/src/decisions/types.ts
CHANGED
|
@@ -71,7 +71,29 @@ export type DecisionEffect =
|
|
|
71
71
|
* derivation to run again. Carries the reason so the follow-up has something
|
|
72
72
|
* to act on, and so the reviewer is not told "saved" when nothing moved.
|
|
73
73
|
*/
|
|
74
|
-
| { readonly kind: "needs_reinference"; readonly note: string }
|
|
74
|
+
| { readonly kind: "needs_reinference"; readonly note: string }
|
|
75
|
+
/**
|
|
76
|
+
* Mark a person as the head of a DURABLE unit, and optionally set that unit's
|
|
77
|
+
* owner label. Today the only producer names the org root, so accepting is how
|
|
78
|
+
* an imported chart's CEO becomes the workspace's root owner.
|
|
79
|
+
*
|
|
80
|
+
* DURABLE addressing, not a temp id: post-apply every unit is durable, so a
|
|
81
|
+
* real id is the general form. A temp id would serve only corrections to
|
|
82
|
+
* not-yet-created units, which a proposal's own `headPersonId` already covers
|
|
83
|
+
* with no effect at all.
|
|
84
|
+
*
|
|
85
|
+
* THIS EFFECT NEVER MINTS AUTHORITY. It writes a presentation/semantic marker
|
|
86
|
+
* and a label. Granting unit or account ownership stays with the human-gated
|
|
87
|
+
* ownership route — a root-unit owner IS an account owner, so an automated
|
|
88
|
+
* grant would be a privilege-escalation path.
|
|
89
|
+
*/
|
|
90
|
+
| {
|
|
91
|
+
readonly kind: "set_unit_head";
|
|
92
|
+
readonly unitId: string;
|
|
93
|
+
readonly personId: string;
|
|
94
|
+
/** Non-null also sets the unit's owner label; null marks the head only. */
|
|
95
|
+
readonly title: string | null;
|
|
96
|
+
};
|
|
75
97
|
|
|
76
98
|
/** The closed set of effect kinds, as runtime data for validators. */
|
|
77
99
|
export const DECISION_EFFECT_KINDS = [
|
|
@@ -81,6 +103,7 @@ export const DECISION_EFFECT_KINDS = [
|
|
|
81
103
|
"unadopt_unit",
|
|
82
104
|
"archive_unit",
|
|
83
105
|
"needs_reinference",
|
|
106
|
+
"set_unit_head",
|
|
84
107
|
] as const satisfies ReadonlyArray<DecisionEffect["kind"]>;
|
|
85
108
|
|
|
86
109
|
/** One answer a human may give, with what it means and what it does. */
|
|
@@ -97,6 +97,7 @@ describe("OrgUnitTreeNodeSchema", () => {
|
|
|
97
97
|
hasChildren: true,
|
|
98
98
|
memberCount: 5,
|
|
99
99
|
openRoleCount: 1,
|
|
100
|
+
placedPeopleCount: 5,
|
|
100
101
|
missingAtNextLevel: null,
|
|
101
102
|
};
|
|
102
103
|
expect(() => OrgUnitTreeNodeSchema.parse(base)).not.toThrow();
|
|
@@ -111,6 +112,7 @@ describe("OrgUnitTreeNodeSchema", () => {
|
|
|
111
112
|
hasChildren: true,
|
|
112
113
|
memberCount: 5,
|
|
113
114
|
openRoleCount: 0,
|
|
115
|
+
placedPeopleCount: 5,
|
|
114
116
|
missingAtNextLevel: null,
|
|
115
117
|
};
|
|
116
118
|
expect(() => OrgUnitTreeNodeSchema.parse(base)).not.toThrow();
|
|
@@ -118,6 +120,30 @@ describe("OrgUnitTreeNodeSchema", () => {
|
|
|
118
120
|
OrgUnitTreeNodeSchema.parse({ ...base, openRoleCount: -1 }),
|
|
119
121
|
).toThrow();
|
|
120
122
|
});
|
|
123
|
+
|
|
124
|
+
it("requires placedPeopleCount, and lets it disagree with memberCount", () => {
|
|
125
|
+
const base = {
|
|
126
|
+
...makeUnit(),
|
|
127
|
+
depth: 3,
|
|
128
|
+
hasChildren: false,
|
|
129
|
+
// The HRIS shape: nobody in this department has an account, so the
|
|
130
|
+
// account-keyed rollup is 0 while 22 people hold seats in it. Both are
|
|
131
|
+
// correct; they answer different questions (ADR-CONTRACTS-150).
|
|
132
|
+
memberCount: 0,
|
|
133
|
+
openRoleCount: 0,
|
|
134
|
+
placedPeopleCount: 22,
|
|
135
|
+
missingAtNextLevel: null,
|
|
136
|
+
};
|
|
137
|
+
expect(() => OrgUnitTreeNodeSchema.parse(base)).not.toThrow();
|
|
138
|
+
|
|
139
|
+
// Required, not optional — pre-launch there is no back-compat window, and
|
|
140
|
+
// an absent count would be indistinguishable from an empty unit.
|
|
141
|
+
const { placedPeopleCount: _omitted, ...withoutIt } = base;
|
|
142
|
+
expect(() => OrgUnitTreeNodeSchema.parse(withoutIt)).toThrow();
|
|
143
|
+
expect(() =>
|
|
144
|
+
OrgUnitTreeNodeSchema.parse({ ...base, placedPeopleCount: -1 }),
|
|
145
|
+
).toThrow();
|
|
146
|
+
});
|
|
121
147
|
});
|
|
122
148
|
|
|
123
149
|
describe("OpenRoleSchema", () => {
|
package/src/org/schemas.ts
CHANGED
|
@@ -1581,6 +1581,18 @@ export const MissingAtNextLevelSchema = z.object({
|
|
|
1581
1581
|
export const OrgUnitTreeNodeSchema = OrgUnitSchema.extend({
|
|
1582
1582
|
depth: z.number().int().min(1).max(5),
|
|
1583
1583
|
hasChildren: z.boolean(),
|
|
1584
|
+
/**
|
|
1585
|
+
* ACCOUNTS homed in this unit's subtree — a rollup of `home_assignments`,
|
|
1586
|
+
* whose `user_id` is NOT NULL. A person who has never signed in therefore
|
|
1587
|
+
* cannot contribute to it, and a freshly HRIS-synced org is ~93 people and
|
|
1588
|
+
* one account, so this is legitimately 0 for a fully staffed department.
|
|
1589
|
+
*
|
|
1590
|
+
* That is not a defect: it is the right population for anything that needs an
|
|
1591
|
+
* account to act on — the share dialog's fanout, the unit-scoped members
|
|
1592
|
+
* table. For "how many people are in this department", use
|
|
1593
|
+
* {@link placedPeopleCount}. The two answer different questions and
|
|
1594
|
+
* legitimately disagree (ADR-CONTRACTS-150, ADR-BE-657).
|
|
1595
|
+
*/
|
|
1584
1596
|
memberCount: z.number().int().min(0),
|
|
1585
1597
|
/**
|
|
1586
1598
|
* Active open roles (`open` + `hiring`) rolled up over this unit's subtree,
|
|
@@ -1588,6 +1600,18 @@ export const OrgUnitTreeNodeSchema = OrgUnitSchema.extend({
|
|
|
1588
1600
|
* count split in the people surfaces. `memberCount` stays real-members-only.
|
|
1589
1601
|
*/
|
|
1590
1602
|
openRoleCount: z.number().int().min(0),
|
|
1603
|
+
/**
|
|
1604
|
+
* Distinct PEOPLE holding a live canonical seat in this unit's subtree —
|
|
1605
|
+
* `placement_role='canonical'`, `status <> 'ended'`, keyed by
|
|
1606
|
+
* `positions.unit_id`. Account linkage is not consulted, so this is the count
|
|
1607
|
+
* that describes an imported workforce.
|
|
1608
|
+
*
|
|
1609
|
+
* Placement and home are independent graphs (ADR-CTRL-159): a person seated
|
|
1610
|
+
* here may be homed elsewhere, and vice versa. Deliberately does NOT filter
|
|
1611
|
+
* `positions.status` — an occupied `closed` seat still draws a card on the
|
|
1612
|
+
* org chart, and a filter here would disagree with it (ADR-BE-657).
|
|
1613
|
+
*/
|
|
1614
|
+
placedPeopleCount: z.number().int().min(0),
|
|
1591
1615
|
missingAtNextLevel: MissingAtNextLevelSchema.nullable(),
|
|
1592
1616
|
});
|
|
1593
1617
|
|