@company-semantics/contracts 58.5.0 → 58.6.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": "58.5.0",
3
+ "version": "58.6.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 = '433bb009d9f1' as const;
3
- export const SPEC_HASH_FULL = '433bb009d9f1037871adde049808503dc040cc4cb44122a8f2d603da02b4dd2b' as const;
2
+ export const SPEC_HASH = 'dd2a725d7ebd' as const;
3
+ export const SPEC_HASH_FULL = 'dd2a725d7ebd694db25efbe0e638077984af41551c1989fb374d9a7b8bc4eb3d' as const;
@@ -5065,11 +5065,14 @@ export interface components {
5065
5065
  summary: {
5066
5066
  executionId: string;
5067
5067
  /** @enum {string} */
5068
- kind: "integration.connect" | "integration.disconnect" | "profile.update" | "slack.send" | "data.ingest" | "data.scope" | "system.cleanup" | "member.changeManager" | "companyMd.ingest" | "companyMd.commentPass" | "semantic.transform" | "companyMd.importContextDoc";
5068
+ kind: "integration.connect" | "integration.disconnect" | "integration.purge" | "profile.update" | "slack.send" | "data.ingest" | "data.scope" | "system.cleanup" | "member.changeManager" | "companyMd.ingest" | "companyMd.commentPass" | "semantic.transform" | "companyMd.importContextDoc";
5069
5069
  target: {
5070
5070
  /** @constant */
5071
5071
  type: "slack";
5072
5072
  workspaceId?: string;
5073
+ } | {
5074
+ /** @constant */
5075
+ type: "bamboohr";
5073
5076
  };
5074
5077
  /** @enum {string} */
5075
5078
  status: "pending" | "succeeded" | "failed";
@@ -9113,7 +9116,7 @@ export interface operations {
9113
9116
  query?: {
9114
9117
  cursor?: string;
9115
9118
  limit?: number;
9116
- kind?: "integration.connect" | "integration.disconnect" | "profile.update" | "slack.send" | "data.ingest" | "data.scope" | "system.cleanup" | "member.changeManager" | "companyMd.ingest" | "companyMd.commentPass" | "semantic.transform" | "companyMd.importContextDoc";
9119
+ kind?: "integration.connect" | "integration.disconnect" | "integration.purge" | "profile.update" | "slack.send" | "data.ingest" | "data.scope" | "system.cleanup" | "member.changeManager" | "companyMd.ingest" | "companyMd.commentPass" | "semantic.transform" | "companyMd.importContextDoc";
9117
9120
  targetType?: string;
9118
9121
  periodStart?: string;
9119
9122
  periodEnd?: string;
@@ -9248,7 +9251,7 @@ export interface operations {
9248
9251
  query?: {
9249
9252
  limit?: number;
9250
9253
  offset?: number;
9251
- kind?: "integration.connect" | "integration.disconnect" | "profile.update" | "slack.send" | "data.ingest" | "data.scope" | "system.cleanup" | "member.changeManager" | "companyMd.ingest" | "companyMd.commentPass" | "semantic.transform" | "companyMd.importContextDoc";
9254
+ kind?: "integration.connect" | "integration.disconnect" | "integration.purge" | "profile.update" | "slack.send" | "data.ingest" | "data.scope" | "system.cleanup" | "member.changeManager" | "companyMd.ingest" | "companyMd.commentPass" | "semantic.transform" | "companyMd.importContextDoc";
9252
9255
  kindPrefix?: string;
9253
9256
  };
9254
9257
  header?: never;
@@ -53,6 +53,27 @@ describe("EXECUTION_KINDS golden snapshot", () => {
53
53
  templateId: "integration.disconnect",
54
54
  },
55
55
  },
56
+ "integration.purge": {
57
+ kind: "integration.purge",
58
+ domain: "integration",
59
+ display: {
60
+ label: "Purge integration data",
61
+ pastTenseLabel: "Integration data purged",
62
+ icon: "unlink",
63
+ },
64
+ governance: {
65
+ visibility: "admin",
66
+ requiresAdmin: true,
67
+ },
68
+ ui: {
69
+ showInAdmin: true,
70
+ showInTimeline: true,
71
+ confirmBeforeRun: true,
72
+ },
73
+ explanation: {
74
+ templateId: "integration.purge",
75
+ },
76
+ },
56
77
  "profile.update": {
57
78
  kind: "profile.update",
58
79
  domain: "profile",
@@ -36,6 +36,10 @@
36
36
  export type ExecutionKind =
37
37
  | "integration.connect"
38
38
  | "integration.disconnect"
39
+ /** Break-glass HRIS purge: disconnect plus an irreversible unwind of all
40
+ * facts still exclusively source-owned, tombstoning the connection as
41
+ * `purged`. Only providers enrolled in RETAIN_ON_DISCONNECT qualify. */
42
+ | "integration.purge"
39
43
  | "profile.update"
40
44
  | "slack.send"
41
45
  | "data.ingest"
@@ -76,6 +76,29 @@ export const EXECUTION_KINDS = {
76
76
  templateId: "integration.disconnect",
77
77
  },
78
78
  },
79
+ "integration.purge": {
80
+ kind: "integration.purge",
81
+ domain: "integration",
82
+ display: {
83
+ label: "Purge integration data",
84
+ pastTenseLabel: "Integration data purged",
85
+ icon: "unlink",
86
+ },
87
+ governance: {
88
+ visibility: "admin",
89
+ requiresAdmin: true,
90
+ // Irreversible by design: the unwind deletes source-owned facts and
91
+ // history, so no kind reverses this one (reversibleBy stays unset).
92
+ },
93
+ ui: {
94
+ showInAdmin: true,
95
+ showInTimeline: true,
96
+ confirmBeforeRun: true,
97
+ },
98
+ explanation: {
99
+ templateId: "integration.purge",
100
+ },
101
+ },
79
102
  "profile.update": {
80
103
  kind: "profile.update",
81
104
  domain: "profile",
@@ -190,10 +190,18 @@ const EXECUTION_KIND_VALUES = Object.keys(EXECUTION_KINDS) as [
190
190
  export const ExecutionSummaryProjectionSchema = z.object({
191
191
  executionId: z.string(),
192
192
  kind: z.enum(EXECUTION_KIND_VALUES),
193
- target: z.object({
194
- type: z.literal("slack"),
195
- workspaceId: z.string().optional(),
196
- }),
193
+ // Mirrors the ExecutionTarget union (summary.ts): Slack carries an optional
194
+ // workspace qualifier; BambooHR is addressed by connectionId alone, so its
195
+ // target is bare (ADR-BE-610).
196
+ target: z.discriminatedUnion("type", [
197
+ z.object({
198
+ type: z.literal("slack"),
199
+ workspaceId: z.string().optional(),
200
+ }),
201
+ z.object({
202
+ type: z.literal("bamboohr"),
203
+ }),
204
+ ]),
197
205
  status: z.enum(["pending", "succeeded", "failed"]),
198
206
  initiatedBy: z.object({
199
207
  actorType: z.enum(["user", "system"]),
@@ -36,6 +36,8 @@ alongside `Meetings`, `Comms`, and `Docs`.
36
36
  - `HrConnectInputSchema` — Input submitted by the app to initiate an HR provider connection.
37
37
  - `HrConnectionStatus` _(type)_
38
38
  - `HrConnectionStatusSchema` — Health of the most recent HR provider sync.
39
+ - `HrisPurgeImpact` _(type)_
40
+ - `HrisPurgeImpactSchema` — Impact of a break-glass HRIS purge (`integration.purge`), counted per entity.
39
41
 
40
42
  <!-- END GENERATED: readme-public-api -->
41
43
 
@@ -3,6 +3,14 @@
3
3
  *
4
4
  * @see ./schemas.ts for the full schema definitions and invariants.
5
5
  */
6
- export { HrConnectionStatusSchema, HrConnectInputSchema } from "./schemas";
6
+ export {
7
+ HrConnectionStatusSchema,
8
+ HrConnectInputSchema,
9
+ HrisPurgeImpactSchema,
10
+ } from "./schemas";
7
11
 
8
- export type { HrConnectionStatus, HrConnectInput } from "./schemas";
12
+ export type {
13
+ HrConnectionStatus,
14
+ HrConnectInput,
15
+ HrisPurgeImpact,
16
+ } from "./schemas";
@@ -146,3 +146,90 @@ export const HrConnectInputSchema = z
146
146
  description: "Input to initiate an HR provider connection.",
147
147
  });
148
148
  export type HrConnectInput = z.infer<typeof HrConnectInputSchema>;
149
+
150
+ // =============================================================================
151
+ // HRIS purge impact
152
+ // =============================================================================
153
+
154
+ /**
155
+ * Impact of a break-glass HRIS purge (`integration.purge`), counted per
156
+ * entity. One shape serves four readers: the purge-preview response, the
157
+ * execution result, the `integration.purged` fact details, and the
158
+ * `connection.purged` audit metadata. Preview and purge are built from the
159
+ * same predicate builders, so on an unchanged org the previewed counts and
160
+ * the executed counts are equal by construction.
161
+ */
162
+ export const HrisPurgeImpactSchema = z
163
+ .object({
164
+ peopleUnlinked: z.number().int().min(0).meta({
165
+ description: "Provider identity links deleted (people unlinked).",
166
+ }),
167
+ personsRetained: z
168
+ .number()
169
+ .int()
170
+ .min(0)
171
+ .meta({
172
+ description:
173
+ "Persons left in the graph — always all of them; persons are " +
174
+ "never deleted by a purge, only unlinked from the provider.",
175
+ }),
176
+ unitsArchived: z.number().int().min(0).meta({
177
+ description: "Source-owned org units soft-archived.",
178
+ }),
179
+ unitsRetained: z.number().int().min(0).meta({
180
+ description:
181
+ "Provider-imported org units retained because a user claimed them.",
182
+ }),
183
+ positionsClosed: z.number().int().min(0).meta({
184
+ description: "Source-owned positions closed (never deleted).",
185
+ }),
186
+ positionsRetained: z.number().int().min(0).meta({
187
+ description:
188
+ "Provider-imported positions retained because a user claimed them.",
189
+ }),
190
+ occupanciesEnded: z.number().int().min(0).meta({
191
+ description: "Source-owned occupancies ended (employment history kept).",
192
+ }),
193
+ occupanciesRetained: z.number().int().min(0).meta({
194
+ description:
195
+ "Provider-imported occupancies retained because a user claimed them.",
196
+ }),
197
+ reportingEdgesRemoved: z.number().int().min(0).meta({
198
+ description: "Source-owned reporting edges deleted.",
199
+ }),
200
+ reportingEdgesRetained: z
201
+ .number()
202
+ .int()
203
+ .min(0)
204
+ .meta({
205
+ description:
206
+ "Provider-imported reporting edges retained because a user took " +
207
+ "ownership of them (user_override or human_confirmed authority).",
208
+ }),
209
+ syncRunsDeleted: z.number().int().min(0).meta({
210
+ description: "Sync-run history rows deleted.",
211
+ }),
212
+ conflictsDeleted: z.number().int().min(0).meta({
213
+ description: "Conflict-ledger rows deleted.",
214
+ }),
215
+ acknowledgementsDeleted: z.number().int().min(0).meta({
216
+ description: "Divergence acknowledgements deleted.",
217
+ }),
218
+ sourceUnitMappingsDeleted: z.number().int().min(0).meta({
219
+ description: "Source-unit mapping rows deleted.",
220
+ }),
221
+ authorityRowsDeleted: z
222
+ .number()
223
+ .int()
224
+ .min(0)
225
+ .meta({
226
+ description:
227
+ "source-authority rows deleted — only rows whose authority is the " +
228
+ "provider itself; human-confirmed and user-override rows are never " +
229
+ "touched.",
230
+ }),
231
+ })
232
+ .meta({
233
+ description: "Per-entity impact of a break-glass HRIS purge.",
234
+ });
235
+ export type HrisPurgeImpact = z.infer<typeof HrisPurgeImpactSchema>;
@@ -114,6 +114,7 @@ describe("CONFIRMATION_LABELS", () => {
114
114
  expect(CONFIRMATION_LABELS).toStrictEqual({
115
115
  "integration.connect": "Connect Integration",
116
116
  "integration.disconnect": "Disconnect Integration",
117
+ "integration.purge": "Purge Integration Data",
117
118
  "profile.update": "Update Profile",
118
119
  "slack.send": "Send Slack Message",
119
120
  "data.ingest": "Import Channel",
@@ -39,6 +39,7 @@ export type ConfirmationRiskLevel =
39
39
  export const CONFIRMATION_LABELS: Record<ExecutionKind, string> = {
40
40
  "integration.connect": "Connect Integration",
41
41
  "integration.disconnect": "Disconnect Integration",
42
+ "integration.purge": "Purge Integration Data",
42
43
  "profile.update": "Update Profile",
43
44
  "slack.send": "Send Slack Message",
44
45
  "data.ingest": "Import Channel",