@company-semantics/contracts 2.1.0 → 2.2.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/api/generated.ts +180 -0
- package/src/index.ts +11 -3
- package/src/org/index.ts +11 -3
- package/src/org/schemas.ts +79 -18
package/package.json
CHANGED
package/src/api/generated.ts
CHANGED
|
@@ -1678,6 +1678,57 @@ export interface paths {
|
|
|
1678
1678
|
patch?: never;
|
|
1679
1679
|
trace?: never;
|
|
1680
1680
|
};
|
|
1681
|
+
"/api/org-units/{unitId}/owners": {
|
|
1682
|
+
parameters: {
|
|
1683
|
+
query?: never;
|
|
1684
|
+
header?: never;
|
|
1685
|
+
path?: never;
|
|
1686
|
+
cookie?: never;
|
|
1687
|
+
};
|
|
1688
|
+
/** List owners of an org unit (local by default; inherited when ?explain=true) */
|
|
1689
|
+
get: operations["listOrgUnitOwners"];
|
|
1690
|
+
put?: never;
|
|
1691
|
+
post?: never;
|
|
1692
|
+
delete?: never;
|
|
1693
|
+
options?: never;
|
|
1694
|
+
head?: never;
|
|
1695
|
+
patch?: never;
|
|
1696
|
+
trace?: never;
|
|
1697
|
+
};
|
|
1698
|
+
"/api/org-units/{unitId}/delegations": {
|
|
1699
|
+
parameters: {
|
|
1700
|
+
query?: never;
|
|
1701
|
+
header?: never;
|
|
1702
|
+
path?: never;
|
|
1703
|
+
cookie?: never;
|
|
1704
|
+
};
|
|
1705
|
+
get?: never;
|
|
1706
|
+
put?: never;
|
|
1707
|
+
/** Grant an explicit delegation to a user on an org unit */
|
|
1708
|
+
post: operations["createOrgUnitDelegation"];
|
|
1709
|
+
delete?: never;
|
|
1710
|
+
options?: never;
|
|
1711
|
+
head?: never;
|
|
1712
|
+
patch?: never;
|
|
1713
|
+
trace?: never;
|
|
1714
|
+
};
|
|
1715
|
+
"/api/org-units/{unitId}/delegations/{id}": {
|
|
1716
|
+
parameters: {
|
|
1717
|
+
query?: never;
|
|
1718
|
+
header?: never;
|
|
1719
|
+
path?: never;
|
|
1720
|
+
cookie?: never;
|
|
1721
|
+
};
|
|
1722
|
+
get?: never;
|
|
1723
|
+
put?: never;
|
|
1724
|
+
post?: never;
|
|
1725
|
+
/** Revoke an existing delegation by id */
|
|
1726
|
+
delete: operations["deleteOrgUnitDelegation"];
|
|
1727
|
+
options?: never;
|
|
1728
|
+
head?: never;
|
|
1729
|
+
patch?: never;
|
|
1730
|
+
trace?: never;
|
|
1731
|
+
};
|
|
1681
1732
|
"/api/org-units/{unitId}/memberships": {
|
|
1682
1733
|
parameters: {
|
|
1683
1734
|
query?: never;
|
|
@@ -3469,6 +3520,62 @@ export interface components {
|
|
|
3469
3520
|
inheritedFromUnitName: string;
|
|
3470
3521
|
}[];
|
|
3471
3522
|
};
|
|
3523
|
+
OrgUnitOwnersResponse: {
|
|
3524
|
+
owners: {
|
|
3525
|
+
/** Format: uuid */
|
|
3526
|
+
userId: string;
|
|
3527
|
+
fullName: string;
|
|
3528
|
+
jobTitle: string | null;
|
|
3529
|
+
slackAvatarUrl: string | null;
|
|
3530
|
+
/** @enum {string} */
|
|
3531
|
+
authoritySource: "structural" | "delegated" | "manual_membership" | "org_admin";
|
|
3532
|
+
/** @enum {string} */
|
|
3533
|
+
authorityOrigin: "topology" | "delegation" | "administrative_override";
|
|
3534
|
+
isLocal: boolean;
|
|
3535
|
+
/** Format: uuid */
|
|
3536
|
+
derivedFromUnitId: string;
|
|
3537
|
+
derivedFromUnitName?: string;
|
|
3538
|
+
derivedFromUserId?: string | null;
|
|
3539
|
+
derivationMetadata?: {
|
|
3540
|
+
[key: string]: unknown;
|
|
3541
|
+
};
|
|
3542
|
+
}[];
|
|
3543
|
+
inherited?: {
|
|
3544
|
+
/** Format: uuid */
|
|
3545
|
+
userId: string;
|
|
3546
|
+
fullName: string;
|
|
3547
|
+
jobTitle: string | null;
|
|
3548
|
+
slackAvatarUrl: string | null;
|
|
3549
|
+
/** @enum {string} */
|
|
3550
|
+
authoritySource: "structural" | "delegated" | "manual_membership" | "org_admin";
|
|
3551
|
+
/** @enum {string} */
|
|
3552
|
+
authorityOrigin: "topology" | "delegation" | "administrative_override";
|
|
3553
|
+
isLocal: boolean;
|
|
3554
|
+
/** Format: uuid */
|
|
3555
|
+
derivedFromUnitId: string;
|
|
3556
|
+
derivedFromUnitName?: string;
|
|
3557
|
+
derivedFromUserId?: string | null;
|
|
3558
|
+
derivationMetadata?: {
|
|
3559
|
+
[key: string]: unknown;
|
|
3560
|
+
};
|
|
3561
|
+
}[];
|
|
3562
|
+
};
|
|
3563
|
+
Delegation: {
|
|
3564
|
+
/** Format: uuid */
|
|
3565
|
+
id: string;
|
|
3566
|
+
/** Format: uuid */
|
|
3567
|
+
orgId: string;
|
|
3568
|
+
/** Format: uuid */
|
|
3569
|
+
unitId: string;
|
|
3570
|
+
/** Format: uuid */
|
|
3571
|
+
userId: string;
|
|
3572
|
+
grantedBy: string | null;
|
|
3573
|
+
grantedAt: string;
|
|
3574
|
+
revokedAt: string | null;
|
|
3575
|
+
/** @enum {string} */
|
|
3576
|
+
status: "active" | "revoked";
|
|
3577
|
+
note: string | null;
|
|
3578
|
+
};
|
|
3472
3579
|
OrgUnitMembershipListResponse: {
|
|
3473
3580
|
/** Format: uuid */
|
|
3474
3581
|
unitId: string;
|
|
@@ -6377,6 +6484,79 @@ export interface operations {
|
|
|
6377
6484
|
};
|
|
6378
6485
|
};
|
|
6379
6486
|
};
|
|
6487
|
+
listOrgUnitOwners: {
|
|
6488
|
+
parameters: {
|
|
6489
|
+
query?: never;
|
|
6490
|
+
header?: never;
|
|
6491
|
+
path: {
|
|
6492
|
+
unitId: string;
|
|
6493
|
+
};
|
|
6494
|
+
cookie?: never;
|
|
6495
|
+
};
|
|
6496
|
+
requestBody?: never;
|
|
6497
|
+
responses: {
|
|
6498
|
+
/** @description Owners hydrated with profile fields. Includes `inherited` when ?explain=true. */
|
|
6499
|
+
200: {
|
|
6500
|
+
headers: {
|
|
6501
|
+
[name: string]: unknown;
|
|
6502
|
+
};
|
|
6503
|
+
content: {
|
|
6504
|
+
"application/json": components["schemas"]["OrgUnitOwnersResponse"];
|
|
6505
|
+
};
|
|
6506
|
+
};
|
|
6507
|
+
};
|
|
6508
|
+
};
|
|
6509
|
+
createOrgUnitDelegation: {
|
|
6510
|
+
parameters: {
|
|
6511
|
+
query?: never;
|
|
6512
|
+
header?: never;
|
|
6513
|
+
path: {
|
|
6514
|
+
unitId: string;
|
|
6515
|
+
};
|
|
6516
|
+
cookie?: never;
|
|
6517
|
+
};
|
|
6518
|
+
requestBody: {
|
|
6519
|
+
content: {
|
|
6520
|
+
"application/json": {
|
|
6521
|
+
/** Format: uuid */
|
|
6522
|
+
userId: string;
|
|
6523
|
+
note?: string;
|
|
6524
|
+
};
|
|
6525
|
+
};
|
|
6526
|
+
};
|
|
6527
|
+
responses: {
|
|
6528
|
+
/** @description Created delegation row */
|
|
6529
|
+
201: {
|
|
6530
|
+
headers: {
|
|
6531
|
+
[name: string]: unknown;
|
|
6532
|
+
};
|
|
6533
|
+
content: {
|
|
6534
|
+
"application/json": components["schemas"]["Delegation"];
|
|
6535
|
+
};
|
|
6536
|
+
};
|
|
6537
|
+
};
|
|
6538
|
+
};
|
|
6539
|
+
deleteOrgUnitDelegation: {
|
|
6540
|
+
parameters: {
|
|
6541
|
+
query?: never;
|
|
6542
|
+
header?: never;
|
|
6543
|
+
path: {
|
|
6544
|
+
unitId: string;
|
|
6545
|
+
id: string;
|
|
6546
|
+
};
|
|
6547
|
+
cookie?: never;
|
|
6548
|
+
};
|
|
6549
|
+
requestBody?: never;
|
|
6550
|
+
responses: {
|
|
6551
|
+
/** @description Delegation revoked */
|
|
6552
|
+
204: {
|
|
6553
|
+
headers: {
|
|
6554
|
+
[name: string]: unknown;
|
|
6555
|
+
};
|
|
6556
|
+
content?: never;
|
|
6557
|
+
};
|
|
6558
|
+
};
|
|
6559
|
+
};
|
|
6380
6560
|
listOrgUnitMemberships: {
|
|
6381
6561
|
parameters: {
|
|
6382
6562
|
query?: never;
|
package/src/index.ts
CHANGED
|
@@ -347,12 +347,16 @@ export { ROLE_DISPLAY_MAP, VIEW_SCOPE_MAP, getViewScope, TRANSFER_RESPONSIBILITI
|
|
|
347
347
|
// View authorization types (Phase 5 - ADR-APP-013)
|
|
348
348
|
export type { AuthorizableView } from './org/index'
|
|
349
349
|
|
|
350
|
-
// Authority & Delegation vocabulary
|
|
350
|
+
// Authority & Delegation vocabulary
|
|
351
351
|
export {
|
|
352
352
|
AuthoritySourceSchema,
|
|
353
353
|
AuthorityOriginSchema,
|
|
354
354
|
AuthorityConfidenceSchema,
|
|
355
|
-
|
|
355
|
+
AuthorityMechanismSchema,
|
|
356
|
+
AuthorityLocalitySchema,
|
|
357
|
+
AuthorityMutabilitySchema,
|
|
358
|
+
OwnerAuthoritySchema,
|
|
359
|
+
OrgUnitOwnerSchema,
|
|
356
360
|
OrgUnitOwnersResponseSchema,
|
|
357
361
|
DelegationSchema,
|
|
358
362
|
CreateDelegationRequestSchema,
|
|
@@ -362,7 +366,11 @@ export type {
|
|
|
362
366
|
AuthoritySource,
|
|
363
367
|
AuthorityOrigin,
|
|
364
368
|
AuthorityConfidence,
|
|
365
|
-
|
|
369
|
+
AuthorityMechanism,
|
|
370
|
+
AuthorityLocality,
|
|
371
|
+
AuthorityMutability,
|
|
372
|
+
OwnerAuthority,
|
|
373
|
+
OrgUnitOwner,
|
|
366
374
|
OrgUnitOwnersResponse,
|
|
367
375
|
Delegation,
|
|
368
376
|
CreateDelegationRequest,
|
package/src/org/index.ts
CHANGED
|
@@ -270,12 +270,16 @@ export type {
|
|
|
270
270
|
UpdateOrgUnitResponse,
|
|
271
271
|
} from './schemas';
|
|
272
272
|
|
|
273
|
-
// Authority & Delegation vocabulary
|
|
273
|
+
// Authority & Delegation vocabulary
|
|
274
274
|
export {
|
|
275
275
|
AuthoritySourceSchema,
|
|
276
276
|
AuthorityOriginSchema,
|
|
277
277
|
AuthorityConfidenceSchema,
|
|
278
|
-
|
|
278
|
+
AuthorityMechanismSchema,
|
|
279
|
+
AuthorityLocalitySchema,
|
|
280
|
+
AuthorityMutabilitySchema,
|
|
281
|
+
OwnerAuthoritySchema,
|
|
282
|
+
OrgUnitOwnerSchema,
|
|
279
283
|
OrgUnitOwnersResponseSchema,
|
|
280
284
|
DelegationSchema,
|
|
281
285
|
CreateDelegationRequestSchema,
|
|
@@ -285,7 +289,11 @@ export type {
|
|
|
285
289
|
AuthoritySource,
|
|
286
290
|
AuthorityOrigin,
|
|
287
291
|
AuthorityConfidence,
|
|
288
|
-
|
|
292
|
+
AuthorityMechanism,
|
|
293
|
+
AuthorityLocality,
|
|
294
|
+
AuthorityMutability,
|
|
295
|
+
OwnerAuthority,
|
|
296
|
+
OrgUnitOwner,
|
|
289
297
|
OrgUnitOwnersResponse,
|
|
290
298
|
Delegation,
|
|
291
299
|
CreateDelegationRequest,
|
package/src/org/schemas.ts
CHANGED
|
@@ -759,19 +759,25 @@ export const OrgUnitMembershipSchema = z.object({
|
|
|
759
759
|
});
|
|
760
760
|
|
|
761
761
|
// ---------------------------------------------------------------------------
|
|
762
|
-
// Authority & Delegation vocabulary
|
|
762
|
+
// Authority & Delegation vocabulary
|
|
763
763
|
//
|
|
764
|
-
//
|
|
765
|
-
//
|
|
766
|
-
//
|
|
767
|
-
//
|
|
768
|
-
//
|
|
764
|
+
// The API expresses authority as orthogonal axes (mechanism × locality ×
|
|
765
|
+
// mutability) instead of a single overloaded `source` enum, so future
|
|
766
|
+
// combinations like inherited-delegated or hris-delegated compose by
|
|
767
|
+
// construction rather than forcing each consumer to add a new switch case.
|
|
768
|
+
// The engine's internal AuthoritySource enum stays narrower than the wire
|
|
769
|
+
// shape — it's debug/audit vocabulary, not API vocabulary.
|
|
769
770
|
// ---------------------------------------------------------------------------
|
|
770
771
|
|
|
772
|
+
/**
|
|
773
|
+
* Engine-internal authority source. Used by the projection storage layer for
|
|
774
|
+
* debugging and drift records; not part of the public API response shape.
|
|
775
|
+
* `manual_membership` was removed when the legacy `l{N}_unit_owner` track was
|
|
776
|
+
* canonicalized onto delegations.
|
|
777
|
+
*/
|
|
771
778
|
export const AuthoritySourceSchema = z.enum([
|
|
772
779
|
'structural',
|
|
773
780
|
'delegated',
|
|
774
|
-
'manual_membership',
|
|
775
781
|
'org_admin',
|
|
776
782
|
]);
|
|
777
783
|
export type AuthoritySource = z.infer<typeof AuthoritySourceSchema>;
|
|
@@ -786,24 +792,79 @@ export type AuthorityOrigin = z.infer<typeof AuthorityOriginSchema>;
|
|
|
786
792
|
export const AuthorityConfidenceSchema = z.enum(['authoritative', 'inferred']);
|
|
787
793
|
export type AuthorityConfidence = z.infer<typeof AuthorityConfidenceSchema>;
|
|
788
794
|
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
795
|
+
/** How the authority arose. */
|
|
796
|
+
export const AuthorityMechanismSchema = z.enum([
|
|
797
|
+
'structural',
|
|
798
|
+
'delegated',
|
|
799
|
+
'rbac',
|
|
800
|
+
]);
|
|
801
|
+
export type AuthorityMechanism = z.infer<typeof AuthorityMechanismSchema>;
|
|
802
|
+
|
|
803
|
+
/** Whether the grant lives on the target unit or is inherited from an ancestor. */
|
|
804
|
+
export const AuthorityLocalitySchema = z.enum(['local', 'inherited']);
|
|
805
|
+
export type AuthorityLocality = z.infer<typeof AuthorityLocalitySchema>;
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* Whether the user can change this authority from this surface.
|
|
809
|
+
* - `derived`: change the upstream source instead (the org chart, RBAC roles).
|
|
810
|
+
* - `user_managed`: removable from this UI.
|
|
811
|
+
*/
|
|
812
|
+
export const AuthorityMutabilitySchema = z.enum(['derived', 'user_managed']);
|
|
813
|
+
export type AuthorityMutability = z.infer<typeof AuthorityMutabilitySchema>;
|
|
814
|
+
|
|
815
|
+
export const OwnerAuthoritySchema = z.object({
|
|
816
|
+
mechanism: AuthorityMechanismSchema,
|
|
817
|
+
locality: AuthorityLocalitySchema,
|
|
818
|
+
mutability: AuthorityMutabilitySchema,
|
|
797
819
|
derivedFromUnitId: z.string().uuid(),
|
|
798
820
|
derivedFromUnitName: z.string().min(1).optional(),
|
|
799
821
|
derivedFromUserId: z.string().uuid().nullable().optional(),
|
|
822
|
+
/**
|
|
823
|
+
* Human-readable reason this authority applies, built at serialize time from
|
|
824
|
+
* the strategy's derivation metadata. Foundation for trust UI, debugging,
|
|
825
|
+
* AI explainability, governance reports, and audits.
|
|
826
|
+
*/
|
|
827
|
+
explanation: z.string(),
|
|
828
|
+
/**
|
|
829
|
+
* Strategy-specific structured metadata, preserved verbatim for tooling that
|
|
830
|
+
* needs more than the explanation string (drift detection, audits).
|
|
831
|
+
*/
|
|
800
832
|
derivationMetadata: z.record(z.string(), z.unknown()).optional(),
|
|
833
|
+
/**
|
|
834
|
+
* `org_unit_delegations.id` when `mechanism === 'delegated'`. Surfaced
|
|
835
|
+
* separately so the UI doesn't need to inspect derivationMetadata to render
|
|
836
|
+
* the revoke action.
|
|
837
|
+
*/
|
|
838
|
+
delegationId: z.string().uuid().optional(),
|
|
839
|
+
});
|
|
840
|
+
export type OwnerAuthority = z.infer<typeof OwnerAuthoritySchema>;
|
|
841
|
+
|
|
842
|
+
export const OrgUnitOwnerSchema = z.object({
|
|
843
|
+
userId: z.string().uuid(),
|
|
844
|
+
fullName: z.string().min(1),
|
|
845
|
+
jobTitle: z.string().nullable(),
|
|
846
|
+
slackAvatarUrl: z.string().nullable(),
|
|
847
|
+
/** All authority grants this user holds for the unit. At least one entry. */
|
|
848
|
+
authorities: z.array(OwnerAuthoritySchema).min(1),
|
|
801
849
|
});
|
|
802
|
-
export type
|
|
850
|
+
export type OrgUnitOwner = z.infer<typeof OrgUnitOwnerSchema>;
|
|
851
|
+
|
|
852
|
+
/**
|
|
853
|
+
* Contract-level invariant: each owner list contains each userId at most once.
|
|
854
|
+
* Duplicate userIds are a serializer bug, not a presentation concern, so we
|
|
855
|
+
* fail Zod parse at the API boundary on both server and client.
|
|
856
|
+
*/
|
|
857
|
+
const uniqueByUserId = (arr: ReadonlyArray<{ userId: string }>): boolean =>
|
|
858
|
+
new Set(arr.map((o) => o.userId)).size === arr.length;
|
|
803
859
|
|
|
804
860
|
export const OrgUnitOwnersResponseSchema = z.object({
|
|
805
|
-
owners: z
|
|
806
|
-
|
|
861
|
+
owners: z
|
|
862
|
+
.array(OrgUnitOwnerSchema)
|
|
863
|
+
.refine(uniqueByUserId, { message: 'duplicate userId in owners' }),
|
|
864
|
+
inherited: z
|
|
865
|
+
.array(OrgUnitOwnerSchema)
|
|
866
|
+
.refine(uniqueByUserId, { message: 'duplicate userId in inherited' })
|
|
867
|
+
.optional(),
|
|
807
868
|
});
|
|
808
869
|
export type OrgUnitOwnersResponse = z.infer<typeof OrgUnitOwnersResponseSchema>;
|
|
809
870
|
|