@company-semantics/contracts 7.0.0 → 7.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": "7.0.0",
3
+ "version": "7.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 = 'e20bec799e8f' as const;
3
- export const SPEC_HASH_FULL = 'e20bec799e8f8bd1a51fccbafa626fad0f4e001789ff8b13cda65847c32972f2' as const;
2
+ export const SPEC_HASH = '937aecbfe6e6' as const;
3
+ export const SPEC_HASH_FULL = '937aecbfe6e6533edabb1b83d66be83f63100e519ecf9e4531af3e8a627e122a' as const;
@@ -1972,6 +1972,30 @@ export interface paths {
1972
1972
  patch?: never;
1973
1973
  trace?: never;
1974
1974
  };
1975
+ "/api/users/{userId}/avatar": {
1976
+ parameters: {
1977
+ query?: never;
1978
+ header?: never;
1979
+ path?: never;
1980
+ cookie?: never;
1981
+ };
1982
+ get?: never;
1983
+ /**
1984
+ * Upload (replace) a user's avatar photo from an image file
1985
+ * @description Accepts a multipart image upload (PNG/JPEG/WebP/HEIC) up to 5 MB. The caller must be the target user or hold org.manage_users. HEIC/HEIF is converted to JPEG and the bytes are re-hosted via the blob store. Returns the resolved avatar.
1986
+ */
1987
+ put: operations["uploadUserAvatar"];
1988
+ post?: never;
1989
+ /**
1990
+ * Clear a user's uploaded avatar (reverts to Slack photo or initials)
1991
+ * @description Clears an in-app uploaded avatar only (source=upload); Slack-sourced avatars are left intact. The caller must be the target user or hold org.manage_users. Returns the resolved avatar after reverting.
1992
+ */
1993
+ delete: operations["deleteUserAvatar"];
1994
+ options?: never;
1995
+ head?: never;
1996
+ patch?: never;
1997
+ trace?: never;
1998
+ };
1975
1999
  "/api/drive/files": {
1976
2000
  parameters: {
1977
2001
  query?: never;
@@ -2782,7 +2806,7 @@ export interface components {
2782
2806
  slackUserId: string | null;
2783
2807
  avatar: {
2784
2808
  /** @enum {string} */
2785
- source: "slack" | "initials";
2809
+ source: "photo" | "initials";
2786
2810
  url?: string;
2787
2811
  initials: string;
2788
2812
  };
@@ -4067,7 +4091,7 @@ export interface components {
4067
4091
  userId: string;
4068
4092
  fullName: string;
4069
4093
  jobTitle: string | null;
4070
- slackAvatarUrl: string | null;
4094
+ avatarUrl: string | null;
4071
4095
  authorities: {
4072
4096
  /** @enum {string} */
4073
4097
  mechanism: "structural" | "delegated" | "rbac";
@@ -4094,7 +4118,7 @@ export interface components {
4094
4118
  userId: string;
4095
4119
  fullName: string;
4096
4120
  jobTitle: string | null;
4097
- slackAvatarUrl: string | null;
4121
+ avatarUrl: string | null;
4098
4122
  authorities: {
4099
4123
  /** @enum {string} */
4100
4124
  mechanism: "structural" | "delegated" | "rbac";
@@ -4228,7 +4252,7 @@ export interface components {
4228
4252
  id: string;
4229
4253
  fullName: string;
4230
4254
  jobTitle: string | null;
4231
- slackAvatarUrl: string | null;
4255
+ avatarUrl: string | null;
4232
4256
  primaryUnitId: string | null;
4233
4257
  }[];
4234
4258
  edges: {
@@ -7923,6 +7947,101 @@ export interface operations {
7923
7947
  };
7924
7948
  };
7925
7949
  };
7950
+ uploadUserAvatar: {
7951
+ parameters: {
7952
+ query?: never;
7953
+ header?: never;
7954
+ path: {
7955
+ userId: string;
7956
+ };
7957
+ cookie?: never;
7958
+ };
7959
+ requestBody: {
7960
+ content: {
7961
+ "multipart/form-data": {
7962
+ [key: string]: unknown;
7963
+ };
7964
+ };
7965
+ };
7966
+ responses: {
7967
+ /** @description Avatar uploaded; resolved avatar returned */
7968
+ 200: {
7969
+ headers: {
7970
+ [name: string]: unknown;
7971
+ };
7972
+ content?: never;
7973
+ };
7974
+ /** @description Missing or malformed multipart upload */
7975
+ 400: {
7976
+ headers: {
7977
+ [name: string]: unknown;
7978
+ };
7979
+ content?: never;
7980
+ };
7981
+ /** @description Caller may not change this avatar */
7982
+ 403: {
7983
+ headers: {
7984
+ [name: string]: unknown;
7985
+ };
7986
+ content?: never;
7987
+ };
7988
+ /** @description Target user is not a member of the caller org */
7989
+ 404: {
7990
+ headers: {
7991
+ [name: string]: unknown;
7992
+ };
7993
+ content?: never;
7994
+ };
7995
+ /** @description Upload exceeds the 5 MB size limit */
7996
+ 413: {
7997
+ headers: {
7998
+ [name: string]: unknown;
7999
+ };
8000
+ content?: never;
8001
+ };
8002
+ /** @description Unsupported image type or bytes are not a valid image */
8003
+ 415: {
8004
+ headers: {
8005
+ [name: string]: unknown;
8006
+ };
8007
+ content?: never;
8008
+ };
8009
+ };
8010
+ };
8011
+ deleteUserAvatar: {
8012
+ parameters: {
8013
+ query?: never;
8014
+ header?: never;
8015
+ path: {
8016
+ userId: string;
8017
+ };
8018
+ cookie?: never;
8019
+ };
8020
+ requestBody?: never;
8021
+ responses: {
8022
+ /** @description Uploaded avatar cleared; resolved avatar returned */
8023
+ 200: {
8024
+ headers: {
8025
+ [name: string]: unknown;
8026
+ };
8027
+ content?: never;
8028
+ };
8029
+ /** @description Caller may not change this avatar */
8030
+ 403: {
8031
+ headers: {
8032
+ [name: string]: unknown;
8033
+ };
8034
+ content?: never;
8035
+ };
8036
+ /** @description Target user is not a member of the caller org */
8037
+ 404: {
8038
+ headers: {
8039
+ [name: string]: unknown;
8040
+ };
8041
+ content?: never;
8042
+ };
8043
+ };
8044
+ };
7926
8045
  listDriveFiles: {
7927
8046
  parameters: {
7928
8047
  query?: never;
@@ -117,6 +117,7 @@ export const openApiRoutes = {
117
117
  '/api/users/org-chart': ['GET'],
118
118
  '/api/users/org-chart/import': ['POST'],
119
119
  '/api/users/org-chart/import/{operationId}/retry': ['POST'],
120
+ '/api/users/{userId}/avatar': ['DELETE', 'PUT'],
120
121
  '/api/work-items/{id}': ['GET'],
121
122
  '/api/work-items/{id}/content': ['PUT'],
122
123
  '/api/work-items/{id}/title': ['PUT'],
package/src/org/index.ts CHANGED
@@ -125,6 +125,8 @@ export {
125
125
  WorkspaceOverviewSchema,
126
126
  WorkspaceMembersResponseSchema,
127
127
  WorkspaceMemberDetailSchema,
128
+ WorkspaceMemberManagesEntrySchema,
129
+ OrgUnitDesignationSchema,
128
130
  RoleCatalogEntrySchema,
129
131
  RoleCatalogResponseSchema,
130
132
  WorkspaceAuthConfigSchema,
@@ -148,6 +150,8 @@ export type {
148
150
  WorkspaceAccessResponse,
149
151
  WorkspaceOverview as WorkspaceOverviewDto,
150
152
  WorkspaceMembersResponse,
153
+ WorkspaceMemberManagesEntry,
154
+ OrgUnitDesignation,
151
155
  WorkspaceAuthConfig as WorkspaceAuthConfigDto,
152
156
  WorkspaceAuditEvent as WorkspaceAuditEventDto,
153
157
  WorkspaceResolvePathResponse,
@@ -25,6 +25,31 @@ const WorkspaceMemberUnitSummarySchema = z.object({
25
25
  role: z.enum(['owner', 'manager', 'member']),
26
26
  });
27
27
 
28
+ /**
29
+ * Designation a member holds over a unit they manage (ADR-CTRL-112).
30
+ *
31
+ * Precedence, highest-first: whole_org > admin > leader > delegate > member.
32
+ * The org-wide designations (`whole_org`, `admin`) anchor to the org root
33
+ * unit. This vocabulary is DISPLAY-ONLY — it summarizes management reach for
34
+ * UI surfaces and is NEVER an authorization input (authority resolution uses
35
+ * the orthogonal membership/delegation axes, not this enum).
36
+ */
37
+ export const OrgUnitDesignationSchema = z.enum([
38
+ 'whole_org',
39
+ 'admin',
40
+ 'leader',
41
+ 'delegate',
42
+ 'member',
43
+ ]);
44
+ export type OrgUnitDesignation = z.infer<typeof OrgUnitDesignationSchema>;
45
+
46
+ export const WorkspaceMemberManagesEntrySchema = z.object({
47
+ unitId: z.string(),
48
+ unitName: z.string(),
49
+ designation: OrgUnitDesignationSchema,
50
+ });
51
+ export type WorkspaceMemberManagesEntry = z.infer<typeof WorkspaceMemberManagesEntrySchema>;
52
+
28
53
  const WorkspaceMemberSchema = z.object({
29
54
  id: z.string(),
30
55
  name: z.string(),
@@ -36,6 +61,7 @@ const WorkspaceMemberSchema = z.object({
36
61
  lastActiveAt: z.string().nullable(),
37
62
  primaryUnitId: z.string().uuid().nullable(),
38
63
  unitMemberships: z.array(WorkspaceMemberUnitSummarySchema),
64
+ manages: z.array(WorkspaceMemberManagesEntrySchema),
39
65
  unitMembershipsTruncated: z.boolean(),
40
66
  inviteStatus: z.enum(['active', 'pending', 'expired']).nullable(),
41
67
  });