@company-semantics/contracts 78.1.0 → 79.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/action-items/__tests__/vocabulary.test.ts +10 -0
- package/src/action-items/schemas.ts +10 -0
- package/src/api/generated-spec-hash.ts +2 -2
- package/src/api/generated.ts +147 -47
- package/src/generated/openapi-routes.ts +1 -0
- package/src/user-notifications/__tests__/vocabulary.test.ts +26 -0
- package/src/user-notifications/schemas.ts +10 -0
package/package.json
CHANGED
|
@@ -31,6 +31,7 @@ function makeItem(over: Partial<Record<string, unknown>> = {}) {
|
|
|
31
31
|
title: "Maya Chen wants access",
|
|
32
32
|
detail: "Reviewing the cross-team roadmap",
|
|
33
33
|
contextLabel: "Sales.md",
|
|
34
|
+
provider: null,
|
|
34
35
|
href: "/@acme/md/doc-1?share=1&request=req-1",
|
|
35
36
|
createdAt: "2026-07-27T00:00:00.000Z",
|
|
36
37
|
...over,
|
|
@@ -139,6 +140,15 @@ describe("ActionItemSchema", () => {
|
|
|
139
140
|
expect(parsed.unitPath).toBeNull();
|
|
140
141
|
});
|
|
141
142
|
|
|
143
|
+
it("requires a provider — null when the item is about the product", () => {
|
|
144
|
+
const { provider: _omitted, ...withoutProvider } = makeItem();
|
|
145
|
+
expect(ActionItemSchema.safeParse(withoutProvider).success).toBe(false);
|
|
146
|
+
expect(
|
|
147
|
+
ActionItemSchema.safeParse(makeItem({ provider: "google_drive" }))
|
|
148
|
+
.success,
|
|
149
|
+
).toBe(true);
|
|
150
|
+
});
|
|
151
|
+
|
|
142
152
|
it("rejects a kind outside the vocabulary", () => {
|
|
143
153
|
expect(() =>
|
|
144
154
|
ActionItemSchema.parse(makeItem({ kind: "org.invite" })),
|
|
@@ -69,6 +69,16 @@ export const ActionItemSchema = z.object({
|
|
|
69
69
|
detail: z.string().nullable(),
|
|
70
70
|
/** The thing it is about, as the user names it, e.g. "Sales.md". */
|
|
71
71
|
contextLabel: z.string(),
|
|
72
|
+
/**
|
|
73
|
+
* The external system this row is ABOUT, when it is about one — the open
|
|
74
|
+
* provider id the identity-link vocabulary uses system-wide ('bamboohr',
|
|
75
|
+
* 'google_drive', 'slack'). A surface shows that system's own mark.
|
|
76
|
+
*
|
|
77
|
+
* Set by the producer, because only it knows: an org's structure findings
|
|
78
|
+
* come from whichever HRIS it connected, which the kind cannot say.
|
|
79
|
+
* `null` when the row is about the product itself (a doc, a chat, billing).
|
|
80
|
+
*/
|
|
81
|
+
provider: z.string().min(1).nullable(),
|
|
72
82
|
/**
|
|
73
83
|
* Where to go to RESOLVE it — a RELATIVE app path, e.g.
|
|
74
84
|
* `/@acme/md/{docId}?share=1&request={id}`.
|
|
@@ -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 = 'c6eea14298b3' as const;
|
|
3
|
+
export const SPEC_HASH_FULL = 'c6eea14298b3f6282e821b61fac860d7c18fbb8af4b5ecf660bc09665a215d9b' as const;
|
package/src/api/generated.ts
CHANGED
|
@@ -4589,6 +4589,30 @@ export interface paths {
|
|
|
4589
4589
|
patch?: never;
|
|
4590
4590
|
trace?: never;
|
|
4591
4591
|
};
|
|
4592
|
+
"/api/source-sync/settings": {
|
|
4593
|
+
parameters: {
|
|
4594
|
+
query?: never;
|
|
4595
|
+
header?: never;
|
|
4596
|
+
path?: never;
|
|
4597
|
+
cookie?: never;
|
|
4598
|
+
};
|
|
4599
|
+
/**
|
|
4600
|
+
* Read whether Source Sync is on for the org
|
|
4601
|
+
* @description The org switch every Source Sync route, job and sweep gates on, and who last changed it and when. Off until an admin turns it on.
|
|
4602
|
+
*/
|
|
4603
|
+
get: operations["getSourceSyncSettings"];
|
|
4604
|
+
/**
|
|
4605
|
+
* Switch Source Sync on or off for the org
|
|
4606
|
+
* @description On lets Source Sync search the connected Drive and propose company.md updates for review. Off pauses it: nothing is read or run, and nothing already brought in is deleted. The caller is recorded as the person who changed it.
|
|
4607
|
+
*/
|
|
4608
|
+
put: operations["putSourceSyncSettings"];
|
|
4609
|
+
post?: never;
|
|
4610
|
+
delete?: never;
|
|
4611
|
+
options?: never;
|
|
4612
|
+
head?: never;
|
|
4613
|
+
patch?: never;
|
|
4614
|
+
trace?: never;
|
|
4615
|
+
};
|
|
4592
4616
|
}
|
|
4593
4617
|
export type webhooks = Record<string, never>;
|
|
4594
4618
|
export interface components {
|
|
@@ -7470,6 +7494,7 @@ export interface components {
|
|
|
7470
7494
|
title: string;
|
|
7471
7495
|
detail: string | null;
|
|
7472
7496
|
contextLabel: string;
|
|
7497
|
+
provider: string | null;
|
|
7473
7498
|
href: string;
|
|
7474
7499
|
createdAt: string;
|
|
7475
7500
|
}[];
|
|
@@ -7491,6 +7516,7 @@ export interface components {
|
|
|
7491
7516
|
title: string;
|
|
7492
7517
|
detail: string | null;
|
|
7493
7518
|
contextLabel: string;
|
|
7519
|
+
provider: string | null;
|
|
7494
7520
|
href: string;
|
|
7495
7521
|
createdAt: string;
|
|
7496
7522
|
};
|
|
@@ -7510,6 +7536,7 @@ export interface components {
|
|
|
7510
7536
|
title: string;
|
|
7511
7537
|
detail: string | null;
|
|
7512
7538
|
contextLabel: string;
|
|
7539
|
+
provider: string | null;
|
|
7513
7540
|
href: string | null;
|
|
7514
7541
|
createdAt: string;
|
|
7515
7542
|
readAt: string | null;
|
|
@@ -9293,6 +9320,14 @@ export interface components {
|
|
|
9293
9320
|
/** @constant */
|
|
9294
9321
|
confirm: true;
|
|
9295
9322
|
};
|
|
9323
|
+
SourceSyncSettingsResponse: {
|
|
9324
|
+
enabled: boolean;
|
|
9325
|
+
changedAt: string | null;
|
|
9326
|
+
changedByLabel: string | null;
|
|
9327
|
+
};
|
|
9328
|
+
SourceSyncPutSettingsRequest: {
|
|
9329
|
+
enabled: boolean;
|
|
9330
|
+
};
|
|
9296
9331
|
/** @description Server-enforced collaboration size limits, published so clients can pre-check. */
|
|
9297
9332
|
CollabSyncLimits: {
|
|
9298
9333
|
maxUpdateBytes: number;
|
|
@@ -17245,14 +17280,7 @@ export interface operations {
|
|
|
17245
17280
|
"application/json": components["schemas"]["SourceSyncDiscoveryRunResponse"];
|
|
17246
17281
|
};
|
|
17247
17282
|
};
|
|
17248
|
-
/** @description Source Sync is
|
|
17249
|
-
404: {
|
|
17250
|
-
headers: {
|
|
17251
|
-
[name: string]: unknown;
|
|
17252
|
-
};
|
|
17253
|
-
content?: never;
|
|
17254
|
-
};
|
|
17255
|
-
/** @description The org has no active Google Drive connection (SOURCE_SYNC_DRIVE_NOT_CONNECTED), or a discovery run is already running (SOURCE_DISCOVERY_ALREADY_RUNNING) */
|
|
17283
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or The org has no active Google Drive connection (SOURCE_SYNC_DRIVE_NOT_CONNECTED), or a discovery run is already running (SOURCE_DISCOVERY_ALREADY_RUNNING) */
|
|
17256
17284
|
409: {
|
|
17257
17285
|
headers: {
|
|
17258
17286
|
[name: string]: unknown;
|
|
@@ -17279,13 +17307,20 @@ export interface operations {
|
|
|
17279
17307
|
"application/json": components["schemas"]["SourceSyncCandidateSetResponse"];
|
|
17280
17308
|
};
|
|
17281
17309
|
};
|
|
17282
|
-
/** @description
|
|
17310
|
+
/** @description The org has no draft candidate set */
|
|
17283
17311
|
404: {
|
|
17284
17312
|
headers: {
|
|
17285
17313
|
[name: string]: unknown;
|
|
17286
17314
|
};
|
|
17287
17315
|
content?: never;
|
|
17288
17316
|
};
|
|
17317
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
|
|
17318
|
+
409: {
|
|
17319
|
+
headers: {
|
|
17320
|
+
[name: string]: unknown;
|
|
17321
|
+
};
|
|
17322
|
+
content?: never;
|
|
17323
|
+
};
|
|
17289
17324
|
};
|
|
17290
17325
|
};
|
|
17291
17326
|
patchSourceCandidateItem: {
|
|
@@ -17327,14 +17362,14 @@ export interface operations {
|
|
|
17327
17362
|
};
|
|
17328
17363
|
content?: never;
|
|
17329
17364
|
};
|
|
17330
|
-
/** @description
|
|
17365
|
+
/** @description The set, item or target document is not the org’s */
|
|
17331
17366
|
404: {
|
|
17332
17367
|
headers: {
|
|
17333
17368
|
[name: string]: unknown;
|
|
17334
17369
|
};
|
|
17335
17370
|
content?: never;
|
|
17336
17371
|
};
|
|
17337
|
-
/** @description The set is no longer a draft (SOURCE_SYNC_CANDIDATE_SET_NOT_DRAFT), or the item’s scope was already approved (SOURCE_SYNC_CANDIDATE_ITEM_FROZEN) */
|
|
17372
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or The set is no longer a draft (SOURCE_SYNC_CANDIDATE_SET_NOT_DRAFT), or the item’s scope was already approved (SOURCE_SYNC_CANDIDATE_ITEM_FROZEN) */
|
|
17338
17373
|
409: {
|
|
17339
17374
|
headers: {
|
|
17340
17375
|
[name: string]: unknown;
|
|
@@ -17374,14 +17409,14 @@ export interface operations {
|
|
|
17374
17409
|
"application/json": components["schemas"]["SourceSyncCandidateSetResponse"];
|
|
17375
17410
|
};
|
|
17376
17411
|
};
|
|
17377
|
-
/** @description
|
|
17412
|
+
/** @description The set, the file or the target document is not the org’s */
|
|
17378
17413
|
404: {
|
|
17379
17414
|
headers: {
|
|
17380
17415
|
[name: string]: unknown;
|
|
17381
17416
|
};
|
|
17382
17417
|
content?: never;
|
|
17383
17418
|
};
|
|
17384
|
-
/** @description No active Google Drive connection (SOURCE_SYNC_DRIVE_NOT_CONNECTED), the set is no longer a draft (SOURCE_SYNC_CANDIDATE_SET_NOT_DRAFT), or the file is already on the list for that document (SOURCE_SYNC_CANDIDATE_ALREADY_IN_SET) */
|
|
17419
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or No active Google Drive connection (SOURCE_SYNC_DRIVE_NOT_CONNECTED), the set is no longer a draft (SOURCE_SYNC_CANDIDATE_SET_NOT_DRAFT), or the file is already on the list for that document (SOURCE_SYNC_CANDIDATE_ALREADY_IN_SET) */
|
|
17385
17420
|
409: {
|
|
17386
17421
|
headers: {
|
|
17387
17422
|
[name: string]: unknown;
|
|
@@ -17425,14 +17460,14 @@ export interface operations {
|
|
|
17425
17460
|
};
|
|
17426
17461
|
content?: never;
|
|
17427
17462
|
};
|
|
17428
|
-
/** @description
|
|
17463
|
+
/** @description The set is not the org’s */
|
|
17429
17464
|
404: {
|
|
17430
17465
|
headers: {
|
|
17431
17466
|
[name: string]: unknown;
|
|
17432
17467
|
};
|
|
17433
17468
|
content?: never;
|
|
17434
17469
|
};
|
|
17435
|
-
/** @description Stale revision (SOURCE_SYNC_CANDIDATE_SET_STALE), an unresolved widening (SOURCE_SYNC_TREATMENT_UNRESOLVED), a file with no document (SOURCE_SYNC_TARGET_UNRESOLVED), a scope already approved (SOURCE_SYNC_SCOPE_ALREADY_APPROVED), or a set no longer a draft (SOURCE_SYNC_CANDIDATE_SET_NOT_DRAFT) */
|
|
17470
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or Stale revision (SOURCE_SYNC_CANDIDATE_SET_STALE), an unresolved widening (SOURCE_SYNC_TREATMENT_UNRESOLVED), a file with no document (SOURCE_SYNC_TARGET_UNRESOLVED), a scope already approved (SOURCE_SYNC_SCOPE_ALREADY_APPROVED), or a set no longer a draft (SOURCE_SYNC_CANDIDATE_SET_NOT_DRAFT) */
|
|
17436
17471
|
409: {
|
|
17437
17472
|
headers: {
|
|
17438
17473
|
[name: string]: unknown;
|
|
@@ -17459,8 +17494,8 @@ export interface operations {
|
|
|
17459
17494
|
"application/json": components["schemas"]["SourceSyncCurrentSynthesisResponse"];
|
|
17460
17495
|
};
|
|
17461
17496
|
};
|
|
17462
|
-
/** @description Source Sync is
|
|
17463
|
-
|
|
17497
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
|
|
17498
|
+
409: {
|
|
17464
17499
|
headers: {
|
|
17465
17500
|
[name: string]: unknown;
|
|
17466
17501
|
};
|
|
@@ -17488,13 +17523,20 @@ export interface operations {
|
|
|
17488
17523
|
"application/json": components["schemas"]["SourceSyncSynthesisResponse"];
|
|
17489
17524
|
};
|
|
17490
17525
|
};
|
|
17491
|
-
/** @description
|
|
17526
|
+
/** @description The batch is not the org’s */
|
|
17492
17527
|
404: {
|
|
17493
17528
|
headers: {
|
|
17494
17529
|
[name: string]: unknown;
|
|
17495
17530
|
};
|
|
17496
17531
|
content?: never;
|
|
17497
17532
|
};
|
|
17533
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
|
|
17534
|
+
409: {
|
|
17535
|
+
headers: {
|
|
17536
|
+
[name: string]: unknown;
|
|
17537
|
+
};
|
|
17538
|
+
content?: never;
|
|
17539
|
+
};
|
|
17498
17540
|
};
|
|
17499
17541
|
};
|
|
17500
17542
|
applySourceSynthesis: {
|
|
@@ -17534,14 +17576,14 @@ export interface operations {
|
|
|
17534
17576
|
};
|
|
17535
17577
|
content?: never;
|
|
17536
17578
|
};
|
|
17537
|
-
/** @description
|
|
17579
|
+
/** @description The batch or an included change is not the org’s */
|
|
17538
17580
|
404: {
|
|
17539
17581
|
headers: {
|
|
17540
17582
|
[name: string]: unknown;
|
|
17541
17583
|
};
|
|
17542
17584
|
content?: never;
|
|
17543
17585
|
};
|
|
17544
|
-
/** @description An included document still has an open question (SOURCE_SYNC_DOC_BLOCKED), or the review or a change is no longer open to apply (SOURCE_SYNC_SYNTHESIS_NOT_OPEN) */
|
|
17586
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or An included document still has an open question (SOURCE_SYNC_DOC_BLOCKED), or the review or a change is no longer open to apply (SOURCE_SYNC_SYNTHESIS_NOT_OPEN) */
|
|
17545
17587
|
409: {
|
|
17546
17588
|
headers: {
|
|
17547
17589
|
[name: string]: unknown;
|
|
@@ -17568,8 +17610,8 @@ export interface operations {
|
|
|
17568
17610
|
"application/json": components["schemas"]["SourceSyncRulesResponse"];
|
|
17569
17611
|
};
|
|
17570
17612
|
};
|
|
17571
|
-
/** @description Source Sync is
|
|
17572
|
-
|
|
17613
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
|
|
17614
|
+
409: {
|
|
17573
17615
|
headers: {
|
|
17574
17616
|
[name: string]: unknown;
|
|
17575
17617
|
};
|
|
@@ -17606,14 +17648,7 @@ export interface operations {
|
|
|
17606
17648
|
};
|
|
17607
17649
|
content?: never;
|
|
17608
17650
|
};
|
|
17609
|
-
/** @description Source Sync is
|
|
17610
|
-
404: {
|
|
17611
|
-
headers: {
|
|
17612
|
-
[name: string]: unknown;
|
|
17613
|
-
};
|
|
17614
|
-
content?: never;
|
|
17615
|
-
};
|
|
17616
|
-
/** @description An active rule already stands for this subject (SOURCE_SYNC_RULE_DUPLICATE); nothing changed */
|
|
17651
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or An active rule already stands for this subject (SOURCE_SYNC_RULE_DUPLICATE); nothing changed */
|
|
17617
17652
|
409: {
|
|
17618
17653
|
headers: {
|
|
17619
17654
|
[name: string]: unknown;
|
|
@@ -17642,13 +17677,20 @@ export interface operations {
|
|
|
17642
17677
|
"application/json": components["schemas"]["SourceSyncRule"];
|
|
17643
17678
|
};
|
|
17644
17679
|
};
|
|
17645
|
-
/** @description
|
|
17680
|
+
/** @description The rule is not the org’s or is already retired */
|
|
17646
17681
|
404: {
|
|
17647
17682
|
headers: {
|
|
17648
17683
|
[name: string]: unknown;
|
|
17649
17684
|
};
|
|
17650
17685
|
content?: never;
|
|
17651
17686
|
};
|
|
17687
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
|
|
17688
|
+
409: {
|
|
17689
|
+
headers: {
|
|
17690
|
+
[name: string]: unknown;
|
|
17691
|
+
};
|
|
17692
|
+
content?: never;
|
|
17693
|
+
};
|
|
17652
17694
|
};
|
|
17653
17695
|
};
|
|
17654
17696
|
listSourceSyncFindings: {
|
|
@@ -17676,8 +17718,8 @@ export interface operations {
|
|
|
17676
17718
|
};
|
|
17677
17719
|
content?: never;
|
|
17678
17720
|
};
|
|
17679
|
-
/** @description Source Sync is
|
|
17680
|
-
|
|
17721
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
|
|
17722
|
+
409: {
|
|
17681
17723
|
headers: {
|
|
17682
17724
|
[name: string]: unknown;
|
|
17683
17725
|
};
|
|
@@ -17723,14 +17765,14 @@ export interface operations {
|
|
|
17723
17765
|
};
|
|
17724
17766
|
content?: never;
|
|
17725
17767
|
};
|
|
17726
|
-
/** @description
|
|
17768
|
+
/** @description The finding is not the org’s or names no source */
|
|
17727
17769
|
404: {
|
|
17728
17770
|
headers: {
|
|
17729
17771
|
[name: string]: unknown;
|
|
17730
17772
|
};
|
|
17731
17773
|
content?: never;
|
|
17732
17774
|
};
|
|
17733
|
-
/** @description The finding already settled on its own (SOURCE_SYNC_FINDING_NOT_OPEN); nothing changed */
|
|
17775
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or The finding already settled on its own (SOURCE_SYNC_FINDING_NOT_OPEN); nothing changed */
|
|
17734
17776
|
409: {
|
|
17735
17777
|
headers: {
|
|
17736
17778
|
[name: string]: unknown;
|
|
@@ -17764,8 +17806,8 @@ export interface operations {
|
|
|
17764
17806
|
};
|
|
17765
17807
|
content?: never;
|
|
17766
17808
|
};
|
|
17767
|
-
/** @description Source Sync is
|
|
17768
|
-
|
|
17809
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
|
|
17810
|
+
409: {
|
|
17769
17811
|
headers: {
|
|
17770
17812
|
[name: string]: unknown;
|
|
17771
17813
|
};
|
|
@@ -17811,8 +17853,8 @@ export interface operations {
|
|
|
17811
17853
|
};
|
|
17812
17854
|
content?: never;
|
|
17813
17855
|
};
|
|
17814
|
-
/** @description Source Sync is
|
|
17815
|
-
|
|
17856
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
|
|
17857
|
+
409: {
|
|
17816
17858
|
headers: {
|
|
17817
17859
|
[name: string]: unknown;
|
|
17818
17860
|
};
|
|
@@ -17845,8 +17887,8 @@ export interface operations {
|
|
|
17845
17887
|
};
|
|
17846
17888
|
content?: never;
|
|
17847
17889
|
};
|
|
17848
|
-
/** @description Source Sync is
|
|
17849
|
-
|
|
17890
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
|
|
17891
|
+
409: {
|
|
17850
17892
|
headers: {
|
|
17851
17893
|
[name: string]: unknown;
|
|
17852
17894
|
};
|
|
@@ -17890,22 +17932,80 @@ export interface operations {
|
|
|
17890
17932
|
};
|
|
17891
17933
|
content?: never;
|
|
17892
17934
|
};
|
|
17893
|
-
/** @description Source Sync is not
|
|
17894
|
-
|
|
17935
|
+
/** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or Workspace-wide access is off or not set up, Drive is not connected or is not a Workspace account, reach is already domain, or Google did not accept the delegation */
|
|
17936
|
+
409: {
|
|
17895
17937
|
headers: {
|
|
17896
17938
|
[name: string]: unknown;
|
|
17897
17939
|
};
|
|
17898
17940
|
content?: never;
|
|
17899
17941
|
};
|
|
17900
|
-
/** @description
|
|
17901
|
-
|
|
17942
|
+
/** @description Google could not be reached to verify the delegation */
|
|
17943
|
+
502: {
|
|
17902
17944
|
headers: {
|
|
17903
17945
|
[name: string]: unknown;
|
|
17904
17946
|
};
|
|
17905
17947
|
content?: never;
|
|
17906
17948
|
};
|
|
17907
|
-
|
|
17908
|
-
|
|
17949
|
+
};
|
|
17950
|
+
};
|
|
17951
|
+
getSourceSyncSettings: {
|
|
17952
|
+
parameters: {
|
|
17953
|
+
query?: never;
|
|
17954
|
+
header?: never;
|
|
17955
|
+
path?: never;
|
|
17956
|
+
cookie?: never;
|
|
17957
|
+
};
|
|
17958
|
+
requestBody?: never;
|
|
17959
|
+
responses: {
|
|
17960
|
+
/** @description The org’s Source Sync switch */
|
|
17961
|
+
200: {
|
|
17962
|
+
headers: {
|
|
17963
|
+
[name: string]: unknown;
|
|
17964
|
+
};
|
|
17965
|
+
content: {
|
|
17966
|
+
"application/json": components["schemas"]["SourceSyncSettingsResponse"];
|
|
17967
|
+
};
|
|
17968
|
+
};
|
|
17969
|
+
/** @description The caller may not manage integrations */
|
|
17970
|
+
403: {
|
|
17971
|
+
headers: {
|
|
17972
|
+
[name: string]: unknown;
|
|
17973
|
+
};
|
|
17974
|
+
content?: never;
|
|
17975
|
+
};
|
|
17976
|
+
};
|
|
17977
|
+
};
|
|
17978
|
+
putSourceSyncSettings: {
|
|
17979
|
+
parameters: {
|
|
17980
|
+
query?: never;
|
|
17981
|
+
header?: never;
|
|
17982
|
+
path?: never;
|
|
17983
|
+
cookie?: never;
|
|
17984
|
+
};
|
|
17985
|
+
requestBody: {
|
|
17986
|
+
content: {
|
|
17987
|
+
"application/json": components["schemas"]["SourceSyncPutSettingsRequest"];
|
|
17988
|
+
};
|
|
17989
|
+
};
|
|
17990
|
+
responses: {
|
|
17991
|
+
/** @description The switch as it now stands */
|
|
17992
|
+
200: {
|
|
17993
|
+
headers: {
|
|
17994
|
+
[name: string]: unknown;
|
|
17995
|
+
};
|
|
17996
|
+
content: {
|
|
17997
|
+
"application/json": components["schemas"]["SourceSyncSettingsResponse"];
|
|
17998
|
+
};
|
|
17999
|
+
};
|
|
18000
|
+
/** @description Invalid body */
|
|
18001
|
+
400: {
|
|
18002
|
+
headers: {
|
|
18003
|
+
[name: string]: unknown;
|
|
18004
|
+
};
|
|
18005
|
+
content?: never;
|
|
18006
|
+
};
|
|
18007
|
+
/** @description The caller may not manage integrations */
|
|
18008
|
+
403: {
|
|
17909
18009
|
headers: {
|
|
17910
18010
|
[name: string]: unknown;
|
|
17911
18011
|
};
|
|
@@ -191,6 +191,7 @@ export const openApiRoutes = {
|
|
|
191
191
|
'/api/source-sync/reach/upgrade': ['POST'],
|
|
192
192
|
'/api/source-sync/rules': ['GET', 'POST'],
|
|
193
193
|
'/api/source-sync/rules/{ruleId}/retire': ['POST'],
|
|
194
|
+
'/api/source-sync/settings': ['GET', 'PUT'],
|
|
194
195
|
'/api/source-sync/standing-orders': ['GET'],
|
|
195
196
|
'/api/source-sync/standing-orders/{scopeKey}': ['PUT'],
|
|
196
197
|
'/api/source-sync/syntheses/current': ['GET'],
|
|
@@ -22,6 +22,7 @@ function makeNotification(over: Record<string, unknown> = {}) {
|
|
|
22
22
|
title: "Dev Patel approved your request",
|
|
23
23
|
detail: null,
|
|
24
24
|
contextLabel: "Q3 OKRs",
|
|
25
|
+
provider: null,
|
|
25
26
|
href: "/@acme/md/doc-1",
|
|
26
27
|
createdAt: "2026-07-30T12:00:00.000Z",
|
|
27
28
|
readAt: null,
|
|
@@ -138,6 +139,30 @@ describe("UserNotificationSchema", () => {
|
|
|
138
139
|
});
|
|
139
140
|
});
|
|
140
141
|
|
|
142
|
+
describe("provider — the external system a row is about", () => {
|
|
143
|
+
it("carries a provider id when the row is about one", () => {
|
|
144
|
+
expect(
|
|
145
|
+
UserNotificationSchema.safeParse(
|
|
146
|
+
makeNotification({ provider: "bamboohr" }),
|
|
147
|
+
).success,
|
|
148
|
+
).toBe(true);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("is REQUIRED — null says 'about the product', absence says nothing", () => {
|
|
152
|
+
const { provider: _omitted, ...withoutProvider } = makeNotification();
|
|
153
|
+
expect(UserNotificationSchema.safeParse(withoutProvider).success).toBe(
|
|
154
|
+
false,
|
|
155
|
+
);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("rejects an empty id — a mark nobody can look up", () => {
|
|
159
|
+
expect(
|
|
160
|
+
UserNotificationSchema.safeParse(makeNotification({ provider: "" }))
|
|
161
|
+
.success,
|
|
162
|
+
).toBe(false);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
141
166
|
describe("FeedItem discriminates on `row`", () => {
|
|
142
167
|
it("accepts an informational row", () => {
|
|
143
168
|
const parsed = FeedItemSchema.safeParse({
|
|
@@ -158,6 +183,7 @@ describe("FeedItem discriminates on `row`", () => {
|
|
|
158
183
|
title: "Maya Chen wants access",
|
|
159
184
|
detail: null,
|
|
160
185
|
contextLabel: "Q3 OKRs",
|
|
186
|
+
provider: null,
|
|
161
187
|
href: "/@acme/md/doc-1?share=1&request=req-1",
|
|
162
188
|
createdAt: "2026-07-30T12:00:00.000Z",
|
|
163
189
|
},
|
|
@@ -49,6 +49,16 @@ export const UserNotificationSchema = z.object({
|
|
|
49
49
|
detail: z.string().nullable(),
|
|
50
50
|
/** The thing it is about, as the user names it, e.g. "Sales.md". */
|
|
51
51
|
contextLabel: z.string(),
|
|
52
|
+
/**
|
|
53
|
+
* The external system this row is ABOUT, when it is about one — the open
|
|
54
|
+
* provider id the identity-link vocabulary uses system-wide ('bamboohr',
|
|
55
|
+
* 'google_drive', 'slack'). A surface shows that system's own mark.
|
|
56
|
+
*
|
|
57
|
+
* Set by the producer, because only it knows: an org's structure findings
|
|
58
|
+
* come from whichever HRIS it connected, which the kind cannot say.
|
|
59
|
+
* `null` when the row is about the product itself (a doc, a chat, billing).
|
|
60
|
+
*/
|
|
61
|
+
provider: z.string().min(1).nullable(),
|
|
52
62
|
/**
|
|
53
63
|
* Where to go to SEE it — a RELATIVE app path.
|
|
54
64
|
*
|