@company-semantics/contracts 13.19.0 → 13.20.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 +4 -4
- package/src/api/generated-spec-hash.ts +2 -2
- package/src/api/generated.ts +19 -2
- package/src/generated/openapi-routes.ts +1 -0
- package/src/index.ts +13 -0
- package/src/org/index.ts +13 -0
- package/src/org/schemas.ts +11 -2
- package/src/org/structure-facts.ts +105 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@company-semantics/contracts",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.20.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -119,15 +119,15 @@
|
|
|
119
119
|
"zod": "^4.4.3"
|
|
120
120
|
},
|
|
121
121
|
"devDependencies": {
|
|
122
|
-
"@types/node": "^
|
|
122
|
+
"@types/node": "^25.9.3",
|
|
123
123
|
"husky": "^9.1.7",
|
|
124
124
|
"lint-staged": "^17.0.7",
|
|
125
125
|
"markdownlint-cli2": "^0.22.1",
|
|
126
126
|
"openapi-typescript": "^7.13.0",
|
|
127
|
-
"prettier": "^3.8.
|
|
127
|
+
"prettier": "^3.8.4",
|
|
128
128
|
"tsx": "^4.22.4",
|
|
129
129
|
"typescript": "^5.8.3",
|
|
130
|
-
"vitest": "^4.1.
|
|
130
|
+
"vitest": "^4.1.9",
|
|
131
131
|
"yaml": "^2.9.0"
|
|
132
132
|
},
|
|
133
133
|
"pnpm": {
|
|
@@ -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 = '255ee9f997af' as const;
|
|
3
|
+
export const SPEC_HASH_FULL = '255ee9f997afb36f3e96cdcffb8aa30a97e5c14f8c21b884974c75f9d126d596' as const;
|
package/src/api/generated.ts
CHANGED
|
@@ -3376,7 +3376,7 @@ export interface components {
|
|
|
3376
3376
|
};
|
|
3377
3377
|
ownerTitle: string;
|
|
3378
3378
|
/** @enum {string} */
|
|
3379
|
-
ownerIcon: "crown" | "crown-cross" | "person" | "medal-military" | "dog" | "cat";
|
|
3379
|
+
ownerIcon: "crown" | "crown-cross" | "person-simple-run" | "person" | "medal-military" | "dog" | "cat" | "linux-logo";
|
|
3380
3380
|
createdAt: string;
|
|
3381
3381
|
memberCount: number;
|
|
3382
3382
|
claimable: boolean;
|
|
@@ -3390,7 +3390,7 @@ export interface components {
|
|
|
3390
3390
|
OrgRenameRequest: {
|
|
3391
3391
|
name?: string;
|
|
3392
3392
|
ownerTitle?: string | null;
|
|
3393
|
-
ownerIcon?: ("crown" | "crown-cross" | "person" | "medal-military" | "dog" | "cat") | null;
|
|
3393
|
+
ownerIcon?: ("crown" | "crown-cross" | "person-simple-run" | "person" | "medal-military" | "dog" | "cat" | "linux-logo") | null;
|
|
3394
3394
|
};
|
|
3395
3395
|
WorkspaceMembersResponse: {
|
|
3396
3396
|
items: {
|
|
@@ -4051,6 +4051,11 @@ export interface components {
|
|
|
4051
4051
|
state: "allowed" | "blocked";
|
|
4052
4052
|
requiredScope?: string;
|
|
4053
4053
|
};
|
|
4054
|
+
manageSharing: {
|
|
4055
|
+
/** @enum {string} */
|
|
4056
|
+
state: "allowed" | "blocked";
|
|
4057
|
+
requiredScope?: string;
|
|
4058
|
+
};
|
|
4054
4059
|
};
|
|
4055
4060
|
workItem?: {
|
|
4056
4061
|
transferOwnership: {
|
|
@@ -4058,6 +4063,18 @@ export interface components {
|
|
|
4058
4063
|
state: "allowed" | "blocked";
|
|
4059
4064
|
requiredScope?: string;
|
|
4060
4065
|
};
|
|
4066
|
+
manageSharing: {
|
|
4067
|
+
/** @enum {string} */
|
|
4068
|
+
state: "allowed" | "blocked";
|
|
4069
|
+
requiredScope?: string;
|
|
4070
|
+
};
|
|
4071
|
+
};
|
|
4072
|
+
meetingRecording?: {
|
|
4073
|
+
manageSharing: {
|
|
4074
|
+
/** @enum {string} */
|
|
4075
|
+
state: "allowed" | "blocked";
|
|
4076
|
+
requiredScope?: string;
|
|
4077
|
+
};
|
|
4061
4078
|
};
|
|
4062
4079
|
};
|
|
4063
4080
|
};
|
|
@@ -82,6 +82,7 @@ export const openApiRoutes = {
|
|
|
82
82
|
'/api/org-units/{unitId}/delegations': ['POST'],
|
|
83
83
|
'/api/org-units/{unitId}/delegations/{id}': ['DELETE', 'PATCH'],
|
|
84
84
|
'/api/org-units/{unitId}/descendants': ['GET'],
|
|
85
|
+
'/api/org-units/{unitId}/head': ['DELETE', 'PUT'],
|
|
85
86
|
'/api/org-units/{unitId}/memberships': ['GET', 'POST'],
|
|
86
87
|
'/api/org-units/{unitId}/memberships/{userId}': ['DELETE'],
|
|
87
88
|
'/api/org-units/{unitId}/memberships/{userId}/role': ['PUT'],
|
package/src/index.ts
CHANGED
|
@@ -358,6 +358,19 @@ export {
|
|
|
358
358
|
// View authorization types (Phase 5 - ADR-APP-013)
|
|
359
359
|
export type { AuthorizableView } from "./org/index";
|
|
360
360
|
|
|
361
|
+
// Org structure facts: provenance + home/membership separation (ADR-CONTRACTS-066)
|
|
362
|
+
export {
|
|
363
|
+
FactSourceTierSchema,
|
|
364
|
+
FACT_SOURCE_TIER_PRECEDENCE,
|
|
365
|
+
FactProvenanceSchema,
|
|
366
|
+
HomeAssignmentSchema,
|
|
367
|
+
} from "./org/index";
|
|
368
|
+
export type {
|
|
369
|
+
FactSourceTier,
|
|
370
|
+
FactProvenance,
|
|
371
|
+
HomeAssignment,
|
|
372
|
+
} from "./org/index";
|
|
373
|
+
|
|
361
374
|
// Authority & Delegation vocabulary
|
|
362
375
|
export {
|
|
363
376
|
AuthoritySourceSchema,
|
package/src/org/index.ts
CHANGED
|
@@ -87,6 +87,19 @@ export type {
|
|
|
87
87
|
export type { AuthorizableView } from "./view-scopes";
|
|
88
88
|
export { VIEW_SCOPE_MAP, getViewScope } from "./view-scopes";
|
|
89
89
|
|
|
90
|
+
// Org structure facts: provenance + home/membership separation (ADR-CONTRACTS-066)
|
|
91
|
+
export {
|
|
92
|
+
FactSourceTierSchema,
|
|
93
|
+
FACT_SOURCE_TIER_PRECEDENCE,
|
|
94
|
+
FactProvenanceSchema,
|
|
95
|
+
HomeAssignmentSchema,
|
|
96
|
+
} from "./structure-facts";
|
|
97
|
+
export type {
|
|
98
|
+
FactSourceTier,
|
|
99
|
+
FactProvenance,
|
|
100
|
+
HomeAssignment,
|
|
101
|
+
} from "./structure-facts";
|
|
102
|
+
|
|
90
103
|
// Canonical OrgUnit tree ordering (PRD-00506)
|
|
91
104
|
export type { TreeOrderableNode } from "./tree-ordering";
|
|
92
105
|
export { orderTreeNodes } from "./tree-ordering";
|
package/src/org/schemas.ts
CHANGED
|
@@ -1438,16 +1438,25 @@ export const CapabilitiesResponseSchema = z.object({
|
|
|
1438
1438
|
orgUnit: z.object({
|
|
1439
1439
|
manage: ActionCapabilitySchema,
|
|
1440
1440
|
}),
|
|
1441
|
-
// Entity ownership-transfer overrides (backend ADR-BE-259)
|
|
1442
|
-
//
|
|
1441
|
+
// Entity ownership-transfer overrides (backend ADR-BE-259) +
|
|
1442
|
+
// sharing-management custody (backend ADR-BE-288). Optional so older
|
|
1443
|
+
// backends that don't derive them still validate. manageSharing gates the
|
|
1444
|
+
// admin Share affordance on content the admin may not be able to view.
|
|
1443
1445
|
companyMd: z
|
|
1444
1446
|
.object({
|
|
1445
1447
|
transferOwnership: ActionCapabilitySchema,
|
|
1448
|
+
manageSharing: ActionCapabilitySchema,
|
|
1446
1449
|
})
|
|
1447
1450
|
.optional(),
|
|
1448
1451
|
workItem: z
|
|
1449
1452
|
.object({
|
|
1450
1453
|
transferOwnership: ActionCapabilitySchema,
|
|
1454
|
+
manageSharing: ActionCapabilitySchema,
|
|
1455
|
+
})
|
|
1456
|
+
.optional(),
|
|
1457
|
+
meetingRecording: z
|
|
1458
|
+
.object({
|
|
1459
|
+
manageSharing: ActionCapabilitySchema,
|
|
1451
1460
|
})
|
|
1452
1461
|
.optional(),
|
|
1453
1462
|
})
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Org structure facts: provenance envelope + the home/membership separation.
|
|
3
|
+
*
|
|
4
|
+
* The org model is several INDEPENDENT graphs — the org-unit tree, the reporting
|
|
5
|
+
* graph, the home assignment, and the membership graph (and, later, positions).
|
|
6
|
+
* This module is the shared vocabulary for two cross-cutting ideas in that model
|
|
7
|
+
* (see ADR-CONTRACTS-066 and control ADR-CTRL-159):
|
|
8
|
+
*
|
|
9
|
+
* 1. Every structural fact carries provenance ({@link FactProvenanceSchema}).
|
|
10
|
+
* 2. "Home" is a dedicated ≤1-per-person relation ({@link HomeAssignmentSchema}),
|
|
11
|
+
* kept SEPARATE from `org_unit_memberships` — not a `kind` flag on memberships.
|
|
12
|
+
*
|
|
13
|
+
* Principles encoded here (do not drift from these):
|
|
14
|
+
* - Membership / home is an INPUT to authority derivation, NOT authority itself.
|
|
15
|
+
* `home member of unit` does not mean `owns unit`.
|
|
16
|
+
* - Facts are immutable; corrections SUPERSEDE prior facts (`supersedesFactId`)
|
|
17
|
+
* rather than mutating in place. This leaves room for event-sourcing later
|
|
18
|
+
* without forcing it now.
|
|
19
|
+
* - A truth hierarchy decides which fact wins: user > sync > import > inferred.
|
|
20
|
+
* - `source` is an OPEN string so new origins (scim, workday, csv, org_chart,
|
|
21
|
+
* google, slack, …) need no schema change; `tier` is the closed precedence axis.
|
|
22
|
+
*/
|
|
23
|
+
import { z } from "zod";
|
|
24
|
+
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Provenance
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The precedence axis for a fact. Closed set, ordered highest-precedence first
|
|
31
|
+
* (see {@link FACT_SOURCE_TIER_PRECEDENCE}). The specific origin lives in the
|
|
32
|
+
* open `source` string; this enum is what comparison / "who wins" reasons over.
|
|
33
|
+
*/
|
|
34
|
+
export const FactSourceTierSchema = z.enum([
|
|
35
|
+
"user",
|
|
36
|
+
"sync",
|
|
37
|
+
"import",
|
|
38
|
+
"inferred",
|
|
39
|
+
]);
|
|
40
|
+
export type FactSourceTier = z.infer<typeof FactSourceTierSchema>;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Truth hierarchy, highest precedence first. A writer at a lower tier must never
|
|
44
|
+
* supersede a fact recorded at a higher tier (e.g. an org-chart import must not
|
|
45
|
+
* overwrite a `user`-entered reporting edge).
|
|
46
|
+
*/
|
|
47
|
+
export const FACT_SOURCE_TIER_PRECEDENCE = [
|
|
48
|
+
"user",
|
|
49
|
+
"sync",
|
|
50
|
+
"import",
|
|
51
|
+
"inferred",
|
|
52
|
+
] as const satisfies ReadonlyArray<FactSourceTier>;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Provenance envelope attached to a structural fact (reporting edge, org unit,
|
|
56
|
+
* membership, home assignment). The live value of any fact is the
|
|
57
|
+
* highest-precedence, non-superseded record.
|
|
58
|
+
*/
|
|
59
|
+
export const FactProvenanceSchema = z.object({
|
|
60
|
+
/** Precedence axis used by the truth hierarchy. */
|
|
61
|
+
tier: FactSourceTierSchema,
|
|
62
|
+
/**
|
|
63
|
+
* Specific origin — OPEN set, e.g. `manual` | `org_chart` | `scim` | `hris` |
|
|
64
|
+
* `csv` | `google` | `slack`. New origins slot in without a schema change.
|
|
65
|
+
*/
|
|
66
|
+
source: z.string().min(1),
|
|
67
|
+
/** Extractor/matcher certainty in [0,1]; `null` for human-entered facts. */
|
|
68
|
+
confidence: z.number().min(0).max(1).nullable(),
|
|
69
|
+
/**
|
|
70
|
+
* True once a human has corrected/confirmed the fact. A locked fact is sticky:
|
|
71
|
+
* lower-tier writers (imports, inference) must not supersede it.
|
|
72
|
+
*/
|
|
73
|
+
locked: z.boolean(),
|
|
74
|
+
/**
|
|
75
|
+
* The fact this record supersedes (immutable correction history); `null`/absent
|
|
76
|
+
* for an original. Enables append+supersede without destructive updates.
|
|
77
|
+
*/
|
|
78
|
+
supersedesFactId: z.string().uuid().nullable().optional(),
|
|
79
|
+
});
|
|
80
|
+
export type FactProvenance = z.infer<typeof FactProvenanceSchema>;
|
|
81
|
+
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// HomeAssignment (separate from membership)
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* A person's single structural home unit — at most one per person per org.
|
|
88
|
+
*
|
|
89
|
+
* SEPARATE relation from `org_unit_memberships` (NOT a `kind`/role flag on a
|
|
90
|
+
* shared table): the cardinalities differ on purpose — exactly one home, many
|
|
91
|
+
* memberships — which is the tell that they are different concepts. A shared
|
|
92
|
+
* `Membership(kind='home'|'member')` would inevitably grow
|
|
93
|
+
* `acting-home`/`temporary-home`/`future-home` flags.
|
|
94
|
+
*
|
|
95
|
+
* Home is an INPUT to authority derivation, sets `department`/`org` scope, and
|
|
96
|
+
* filters chart inclusion. It is NOT authority by itself (see Principles above).
|
|
97
|
+
* Supersedes the legacy `users.primary_unit_id` pointer (ADR-BE-120).
|
|
98
|
+
*/
|
|
99
|
+
export const HomeAssignmentSchema = z.object({
|
|
100
|
+
personId: z.string().uuid(),
|
|
101
|
+
orgUnitId: z.string().uuid(),
|
|
102
|
+
/** Provenance of this home assignment. Optional on lightweight projections. */
|
|
103
|
+
provenance: FactProvenanceSchema.optional(),
|
|
104
|
+
});
|
|
105
|
+
export type HomeAssignment = z.infer<typeof HomeAssignmentSchema>;
|