@checkstack/auth-common 0.2.0 → 0.4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,70 @@
1
1
  # @checkstack/auth-common
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - df6ac7b: Added onboarding flow and user profile
8
+
9
+ ## 0.3.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 7a23261: ## TanStack Query Integration
14
+
15
+ Migrated all frontend components to use `usePluginClient` hook with TanStack Query integration, replacing the legacy `forPlugin()` pattern.
16
+
17
+ ### New Features
18
+
19
+ - **`usePluginClient` hook**: Provides type-safe access to plugin APIs with `.useQuery()` and `.useMutation()` methods
20
+ - **Automatic request deduplication**: Multiple components requesting the same data share a single network request
21
+ - **Built-in caching**: Configurable stale time and cache duration per query
22
+ - **Loading/error states**: TanStack Query provides `isLoading`, `error`, `isRefetching` states automatically
23
+ - **Background refetching**: Stale data is automatically refreshed when components mount
24
+
25
+ ### Contract Changes
26
+
27
+ All RPC contracts now require `operationType: "query"` or `operationType: "mutation"` metadata:
28
+
29
+ ```typescript
30
+ const getItems = proc()
31
+ .meta({ operationType: "query", access: [access.read] })
32
+ .output(z.array(itemSchema))
33
+ .query();
34
+
35
+ const createItem = proc()
36
+ .meta({ operationType: "mutation", access: [access.manage] })
37
+ .input(createItemSchema)
38
+ .output(itemSchema)
39
+ .mutation();
40
+ ```
41
+
42
+ ### Migration
43
+
44
+ ```typescript
45
+ // Before (forPlugin pattern)
46
+ const api = useApi(myPluginApiRef);
47
+ const [items, setItems] = useState<Item[]>([]);
48
+ useEffect(() => {
49
+ api.getItems().then(setItems);
50
+ }, [api]);
51
+
52
+ // After (usePluginClient pattern)
53
+ const client = usePluginClient(MyPluginApi);
54
+ const { data: items, isLoading } = client.getItems.useQuery({});
55
+ ```
56
+
57
+ ### Bug Fixes
58
+
59
+ - Fixed `rpc.test.ts` test setup for middleware type inference
60
+ - Fixed `SearchDialog` to use `setQuery` instead of deprecated `search` method
61
+ - Fixed null→undefined warnings in notification and queue frontends
62
+
63
+ ### Patch Changes
64
+
65
+ - Updated dependencies [7a23261]
66
+ - @checkstack/common@0.3.0
67
+
3
68
  ## 0.2.0
4
69
 
5
70
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/auth-common",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
package/src/routes.ts CHANGED
@@ -11,4 +11,6 @@ export const authRoutes = createRoutes("auth", {
11
11
  forgotPassword: "/forgot-password",
12
12
  resetPassword: "/reset-password",
13
13
  changePassword: "/change-password",
14
+ profile: "/profile",
15
+ onboarding: "/onboarding",
14
16
  });
@@ -1,16 +1,12 @@
1
- import { oc } from "@orpc/contract";
2
1
  import {
3
2
  createClientDefinition,
4
- type ProcedureMetadata,
3
+ proc,
5
4
  lucideIconSchema,
6
5
  } from "@checkstack/common";
7
6
  import { z } from "zod";
8
7
  import { authAccess } from "./access";
9
8
  import { pluginMetadata } from "./plugin-metadata";
10
9
 
11
- // Base builder with full metadata support
12
- const _base = oc.$meta<ProcedureMetadata>({});
13
-
14
10
  // Zod schemas for return types
15
11
  const UserDtoSchema = z.object({
16
12
  id: z.string(),
@@ -25,7 +21,7 @@ const RoleDtoSchema = z.object({
25
21
  description: z.string().optional().nullable(),
26
22
  accessRules: z.array(z.string()),
27
23
  isSystem: z.boolean().optional(),
28
- isAssignable: z.boolean().optional(), // False for anonymous role
24
+ isAssignable: z.boolean().optional(),
29
25
  });
30
26
 
31
27
  const AccessRuleDtoSchema = z.object({
@@ -40,9 +36,9 @@ const StrategyDtoSchema = z.object({
40
36
  icon: lucideIconSchema.optional(),
41
37
  enabled: z.boolean(),
42
38
  configVersion: z.number(),
43
- configSchema: z.record(z.string(), z.unknown()), // JSON Schema representation
44
- config: z.record(z.string(), z.unknown()).optional(), // VersionedConfig.data (secrets redacted)
45
- adminInstructions: z.string().optional(), // Markdown instructions for admins
39
+ configSchema: z.record(z.string(), z.unknown()),
40
+ config: z.record(z.string(), z.unknown()).optional(),
41
+ adminInstructions: z.string().optional(),
46
42
  });
47
43
 
48
44
  const EnabledStrategyDtoSchema = z.object({
@@ -58,32 +54,25 @@ const RegistrationStatusSchema = z.object({
58
54
  allowRegistration: z.boolean(),
59
55
  });
60
56
 
61
- // ==========================================================================
62
- // SERVICE-TO-SERVICE SCHEMAS (for auth provider plugins like LDAP)
63
- // ==========================================================================
64
-
57
+ // Service-to-service schemas
65
58
  const FindUserByEmailInputSchema = z.object({
66
59
  email: z.string().email(),
67
60
  });
68
61
 
69
- const FindUserByEmailOutputSchema = z
70
- .object({
71
- id: z.string(),
72
- })
73
- .optional();
62
+ const FindUserByEmailOutputSchema = z.object({ id: z.string() }).optional();
74
63
 
75
64
  const UpsertExternalUserInputSchema = z.object({
76
65
  email: z.string().email(),
77
66
  name: z.string(),
78
- providerId: z.string(), // e.g., "ldap"
79
- accountId: z.string(), // Provider-specific account ID (e.g., LDAP username)
80
- password: z.string(), // Hashed password
81
- autoUpdateUser: z.boolean().optional(), // Update existing user's name
67
+ providerId: z.string(),
68
+ accountId: z.string(),
69
+ password: z.string(),
70
+ autoUpdateUser: z.boolean().optional(),
82
71
  });
83
72
 
84
73
  const UpsertExternalUserOutputSchema = z.object({
85
74
  userId: z.string(),
86
- created: z.boolean(), // true if new user was created, false if existing
75
+ created: z.boolean(),
87
76
  });
88
77
 
89
78
  const CreateSessionInputSchema = z.object({
@@ -95,7 +84,7 @@ const CreateSessionInputSchema = z.object({
95
84
  const CreateCredentialUserInputSchema = z.object({
96
85
  email: z.string().email(),
97
86
  name: z.string().min(1),
98
- password: z.string(), // Validated against passwordSchema on backend
87
+ password: z.string(),
99
88
  });
100
89
 
101
90
  const CreateCredentialUserOutputSchema = z.object({
@@ -106,90 +95,160 @@ const CreateCredentialUserOutputSchema = z.object({
106
95
  export const authContract = {
107
96
  // ==========================================================================
108
97
  // ANONYMOUS ENDPOINTS (userType: "anonymous")
109
- // These can be called without authentication (login/registration pages)
110
98
  // ==========================================================================
111
99
 
112
- getEnabledStrategies: _base
113
- .meta({ userType: "anonymous" })
114
- .output(z.array(EnabledStrategyDtoSchema)),
115
-
116
- getRegistrationStatus: _base
117
- .meta({ userType: "anonymous" })
118
- .output(RegistrationStatusSchema),
100
+ getEnabledStrategies: proc({
101
+ operationType: "query",
102
+ userType: "anonymous",
103
+ access: [],
104
+ }).output(z.array(EnabledStrategyDtoSchema)),
105
+
106
+ getRegistrationStatus: proc({
107
+ operationType: "query",
108
+ userType: "anonymous",
109
+ access: [],
110
+ }).output(RegistrationStatusSchema),
111
+
112
+ getOnboardingStatus: proc({
113
+ operationType: "query",
114
+ userType: "anonymous",
115
+ access: [],
116
+ }).output(z.object({ needsOnboarding: z.boolean() })),
117
+
118
+ completeOnboarding: proc({
119
+ operationType: "mutation",
120
+ userType: "anonymous",
121
+ access: [],
122
+ })
123
+ .input(
124
+ z.object({
125
+ name: z.string().min(1),
126
+ email: z.string().email(),
127
+ password: z.string(),
128
+ }),
129
+ )
130
+ .output(z.object({ success: z.boolean() })),
119
131
 
120
132
  // ==========================================================================
121
- // AUTHENTICATED ENDPOINTS (userType: "authenticated" - no specific access rule)
133
+ // AUTHENTICATED ENDPOINTS (userType: "authenticated")
122
134
  // ==========================================================================
123
135
 
124
- accessRules: _base
125
- .meta({ userType: "authenticated" }) // Any authenticated user can check their own access rules
126
- .output(z.object({ accessRules: z.array(z.string()) })),
136
+ accessRules: proc({
137
+ operationType: "query",
138
+ userType: "authenticated",
139
+ access: [],
140
+ }).output(z.object({ accessRules: z.array(z.string()) })),
141
+
142
+ getCurrentUserProfile: proc({
143
+ operationType: "query",
144
+ userType: "user",
145
+ access: [],
146
+ }).output(
147
+ z.object({
148
+ id: z.string(),
149
+ name: z.string(),
150
+ email: z.string(),
151
+ hasCredentialAccount: z.boolean(),
152
+ }),
153
+ ),
154
+
155
+ updateCurrentUser: proc({
156
+ operationType: "mutation",
157
+ userType: "user",
158
+ access: [],
159
+ })
160
+ .input(
161
+ z.object({
162
+ name: z.string().min(1).optional(),
163
+ email: z.string().email().optional(),
164
+ }),
165
+ )
166
+ .output(z.void()),
127
167
 
128
168
  // ==========================================================================
129
169
  // USER MANAGEMENT (userType: "user" with access)
130
170
  // ==========================================================================
131
171
 
132
- getUsers: _base
133
- .meta({ userType: "user", access: [authAccess.users.read] })
134
- .output(z.array(UserDtoSchema)),
172
+ getUsers: proc({
173
+ operationType: "query",
174
+ userType: "user",
175
+ access: [authAccess.users.read],
176
+ }).output(z.array(UserDtoSchema)),
135
177
 
136
- deleteUser: _base
137
- .meta({ userType: "user", access: [authAccess.users.manage] })
178
+ deleteUser: proc({
179
+ operationType: "mutation",
180
+ userType: "user",
181
+ access: [authAccess.users.manage],
182
+ })
138
183
  .input(z.string())
139
184
  .output(z.void()),
140
185
 
141
- createCredentialUser: _base
142
- .meta({ userType: "user", access: [authAccess.users.create] })
186
+ createCredentialUser: proc({
187
+ operationType: "mutation",
188
+ userType: "user",
189
+ access: [authAccess.users.create],
190
+ })
143
191
  .input(CreateCredentialUserInputSchema)
144
192
  .output(CreateCredentialUserOutputSchema),
145
193
 
146
- updateUserRoles: _base
147
- .meta({ userType: "user", access: [authAccess.users.manage] })
148
- .input(
149
- z.object({
150
- userId: z.string(),
151
- roles: z.array(z.string()),
152
- })
153
- )
194
+ updateUserRoles: proc({
195
+ operationType: "mutation",
196
+ userType: "user",
197
+ access: [authAccess.users.manage],
198
+ })
199
+ .input(z.object({ userId: z.string(), roles: z.array(z.string()) }))
154
200
  .output(z.void()),
155
201
 
156
202
  // ==========================================================================
157
203
  // ROLE MANAGEMENT (userType: "user" with access)
158
204
  // ==========================================================================
159
205
 
160
- getRoles: _base
161
- .meta({ userType: "user", access: [authAccess.roles.read] })
162
- .output(z.array(RoleDtoSchema)),
163
-
164
- getAccessRules: _base
165
- .meta({ userType: "user", access: [authAccess.roles.read] })
166
- .output(z.array(AccessRuleDtoSchema)),
167
-
168
- createRole: _base
169
- .meta({ userType: "user", access: [authAccess.roles.create] })
206
+ getRoles: proc({
207
+ operationType: "query",
208
+ userType: "user",
209
+ access: [authAccess.roles.read],
210
+ }).output(z.array(RoleDtoSchema)),
211
+
212
+ getAccessRules: proc({
213
+ operationType: "query",
214
+ userType: "user",
215
+ access: [authAccess.roles.read],
216
+ }).output(z.array(AccessRuleDtoSchema)),
217
+
218
+ createRole: proc({
219
+ operationType: "mutation",
220
+ userType: "user",
221
+ access: [authAccess.roles.create],
222
+ })
170
223
  .input(
171
224
  z.object({
172
225
  name: z.string(),
173
226
  description: z.string().optional(),
174
227
  accessRules: z.array(z.string()),
175
- })
228
+ }),
176
229
  )
177
230
  .output(z.void()),
178
231
 
179
- updateRole: _base
180
- .meta({ userType: "user", access: [authAccess.roles.update] })
232
+ updateRole: proc({
233
+ operationType: "mutation",
234
+ userType: "user",
235
+ access: [authAccess.roles.update],
236
+ })
181
237
  .input(
182
238
  z.object({
183
239
  id: z.string(),
184
240
  name: z.string().optional(),
185
241
  description: z.string().optional(),
186
242
  accessRules: z.array(z.string()),
187
- })
243
+ }),
188
244
  )
189
245
  .output(z.void()),
190
246
 
191
- deleteRole: _base
192
- .meta({ userType: "user", access: [authAccess.roles.delete] })
247
+ deleteRole: proc({
248
+ operationType: "mutation",
249
+ userType: "user",
250
+ access: [authAccess.roles.delete],
251
+ })
193
252
  .input(z.string())
194
253
  .output(z.void()),
195
254
 
@@ -197,41 +256,47 @@ export const authContract = {
197
256
  // STRATEGY MANAGEMENT (userType: "user" with access)
198
257
  // ==========================================================================
199
258
 
200
- getStrategies: _base
201
- .meta({ userType: "user", access: [authAccess.strategies] })
202
- .output(z.array(StrategyDtoSchema)),
259
+ getStrategies: proc({
260
+ operationType: "query",
261
+ userType: "user",
262
+ access: [authAccess.strategies],
263
+ }).output(z.array(StrategyDtoSchema)),
203
264
 
204
- updateStrategy: _base
205
- .meta({ userType: "user", access: [authAccess.strategies] })
265
+ updateStrategy: proc({
266
+ operationType: "mutation",
267
+ userType: "user",
268
+ access: [authAccess.strategies],
269
+ })
206
270
  .input(
207
271
  z.object({
208
272
  id: z.string(),
209
273
  enabled: z.boolean(),
210
274
  config: z.record(z.string(), z.unknown()).optional(),
211
- })
275
+ }),
212
276
  )
213
277
  .output(z.object({ success: z.boolean() })),
214
278
 
215
- reloadAuth: _base
216
- .meta({ userType: "user", access: [authAccess.strategies] })
217
- .output(z.object({ success: z.boolean() })),
279
+ reloadAuth: proc({
280
+ operationType: "mutation",
281
+ userType: "user",
282
+ access: [authAccess.strategies],
283
+ }).output(z.object({ success: z.boolean() })),
218
284
 
219
285
  // ==========================================================================
220
286
  // REGISTRATION MANAGEMENT (userType: "user" with access)
221
287
  // ==========================================================================
222
288
 
223
- getRegistrationSchema: _base
224
- .meta({
225
- userType: "user",
226
- access: [authAccess.registration],
227
- })
228
- .output(z.record(z.string(), z.unknown())),
229
-
230
- setRegistrationStatus: _base
231
- .meta({
232
- userType: "user",
233
- access: [authAccess.registration],
234
- })
289
+ getRegistrationSchema: proc({
290
+ operationType: "query",
291
+ userType: "user",
292
+ access: [authAccess.registration],
293
+ }).output(z.record(z.string(), z.unknown())),
294
+
295
+ setRegistrationStatus: proc({
296
+ operationType: "mutation",
297
+ userType: "user",
298
+ access: [authAccess.registration],
299
+ })
235
300
  .input(RegistrationStatusSchema)
236
301
  .output(z.object({ success: z.boolean() })),
237
302
 
@@ -239,48 +304,41 @@ export const authContract = {
239
304
  // INTERNAL SERVICE ENDPOINTS (userType: "service")
240
305
  // ==========================================================================
241
306
 
242
- /**
243
- * Get access rules assigned to the anonymous role.
244
- * Used by core AuthService for access checks on public endpoints.
245
- */
246
- getAnonymousAccessRules: _base
247
- .meta({ userType: "service" })
248
- .output(z.array(z.string())),
307
+ getAnonymousAccessRules: proc({
308
+ operationType: "query",
309
+ userType: "service",
310
+ access: [],
311
+ }).output(z.array(z.string())),
249
312
 
250
- /**
251
- * Find a user by email address.
252
- * Used by external auth providers (e.g., LDAP) to check if a user exists.
253
- */
254
- findUserByEmail: _base
255
- .meta({ userType: "service" })
313
+ findUserByEmail: proc({
314
+ operationType: "query",
315
+ userType: "service",
316
+ access: [],
317
+ })
256
318
  .input(FindUserByEmailInputSchema)
257
319
  .output(FindUserByEmailOutputSchema),
258
320
 
259
- /**
260
- * Upsert a user from an external auth provider.
261
- * Creates user + account if new, or updates user if autoUpdateUser is true.
262
- * Used by external auth providers (e.g., LDAP) to sync users.
263
- */
264
- upsertExternalUser: _base
265
- .meta({ userType: "service" })
321
+ upsertExternalUser: proc({
322
+ operationType: "mutation",
323
+ userType: "service",
324
+ access: [],
325
+ })
266
326
  .input(UpsertExternalUserInputSchema)
267
327
  .output(UpsertExternalUserOutputSchema),
268
328
 
269
- /**
270
- * Create a session for a user.
271
- * Used by external auth providers (e.g., LDAP) after successful authentication.
272
- */
273
- createSession: _base
274
- .meta({ userType: "service" })
329
+ createSession: proc({
330
+ operationType: "mutation",
331
+ userType: "service",
332
+ access: [],
333
+ })
275
334
  .input(CreateSessionInputSchema)
276
335
  .output(z.object({ sessionId: z.string() })),
277
336
 
278
- /**
279
- * Get a user by their ID.
280
- * Used by notification backend to fetch user email for contact resolution.
281
- */
282
- getUserById: _base
283
- .meta({ userType: "service" })
337
+ getUserById: proc({
338
+ operationType: "query",
339
+ userType: "service",
340
+ access: [],
341
+ })
284
342
  .input(z.object({ userId: z.string() }))
285
343
  .output(
286
344
  z
@@ -289,57 +347,54 @@ export const authContract = {
289
347
  email: z.string(),
290
348
  name: z.string().nullable(),
291
349
  })
292
- .optional()
350
+ .optional(),
293
351
  ),
294
352
 
295
- /**
296
- * Filter a list of user IDs to only those who have a specific access rule.
297
- * Used by SignalService to send signals only to authorized users.
298
- */
299
- filterUsersByAccessRule: _base
300
- .meta({ userType: "service" })
353
+ filterUsersByAccessRule: proc({
354
+ operationType: "query",
355
+ userType: "service",
356
+ access: [],
357
+ })
301
358
  .input(
302
359
  z.object({
303
360
  userIds: z.array(z.string()),
304
- accessRule: z.string(), // Fully-qualified access rule ID
305
- })
361
+ accessRule: z.string(),
362
+ }),
306
363
  )
307
- .output(z.array(z.string())), // Returns filtered user IDs
364
+ .output(z.array(z.string())),
308
365
 
309
366
  // ==========================================================================
310
367
  // APPLICATION MANAGEMENT (userType: "user" with access)
311
- // External API applications (API keys) with RBAC integration
312
368
  // ==========================================================================
313
369
 
314
- getApplications: _base
315
- .meta({
316
- userType: "user",
317
- access: [authAccess.applications],
318
- })
319
- .output(
320
- z.array(
321
- z.object({
322
- id: z.string(),
323
- name: z.string(),
324
- description: z.string().optional().nullable(),
325
- roles: z.array(z.string()),
326
- createdById: z.string(),
327
- createdAt: z.coerce.date(),
328
- lastUsedAt: z.coerce.date().optional().nullable(),
329
- })
330
- )
370
+ getApplications: proc({
371
+ operationType: "query",
372
+ userType: "user",
373
+ access: [authAccess.applications],
374
+ }).output(
375
+ z.array(
376
+ z.object({
377
+ id: z.string(),
378
+ name: z.string(),
379
+ description: z.string().optional().nullable(),
380
+ roles: z.array(z.string()),
381
+ createdById: z.string(),
382
+ createdAt: z.coerce.date(),
383
+ lastUsedAt: z.coerce.date().optional().nullable(),
384
+ }),
331
385
  ),
386
+ ),
332
387
 
333
- createApplication: _base
334
- .meta({
335
- userType: "user",
336
- access: [authAccess.applications],
337
- })
388
+ createApplication: proc({
389
+ operationType: "mutation",
390
+ userType: "user",
391
+ access: [authAccess.applications],
392
+ })
338
393
  .input(
339
394
  z.object({
340
395
  name: z.string().min(1).max(100),
341
396
  description: z.string().max(500).optional(),
342
- })
397
+ }),
343
398
  )
344
399
  .output(
345
400
  z.object({
@@ -351,69 +406,66 @@ export const authContract = {
351
406
  createdById: z.string(),
352
407
  createdAt: z.coerce.date(),
353
408
  }),
354
- secret: z.string(), // Full secret - ONLY shown once!
355
- })
409
+ secret: z.string(),
410
+ }),
356
411
  ),
357
412
 
358
- updateApplication: _base
359
- .meta({
360
- userType: "user",
361
- access: [authAccess.applications],
362
- })
413
+ updateApplication: proc({
414
+ operationType: "mutation",
415
+ userType: "user",
416
+ access: [authAccess.applications],
417
+ })
363
418
  .input(
364
419
  z.object({
365
420
  id: z.string(),
366
421
  name: z.string().optional(),
367
422
  description: z.string().optional().nullable(),
368
423
  roles: z.array(z.string()).optional(),
369
- })
424
+ }),
370
425
  )
371
426
  .output(z.void()),
372
427
 
373
- deleteApplication: _base
374
- .meta({
375
- userType: "user",
376
- access: [authAccess.applications],
377
- })
428
+ deleteApplication: proc({
429
+ operationType: "mutation",
430
+ userType: "user",
431
+ access: [authAccess.applications],
432
+ })
378
433
  .input(z.string())
379
434
  .output(z.void()),
380
435
 
381
- regenerateApplicationSecret: _base
382
- .meta({
383
- userType: "user",
384
- access: [authAccess.applications],
385
- })
436
+ regenerateApplicationSecret: proc({
437
+ operationType: "mutation",
438
+ userType: "user",
439
+ access: [authAccess.applications],
440
+ })
386
441
  .input(z.string())
387
- .output(z.object({ secret: z.string() })), // New secret - shown once
442
+ .output(z.object({ secret: z.string() })),
388
443
 
389
444
  // ==========================================================================
390
445
  // TEAM MANAGEMENT (userType: "authenticated" with access)
391
- // Resource-level access control via teams
392
- // Both users and applications can manage teams with proper access
393
446
  // ==========================================================================
394
447
 
395
- getTeams: _base
396
- .meta({
397
- userType: "authenticated",
398
- access: [authAccess.teams.read],
399
- })
400
- .output(
401
- z.array(
402
- z.object({
403
- id: z.string(),
404
- name: z.string(),
405
- description: z.string().optional().nullable(),
406
- memberCount: z.number(),
407
- isManager: z.boolean(),
408
- })
409
- )
448
+ getTeams: proc({
449
+ operationType: "query",
450
+ userType: "authenticated",
451
+ access: [authAccess.teams.read],
452
+ }).output(
453
+ z.array(
454
+ z.object({
455
+ id: z.string(),
456
+ name: z.string(),
457
+ description: z.string().optional().nullable(),
458
+ memberCount: z.number(),
459
+ isManager: z.boolean(),
460
+ }),
410
461
  ),
462
+ ),
411
463
 
412
- getTeam: _base
413
- .meta({
414
- userType: "authenticated",
415
- access: [authAccess.teams.read],
416
- })
464
+ getTeam: proc({
465
+ operationType: "query",
466
+ userType: "authenticated",
467
+ access: [authAccess.teams.read],
468
+ })
417
469
  .input(z.object({ teamId: z.string() }))
418
470
  .output(
419
471
  z
@@ -422,87 +474,87 @@ export const authContract = {
422
474
  name: z.string(),
423
475
  description: z.string().optional().nullable(),
424
476
  members: z.array(
425
- z.object({ id: z.string(), name: z.string(), email: z.string() })
477
+ z.object({ id: z.string(), name: z.string(), email: z.string() }),
426
478
  ),
427
479
  managers: z.array(
428
- z.object({ id: z.string(), name: z.string(), email: z.string() })
480
+ z.object({ id: z.string(), name: z.string(), email: z.string() }),
429
481
  ),
430
482
  })
431
- .optional()
483
+ .optional(),
432
484
  ),
433
485
 
434
- createTeam: _base
435
- .meta({
436
- userType: "authenticated",
437
- access: [authAccess.teams.manage],
438
- })
486
+ createTeam: proc({
487
+ operationType: "mutation",
488
+ userType: "authenticated",
489
+ access: [authAccess.teams.manage],
490
+ })
439
491
  .input(
440
492
  z.object({
441
493
  name: z.string().min(1).max(100),
442
494
  description: z.string().max(500).optional(),
443
- })
495
+ }),
444
496
  )
445
497
  .output(z.object({ id: z.string() })),
446
498
 
447
- updateTeam: _base
448
- .meta({
449
- userType: "authenticated",
450
- access: [authAccess.teams.read],
451
- })
499
+ updateTeam: proc({
500
+ operationType: "mutation",
501
+ userType: "authenticated",
502
+ access: [authAccess.teams.read],
503
+ })
452
504
  .input(
453
505
  z.object({
454
506
  id: z.string(),
455
507
  name: z.string().optional(),
456
508
  description: z.string().optional().nullable(),
457
- })
509
+ }),
458
510
  )
459
511
  .output(z.void()),
460
512
 
461
- deleteTeam: _base
462
- .meta({
463
- userType: "authenticated",
464
- access: [authAccess.teams.manage],
465
- })
513
+ deleteTeam: proc({
514
+ operationType: "mutation",
515
+ userType: "authenticated",
516
+ access: [authAccess.teams.manage],
517
+ })
466
518
  .input(z.string())
467
519
  .output(z.void()),
468
520
 
469
- addUserToTeam: _base
470
- .meta({
471
- userType: "authenticated",
472
- access: [authAccess.teams.read],
473
- })
521
+ addUserToTeam: proc({
522
+ operationType: "mutation",
523
+ userType: "authenticated",
524
+ access: [authAccess.teams.read],
525
+ })
474
526
  .input(z.object({ teamId: z.string(), userId: z.string() }))
475
527
  .output(z.void()),
476
528
 
477
- removeUserFromTeam: _base
478
- .meta({
479
- userType: "authenticated",
480
- access: [authAccess.teams.read],
481
- })
529
+ removeUserFromTeam: proc({
530
+ operationType: "mutation",
531
+ userType: "authenticated",
532
+ access: [authAccess.teams.read],
533
+ })
482
534
  .input(z.object({ teamId: z.string(), userId: z.string() }))
483
535
  .output(z.void()),
484
536
 
485
- addTeamManager: _base
486
- .meta({
487
- userType: "authenticated",
488
- access: [authAccess.teams.manage],
489
- })
537
+ addTeamManager: proc({
538
+ operationType: "mutation",
539
+ userType: "authenticated",
540
+ access: [authAccess.teams.manage],
541
+ })
490
542
  .input(z.object({ teamId: z.string(), userId: z.string() }))
491
543
  .output(z.void()),
492
544
 
493
- removeTeamManager: _base
494
- .meta({
495
- userType: "authenticated",
496
- access: [authAccess.teams.manage],
497
- })
545
+ removeTeamManager: proc({
546
+ operationType: "mutation",
547
+ userType: "authenticated",
548
+ access: [authAccess.teams.manage],
549
+ })
498
550
  .input(z.object({ teamId: z.string(), userId: z.string() }))
499
551
  .output(z.void()),
500
552
 
501
- getResourceTeamAccess: _base
502
- .meta({
503
- userType: "authenticated",
504
- access: [authAccess.teams.read],
505
- })
553
+ getResourceTeamAccess: proc({
554
+ operationType: "query",
555
+ userType: "authenticated",
556
+ access: [authAccess.teams.read],
557
+ })
506
558
  .input(z.object({ resourceType: z.string(), resourceId: z.string() }))
507
559
  .output(
508
560
  z.array(
@@ -511,15 +563,15 @@ export const authContract = {
511
563
  teamName: z.string(),
512
564
  canRead: z.boolean(),
513
565
  canManage: z.boolean(),
514
- })
515
- )
566
+ }),
567
+ ),
516
568
  ),
517
569
 
518
- setResourceTeamAccess: _base
519
- .meta({
520
- userType: "authenticated",
521
- access: [authAccess.teams.manage],
522
- })
570
+ setResourceTeamAccess: proc({
571
+ operationType: "mutation",
572
+ userType: "authenticated",
573
+ access: [authAccess.teams.manage],
574
+ })
523
575
  .input(
524
576
  z.object({
525
577
  resourceType: z.string(),
@@ -527,44 +579,43 @@ export const authContract = {
527
579
  teamId: z.string(),
528
580
  canRead: z.boolean().optional(),
529
581
  canManage: z.boolean().optional(),
530
- })
582
+ }),
531
583
  )
532
584
  .output(z.void()),
533
585
 
534
- removeResourceTeamAccess: _base
535
- .meta({
536
- userType: "authenticated",
537
- access: [authAccess.teams.manage],
538
- })
586
+ removeResourceTeamAccess: proc({
587
+ operationType: "mutation",
588
+ userType: "authenticated",
589
+ access: [authAccess.teams.manage],
590
+ })
539
591
  .input(
540
592
  z.object({
541
593
  resourceType: z.string(),
542
594
  resourceId: z.string(),
543
595
  teamId: z.string(),
544
- })
596
+ }),
545
597
  )
546
598
  .output(z.void()),
547
599
 
548
- // Resource-level access settings (teamOnly flag)
549
- getResourceAccessSettings: _base
550
- .meta({
551
- userType: "authenticated",
552
- access: [authAccess.teams.read],
553
- })
600
+ getResourceAccessSettings: proc({
601
+ operationType: "query",
602
+ userType: "authenticated",
603
+ access: [authAccess.teams.read],
604
+ })
554
605
  .input(z.object({ resourceType: z.string(), resourceId: z.string() }))
555
606
  .output(z.object({ teamOnly: z.boolean() })),
556
607
 
557
- setResourceAccessSettings: _base
558
- .meta({
559
- userType: "authenticated",
560
- access: [authAccess.teams.manage],
561
- })
608
+ setResourceAccessSettings: proc({
609
+ operationType: "mutation",
610
+ userType: "authenticated",
611
+ access: [authAccess.teams.manage],
612
+ })
562
613
  .input(
563
614
  z.object({
564
615
  resourceType: z.string(),
565
616
  resourceId: z.string(),
566
617
  teamOnly: z.boolean(),
567
- })
618
+ }),
568
619
  )
569
620
  .output(z.void()),
570
621
 
@@ -572,8 +623,11 @@ export const authContract = {
572
623
  // S2S ENDPOINTS FOR TEAM ACCESS (userType: "service")
573
624
  // ==========================================================================
574
625
 
575
- checkResourceTeamAccess: _base
576
- .meta({ userType: "service" })
626
+ checkResourceTeamAccess: proc({
627
+ operationType: "query",
628
+ userType: "service",
629
+ access: [],
630
+ })
577
631
  .input(
578
632
  z.object({
579
633
  userId: z.string(),
@@ -582,12 +636,15 @@ export const authContract = {
582
636
  resourceId: z.string(),
583
637
  action: z.enum(["read", "manage"]),
584
638
  hasGlobalAccess: z.boolean(),
585
- })
639
+ }),
586
640
  )
587
641
  .output(z.object({ hasAccess: z.boolean() })),
588
642
 
589
- getAccessibleResourceIds: _base
590
- .meta({ userType: "service" })
643
+ getAccessibleResourceIds: proc({
644
+ operationType: "query",
645
+ userType: "service",
646
+ access: [],
647
+ })
591
648
  .input(
592
649
  z.object({
593
650
  userId: z.string(),
@@ -596,12 +653,15 @@ export const authContract = {
596
653
  resourceIds: z.array(z.string()),
597
654
  action: z.enum(["read", "manage"]),
598
655
  hasGlobalAccess: z.boolean(),
599
- })
656
+ }),
600
657
  )
601
658
  .output(z.array(z.string())),
602
659
 
603
- deleteResourceGrants: _base
604
- .meta({ userType: "service" })
660
+ deleteResourceGrants: proc({
661
+ operationType: "mutation",
662
+ userType: "service",
663
+ access: [],
664
+ })
605
665
  .input(z.object({ resourceType: z.string(), resourceId: z.string() }))
606
666
  .output(z.void()),
607
667
  };