founder-schema 0.19.0 → 0.20.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 (142) hide show
  1. package/README.md +46 -0
  2. package/dist/access/permissions.d.ts +3 -3
  3. package/dist/access/permissions.d.ts.map +1 -1
  4. package/dist/access/permissions.js.map +1 -1
  5. package/dist/core/common.d.ts +42 -15
  6. package/dist/core/common.d.ts.map +1 -1
  7. package/dist/core/common.js +58 -15
  8. package/dist/core/common.js.map +1 -1
  9. package/dist/core/deletion.d.ts +40 -0
  10. package/dist/core/deletion.d.ts.map +1 -0
  11. package/dist/core/deletion.js +39 -0
  12. package/dist/core/deletion.js.map +1 -0
  13. package/dist/domains/audit/audit.d.ts +36 -12
  14. package/dist/domains/audit/audit.d.ts.map +1 -1
  15. package/dist/domains/audit/audit.js +9 -10
  16. package/dist/domains/audit/audit.js.map +1 -1
  17. package/dist/domains/billing/billing.d.ts +29 -13
  18. package/dist/domains/billing/billing.d.ts.map +1 -1
  19. package/dist/domains/billing/billing.js +2 -3
  20. package/dist/domains/billing/billing.js.map +1 -1
  21. package/dist/domains/chat/chat.d.ts +19 -5
  22. package/dist/domains/chat/chat.d.ts.map +1 -1
  23. package/dist/domains/chat/chat.js +10 -10
  24. package/dist/domains/chat/chat.js.map +1 -1
  25. package/dist/domains/communities/communities.d.ts +95 -57
  26. package/dist/domains/communities/communities.d.ts.map +1 -1
  27. package/dist/domains/contributions/contributions.d.ts +28 -12
  28. package/dist/domains/contributions/contributions.d.ts.map +1 -1
  29. package/dist/domains/contributions/contributions.js +3 -0
  30. package/dist/domains/contributions/contributions.js.map +1 -1
  31. package/dist/domains/discover/discover.d.ts +2 -2
  32. package/dist/domains/feed/feed.d.ts +111 -63
  33. package/dist/domains/feed/feed.d.ts.map +1 -1
  34. package/dist/domains/feed/feed.js +3 -0
  35. package/dist/domains/feed/feed.js.map +1 -1
  36. package/dist/domains/location/areas.d.ts +7 -0
  37. package/dist/domains/location/areas.d.ts.map +1 -1
  38. package/dist/domains/location/areas.js +3 -0
  39. package/dist/domains/location/areas.js.map +1 -1
  40. package/dist/domains/media/media.d.ts +22 -0
  41. package/dist/domains/media/media.d.ts.map +1 -1
  42. package/dist/domains/media/media.js +20 -0
  43. package/dist/domains/media/media.js.map +1 -1
  44. package/dist/domains/members/members.d.ts +26 -9
  45. package/dist/domains/members/members.d.ts.map +1 -1
  46. package/dist/domains/members/members.js +9 -10
  47. package/dist/domains/members/members.js.map +1 -1
  48. package/dist/domains/membership/membership.d.ts +19 -0
  49. package/dist/domains/membership/membership.d.ts.map +1 -1
  50. package/dist/domains/membership/membership.js +10 -0
  51. package/dist/domains/membership/membership.js.map +1 -1
  52. package/dist/domains/moderation/moderation.d.ts +8 -2
  53. package/dist/domains/moderation/moderation.d.ts.map +1 -1
  54. package/dist/domains/moderation/moderation.js +3 -6
  55. package/dist/domains/moderation/moderation.js.map +1 -1
  56. package/dist/domains/notifications/notifications.d.ts +10 -6
  57. package/dist/domains/notifications/notifications.d.ts.map +1 -1
  58. package/dist/domains/onboarding/onboarding-answers.js +1 -1
  59. package/dist/domains/onboarding/onboarding-answers.js.map +1 -1
  60. package/dist/domains/onboarding/onboarding.d.ts +11 -10
  61. package/dist/domains/onboarding/onboarding.d.ts.map +1 -1
  62. package/dist/domains/onboarding/onboarding.js +16 -9
  63. package/dist/domains/onboarding/onboarding.js.map +1 -1
  64. package/dist/domains/people/person.d.ts +54 -0
  65. package/dist/domains/people/person.d.ts.map +1 -0
  66. package/dist/domains/people/person.js +73 -0
  67. package/dist/domains/people/person.js.map +1 -0
  68. package/dist/domains/products/products.d.ts +62 -33
  69. package/dist/domains/products/products.d.ts.map +1 -1
  70. package/dist/domains/products/products.js +3 -0
  71. package/dist/domains/products/products.js.map +1 -1
  72. package/dist/domains/profile/founder-profile.d.ts +36 -19
  73. package/dist/domains/profile/founder-profile.d.ts.map +1 -1
  74. package/dist/domains/profile/founder-profile.js +43 -21
  75. package/dist/domains/profile/founder-profile.js.map +1 -1
  76. package/dist/domains/reviews/reviews.d.ts +25 -15
  77. package/dist/domains/reviews/reviews.d.ts.map +1 -1
  78. package/dist/domains/support/support.d.ts +47 -10
  79. package/dist/domains/support/support.d.ts.map +1 -1
  80. package/dist/domains/support/support.js +4 -2
  81. package/dist/domains/support/support.js.map +1 -1
  82. package/dist/domains/team/team.d.ts +9 -3
  83. package/dist/domains/team/team.d.ts.map +1 -1
  84. package/dist/domains/team/team.js +3 -6
  85. package/dist/domains/team/team.js.map +1 -1
  86. package/dist/index.d.ts +11 -9
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +13 -9
  89. package/dist/index.js.map +1 -1
  90. package/package.json +3 -2
  91. package/dist/account.d.ts +0 -40
  92. package/dist/account.d.ts.map +0 -1
  93. package/dist/account.js +0 -39
  94. package/dist/account.js.map +0 -1
  95. package/dist/chat.d.ts +0 -187
  96. package/dist/chat.d.ts.map +0 -1
  97. package/dist/chat.js +0 -189
  98. package/dist/chat.js.map +0 -1
  99. package/dist/common.d.ts +0 -304
  100. package/dist/common.d.ts.map +0 -1
  101. package/dist/common.js +0 -340
  102. package/dist/common.js.map +0 -1
  103. package/dist/discover.d.ts +0 -245
  104. package/dist/discover.d.ts.map +0 -1
  105. package/dist/discover.js +0 -68
  106. package/dist/discover.js.map +0 -1
  107. package/dist/errors.d.ts +0 -85
  108. package/dist/errors.d.ts.map +0 -1
  109. package/dist/errors.js +0 -89
  110. package/dist/errors.js.map +0 -1
  111. package/dist/feed.d.ts +0 -1658
  112. package/dist/feed.d.ts.map +0 -1
  113. package/dist/feed.js +0 -623
  114. package/dist/feed.js.map +0 -1
  115. package/dist/founder-profile.d.ts +0 -387
  116. package/dist/founder-profile.d.ts.map +0 -1
  117. package/dist/founder-profile.js +0 -180
  118. package/dist/founder-profile.js.map +0 -1
  119. package/dist/limits.d.ts +0 -76
  120. package/dist/limits.d.ts.map +0 -1
  121. package/dist/limits.js +0 -84
  122. package/dist/limits.js.map +0 -1
  123. package/dist/onboarding.d.ts +0 -1018
  124. package/dist/onboarding.d.ts.map +0 -1
  125. package/dist/onboarding.js +0 -717
  126. package/dist/onboarding.js.map +0 -1
  127. package/dist/responses/common.d.ts +0 -167
  128. package/dist/responses/common.d.ts.map +0 -1
  129. package/dist/responses/common.js +0 -67
  130. package/dist/responses/common.js.map +0 -1
  131. package/dist/responses/index.d.ts +0 -7
  132. package/dist/responses/index.d.ts.map +0 -1
  133. package/dist/responses/index.js +0 -7
  134. package/dist/responses/index.js.map +0 -1
  135. package/dist/uploads.d.ts +0 -113
  136. package/dist/uploads.d.ts.map +0 -1
  137. package/dist/uploads.js +0 -106
  138. package/dist/uploads.js.map +0 -1
  139. package/dist/validation.d.ts +0 -136
  140. package/dist/validation.d.ts.map +0 -1
  141. package/dist/validation.js +0 -142
  142. package/dist/validation.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"feed.d.ts","sourceRoot":"","sources":["../src/feed.ts"],"names":[],"mappings":"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"}
package/dist/feed.js DELETED
@@ -1,623 +0,0 @@
1
- /**
2
- * founder-schema — Feed wire shapes: post, poll, comment, reaction
3
- *
4
- * ADAPTED FROM `jansathi-community-schema`, NOT DEPENDENT ON IT.
5
- *
6
- * The user ruled on 2026-09-21 that Founder Circle is a standalone app, so
7
- * these shapes are copied and cut down rather than imported. The reason is
8
- * worth keeping: `jansathi-community-schema` encodes Jansathi's reach levels,
9
- * community designations, official-area kinds and crowdfunding audiences.
10
- * Depending on it would put all of that permanently inside our contract for a
11
- * feed that has none of those concepts, and would mean a Jansathi publish can
12
- * break this product.
13
- *
14
- * DELIBERATELY NOT PORTED, so nobody "restores" them:
15
- * - the five civic verticals (lost_found, suggestions_complaints,
16
- * donate_item, crowdfunding, event). `contentKind` here is post | poll
17
- * only; comment threads and bookmarks key off it, and reactions and
18
- * reports off the same union plus `comment`.
19
- * - official communities, designations, identity verification badges.
20
- * - social score, and the whole area-proximity ranking vocabulary
21
- * (local / district / state / national / global).
22
- * - `areaLineage` as a REQUIRED authorship snapshot. Jansathi gates its
23
- * composer on a declared residence resolving to Indian district level or
24
- * deeper; the user ruled location is never mandatory here, so nothing in
25
- * this file requires one.
26
- * - anonymous posting, which in Jansathi is gated on identity verification
27
- * we do not have. A founders' network is an identified network.
28
- *
29
- * @module founder-schema/feed
30
- */
31
- import { z } from 'zod';
32
- import { emptyStringToUndefined, objectIdSchema, paginationQuerySchema, safeUrlSchema, usernameSchema, } from './common.js';
33
- import { LINK_PREVIEW_DESCRIPTION_MAX, LINK_PREVIEW_TITLE_MAX, MEDIA_ALT_MAX, REPORT_NOTE_MAX, } from './limits.js';
34
- import { topicSchema } from './onboarding.js';
35
- import { paginatedSchema } from './responses/common.js';
36
- import { uploadKeySchema } from './uploads.js';
37
- import { VALIDATION_MESSAGE } from './validation.js';
38
- // ─── Limits ──────────────────────────────────────────────────────────────────
39
- /**
40
- * Exported because the composer must count down to the SAME number the server
41
- * rejects at. A client-side limit that disagrees with the server is a message
42
- * a member cannot send and cannot see why.
43
- */
44
- export const POST_MAX_BODY_CHARS = 5000;
45
- /**
46
- * Total attachments on one post, images and videos together.
47
- *
48
- * ONE cap over ONE ordered list, rather than Jansathi's separate image and
49
- * video arrays. A member who posts a screenshot, then a clip, then another
50
- * screenshot means that order, and two parallel arrays cannot express it: the
51
- * card would show both images and then the video, which is not what was
52
- * written.
53
- */
54
- export const POST_MAX_MEDIA = 10;
55
- /**
56
- * Topics per item.
57
- *
58
- * Capped low on purpose: a post tagged with everything is about nothing, and
59
- * one tagged with ten matches every member, which is how a relevance feature
60
- * turns back into a chronological one.
61
- */
62
- export const MAX_TOPICS = 3;
63
- export const COMMENT_MAX_BODY_CHARS = 2000;
64
- export const POLL_QUESTION_MAX_CHARS = 280;
65
- export const POLL_OPTION_MAX_CHARS = 80;
66
- export const POLL_MIN_OPTIONS = 2;
67
- export const POLL_MAX_OPTIONS = 6;
68
- /** 5 minutes. Below this a poll closes before anyone sees it. */
69
- export const POLL_MIN_DURATION_MS = 5 * 60 * 1000;
70
- /** 30 days. */
71
- export const POLL_MAX_DURATION_MS = 30 * 24 * 60 * 60 * 1000;
72
- /**
73
- * How long after writing it the author may still edit a post or a comment.
74
- *
75
- * A window rather than forever: an edit after people have reacted changes what
76
- * they reacted to. Deletion has no window, because a member must always be able
77
- * to remove their own words. The server is the gate (`EDIT_WINDOW_CLOSED`);
78
- * a client uses this to stop offering Edit at the moment the server would
79
- * start refusing it, instead of on the next reload.
80
- */
81
- export const EDIT_WINDOW_MS = 15 * 60 * 1000;
82
- // ─── Enums ───────────────────────────────────────────────────────────────────
83
- /**
84
- * What can appear in the feed. Two kinds, not seven.
85
- *
86
- * Engagement is keyed by `(contentKind, contentId)` so one engagement bar
87
- * serves both, and comments hang off the same pair. Adding a kind later is
88
- * additive; the union is deliberately narrow now so the client never has to
89
- * handle a kind this product does not have.
90
- */
91
- export const CONTENT_KIND_VALUES = ['post', 'poll'];
92
- export const contentKindSchema = z.enum(CONTENT_KIND_VALUES);
93
- /**
94
- * What a reaction or a report can point at: a feed item, or a comment on one.
95
- *
96
- * Wider than `ContentKind` on purpose. A comment carries reaction counts and a
97
- * viewer reaction, and a comment can be abusive, so both reach it. A bookmark
98
- * and a comment thread cannot: they take `ContentKind`. Until 0.2.0 the
99
- * reaction and report RESPONSES were typed `ContentKind` while the routes
100
- * accepted comments, so every answer about a comment broke this contract.
101
- */
102
- export const ENGAGEMENT_TARGET_KIND_VALUES = [...CONTENT_KIND_VALUES, 'comment'];
103
- export const engagementTargetKindSchema = z.enum(ENGAGEMENT_TARGET_KIND_VALUES);
104
- /**
105
- * Reactions. Jansathi's `support` is dropped: it exists for reacting to a
106
- * civic complaint or a lost-and-found notice, which this feed does not carry.
107
- *
108
- * ⚠️ These values are stored per reaction row, so removing one orphans data.
109
- * Append only.
110
- */
111
- export const REACTION_TYPE_VALUES = ['like', 'celebrate', 'insightful', 'curious'];
112
- export const reactionTypeSchema = z.enum(REACTION_TYPE_VALUES);
113
- /**
114
- * Feed ordering.
115
- *
116
- * `new` is the default here, unlike Jansathi where `hot` leads. A hot ranking
117
- * needs volume to be meaningful, and a brand-new network ranking a handful of
118
- * posts by a blended score mostly hides the newest thing somebody just wrote.
119
- * Revisit when there is enough content for `hot` to mean anything.
120
- */
121
- export const FEED_SORT_VALUES = ['new', 'top'];
122
- export const feedSortSchema = z.enum(FEED_SORT_VALUES);
123
- /**
124
- * Counts keyed by reaction type, e.g. `{ like: 4, celebrate: 1 }`. Only the
125
- * reactions an item actually has need appear.
126
- *
127
- * ⚠️ `partialRecord`, NOT `record`. In Zod 4 an enum-keyed `z.record` is
128
- * EXHAUSTIVE: it demands every key, so `{ like: 4 }` fails with three missing
129
- * keys and `{}` fails with four. That would force the server to ship a zero for
130
- * every reaction on every item, and the day a fifth reaction is added every
131
- * previously stored payload and every older client stops parsing.
132
- * `partialRecord` keeps the key validation without the exhaustiveness, so an
133
- * unknown key like Jansathi's `support` is still refused.
134
- */
135
- export const reactionCountsSchema = z.partialRecord(reactionTypeSchema, z.number().int().nonnegative());
136
- // ─── Author byline ───────────────────────────────────────────────────────────
137
- /**
138
- * The author as a card renders them.
139
- *
140
- * Every field here is LIVE, joined against the profile at read time rather
141
- * than frozen onto the post at write time. So a renamed handle, a new avatar
142
- * or an edited headline updates on old posts, and the byline link always
143
- * targets the current username instead of 404ing on a handle that moved.
144
- *
145
- * Jansathi additionally snapshots `localName` ("where the author was when
146
- * posting"). Not ported: location is optional here, so a byline that depends
147
- * on one would be blank for anyone who never set it.
148
- */
149
- export const feedAuthorSchema = z.object({
150
- userId: z.string(),
151
- username: usernameSchema,
152
- displayName: z.string(),
153
- /** Server-generated or from the login provider, never member-typed, so a
154
- * plain URL check. Same reasoning as `avatarUrl` on the profile. */
155
- avatarUrl: z.url().optional(),
156
- /** The author's one-line headline, live-joined. Gives a founders' byline
157
- * the context a civic byline got from an area label. */
158
- headline: z.string().optional(),
159
- });
160
- // ─── Media ───────────────────────────────────────────────────────────────────
161
- /**
162
- * `width` and `height` are required so a card can reserve the right box before
163
- * the image loads. Without them every image arrival shifts the feed under the
164
- * reader's thumb.
165
- *
166
- * URLs here come from our own upload pipeline, so they take a plain `z.url()`
167
- * rather than `httpUrlSchema`. ⚠️ If a "paste an image link" path is ever
168
- * added, these become member-supplied and must move to `httpUrlSchema`.
169
- */
170
- export const feedImageSchema = z.object({
171
- kind: z.literal('image'),
172
- url: z.url(),
173
- thumbnailUrl: z.url().optional(),
174
- width: z.number().int().positive(),
175
- height: z.number().int().positive(),
176
- /** Author-supplied alt text. Optional, and worth asking for. */
177
- alt: z.string().max(MEDIA_ALT_MAX).optional(),
178
- });
179
- export const feedVideoSchema = z.object({
180
- kind: z.literal('video'),
181
- url: z.url(),
182
- /** Poster frame, server-extracted. Required: a video with no poster is a
183
- * black rectangle in the feed. */
184
- thumbnailUrl: z.url(),
185
- width: z.number().int().positive(),
186
- height: z.number().int().positive(),
187
- /** Seconds. */
188
- duration: z.number().positive(),
189
- });
190
- /**
191
- * One ordered list, discriminated on `kind`, so the carousel renders
192
- * attachments in the order they were attached and can switch on the kind
193
- * without inspecting fields.
194
- */
195
- export const feedMediaSchema = z.discriminatedUnion('kind', [feedImageSchema, feedVideoSchema]);
196
- // ─── Link preview ────────────────────────────────────────────────────────────
197
- /**
198
- * Preview for the first link in a post body. Server-derived at write time and
199
- * stored, never re-fetched at render: a card that fetches a third-party page
200
- * per scroll leaks every reader's address to that site and blocks the feed on
201
- * somebody else's latency.
202
- *
203
- * Both URLs take `safeUrlSchema`: the scheme and host rules, WITHOUT the
204
- * typed-URL cap. `url` came out of a post body, which is already capped as a
205
- * whole, and `imageUrl` is whatever the remote page advertised; a long CDN URL
206
- * is ordinary, and one over `LINK_URL_MAX` would otherwise fail the whole feed
207
- * page it sits on. Neither is ours, so a consumer still treats both as
208
- * untrusted at render.
209
- */
210
- export const linkPreviewSchema = z.object({
211
- url: safeUrlSchema,
212
- title: z.string().max(LINK_PREVIEW_TITLE_MAX).optional(),
213
- description: z.string().max(LINK_PREVIEW_DESCRIPTION_MAX).optional(),
214
- imageUrl: safeUrlSchema.optional(),
215
- });
216
- // ─── Viewer state ────────────────────────────────────────────────────────────
217
- /**
218
- * What THIS viewer has done to this item, computed per request.
219
- *
220
- * Optional as a block, because an unauthenticated or server-rendered read has
221
- * no viewer. ⚠️ A client must treat an absent `viewer` as "no state known",
222
- * never as "has not reacted": rendering an empty reaction button off a missing
223
- * block is how a member sees their own reaction disappear on reload.
224
- */
225
- export const viewerStateSchema = z.object({
226
- reaction: reactionTypeSchema.nullable(),
227
- bookmarked: z.boolean(),
228
- isAuthor: z.boolean(),
229
- /**
230
- * What this viewer may DO, decided by the server and sent as plain answers.
231
- *
232
- * Not role data for the client to reason about. The moment a client derives
233
- * "can I edit this" from roles and ownership, that derivation is a second
234
- * implementation of the rule, it drifts from the server's, and the drift is
235
- * invisible until the two disagree: either a button that 403s or a button
236
- * that should not have been there. `isAuthor` stays because the byline reads
237
- * differently for your own post, not because the client should compute rights
238
- * from it.
239
- *
240
- * `canEdit` is false once the edit window closes, so it is not simply
241
- * `isAuthor`.
242
- */
243
- canEdit: z.boolean(),
244
- canDelete: z.boolean(),
245
- canReport: z.boolean(),
246
- });
247
- // ─── Post ────────────────────────────────────────────────────────────────────
248
- /**
249
- * A post as the feed and the single-post page receive it.
250
- *
251
- * Counts are denormalised onto the row so one document serves a whole card.
252
- *
253
- * No `score` and no up/down vote. Jansathi's signed score exists to rank civic
254
- * content by community judgement, and a downvote arrow on a founder's first
255
- * post is a different product. Reactions and comments are the engagement axes
256
- * here. Adding a score later is additive; removing a visible downvote after
257
- * members have used it is not.
258
- */
259
- export const feedPostSchema = z.object({
260
- id: objectIdSchema,
261
- contentKind: z.literal('post'),
262
- author: feedAuthorSchema,
263
- /**
264
- * The WHOLE body, never a server-side truncation.
265
- *
266
- * So there is no "was this shortened" flag and no second fetch to read the
267
- * rest: the card clamps visually and expands in place. At a 5,000 character
268
- * cap a page of twenty posts is small enough that trimming would cost a round
269
- * trip to save nothing. If that ever stops being true, a truncation flag is
270
- * an additive change; a client that has been guessing is not.
271
- */
272
- text: z.string().max(POST_MAX_BODY_CHARS),
273
- /** Ordered as the author attached them. */
274
- media: z.array(feedMediaSchema).max(POST_MAX_MEDIA),
275
- /** Present only when the body had an embeddable link. */
276
- linkPreview: linkPreviewSchema.optional(),
277
- /**
278
- * What this post is ABOUT, from the same vocabulary a member picks as their
279
- * interests. This is the whole mechanism behind a relevant feed: matching is
280
- * an intersection of two lists drawn from one enum, not a guess from who
281
- * wrote it.
282
- *
283
- * ⚠️ An EMPTY array is allowed and means the post is untagged, so interest
284
- * matching cannot reach it. That is a real consequence, not a nuance: an
285
- * untagged post is only ever found chronologically.
286
- */
287
- topics: z.array(topicSchema).max(MAX_TOPICS),
288
- commentCount: z.number().int().nonnegative(),
289
- reactionCounts: reactionCountsSchema,
290
- createdAt: z.iso.datetime(),
291
- /** Null when never edited. The edit window is the server's to enforce. */
292
- editedAt: z.iso.datetime().nullable(),
293
- viewer: viewerStateSchema.optional(),
294
- });
295
- // ─── Poll ────────────────────────────────────────────────────────────────────
296
- /**
297
- * One choice. `index` is the identifier a vote refers to, not the label:
298
- * sending indices avoids ambiguity between two options whose labels differ
299
- * only by case, spacing or an invisible character.
300
- */
301
- export const pollOptionSchema = z.object({
302
- index: z
303
- .number()
304
- .int()
305
- .min(0)
306
- .max(POLL_MAX_OPTIONS - 1),
307
- label: z.string().min(1).max(POLL_OPTION_MAX_CHARS),
308
- voteCount: z.number().int().nonnegative(),
309
- });
310
- /**
311
- * A poll. Its own kind, not a post with extra fields, because votes are their
312
- * own records keyed by (poll, voter) and a post has nothing equivalent.
313
- *
314
- * Polls are not editable. Changing a question or an option after a vote has
315
- * been cast silently re-purposes that vote. Closing early is allowed; editing
316
- * is not.
317
- */
318
- export const feedPollSchema = z.object({
319
- id: objectIdSchema,
320
- contentKind: z.literal('poll'),
321
- author: feedAuthorSchema,
322
- question: z.string().min(1).max(POLL_QUESTION_MAX_CHARS),
323
- options: z.array(pollOptionSchema).min(POLL_MIN_OPTIONS).max(POLL_MAX_OPTIONS),
324
- /** Unique voters, not votes: with multi-select the two differ. */
325
- totalVoters: z.number().int().nonnegative(),
326
- allowsMultipleChoices: z.boolean(),
327
- closesAt: z.iso.datetime(),
328
- /**
329
- * Whether the poll is closed, decided by the SERVER's clock.
330
- *
331
- * Derivable from `closesAt`, and deliberately sent anyway: a device with a
332
- * wrong clock would otherwise show a live poll as finished, or offer a vote
333
- * the server then rejects, and the member sees a control that lies. `closesAt`
334
- * stays for rendering "closes in 2 days"; this is what gates the control.
335
- */
336
- isClosed: z.boolean(),
337
- /** As on a post. A poll is feed content and is matched the same way. */
338
- topics: z.array(topicSchema).max(MAX_TOPICS),
339
- commentCount: z.number().int().nonnegative(),
340
- reactionCounts: reactionCountsSchema,
341
- createdAt: z.iso.datetime(),
342
- /** Always null. Kept so one byline component renders both kinds. */
343
- editedAt: z.iso.datetime().nullable(),
344
- viewer: viewerStateSchema
345
- .extend({
346
- /** Indices this viewer chose. Empty means not voted yet, and it is
347
- * always populated for the viewer: a voter can always see their own
348
- * answer even where others' results are hidden. */
349
- votedOptionIndices: z.array(z.number().int().nonnegative()),
350
- })
351
- .optional(),
352
- });
353
- // ─── The feed item union ─────────────────────────────────────────────────────
354
- /**
355
- * Discriminated on `contentKind`, so a client narrows with a switch and the
356
- * compiler catches an unhandled kind the day one is added. A plain union would
357
- * need every field checked by hand and would silently accept a hybrid.
358
- */
359
- export const feedItemSchema = z.discriminatedUnion('contentKind', [feedPostSchema, feedPollSchema]);
360
- // ─── Comments ────────────────────────────────────────────────────────────────
361
- /**
362
- * A comment, one level of nesting only: a reply to a comment is allowed, a
363
- * reply to a reply is not. Two levels stay readable on a phone; three do not,
364
- * and the server is what enforces it.
365
- */
366
- export const feedCommentSchema = z.object({
367
- id: objectIdSchema,
368
- contentKind: contentKindSchema,
369
- contentId: objectIdSchema,
370
- /** Null for a top-level comment. A non-null value may only name a top-level
371
- * comment, never a reply. */
372
- parentCommentId: objectIdSchema.nullable(),
373
- author: feedAuthorSchema,
374
- text: z.string().max(COMMENT_MAX_BODY_CHARS),
375
- /** Meaningful only on a top-level comment; always 0 on a reply. */
376
- replyCount: z.number().int().nonnegative(),
377
- reactionCounts: reactionCountsSchema,
378
- createdAt: z.iso.datetime(),
379
- editedAt: z.iso.datetime().nullable(),
380
- /** No `bookmarked`: the post is the right thing to save, not a comment. */
381
- viewer: viewerStateSchema.omit({ bookmarked: true }).optional(),
382
- });
383
- // ─── Queries ─────────────────────────────────────────────────────────────────
384
- /**
385
- * `GET /api/v1/feed`. Inherits `limit` and `cursor`, which already tolerate an
386
- * emptied control rather than answering 400.
387
- *
388
- * `interests=true` narrows to the viewer's topics (falling back to the plain
389
- * feed when they have none). `z.stringbool`, so `true`/`false`/`1`/`0` all
390
- * read as a person means them; until 0.2.0 the backend read this parameter
391
- * raw, outside the schema, and only the exact string `true` counted.
392
- *
393
- * ⚠ NO `authorId`. It was accepted here and then ignored by the server, so a
394
- * profile page asking for one founder's posts silently got everybody's. A
395
- * member's own posts are `GET /api/v1/feed/by-author/:userId`.
396
- */
397
- export const feedQuerySchema = paginationQuerySchema.extend({
398
- sort: z.preprocess(emptyStringToUndefined, feedSortSchema.default('new')),
399
- interests: z.preprocess(emptyStringToUndefined, z.stringbool().default(false)),
400
- });
401
- /** `GET /api/v1/feed/:contentKind/:contentId/comments`. */
402
- export const commentsQuerySchema = paginationQuerySchema.extend({
403
- /** Omitted lists top-level comments; set, it lists that comment's replies. */
404
- parentCommentId: z.preprocess(emptyStringToUndefined, objectIdSchema.optional()),
405
- });
406
- // ─── Route parameters ────────────────────────────────────────────────────────
407
- /**
408
- * Every id and kind in a feed URL, as a schema, so a bad one answers exactly
409
- * as a bad body field does: 400 `VALIDATION_ERROR`, the issue at
410
- * `location: 'params'`. Until 0.2.0 these were hand checks that answered
411
- * "Invalid id." with no issues at all, and the comment routes never looked at
412
- * `:contentKind`.
413
- */
414
- /** `GET /feed/:id`, the permalink. */
415
- export const feedItemParamsSchema = z.object({ id: objectIdSchema });
416
- /** `PATCH|DELETE /feed/:contentId`. */
417
- export const contentParamsSchema = z.object({ contentId: objectIdSchema });
418
- /** A bookmark and a comment thread: a post or a poll. */
419
- export const contentTargetParamsSchema = z.object({
420
- contentKind: contentKindSchema,
421
- contentId: objectIdSchema,
422
- });
423
- /** A reaction and a report: a post, a poll or a comment. */
424
- export const engagementTargetParamsSchema = z.object({
425
- contentKind: engagementTargetKindSchema,
426
- contentId: objectIdSchema,
427
- });
428
- /** `POST|DELETE /feed/poll/:pollId/vote`. */
429
- export const pollParamsSchema = z.object({ pollId: objectIdSchema });
430
- /** `DELETE /feed/comments/:commentId`. */
431
- export const commentParamsSchema = z.object({ commentId: objectIdSchema });
432
- /** `GET /feed/by-author/:userId`. */
433
- export const authorParamsSchema = z.object({ userId: objectIdSchema });
434
- // ─── Pages ───────────────────────────────────────────────────────────────────
435
- /**
436
- * A page of the feed, and of one member's posts (`by-author`), which is the
437
- * same shape. `nextCursor` is null on the last page.
438
- */
439
- export const feedPageSchema = paginatedSchema(feedItemSchema);
440
- /** A page of a thread: top-level comments, or one comment's replies. */
441
- export const commentPageSchema = paginatedSchema(feedCommentSchema);
442
- // ─── Write bodies ────────────────────────────────────────────────────────────
443
- /**
444
- * ⚠️ Every write body below is its own object with NO defaults, and none of
445
- * them is built with `.pick().partial()`. `.partial()` does not switch off
446
- * `.default()`, so a patch body built that way rewrites defaulted fields on
447
- * every request. See `updateFounderProfileBodySchema` for the incident.
448
- */
449
- /**
450
- * An attachment on the way IN: a reference to something already uploaded, and
451
- * deliberately not a URL.
452
- *
453
- * Upload happens first, straight to storage, and the composer sends back the
454
- * key it was given (`uploadKeySchema`, in `uploads`). The server resolves that
455
- * key to the URL, dimensions and poster frame it reads from the object itself,
456
- * and those become the read shape.
457
- *
458
- * ⚠ The first draft of this took the full read shape, URL included. That is
459
- * the same hole that was closed on the profile: a URL in a write body is a
460
- * member-supplied URL, so a post could have carried `javascript:` in an image
461
- * source, and nothing downstream re-checks a value the server itself stored.
462
- * Taking a key instead removes the question rather than validating it, and it
463
- * also stops a member pointing a post at somebody else's file.
464
- *
465
- * `width`, `height` and `duration` are NOT accepted here either. They are
466
- * properties of the uploaded object, so the server reads them from the object;
467
- * taking them from the client would let a caller claim a 1x1 image and collapse
468
- * the card.
469
- */
470
- export const attachedMediaSchema = z.object({
471
- uploadKey: uploadKeySchema,
472
- /** Author-supplied alt text, the one media field a member does write. */
473
- alt: z.string().trim().max(MEDIA_ALT_MAX).optional(),
474
- });
475
- /**
476
- * A post must carry something. Text alone, media alone, or both; empty is
477
- * refused here rather than reaching the feed as a blank card.
478
- */
479
- export const createPostBodySchema = z
480
- .object({
481
- text: z.string().trim().max(POST_MAX_BODY_CHARS).optional(),
482
- /** Already uploaded. See `attachedMediaSchema`. Order is preserved. */
483
- media: z.array(attachedMediaSchema).max(POST_MAX_MEDIA).optional(),
484
- /** Absent means untagged, which means interest matching cannot find it. */
485
- topics: z.array(topicSchema).max(MAX_TOPICS).optional(),
486
- })
487
- .refine((b) => Boolean(b.text?.length) || Boolean(b.media?.length), {
488
- error: VALIDATION_MESSAGE.postEmpty,
489
- path: ['text'],
490
- });
491
- /** Only the text is editable. Changing media after the fact makes every
492
- * earlier reply look like a reply to something else. */
493
- export const updatePostBodySchema = z.object({
494
- text: z.string().trim().min(1).max(POST_MAX_BODY_CHARS),
495
- });
496
- export const createPollBodySchema = z
497
- .object({
498
- question: z.string().trim().min(1).max(POLL_QUESTION_MAX_CHARS),
499
- options: z
500
- .array(z.object({ label: z.string().trim().min(1).max(POLL_OPTION_MAX_CHARS) }))
501
- .min(POLL_MIN_OPTIONS)
502
- .max(POLL_MAX_OPTIONS),
503
- /**
504
- * Duration from now, NOT an absolute closing time. A client whose clock is
505
- * wrong would otherwise open a poll that is already closed, and the member
506
- * would have no way to tell why.
507
- */
508
- durationMs: z.number().int().min(POLL_MIN_DURATION_MS).max(POLL_MAX_DURATION_MS),
509
- allowsMultipleChoices: z.boolean(),
510
- topics: z.array(topicSchema).max(MAX_TOPICS).optional(),
511
- })
512
- .refine((b) => {
513
- const seen = new Set();
514
- for (const o of b.options) {
515
- const key = o.label.trim().toLowerCase();
516
- if (seen.has(key))
517
- return false;
518
- seen.add(key);
519
- }
520
- return true;
521
- }, { error: VALIDATION_MESSAGE.pollOptionsDuplicate, path: ['options'] });
522
- /** Cast or change a vote. The server upserts on (poll, voter), so voting
523
- * twice replaces rather than doubles. */
524
- export const castVoteBodySchema = z.object({
525
- optionIndices: z
526
- .array(z
527
- .number()
528
- .int()
529
- .min(0)
530
- .max(POLL_MAX_OPTIONS - 1))
531
- .min(1)
532
- .max(POLL_MAX_OPTIONS),
533
- });
534
- export const createCommentBodySchema = z.object({
535
- text: z.string().trim().min(1).max(COMMENT_MAX_BODY_CHARS),
536
- /** Null for a top-level comment. */
537
- parentCommentId: objectIdSchema.nullable(),
538
- });
539
- export const updateCommentBodySchema = z.object({
540
- text: z.string().trim().min(1).max(COMMENT_MAX_BODY_CHARS),
541
- });
542
- /** Set or clear a reaction. `null` clears it; at most one per viewer per item. */
543
- export const setReactionBodySchema = z.object({
544
- reaction: reactionTypeSchema.nullable(),
545
- });
546
- // ─── Engagement responses ────────────────────────────────────────────────────
547
- /**
548
- * Returned by the reaction endpoint so the card can render the authoritative
549
- * result without a follow-up read. Without the fresh counts a client has to
550
- * guess the new total, and two quick taps leave it showing a number the server
551
- * never had.
552
- */
553
- export const setReactionResponseSchema = z.object({
554
- contentKind: engagementTargetKindSchema,
555
- contentId: objectIdSchema,
556
- reaction: reactionTypeSchema.nullable(),
557
- reactionCounts: reactionCountsSchema,
558
- });
559
- // ─── Reporting ───────────────────────────────────────────────────────────────
560
- /**
561
- * Why a member reported something.
562
- *
563
- * ⚠️ Stored on every report row, so this is data, not a label: removing a value
564
- * orphans reports already filed under it, and the counts nobody can recover are
565
- * exactly the ones a moderation review needs. Append only.
566
- *
567
- * ⚠️ A REASON THAT IS MISSING DOES NOT DISAPPEAR, it lands in `other`. Whatever
568
- * is not named here becomes an undifferentiated pile that no aggregate can see
569
- * a pattern in, which is the one thing report categories exist for. Worth being
570
- * deliberate about the absences rather than discovering them later.
571
- */
572
- export const REPORT_REASON_VALUES = [
573
- 'spam',
574
- 'harassment',
575
- 'misinformation',
576
- 'off_topic',
577
- 'impersonation',
578
- 'other',
579
- ];
580
- export const reportReasonSchema = z.enum(REPORT_REASON_VALUES);
581
- /**
582
- * What a member sends to report a post, poll or comment.
583
- *
584
- * The target is the URL's, not the body's: a report is filed against a specific
585
- * thing at a specific address, and taking the target from the body would let a
586
- * caller report one item while the route thinks it is another.
587
- *
588
- * `note` is free text and optional, which is the pressure valve for everything
589
- * the enum does not name. ⚠️ It is written by a member, so it is untrusted at
590
- * render: a moderation queue displays it, and a moderation queue is a screen
591
- * staff read quickly.
592
- */
593
- export const createReportBodySchema = z.object({
594
- reason: reportReasonSchema,
595
- note: z.string().trim().max(REPORT_NOTE_MAX).optional(),
596
- });
597
- /**
598
- * The answer to filing one.
599
- *
600
- * `alreadyReported` distinguishes "we have taken this" from "you already told
601
- * us", because one report per member per target means a second press is a
602
- * no-op, and a silent no-op reads as a failure to somebody who pressed twice
603
- * deliberately. It is NOT a count: how many OTHER people reported an item is
604
- * moderation's business and telling a reporter would turn the count into a
605
- * score anyone could farm.
606
- */
607
- export const createReportResponseSchema = z.object({
608
- contentKind: engagementTargetKindSchema,
609
- contentId: objectIdSchema,
610
- alreadyReported: z.boolean(),
611
- });
612
- /** The bookmark endpoint is a toggle and returns the state it settled on. */
613
- export const toggleBookmarkResponseSchema = z.object({
614
- contentKind: contentKindSchema,
615
- contentId: objectIdSchema,
616
- bookmarked: z.boolean(),
617
- });
618
- /** A vote returns the whole poll: counts, totals and the viewer's own choices
619
- * all move together, and reassembling them client-side drifts. */
620
- export const castVoteResponseSchema = z.object({
621
- poll: feedPollSchema,
622
- });
623
- //# sourceMappingURL=feed.js.map