@company-semantics/contracts 0.122.0 → 0.124.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.
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Content Domain Barrel
3
+ *
4
+ * Re-exports content response schemas for company-md, teams, departments, and drive.
5
+ * Import from '@company-semantics/contracts/content'.
6
+ */
7
+
8
+ // Company.md response schemas (PRD-00448)
9
+ export {
10
+ CompanyMdListResponseSchema,
11
+ CompanyMdDocResponseSchema,
12
+ CompanyMdShareResponseSchema,
13
+ CompanyMdContextBankResponseSchema,
14
+ CompanyMdSettingsResponseSchema,
15
+ } from './schemas';
16
+ export type {
17
+ CompanyMdListResponse,
18
+ CompanyMdDocResponse,
19
+ CompanyMdShareResponse,
20
+ CompanyMdContextBankResponse,
21
+ CompanyMdSettingsResponse,
22
+ } from './schemas';
23
+
24
+ // Team response schemas (PRD-00448)
25
+ export { TeamListResponseSchema, TeamResponseSchema } from './schemas';
26
+ export type { TeamListResponse, TeamResponse } from './schemas';
27
+
28
+ // Department response schemas (PRD-00448)
29
+ export { DepartmentListResponseSchema, DepartmentResponseSchema } from './schemas';
30
+ export type { DepartmentListResponse, DepartmentResponse } from './schemas';
31
+
32
+ // Drive response schemas (PRD-00448)
33
+ export { DriveFileListResponseSchema, DriveFileContentResponseSchema } from './schemas';
34
+ export type { DriveFileListResponse, DriveFileContentResponse } from './schemas';
@@ -0,0 +1,286 @@
1
+ /**
2
+ * Content Domain Response Schemas
3
+ *
4
+ * Zod response schemas for content and org structure endpoints.
5
+ * Canonical location for runtime validation of company-md, team,
6
+ * department, and drive API responses.
7
+ *
8
+ * Covers:
9
+ * - company-md.ts (GET /api/company-md/tree, GET /api/company-md/docs/:slug, etc.)
10
+ * - company-md-sharing.ts (GET /api/company-md/docs/:slug/sharing)
11
+ * - teams.ts (GET /api/teams, GET /api/teams/:teamId, etc.)
12
+ * - departments.ts (GET /api/departments, GET /api/departments/:id, etc.)
13
+ * - drive.ts (GET /api/drive/files, GET /api/drive/files/recent, etc.)
14
+ */
15
+ import { z } from 'zod';
16
+ import { CursorPageSchema } from '../api/primitives';
17
+
18
+ // ---------------------------------------------------------------------------
19
+ // Company.md Sub-schemas
20
+ // ---------------------------------------------------------------------------
21
+
22
+ const CompanyMdOwningTeamSchema = z.object({
23
+ id: z.string(),
24
+ name: z.string(),
25
+ });
26
+
27
+ const CompanyMdPersonSchema = z.object({
28
+ id: z.string(),
29
+ name: z.string(),
30
+ });
31
+
32
+ const CompanyMdSourceSchema = z.object({
33
+ label: z.string(),
34
+ sourceType: z.enum(['meeting', 'document', 'conversation', 'manual']),
35
+ referencedAt: z.string(),
36
+ });
37
+
38
+ const CompanyMdDependencySchema = z.object({
39
+ targetSlug: z.string(),
40
+ description: z.string(),
41
+ });
42
+
43
+ const CompanyMdTreeNodeSchema = z.object({
44
+ id: z.string(),
45
+ slug: z.string(),
46
+ title: z.string(),
47
+ level: z.enum(['root', 'department', 'team', 'context']),
48
+ parentId: z.string().nullable(),
49
+ department: z.string().nullable(),
50
+ departmentId: z.string().nullable(),
51
+ visibility: z.enum(['public', 'private']),
52
+ owningTeam: CompanyMdOwningTeamSchema.nullable(),
53
+ type: z.enum(['company', 'department', 'team', 'cross_team', 'doc', 'goal', 'source', 'map', 'context_bank']),
54
+ canEdit: z.boolean(),
55
+ memberCount: z.number().int(),
56
+ description: z.string().optional(),
57
+ departmentIds: z.array(z.string()).optional(),
58
+ });
59
+
60
+ // ---------------------------------------------------------------------------
61
+ // Company.md HTTP Response Schemas
62
+ // ---------------------------------------------------------------------------
63
+
64
+ /** Response for GET /api/company-md/tree */
65
+ export const CompanyMdListResponseSchema = CursorPageSchema(CompanyMdTreeNodeSchema);
66
+
67
+ /** Response for GET /api/company-md/docs/:slug */
68
+ export const CompanyMdDocResponseSchema = z.object({
69
+ id: z.string(),
70
+ slug: z.string(),
71
+ title: z.string(),
72
+ level: z.enum(['root', 'department', 'team', 'context']),
73
+ department: z.string().nullable(),
74
+ departmentId: z.string().nullable(),
75
+ content: z.string(),
76
+ visibility: z.enum(['public', 'private']),
77
+ parentId: z.string().nullable(),
78
+ owningTeam: CompanyMdOwningTeamSchema.nullable(),
79
+ owner: CompanyMdPersonSchema.nullable(),
80
+ coOwners: z.array(CompanyMdPersonSchema),
81
+ canEdit: z.boolean(),
82
+ inheritsFrom: z.string().nullable(),
83
+ sources: z.array(CompanyMdSourceSchema),
84
+ dependencies: z.array(CompanyMdDependencySchema),
85
+ members: z.array(CompanyMdPersonSchema),
86
+ extractionStatus: z.enum(['pending', 'extracting', 'complete', 'failed']),
87
+ createdAt: z.string(),
88
+ updatedAt: z.string(),
89
+ });
90
+
91
+ // ---------------------------------------------------------------------------
92
+ // Company.md Sharing Sub-schemas
93
+ // ---------------------------------------------------------------------------
94
+
95
+ const AclEntrySchema = z.object({
96
+ principalType: z.enum(['user', 'team']),
97
+ principalId: z.string(),
98
+ principalName: z.string(),
99
+ accessLevel: z.enum(['viewer', 'commenter', 'editor']),
100
+ grantedBy: z.object({ id: z.string(), name: z.string() }).nullable(),
101
+ grantedAt: z.string(),
102
+ });
103
+
104
+ const AccessReasonSchema = z.object({
105
+ source: z.enum(['org_rbac', 'sharing_policy', 'team_baseline', 'acl_grant', 'doc_ownership']),
106
+ detail: z.string(),
107
+ });
108
+
109
+ const EffectiveAccessSchema = z.object({
110
+ level: z.enum(['none', 'viewer', 'commenter', 'editor']),
111
+ reasons: z.array(AccessReasonSchema),
112
+ canShare: z.boolean(),
113
+ });
114
+
115
+ /** Response for GET /api/company-md/docs/:slug/sharing */
116
+ export const CompanyMdShareResponseSchema = z.object({
117
+ sharingPolicy: z.enum(['restricted', 'org_read', 'org_comment', 'org_edit']),
118
+ acl: z.array(AclEntrySchema),
119
+ effectiveAccess: EffectiveAccessSchema,
120
+ });
121
+
122
+ // ---------------------------------------------------------------------------
123
+ // Company.md Context Bank + Settings Response Schemas
124
+ // ---------------------------------------------------------------------------
125
+
126
+ const CompanyMdContextBankItemSchema = z.object({
127
+ id: z.string(),
128
+ slug: z.string(),
129
+ title: z.string(),
130
+ visibility: z.enum(['public', 'private']),
131
+ updatedAt: z.string(),
132
+ });
133
+
134
+ /** Response for GET /api/company-md/docs/:slug/context-bank */
135
+ export const CompanyMdContextBankResponseSchema = z.object({
136
+ items: z.array(CompanyMdContextBankItemSchema),
137
+ });
138
+
139
+ const CompanyMdLevelLabelsSchema = z.object({
140
+ root: z.string(),
141
+ department: z.string(),
142
+ team: z.string(),
143
+ });
144
+
145
+ /** Response for GET /api/company-md/settings */
146
+ export const CompanyMdSettingsResponseSchema = z.object({
147
+ levelLabels: CompanyMdLevelLabelsSchema,
148
+ });
149
+
150
+ // ---------------------------------------------------------------------------
151
+ // Team Sub-schemas
152
+ // ---------------------------------------------------------------------------
153
+
154
+ const TeamMemberSchema = z.object({
155
+ userId: z.string(),
156
+ name: z.string(),
157
+ email: z.string(),
158
+ role: z.enum(['member', 'manager', 'owner']),
159
+ joinedAt: z.string(),
160
+ });
161
+
162
+ const TeamSummarySchema = z.object({
163
+ id: z.string(),
164
+ name: z.string(),
165
+ slug: z.string(),
166
+ description: z.string().nullable(),
167
+ memberCount: z.number().int(),
168
+ scope: z.enum(['department', 'cross_department', 'org']),
169
+ department: z.object({ id: z.string(), name: z.string(), slug: z.string() }).nullable(),
170
+ homeDepartment: z.object({ id: z.string(), name: z.string(), slug: z.string() }).nullable(),
171
+ });
172
+
173
+ // ---------------------------------------------------------------------------
174
+ // Team HTTP Response Schemas
175
+ // ---------------------------------------------------------------------------
176
+
177
+ /** Response for GET /api/teams */
178
+ export const TeamListResponseSchema = z.object({
179
+ teams: z.array(TeamSummarySchema),
180
+ });
181
+
182
+ /** Response for GET /api/teams/:teamId */
183
+ export const TeamResponseSchema = z.object({
184
+ id: z.string(),
185
+ name: z.string(),
186
+ slug: z.string(),
187
+ description: z.string().nullable(),
188
+ syncMode: z.enum(['manual_only', 'synced_readonly', 'synced_with_overrides']),
189
+ members: z.array(TeamMemberSchema),
190
+ });
191
+
192
+ // ---------------------------------------------------------------------------
193
+ // Department Sub-schemas
194
+ // ---------------------------------------------------------------------------
195
+
196
+ const DepartmentMemberSchema = z.object({
197
+ userId: z.string(),
198
+ name: z.string(),
199
+ email: z.string(),
200
+ role: z.enum(['member', 'manager', 'owner']),
201
+ joinedAt: z.string(),
202
+ });
203
+
204
+ const DepartmentSummarySchema = z.object({
205
+ id: z.string(),
206
+ name: z.string(),
207
+ slug: z.string(),
208
+ description: z.string().nullable(),
209
+ memberCount: z.number().int(),
210
+ position: z.number().int(),
211
+ });
212
+
213
+ // ---------------------------------------------------------------------------
214
+ // Department HTTP Response Schemas
215
+ // ---------------------------------------------------------------------------
216
+
217
+ /** Response for GET /api/departments */
218
+ export const DepartmentListResponseSchema = z.object({
219
+ departments: z.array(DepartmentSummarySchema),
220
+ });
221
+
222
+ /** Response for GET /api/departments/:id */
223
+ export const DepartmentResponseSchema = z.object({
224
+ id: z.string(),
225
+ name: z.string(),
226
+ slug: z.string(),
227
+ description: z.string().nullable(),
228
+ position: z.number().int(),
229
+ syncMode: z.enum(['manual_only', 'scim', 'hris']),
230
+ memberCount: z.number().int(),
231
+ members: z.array(DepartmentMemberSchema),
232
+ });
233
+
234
+ // ---------------------------------------------------------------------------
235
+ // Drive Sub-schemas
236
+ // ---------------------------------------------------------------------------
237
+
238
+ const DriveFileOwnerSchema = z.object({
239
+ displayName: z.string().optional(),
240
+ emailAddress: z.string().optional(),
241
+ });
242
+
243
+ const DriveFileSchema = z.object({
244
+ id: z.string(),
245
+ name: z.string(),
246
+ mimeType: z.string(),
247
+ createdTime: z.string().optional(),
248
+ modifiedTime: z.string().optional(),
249
+ owners: z.array(DriveFileOwnerSchema).optional(),
250
+ webViewLink: z.string().optional(),
251
+ iconLink: z.string().optional(),
252
+ size: z.string().optional(),
253
+ });
254
+
255
+ // ---------------------------------------------------------------------------
256
+ // Drive HTTP Response Schemas
257
+ // ---------------------------------------------------------------------------
258
+
259
+ /** Response for GET /api/drive/files and GET /api/drive/files/recent */
260
+ export const DriveFileListResponseSchema = z.object({
261
+ files: z.array(DriveFileSchema),
262
+ nextPageToken: z.string().optional(),
263
+ });
264
+
265
+ /** Response for GET /api/drive/files/:fileId/content */
266
+ export const DriveFileContentResponseSchema = z.object({
267
+ content: z.string(),
268
+ exportedAs: z.string(),
269
+ truncated: z.boolean(),
270
+ });
271
+
272
+ // ---------------------------------------------------------------------------
273
+ // Inferred Types
274
+ // ---------------------------------------------------------------------------
275
+
276
+ export type CompanyMdListResponse = z.infer<typeof CompanyMdListResponseSchema>;
277
+ export type CompanyMdDocResponse = z.infer<typeof CompanyMdDocResponseSchema>;
278
+ export type CompanyMdShareResponse = z.infer<typeof CompanyMdShareResponseSchema>;
279
+ export type CompanyMdContextBankResponse = z.infer<typeof CompanyMdContextBankResponseSchema>;
280
+ export type CompanyMdSettingsResponse = z.infer<typeof CompanyMdSettingsResponseSchema>;
281
+ export type TeamListResponse = z.infer<typeof TeamListResponseSchema>;
282
+ export type TeamResponse = z.infer<typeof TeamResponseSchema>;
283
+ export type DepartmentListResponse = z.infer<typeof DepartmentListResponseSchema>;
284
+ export type DepartmentResponse = z.infer<typeof DepartmentResponseSchema>;
285
+ export type DriveFileListResponse = z.infer<typeof DriveFileListResponseSchema>;
286
+ export type DriveFileContentResponse = z.infer<typeof DriveFileContentResponseSchema>;
@@ -30,5 +30,29 @@ export type { AvatarSource, ResolvedAvatar } from './avatar';
30
30
  export { generateInitials, resolveAvatar } from './avatar';
31
31
 
32
32
  // Response Schemas (Zod) - canonical location per ADR-CONT-044
33
- export { MeResponseSchema, AuthStartResponseSchema, AuthVerifyResponseSchema, SsoConfigResponseSchema, ProfileResponseSchema } from './schemas';
34
- export type { MeResponse, AuthStartResponse, AuthVerifyResponse, SsoConfigResponse, ProfileResponse } from './schemas';
33
+ export {
34
+ MeResponseSchema,
35
+ AuthStartResponseSchema,
36
+ AuthVerifyResponseSchema,
37
+ SsoConfigResponseSchema,
38
+ ProfileResponseSchema,
39
+ AccountSessionListSchema,
40
+ AccountSessionRevokeResponseSchema,
41
+ AccountDeletionEligibilityResponseSchema,
42
+ AccountDeleteResponseSchema,
43
+ AccountConfirmDeletionResponseSchema,
44
+ AccountCancelDeletionResponseSchema,
45
+ } from './schemas';
46
+ export type {
47
+ MeResponse,
48
+ AuthStartResponse,
49
+ AuthVerifyResponse,
50
+ SsoConfigResponse,
51
+ ProfileResponse,
52
+ AccountSessionList,
53
+ AccountSessionRevokeResponse,
54
+ AccountDeletionEligibilityResponse,
55
+ AccountDeleteResponse,
56
+ AccountConfirmDeletionResponse,
57
+ AccountCancelDeletionResponse,
58
+ } from './schemas';
@@ -137,3 +137,88 @@ export const ProfileResponseSchema = z.object({
137
137
  });
138
138
 
139
139
  export type ProfileResponse = z.infer<typeof ProfileResponseSchema>;
140
+
141
+ // ---------------------------------------------------------------------------
142
+ // GET /api/account/sessions
143
+ // ---------------------------------------------------------------------------
144
+
145
+ const AccountSessionSchema = z.object({
146
+ id: z.string(),
147
+ deviceLabel: z.string(),
148
+ ipAddress: z.string().nullable(),
149
+ createdAt: z.string(),
150
+ lastActiveAt: z.string().nullable(),
151
+ isCurrent: z.boolean(),
152
+ });
153
+
154
+ export const AccountSessionListSchema = z.object({
155
+ sessions: z.array(AccountSessionSchema),
156
+ });
157
+
158
+ export type AccountSessionList = z.infer<typeof AccountSessionListSchema>;
159
+
160
+ // ---------------------------------------------------------------------------
161
+ // DELETE /api/account/sessions/:sessionId
162
+ // ---------------------------------------------------------------------------
163
+
164
+ export const AccountSessionRevokeResponseSchema = z.object({
165
+ success: z.literal(true),
166
+ ok: z.literal(true),
167
+ });
168
+
169
+ export type AccountSessionRevokeResponse = z.infer<typeof AccountSessionRevokeResponseSchema>;
170
+
171
+ // ---------------------------------------------------------------------------
172
+ // GET /api/account/deletion-eligibility
173
+ // ---------------------------------------------------------------------------
174
+
175
+ const DeletionBlockerSchema = z.discriminatedUnion('type', [
176
+ z.object({
177
+ type: z.literal('sole_workspace_owner'),
178
+ workspaceId: z.string(),
179
+ workspaceName: z.string(),
180
+ }),
181
+ z.object({
182
+ type: z.literal('active_legal_hold'),
183
+ holdId: z.string(),
184
+ }),
185
+ ]);
186
+
187
+ export const AccountDeletionEligibilityResponseSchema = z.object({
188
+ eligible: z.boolean(),
189
+ blockers: z.array(DeletionBlockerSchema),
190
+ });
191
+
192
+ export type AccountDeletionEligibilityResponse = z.infer<typeof AccountDeletionEligibilityResponseSchema>;
193
+
194
+ // ---------------------------------------------------------------------------
195
+ // POST /api/account/delete
196
+ // ---------------------------------------------------------------------------
197
+
198
+ export const AccountDeleteResponseSchema = z.object({
199
+ status: z.literal('confirmation_pending'),
200
+ message: z.string(),
201
+ });
202
+
203
+ export type AccountDeleteResponse = z.infer<typeof AccountDeleteResponseSchema>;
204
+
205
+ // ---------------------------------------------------------------------------
206
+ // POST /api/account/confirm-deletion
207
+ // ---------------------------------------------------------------------------
208
+
209
+ export const AccountConfirmDeletionResponseSchema = z.object({
210
+ status: z.literal('pending_deletion'),
211
+ });
212
+
213
+ export type AccountConfirmDeletionResponse = z.infer<typeof AccountConfirmDeletionResponseSchema>;
214
+
215
+ // ---------------------------------------------------------------------------
216
+ // POST /api/account/cancel-deletion
217
+ // ---------------------------------------------------------------------------
218
+
219
+ export const AccountCancelDeletionResponseSchema = z.object({
220
+ success: z.literal(true),
221
+ ok: z.literal(true),
222
+ });
223
+
224
+ export type AccountCancelDeletionResponse = z.infer<typeof AccountCancelDeletionResponseSchema>;
package/src/org/index.ts CHANGED
@@ -201,3 +201,17 @@ export type {
201
201
  OwnershipTransferResponse,
202
202
  OwnershipTransferPreview,
203
203
  } from './schemas';
204
+
205
+ // Org-ops response schemas (PRD-00449)
206
+ export {
207
+ OrgSystemEventsListSchema,
208
+ AcknowledgeSystemEventResponseSchema,
209
+ OrgBudgetConfigSchema,
210
+ OrgUsageResponseSchema,
211
+ } from './schemas';
212
+ export type {
213
+ OrgSystemEventsList,
214
+ AcknowledgeSystemEventResponse,
215
+ OrgBudgetConfig,
216
+ OrgUsageResponse,
217
+ } from './schemas';
@@ -502,3 +502,109 @@ export const OwnershipTransferPreviewSchema = z.object({
502
502
  });
503
503
 
504
504
  export type OwnershipTransferPreview = z.infer<typeof OwnershipTransferPreviewSchema>;
505
+
506
+ // ---------------------------------------------------------------------------
507
+ // GET /api/org/system-events
508
+ // ---------------------------------------------------------------------------
509
+
510
+ const OrgSystemEventSchema = z.object({
511
+ id: z.string(),
512
+ type: z.string(),
513
+ payload: z.unknown(),
514
+ createdAt: z.string(),
515
+ });
516
+
517
+ export const OrgSystemEventsListSchema = z.object({
518
+ events: z.array(OrgSystemEventSchema),
519
+ });
520
+
521
+ export type OrgSystemEventsList = z.infer<typeof OrgSystemEventsListSchema>;
522
+
523
+ // ---------------------------------------------------------------------------
524
+ // POST /api/org/system-events/:id/acknowledge
525
+ // ---------------------------------------------------------------------------
526
+
527
+ export const AcknowledgeSystemEventResponseSchema = z.object({
528
+ success: z.literal(true),
529
+ });
530
+
531
+ export type AcknowledgeSystemEventResponse = z.infer<typeof AcknowledgeSystemEventResponseSchema>;
532
+
533
+ // ---------------------------------------------------------------------------
534
+ // GET /api/orgs/:orgId/budget-config
535
+ // PUT /api/orgs/:orgId/budget-config
536
+ // ---------------------------------------------------------------------------
537
+
538
+ export const OrgBudgetConfigSchema = z.object({
539
+ monthlyBudgetUsd: z.number().nullable(),
540
+ maxCostPerExecution: z.number().nullable(),
541
+ agenticMaxSteps: z.number().int().nullable(),
542
+ alertThresholdPct: z.number().int(),
543
+ enabled: z.boolean(),
544
+ });
545
+
546
+ export type OrgBudgetConfig = z.infer<typeof OrgBudgetConfigSchema>;
547
+
548
+ // ---------------------------------------------------------------------------
549
+ // GET /api/orgs/:orgId/ai-usage
550
+ // Matches UnifiedUsageResponse from usage/types.ts
551
+ // ---------------------------------------------------------------------------
552
+
553
+ const UnifiedUsageSummarySchema = z.object({
554
+ executions: z.number(),
555
+ totalCostUsd: z.string(),
556
+ totalTokens: z.number(),
557
+ avgDurationMs: z.number(),
558
+ failureRate: z.number(),
559
+ });
560
+
561
+ const UnifiedDailyUsageSchema = z.object({
562
+ date: z.string(),
563
+ executions: z.number(),
564
+ totalCostUsd: z.string(),
565
+ });
566
+
567
+ const UnifiedProfileUsageSchema = z.object({
568
+ profile: z.string(),
569
+ executions: z.number(),
570
+ percentOfTotal: z.number(),
571
+ totalCostUsd: z.string(),
572
+ avgDurationMs: z.number(),
573
+ failureRate: z.number(),
574
+ });
575
+
576
+ const UnifiedUserUsageSchema = z.object({
577
+ userId: z.string(),
578
+ email: z.string(),
579
+ executions: z.number(),
580
+ totalCostUsd: z.string(),
581
+ totalTokens: z.number(),
582
+ favoriteProfile: z.string(),
583
+ });
584
+
585
+ const UnifiedModelUsageSchema = z.object({
586
+ model: z.string(),
587
+ provider: z.string(),
588
+ totalTokens: z.number(),
589
+ estimatedCostUsd: z.string(),
590
+ requestCount: z.number(),
591
+ });
592
+
593
+ const UnifiedFeatureUsageSchema = z.object({
594
+ feature: z.string(),
595
+ totalTokens: z.number(),
596
+ estimatedCostUsd: z.string(),
597
+ requestCount: z.number(),
598
+ });
599
+
600
+ export const OrgUsageResponseSchema = z.object({
601
+ period: z.object({ start: z.string(), end: z.string() }),
602
+ summary: UnifiedUsageSummarySchema,
603
+ daily: z.array(UnifiedDailyUsageSchema),
604
+ byProfile: z.array(UnifiedProfileUsageSchema),
605
+ byUser: z.array(UnifiedUserUsageSchema),
606
+ byModel: z.array(UnifiedModelUsageSchema),
607
+ byFeature: z.array(UnifiedFeatureUsageSchema),
608
+ });
609
+
610
+ export type OrgUsageResponse = z.infer<typeof OrgUsageResponseSchema>;