@oxyhq/contracts 0.1.0 → 0.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.
@@ -0,0 +1,535 @@
1
+ /**
2
+ * Recommendation-engine API contracts.
3
+ *
4
+ * SINGLE SOURCE OF TRUTH for the wire shape of the reputation-weighted
5
+ * profile-recommendation surface (`POST /profiles/recommendations`) and the
6
+ * cross-app signal-ingest endpoint (`POST /app-signals/ingest`). The API
7
+ * validates its INPUT/OUTPUT against these schemas; consumer SDKs validate the
8
+ * same definitions, so the producer and every consumer cannot drift.
9
+ *
10
+ * Platform-agnostic — zod is the only runtime dependency (no react / react-native
11
+ * / expo, ESM-safe).
12
+ */
13
+ import { z } from 'zod';
14
+ /** User-type filters a caller may exclude from the recommendation surface. */
15
+ export declare const recommendationExcludeTypeSchema: z.ZodEnum<["federated", "agent", "automated"]>;
16
+ export type RecommendationExcludeType = z.infer<typeof recommendationExcludeTypeSchema>;
17
+ /**
18
+ * A caller-supplied editorial boost. `userIds` are nudged up (or down, for a
19
+ * negative weight) in the ranking; the optional `reason` is for audit/telemetry
20
+ * only and never surfaced to end users. Boost members still pass the eligibility
21
+ * gate — a boost cannot resurrect a private/restricted/ineligible account.
22
+ */
23
+ export declare const recommendationBoostSchema: z.ZodObject<{
24
+ userIds: z.ZodArray<z.ZodString, "many">;
25
+ weight: z.ZodNumber;
26
+ reason: z.ZodOptional<z.ZodString>;
27
+ }, "strip", z.ZodTypeAny, {
28
+ userIds: string[];
29
+ weight: number;
30
+ reason?: string | undefined;
31
+ }, {
32
+ userIds: string[];
33
+ weight: number;
34
+ reason?: string | undefined;
35
+ }>;
36
+ export type RecommendationBoost = z.infer<typeof recommendationBoostSchema>;
37
+ /**
38
+ * Per-request overrides for the scoring signal weights. Every key is optional
39
+ * and clamped server-side to the resolved weight profile's allowed range — a
40
+ * caller can re-weight signals but never escape the profile's bounds.
41
+ */
42
+ export declare const recommendationSignalWeightsSchema: z.ZodObject<{
43
+ graph: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
44
+ completeness: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
45
+ verified: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
46
+ curation: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
47
+ interest: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
48
+ appBoost: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
49
+ repCandidate: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
50
+ }, "strip", z.ZodTypeAny, {
51
+ verified?: number | undefined;
52
+ graph?: number | undefined;
53
+ completeness?: number | undefined;
54
+ curation?: number | undefined;
55
+ interest?: number | undefined;
56
+ appBoost?: number | undefined;
57
+ repCandidate?: number | undefined;
58
+ }, {
59
+ verified?: number | undefined;
60
+ graph?: number | undefined;
61
+ completeness?: number | undefined;
62
+ curation?: number | undefined;
63
+ interest?: number | undefined;
64
+ appBoost?: number | undefined;
65
+ repCandidate?: number | undefined;
66
+ }>;
67
+ export type RecommendationSignalWeights = z.infer<typeof recommendationSignalWeightsSchema>;
68
+ /**
69
+ * Request body for `POST /profiles/recommendations`.
70
+ *
71
+ * `clientId` selects the per-app weight profile (the Application `_id`); when
72
+ * omitted the default profile is used. `excludeIds` removes accounts the caller
73
+ * has already seen/handled; `boosts` and `signalWeights` let the caller bias the
74
+ * ranking within server-enforced bounds.
75
+ */
76
+ export declare const recommendationRequestSchema: z.ZodObject<{
77
+ clientId: z.ZodOptional<z.ZodString>;
78
+ limit: z.ZodOptional<z.ZodNumber>;
79
+ offset: z.ZodOptional<z.ZodNumber>;
80
+ excludeTypes: z.ZodOptional<z.ZodArray<z.ZodEnum<["federated", "agent", "automated"]>, "many">>;
81
+ excludeIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
82
+ boosts: z.ZodOptional<z.ZodArray<z.ZodObject<{
83
+ userIds: z.ZodArray<z.ZodString, "many">;
84
+ weight: z.ZodNumber;
85
+ reason: z.ZodOptional<z.ZodString>;
86
+ }, "strip", z.ZodTypeAny, {
87
+ userIds: string[];
88
+ weight: number;
89
+ reason?: string | undefined;
90
+ }, {
91
+ userIds: string[];
92
+ weight: number;
93
+ reason?: string | undefined;
94
+ }>, "many">>;
95
+ signalWeights: z.ZodOptional<z.ZodObject<{
96
+ graph: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
97
+ completeness: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
98
+ verified: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
99
+ curation: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
100
+ interest: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
101
+ appBoost: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
102
+ repCandidate: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
103
+ }, "strip", z.ZodTypeAny, {
104
+ verified?: number | undefined;
105
+ graph?: number | undefined;
106
+ completeness?: number | undefined;
107
+ curation?: number | undefined;
108
+ interest?: number | undefined;
109
+ appBoost?: number | undefined;
110
+ repCandidate?: number | undefined;
111
+ }, {
112
+ verified?: number | undefined;
113
+ graph?: number | undefined;
114
+ completeness?: number | undefined;
115
+ curation?: number | undefined;
116
+ interest?: number | undefined;
117
+ appBoost?: number | undefined;
118
+ repCandidate?: number | undefined;
119
+ }>>;
120
+ }, "strip", z.ZodTypeAny, {
121
+ clientId?: string | undefined;
122
+ limit?: number | undefined;
123
+ offset?: number | undefined;
124
+ excludeTypes?: ("federated" | "agent" | "automated")[] | undefined;
125
+ excludeIds?: string[] | undefined;
126
+ boosts?: {
127
+ userIds: string[];
128
+ weight: number;
129
+ reason?: string | undefined;
130
+ }[] | undefined;
131
+ signalWeights?: {
132
+ verified?: number | undefined;
133
+ graph?: number | undefined;
134
+ completeness?: number | undefined;
135
+ curation?: number | undefined;
136
+ interest?: number | undefined;
137
+ appBoost?: number | undefined;
138
+ repCandidate?: number | undefined;
139
+ } | undefined;
140
+ }, {
141
+ clientId?: string | undefined;
142
+ limit?: number | undefined;
143
+ offset?: number | undefined;
144
+ excludeTypes?: ("federated" | "agent" | "automated")[] | undefined;
145
+ excludeIds?: string[] | undefined;
146
+ boosts?: {
147
+ userIds: string[];
148
+ weight: number;
149
+ reason?: string | undefined;
150
+ }[] | undefined;
151
+ signalWeights?: {
152
+ verified?: number | undefined;
153
+ graph?: number | undefined;
154
+ completeness?: number | undefined;
155
+ curation?: number | undefined;
156
+ interest?: number | undefined;
157
+ appBoost?: number | undefined;
158
+ repCandidate?: number | undefined;
159
+ } | undefined;
160
+ }>;
161
+ export type RecommendationRequest = z.infer<typeof recommendationRequestSchema>;
162
+ /** Follower/following counts attached to a recommendation item. */
163
+ export declare const recommendationCountSchema: z.ZodObject<{
164
+ followers: z.ZodNumber;
165
+ following: z.ZodNumber;
166
+ }, "strip", z.ZodTypeAny, {
167
+ followers: number;
168
+ following: number;
169
+ }, {
170
+ followers: number;
171
+ following: number;
172
+ }>;
173
+ export type RecommendationCount = z.infer<typeof recommendationCountSchema>;
174
+ /**
175
+ * A single recommended profile.
176
+ *
177
+ * `name` reuses the canonical {@link userNameSchema} so `name.displayName` is the
178
+ * already-resolved server-side value. `score` and `matchedSignals` are present
179
+ * only on the scored (v2) path; `mutualCount` and `_count` are always present.
180
+ */
181
+ export declare const recommendationItemSchema: z.ZodObject<{
182
+ id: z.ZodString;
183
+ username: z.ZodOptional<z.ZodString>;
184
+ name: z.ZodObject<{
185
+ first: z.ZodOptional<z.ZodString>;
186
+ last: z.ZodOptional<z.ZodString>;
187
+ full: z.ZodOptional<z.ZodString>;
188
+ displayName: z.ZodString;
189
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
190
+ first: z.ZodOptional<z.ZodString>;
191
+ last: z.ZodOptional<z.ZodString>;
192
+ full: z.ZodOptional<z.ZodString>;
193
+ displayName: z.ZodString;
194
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
195
+ first: z.ZodOptional<z.ZodString>;
196
+ last: z.ZodOptional<z.ZodString>;
197
+ full: z.ZodOptional<z.ZodString>;
198
+ displayName: z.ZodString;
199
+ }, z.ZodTypeAny, "passthrough">>;
200
+ avatar: z.ZodOptional<z.ZodNullable<z.ZodString>>;
201
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
202
+ verified: z.ZodOptional<z.ZodBoolean>;
203
+ trustTier: z.ZodOptional<z.ZodString>;
204
+ mutualCount: z.ZodNumber;
205
+ score: z.ZodOptional<z.ZodNumber>;
206
+ matchedSignals: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
207
+ isFederated: z.ZodOptional<z.ZodBoolean>;
208
+ isAgent: z.ZodOptional<z.ZodBoolean>;
209
+ isAutomated: z.ZodOptional<z.ZodBoolean>;
210
+ instance: z.ZodOptional<z.ZodString>;
211
+ _count: z.ZodObject<{
212
+ followers: z.ZodNumber;
213
+ following: z.ZodNumber;
214
+ }, "strip", z.ZodTypeAny, {
215
+ followers: number;
216
+ following: number;
217
+ }, {
218
+ followers: number;
219
+ following: number;
220
+ }>;
221
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
222
+ id: z.ZodString;
223
+ username: z.ZodOptional<z.ZodString>;
224
+ name: z.ZodObject<{
225
+ first: z.ZodOptional<z.ZodString>;
226
+ last: z.ZodOptional<z.ZodString>;
227
+ full: z.ZodOptional<z.ZodString>;
228
+ displayName: z.ZodString;
229
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
230
+ first: z.ZodOptional<z.ZodString>;
231
+ last: z.ZodOptional<z.ZodString>;
232
+ full: z.ZodOptional<z.ZodString>;
233
+ displayName: z.ZodString;
234
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
235
+ first: z.ZodOptional<z.ZodString>;
236
+ last: z.ZodOptional<z.ZodString>;
237
+ full: z.ZodOptional<z.ZodString>;
238
+ displayName: z.ZodString;
239
+ }, z.ZodTypeAny, "passthrough">>;
240
+ avatar: z.ZodOptional<z.ZodNullable<z.ZodString>>;
241
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
242
+ verified: z.ZodOptional<z.ZodBoolean>;
243
+ trustTier: z.ZodOptional<z.ZodString>;
244
+ mutualCount: z.ZodNumber;
245
+ score: z.ZodOptional<z.ZodNumber>;
246
+ matchedSignals: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
247
+ isFederated: z.ZodOptional<z.ZodBoolean>;
248
+ isAgent: z.ZodOptional<z.ZodBoolean>;
249
+ isAutomated: z.ZodOptional<z.ZodBoolean>;
250
+ instance: z.ZodOptional<z.ZodString>;
251
+ _count: z.ZodObject<{
252
+ followers: z.ZodNumber;
253
+ following: z.ZodNumber;
254
+ }, "strip", z.ZodTypeAny, {
255
+ followers: number;
256
+ following: number;
257
+ }, {
258
+ followers: number;
259
+ following: number;
260
+ }>;
261
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
262
+ id: z.ZodString;
263
+ username: z.ZodOptional<z.ZodString>;
264
+ name: z.ZodObject<{
265
+ first: z.ZodOptional<z.ZodString>;
266
+ last: z.ZodOptional<z.ZodString>;
267
+ full: z.ZodOptional<z.ZodString>;
268
+ displayName: z.ZodString;
269
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
270
+ first: z.ZodOptional<z.ZodString>;
271
+ last: z.ZodOptional<z.ZodString>;
272
+ full: z.ZodOptional<z.ZodString>;
273
+ displayName: z.ZodString;
274
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
275
+ first: z.ZodOptional<z.ZodString>;
276
+ last: z.ZodOptional<z.ZodString>;
277
+ full: z.ZodOptional<z.ZodString>;
278
+ displayName: z.ZodString;
279
+ }, z.ZodTypeAny, "passthrough">>;
280
+ avatar: z.ZodOptional<z.ZodNullable<z.ZodString>>;
281
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
282
+ verified: z.ZodOptional<z.ZodBoolean>;
283
+ trustTier: z.ZodOptional<z.ZodString>;
284
+ mutualCount: z.ZodNumber;
285
+ score: z.ZodOptional<z.ZodNumber>;
286
+ matchedSignals: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
287
+ isFederated: z.ZodOptional<z.ZodBoolean>;
288
+ isAgent: z.ZodOptional<z.ZodBoolean>;
289
+ isAutomated: z.ZodOptional<z.ZodBoolean>;
290
+ instance: z.ZodOptional<z.ZodString>;
291
+ _count: z.ZodObject<{
292
+ followers: z.ZodNumber;
293
+ following: z.ZodNumber;
294
+ }, "strip", z.ZodTypeAny, {
295
+ followers: number;
296
+ following: number;
297
+ }, {
298
+ followers: number;
299
+ following: number;
300
+ }>;
301
+ }, z.ZodTypeAny, "passthrough">>;
302
+ export type RecommendationItem = z.infer<typeof recommendationItemSchema>;
303
+ /** Wire shape of the recommendation response — an array of items. */
304
+ export declare const recommendationResponseSchema: z.ZodArray<z.ZodObject<{
305
+ id: z.ZodString;
306
+ username: z.ZodOptional<z.ZodString>;
307
+ name: z.ZodObject<{
308
+ first: z.ZodOptional<z.ZodString>;
309
+ last: z.ZodOptional<z.ZodString>;
310
+ full: z.ZodOptional<z.ZodString>;
311
+ displayName: z.ZodString;
312
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
313
+ first: z.ZodOptional<z.ZodString>;
314
+ last: z.ZodOptional<z.ZodString>;
315
+ full: z.ZodOptional<z.ZodString>;
316
+ displayName: z.ZodString;
317
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
318
+ first: z.ZodOptional<z.ZodString>;
319
+ last: z.ZodOptional<z.ZodString>;
320
+ full: z.ZodOptional<z.ZodString>;
321
+ displayName: z.ZodString;
322
+ }, z.ZodTypeAny, "passthrough">>;
323
+ avatar: z.ZodOptional<z.ZodNullable<z.ZodString>>;
324
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
325
+ verified: z.ZodOptional<z.ZodBoolean>;
326
+ trustTier: z.ZodOptional<z.ZodString>;
327
+ mutualCount: z.ZodNumber;
328
+ score: z.ZodOptional<z.ZodNumber>;
329
+ matchedSignals: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
330
+ isFederated: z.ZodOptional<z.ZodBoolean>;
331
+ isAgent: z.ZodOptional<z.ZodBoolean>;
332
+ isAutomated: z.ZodOptional<z.ZodBoolean>;
333
+ instance: z.ZodOptional<z.ZodString>;
334
+ _count: z.ZodObject<{
335
+ followers: z.ZodNumber;
336
+ following: z.ZodNumber;
337
+ }, "strip", z.ZodTypeAny, {
338
+ followers: number;
339
+ following: number;
340
+ }, {
341
+ followers: number;
342
+ following: number;
343
+ }>;
344
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
345
+ id: z.ZodString;
346
+ username: z.ZodOptional<z.ZodString>;
347
+ name: z.ZodObject<{
348
+ first: z.ZodOptional<z.ZodString>;
349
+ last: z.ZodOptional<z.ZodString>;
350
+ full: z.ZodOptional<z.ZodString>;
351
+ displayName: z.ZodString;
352
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
353
+ first: z.ZodOptional<z.ZodString>;
354
+ last: z.ZodOptional<z.ZodString>;
355
+ full: z.ZodOptional<z.ZodString>;
356
+ displayName: z.ZodString;
357
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
358
+ first: z.ZodOptional<z.ZodString>;
359
+ last: z.ZodOptional<z.ZodString>;
360
+ full: z.ZodOptional<z.ZodString>;
361
+ displayName: z.ZodString;
362
+ }, z.ZodTypeAny, "passthrough">>;
363
+ avatar: z.ZodOptional<z.ZodNullable<z.ZodString>>;
364
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
365
+ verified: z.ZodOptional<z.ZodBoolean>;
366
+ trustTier: z.ZodOptional<z.ZodString>;
367
+ mutualCount: z.ZodNumber;
368
+ score: z.ZodOptional<z.ZodNumber>;
369
+ matchedSignals: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
370
+ isFederated: z.ZodOptional<z.ZodBoolean>;
371
+ isAgent: z.ZodOptional<z.ZodBoolean>;
372
+ isAutomated: z.ZodOptional<z.ZodBoolean>;
373
+ instance: z.ZodOptional<z.ZodString>;
374
+ _count: z.ZodObject<{
375
+ followers: z.ZodNumber;
376
+ following: z.ZodNumber;
377
+ }, "strip", z.ZodTypeAny, {
378
+ followers: number;
379
+ following: number;
380
+ }, {
381
+ followers: number;
382
+ following: number;
383
+ }>;
384
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
385
+ id: z.ZodString;
386
+ username: z.ZodOptional<z.ZodString>;
387
+ name: z.ZodObject<{
388
+ first: z.ZodOptional<z.ZodString>;
389
+ last: z.ZodOptional<z.ZodString>;
390
+ full: z.ZodOptional<z.ZodString>;
391
+ displayName: z.ZodString;
392
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
393
+ first: z.ZodOptional<z.ZodString>;
394
+ last: z.ZodOptional<z.ZodString>;
395
+ full: z.ZodOptional<z.ZodString>;
396
+ displayName: z.ZodString;
397
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
398
+ first: z.ZodOptional<z.ZodString>;
399
+ last: z.ZodOptional<z.ZodString>;
400
+ full: z.ZodOptional<z.ZodString>;
401
+ displayName: z.ZodString;
402
+ }, z.ZodTypeAny, "passthrough">>;
403
+ avatar: z.ZodOptional<z.ZodNullable<z.ZodString>>;
404
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
405
+ verified: z.ZodOptional<z.ZodBoolean>;
406
+ trustTier: z.ZodOptional<z.ZodString>;
407
+ mutualCount: z.ZodNumber;
408
+ score: z.ZodOptional<z.ZodNumber>;
409
+ matchedSignals: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
410
+ isFederated: z.ZodOptional<z.ZodBoolean>;
411
+ isAgent: z.ZodOptional<z.ZodBoolean>;
412
+ isAutomated: z.ZodOptional<z.ZodBoolean>;
413
+ instance: z.ZodOptional<z.ZodString>;
414
+ _count: z.ZodObject<{
415
+ followers: z.ZodNumber;
416
+ following: z.ZodNumber;
417
+ }, "strip", z.ZodTypeAny, {
418
+ followers: number;
419
+ following: number;
420
+ }, {
421
+ followers: number;
422
+ following: number;
423
+ }>;
424
+ }, z.ZodTypeAny, "passthrough">>, "many">;
425
+ export type RecommendationResponse = z.infer<typeof recommendationResponseSchema>;
426
+ /** One endorsement edge an app reports: `ownerId` endorses `memberId`. */
427
+ export declare const appEndorsementInputSchema: z.ZodObject<{
428
+ ownerId: z.ZodString;
429
+ memberId: z.ZodString;
430
+ op: z.ZodDefault<z.ZodEnum<["add", "remove"]>>;
431
+ sourceId: z.ZodOptional<z.ZodString>;
432
+ }, "strip", z.ZodTypeAny, {
433
+ ownerId: string;
434
+ memberId: string;
435
+ op: "add" | "remove";
436
+ sourceId?: string | undefined;
437
+ }, {
438
+ ownerId: string;
439
+ memberId: string;
440
+ op?: "add" | "remove" | undefined;
441
+ sourceId?: string | undefined;
442
+ }>;
443
+ export type AppEndorsementInput = z.infer<typeof appEndorsementInputSchema>;
444
+ /** One interest signal an app reports: how interested `userId` is in a topic. */
445
+ export declare const appInterestInputSchema: z.ZodObject<{
446
+ userId: z.ZodString;
447
+ interestScore: z.ZodNumber;
448
+ }, "strip", z.ZodTypeAny, {
449
+ userId: string;
450
+ interestScore: number;
451
+ }, {
452
+ userId: string;
453
+ interestScore: number;
454
+ }>;
455
+ export type AppInterestInput = z.infer<typeof appInterestInputSchema>;
456
+ /**
457
+ * Request body for `POST /app-signals/ingest` (service token, `signals:write`).
458
+ *
459
+ * At least one of `endorsements` / `interests` must be non-empty — an ingest
460
+ * with neither is a no-op and rejected so a misconfigured caller is surfaced
461
+ * rather than silently succeeding.
462
+ */
463
+ export declare const appUserSignalIngestSchema: z.ZodEffects<z.ZodObject<{
464
+ endorsements: z.ZodOptional<z.ZodArray<z.ZodObject<{
465
+ ownerId: z.ZodString;
466
+ memberId: z.ZodString;
467
+ op: z.ZodDefault<z.ZodEnum<["add", "remove"]>>;
468
+ sourceId: z.ZodOptional<z.ZodString>;
469
+ }, "strip", z.ZodTypeAny, {
470
+ ownerId: string;
471
+ memberId: string;
472
+ op: "add" | "remove";
473
+ sourceId?: string | undefined;
474
+ }, {
475
+ ownerId: string;
476
+ memberId: string;
477
+ op?: "add" | "remove" | undefined;
478
+ sourceId?: string | undefined;
479
+ }>, "many">>;
480
+ interests: z.ZodOptional<z.ZodArray<z.ZodObject<{
481
+ userId: z.ZodString;
482
+ interestScore: z.ZodNumber;
483
+ }, "strip", z.ZodTypeAny, {
484
+ userId: string;
485
+ interestScore: number;
486
+ }, {
487
+ userId: string;
488
+ interestScore: number;
489
+ }>, "many">>;
490
+ }, "strip", z.ZodTypeAny, {
491
+ endorsements?: {
492
+ ownerId: string;
493
+ memberId: string;
494
+ op: "add" | "remove";
495
+ sourceId?: string | undefined;
496
+ }[] | undefined;
497
+ interests?: {
498
+ userId: string;
499
+ interestScore: number;
500
+ }[] | undefined;
501
+ }, {
502
+ endorsements?: {
503
+ ownerId: string;
504
+ memberId: string;
505
+ op?: "add" | "remove" | undefined;
506
+ sourceId?: string | undefined;
507
+ }[] | undefined;
508
+ interests?: {
509
+ userId: string;
510
+ interestScore: number;
511
+ }[] | undefined;
512
+ }>, {
513
+ endorsements?: {
514
+ ownerId: string;
515
+ memberId: string;
516
+ op: "add" | "remove";
517
+ sourceId?: string | undefined;
518
+ }[] | undefined;
519
+ interests?: {
520
+ userId: string;
521
+ interestScore: number;
522
+ }[] | undefined;
523
+ }, {
524
+ endorsements?: {
525
+ ownerId: string;
526
+ memberId: string;
527
+ op?: "add" | "remove" | undefined;
528
+ sourceId?: string | undefined;
529
+ }[] | undefined;
530
+ interests?: {
531
+ userId: string;
532
+ interestScore: number;
533
+ }[] | undefined;
534
+ }>;
535
+ export type AppUserSignalIngest = z.infer<typeof appUserSignalIngestSchema>;