@growth-labs/cms 0.5.29 → 0.5.31

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 (151) hide show
  1. package/dist/engine/foundry-dispatch.d.ts +7 -2
  2. package/dist/engine/foundry-dispatch.d.ts.map +1 -1
  3. package/dist/engine/foundry-dispatch.js +24 -6
  4. package/dist/engine/foundry-dispatch.js.map +1 -1
  5. package/dist/engine/fronts-publish-intent.d.ts +174 -0
  6. package/dist/engine/fronts-publish-intent.d.ts.map +1 -0
  7. package/dist/engine/fronts-publish-intent.js +352 -0
  8. package/dist/engine/fronts-publish-intent.js.map +1 -0
  9. package/dist/engine/fronts-publish.d.ts +80 -0
  10. package/dist/engine/fronts-publish.d.ts.map +1 -0
  11. package/dist/engine/fronts-publish.js +286 -0
  12. package/dist/engine/fronts-publish.js.map +1 -0
  13. package/dist/engine/index.d.ts +7 -0
  14. package/dist/engine/index.d.ts.map +1 -1
  15. package/dist/engine/index.js +10 -0
  16. package/dist/engine/index.js.map +1 -1
  17. package/dist/engine/publication-continuity.d.ts +77 -0
  18. package/dist/engine/publication-continuity.d.ts.map +1 -0
  19. package/dist/engine/publication-continuity.js +94 -0
  20. package/dist/engine/publication-continuity.js.map +1 -0
  21. package/dist/engine/publication-receipt/canonical-json.d.ts +34 -0
  22. package/dist/engine/publication-receipt/canonical-json.d.ts.map +1 -0
  23. package/dist/engine/publication-receipt/canonical-json.js +100 -0
  24. package/dist/engine/publication-receipt/canonical-json.js.map +1 -0
  25. package/dist/engine/publication-receipt/receipt.d.ts +316 -0
  26. package/dist/engine/publication-receipt/receipt.d.ts.map +1 -0
  27. package/dist/engine/publication-receipt/receipt.js +131 -0
  28. package/dist/engine/publication-receipt/receipt.js.map +1 -0
  29. package/dist/engine/publication-receipt/signature.d.ts +36 -0
  30. package/dist/engine/publication-receipt/signature.d.ts.map +1 -0
  31. package/dist/engine/publication-receipt/signature.js +79 -0
  32. package/dist/engine/publication-receipt/signature.js.map +1 -0
  33. package/dist/engine/publication.d.ts.map +1 -1
  34. package/dist/engine/publication.js +2 -0
  35. package/dist/engine/publication.js.map +1 -1
  36. package/dist/engine/publisher.d.ts.map +1 -1
  37. package/dist/engine/publisher.js +23 -1
  38. package/dist/engine/publisher.js.map +1 -1
  39. package/dist/engine/source-sections.d.ts +20 -0
  40. package/dist/engine/source-sections.d.ts.map +1 -0
  41. package/dist/engine/source-sections.js +130 -0
  42. package/dist/engine/source-sections.js.map +1 -0
  43. package/dist/engine/validator/checks/source-section-diagnostics.d.ts +7 -0
  44. package/dist/engine/validator/checks/source-section-diagnostics.d.ts.map +1 -0
  45. package/dist/engine/validator/checks/source-section-diagnostics.js +120 -0
  46. package/dist/engine/validator/checks/source-section-diagnostics.js.map +1 -0
  47. package/dist/engine/validator/index.d.ts +10 -0
  48. package/dist/engine/validator/index.d.ts.map +1 -1
  49. package/dist/engine/validator/index.js +4 -0
  50. package/dist/engine/validator/index.js.map +1 -1
  51. package/dist/engine/validator/types.d.ts +1 -1
  52. package/dist/engine/validator/types.d.ts.map +1 -1
  53. package/dist/engine/validator/types.js +10 -0
  54. package/dist/engine/validator/types.js.map +1 -1
  55. package/dist/integration/index.d.ts.map +1 -1
  56. package/dist/integration/index.js +10 -0
  57. package/dist/integration/index.js.map +1 -1
  58. package/dist/providers/types.d.ts +1 -0
  59. package/dist/providers/types.d.ts.map +1 -1
  60. package/dist/routes/content.d.ts.map +1 -1
  61. package/dist/routes/content.js +22 -2
  62. package/dist/routes/content.js.map +1 -1
  63. package/dist/routes/fronts-publish.d.ts +10 -0
  64. package/dist/routes/fronts-publish.d.ts.map +1 -0
  65. package/dist/routes/fronts-publish.js +250 -0
  66. package/dist/routes/fronts-publish.js.map +1 -0
  67. package/dist/routes/index.d.ts +3 -0
  68. package/dist/routes/index.d.ts.map +1 -1
  69. package/dist/routes/index.js +4 -0
  70. package/dist/routes/index.js.map +1 -1
  71. package/dist/routes/surveys.d.ts.map +1 -1
  72. package/dist/routes/surveys.js +13 -1
  73. package/dist/routes/surveys.js.map +1 -1
  74. package/dist/schema/insights-ingest.d.ts +28 -28
  75. package/dist/schema/layout.d.ts +2 -2
  76. package/dist/schema/migrations.d.ts.map +1 -1
  77. package/dist/schema/migrations.js +36 -0
  78. package/dist/schema/migrations.js.map +1 -1
  79. package/dist/schema/portable-text.d.ts +2 -2
  80. package/dist/schema/tables.d.ts +1 -1
  81. package/dist/schema/tables.d.ts.map +1 -1
  82. package/dist/schema/tables.js +2 -0
  83. package/dist/schema/tables.js.map +1 -1
  84. package/dist/schema/types.d.ts +59 -0
  85. package/dist/schema/types.d.ts.map +1 -1
  86. package/dist/schema/types.js.map +1 -1
  87. package/dist/surveys/access.d.ts +2 -0
  88. package/dist/surveys/access.d.ts.map +1 -1
  89. package/dist/surveys/access.js +7 -0
  90. package/dist/surveys/access.js.map +1 -1
  91. package/dist/surveys/errors.d.ts +8 -0
  92. package/dist/surveys/errors.d.ts.map +1 -1
  93. package/dist/surveys/errors.js +12 -0
  94. package/dist/surveys/errors.js.map +1 -1
  95. package/dist/surveys/schema.d.ts +129 -54
  96. package/dist/surveys/schema.d.ts.map +1 -1
  97. package/dist/surveys/schema.js +45 -0
  98. package/dist/surveys/schema.js.map +1 -1
  99. package/dist/ui/api/fronts/publish-callback.d.ts +3 -0
  100. package/dist/ui/api/fronts/publish-callback.d.ts.map +1 -0
  101. package/dist/ui/api/fronts/publish-callback.js +8 -0
  102. package/dist/ui/api/fronts/publish-callback.js.map +1 -0
  103. package/dist/ui/api/fronts/schedule.d.ts +3 -0
  104. package/dist/ui/api/fronts/schedule.d.ts.map +1 -0
  105. package/dist/ui/api/fronts/schedule.js +8 -0
  106. package/dist/ui/api/fronts/schedule.js.map +1 -0
  107. package/dist/ui/editor/ContentForm.d.ts.map +1 -1
  108. package/dist/ui/editor/ContentForm.js +52 -1
  109. package/dist/ui/editor/ContentForm.js.map +1 -1
  110. package/dist/ui/editor/body-warnings.d.ts +27 -0
  111. package/dist/ui/editor/body-warnings.d.ts.map +1 -0
  112. package/dist/ui/editor/body-warnings.js +58 -0
  113. package/dist/ui/editor/body-warnings.js.map +1 -0
  114. package/dist/ui/screens/SurveyResponsesScreen.d.ts +7 -1
  115. package/dist/ui/screens/SurveyResponsesScreen.d.ts.map +1 -1
  116. package/dist/ui/screens/SurveyResponsesScreen.js +141 -32
  117. package/dist/ui/screens/SurveyResponsesScreen.js.map +1 -1
  118. package/migrations/0026_fronts_publish.sql +31 -0
  119. package/migrations/0027_fronts_publish_intent.sql +44 -0
  120. package/package.json +1 -1
  121. package/src/engine/foundry-dispatch.ts +22 -6
  122. package/src/engine/fronts-publish-intent.ts +676 -0
  123. package/src/engine/fronts-publish.ts +417 -0
  124. package/src/engine/index.ts +60 -0
  125. package/src/engine/publication-continuity.ts +140 -0
  126. package/src/engine/publication-receipt/canonical-json.ts +123 -0
  127. package/src/engine/publication-receipt/receipt.ts +160 -0
  128. package/src/engine/publication-receipt/signature.ts +112 -0
  129. package/src/engine/publication.ts +2 -0
  130. package/src/engine/publisher.ts +23 -1
  131. package/src/engine/source-sections.ts +153 -0
  132. package/src/engine/validator/checks/source-section-diagnostics.ts +187 -0
  133. package/src/engine/validator/index.ts +12 -0
  134. package/src/engine/validator/types.ts +19 -0
  135. package/src/integration/index.ts +10 -0
  136. package/src/providers/types.ts +1 -1
  137. package/src/routes/content.ts +23 -2
  138. package/src/routes/fronts-publish.ts +292 -0
  139. package/src/routes/index.ts +8 -0
  140. package/src/routes/surveys.ts +12 -1
  141. package/src/schema/migrations.ts +36 -0
  142. package/src/schema/tables.ts +2 -0
  143. package/src/schema/types.ts +61 -0
  144. package/src/surveys/access.ts +9 -0
  145. package/src/surveys/errors.ts +12 -0
  146. package/src/surveys/schema.ts +47 -0
  147. package/src/ui/api/fronts/publish-callback.ts +18 -0
  148. package/src/ui/api/fronts/schedule.ts +18 -0
  149. package/src/ui/editor/ContentForm.tsx +93 -0
  150. package/src/ui/editor/body-warnings.ts +78 -0
  151. package/src/ui/screens/SurveyResponsesScreen.tsx +369 -121
@@ -18,8 +18,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
18
18
  answerCount: z.ZodNumber;
19
19
  }, "strict", z.ZodTypeAny, {
20
20
  options: string[];
21
- id: string;
22
21
  kind: "single_choice";
22
+ id: string;
23
23
  counts: Record<string, number>;
24
24
  average: null;
25
25
  distribution: null;
@@ -30,8 +30,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
30
30
  answerCount: number;
31
31
  }, {
32
32
  options: string[];
33
- id: string;
34
33
  kind: "single_choice";
34
+ id: string;
35
35
  counts: Record<string, number>;
36
36
  average: null;
37
37
  distribution: null;
@@ -54,8 +54,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
54
54
  answerCount: z.ZodNumber;
55
55
  }, "strict", z.ZodTypeAny, {
56
56
  options: string[];
57
- id: string;
58
57
  kind: "multi_choice";
58
+ id: string;
59
59
  counts: Record<string, number>;
60
60
  average: null;
61
61
  distribution: null;
@@ -66,8 +66,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
66
66
  answerCount: number;
67
67
  }, {
68
68
  options: string[];
69
- id: string;
70
69
  kind: "multi_choice";
70
+ id: string;
71
71
  counts: Record<string, number>;
72
72
  average: null;
73
73
  distribution: null;
@@ -108,8 +108,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
108
108
  min: number;
109
109
  max: number;
110
110
  };
111
- id: string;
112
111
  kind: "scale";
112
+ id: string;
113
113
  counts: null;
114
114
  average: number | null;
115
115
  distribution: Record<string, number>;
@@ -123,8 +123,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
123
123
  min: number;
124
124
  max: number;
125
125
  };
126
- id: string;
127
126
  kind: "scale";
127
+ id: string;
128
128
  counts: null;
129
129
  average: number | null;
130
130
  distribution: Record<string, number>;
@@ -155,8 +155,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
155
155
  options: {
156
156
  max_length: number;
157
157
  };
158
- id: string;
159
158
  kind: "text";
159
+ id: string;
160
160
  counts: null;
161
161
  average: null;
162
162
  distribution: null;
@@ -169,8 +169,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
169
169
  options: {
170
170
  max_length: number;
171
171
  };
172
- id: string;
173
172
  kind: "text";
173
+ id: string;
174
174
  counts: null;
175
175
  average: null;
176
176
  distribution: null;
@@ -181,8 +181,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
181
181
  answerCount: number;
182
182
  }>]>, {
183
183
  options: string[];
184
- id: string;
185
184
  kind: "single_choice";
185
+ id: string;
186
186
  counts: Record<string, number>;
187
187
  average: null;
188
188
  distribution: null;
@@ -193,8 +193,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
193
193
  answerCount: number;
194
194
  } | {
195
195
  options: string[];
196
- id: string;
197
196
  kind: "multi_choice";
197
+ id: string;
198
198
  counts: Record<string, number>;
199
199
  average: null;
200
200
  distribution: null;
@@ -208,8 +208,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
208
208
  min: number;
209
209
  max: number;
210
210
  };
211
- id: string;
212
211
  kind: "scale";
212
+ id: string;
213
213
  counts: null;
214
214
  average: number | null;
215
215
  distribution: Record<string, number>;
@@ -222,8 +222,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
222
222
  options: {
223
223
  max_length: number;
224
224
  };
225
- id: string;
226
225
  kind: "text";
226
+ id: string;
227
227
  counts: null;
228
228
  average: null;
229
229
  distribution: null;
@@ -234,8 +234,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
234
234
  answerCount: number;
235
235
  }, {
236
236
  options: string[];
237
- id: string;
238
237
  kind: "single_choice";
238
+ id: string;
239
239
  counts: Record<string, number>;
240
240
  average: null;
241
241
  distribution: null;
@@ -246,8 +246,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
246
246
  answerCount: number;
247
247
  } | {
248
248
  options: string[];
249
- id: string;
250
249
  kind: "multi_choice";
250
+ id: string;
251
251
  counts: Record<string, number>;
252
252
  average: null;
253
253
  distribution: null;
@@ -261,8 +261,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
261
261
  min: number;
262
262
  max: number;
263
263
  };
264
- id: string;
265
264
  kind: "scale";
265
+ id: string;
266
266
  counts: null;
267
267
  average: number | null;
268
268
  distribution: Record<string, number>;
@@ -275,8 +275,8 @@ export declare const SurveyQuestionSchema: z.ZodEffects<z.ZodDiscriminatedUnion<
275
275
  options: {
276
276
  max_length: number;
277
277
  };
278
- id: string;
279
278
  kind: "text";
279
+ id: string;
280
280
  counts: null;
281
281
  average: null;
282
282
  distribution: null;
@@ -317,8 +317,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
317
317
  answerCount: z.ZodNumber;
318
318
  }, "strict", z.ZodTypeAny, {
319
319
  options: string[];
320
- id: string;
321
320
  kind: "single_choice";
321
+ id: string;
322
322
  counts: Record<string, number>;
323
323
  average: null;
324
324
  distribution: null;
@@ -329,8 +329,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
329
329
  answerCount: number;
330
330
  }, {
331
331
  options: string[];
332
- id: string;
333
332
  kind: "single_choice";
333
+ id: string;
334
334
  counts: Record<string, number>;
335
335
  average: null;
336
336
  distribution: null;
@@ -353,8 +353,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
353
353
  answerCount: z.ZodNumber;
354
354
  }, "strict", z.ZodTypeAny, {
355
355
  options: string[];
356
- id: string;
357
356
  kind: "multi_choice";
357
+ id: string;
358
358
  counts: Record<string, number>;
359
359
  average: null;
360
360
  distribution: null;
@@ -365,8 +365,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
365
365
  answerCount: number;
366
366
  }, {
367
367
  options: string[];
368
- id: string;
369
368
  kind: "multi_choice";
369
+ id: string;
370
370
  counts: Record<string, number>;
371
371
  average: null;
372
372
  distribution: null;
@@ -407,8 +407,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
407
407
  min: number;
408
408
  max: number;
409
409
  };
410
- id: string;
411
410
  kind: "scale";
411
+ id: string;
412
412
  counts: null;
413
413
  average: number | null;
414
414
  distribution: Record<string, number>;
@@ -422,8 +422,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
422
422
  min: number;
423
423
  max: number;
424
424
  };
425
- id: string;
426
425
  kind: "scale";
426
+ id: string;
427
427
  counts: null;
428
428
  average: number | null;
429
429
  distribution: Record<string, number>;
@@ -454,8 +454,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
454
454
  options: {
455
455
  max_length: number;
456
456
  };
457
- id: string;
458
457
  kind: "text";
458
+ id: string;
459
459
  counts: null;
460
460
  average: null;
461
461
  distribution: null;
@@ -468,8 +468,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
468
468
  options: {
469
469
  max_length: number;
470
470
  };
471
- id: string;
472
471
  kind: "text";
472
+ id: string;
473
473
  counts: null;
474
474
  average: null;
475
475
  distribution: null;
@@ -480,8 +480,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
480
480
  answerCount: number;
481
481
  }>]>, {
482
482
  options: string[];
483
- id: string;
484
483
  kind: "single_choice";
484
+ id: string;
485
485
  counts: Record<string, number>;
486
486
  average: null;
487
487
  distribution: null;
@@ -492,8 +492,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
492
492
  answerCount: number;
493
493
  } | {
494
494
  options: string[];
495
- id: string;
496
495
  kind: "multi_choice";
496
+ id: string;
497
497
  counts: Record<string, number>;
498
498
  average: null;
499
499
  distribution: null;
@@ -507,8 +507,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
507
507
  min: number;
508
508
  max: number;
509
509
  };
510
- id: string;
511
510
  kind: "scale";
511
+ id: string;
512
512
  counts: null;
513
513
  average: number | null;
514
514
  distribution: Record<string, number>;
@@ -521,8 +521,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
521
521
  options: {
522
522
  max_length: number;
523
523
  };
524
- id: string;
525
524
  kind: "text";
525
+ id: string;
526
526
  counts: null;
527
527
  average: null;
528
528
  distribution: null;
@@ -533,8 +533,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
533
533
  answerCount: number;
534
534
  }, {
535
535
  options: string[];
536
- id: string;
537
536
  kind: "single_choice";
537
+ id: string;
538
538
  counts: Record<string, number>;
539
539
  average: null;
540
540
  distribution: null;
@@ -545,8 +545,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
545
545
  answerCount: number;
546
546
  } | {
547
547
  options: string[];
548
- id: string;
549
548
  kind: "multi_choice";
549
+ id: string;
550
550
  counts: Record<string, number>;
551
551
  average: null;
552
552
  distribution: null;
@@ -560,8 +560,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
560
560
  min: number;
561
561
  max: number;
562
562
  };
563
- id: string;
564
563
  kind: "scale";
564
+ id: string;
565
565
  counts: null;
566
566
  average: number | null;
567
567
  distribution: Record<string, number>;
@@ -574,8 +574,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
574
574
  options: {
575
575
  max_length: number;
576
576
  };
577
- id: string;
578
577
  kind: "text";
578
+ id: string;
579
579
  counts: null;
580
580
  average: null;
581
581
  distribution: null;
@@ -591,18 +591,57 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
591
591
  submittedAt: z.ZodString;
592
592
  respondentSegment: z.ZodEnum<["member", "non_member", "unknown"]>;
593
593
  anonymous: z.ZodBoolean;
594
+ contactId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
595
+ respondent: z.ZodOptional<z.ZodNullable<z.ZodObject<{
596
+ label: z.ZodEffects<z.ZodString, string, string>;
597
+ detail: z.ZodOptional<z.ZodNullable<z.ZodString>>;
598
+ }, "strict", z.ZodTypeAny, {
599
+ label: string;
600
+ detail?: string | null | undefined;
601
+ }, {
602
+ label: string;
603
+ detail?: string | null | undefined;
604
+ }>>>;
605
+ answers: z.ZodOptional<z.ZodArray<z.ZodObject<{
606
+ questionId: z.ZodString;
607
+ value: z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodArray<z.ZodString, "many">]>;
608
+ }, "strict", z.ZodTypeAny, {
609
+ value: string | number | string[];
610
+ questionId: string;
611
+ }, {
612
+ value: string | number | string[];
613
+ questionId: string;
614
+ }>, "many">>;
594
615
  }, "strict", z.ZodTypeAny, {
595
- id: string;
596
616
  channel: "email" | "site" | "direct";
617
+ id: string;
597
618
  submittedAt: string;
598
619
  respondentSegment: "member" | "non_member" | "unknown";
599
620
  anonymous: boolean;
621
+ contactId?: string | null | undefined;
622
+ respondent?: {
623
+ label: string;
624
+ detail?: string | null | undefined;
625
+ } | null | undefined;
626
+ answers?: {
627
+ value: string | number | string[];
628
+ questionId: string;
629
+ }[] | undefined;
600
630
  }, {
601
- id: string;
602
631
  channel: "email" | "site" | "direct";
632
+ id: string;
603
633
  submittedAt: string;
604
634
  respondentSegment: "member" | "non_member" | "unknown";
605
635
  anonymous: boolean;
636
+ contactId?: string | null | undefined;
637
+ respondent?: {
638
+ label: string;
639
+ detail?: string | null | undefined;
640
+ } | null | undefined;
641
+ answers?: {
642
+ value: string | number | string[];
643
+ questionId: string;
644
+ }[] | undefined;
606
645
  }>, "many">;
607
646
  freeText: z.ZodArray<z.ZodObject<{
608
647
  questionId: z.ZodString;
@@ -629,8 +668,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
629
668
  };
630
669
  questions: ({
631
670
  options: string[];
632
- id: string;
633
671
  kind: "single_choice";
672
+ id: string;
634
673
  counts: Record<string, number>;
635
674
  average: null;
636
675
  distribution: null;
@@ -641,8 +680,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
641
680
  answerCount: number;
642
681
  } | {
643
682
  options: string[];
644
- id: string;
645
683
  kind: "multi_choice";
684
+ id: string;
646
685
  counts: Record<string, number>;
647
686
  average: null;
648
687
  distribution: null;
@@ -656,8 +695,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
656
695
  min: number;
657
696
  max: number;
658
697
  };
659
- id: string;
660
698
  kind: "scale";
699
+ id: string;
661
700
  counts: null;
662
701
  average: number | null;
663
702
  distribution: Record<string, number>;
@@ -670,8 +709,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
670
709
  options: {
671
710
  max_length: number;
672
711
  };
673
- id: string;
674
712
  kind: "text";
713
+ id: string;
675
714
  counts: null;
676
715
  average: null;
677
716
  distribution: null;
@@ -682,11 +721,20 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
682
721
  answerCount: number;
683
722
  })[];
684
723
  responses: {
685
- id: string;
686
724
  channel: "email" | "site" | "direct";
725
+ id: string;
687
726
  submittedAt: string;
688
727
  respondentSegment: "member" | "non_member" | "unknown";
689
728
  anonymous: boolean;
729
+ contactId?: string | null | undefined;
730
+ respondent?: {
731
+ label: string;
732
+ detail?: string | null | undefined;
733
+ } | null | undefined;
734
+ answers?: {
735
+ value: string | number | string[];
736
+ questionId: string;
737
+ }[] | undefined;
690
738
  }[];
691
739
  freeText: {
692
740
  value: string;
@@ -703,8 +751,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
703
751
  };
704
752
  questions: ({
705
753
  options: string[];
706
- id: string;
707
754
  kind: "single_choice";
755
+ id: string;
708
756
  counts: Record<string, number>;
709
757
  average: null;
710
758
  distribution: null;
@@ -715,8 +763,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
715
763
  answerCount: number;
716
764
  } | {
717
765
  options: string[];
718
- id: string;
719
766
  kind: "multi_choice";
767
+ id: string;
720
768
  counts: Record<string, number>;
721
769
  average: null;
722
770
  distribution: null;
@@ -730,8 +778,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
730
778
  min: number;
731
779
  max: number;
732
780
  };
733
- id: string;
734
781
  kind: "scale";
782
+ id: string;
735
783
  counts: null;
736
784
  average: number | null;
737
785
  distribution: Record<string, number>;
@@ -744,8 +792,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
744
792
  options: {
745
793
  max_length: number;
746
794
  };
747
- id: string;
748
795
  kind: "text";
796
+ id: string;
749
797
  counts: null;
750
798
  average: null;
751
799
  distribution: null;
@@ -756,11 +804,20 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
756
804
  answerCount: number;
757
805
  })[];
758
806
  responses: {
759
- id: string;
760
807
  channel: "email" | "site" | "direct";
808
+ id: string;
761
809
  submittedAt: string;
762
810
  respondentSegment: "member" | "non_member" | "unknown";
763
811
  anonymous: boolean;
812
+ contactId?: string | null | undefined;
813
+ respondent?: {
814
+ label: string;
815
+ detail?: string | null | undefined;
816
+ } | null | undefined;
817
+ answers?: {
818
+ value: string | number | string[];
819
+ questionId: string;
820
+ }[] | undefined;
764
821
  }[];
765
822
  freeText: {
766
823
  value: string;
@@ -777,8 +834,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
777
834
  };
778
835
  questions: ({
779
836
  options: string[];
780
- id: string;
781
837
  kind: "single_choice";
838
+ id: string;
782
839
  counts: Record<string, number>;
783
840
  average: null;
784
841
  distribution: null;
@@ -789,8 +846,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
789
846
  answerCount: number;
790
847
  } | {
791
848
  options: string[];
792
- id: string;
793
849
  kind: "multi_choice";
850
+ id: string;
794
851
  counts: Record<string, number>;
795
852
  average: null;
796
853
  distribution: null;
@@ -804,8 +861,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
804
861
  min: number;
805
862
  max: number;
806
863
  };
807
- id: string;
808
864
  kind: "scale";
865
+ id: string;
809
866
  counts: null;
810
867
  average: number | null;
811
868
  distribution: Record<string, number>;
@@ -818,8 +875,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
818
875
  options: {
819
876
  max_length: number;
820
877
  };
821
- id: string;
822
878
  kind: "text";
879
+ id: string;
823
880
  counts: null;
824
881
  average: null;
825
882
  distribution: null;
@@ -830,11 +887,20 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
830
887
  answerCount: number;
831
888
  })[];
832
889
  responses: {
833
- id: string;
834
890
  channel: "email" | "site" | "direct";
891
+ id: string;
835
892
  submittedAt: string;
836
893
  respondentSegment: "member" | "non_member" | "unknown";
837
894
  anonymous: boolean;
895
+ contactId?: string | null | undefined;
896
+ respondent?: {
897
+ label: string;
898
+ detail?: string | null | undefined;
899
+ } | null | undefined;
900
+ answers?: {
901
+ value: string | number | string[];
902
+ questionId: string;
903
+ }[] | undefined;
838
904
  }[];
839
905
  freeText: {
840
906
  value: string;
@@ -851,8 +917,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
851
917
  };
852
918
  questions: ({
853
919
  options: string[];
854
- id: string;
855
920
  kind: "single_choice";
921
+ id: string;
856
922
  counts: Record<string, number>;
857
923
  average: null;
858
924
  distribution: null;
@@ -863,8 +929,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
863
929
  answerCount: number;
864
930
  } | {
865
931
  options: string[];
866
- id: string;
867
932
  kind: "multi_choice";
933
+ id: string;
868
934
  counts: Record<string, number>;
869
935
  average: null;
870
936
  distribution: null;
@@ -878,8 +944,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
878
944
  min: number;
879
945
  max: number;
880
946
  };
881
- id: string;
882
947
  kind: "scale";
948
+ id: string;
883
949
  counts: null;
884
950
  average: number | null;
885
951
  distribution: Record<string, number>;
@@ -892,8 +958,8 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
892
958
  options: {
893
959
  max_length: number;
894
960
  };
895
- id: string;
896
961
  kind: "text";
962
+ id: string;
897
963
  counts: null;
898
964
  average: null;
899
965
  distribution: null;
@@ -904,11 +970,20 @@ export declare const SurveyResultsSchema: z.ZodEffects<z.ZodObject<{
904
970
  answerCount: number;
905
971
  })[];
906
972
  responses: {
907
- id: string;
908
973
  channel: "email" | "site" | "direct";
974
+ id: string;
909
975
  submittedAt: string;
910
976
  respondentSegment: "member" | "non_member" | "unknown";
911
977
  anonymous: boolean;
978
+ contactId?: string | null | undefined;
979
+ respondent?: {
980
+ label: string;
981
+ detail?: string | null | undefined;
982
+ } | null | undefined;
983
+ answers?: {
984
+ value: string | number | string[];
985
+ questionId: string;
986
+ }[] | undefined;
912
987
  }[];
913
988
  freeText: {
914
989
  value: string;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/surveys/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,oBAAoB,MAAM,CAAA;AAgBvC,eAAO,MAAM,cAAc,aAIA,CAAA;AAC3B,eAAO,MAAM,sBAAsB,aAAiB,CAAA;AAcpD,eAAO,MAAM,oBAAoB,4CAA0C,CAAA;AAC3E,eAAO,MAAM,6BAA6B,gDAA8C,CAAA;AAwFxF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0D9B,CAAA;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqH7B,CAAA;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;EAuC/B,CAAA;AAwFH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACjE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAC/D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/surveys/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,oBAAoB,MAAM,CAAA;AAgBvC,eAAO,MAAM,cAAc,aAIA,CAAA;AAC3B,eAAO,MAAM,sBAAsB,aAAiB,CAAA;AAmBpD,eAAO,MAAM,oBAAoB,4CAA0C,CAAA;AAC3E,eAAO,MAAM,6BAA6B,gDAA8C,CAAA;AAwFxF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0D9B,CAAA;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+J7B,CAAA;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;EAuC/B,CAAA;AAwFH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACjE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAC/D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA"}
@@ -27,6 +27,11 @@ const BoundedRecordIdSchema = z
27
27
  .regex(/^[A-Za-z0-9][A-Za-z0-9._:-]*$/);
28
28
  const IsoTimestampSchema = z.string().datetime({ offset: true });
29
29
  const CountSchema = z.number().int().nonnegative().max(MAX_COUNT);
30
+ const AnswerValueSchema = z.union([
31
+ z.string().max(MAX_FREE_TEXT_LENGTH),
32
+ z.number().int(),
33
+ z.array(z.string().max(MAX_OPTION_LENGTH)).max(MAX_CHOICE_OPTIONS),
34
+ ]);
30
35
  const NonemptyBoundedStringSchema = z
31
36
  .string()
32
37
  .min(1)
@@ -183,6 +188,33 @@ export const SurveyResultsSchema = z
183
188
  submittedAt: IsoTimestampSchema,
184
189
  respondentSegment: SurveyRespondentSegmentSchema,
185
190
  anonymous: z.boolean(),
191
+ // Opaque upstream contact handle. The host resolves its own member
192
+ // record from this; no email or name crosses the reporting boundary.
193
+ // Optional because the reporting upstream only emits these when the
194
+ // caller opts in. A consumer that always required them could not
195
+ // read a legacy payload, and this object is strict, so a consumer
196
+ // that never expected them discards the whole response.
197
+ contactId: BoundedRecordIdSchema.nullable().optional(),
198
+ // Host-enriched, optional. The consuming site joins contactId to its
199
+ // own member record and attaches a display label here; the reporting
200
+ // upstream never sees it. Absent means "not resolved", not "anonymous".
201
+ respondent: z
202
+ .object({
203
+ label: NonemptyBoundedStringSchema,
204
+ detail: z.string().max(MAX_OPTION_LENGTH).nullable().optional(),
205
+ })
206
+ .strict()
207
+ .nullable()
208
+ .optional(),
209
+ answers: z
210
+ .array(z
211
+ .object({
212
+ questionId: SurveyQuestionIdSchema,
213
+ value: AnswerValueSchema,
214
+ })
215
+ .strict())
216
+ .max(MAX_QUESTIONS)
217
+ .optional(),
186
218
  })
187
219
  .strict())
188
220
  .max(MAX_RESPONSES),
@@ -227,6 +259,19 @@ export const SurveyResultsSchema = z
227
259
  if (results.responses.length > results.survey.responseCount) {
228
260
  ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Response rows exceed survey total' });
229
261
  }
262
+ for (const [index, response] of results.responses.entries()) {
263
+ const seen = new Set();
264
+ for (const [answerIndex, answer] of (response.answers ?? []).entries()) {
265
+ if (seen.has(answer.questionId)) {
266
+ ctx.addIssue({
267
+ code: z.ZodIssueCode.custom,
268
+ path: ['responses', index, 'answers', answerIndex, 'questionId'],
269
+ message: 'Answers must reference distinct questions',
270
+ });
271
+ }
272
+ seen.add(answer.questionId);
273
+ }
274
+ }
230
275
  const responses = new Map();
231
276
  for (const [index, response] of results.responses.entries()) {
232
277
  if (responses.has(response.id)) {