@company-semantics/contracts 78.0.0 → 78.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@company-semantics/contracts",
3
- "version": "78.0.0",
3
+ "version": "78.1.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 = '7fba2cafe8fa' as const;
3
- export const SPEC_HASH_FULL = '7fba2cafe8fac0d1d504b68950dc7991091381a49522af2660bc8bcb3b2a865a' as const;
2
+ export const SPEC_HASH = '5fb16e310c8b' as const;
3
+ export const SPEC_HASH_FULL = '5fb16e310c8baf449866b5b84ae859bd3933c7835ba47b6758452fe4dfcceba5' as const;
@@ -7500,7 +7500,7 @@ export interface components {
7500
7500
  notification: {
7501
7501
  id: string;
7502
7502
  /** @enum {string} */
7503
- kind: "companyMd.access_requested" | "companyMd.access_request_approved" | "companyMd.access_request_denied" | "comment.mention" | "comment.reply" | "chat.mention" | "proactive.org_became_shared" | "proactive.brief_morning" | "proactive.billing_balance_below_half" | "proactive.billing_balance_below_threshold" | "proactive.billing_auto_recharge_succeeded" | "proactive.billing_top_up_credited" | "proactive.billing_monthly_budget_80" | "proactive.billing_monthly_budget_100" | "proactive.billing_user_monthly_limit_reached" | "proactive.billing_byo_key_invalid" | "proactive.billing_provider_price_changed" | "proactive.billing_payment_recovered" | "proactive.billing_balance_exhausted" | "proactive.billing_auto_recharge_failed" | "proactive.billing_payment_past_due" | "proactive.billing_suspended" | "proactive.billing_subscription_canceled" | "proactive.source_sync_docs_updated" | "proactive.source_sync_review_ready";
7503
+ kind: "companyMd.access_requested" | "companyMd.access_request_approved" | "companyMd.access_request_denied" | "comment.mention" | "comment.reply" | "chat.mention" | "proactive.org_became_shared" | "proactive.brief_morning" | "proactive.billing_balance_below_half" | "proactive.billing_balance_below_threshold" | "proactive.billing_auto_recharge_succeeded" | "proactive.billing_top_up_credited" | "proactive.billing_monthly_budget_80" | "proactive.billing_monthly_budget_100" | "proactive.billing_user_monthly_limit_reached" | "proactive.billing_byo_key_invalid" | "proactive.billing_provider_price_changed" | "proactive.billing_payment_recovered" | "proactive.billing_balance_exhausted" | "proactive.billing_auto_recharge_failed" | "proactive.billing_payment_past_due" | "proactive.billing_suspended" | "proactive.billing_subscription_canceled" | "proactive.source_sync_docs_updated" | "proactive.source_sync_review_ready" | "proactive.org_structure_review_ready";
7504
7504
  target: {
7505
7505
  /** @enum {string} */
7506
7506
  type: "company_md" | "org_unit" | "org" | "execution";
@@ -128,6 +128,12 @@ the three from another.
128
128
  candidate set id or the synthesis batch id for `review_ready`. Their inbox
129
129
  rows are `proactive.source_sync_*`, distinct from the kind strings. Neither
130
130
  sets `emailKind`.
131
+ - **`orgStructure.review_ready` is a `notice`** (the ADR with slug
132
+ `org-structure-review-ready-is-a-notice`). The first-sync analysis finished
133
+ and its proposal waits for review. Its counts are scope-gated and nothing is
134
+ broken, so it gets an unread inbox row (`proactive.org_structure_review_ready`)
135
+ and no chat or banner. It is triggered by the committed insert of a
136
+ `validated` proposal, and its occurrence key is the proposal id.
131
137
  - **The occurrence vocabulary is closed.** `ProactiveEventId` is branded so a
132
138
  raw string cannot stand in for an occurrence; `ProactiveRecipientReason` is a
133
139
  closed enum because the recipients table is the frozen audit record of who
@@ -257,6 +257,8 @@ describe("the kind registry", () => {
257
257
  // renderer is what resolves the scope-gated count and names at read time.
258
258
  "sourceSync.docs_updated": "proactive",
259
259
  "sourceSync.review_ready": "proactive",
260
+ // The org structure row is rendered by `src/proactive/` as well.
261
+ "orgStructure.review_ready": "proactive",
260
262
  };
261
263
 
262
264
  expect(Object.keys(EXPECTED_INBOX_DOMAIN).sort()).toEqual(
@@ -310,6 +312,22 @@ describe("the kind registry", () => {
310
312
  expect(plan.inboxKind).toBe("proactive.source_sync_docs_updated");
311
313
  });
312
314
 
315
+ it("orgStructure.review_ready is a notice: an unread inbox row, no banner and no chat", () => {
316
+ // The analysis counts are scope-gated, so a frozen chat has nothing it may
317
+ // say, and nothing is broken, so there is no banner (control
318
+ // docs/proactive-delivery.md). The row carries the attention.
319
+ const plan = PROACTIVE_EVENT_KINDS["orgStructure.review_ready"];
320
+
321
+ expect(plan.class).toBe("notice");
322
+ expect(CLASS_SURFACES[plan.class].chat).toBe(false);
323
+ expect(CLASS_SURFACES[plan.class].banner).toBe(false);
324
+ expect("chatTemplate" in plan).toBe(false);
325
+ expect("bannerType" in plan).toBe(false);
326
+ expect("emailKind" in plan).toBe(false);
327
+ expect(bornRead(CLASS_SURFACES[plan.class], "inbox")).toBe(false);
328
+ expect(plan.inboxKind).toBe("proactive.org_structure_review_ready");
329
+ });
330
+
313
331
  it("sourceSync.review_ready is explained: a chat and an inbox row, never a banner", () => {
314
332
  // A review is waiting, so the chat explains what it is and what happens if
315
333
  // it is left alone — and carries the badge. Nothing is broken and nothing
@@ -282,6 +282,26 @@ export const PROACTIVE_EVENT_KIND_IDS = [
282
282
  * silent.
283
283
  */
284
284
  "sourceSync.review_ready",
285
+
286
+ // ===========================================================================
287
+ // Org structure (ADR-BE-680 deferred it; the first-sync notice)
288
+ // ===========================================================================
289
+ /**
290
+ * The analysis a first BambooHR connect started on its own has finished, and
291
+ * its proposal is waiting for review. A `notice`, which means an inbox row
292
+ * and nothing else (control docs/proactive-delivery.md): the analysis counts
293
+ * are scope-gated, so there is nothing a frozen chat may say, and nothing is
294
+ * broken or stopped, so there is no banner. A person who launched a run by
295
+ * hand is already watching it dock in their chat (ADR-APP-298), so only the
296
+ * connect chain's run announces.
297
+ *
298
+ * TRIGGER: the committed insert of a `validated` proposal by that run. A
299
+ * `blocked` proposal is not a review and announces nothing.
300
+ *
301
+ * OCCURRENCE KEY: the proposal id. One proposal announces once, however many
302
+ * times its job is redelivered.
303
+ */
304
+ "orgStructure.review_ready",
285
305
  ] as const;
286
306
  export type ProactiveEventKind = (typeof PROACTIVE_EVENT_KIND_IDS)[number];
287
307
 
@@ -253,4 +253,13 @@ export const PROACTIVE_EVENT_KINDS = {
253
253
  // later (ADR slug `action-items-are-standing-state-not-notifications`).
254
254
  actionItemKind: "sourceSync.proposal_pending",
255
255
  },
256
+ /**
257
+ * A first-sync org structure review is waiting. A NOTICE: the inbox row is
258
+ * the whole announcement and arrives unread, and the plan union makes a chat
259
+ * for it a compile error. Keyed on the proposal id.
260
+ */
261
+ "orgStructure.review_ready": {
262
+ class: "notice",
263
+ inboxKind: "proactive.org_structure_review_ready",
264
+ },
256
265
  } as const satisfies Record<ProactiveEventKind, ProactiveEventDefinition>;
@@ -75,6 +75,9 @@ that renders them alongside action items at the top of `/me/work`.
75
75
  candidate-set id; the COUNT of updated documents, and which ones, is resolved
76
76
  by the renderer at read time under the reader's authority — which is why it
77
77
  belongs in this row and never in the frozen pushed chat.
78
+ - **`proactive.org_structure_review_ready` is the org structure notice's row.**
79
+ It arrives UNREAD, because a `notice` has no other surface to hold the badge.
80
+ The renderer links it to the place the review is opened.
78
81
  - **This is a mention row, not a chat-unread model.** Being named is a discrete
79
82
  fact you come back to; "this chat has new messages" is not modeled here or
80
83
  anywhere, and the proactive `unread` flag on a chat summary stays a one-time
@@ -206,3 +206,12 @@ describe("FeedListResponse", () => {
206
206
  ).toBe(false);
207
207
  });
208
208
  });
209
+
210
+ describe("the org structure inbox row", () => {
211
+ it("is registered under the proactive renderer, never under its kind's string", () => {
212
+ expect(USER_NOTIFICATION_KINDS).toContain(
213
+ "proactive.org_structure_review_ready",
214
+ );
215
+ expect(USER_NOTIFICATION_KINDS).not.toContain("orgStructure.review_ready");
216
+ });
217
+ });
@@ -221,6 +221,14 @@ export const USER_NOTIFICATION_KINDS = [
221
221
  * `sourceSync.proposal_pending` ACTION ITEM, not this row.
222
222
  */
223
223
  "proactive.source_sync_review_ready",
224
+ /**
225
+ * The org structure analysis a first BambooHR connect started has finished,
226
+ * and its review is waiting. The durable row of the
227
+ * `orgStructure.review_ready` proactive kind, a `notice`: no banner and no
228
+ * pushed chat, so this row IS the attention and arrives UNREAD. It links to
229
+ * where the review is opened.
230
+ */
231
+ "proactive.org_structure_review_ready",
224
232
  ] as const;
225
233
 
226
234
  export type UserNotificationKind = (typeof USER_NOTIFICATION_KINDS)[number];