@oxyhq/crowdsource-contracts 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.
Files changed (87) hide show
  1. package/dist/appeals.d.ts +323 -0
  2. package/dist/appeals.d.ts.map +1 -0
  3. package/dist/appeals.js +203 -0
  4. package/dist/appeals.js.map +1 -0
  5. package/dist/case-envelope.d.ts +59 -59
  6. package/dist/case-envelope.d.ts.map +1 -1
  7. package/dist/case-envelope.js +32 -32
  8. package/dist/case-envelope.js.map +1 -1
  9. package/dist/decisions.d.ts +3 -3
  10. package/dist/decisions.d.ts.map +1 -1
  11. package/dist/decisions.js +28 -28
  12. package/dist/decisions.js.map +1 -1
  13. package/dist/esm/appeals.js +200 -0
  14. package/dist/esm/appeals.js.map +1 -0
  15. package/dist/esm/case-envelope.js +380 -0
  16. package/dist/esm/case-envelope.js.map +1 -0
  17. package/dist/esm/closed.js +32 -0
  18. package/dist/esm/closed.js.map +1 -0
  19. package/dist/esm/decisions.js +195 -0
  20. package/dist/esm/decisions.js.map +1 -0
  21. package/dist/esm/index.js +48 -0
  22. package/dist/esm/index.js.map +1 -0
  23. package/dist/esm/json-schema.js +84 -0
  24. package/dist/esm/json-schema.js.map +1 -0
  25. package/dist/esm/package.json +1 -0
  26. package/dist/esm/policies.js +175 -0
  27. package/dist/esm/policies.js.map +1 -0
  28. package/dist/esm/primitives.js +249 -0
  29. package/dist/esm/primitives.js.map +1 -0
  30. package/dist/esm/reputation-events.js +125 -0
  31. package/dist/esm/reputation-events.js.map +1 -0
  32. package/dist/esm/resources.js +455 -0
  33. package/dist/esm/resources.js.map +1 -0
  34. package/dist/esm/reviewer-surface.js +612 -0
  35. package/dist/esm/reviewer-surface.js.map +1 -0
  36. package/dist/esm/reviews.js +141 -0
  37. package/dist/esm/reviews.js.map +1 -0
  38. package/dist/esm/taxonomy.js +278 -0
  39. package/dist/esm/taxonomy.js.map +1 -0
  40. package/dist/esm/webhooks.js +188 -0
  41. package/dist/esm/webhooks.js.map +1 -0
  42. package/dist/index.d.ts +13 -11
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +13 -11
  45. package/dist/index.js.map +1 -1
  46. package/dist/json-schema.d.ts +2 -2
  47. package/dist/json-schema.d.ts.map +1 -1
  48. package/dist/json-schema.js +26 -21
  49. package/dist/json-schema.js.map +1 -1
  50. package/dist/policies.d.ts +1 -1
  51. package/dist/policies.d.ts.map +1 -1
  52. package/dist/policies.js +14 -14
  53. package/dist/policies.js.map +1 -1
  54. package/dist/primitives.d.ts +17 -0
  55. package/dist/primitives.d.ts.map +1 -1
  56. package/dist/primitives.js +22 -1
  57. package/dist/primitives.js.map +1 -1
  58. package/dist/reputation-events.js +19 -19
  59. package/dist/reputation-events.js.map +1 -1
  60. package/dist/resources.d.ts +116 -39
  61. package/dist/resources.d.ts.map +1 -1
  62. package/dist/resources.js +143 -121
  63. package/dist/resources.js.map +1 -1
  64. package/dist/reviewer-surface.d.ts +1956 -0
  65. package/dist/reviewer-surface.d.ts.map +1 -0
  66. package/dist/reviewer-surface.js +615 -0
  67. package/dist/reviewer-surface.js.map +1 -0
  68. package/dist/reviews.d.ts +2 -2
  69. package/dist/reviews.js +15 -15
  70. package/dist/reviews.js.map +1 -1
  71. package/dist/webhooks.d.ts +4 -4
  72. package/dist/webhooks.d.ts.map +1 -1
  73. package/dist/webhooks.js +18 -18
  74. package/dist/webhooks.js.map +1 -1
  75. package/package.json +4 -4
  76. package/src/appeals.ts +229 -0
  77. package/src/case-envelope.ts +5 -5
  78. package/src/decisions.ts +6 -6
  79. package/src/index.ts +13 -11
  80. package/src/json-schema.ts +13 -8
  81. package/src/policies.ts +3 -3
  82. package/src/primitives.ts +25 -0
  83. package/src/reputation-events.ts +4 -4
  84. package/src/resources.ts +136 -100
  85. package/src/reviewer-surface.ts +715 -0
  86. package/src/reviews.ts +4 -4
  87. package/src/webhooks.ts +4 -4
@@ -0,0 +1,612 @@
1
+ /**
2
+ * The Reviewer API wire contract (§10.3) — what the backend sends and the
3
+ * reviewer app receives, declared once.
4
+ *
5
+ * ## Why this module exists at all
6
+ *
7
+ * It exists because the alternative was tried and failed silently. The backend
8
+ * and the reviewer app each wrote their own version of these shapes, and they
9
+ * agreed on almost nothing: the state vocabularies differed outright
10
+ * (`community` against `community_reviewer`), so did the sensitivity classes
11
+ * (`standard`/`sensitive`/`restricted` against an invented
12
+ * `none`/`low`/`high`/`critical`); the assignment package disagreed on
13
+ * `allegation` against `allegations`, on `policyVersion` against `version`, and
14
+ * on five fields that existed on one side only. Nothing caught it, because there
15
+ * was no shared declaration for anything to be checked against.
16
+ *
17
+ * So the rule this module encodes: **a field that crosses the reviewer boundary
18
+ * is declared here and nowhere else.**
19
+ *
20
+ * ## Schemas, and types inferred from them
21
+ *
22
+ * Every shape is a Zod schema, and its TypeScript type is `z.infer` of that
23
+ * schema. One declaration, so the two cannot disagree — which is a property worth
24
+ * more here than the hand-written interfaces it replaces, since "two declarations
25
+ * of one shape drifted apart" is the exact bug this file was written to end.
26
+ *
27
+ * Both halves are load-bearing and they catch different failures:
28
+ *
29
+ * - The **type** is what the backend's builders return and what the app's
30
+ * projections return, so a renamed field is a compile error on BOTH sides at
31
+ * once — the check that would have caught every drift listed above on the day
32
+ * it appeared.
33
+ * - The **schema** is what the app parses the response WITH, and it is
34
+ * `.strict()` at every level. §9.1's hidden column has no field on any shape
35
+ * here, so a server that starts sending a report count or an author's
36
+ * reputation is REFUSED rather than having it quietly reach a screen. A type
37
+ * cannot do that: types are gone at runtime, and the wire is where an
38
+ * unexpected field actually arrives.
39
+ *
40
+ * Strict is the right direction for this surface specifically. A reviewer seeing
41
+ * a blank screen is a bug somebody fixes today; a reviewer seeing an author's
42
+ * reputation is a bug nobody notices.
43
+ *
44
+ * ## What is deliberately NOT here
45
+ *
46
+ * No case id, on any shape. §8.7 pseudonymises what a reviewer does not need and
47
+ * a case id is not needed to judge material; more to the point, a case id on the
48
+ * wire is a case id in a URL, and "nobody chooses the case they review" holds
49
+ * because the assignment is the only handle. No reporter, no report count, no
50
+ * reputation, no juror identity, no partial tally.
51
+ */
52
+ import { z } from 'zod';
53
+ import { DecisionOutcomeSchema } from './decisions.js';
54
+ import { PolicyRuleSchema, PolicySetIdSchema, PolicyVersionSchema } from './policies.js';
55
+ import { CustomPayloadSchema, IdentifierSchema, LanguageTagSchema, MetadataBagSchema, MimeTypeSchema, TimestampSchema, UnitIntervalSchema, } from './primitives.js';
56
+ import { AudioResourceDataSchema, ConversationResourceDataSchema, DocumentResourceDataSchema, LinkResourceDataSchema, ListingResourceDataSchema, LocationResourceDataSchema, MetadataResourceDataSchema, PrincipalRefSchema, ProfileResourceDataSchema, RelationSchema, ResourceIdSchema, ResourceRoleSchema, TextResourceDataSchema, VideoResourceDataSchema, } from './resources.js';
57
+ import { ReviewOutcomeSchema } from './reviews.js';
58
+ import { SensitivityHintSchema, TAXONOMY_FAMILIES, TaxonomyCodeSchema, TaxonomyFamilySchema, } from './taxonomy.js';
59
+ // --- vocabularies ------------------------------------------------------------
60
+ /**
61
+ * §8.1's seven onboarding states, ordered from least to most capable.
62
+ *
63
+ * §8.1 writes them as English prose labels ("Community Reviewer", "Category
64
+ * Specialist"). These are the identifiers, and they are the SHORT forms on
65
+ * purpose: the `_reviewer` suffix says nothing a `ReviewerState` type does not
66
+ * already say, and `specialist` pairs with a separate `specialistCategories`
67
+ * field, so `category_specialist` would name the category twice.
68
+ *
69
+ * `suspended` is apart from the ordering rather than at the bottom of it — see
70
+ * the backend's `REVIEWER_STATE_RANK`, which gives it -1 so every capability
71
+ * comparison fails for it, including one against `applicant`.
72
+ */
73
+ export const REVIEWER_STATES = [
74
+ 'applicant',
75
+ 'calibrating',
76
+ 'community',
77
+ 'trusted',
78
+ 'specialist',
79
+ 'appeals',
80
+ 'suspended',
81
+ ];
82
+ export const ReviewerStateSchema = z.enum(REVIEWER_STATES);
83
+ /**
84
+ * The sensitivity classes a jury can be shown, ranked (§7.5, §13.7).
85
+ *
86
+ * Triage computes a fourth, `prohibited`, and it is absent here on purpose: §7.5
87
+ * routes that material to a specialist team under legal protocol and never to a
88
+ * jury, so a reviewer-facing type that could express it would eventually be
89
+ * handed it. The backend's `sensitivityRank` throws rather than returning a
90
+ * number for it, for the same reason.
91
+ *
92
+ * This is also the vocabulary a reviewer's own consent is stored in, as a rank —
93
+ * which is why it could never have been the app's invented
94
+ * `none`/`low`/`high`/`critical`: those four map onto nothing the server computes
95
+ * or the reviewer consented to.
96
+ */
97
+ export const REVIEWER_SENSITIVITY_CLASSES = ['standard', 'sensitive', 'restricted'];
98
+ export const ReviewerSensitivityClassSchema = z.enum(REVIEWER_SENSITIVITY_CLASSES);
99
+ /**
100
+ * The eligibility requirements a reviewer may be TOLD about (§8.2).
101
+ *
102
+ * §8.2 lists ten conditions and this list is eight, which is the interesting
103
+ * part. Two groups are missing and neither is an oversight:
104
+ *
105
+ * - **Relative to a case.** Conflict with a party, prior participation in the
106
+ * case or incident, and coordination-cluster overlap are properties of a
107
+ * candidate against a specific case's parties — they live in
108
+ * `sortition/exclusions.ts` where the parties are known, and outside a draw
109
+ * there is no answer to give.
110
+ * - **Anti-abuse signals.** A sock-puppet suspicion is deliberately not
111
+ * disclosed. Telling somebody they are flagged tells them what to change,
112
+ * which is the same reasoning that keeps `suspectedSockPuppet` and
113
+ * `riskClusterId` out of the profile projection entirely.
114
+ *
115
+ * Exposure is absent too, but only because it has a richer home of its own:
116
+ * `ReviewerExposureView` gives the numbers rather than a boolean.
117
+ *
118
+ * Every id here maps to a check the server actually performs, so the app can
119
+ * never display a requirement nobody enforces. There is no server-authored
120
+ * explanation string: the app is translated (`locales/*.json`) and a sentence
121
+ * composed by a backend with no locale would arrive in the wrong language.
122
+ */
123
+ export const REVIEWER_ELIGIBILITY_REQUIREMENTS = [
124
+ /** §8.2: "an active and authenticated Oxy account". */
125
+ 'oxy_account',
126
+ /** §8.2: personhood sufficient for real decisions. */
127
+ 'personhood',
128
+ /** §8.2: an age compatible with the chosen categories. */
129
+ 'age',
130
+ /** §13.7: the reviewing rules were accepted. */
131
+ 'rules_accepted',
132
+ /** §8.2: at least one language, or no case can ever match. */
133
+ 'languages_selected',
134
+ /** §8.2: at least one category, likewise. */
135
+ 'categories_selected',
136
+ /** §8.1: every training module complete. */
137
+ 'training_current',
138
+ /** §8.2: calibration passed and not lapsed. */
139
+ 'calibration_current',
140
+ ];
141
+ export const ReviewerEligibilityRequirementIdSchema = z.enum(REVIEWER_ELIGIBILITY_REQUIREMENTS);
142
+ /**
143
+ * §13.7's ceiling on a self-chosen daily limit.
144
+ *
145
+ * Declared here because the request schema below bounds the body with it and the
146
+ * app's control has to offer the same range — two numbers that must agree, so
147
+ * there is one.
148
+ */
149
+ export const REVIEWER_DAILY_LIMIT_MAX = 40;
150
+ /** The header §8.7's assignment token travels in. One spelling, both sides. */
151
+ export const ASSIGNMENT_TOKEN_HEADER = 'x-assignment-token';
152
+ // --- case material -----------------------------------------------------------
153
+ /**
154
+ * A resource asset as a reviewer receives it (§8.7, §9.1).
155
+ *
156
+ * The envelope's `AssetRef` carries `uploadId` OR `url`, plus a `sha256`. None of
157
+ * the three reaches a reviewer:
158
+ *
159
+ * - `url` is a location on the REPORTING APPLICATION's own host, so sending it
160
+ * puts that application's brand in front of the jury — §9.1's last hidden row
161
+ * — and it bypasses the media chokepoint every Oxy surface resolves files
162
+ * through.
163
+ * - `sha256` is what pins a case to the exact bytes reported. A reviewer does
164
+ * not verify that; the case does.
165
+ *
166
+ * What replaces them is `fileId`, a bare Oxy file id resolved through
167
+ * `getFileDownloadUrl` at the app root, and `retrievable`, which is the honest
168
+ * answer when there is nothing a reviewer can be shown. A reviewer facing an
169
+ * unretrievable resource has an outcome for exactly that (`content_unavailable`),
170
+ * which is why this is a flag rather than an omission: dropping the resource
171
+ * would hide from the jury that material existed at all.
172
+ */
173
+ export const ReviewerAssetSchema = z.strictObject({
174
+ mediaType: MimeTypeSchema,
175
+ /** Bare Oxy file id. Absent whenever `retrievable` is false. */
176
+ fileId: IdentifierSchema.optional(),
177
+ /** False when CrowdSource cannot serve these bytes to a reviewer. */
178
+ retrievable: z.boolean(),
179
+ sizeBytes: z.number().int().positive().optional(),
180
+ width: z.number().int().positive().optional(),
181
+ height: z.number().int().positive().optional(),
182
+ durationSeconds: z.number().positive().optional(),
183
+ });
184
+ /**
185
+ * The envelope fields every reviewer-facing resource carries.
186
+ *
187
+ * `sha256` is absent, as above. `authorPrincipalRef` is PRESENT, and that is a
188
+ * decision rather than an oversight: §9.1 hides the author's IDENTITY and
189
+ * REPUTATION, and an envelope-scoped pseudonym (§13.5's "a pseudonymous
190
+ * principal wherever one suffices") is neither. It resolves to nothing outside
191
+ * this one case, and which resources share an author is exactly the context a
192
+ * harassment allegation cannot be judged without.
193
+ */
194
+ const reviewerResourceShape = {
195
+ id: ResourceIdSchema,
196
+ role: ResourceRoleSchema,
197
+ language: LanguageTagSchema.optional(),
198
+ createdAt: TimestampSchema.optional(),
199
+ authorPrincipalRef: PrincipalRefSchema.optional(),
200
+ sensitivity: SensitivityHintSchema.optional(),
201
+ };
202
+ /**
203
+ * One resource of case material, as a reviewer receives it.
204
+ *
205
+ * Built from the same `*DataSchema` exports the envelope's own resources are
206
+ * built from, so the twelve content shapes exist once. What differs is exactly
207
+ * the two things the reviewer projection changes: no `sha256`, and `asset` is a
208
+ * media handle rather than a locator.
209
+ *
210
+ * A strict parse rather than a hand-written field-by-field copy, and the reason
211
+ * is the direction each fails in. A copy can only drop what somebody thought to
212
+ * drop, and it can also DROP MATERIAL by accident — a jury shown less than the
213
+ * application sent is the worse failure of the two. A strict parse against a
214
+ * closed union refuses an unknown field outright and cannot silently lose a known
215
+ * one.
216
+ *
217
+ * `__tests__/reviewer-surface.test.ts` asserts this union still covers every
218
+ * `RESOURCE_TYPES` member and every base field of an envelope resource, so a new
219
+ * resource type or field in `resources.ts` cannot quietly stop reaching a jury.
220
+ */
221
+ export const ReviewerResourceSchema = z.discriminatedUnion('type', [
222
+ z.strictObject({
223
+ ...reviewerResourceShape,
224
+ type: z.literal('text'),
225
+ data: TextResourceDataSchema,
226
+ }),
227
+ z.strictObject({
228
+ ...reviewerResourceShape,
229
+ type: z.literal('link'),
230
+ data: LinkResourceDataSchema,
231
+ }),
232
+ z.strictObject({
233
+ ...reviewerResourceShape,
234
+ type: z.literal('profile'),
235
+ data: ProfileResourceDataSchema,
236
+ }),
237
+ z.strictObject({
238
+ ...reviewerResourceShape,
239
+ type: z.literal('conversation'),
240
+ data: ConversationResourceDataSchema,
241
+ }),
242
+ z.strictObject({
243
+ ...reviewerResourceShape,
244
+ type: z.literal('listing'),
245
+ data: ListingResourceDataSchema,
246
+ }),
247
+ z.strictObject({
248
+ ...reviewerResourceShape,
249
+ type: z.literal('location'),
250
+ data: LocationResourceDataSchema,
251
+ }),
252
+ z.strictObject({
253
+ ...reviewerResourceShape,
254
+ type: z.literal('metadata'),
255
+ data: MetadataResourceDataSchema,
256
+ }),
257
+ z.strictObject({
258
+ ...reviewerResourceShape,
259
+ type: z.literal('custom'),
260
+ schemaId: IdentifierSchema,
261
+ payload: CustomPayloadSchema,
262
+ }),
263
+ z.strictObject({
264
+ ...reviewerResourceShape,
265
+ type: z.literal('image'),
266
+ asset: ReviewerAssetSchema,
267
+ }),
268
+ z.strictObject({
269
+ ...reviewerResourceShape,
270
+ type: z.literal('video'),
271
+ asset: ReviewerAssetSchema,
272
+ data: VideoResourceDataSchema.optional(),
273
+ }),
274
+ z.strictObject({
275
+ ...reviewerResourceShape,
276
+ type: z.literal('audio'),
277
+ asset: ReviewerAssetSchema,
278
+ data: AudioResourceDataSchema.optional(),
279
+ }),
280
+ z.strictObject({
281
+ ...reviewerResourceShape,
282
+ type: z.literal('document'),
283
+ asset: ReviewerAssetSchema,
284
+ data: DocumentResourceDataSchema,
285
+ }),
286
+ ]);
287
+ // --- the assignment package --------------------------------------------------
288
+ /**
289
+ * The renderable package for ONE assignment (§8.7, §9.1).
290
+ *
291
+ * `language` is nullable because an envelope's resources may declare none, and
292
+ * `families` is plural because a case can allege several: a reviewer is only
293
+ * drawn when they accept ALL of them (§8.2), so naming one would misdescribe what
294
+ * they were asked to judge.
295
+ *
296
+ * `allegations.unverified` is a constant `true` on the wire. It is redundant to a
297
+ * reader of this file and it is not redundant to a screen: §9.1's requirement is
298
+ * that the claim is presented AS a claim, and a flag that must be read to render
299
+ * the label cannot be forgotten the way a comment can. `codes` is plural because
300
+ * a case is the union of every report about the same material (§7.3) and
301
+ * reporters do not all choose the same code — a singular field would silently
302
+ * show a jury one allegation out of several.
303
+ *
304
+ * `watermark` is §13.8's pseudonymous per-assignment mark. Server-issued so a
305
+ * leaked screenshot is traceable to one assignment; never synthesised on the
306
+ * device, because a watermark the client composes is one the client can also omit
307
+ * or forge, leaving a reviewer with the impression of a sealed screen and no
308
+ * actual trace.
309
+ */
310
+ export const AssignmentPackageSchema = z.strictObject({
311
+ assignmentId: IdentifierSchema,
312
+ /** The case revision this assignment is bound to (§8.7, §9.9). */
313
+ caseRevision: z.number().int().positive(),
314
+ /** ISO instant. After this the assignment is gone and a replacement is drawn. */
315
+ expiresAt: TimestampSchema,
316
+ language: LanguageTagSchema.nullable(),
317
+ families: z.array(TaxonomyFamilySchema).max(TAXONOMY_FAMILIES.length),
318
+ allegations: z.strictObject({
319
+ unverified: z.literal(true),
320
+ codes: z.array(TaxonomyCodeSchema),
321
+ }),
322
+ /** §9.1's "applicable policy and its rules", in full and at one version (§6.4). */
323
+ policy: z.strictObject({
324
+ policySetId: PolicySetIdSchema,
325
+ version: PolicyVersionSchema,
326
+ taxonomyVersion: z.string().min(1).max(32),
327
+ rules: z.array(PolicyRuleSchema),
328
+ }),
329
+ /** §9.1's warnings and sensitivity, plus §13.7's blur decision. */
330
+ presentation: z.strictObject({
331
+ sensitivityClass: ReviewerSensitivityClassSchema,
332
+ requiresRedaction: z.boolean(),
333
+ blurBeforeReveal: z.boolean(),
334
+ }),
335
+ resources: z.array(ReviewerResourceSchema),
336
+ /** §5.5 — which resource replies to, quotes or contextualises which. */
337
+ relations: z.array(RelationSchema),
338
+ watermark: z.string().min(1).max(64).nullable(),
339
+ /**
340
+ * §9.8's "contexto adicional" — the author's own words, present ONLY when this
341
+ * assignment belongs to an appeal revision and the author supplied any. Optional
342
+ * rather than nullable so a first-instance panel receives no such key at all: a
343
+ * `null` would let a screen infer "this is an appeal" from the field existing.
344
+ *
345
+ * `unverified` is a constant `true` for the same reason it is on an allegation —
346
+ * this is a claim by an interested party, not a finding, and the flag is what
347
+ * makes a screen say so.
348
+ *
349
+ * What this shape deliberately CANNOT carry is everything else about the appeal.
350
+ * Not the reason code, which is an argument about the verdict and would anchor
351
+ * the panel against §9.1's list. Not the superseded decision, its outcome, its
352
+ * findings or its jury — that is §9.8's blindness rule. Not the threshold this
353
+ * panel is held to, which is a property of the count and not of the material. A
354
+ * reviewer can tell they are looking at a contested case, because somebody is
355
+ * contesting it in their own words; they cannot tell what anybody concluded. The
356
+ * absence of those fields is the enforcement, and `.strict()` is what makes a
357
+ * server that starts sending one a refusal rather than a screen.
358
+ */
359
+ authorContext: z
360
+ .strictObject({
361
+ unverified: z.literal(true),
362
+ statement: z.string().min(1),
363
+ /**
364
+ * The same shapes `AppealAuthorContextSchema` stores, reused rather than
365
+ * restated: `resourceIds` point at material already in the case snapshot,
366
+ * and `fields` is §9.8's "evidencia estructurada" as a flat bag of scalars.
367
+ * Restating them as some reviewer-shaped variant would need a translation
368
+ * step, and a translation step between two declarations of one shape is how
369
+ * the drift this file exists to end got started.
370
+ */
371
+ resourceIds: z.array(ResourceIdSchema).optional(),
372
+ fields: MetadataBagSchema.optional(),
373
+ })
374
+ .optional(),
375
+ });
376
+ /**
377
+ * What `POST /v1/reviewer/assignments/next` returns.
378
+ *
379
+ * The token is here and on no other response, because it is handed over exactly
380
+ * once and only its hash is stored (§8.7). Every later call on this assignment
381
+ * presents it in `x-assignment-token`.
382
+ */
383
+ export const IssuedAssignmentPackageSchema = AssignmentPackageSchema.extend({
384
+ token: z.string().min(1).max(128),
385
+ });
386
+ // --- the reviewer's own profile ----------------------------------------------
387
+ export const ReviewerEligibilityRequirementSchema = z.strictObject({
388
+ id: ReviewerEligibilityRequirementIdSchema,
389
+ met: z.boolean(),
390
+ });
391
+ /**
392
+ * §4.1's "Fiabilidad" — the reviewer's OWN standing in one category.
393
+ *
394
+ * Per category and not per (category, language): reliability is seeded by
395
+ * calibration and moved by gold cases and audits, none of which are measured per
396
+ * language, so a per-language figure would be the same number repeated. §4.1 asks
397
+ * for both axes and this is the honest half of it.
398
+ *
399
+ * It is never anybody else's figure. §9.1 forbids a reviewer seeing another
400
+ * person's reputation, and no shape on this surface could carry one.
401
+ */
402
+ export const ReviewerCategoryStandingSchema = z.strictObject({
403
+ category: TaxonomyFamilySchema,
404
+ reliability: UnitIntervalSchema,
405
+ specialist: z.boolean(),
406
+ });
407
+ /**
408
+ * §13.7's exposure and rest, as numbers rather than as a verdict.
409
+ *
410
+ * `breakRequiredUntil` is the sensitive-material rest of the backend's
411
+ * `eligibility.ts`: after `SENSITIVE_EXPOSURE_MAX` sensitive cases inside
412
+ * `SENSITIVE_EXPOSURE_WINDOW_HOURS`, the oldest of them leaving the window is
413
+ * when the reviewer may be drawn for sensitive material again. It rests only the
414
+ * SENSITIVE route — somebody who has worked through several distressing cases can
415
+ * still judge a spam report — so it is not a blanket block, and a screen showing
416
+ * it has to say which route it applies to.
417
+ */
418
+ export const ReviewerExposureViewSchema = z.strictObject({
419
+ reviewedToday: z.number().int().nonnegative(),
420
+ dailyLimit: z.number().int().positive(),
421
+ openAssignments: z.number().int().nonnegative(),
422
+ maxOpenAssignments: z.number().int().positive(),
423
+ /** ISO instant, or null when no rest is being enforced. */
424
+ breakRequiredUntil: TimestampSchema.nullable(),
425
+ });
426
+ /**
427
+ * §13.7 — consent, per category and revocable at any moment.
428
+ *
429
+ * `maxSensitivity` lives here rather than in preferences because it IS consent:
430
+ * the ceiling of what this person agreed to be shown. Keeping a second copy of
431
+ * `sensitiveCategories` under preferences — which is what the app used to declare
432
+ * — guarantees two fields that can disagree about the same fact.
433
+ */
434
+ export const ReviewerConsentViewSchema = z.strictObject({
435
+ /** ISO instant the reviewer accepted the reviewing rules, or null. */
436
+ rulesAcceptedAt: TimestampSchema.nullable(),
437
+ /** §8.2's age compatibility, as the one bit the routing needs (§13.5). */
438
+ ageConfirmed: z.boolean(),
439
+ maxSensitivity: ReviewerSensitivityClassSchema,
440
+ sensitiveCategories: z.array(TaxonomyFamilySchema),
441
+ });
442
+ export const ReviewerPreferencesViewSchema = z.strictObject({
443
+ /** BCP-47 primary subtags the reviewer reads. */
444
+ languages: z.array(z.string().min(2).max(16)),
445
+ categories: z.array(TaxonomyFamilySchema),
446
+ dailyLimit: z.number().int().positive(),
447
+ /** False means this reviewer is in no draw at all — §4.1's immediate exit. */
448
+ availableForAssignment: z.boolean(),
449
+ });
450
+ /**
451
+ * `GET /v1/reviewer/profile` (§10.3: "eligibility, categories and PRIVATE
452
+ * reliability").
453
+ *
454
+ * Private meaning shown to its owner and to nobody else. What the document holds
455
+ * and this does not: `oxyUserId` (§8.7 keeps the identity and the reviewer id
456
+ * apart), `samplingKey` (publishing it would let somebody reason about when they
457
+ * are likely to be considered), `personhoodConfidence` (the threshold is what
458
+ * matters; a bare number invites optimising a figure whose inputs are invisible),
459
+ * and the anti-abuse signals.
460
+ */
461
+ export const ReviewerProfileViewSchema = z.strictObject({
462
+ reviewerId: IdentifierSchema,
463
+ state: ReviewerStateSchema,
464
+ eligibility: z.array(ReviewerEligibilityRequirementSchema),
465
+ standings: z.array(ReviewerCategoryStandingSchema),
466
+ completedReviewCount: z.number().int().nonnegative(),
467
+ preferences: ReviewerPreferencesViewSchema,
468
+ consent: ReviewerConsentViewSchema,
469
+ exposure: ReviewerExposureViewSchema,
470
+ });
471
+ /**
472
+ * The body of `POST /v1/reviewer/preferences` (§10.3).
473
+ *
474
+ * This is also §4.1's onboarding submission. There is no
475
+ * `POST /v1/reviewer/onboarding`: §10.3's route table has no such endpoint, and
476
+ * everything the onboarding screen collects — languages, categories, sensitive
477
+ * consent, age — is precisely what §10.3 says this route updates. Rules
478
+ * acceptance is the one thing that had no home, so it is a field here.
479
+ *
480
+ * `.strict()` matters more here than anywhere else on this surface. `state`,
481
+ * `personhoodConfidence`, `reliabilityByCategory` and `completedReviewCount` are
482
+ * the fields that decide who sits on a jury, and a lenient schema plus a
483
+ * spread-based update is exactly how a reviewer would promote themselves. The
484
+ * schema refuses unknown keys and the service takes named arguments, so there are
485
+ * two independent reasons it cannot happen.
486
+ *
487
+ * Every field is optional and at least one must be present: a partial update is
488
+ * the normal case (the wellbeing screen changes one toggle), and an empty body is
489
+ * a mistake worth naming rather than a no-op worth accepting.
490
+ */
491
+ export const ReviewerPreferencesUpdateSchema = z
492
+ .strictObject({
493
+ languages: z.array(z.string().min(2).max(16)).max(20).optional(),
494
+ categories: z.array(TaxonomyFamilySchema).max(TAXONOMY_FAMILIES.length).optional(),
495
+ /** §13.7: acceptance is recorded once and is never revoked to `false` here. */
496
+ rulesAccepted: z.literal(true).optional(),
497
+ isAdult: z.boolean().optional(),
498
+ available: z.boolean().optional(),
499
+ dailyReviewLimit: z.number().int().min(1).max(REVIEWER_DAILY_LIMIT_MAX).optional(),
500
+ maxSensitivity: ReviewerSensitivityClassSchema.optional(),
501
+ consentedSensitiveCategories: z
502
+ .array(TaxonomyFamilySchema)
503
+ .max(TAXONOMY_FAMILIES.length)
504
+ .optional(),
505
+ declaredConflictApplications: z.array(z.string().min(1).max(64)).max(50).optional(),
506
+ principalLinks: z
507
+ .array(z.strictObject({
508
+ applicationId: z.string().min(1).max(64),
509
+ externalPrincipalId: z.string().min(1).max(256),
510
+ }))
511
+ .max(50)
512
+ .optional(),
513
+ })
514
+ .refine((value) => Object.keys(value).length > 0, {
515
+ message: 'a preferences update must change at least one field',
516
+ });
517
+ // --- training and calibration ------------------------------------------------
518
+ /** `GET /v1/reviewer/training` (§10.3: "list modules and calibration"). */
519
+ export const ReviewerTrainingViewSchema = z.strictObject({
520
+ modules: z.array(z.strictObject({
521
+ moduleId: z.string().min(1).max(64),
522
+ title: z.string().min(1).max(200),
523
+ families: z.array(TaxonomyFamilySchema),
524
+ completed: z.boolean(),
525
+ })),
526
+ trainingComplete: z.boolean(),
527
+ /**
528
+ * The items to answer: `itemId` and `text`, and nothing else.
529
+ *
530
+ * A calibration that hands back `expectedViolation` or `expectedCode` is one
531
+ * everybody passes on the second attempt, which measures attendance rather than
532
+ * judgement.
533
+ */
534
+ calibrationItems: z.array(z.strictObject({ itemId: z.string().min(1).max(64), text: z.string().min(1) })),
535
+ calibrationOpen: z.boolean(),
536
+ /** ISO instant, or null when never passed. */
537
+ calibrationPassedAt: TimestampSchema.nullable(),
538
+ /** ISO instant after which calibration lapses (§8.2), or null. */
539
+ calibrationCurrentUntil: TimestampSchema.nullable(),
540
+ calibrationScore: UnitIntervalSchema.nullable(),
541
+ calibrationAttempts: z.number().int().nonnegative(),
542
+ /** The score a pass requires, so the app does not restate it. */
543
+ calibrationPassScore: UnitIntervalSchema,
544
+ });
545
+ /** The body of `POST /v1/reviewer/training/calibration`. */
546
+ export const ReviewerCalibrationSubmissionSchema = z.strictObject({
547
+ answers: z
548
+ .array(z.strictObject({
549
+ itemId: z.string().min(1).max(64),
550
+ violation: z.boolean(),
551
+ code: TaxonomyCodeSchema.optional(),
552
+ }))
553
+ .min(1)
554
+ .max(64),
555
+ });
556
+ /**
557
+ * What a graded attempt reports back.
558
+ *
559
+ * The score and which items were wrong, never which answer was right — see
560
+ * `calibrationItems` above.
561
+ */
562
+ export const ReviewerCalibrationResultViewSchema = z.strictObject({
563
+ passed: z.boolean(),
564
+ score: UnitIntervalSchema,
565
+ incorrectItemIds: z.array(z.string().min(1).max(64)),
566
+ state: ReviewerStateSchema,
567
+ });
568
+ // --- history -----------------------------------------------------------------
569
+ export const REVIEW_HISTORY_PAGE_SIZE_MAX = 50;
570
+ export const REVIEW_HISTORY_PAGE_SIZE_DEFAULT = 20;
571
+ /**
572
+ * §4.1's "Historial" — one completed review as its author may see it back.
573
+ *
574
+ * `outcome` is the reviewer's OWN submitted outcome. `decision` is populated only
575
+ * once a decision has been PUBLISHED for the revision this reviewer judged, and
576
+ * carries the outcome and the moment and nothing else — no agreement figure, no
577
+ * jury size, no vote count, no findings. §4.1 asks the history to show "results
578
+ * that may already be revealed"; §9.1 forbids previous votes and partial results.
579
+ * Both hold: a published decision is not partial, and an agreement ratio IS a
580
+ * tally, so it has no field here rather than merely being left unset.
581
+ */
582
+ export const ReviewHistoryEntrySchema = z.strictObject({
583
+ reviewId: IdentifierSchema,
584
+ /** ISO instant. */
585
+ submittedAt: TimestampSchema,
586
+ families: z.array(TaxonomyFamilySchema),
587
+ language: LanguageTagSchema.nullable(),
588
+ outcome: ReviewOutcomeSchema,
589
+ decision: z
590
+ .strictObject({ outcome: DecisionOutcomeSchema, publishedAt: TimestampSchema })
591
+ .nullable(),
592
+ });
593
+ /** `GET /v1/reviewer/reviews`. */
594
+ export const ReviewHistoryPageSchema = z.strictObject({
595
+ entries: z.array(ReviewHistoryEntrySchema),
596
+ /** Opaque cursor for the next page, or null when the list is exhausted. */
597
+ nextCursor: z.string().min(1).max(64).nullable(),
598
+ });
599
+ /**
600
+ * The query of `GET /v1/reviewer/reviews`.
601
+ *
602
+ * The cursor is opaque to the client and meaningful to the server, which is what
603
+ * lets the pagination change without a client change. It is not an offset: a
604
+ * reviewer submitting a review between two pages would shift every offset by one
605
+ * and silently skip an entry — in a list whose only purpose is somebody checking
606
+ * their own record.
607
+ */
608
+ export const ReviewHistoryQuerySchema = z.strictObject({
609
+ cursor: z.string().min(1).max(64).optional(),
610
+ limit: z.coerce.number().int().min(1).max(REVIEW_HISTORY_PAGE_SIZE_MAX).optional(),
611
+ });
612
+ //# sourceMappingURL=reviewer-surface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviewer-surface.js","sourceRoot":"","sources":["../../src/reviewer-surface.ts"],"names":[],"mappings":"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"}