@company-semantics/contracts 1.18.0 → 1.19.1

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": "1.18.0",
3
+ "version": "1.19.1",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -112,7 +112,7 @@
112
112
  "node": "22.x"
113
113
  },
114
114
  "dependencies": {
115
- "zod": "^4.4.1"
115
+ "zod": "^4.4.3"
116
116
  },
117
117
  "devDependencies": {
118
118
  "@types/node": "^25.6.0",
@@ -123,7 +123,7 @@
123
123
  "tsx": "^4.21.0",
124
124
  "typescript": "^5",
125
125
  "vitest": "^4.1.5",
126
- "yaml": "^2.8.3"
126
+ "yaml": "^2.8.4"
127
127
  },
128
128
  "pnpm": {
129
129
  "overrides": {
@@ -1,3 +1,3 @@
1
1
  // AUTO-GENERATED — do not edit. Run pnpm generate:spec-hash to regenerate.
2
- export const SPEC_HASH = '6edfe6e7117c' as const;
3
- export const SPEC_HASH_FULL = '6edfe6e7117c49e81cd7cad51ac9cd5c6f4c9e18cf7a37ff82a5630855404a00' as const;
2
+ export const SPEC_HASH = '31649ac66bff' as const;
3
+ export const SPEC_HASH_FULL = '31649ac66bff5a6c278ce4139c06aa4df50333ef325c11e916698f9b578d68e8' as const;
@@ -2394,6 +2394,7 @@ export interface components {
2394
2394
  roleNames: string[];
2395
2395
  joinedAt: string;
2396
2396
  lastActiveAt: string | null;
2397
+ primaryUnitId: string | null;
2397
2398
  unitMemberships: {
2398
2399
  unitId: string;
2399
2400
  unitName: string;
@@ -2581,6 +2582,7 @@ export interface components {
2581
2582
  roleNames: string[];
2582
2583
  joinedAt: string;
2583
2584
  lastActiveAt: string | null;
2585
+ primaryUnitId: string | null;
2584
2586
  unitMemberships: {
2585
2587
  unitId: string;
2586
2588
  unitName: string;
@@ -3085,6 +3087,10 @@ export interface components {
3085
3087
  depth: number;
3086
3088
  hasChildren: boolean;
3087
3089
  memberCount: number;
3090
+ missingAtNextLevel: {
3091
+ count: number;
3092
+ userIds: string[];
3093
+ } | null;
3088
3094
  }[];
3089
3095
  };
3090
3096
  OrgUnitDescendantsResponse: {
@@ -3228,6 +3234,10 @@ export interface components {
3228
3234
  depth: number;
3229
3235
  hasChildren: boolean;
3230
3236
  memberCount: number;
3237
+ missingAtNextLevel: {
3238
+ count: number;
3239
+ userIds: string[];
3240
+ } | null;
3231
3241
  }[];
3232
3242
  levelConfig: {
3233
3243
  /** Format: uuid */
@@ -78,7 +78,13 @@ describe('OrgUnitSchema', () => {
78
78
 
79
79
  describe('OrgUnitTreeNodeSchema', () => {
80
80
  it('requires depth 1..5', () => {
81
- const base = { ...makeUnit(), depth: 3, hasChildren: true, memberCount: 5 };
81
+ const base = {
82
+ ...makeUnit(),
83
+ depth: 3,
84
+ hasChildren: true,
85
+ memberCount: 5,
86
+ missingAtNextLevel: null,
87
+ };
82
88
  expect(() => OrgUnitTreeNodeSchema.parse(base)).not.toThrow();
83
89
  expect(() => OrgUnitTreeNodeSchema.parse({ ...base, depth: 0 })).toThrow();
84
90
  expect(() => OrgUnitTreeNodeSchema.parse({ ...base, depth: 6 })).toThrow();
@@ -154,7 +160,10 @@ describe('OrgLevelConfigSchema', () => {
154
160
  describe('Response schemas', () => {
155
161
  it('OrgUnitTreeResponseSchema accepts empty tree', () => {
156
162
  expect(() =>
157
- OrgUnitTreeResponseSchema.parse({ nodes: [], levelConfig: [] })
163
+ OrgUnitTreeResponseSchema.parse({
164
+ nodes: [],
165
+ levelConfig: [],
166
+ })
158
167
  ).not.toThrow();
159
168
  });
160
169
 
package/src/org/index.ts CHANGED
@@ -234,6 +234,7 @@ export {
234
234
  OrgLevelIconSchema,
235
235
  OrgUnitResponseSchema,
236
236
  OrgUnitTreeResponseSchema,
237
+ MissingAtNextLevelSchema,
237
238
  OrgUnitChildrenResponseSchema,
238
239
  OrgUnitAncestorsResponseSchema,
239
240
  OrgUnitDescendantsResponseSchema,
@@ -255,6 +256,7 @@ export type {
255
256
  OrgLevelIcon,
256
257
  OrgUnitResponse,
257
258
  OrgUnitTreeResponse,
259
+ MissingAtNextLevel,
258
260
  OrgUnitChildrenResponse,
259
261
  OrgUnitAncestorsResponse,
260
262
  OrgUnitDescendantsResponse,
@@ -32,6 +32,7 @@ const WorkspaceMemberSchema = z.object({
32
32
  roleNames: z.array(z.string()),
33
33
  joinedAt: z.string(),
34
34
  lastActiveAt: z.string().nullable(),
35
+ primaryUnitId: z.string().uuid().nullable(),
35
36
  unitMemberships: z.array(WorkspaceMemberUnitSummarySchema),
36
37
  unitMembershipsTruncated: z.boolean(),
37
38
  inviteStatus: z.enum(['active', 'pending', 'expired']).nullable(),
@@ -712,10 +713,23 @@ export const OrgUnitSchema = z.object({
712
713
  updatedAt: z.string(),
713
714
  });
714
715
 
716
+ /**
717
+ * Active users home directly at this unit who have no level-(depth+1) home
718
+ * assignment within its subtree. The settings UI surfaces this as a
719
+ * synthetic "[child level label] assignment missing" row above the
720
+ * children list at every level. `null` for leaf-level units (no children
721
+ * configured below them) where the concept is meaningless.
722
+ */
723
+ export const MissingAtNextLevelSchema = z.object({
724
+ count: z.number().int().min(0),
725
+ userIds: z.array(z.string().uuid()),
726
+ });
727
+
715
728
  export const OrgUnitTreeNodeSchema = OrgUnitSchema.extend({
716
729
  depth: z.number().int().min(1).max(5),
717
730
  hasChildren: z.boolean(),
718
731
  memberCount: z.number().int().min(0),
732
+ missingAtNextLevel: MissingAtNextLevelSchema.nullable(),
719
733
  });
720
734
 
721
735
  export const OrgUnitMembershipSchema = z.object({
@@ -852,6 +866,7 @@ export type OrgLevelConfig = z.infer<typeof OrgLevelConfigSchema>;
852
866
  export type OrgLevelIcon = z.infer<typeof OrgLevelIconSchema>;
853
867
  export type OrgUnitResponse = z.infer<typeof OrgUnitResponseSchema>;
854
868
  export type OrgUnitTreeResponse = z.infer<typeof OrgUnitTreeResponseSchema>;
869
+ export type MissingAtNextLevel = z.infer<typeof MissingAtNextLevelSchema>;
855
870
  export type OrgUnitChildrenResponse = z.infer<typeof OrgUnitChildrenResponseSchema>;
856
871
  export type OrgUnitAncestorsResponse = z.infer<typeof OrgUnitAncestorsResponseSchema>;
857
872
  export type OrgUnitDescendantsResponse = z.infer<typeof OrgUnitDescendantsResponseSchema>;
package/src/org/types.ts CHANGED
@@ -125,6 +125,12 @@ export interface WorkspaceMember {
125
125
  joinedAt: string;
126
126
  /** ISO timestamp of last activity; null if never recorded. */
127
127
  lastActiveAt: string | null;
128
+ /**
129
+ * Home org-unit (`users.primary_unit_id`). Null for org-scoped users
130
+ * (no level-2 home assignment). Used by the unit-detail Members table to
131
+ * roll up "people in this org-unit" across the subtree.
132
+ */
133
+ primaryUnitId: string | null;
128
134
  /** OrgUnit memberships for this member, capped at a small number server-side. */
129
135
  unitMemberships: WorkspaceMemberUnitSummary[];
130
136
  /** True when server truncated `unitMemberships`; detail endpoint returns the full list. */