founder-schema 0.11.0 → 0.13.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 (99) hide show
  1. package/README.md +85 -0
  2. package/dist/access/access.d.ts +10 -6
  3. package/dist/access/access.d.ts.map +1 -1
  4. package/dist/access/access.js +8 -1
  5. package/dist/access/access.js.map +1 -1
  6. package/dist/access/permissions.d.ts +60 -3
  7. package/dist/access/permissions.d.ts.map +1 -1
  8. package/dist/access/permissions.js +24 -0
  9. package/dist/access/permissions.js.map +1 -1
  10. package/dist/access/roles.d.ts +3 -3
  11. package/dist/access/standing.d.ts +59 -0
  12. package/dist/access/standing.d.ts.map +1 -0
  13. package/dist/access/standing.js +52 -0
  14. package/dist/access/standing.js.map +1 -0
  15. package/dist/core/errors.d.ts +51 -1
  16. package/dist/core/errors.d.ts.map +1 -1
  17. package/dist/core/errors.js +89 -1
  18. package/dist/core/errors.js.map +1 -1
  19. package/dist/core/limits.d.ts +29 -3
  20. package/dist/core/limits.d.ts.map +1 -1
  21. package/dist/core/limits.js +30 -3
  22. package/dist/core/limits.js.map +1 -1
  23. package/dist/core/responses.d.ts +59 -0
  24. package/dist/core/responses.d.ts.map +1 -1
  25. package/dist/core/responses.js +6 -0
  26. package/dist/core/responses.js.map +1 -1
  27. package/dist/core/validation.d.ts +14 -0
  28. package/dist/core/validation.d.ts.map +1 -1
  29. package/dist/core/validation.js +14 -0
  30. package/dist/core/validation.js.map +1 -1
  31. package/dist/domains/audit/audit.d.ts +28 -7
  32. package/dist/domains/audit/audit.d.ts.map +1 -1
  33. package/dist/domains/audit/audit.js +17 -0
  34. package/dist/domains/audit/audit.js.map +1 -1
  35. package/dist/domains/billing/billing.d.ts +1180 -0
  36. package/dist/domains/billing/billing.d.ts.map +1 -0
  37. package/dist/domains/billing/billing.js +403 -0
  38. package/dist/domains/billing/billing.js.map +1 -0
  39. package/dist/domains/billing/gst.d.ts +229 -0
  40. package/dist/domains/billing/gst.d.ts.map +1 -0
  41. package/dist/domains/billing/gst.js +117 -0
  42. package/dist/domains/billing/gst.js.map +1 -0
  43. package/dist/domains/chat/chat.d.ts +85 -0
  44. package/dist/domains/chat/chat.d.ts.map +1 -1
  45. package/dist/domains/chat/chat.js +62 -0
  46. package/dist/domains/chat/chat.js.map +1 -1
  47. package/dist/domains/communities/communities.d.ts +13 -11
  48. package/dist/domains/communities/communities.d.ts.map +1 -1
  49. package/dist/domains/communities/communities.js +7 -0
  50. package/dist/domains/communities/communities.js.map +1 -1
  51. package/dist/domains/contributions/contributions.d.ts +2 -2
  52. package/dist/domains/contributions/contributions.d.ts.map +1 -1
  53. package/dist/domains/contributions/contributions.js +3 -2
  54. package/dist/domains/contributions/contributions.js.map +1 -1
  55. package/dist/domains/dashboard/dashboard.d.ts +9 -1
  56. package/dist/domains/dashboard/dashboard.d.ts.map +1 -1
  57. package/dist/domains/dashboard/dashboard.js +15 -0
  58. package/dist/domains/dashboard/dashboard.js.map +1 -1
  59. package/dist/domains/feed/feed.d.ts.map +1 -1
  60. package/dist/domains/feed/feed.js +7 -1
  61. package/dist/domains/feed/feed.js.map +1 -1
  62. package/dist/domains/members/members.d.ts +30 -5
  63. package/dist/domains/members/members.d.ts.map +1 -1
  64. package/dist/domains/members/members.js +23 -0
  65. package/dist/domains/members/members.js.map +1 -1
  66. package/dist/domains/membership/membership.d.ts +240 -0
  67. package/dist/domains/membership/membership.d.ts.map +1 -0
  68. package/dist/domains/membership/membership.js +159 -0
  69. package/dist/domains/membership/membership.js.map +1 -0
  70. package/dist/domains/notifications/notifications.d.ts +43 -1
  71. package/dist/domains/notifications/notifications.d.ts.map +1 -1
  72. package/dist/domains/notifications/notifications.js +19 -0
  73. package/dist/domains/notifications/notifications.js.map +1 -1
  74. package/dist/domains/onboarding/onboarding.d.ts +0 -10
  75. package/dist/domains/onboarding/onboarding.d.ts.map +1 -1
  76. package/dist/domains/onboarding/onboarding.js +9 -3
  77. package/dist/domains/onboarding/onboarding.js.map +1 -1
  78. package/dist/domains/products/products.d.ts +44 -12
  79. package/dist/domains/products/products.d.ts.map +1 -1
  80. package/dist/domains/products/products.js +33 -3
  81. package/dist/domains/products/products.js.map +1 -1
  82. package/dist/domains/profile/founder-profile.d.ts +10 -4
  83. package/dist/domains/profile/founder-profile.d.ts.map +1 -1
  84. package/dist/domains/profile/founder-profile.js +6 -3
  85. package/dist/domains/profile/founder-profile.js.map +1 -1
  86. package/dist/domains/reviews/reviews.d.ts +3 -0
  87. package/dist/domains/reviews/reviews.d.ts.map +1 -1
  88. package/dist/domains/reviews/reviews.js +6 -1
  89. package/dist/domains/reviews/reviews.js.map +1 -1
  90. package/dist/domains/support/support.d.ts +16 -1
  91. package/dist/domains/support/support.d.ts.map +1 -1
  92. package/dist/domains/support/support.js +5 -0
  93. package/dist/domains/support/support.js.map +1 -1
  94. package/dist/domains/team/team.d.ts +4 -4
  95. package/dist/index.d.ts +7 -4
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +9 -4
  98. package/dist/index.js.map +1 -1
  99. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"products.d.ts","sourceRoot":"","sources":["../../../src/domains/products/products.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"products.d.ts","sourceRoot":"","sources":["../../../src/domains/products/products.ts"],"names":[],"mappings":"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"}
@@ -51,6 +51,7 @@
51
51
  * PUT /api/v1/products/:productId/screenshots setProductScreenshotsBodySchema -> productSchema
52
52
  * PUT /api/v1/products/:productId/visibility setProductVisibilityBodySchema -> productSchema
53
53
  * PUT /api/v1/products/:productId/status setProductStatusBodySchema -> productSchema
54
+ * PUT /api/v1/products/:productId/live setProductLiveBodySchema -> productSchema (0.12.0)
54
55
  * GET /api/v1/products/:productId/team productTeamPageSchema
55
56
  * GET /api/v1/products/:productId/invites productPendingInvitePageSchema (managers)
56
57
  * POST /api/v1/products/:productId/invites inviteProductMemberBodySchema -> productPendingInviteSchema
@@ -235,8 +236,24 @@ export const productCardSchema = z.object({
235
236
  * "my products", on a team member's profile): a "Hidden by moderators" badge.
236
237
  */
237
238
  hiddenByStaff: z.boolean().optional(),
239
+ /**
240
+ * Paused (0.12.0): its owner owns more products than their plan keeps
241
+ * live. Like a hidden one, only its team and staff see it at all: a
242
+ * "Paused" badge. The owner makes it live again (`PUT .../live`) when a
243
+ * place is free.
244
+ */
245
+ paused: z.boolean().optional(),
238
246
  viewer: productCardViewerSchema.optional(),
239
247
  });
248
+ /**
249
+ * Why a product is paused (0.12.0). ⚠ Stored: append only.
250
+ * limit over its owner's live places (a plan ended, a refund, joining
251
+ * without one): it comes back by itself when a place frees
252
+ * owner its owner paused it, to free a place for another: it stays
253
+ * paused until they make it live
254
+ */
255
+ export const PRODUCT_PAUSED_BY_VALUES = ['limit', 'owner'];
256
+ export const productPausedBySchema = z.enum(PRODUCT_PAUSED_BY_VALUES);
240
257
  /** One person on a product's team, live-joined like every byline. */
241
258
  export const productTeamMemberSchema = memberBylineSchema.extend({
242
259
  role: productTeamRoleSchema,
@@ -260,6 +277,12 @@ export const productViewerSchema = productCardViewerSchema.extend({
260
277
  canManageTeam: z.boolean(),
261
278
  /** Owner. */
262
279
  canDelete: z.boolean(),
280
+ /**
281
+ * Owner (0.12.0): may pause it, or make it live again. Making it live is
282
+ * refused with `PRODUCT_LIMIT_REACHED` when no live place is free; the page
283
+ * says so from `GET /me/membership`.
284
+ */
285
+ canSetLive: z.boolean(),
263
286
  /** Anyone on the team: tag posts with it, reply to reviews, mark feedback, confirm testers. */
264
287
  canRepresent: z.boolean(),
265
288
  /** Not on its team, no review yet, and the product is open. */
@@ -274,6 +297,8 @@ export const productViewerSchema = productCardViewerSchema.extend({
274
297
  });
275
298
  /** The product page. */
276
299
  export const productSchema = productCardSchema.extend({
300
+ /** Set with `paused` (0.12.0): who paused it, so the page says why. */
301
+ pausedBy: productPausedBySchema.optional(),
277
302
  description: z.string().optional(),
278
303
  links: productLinksSchema,
279
304
  videoUrl: z.string().optional(),
@@ -324,9 +349,9 @@ export const productInviteSchema = z.object({
324
349
  export const productInvitesSchema = z.object({ items: z.array(productInviteSchema) });
325
350
  /**
326
351
  * `GET /products/mine`: every product the viewer is on the team of, archived
327
- * included, owned first. Not paged: a founder owns at most `PRODUCTS_OWNED_MAX`,
328
- * and joins teams by accepting invitations one at a time, so the list stays
329
- * short in practice; there is no hard cap on teams joined.
352
+ * and paused included, owned first. Not paged: a founder lists few, and joins
353
+ * teams by accepting invitations one at a time, so the list stays short in
354
+ * practice; there is no hard cap on teams joined.
330
355
  */
331
356
  export const myProductsSchema = z.object({ items: z.array(productCardSchema) });
332
357
  /** A member the team confirmed tested the product. */
@@ -448,6 +473,11 @@ export const setProductLogoBodySchema = z.object({ mediaId: objectIdSchema });
448
473
  export const setProductScreenshotsBodySchema = z.object({ screenshots: screenshotsInputSchema });
449
474
  export const setProductVisibilityBodySchema = z.object({ visibility: productVisibilitySchema });
450
475
  export const setProductStatusBodySchema = z.object({ status: productStatusSchema });
476
+ /**
477
+ * `PUT /products/:productId/live` (0.12.0, owner): `false` pauses it (to free
478
+ * a live place for another), `true` makes a paused one live again.
479
+ */
480
+ export const setProductLiveBodySchema = z.object({ live: z.boolean() });
451
481
  /**
452
482
  * Invite a member to the team; they must accept. `userId` is the member's id
453
483
  * as every card carries it (`founderCardSchema.userId`). Someone who cannot
@@ -1 +1 @@
1
- {"version":3,"file":"products.js","sourceRoot":"","sources":["../../../src/domains/products/products.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * founder-schema — Products: what founders build, and the help around it\n *\n * THE IDEA (the user, 2026-10-06): founders help each other with their\n * products. A founder adds what they build; a post or poll can say which of\n * their products it is about and what they want (\"testers wanted\"); every\n * comment on it becomes that product's feedback; the community reviews and\n * upvotes it; and the help a member gives is recognised in their contribution\n * score.\n *\n * THE COMPANY STAYS THE PROFILE'S `venture` (one per founder). There are no\n * company pages: co-founders join a PRODUCT's team, as Product Hunt lists a\n * product's makers. Revisit only if one team running many products finds\n * re-inviting each time tedious.\n *\n * VISIBILITY, two states (the user's ruling): `unlisted` by default, a page\n * anyone signed in can open by its link and that shows on its team's profiles;\n * `listed`, also in Discover. Listing needs a logo, a tagline and at least one\n * screenshot (`PRODUCT_NOT_LISTABLE` names what is missing), so Discover never\n * shows an empty card.\n *\n * THE TEAM: an owner, co-founders and team members, joined by invitation and\n * acceptance (nobody is put on a team without saying yes), with no limit on\n * its size (the user's ruling). Who may do what:\n *\n * owner co-founder team\n * edit, images, list, invite ✓ ✓\n * tag posts, reply to reviews, ✓ ✓ ✓\n * mark feedback, confirm testers\n * change roles, remove, hand over ✓\n * archive, delete ✓\n *\n * A product's images belong to the product, not to whoever uploaded them.\n * When the owner deletes their account the product passes to the longest-\n * standing co-founder (else team member); with nobody left it is deleted.\n *\n * Routes (all signed in):\n * GET /api/v1/products Discover: productDiscoverQuerySchema\n * GET /api/v1/products/facets productFacetsSchema\n * POST /api/v1/products createProductBodySchema -> IdResponse\n * GET /api/v1/products/mine myProductsSchema\n * GET /api/v1/products/invites productInvitesSchema\n * PUT /api/v1/products/invites/:productId accept -> productSchema\n * DELETE /api/v1/products/invites/:productId decline -> IdResponse\n * GET /api/v1/products/by-member/:userId productCardPageSchema (their teams)\n * GET /api/v1/products/:productId productSchema\n * PATCH /api/v1/products/:productId updateProductBodySchema -> productSchema\n * DELETE /api/v1/products/:productId -> IdResponse (owner)\n * PUT /api/v1/products/:productId/logo setProductLogoBodySchema -> productSchema\n * DELETE /api/v1/products/:productId/logo -> productSchema\n * PUT /api/v1/products/:productId/screenshots setProductScreenshotsBodySchema -> productSchema\n * PUT /api/v1/products/:productId/visibility setProductVisibilityBodySchema -> productSchema\n * PUT /api/v1/products/:productId/status setProductStatusBodySchema -> productSchema\n * GET /api/v1/products/:productId/team productTeamPageSchema\n * GET /api/v1/products/:productId/invites productPendingInvitePageSchema (managers)\n * POST /api/v1/products/:productId/invites inviteProductMemberBodySchema -> productPendingInviteSchema\n * PUT /api/v1/products/:productId/team/:userId setProductMemberRoleBodySchema -> IdResponse\n * (works on someone still invited too; refetch the team and the invites)\n * DELETE /api/v1/products/:productId/team/:userId remove, cancel an invite, or leave -> IdResponse\n * POST /api/v1/products/:productId/transfer transferProductBodySchema -> productSchema\n * PUT /api/v1/products/:productId/upvote -> productUpvoteResponseSchema\n * DELETE /api/v1/products/:productId/upvote -> productUpvoteResponseSchema\n * GET /api/v1/products/:productId/posts FeedPage (posts and polls tagged with it)\n * GET /api/v1/products/:productId/feedback productFeedbackQuerySchema -> productFeedbackPageSchema (feed)\n * GET /api/v1/products/:productId/testers productTesterPageSchema\n * PUT /api/v1/products/:productId/testers/:userId confirm -> productTesterSchema\n * DELETE /api/v1/products/:productId/testers/:userId withdraw -> IdResponse\n * POST /api/v1/products/:productId/report createReportBodySchema -> CreateReportResponse\n * (reviews: `domains/reviews`)\n *\n * @module founder-schema/domains/products\n */\n\nimport { z } from 'zod';\nimport {\n emptyStringToUndefined,\n httpUrlOnHosts,\n httpUrlSchema,\n industrySchema,\n multiValueQuery,\n objectIdSchema,\n optionalTrimmedString,\n paginationQuerySchema,\n productListingRequirementSchema,\n youtubeVideoId,\n} from '../../core/common.js';\nimport {\n DISCOVER_FILTER_VALUES_MAX,\n DISCOVER_TEXT_MAX,\n PRODUCT_CAPTION_MAX,\n PRODUCT_DESCRIPTION_MAX,\n PRODUCT_NAME_MAX,\n PRODUCT_SCREENSHOTS_MAX,\n PRODUCT_TAGLINE_MAX,\n} from '../../core/limits.js';\nimport { paginatedSchema } from '../../core/responses.js';\nimport { VALIDATION_MESSAGE } from '../../core/validation.js';\nimport { mediaImageSchema } from '../media/media.js';\nimport { topicSchema } from '../onboarding/onboarding.js';\nimport { memberBylineSchema } from '../profile/founder-profile.js';\n\n/** Topics a product carries, as a post does: what interest matching reads. */\nexport const PRODUCT_TOPICS_MAX = 3;\n\n// ─── Vocabulary ──────────────────────────────────────────────────────────────\n// ⚠ Every list below is STORED. Append only; removing a value orphans rows.\n\n/**\n * Where the product is in its life. Its own list, deliberately not the\n * venture's funding stage (`startupStageSchema`): \"seed\" says how a company is\n * funded, \"beta\" says whether you can use the thing. Ordered earliest first.\n */\nexport const PRODUCT_STAGE_VALUES = ['idea', 'building', 'beta', 'live'] as const;\nexport const productStageSchema = z.enum(PRODUCT_STAGE_VALUES);\nexport type ProductStage = z.infer<typeof productStageSchema>;\n\nexport const PRODUCT_PLATFORM_VALUES = [\n 'web',\n 'ios',\n 'android',\n 'desktop',\n 'browser_extension',\n 'api',\n 'hardware',\n 'other',\n] as const;\nexport const productPlatformSchema = z.enum(PRODUCT_PLATFORM_VALUES);\nexport type ProductPlatform = z.infer<typeof productPlatformSchema>;\n\n/** `unlisted` (the default) or `listed` in Discover. See the module note. */\nexport const PRODUCT_VISIBILITY_VALUES = ['unlisted', 'listed'] as const;\nexport const productVisibilitySchema = z.enum(PRODUCT_VISIBILITY_VALUES);\nexport type ProductVisibility = z.infer<typeof productVisibilitySchema>;\n\n/**\n * `archived`: kept, readable and still on its team's profiles, but out of\n * Discover and closed to new posts, reviews and upvotes. Restorable.\n */\nexport const PRODUCT_STATUS_VALUES = ['active', 'archived'] as const;\nexport const productStatusSchema = z.enum(PRODUCT_STATUS_VALUES);\nexport type ProductStatus = z.infer<typeof productStatusSchema>;\n\n/** One owner per product; see the module note for what each role may do. */\nexport const PRODUCT_TEAM_ROLE_VALUES = ['owner', 'cofounder', 'team'] as const;\nexport const productTeamRoleSchema = z.enum(PRODUCT_TEAM_ROLE_VALUES);\nexport type ProductTeamRole = z.infer<typeof productTeamRoleSchema>;\n\n/** The roles an invitation (or a role change) may give. Ownership is handed over, never invited. */\nexport const PRODUCT_INVITABLE_ROLE_VALUES = ['cofounder', 'team'] as const;\nexport const productInvitableRoleSchema = z.enum(PRODUCT_INVITABLE_ROLE_VALUES);\nexport type ProductInvitableRole = z.infer<typeof productInvitableRoleSchema>;\n\n/**\n * What a post or poll about a product ASKS of the community. Optional, and\n * only with a product. Each ask keeps the product on that shelf of Discover\n * for `PRODUCT_ASK_OPEN_DAYS`.\n *\n * feedback \"tell me what you think\"\n * testers \"try it\": confirmed testers are recognised (`/testers`)\n * launch \"it is out\"\n * ideas \"what should it do next\"\n */\nexport const PRODUCT_ASK_VALUES = ['feedback', 'testers', 'launch', 'ideas'] as const;\nexport const productAskSchema = z.enum(PRODUCT_ASK_VALUES);\nexport type ProductAsk = z.infer<typeof productAskSchema>;\n\n/**\n * Discover's orders.\n *\n * trending recent upvotes, reviews and feedback, newer counting more\n * (recomputed every 15 minutes). The default.\n * new newest first by when it was FIRST listed (unlisting and\n * listing again does not move it back to the top)\n * top_rated best rated, pulled toward a neutral 3 stars by 5 imaginary\n * reviews so a few perfect ratings cannot beat many excellent\n * ones; only products with `REVIEW_AVERAGE_MIN_COUNT` reviews\n */\nexport const PRODUCT_SORT_VALUES = ['trending', 'new', 'top_rated'] as const;\nexport const productSortSchema = z.enum(PRODUCT_SORT_VALUES);\nexport type ProductSort = z.infer<typeof productSortSchema>;\n\n/**\n * What listing needs (defined in core, beside the error details that carry it:\n * `PRODUCT_NOT_LISTABLE` returns the missing ones in `details.missing`).\n */\nexport {\n PRODUCT_LISTING_REQUIREMENT_VALUES,\n type ProductListingRequirement,\n productListingRequirementSchema,\n} from '../../core/common.js';\n\n// ─── Fields ──────────────────────────────────────────────────────────────────\n\n/**\n * Where to get it. Every link is member-typed, so every one is\n * `httpUrlSchema`, and the store links must also be ON the store: the\n * hostname is parsed and compared exactly (`httpUrlOnHosts`).\n */\nexport const productLinksSchema = z.object({\n website: httpUrlSchema.optional(),\n appStore: httpUrlOnHosts(\n ['apps.apple.com', 'itunes.apple.com'],\n VALIDATION_MESSAGE.appStoreLinkHost,\n ).optional(),\n playStore: httpUrlOnHosts(['play.google.com'], VALIDATION_MESSAGE.playStoreLinkHost).optional(),\n github: httpUrlOnHosts(\n ['github.com', 'www.github.com'],\n VALIDATION_MESSAGE.githubLinkHost,\n ).optional(),\n});\nexport type ProductLinks = z.infer<typeof productLinksSchema>;\n\n/**\n * A demo video: a link to one YouTube VIDEO, played in the page (never\n * uploaded). A channel or playlist link is refused: the page cannot embed it\n * (`youtubeVideoId`, 0.7.0).\n */\nexport const productVideoUrlSchema = httpUrlSchema.refine((url) => youtubeVideoId(url) !== null, {\n error: VALIDATION_MESSAGE.videoLinkHost,\n});\n\nconst platformsSchema = z\n .array(productPlatformSchema)\n .max(PRODUCT_PLATFORM_VALUES.length)\n .refine((list) => new Set(list).size === list.length, {\n error: VALIDATION_MESSAGE.platformsDuplicate,\n });\n\n// ─── Read shapes ─────────────────────────────────────────────────────────────\n\n/**\n * A product named on something else: the chip on a post or poll, a\n * notification, a points entry. `logoUrl` is the logo's smallest size.\n */\nexport const productChipSchema = z.object({\n id: objectIdSchema,\n /** For a readable URL, `/products/<id>/<slug>`. The id is what resolves; a renamed product keeps its links. */\n slug: z.string(),\n name: z.string(),\n logoUrl: z.url().optional(),\n});\nexport type ProductChip = z.infer<typeof productChipSchema>;\n\n/**\n * How it is rated. `average` (one decimal) is null until the product has\n * `REVIEW_AVERAGE_MIN_COUNT` reviews: a client shows \"Not enough reviews yet\",\n * never a lone 5.0 from one friend.\n */\nexport const productRatingSchema = z.object({\n count: z.number().int().nonnegative(),\n average: z.number().min(1).max(5).nullable(),\n});\nexport type ProductRating = z.infer<typeof productRatingSchema>;\n\n/** One screenshot: a processed image (every size, ready for `srcset`) and its caption. */\nexport const productScreenshotSchema = mediaImageSchema.extend({\n caption: z.string().max(PRODUCT_CAPTION_MAX).optional(),\n});\nexport type ProductScreenshot = z.infer<typeof productScreenshotSchema>;\n\n/** What this viewer may do on a Discover card. */\nexport const productCardViewerSchema = z.object({\n upvoted: z.boolean(),\n /** Not on its team, and the product is open (not archived). */\n canUpvote: z.boolean(),\n /** Their role on its team, or null. */\n role: productTeamRoleSchema.nullable(),\n /**\n * They may act FOR it now (0.7.0): on its team, and it is neither archived\n * nor hidden by staff. The server's own rule, for a picker such as the\n * composer's \"about which product\" (the page's `viewer.canRepresent`).\n */\n canRepresent: z.boolean().optional(),\n});\n\n/**\n * A product on Discover, on a profile, in \"my products\". `cover` is the first\n * screenshot. `openAsks` are the asks whose window is open now, by the\n * server's clock (\"Testers wanted\").\n */\nexport const productCardSchema = z.object({\n id: objectIdSchema,\n slug: z.string(),\n name: z.string(),\n tagline: z.string().optional(),\n logo: mediaImageSchema.optional(),\n cover: mediaImageSchema.optional(),\n industry: industrySchema,\n stage: productStageSchema,\n platforms: z.array(productPlatformSchema),\n visibility: productVisibilitySchema,\n status: productStatusSchema,\n rating: productRatingSchema,\n upvoteCount: z.number().int().nonnegative(),\n openAsks: z.array(productAskSchema),\n /**\n * Staff hid it (0.7.0). Only ever on a card its team or staff can see (in\n * \"my products\", on a team member's profile): a \"Hidden by moderators\" badge.\n */\n hiddenByStaff: z.boolean().optional(),\n viewer: productCardViewerSchema.optional(),\n});\nexport type ProductCard = z.infer<typeof productCardSchema>;\n\n/** One person on a product's team, live-joined like every byline. */\nexport const productTeamMemberSchema = memberBylineSchema.extend({\n role: productTeamRoleSchema,\n /** When they accepted (or, for the owner, created the product). */\n joinedAt: z.iso.datetime(),\n});\nexport type ProductTeamMember = z.infer<typeof productTeamMemberSchema>;\n\n/**\n * What THIS viewer may do on the product page, decided by the server and sent\n * as plain answers (the same rule as `viewerStateSchema` on a post).\n */\nexport const productViewerSchema = productCardViewerSchema.extend({\n /** An invitation to the team is waiting for them: offer Accept / Decline. */\n invited: z.boolean(),\n /** Their own review of it, if any, so the page offers Edit instead of Write. */\n reviewId: objectIdSchema.nullable(),\n /** The team confirmed them as a tester. */\n tester: z.boolean(),\n /** Owner and co-founders: details, images, listing, invitations. */\n canEdit: z.boolean(),\n /** Owner: roles, removals, handing over. */\n canManageTeam: z.boolean(),\n /** Owner. */\n canDelete: z.boolean(),\n /** Anyone on the team: tag posts with it, reply to reviews, mark feedback, confirm testers. */\n canRepresent: z.boolean(),\n /** Not on its team, no review yet, and the product is open. */\n canReview: z.boolean(),\n canReport: z.boolean(),\n /**\n * For whoever may edit: what listing still needs. Empty means it can be\n * listed (or already is). Lets the page show a checklist before the member\n * tries and is refused.\n */\n missingForListing: z.array(productListingRequirementSchema),\n});\nexport type ProductViewer = z.infer<typeof productViewerSchema>;\n\n/** The product page. */\nexport const productSchema = productCardSchema.extend({\n description: z.string().optional(),\n links: productLinksSchema,\n videoUrl: z.string().optional(),\n topics: z.array(topicSchema).max(PRODUCT_TOPICS_MAX),\n screenshots: z.array(productScreenshotSchema).max(PRODUCT_SCREENSHOTS_MAX),\n /** The owner first, then co-founders, then the team, each by when they joined; at most `PRODUCT_TEAM_SHOWN`. */\n team: z.array(productTeamMemberSchema),\n teamCount: z.number().int().nonnegative(),\n counts: z.object({\n /** Posts and polls tagged with it. */\n posts: z.number().int().nonnegative(),\n /** Comments on those from people outside its team: what the Feedback tab lists. */\n feedback: z.number().int().nonnegative(),\n /** Members the team confirmed as testers. */\n testers: z.number().int().nonnegative(),\n }),\n listedAt: z.iso.datetime().nullable(),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n /**\n * Only for its team and for staff: staff hid it, so everyone else gets 404.\n * The page tells the team why it vanished from Discover.\n */\n hiddenByStaff: z.boolean().optional(),\n viewer: productViewerSchema.optional(),\n});\nexport type Product = z.infer<typeof productSchema>;\n\n/**\n * An invitation the team sent and nobody has answered yet, as its managers see\n * it (`GET /products/:id/invites`): who, for what role, sent by whom. The owner\n * may change its role (`PUT /team/:userId`) or cancel it (`DELETE /team/:userId`).\n */\nexport const productPendingInviteSchema = z.object({\n member: memberBylineSchema,\n role: productInvitableRoleSchema,\n /** Null when whoever invited has since deleted their account. */\n invitedBy: memberBylineSchema.nullable(),\n invitedAt: z.iso.datetime(),\n});\nexport type ProductPendingInvite = z.infer<typeof productPendingInviteSchema>;\n\n/** A team invitation waiting for the viewer's answer. */\nexport const productInviteSchema = z.object({\n product: productChipSchema.extend({ tagline: z.string().optional() }),\n role: productInvitableRoleSchema,\n /** Null when whoever invited has since deleted their account. */\n invitedBy: memberBylineSchema.nullable(),\n invitedAt: z.iso.datetime(),\n});\nexport type ProductInvite = z.infer<typeof productInviteSchema>;\n\n/** `GET /products/invites`. Never paged: invitations are few, and each needs an answer. */\nexport const productInvitesSchema = z.object({ items: z.array(productInviteSchema) });\nexport type ProductInvites = z.infer<typeof productInvitesSchema>;\n\n/**\n * `GET /products/mine`: every product the viewer is on the team of, archived\n * included, owned first. Not paged: a founder owns at most `PRODUCTS_OWNED_MAX`,\n * and joins teams by accepting invitations one at a time, so the list stays\n * short in practice; there is no hard cap on teams joined.\n */\nexport const myProductsSchema = z.object({ items: z.array(productCardSchema) });\nexport type MyProducts = z.infer<typeof myProductsSchema>;\n\n/** A member the team confirmed tested the product. */\nexport const productTesterSchema = z.object({\n member: memberBylineSchema,\n confirmedAt: z.iso.datetime(),\n});\nexport type ProductTester = z.infer<typeof productTesterSchema>;\n\nexport const productCardPageSchema = paginatedSchema(productCardSchema);\nexport type ProductCardPage = z.infer<typeof productCardPageSchema>;\nexport const productTeamPageSchema = paginatedSchema(productTeamMemberSchema);\nexport type ProductTeamPage = z.infer<typeof productTeamPageSchema>;\nexport const productTesterPageSchema = paginatedSchema(productTesterSchema);\nexport type ProductTesterPage = z.infer<typeof productTesterPageSchema>;\n/** Co-founder invitations first, then team; within each, the oldest invitation first. */\nexport const productPendingInvitePageSchema = paginatedSchema(productPendingInviteSchema);\nexport type ProductPendingInvitePage = z.infer<typeof productPendingInvitePageSchema>;\n\n/** `PUT|DELETE /products/:id/upvote`: the state it settled on and the fresh count. */\nexport const productUpvoteResponseSchema = z.object({\n productId: objectIdSchema,\n upvoted: z.boolean(),\n upvoteCount: z.number().int().nonnegative(),\n});\nexport type ProductUpvoteResponse = z.infer<typeof productUpvoteResponseSchema>;\n\n/**\n * Discover's filter drawer for products: every value with how many LISTED\n * products match, zero counts included, in the list's own order.\n */\nconst facetSchema = <T extends z.ZodType>(value: T) =>\n z.array(z.object({ value, count: z.number().int().nonnegative() }));\nexport const productFacetsSchema = z.object({\n industries: facetSchema(industrySchema),\n stages: facetSchema(productStageSchema),\n platforms: facetSchema(productPlatformSchema),\n asks: facetSchema(productAskSchema),\n});\nexport type ProductFacets = z.infer<typeof productFacetsSchema>;\n\n// ─── Queries and params ──────────────────────────────────────────────────────\n\n/** A Discover multi-select (`?industry=a&industry=b`): see `multiValueQuery`. */\nconst multiValue = <T extends z.ZodType>(inner: T) =>\n multiValueQuery(inner, DISCOVER_FILTER_VALUES_MAX);\n\n/**\n * `GET /api/v1/products`: LISTED products only. Filters of one kind mean \"any\n * of\", different kinds combine (\"fintech AND beta\"). `ask` keeps products\n * whose ask is open now. `q` matches the start of the name; an emptied box\n * (`?q=`) is no search, never a 400.\n */\nexport const productDiscoverQuerySchema = paginationQuerySchema.extend({\n sort: z.preprocess(emptyStringToUndefined, productSortSchema.default('trending')),\n q: optionalTrimmedString(DISCOVER_TEXT_MAX),\n industry: multiValue(industrySchema),\n stage: multiValue(productStageSchema),\n platform: multiValue(productPlatformSchema),\n ask: z.preprocess(emptyStringToUndefined, productAskSchema.optional()),\n});\nexport type ProductDiscoverQuery = z.infer<typeof productDiscoverQuerySchema>;\nexport type ProductDiscoverQueryInput = z.input<typeof productDiscoverQuerySchema>;\n\n/**\n * `GET /products/:id/feedback`: comments from outside its team on the posts\n * and polls tagged with it, newest first. `helpful=true` narrows to the ones\n * the team marked as having helped.\n */\nexport const productFeedbackQuerySchema = paginationQuerySchema.extend({\n helpful: z.preprocess(emptyStringToUndefined, z.stringbool().default(false)),\n});\nexport type ProductFeedbackQuery = z.infer<typeof productFeedbackQuerySchema>;\nexport type ProductFeedbackQueryInput = z.input<typeof productFeedbackQuerySchema>;\n\nexport const productParamsSchema = z.object({ productId: objectIdSchema });\nexport type ProductParams = z.infer<typeof productParamsSchema>;\n/** `/products/:productId/team/:userId`, `/products/:productId/testers/:userId`. */\nexport const productMemberParamsSchema = z.object({\n productId: objectIdSchema,\n userId: objectIdSchema,\n});\nexport type ProductMemberParams = z.infer<typeof productMemberParamsSchema>;\n/** `/products/by-member/:userId`. */\nexport const productsByMemberParamsSchema = z.object({ userId: objectIdSchema });\nexport type ProductsByMemberParams = z.infer<typeof productsByMemberParamsSchema>;\n\n// ─── Write bodies ────────────────────────────────────────────────────────────\n// Each its own object with NO defaults (see `updateFounderProfileBodySchema`).\n\n/** A screenshot on the way in: an uploaded, processed image id, and its caption. */\nexport const productScreenshotInputSchema = z.object({\n mediaId: objectIdSchema,\n caption: z.string().trim().max(PRODUCT_CAPTION_MAX).optional(),\n});\nexport type ProductScreenshotInput = z.infer<typeof productScreenshotInputSchema>;\n\nconst screenshotsInputSchema = z\n .array(productScreenshotInputSchema)\n .max(PRODUCT_SCREENSHOTS_MAX)\n .refine((list) => new Set(list.map((s) => s.mediaId)).size === list.length, {\n error: VALIDATION_MESSAGE.screenshotsDuplicate,\n });\n\n/**\n * `POST /api/v1/products`. Starts `unlisted`, owned by the caller. The logo\n * and screenshots may come now or later (uploaded first, purpose\n * `product_logo` / `product_screenshot`, like a post's images).\n */\nexport const createProductBodySchema = z.object({\n name: z.string().trim().min(1).max(PRODUCT_NAME_MAX),\n tagline: z.string().trim().min(1).max(PRODUCT_TAGLINE_MAX).optional(),\n description: z.string().trim().min(1).max(PRODUCT_DESCRIPTION_MAX).optional(),\n industry: industrySchema,\n stage: productStageSchema,\n platforms: platformsSchema.optional(),\n topics: z.array(topicSchema).max(PRODUCT_TOPICS_MAX).optional(),\n links: productLinksSchema.optional(),\n videoUrl: productVideoUrlSchema.optional(),\n logoMediaId: objectIdSchema.optional(),\n screenshots: screenshotsInputSchema.optional(),\n});\nexport type CreateProductBody = z.infer<typeof createProductBodySchema>;\n\n/** Text the editor may empty: absent leaves it, `null` clears it, `\"\"` is refused. */\nconst clearable = <T extends z.ZodType>(inner: T) => inner.nullable().optional();\n\n/**\n * `PATCH /api/v1/products/:id`: only the keys that changed. Images, listing\n * and status have their own routes. `links` is sent whole.\n */\nexport const updateProductBodySchema = z.object({\n name: z.string().trim().min(1).max(PRODUCT_NAME_MAX).optional(),\n tagline: clearable(\n z.string().trim().min(1, VALIDATION_MESSAGE.clearWithNull).max(PRODUCT_TAGLINE_MAX),\n ),\n description: clearable(\n z.string().trim().min(1, VALIDATION_MESSAGE.clearWithNull).max(PRODUCT_DESCRIPTION_MAX),\n ),\n industry: industrySchema.optional(),\n stage: productStageSchema.optional(),\n platforms: platformsSchema.optional(),\n topics: z.array(topicSchema).max(PRODUCT_TOPICS_MAX).optional(),\n links: productLinksSchema.optional(),\n videoUrl: clearable(productVideoUrlSchema),\n});\nexport type UpdateProductBody = z.infer<typeof updateProductBodySchema>;\n\n/** `PUT /products/:id/logo`: a processed `product_logo` upload. The old logo's files are deleted. */\nexport const setProductLogoBodySchema = z.object({ mediaId: objectIdSchema });\nexport type SetProductLogoBody = z.infer<typeof setProductLogoBodySchema>;\n\n/**\n * `PUT /products/:id/screenshots`: the WHOLE gallery as it should now be, in\n * order. One call adds, removes, reorders and re-captions: screenshots already\n * on the product stay; new ids must be the caller's processed\n * `product_screenshot` uploads; any left out are deleted from storage.\n */\nexport const setProductScreenshotsBodySchema = z.object({ screenshots: screenshotsInputSchema });\nexport type SetProductScreenshotsBody = z.infer<typeof setProductScreenshotsBodySchema>;\n\nexport const setProductVisibilityBodySchema = z.object({ visibility: productVisibilitySchema });\nexport type SetProductVisibilityBody = z.infer<typeof setProductVisibilityBodySchema>;\n\nexport const setProductStatusBodySchema = z.object({ status: productStatusSchema });\nexport type SetProductStatusBody = z.infer<typeof setProductStatusBodySchema>;\n\n/**\n * Invite a member to the team; they must accept. `userId` is the member's id\n * as every card carries it (`founderCardSchema.userId`). Someone who cannot\n * join (has not finished onboarding, paused, suspended, deleted) is\n * `PRODUCT_MEMBER_NOT_INVITABLE`; someone already on it or invited,\n * `PRODUCT_ALREADY_MEMBER`.\n */\nexport const inviteProductMemberBodySchema = z.object({\n userId: objectIdSchema,\n role: productInvitableRoleSchema,\n});\nexport type InviteProductMemberBody = z.infer<typeof inviteProductMemberBodySchema>;\n\n/**\n * The owner changes someone's role (on the team or still invited). The\n * owner's own role changes only by handing over (`PRODUCT_OWNER_MUST_TRANSFER`);\n * someone not on the team or invited is `PRODUCT_NOT_ON_TEAM`.\n */\nexport const setProductMemberRoleBodySchema = z.object({ role: productInvitableRoleSchema });\nexport type SetProductMemberRoleBody = z.infer<typeof setProductMemberRoleBodySchema>;\n\n/**\n * The owner hands the product to someone already on its team (not merely\n * invited: `PRODUCT_NOT_ON_TEAM`), who must have room under\n * `PRODUCTS_OWNED_MAX` (`PRODUCT_LIMIT_REACHED`). The old owner becomes a co-founder.\n */\nexport const transferProductBodySchema = z.object({ userId: objectIdSchema });\nexport type TransferProductBody = z.infer<typeof transferProductBodySchema>;\n"]}
1
+ {"version":3,"file":"products.js","sourceRoot":"","sources":["../../../src/domains/products/products.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * founder-schema — Products: what founders build, and the help around it\n *\n * THE IDEA (the user, 2026-10-06): founders help each other with their\n * products. A founder adds what they build; a post or poll can say which of\n * their products it is about and what they want (\"testers wanted\"); every\n * comment on it becomes that product's feedback; the community reviews and\n * upvotes it; and the help a member gives is recognised in their contribution\n * score.\n *\n * THE COMPANY STAYS THE PROFILE'S `venture` (one per founder). There are no\n * company pages: co-founders join a PRODUCT's team, as Product Hunt lists a\n * product's makers. Revisit only if one team running many products finds\n * re-inviting each time tedious.\n *\n * VISIBILITY, two states (the user's ruling): `unlisted` by default, a page\n * anyone signed in can open by its link and that shows on its team's profiles;\n * `listed`, also in Discover. Listing needs a logo, a tagline and at least one\n * screenshot (`PRODUCT_NOT_LISTABLE` names what is missing), so Discover never\n * shows an empty card.\n *\n * THE TEAM: an owner, co-founders and team members, joined by invitation and\n * acceptance (nobody is put on a team without saying yes), with no limit on\n * its size (the user's ruling). Who may do what:\n *\n * owner co-founder team\n * edit, images, list, invite ✓ ✓\n * tag posts, reply to reviews, ✓ ✓ ✓\n * mark feedback, confirm testers\n * change roles, remove, hand over ✓\n * archive, delete ✓\n *\n * A product's images belong to the product, not to whoever uploaded them.\n * When the owner deletes their account the product passes to the longest-\n * standing co-founder (else team member); with nobody left it is deleted.\n *\n * Routes (all signed in):\n * GET /api/v1/products Discover: productDiscoverQuerySchema\n * GET /api/v1/products/facets productFacetsSchema\n * POST /api/v1/products createProductBodySchema -> IdResponse\n * GET /api/v1/products/mine myProductsSchema\n * GET /api/v1/products/invites productInvitesSchema\n * PUT /api/v1/products/invites/:productId accept -> productSchema\n * DELETE /api/v1/products/invites/:productId decline -> IdResponse\n * GET /api/v1/products/by-member/:userId productCardPageSchema (their teams)\n * GET /api/v1/products/:productId productSchema\n * PATCH /api/v1/products/:productId updateProductBodySchema -> productSchema\n * DELETE /api/v1/products/:productId -> IdResponse (owner)\n * PUT /api/v1/products/:productId/logo setProductLogoBodySchema -> productSchema\n * DELETE /api/v1/products/:productId/logo -> productSchema\n * PUT /api/v1/products/:productId/screenshots setProductScreenshotsBodySchema -> productSchema\n * PUT /api/v1/products/:productId/visibility setProductVisibilityBodySchema -> productSchema\n * PUT /api/v1/products/:productId/status setProductStatusBodySchema -> productSchema\n * PUT /api/v1/products/:productId/live setProductLiveBodySchema -> productSchema (0.12.0)\n * GET /api/v1/products/:productId/team productTeamPageSchema\n * GET /api/v1/products/:productId/invites productPendingInvitePageSchema (managers)\n * POST /api/v1/products/:productId/invites inviteProductMemberBodySchema -> productPendingInviteSchema\n * PUT /api/v1/products/:productId/team/:userId setProductMemberRoleBodySchema -> IdResponse\n * (works on someone still invited too; refetch the team and the invites)\n * DELETE /api/v1/products/:productId/team/:userId remove, cancel an invite, or leave -> IdResponse\n * POST /api/v1/products/:productId/transfer transferProductBodySchema -> productSchema\n * PUT /api/v1/products/:productId/upvote -> productUpvoteResponseSchema\n * DELETE /api/v1/products/:productId/upvote -> productUpvoteResponseSchema\n * GET /api/v1/products/:productId/posts FeedPage (posts and polls tagged with it)\n * GET /api/v1/products/:productId/feedback productFeedbackQuerySchema -> productFeedbackPageSchema (feed)\n * GET /api/v1/products/:productId/testers productTesterPageSchema\n * PUT /api/v1/products/:productId/testers/:userId confirm -> productTesterSchema\n * DELETE /api/v1/products/:productId/testers/:userId withdraw -> IdResponse\n * POST /api/v1/products/:productId/report createReportBodySchema -> CreateReportResponse\n * (reviews: `domains/reviews`)\n *\n * @module founder-schema/domains/products\n */\n\nimport { z } from 'zod';\nimport {\n emptyStringToUndefined,\n httpUrlOnHosts,\n httpUrlSchema,\n industrySchema,\n multiValueQuery,\n objectIdSchema,\n optionalTrimmedString,\n paginationQuerySchema,\n productListingRequirementSchema,\n youtubeVideoId,\n} from '../../core/common.js';\nimport {\n DISCOVER_FILTER_VALUES_MAX,\n DISCOVER_TEXT_MAX,\n PRODUCT_CAPTION_MAX,\n PRODUCT_DESCRIPTION_MAX,\n PRODUCT_NAME_MAX,\n PRODUCT_SCREENSHOTS_MAX,\n PRODUCT_TAGLINE_MAX,\n} from '../../core/limits.js';\nimport { paginatedSchema } from '../../core/responses.js';\nimport { VALIDATION_MESSAGE } from '../../core/validation.js';\nimport { mediaImageSchema } from '../media/media.js';\nimport { topicSchema } from '../onboarding/onboarding.js';\nimport { memberBylineSchema } from '../profile/founder-profile.js';\n\n/** Topics a product carries, as a post does: what interest matching reads. */\nexport const PRODUCT_TOPICS_MAX = 3;\n\n// ─── Vocabulary ──────────────────────────────────────────────────────────────\n// ⚠ Every list below is STORED. Append only; removing a value orphans rows.\n\n/**\n * Where the product is in its life. Its own list, deliberately not the\n * venture's funding stage (`startupStageSchema`): \"seed\" says how a company is\n * funded, \"beta\" says whether you can use the thing. Ordered earliest first.\n */\nexport const PRODUCT_STAGE_VALUES = ['idea', 'building', 'beta', 'live'] as const;\nexport const productStageSchema = z.enum(PRODUCT_STAGE_VALUES);\nexport type ProductStage = z.infer<typeof productStageSchema>;\n\nexport const PRODUCT_PLATFORM_VALUES = [\n 'web',\n 'ios',\n 'android',\n 'desktop',\n 'browser_extension',\n 'api',\n 'hardware',\n 'other',\n] as const;\nexport const productPlatformSchema = z.enum(PRODUCT_PLATFORM_VALUES);\nexport type ProductPlatform = z.infer<typeof productPlatformSchema>;\n\n/** `unlisted` (the default) or `listed` in Discover. See the module note. */\nexport const PRODUCT_VISIBILITY_VALUES = ['unlisted', 'listed'] as const;\nexport const productVisibilitySchema = z.enum(PRODUCT_VISIBILITY_VALUES);\nexport type ProductVisibility = z.infer<typeof productVisibilitySchema>;\n\n/**\n * `archived`: kept, readable and still on its team's profiles, but out of\n * Discover and closed to new posts, reviews and upvotes. Restorable.\n */\nexport const PRODUCT_STATUS_VALUES = ['active', 'archived'] as const;\nexport const productStatusSchema = z.enum(PRODUCT_STATUS_VALUES);\nexport type ProductStatus = z.infer<typeof productStatusSchema>;\n\n/** One owner per product; see the module note for what each role may do. */\nexport const PRODUCT_TEAM_ROLE_VALUES = ['owner', 'cofounder', 'team'] as const;\nexport const productTeamRoleSchema = z.enum(PRODUCT_TEAM_ROLE_VALUES);\nexport type ProductTeamRole = z.infer<typeof productTeamRoleSchema>;\n\n/** The roles an invitation (or a role change) may give. Ownership is handed over, never invited. */\nexport const PRODUCT_INVITABLE_ROLE_VALUES = ['cofounder', 'team'] as const;\nexport const productInvitableRoleSchema = z.enum(PRODUCT_INVITABLE_ROLE_VALUES);\nexport type ProductInvitableRole = z.infer<typeof productInvitableRoleSchema>;\n\n/**\n * What a post or poll about a product ASKS of the community. Optional, and\n * only with a product. Each ask keeps the product on that shelf of Discover\n * for `PRODUCT_ASK_OPEN_DAYS`.\n *\n * feedback \"tell me what you think\"\n * testers \"try it\": confirmed testers are recognised (`/testers`)\n * launch \"it is out\"\n * ideas \"what should it do next\"\n */\nexport const PRODUCT_ASK_VALUES = ['feedback', 'testers', 'launch', 'ideas'] as const;\nexport const productAskSchema = z.enum(PRODUCT_ASK_VALUES);\nexport type ProductAsk = z.infer<typeof productAskSchema>;\n\n/**\n * Discover's orders.\n *\n * trending recent upvotes, reviews and feedback, newer counting more\n * (recomputed every 15 minutes). The default.\n * new newest first by when it was FIRST listed (unlisting and\n * listing again does not move it back to the top)\n * top_rated best rated, pulled toward a neutral 3 stars by 5 imaginary\n * reviews so a few perfect ratings cannot beat many excellent\n * ones; only products with `REVIEW_AVERAGE_MIN_COUNT` reviews\n */\nexport const PRODUCT_SORT_VALUES = ['trending', 'new', 'top_rated'] as const;\nexport const productSortSchema = z.enum(PRODUCT_SORT_VALUES);\nexport type ProductSort = z.infer<typeof productSortSchema>;\n\n/**\n * What listing needs (defined in core, beside the error details that carry it:\n * `PRODUCT_NOT_LISTABLE` returns the missing ones in `details.missing`).\n */\nexport {\n PRODUCT_LISTING_REQUIREMENT_VALUES,\n type ProductListingRequirement,\n productListingRequirementSchema,\n} from '../../core/common.js';\n\n// ─── Fields ──────────────────────────────────────────────────────────────────\n\n/**\n * Where to get it. Every link is member-typed, so every one is\n * `httpUrlSchema`, and the store links must also be ON the store: the\n * hostname is parsed and compared exactly (`httpUrlOnHosts`).\n */\nexport const productLinksSchema = z.object({\n website: httpUrlSchema.optional(),\n appStore: httpUrlOnHosts(\n ['apps.apple.com', 'itunes.apple.com'],\n VALIDATION_MESSAGE.appStoreLinkHost,\n ).optional(),\n playStore: httpUrlOnHosts(['play.google.com'], VALIDATION_MESSAGE.playStoreLinkHost).optional(),\n github: httpUrlOnHosts(\n ['github.com', 'www.github.com'],\n VALIDATION_MESSAGE.githubLinkHost,\n ).optional(),\n});\nexport type ProductLinks = z.infer<typeof productLinksSchema>;\n\n/**\n * A demo video: a link to one YouTube VIDEO, played in the page (never\n * uploaded). A channel or playlist link is refused: the page cannot embed it\n * (`youtubeVideoId`, 0.7.0).\n */\nexport const productVideoUrlSchema = httpUrlSchema.refine((url) => youtubeVideoId(url) !== null, {\n error: VALIDATION_MESSAGE.videoLinkHost,\n});\n\nconst platformsSchema = z\n .array(productPlatformSchema)\n .max(PRODUCT_PLATFORM_VALUES.length)\n .refine((list) => new Set(list).size === list.length, {\n error: VALIDATION_MESSAGE.platformsDuplicate,\n });\n\n// ─── Read shapes ─────────────────────────────────────────────────────────────\n\n/**\n * A product named on something else: the chip on a post or poll, a\n * notification, a points entry. `logoUrl` is the logo's smallest size.\n */\nexport const productChipSchema = z.object({\n id: objectIdSchema,\n /** For a readable URL, `/products/<id>/<slug>`. The id is what resolves; a renamed product keeps its links. */\n slug: z.string(),\n name: z.string(),\n logoUrl: z.url().optional(),\n});\nexport type ProductChip = z.infer<typeof productChipSchema>;\n\n/**\n * How it is rated. `average` (one decimal) is null until the product has\n * `REVIEW_AVERAGE_MIN_COUNT` reviews: a client shows \"Not enough reviews yet\",\n * never a lone 5.0 from one friend.\n */\nexport const productRatingSchema = z.object({\n count: z.number().int().nonnegative(),\n average: z.number().min(1).max(5).nullable(),\n});\nexport type ProductRating = z.infer<typeof productRatingSchema>;\n\n/** One screenshot: a processed image (every size, ready for `srcset`) and its caption. */\nexport const productScreenshotSchema = mediaImageSchema.extend({\n caption: z.string().max(PRODUCT_CAPTION_MAX).optional(),\n});\nexport type ProductScreenshot = z.infer<typeof productScreenshotSchema>;\n\n/** What this viewer may do on a Discover card. */\nexport const productCardViewerSchema = z.object({\n upvoted: z.boolean(),\n /** Not on its team, and the product is open (not archived). */\n canUpvote: z.boolean(),\n /** Their role on its team, or null. */\n role: productTeamRoleSchema.nullable(),\n /**\n * They may act FOR it now (0.7.0): on its team, and it is neither archived\n * nor hidden by staff. The server's own rule, for a picker such as the\n * composer's \"about which product\" (the page's `viewer.canRepresent`).\n */\n canRepresent: z.boolean().optional(),\n});\n\n/**\n * A product on Discover, on a profile, in \"my products\". `cover` is the first\n * screenshot. `openAsks` are the asks whose window is open now, by the\n * server's clock (\"Testers wanted\").\n */\nexport const productCardSchema = z.object({\n id: objectIdSchema,\n slug: z.string(),\n name: z.string(),\n tagline: z.string().optional(),\n logo: mediaImageSchema.optional(),\n cover: mediaImageSchema.optional(),\n industry: industrySchema,\n stage: productStageSchema,\n platforms: z.array(productPlatformSchema),\n visibility: productVisibilitySchema,\n status: productStatusSchema,\n rating: productRatingSchema,\n upvoteCount: z.number().int().nonnegative(),\n openAsks: z.array(productAskSchema),\n /**\n * Staff hid it (0.7.0). Only ever on a card its team or staff can see (in\n * \"my products\", on a team member's profile): a \"Hidden by moderators\" badge.\n */\n hiddenByStaff: z.boolean().optional(),\n /**\n * Paused (0.12.0): its owner owns more products than their plan keeps\n * live. Like a hidden one, only its team and staff see it at all: a\n * \"Paused\" badge. The owner makes it live again (`PUT .../live`) when a\n * place is free.\n */\n paused: z.boolean().optional(),\n viewer: productCardViewerSchema.optional(),\n});\nexport type ProductCard = z.infer<typeof productCardSchema>;\n\n/**\n * Why a product is paused (0.12.0). ⚠ Stored: append only.\n * limit over its owner's live places (a plan ended, a refund, joining\n * without one): it comes back by itself when a place frees\n * owner its owner paused it, to free a place for another: it stays\n * paused until they make it live\n */\nexport const PRODUCT_PAUSED_BY_VALUES = ['limit', 'owner'] as const;\nexport const productPausedBySchema = z.enum(PRODUCT_PAUSED_BY_VALUES);\nexport type ProductPausedBy = z.infer<typeof productPausedBySchema>;\n\n/** One person on a product's team, live-joined like every byline. */\nexport const productTeamMemberSchema = memberBylineSchema.extend({\n role: productTeamRoleSchema,\n /** When they accepted (or, for the owner, created the product). */\n joinedAt: z.iso.datetime(),\n});\nexport type ProductTeamMember = z.infer<typeof productTeamMemberSchema>;\n\n/**\n * What THIS viewer may do on the product page, decided by the server and sent\n * as plain answers (the same rule as `viewerStateSchema` on a post).\n */\nexport const productViewerSchema = productCardViewerSchema.extend({\n /** An invitation to the team is waiting for them: offer Accept / Decline. */\n invited: z.boolean(),\n /** Their own review of it, if any, so the page offers Edit instead of Write. */\n reviewId: objectIdSchema.nullable(),\n /** The team confirmed them as a tester. */\n tester: z.boolean(),\n /** Owner and co-founders: details, images, listing, invitations. */\n canEdit: z.boolean(),\n /** Owner: roles, removals, handing over. */\n canManageTeam: z.boolean(),\n /** Owner. */\n canDelete: z.boolean(),\n /**\n * Owner (0.12.0): may pause it, or make it live again. Making it live is\n * refused with `PRODUCT_LIMIT_REACHED` when no live place is free; the page\n * says so from `GET /me/membership`.\n */\n canSetLive: z.boolean(),\n /** Anyone on the team: tag posts with it, reply to reviews, mark feedback, confirm testers. */\n canRepresent: z.boolean(),\n /** Not on its team, no review yet, and the product is open. */\n canReview: z.boolean(),\n canReport: z.boolean(),\n /**\n * For whoever may edit: what listing still needs. Empty means it can be\n * listed (or already is). Lets the page show a checklist before the member\n * tries and is refused.\n */\n missingForListing: z.array(productListingRequirementSchema),\n});\nexport type ProductViewer = z.infer<typeof productViewerSchema>;\n\n/** The product page. */\nexport const productSchema = productCardSchema.extend({\n /** Set with `paused` (0.12.0): who paused it, so the page says why. */\n pausedBy: productPausedBySchema.optional(),\n description: z.string().optional(),\n links: productLinksSchema,\n videoUrl: z.string().optional(),\n topics: z.array(topicSchema).max(PRODUCT_TOPICS_MAX),\n screenshots: z.array(productScreenshotSchema).max(PRODUCT_SCREENSHOTS_MAX),\n /** The owner first, then co-founders, then the team, each by when they joined; at most `PRODUCT_TEAM_SHOWN`. */\n team: z.array(productTeamMemberSchema),\n teamCount: z.number().int().nonnegative(),\n counts: z.object({\n /** Posts and polls tagged with it. */\n posts: z.number().int().nonnegative(),\n /** Comments on those from people outside its team: what the Feedback tab lists. */\n feedback: z.number().int().nonnegative(),\n /** Members the team confirmed as testers. */\n testers: z.number().int().nonnegative(),\n }),\n listedAt: z.iso.datetime().nullable(),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n /**\n * Only for its team and for staff: staff hid it, so everyone else gets 404.\n * The page tells the team why it vanished from Discover.\n */\n hiddenByStaff: z.boolean().optional(),\n viewer: productViewerSchema.optional(),\n});\nexport type Product = z.infer<typeof productSchema>;\n\n/**\n * An invitation the team sent and nobody has answered yet, as its managers see\n * it (`GET /products/:id/invites`): who, for what role, sent by whom. The owner\n * may change its role (`PUT /team/:userId`) or cancel it (`DELETE /team/:userId`).\n */\nexport const productPendingInviteSchema = z.object({\n member: memberBylineSchema,\n role: productInvitableRoleSchema,\n /** Null when whoever invited has since deleted their account. */\n invitedBy: memberBylineSchema.nullable(),\n invitedAt: z.iso.datetime(),\n});\nexport type ProductPendingInvite = z.infer<typeof productPendingInviteSchema>;\n\n/** A team invitation waiting for the viewer's answer. */\nexport const productInviteSchema = z.object({\n product: productChipSchema.extend({ tagline: z.string().optional() }),\n role: productInvitableRoleSchema,\n /** Null when whoever invited has since deleted their account. */\n invitedBy: memberBylineSchema.nullable(),\n invitedAt: z.iso.datetime(),\n});\nexport type ProductInvite = z.infer<typeof productInviteSchema>;\n\n/** `GET /products/invites`. Never paged: invitations are few, and each needs an answer. */\nexport const productInvitesSchema = z.object({ items: z.array(productInviteSchema) });\nexport type ProductInvites = z.infer<typeof productInvitesSchema>;\n\n/**\n * `GET /products/mine`: every product the viewer is on the team of, archived\n * and paused included, owned first. Not paged: a founder lists few, and joins\n * teams by accepting invitations one at a time, so the list stays short in\n * practice; there is no hard cap on teams joined.\n */\nexport const myProductsSchema = z.object({ items: z.array(productCardSchema) });\nexport type MyProducts = z.infer<typeof myProductsSchema>;\n\n/** A member the team confirmed tested the product. */\nexport const productTesterSchema = z.object({\n member: memberBylineSchema,\n confirmedAt: z.iso.datetime(),\n});\nexport type ProductTester = z.infer<typeof productTesterSchema>;\n\nexport const productCardPageSchema = paginatedSchema(productCardSchema);\nexport type ProductCardPage = z.infer<typeof productCardPageSchema>;\nexport const productTeamPageSchema = paginatedSchema(productTeamMemberSchema);\nexport type ProductTeamPage = z.infer<typeof productTeamPageSchema>;\nexport const productTesterPageSchema = paginatedSchema(productTesterSchema);\nexport type ProductTesterPage = z.infer<typeof productTesterPageSchema>;\n/** Co-founder invitations first, then team; within each, the oldest invitation first. */\nexport const productPendingInvitePageSchema = paginatedSchema(productPendingInviteSchema);\nexport type ProductPendingInvitePage = z.infer<typeof productPendingInvitePageSchema>;\n\n/** `PUT|DELETE /products/:id/upvote`: the state it settled on and the fresh count. */\nexport const productUpvoteResponseSchema = z.object({\n productId: objectIdSchema,\n upvoted: z.boolean(),\n upvoteCount: z.number().int().nonnegative(),\n});\nexport type ProductUpvoteResponse = z.infer<typeof productUpvoteResponseSchema>;\n\n/**\n * Discover's filter drawer for products: every value with how many LISTED\n * products match, zero counts included, in the list's own order.\n */\nconst facetSchema = <T extends z.ZodType>(value: T) =>\n z.array(z.object({ value, count: z.number().int().nonnegative() }));\nexport const productFacetsSchema = z.object({\n industries: facetSchema(industrySchema),\n stages: facetSchema(productStageSchema),\n platforms: facetSchema(productPlatformSchema),\n asks: facetSchema(productAskSchema),\n});\nexport type ProductFacets = z.infer<typeof productFacetsSchema>;\n\n// ─── Queries and params ──────────────────────────────────────────────────────\n\n/** A Discover multi-select (`?industry=a&industry=b`): see `multiValueQuery`. */\nconst multiValue = <T extends z.ZodType>(inner: T) =>\n multiValueQuery(inner, DISCOVER_FILTER_VALUES_MAX);\n\n/**\n * `GET /api/v1/products`: LISTED products only. Filters of one kind mean \"any\n * of\", different kinds combine (\"fintech AND beta\"). `ask` keeps products\n * whose ask is open now. `q` matches the start of the name; an emptied box\n * (`?q=`) is no search, never a 400.\n */\nexport const productDiscoverQuerySchema = paginationQuerySchema.extend({\n sort: z.preprocess(emptyStringToUndefined, productSortSchema.default('trending')),\n q: optionalTrimmedString(DISCOVER_TEXT_MAX),\n industry: multiValue(industrySchema),\n stage: multiValue(productStageSchema),\n platform: multiValue(productPlatformSchema),\n ask: z.preprocess(emptyStringToUndefined, productAskSchema.optional()),\n});\nexport type ProductDiscoverQuery = z.infer<typeof productDiscoverQuerySchema>;\nexport type ProductDiscoverQueryInput = z.input<typeof productDiscoverQuerySchema>;\n\n/**\n * `GET /products/:id/feedback`: comments from outside its team on the posts\n * and polls tagged with it, newest first. `helpful=true` narrows to the ones\n * the team marked as having helped.\n */\nexport const productFeedbackQuerySchema = paginationQuerySchema.extend({\n helpful: z.preprocess(emptyStringToUndefined, z.stringbool().default(false)),\n});\nexport type ProductFeedbackQuery = z.infer<typeof productFeedbackQuerySchema>;\nexport type ProductFeedbackQueryInput = z.input<typeof productFeedbackQuerySchema>;\n\nexport const productParamsSchema = z.object({ productId: objectIdSchema });\nexport type ProductParams = z.infer<typeof productParamsSchema>;\n/** `/products/:productId/team/:userId`, `/products/:productId/testers/:userId`. */\nexport const productMemberParamsSchema = z.object({\n productId: objectIdSchema,\n userId: objectIdSchema,\n});\nexport type ProductMemberParams = z.infer<typeof productMemberParamsSchema>;\n/** `/products/by-member/:userId`. */\nexport const productsByMemberParamsSchema = z.object({ userId: objectIdSchema });\nexport type ProductsByMemberParams = z.infer<typeof productsByMemberParamsSchema>;\n\n// ─── Write bodies ────────────────────────────────────────────────────────────\n// Each its own object with NO defaults (see `updateFounderProfileBodySchema`).\n\n/** A screenshot on the way in: an uploaded, processed image id, and its caption. */\nexport const productScreenshotInputSchema = z.object({\n mediaId: objectIdSchema,\n caption: z.string().trim().max(PRODUCT_CAPTION_MAX).optional(),\n});\nexport type ProductScreenshotInput = z.infer<typeof productScreenshotInputSchema>;\n\nconst screenshotsInputSchema = z\n .array(productScreenshotInputSchema)\n .max(PRODUCT_SCREENSHOTS_MAX)\n .refine((list) => new Set(list.map((s) => s.mediaId)).size === list.length, {\n error: VALIDATION_MESSAGE.screenshotsDuplicate,\n });\n\n/**\n * `POST /api/v1/products`. Starts `unlisted`, owned by the caller. The logo\n * and screenshots may come now or later (uploaded first, purpose\n * `product_logo` / `product_screenshot`, like a post's images).\n */\nexport const createProductBodySchema = z.object({\n name: z.string().trim().min(1).max(PRODUCT_NAME_MAX),\n tagline: z.string().trim().min(1).max(PRODUCT_TAGLINE_MAX).optional(),\n description: z.string().trim().min(1).max(PRODUCT_DESCRIPTION_MAX).optional(),\n industry: industrySchema,\n stage: productStageSchema,\n platforms: platformsSchema.optional(),\n topics: z.array(topicSchema).max(PRODUCT_TOPICS_MAX).optional(),\n links: productLinksSchema.optional(),\n videoUrl: productVideoUrlSchema.optional(),\n logoMediaId: objectIdSchema.optional(),\n screenshots: screenshotsInputSchema.optional(),\n});\nexport type CreateProductBody = z.infer<typeof createProductBodySchema>;\n\n/** Text the editor may empty: absent leaves it, `null` clears it, `\"\"` is refused. */\nconst clearable = <T extends z.ZodType>(inner: T) => inner.nullable().optional();\n\n/**\n * `PATCH /api/v1/products/:id`: only the keys that changed. Images, listing\n * and status have their own routes. `links` is sent whole.\n */\nexport const updateProductBodySchema = z.object({\n name: z.string().trim().min(1).max(PRODUCT_NAME_MAX).optional(),\n tagline: clearable(\n z.string().trim().min(1, VALIDATION_MESSAGE.clearWithNull).max(PRODUCT_TAGLINE_MAX),\n ),\n description: clearable(\n z.string().trim().min(1, VALIDATION_MESSAGE.clearWithNull).max(PRODUCT_DESCRIPTION_MAX),\n ),\n industry: industrySchema.optional(),\n stage: productStageSchema.optional(),\n platforms: platformsSchema.optional(),\n topics: z.array(topicSchema).max(PRODUCT_TOPICS_MAX).optional(),\n links: productLinksSchema.optional(),\n videoUrl: clearable(productVideoUrlSchema),\n});\nexport type UpdateProductBody = z.infer<typeof updateProductBodySchema>;\n\n/** `PUT /products/:id/logo`: a processed `product_logo` upload. The old logo's files are deleted. */\nexport const setProductLogoBodySchema = z.object({ mediaId: objectIdSchema });\nexport type SetProductLogoBody = z.infer<typeof setProductLogoBodySchema>;\n\n/**\n * `PUT /products/:id/screenshots`: the WHOLE gallery as it should now be, in\n * order. One call adds, removes, reorders and re-captions: screenshots already\n * on the product stay; new ids must be the caller's processed\n * `product_screenshot` uploads; any left out are deleted from storage.\n */\nexport const setProductScreenshotsBodySchema = z.object({ screenshots: screenshotsInputSchema });\nexport type SetProductScreenshotsBody = z.infer<typeof setProductScreenshotsBodySchema>;\n\nexport const setProductVisibilityBodySchema = z.object({ visibility: productVisibilitySchema });\nexport type SetProductVisibilityBody = z.infer<typeof setProductVisibilityBodySchema>;\n\nexport const setProductStatusBodySchema = z.object({ status: productStatusSchema });\nexport type SetProductStatusBody = z.infer<typeof setProductStatusBodySchema>;\n\n/**\n * `PUT /products/:productId/live` (0.12.0, owner): `false` pauses it (to free\n * a live place for another), `true` makes a paused one live again.\n */\nexport const setProductLiveBodySchema = z.object({ live: z.boolean() });\nexport type SetProductLiveBody = z.infer<typeof setProductLiveBodySchema>;\n\n/**\n * Invite a member to the team; they must accept. `userId` is the member's id\n * as every card carries it (`founderCardSchema.userId`). Someone who cannot\n * join (has not finished onboarding, paused, suspended, deleted) is\n * `PRODUCT_MEMBER_NOT_INVITABLE`; someone already on it or invited,\n * `PRODUCT_ALREADY_MEMBER`.\n */\nexport const inviteProductMemberBodySchema = z.object({\n userId: objectIdSchema,\n role: productInvitableRoleSchema,\n});\nexport type InviteProductMemberBody = z.infer<typeof inviteProductMemberBodySchema>;\n\n/**\n * The owner changes someone's role (on the team or still invited). The\n * owner's own role changes only by handing over (`PRODUCT_OWNER_MUST_TRANSFER`);\n * someone not on the team or invited is `PRODUCT_NOT_ON_TEAM`.\n */\nexport const setProductMemberRoleBodySchema = z.object({ role: productInvitableRoleSchema });\nexport type SetProductMemberRoleBody = z.infer<typeof setProductMemberRoleBodySchema>;\n\n/**\n * The owner hands the product to someone already on its team (not merely\n * invited: `PRODUCT_NOT_ON_TEAM`), who must have room under\n * `PRODUCTS_OWNED_MAX` (`PRODUCT_LIMIT_REACHED`). The old owner becomes a co-founder.\n */\nexport const transferProductBodySchema = z.object({ userId: objectIdSchema });\nexport type TransferProductBody = z.infer<typeof transferProductBodySchema>;\n"]}
@@ -356,9 +356,10 @@ export type PublicBirthday = z.infer<typeof publicBirthdaySchema>;
356
356
  * client renders what arrives. Built field by field on the server
357
357
  * (`toMemberPublic`), never by dropping fields from a fuller document.
358
358
  *
359
- * `viewer.canMessage` is the server's answer to "may I start a chat with
360
- * them": who may message whom will follow membership and plans, so no client
361
- * works it out.
359
+ * `viewer.canMessage` is the server's answer to "offer Message": the tap
360
+ * opens a conversation, or (0.13.0) the sheet that makes one possible (the
361
+ * membership for a viewer, the plans for a member without one). Who may
362
+ * message whom follows membership and plans, so no client works it out.
362
363
  */
363
364
  export declare const memberProfileSchema: z.ZodObject<{
364
365
  id: z.ZodString;
@@ -369,6 +370,7 @@ export declare const memberProfileSchema: z.ZodObject<{
369
370
  }, z.core.$strip>>;
370
371
  about: z.ZodPreprocess<z.ZodOptional<z.ZodString>, unknown>;
371
372
  displayName: z.ZodString;
373
+ createdAt: z.ZodISODateTime;
372
374
  userId: z.ZodString;
373
375
  username: z.ZodString;
374
376
  avatarUrl: z.ZodOptional<z.ZodURL>;
@@ -454,7 +456,6 @@ export declare const memberProfileSchema: z.ZodObject<{
454
456
  github: z.ZodOptional<z.ZodURL>;
455
457
  website: z.ZodOptional<z.ZodURL>;
456
458
  }, z.core.$strip>>;
457
- createdAt: z.ZodISODateTime;
458
459
  shown: z.ZodObject<{
459
460
  email: z.ZodOptional<z.ZodString>;
460
461
  phone: z.ZodOptional<z.ZodString>;
@@ -590,6 +591,11 @@ export declare const updateUsernameBodySchema: z.ZodObject<{
590
591
  username: z.ZodString;
591
592
  }, z.core.$strip>;
592
593
  export type UpdateUsernameBody = z.infer<typeof updateUsernameBodySchema>;
594
+ /** `GET /api/v1/profiles/username-available?username=` (0.13.0): the handle asked about. */
595
+ export declare const usernameAvailabilityQuerySchema: z.ZodObject<{
596
+ username: z.ZodString;
597
+ }, z.core.$strip>;
598
+ export type UsernameAvailabilityQuery = z.infer<typeof usernameAvailabilityQuerySchema>;
593
599
  /** Availability probe behind the username field. */
594
600
  export declare const usernameAvailabilitySchema: z.ZodObject<{
595
601
  username: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"founder-profile.d.ts","sourceRoot":"","sources":["../../../src/domains/profile/founder-profile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"founder-profile.d.ts","sourceRoot":"","sources":["../../../src/domains/profile/founder-profile.ts"],"names":[],"mappings":"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"}
@@ -218,9 +218,10 @@ export const publicBirthdaySchema = z.object({
218
218
  * client renders what arrives. Built field by field on the server
219
219
  * (`toMemberPublic`), never by dropping fields from a fuller document.
220
220
  *
221
- * `viewer.canMessage` is the server's answer to "may I start a chat with
222
- * them": who may message whom will follow membership and plans, so no client
223
- * works it out.
221
+ * `viewer.canMessage` is the server's answer to "offer Message": the tap
222
+ * opens a conversation, or (0.13.0) the sheet that makes one possible (the
223
+ * membership for a viewer, the plans for a member without one). Who may
224
+ * message whom follows membership and plans, so no client works it out.
224
225
  */
225
226
  export const memberProfileSchema = founderProfileSchema
226
227
  .pick({
@@ -305,6 +306,8 @@ export const updateFounderProfileBodySchema = z.object({
305
306
  * uniqueness check, and it refuses a reserved handle (`chosenUsernameSchema`).
306
307
  */
307
308
  export const updateUsernameBodySchema = z.object({ username: chosenUsernameSchema });
309
+ /** `GET /api/v1/profiles/username-available?username=` (0.13.0): the handle asked about. */
310
+ export const usernameAvailabilityQuerySchema = z.object({ username: usernameSchema });
308
311
  /** Availability probe behind the username field. */
309
312
  export const usernameAvailabilitySchema = z.object({
310
313
  username: usernameSchema,
@@ -1 +1 @@
1
- {"version":3,"file":"founder-profile.js","sourceRoot":"","sources":["../../../src/domains/profile/founder-profile.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * founder-schema — The founder profile\n *\n * One member, one profile. The central auth account owns identity (email,\n * verification, deletion); this owns everything Founder Circle shows.\n *\n * @module founder-schema/domains/profile\n */\n\nimport { z } from 'zod';\nimport {\n chosenUsernameSchema,\n displayNameSchema,\n GOAL_VALUES,\n genderSchema,\n goalSchema,\n httpUrlSchema,\n industrySchema,\n locationSchema,\n objectIdSchema,\n optionalTrimmedString,\n phoneSchema,\n skillSchema,\n startupStageSchema,\n usernameSchema,\n} from '../../core/common.js';\nimport {\n ABOUT_MAX,\n DISPLAY_NAME_MAX,\n FOUNDED_YEAR_MIN,\n HEADLINE_MAX,\n SKILLS_MAX,\n TEAM_SIZE_MAX,\n TEAM_SIZE_MIN,\n VENTURE_NAME_MAX,\n VENTURE_TAGLINE_MAX,\n} from '../../core/limits.js';\nimport { VALIDATION_MESSAGE } from '../../core/validation.js';\nimport { mediaImageSchema } from '../media/media.js';\n\n// ─── Venture ─────────────────────────────────────────────────────────────────\n\n/**\n * ⚠ NUMBERS ARE NUMBERS, never coerced. This is a BODY, which arrives as JSON\n * and already carries types. `z.coerce.number()` here accepted `teamSize: true`\n * as 1 and `\" \"` as 0, and made the schema's input type `unknown`, so a form\n * typed against it could put anything in the field. Coercion belongs to query\n * strings, where everything is text; a form converts its text input before it\n * builds the body.\n */\nexport const ventureSchema = z.object({\n name: z.string().trim().min(1).max(VENTURE_NAME_MAX),\n tagline: optionalTrimmedString(VENTURE_TAGLINE_MAX),\n website: httpUrlSchema.optional(),\n industry: industrySchema,\n stage: startupStageSchema,\n /** Team size including the founder. Optional: a solo pre-idea founder has none to report. */\n teamSize: z.number().int().min(TEAM_SIZE_MIN).max(TEAM_SIZE_MAX).optional(),\n /**\n * Not in the future. The bound is read per parse, never captured once.\n *\n * `.max(new Date().getUTCFullYear())` looks equivalent and is not: it is\n * evaluated when this module is imported, so a server process still up on\n * 1 January rejects the new year until somebody restarts it. The backend's\n * Mongoose model deliberately carries no upper bound for the same reason, a\n * `max` there being frozen at schema construction. This is where the ceiling\n * lives.\n */\n foundedYear: z\n .number()\n .int()\n .min(FOUNDED_YEAR_MIN)\n .refine((year) => year <= new Date().getUTCFullYear(), {\n error: VALIDATION_MESSAGE.foundedYearFuture,\n })\n .optional(),\n});\nexport type Venture = z.infer<typeof ventureSchema>;\n\n// ─── A member as other surfaces name them ────────────────────────────────────\n\n/**\n * A member as a byline renders them: on a post (`feedAuthorSchema` is this), a\n * product's team, a review, a notification, the top-helpers list.\n *\n * Every field is LIVE, joined against the profile at read time rather than\n * frozen onto the post or review at write time. So a renamed handle, a new\n * photo or an edited headline updates everywhere, the link always targets the\n * current username, and nothing personal survives in other people's rows once\n * an account is deleted.\n */\nexport const memberBylineSchema = z.object({\n userId: z.string(),\n username: usernameSchema,\n displayName: z.string(),\n /** Server-generated or from the login provider, never member-typed, so a\n * plain URL check. Same reasoning as `avatarUrl` on the profile. */\n avatarUrl: z.url().optional(),\n /** The member's one-line headline, live-joined. */\n headline: z.string().optional(),\n});\nexport type MemberByline = z.infer<typeof memberBylineSchema>;\n\n/**\n * What a member has given the community, on their profile and card.\n *\n * `score` is points earned from OTHER members' recognition only: a product's\n * team marking your feedback helpful, confirming you tested their product,\n * and members finding your review helpful (writing one earns nothing by\n * itself). Nothing a member\n * does to their own product counts, so the score cannot be bought by having a\n * popular one. `helpedCount` is how many different founders recognised that\n * help (\"Helped 12 founders\"). See `domains/contributions`.\n */\nexport const contributionSummarySchema = z.object({\n score: z.number().int().nonnegative(),\n helpedCount: z.number().int().nonnegative(),\n});\nexport type ContributionSummary = z.infer<typeof contributionSummarySchema>;\n\n// ─── Profile ─────────────────────────────────────────────────────────────────\n\n/**\n * The founder's off-platform links. ONE shape: onboarding's contact step picks\n * its three from this, so a link one side knows can never be missing on the\n * other. (It was written twice until 0.2.0, and the profile side lacked\n * Instagram, which onboarding collected.)\n *\n * Defined without a default, because the read side wants one and the write\n * side must not have one; each adds its own.\n */\nexport const founderLinksSchema = z.object({\n linkedin: httpUrlSchema.optional(),\n x: httpUrlSchema.optional(),\n instagram: httpUrlSchema.optional(),\n github: httpUrlSchema.optional(),\n website: httpUrlSchema.optional(),\n});\nexport type FounderLinks = z.infer<typeof founderLinksSchema>;\n\n/**\n * The profile as the owner sees it. A peer sees the redacted projection\n * (`founderCardSchema`), which is built on the server and never by dropping\n * fields on the client.\n */\nexport const founderProfileSchema = z.object({\n id: z.string(),\n userId: z.string(),\n username: usernameSchema,\n displayName: z.string().trim().min(1).max(DISPLAY_NAME_MAX),\n headline: optionalTrimmedString(HEADLINE_MAX),\n about: optionalTrimmedString(ABOUT_MAX),\n /**\n * Plain `z.url()`, NOT `httpUrlSchema`, and the difference is deliberate.\n *\n * No member can write this field: it appears in no write body, and\n * `public-surface.test.ts` asserts that and will fail the day somebody adds it\n * to a form. So the scheme restriction would be defending a field that takes\n * no member input, while refusing hosts we legitimately serve avatars from,\n * our own dev host among them. A read schema that rejects our own response is\n * a self-inflicted outage.\n *\n * ⚠️ That argument holds only while nothing member-supplied reaches this\n * field. Two sources write an avatar today and NEITHER is a member typing a\n * URL: our own upload path, and the central-auth `user.created` /\n * `user.updated` webhook, which carries the Google OAuth picture. If a\n * \"paste a link to your photo\" control is ever added, this goes back to\n * `httpUrlSchema` and the ruling behind it is void.\n *\n * WHICH picture: the member's uploaded photo at its small size (192, see\n * `MEDIA_SIZES.avatar`), else their sign-in provider's picture, else absent.\n * Every surface that shows this member resolves it the same way.\n */\n avatarUrl: z.url().optional(),\n /**\n * The uploaded photo itself, every size, when the member has one. Absent\n * means `avatarUrl` (if any) is the sign-in provider's picture, so a client\n * offers \"Remove photo\" only when this is present. Not on `founderCardSchema`:\n * a card needs one small picture, not the set.\n */\n avatar: mediaImageSchema.optional(),\n location: locationSchema.optional(),\n venture: ventureSchema.optional(),\n skills: z.array(skillSchema).max(SKILLS_MAX).default([]),\n goals: z.array(goalSchema).max(GOAL_VALUES.length).default([]),\n links: founderLinksSchema.default({}),\n /**\n * Their contribution to other founders. Server-computed, never written by a\n * member. REQUIRED, no default: a read-side default would let a server that\n * forgot the field pass as a real zero.\n */\n contribution: contributionSummarySchema,\n /** Onboarding is finished and the member is visible in Discover. */\n isOnboarded: z.boolean().default(false),\n /** Member paused their own profile. Hidden from Discover, keeps their data. */\n isActive: z.boolean().default(true),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n});\nexport type FounderProfile = z.infer<typeof founderProfileSchema>;\n\n/**\n * What one founder sees of another in Discover and on a profile page.\n *\n * Built server-side. Keep it a strict subset of `founderProfileSchema` — if a\n * private field ever needs to show here, that is a product decision, not an\n * accident of spreading the full document.\n */\nexport const founderCardSchema = founderProfileSchema.pick({\n id: true,\n /**\n * The MEMBER's id (0.6.0): what a team invitation, a chat and every byline\n * key on. `id` is the profile's own id, which nothing takes as input.\n */\n userId: true,\n username: true,\n displayName: true,\n headline: true,\n avatarUrl: true,\n location: true,\n venture: true,\n skills: true,\n goals: true,\n contribution: true,\n});\nexport type FounderCard = z.infer<typeof founderCardSchema>;\n\n// ─── What a member chooses to show (0.11.0) ──────────────────────────────────\n\n/**\n * The four personal details a member MAY show on their profile page (the\n * user's ruling, 2026-10-11). Each is PRIVATE until its owner turns it on;\n * everything else on a profile is public as before. Changed only through\n * `PATCH /profiles/me/personal`.\n */\nexport const CONTACT_VISIBILITY_FIELDS = ['email', 'phone', 'gender', 'birthday'] as const;\nexport type ContactVisibilityField = (typeof CONTACT_VISIBILITY_FIELDS)[number];\n\n/** Which of the four the member shows. Every key present on a read: false is private. */\nexport const contactVisibilitySchema = z.object({\n email: z.boolean(),\n phone: z.boolean(),\n gender: z.boolean(),\n birthday: z.boolean(),\n});\nexport type ContactVisibility = z.infer<typeof contactVisibilitySchema>;\n\n/**\n * A birthday as OTHERS see it: day and month, NEVER the year (the user's\n * ruling). The year would give away the age and, with the name, the full date\n * of birth that identity checks ask for. The year is never on the wire.\n */\nexport const publicBirthdaySchema = z.object({\n day: z.number().int().min(1).max(31),\n month: z.number().int().min(1).max(12),\n});\nexport type PublicBirthday = z.infer<typeof publicBirthdaySchema>;\n\n/**\n * `GET /api/v1/founders/by-username/:username` (0.11.0): one member's profile\n * page, as a signed-in member (or the member themself) sees it.\n *\n * The card's fields, what only a page has room for (about, links, member\n * since), and `shown`: the personal details this member has CHOSEN to show,\n * and nothing else. Email and phone go to members only, never to an account\n * without membership (the coming viewer tier); the server decides, and a\n * client renders what arrives. Built field by field on the server\n * (`toMemberPublic`), never by dropping fields from a fuller document.\n *\n * `viewer.canMessage` is the server's answer to \"may I start a chat with\n * them\": who may message whom will follow membership and plans, so no client\n * works it out.\n */\nexport const memberProfileSchema = founderProfileSchema\n .pick({\n id: true,\n userId: true,\n username: true,\n displayName: true,\n headline: true,\n about: true,\n avatarUrl: true,\n location: true,\n venture: true,\n skills: true,\n goals: true,\n links: true,\n contribution: true,\n createdAt: true,\n })\n .extend({\n shown: z.object({\n email: z.string().optional(),\n phone: z.string().optional(),\n gender: genderSchema.optional(),\n birthday: publicBirthdaySchema.optional(),\n }),\n viewer: z.object({ isSelf: z.boolean(), canMessage: z.boolean() }),\n });\nexport type MemberProfile = z.infer<typeof memberProfileSchema>;\n\n/** The member page's address: `/discover/<username>`. */\nexport const memberHandleParamsSchema = z.object({ username: usernameSchema });\nexport type MemberHandleParams = z.infer<typeof memberHandleParamsSchema>;\n\n// ─── Write bodies ────────────────────────────────────────────────────────────\n\n/**\n * A text field the member is allowed to empty.\n *\n * Three states, and they are deliberately distinct:\n * absent do not touch this field\n * null clear it (the backend turns this into an `$unset`)\n * \"\" REJECTED\n *\n * The empty string is refused on purpose. A form that forgets to convert a\n * cleared input to `null` then fails loudly at the boundary, instead of being\n * silently dropped and leaving the member staring at text they just deleted.\n * `optionalTrimmedString` does the dropping, which is right for a create body\n * and wrong for a patch.\n */\nconst clearableText = (maxLength: number) =>\n z.string().trim().min(1, VALIDATION_MESSAGE.clearWithNull).max(maxLength).nullable().optional();\n\n/**\n * Patch body for the Me tab. Only the keys the member actually changed.\n *\n * ⚠️ Written as its own object ON PURPOSE. Do NOT rebuild it as\n * `founderProfileSchema.pick({...}).partial()`: `.partial()` does not switch\n * off `.default()`, so `skills`, `goals` and `links` would materialise as\n * `[]`, `[]` and `{}` on every request, including an empty one. Under a `$set`\n * that wipes a member's skills and every one of their links the moment they\n * edit their display name. `tsc` cannot see it and the request looks correct in\n * the network tab.\n *\n * The rule this comes from: defaults belong on the READ side. A write body\n * states what the caller sent and nothing else.\n */\nexport const updateFounderProfileBodySchema = z.object({\n displayName: displayNameSchema.optional(),\n headline: clearableText(HEADLINE_MAX),\n about: clearableText(ABOUT_MAX),\n /**\n * Carries the whole location; `locationSchema` has no default to fill a gap.\n * `null` removes it (0.10.0): a member may stop showing their city on\n * Discover, and nothing else would take it off once given.\n */\n location: locationSchema.nullable().optional(),\n /**\n * The whole venture, or `null` to remove it (0.10.0), its business type\n * with it: a member whose venture closed is no longer building it.\n */\n venture: ventureSchema.nullable().optional(),\n skills: z.array(skillSchema).max(SKILLS_MAX).optional(),\n goals: z.array(goalSchema).max(GOAL_VALUES.length).optional(),\n /** Sent whole. To drop one link, send the object without that key. */\n links: founderLinksSchema.optional(),\n});\nexport type UpdateFounderProfileBody = z.infer<typeof updateFounderProfileBodySchema>;\n\n/**\n * Username change. Separate from the profile patch because it needs a\n * uniqueness check, and it refuses a reserved handle (`chosenUsernameSchema`).\n */\nexport const updateUsernameBodySchema = z.object({ username: chosenUsernameSchema });\nexport type UpdateUsernameBody = z.infer<typeof updateUsernameBodySchema>;\n\n/** Availability probe behind the username field. */\nexport const usernameAvailabilitySchema = z.object({\n username: usernameSchema,\n available: z.boolean(),\n /** Present when unavailable: `taken` or `reserved`. */\n reason: z.enum(['taken', 'reserved']).optional(),\n});\nexport type UsernameAvailability = z.infer<typeof usernameAvailabilitySchema>;\n\n// ─── The member's own personal details ──────────────────────────────────────\n\n/**\n * `GET /api/v1/profiles/me/personal` (0.10.0): what ONLY the member sees of\n * themselves, the \"Personal details\" card of the Me tab's Profile.\n *\n * ⚠ OWNER ONLY, and kept OFF `founderProfileSchema` on purpose. Email, phone,\n * gender and date of birth are personal data: they appear on no card, no\n * search, no team list, no byline and no audit detail. The profile is read on\n * every page by the app shell; these do not travel with it, they are asked\n * for only where they are shown.\n *\n * Read shapes are plain where the stored value may predate today's rule (a\n * phone seeded from the sign-in provider in another format): a read schema\n * that rejects our own stored value is a self-inflicted outage. The write\n * body holds the rules.\n */\nexport const myPersonalDetailsSchema = z.object({\n /** The profile's display name: the card's first row. */\n displayName: z.string(),\n /** The sign-in account's. Changed there (Account settings), never here. */\n email: z.string().optional(),\n /** Ten digits as stored on the account mirror; display adds the `+91`. */\n phone: z.string().optional(),\n gender: genderSchema.optional(),\n /**\n * `YYYY-MM-DD`. READ ONLY: it is the 18+ check's input, given once at\n * onboarding. A date of birth that could be edited later would be an age\n * gate anyone could walk around.\n */\n dateOfBirth: z.string().optional(),\n /** Which of email, phone, gender and birthday the member shows on their page (0.11.0). */\n visibility: contactVisibilitySchema,\n});\nexport type MyPersonalDetails = z.infer<typeof myPersonalDetailsSchema>;\n\n/**\n * `PATCH /api/v1/profiles/me/personal` (0.10.0): name, phone and gender. Only\n * the keys the member changed; answers with `myPersonalDetailsSchema`.\n *\n * ONE RULE PER FIELD: the very schemas onboarding finishes with (the display\n * name, the ten-digit phone, the gender enum with prefer-not-to-say), so a\n * value one accepts the other can never refuse.\n *\n * ⚠ NO `.default()` and no `.partial()` of a read shape (see\n * `updateFounderProfileBodySchema`): absent means unchanged, and a default\n * would overwrite what is stored. No `dateOfBirth`: read only, above. No\n * `email`: the sign-in account owns it.\n *\n * Name and phone are PRODUCT-OWNED on Founder Circle's account mirror: the\n * sign-in service seeds them once and never overwrites them, so this edits\n * Founder Circle's copy and never calls the sign-in service.\n */\nexport const updateMyPersonalDetailsBodySchema = z.object({\n displayName: displayNameSchema.optional(),\n phone: phoneSchema.optional(),\n gender: genderSchema.optional(),\n /**\n * The city, or `null` to remove it (0.11.0): it moved to the Personal\n * Details card, so its editor saves it here, with the rest, in one\n * transaction. `PATCH /profiles/me` still takes it too.\n */\n location: locationSchema.nullable().optional(),\n /** Only the switches that changed (0.11.0). */\n visibility: contactVisibilitySchema.partial().optional(),\n});\nexport type UpdateMyPersonalDetailsBody = z.infer<typeof updateMyPersonalDetailsBodySchema>;\n\n// ─── The member's own photo ──────────────────────────────────────────────────\n\n/**\n * `PUT /api/v1/profiles/me/avatar`: use a completed upload (purpose `avatar`)\n * as the member's photo. Answers with the updated `founderProfileSchema`.\n *\n * The previous photo is deleted from storage, not merely unlinked, so its old\n * address stops working. `DELETE /api/v1/profiles/me/avatar` removes the photo\n * the same way and the member falls back to their sign-in provider's picture.\n */\nexport const setAvatarBodySchema = z.object({ mediaId: objectIdSchema });\nexport type SetAvatarBody = z.infer<typeof setAvatarBodySchema>;\n"]}
1
+ {"version":3,"file":"founder-profile.js","sourceRoot":"","sources":["../../../src/domains/profile/founder-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,UAAU,EACV,aAAa,EACb,cAAc,EACd,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,gFAAgF;AAEhF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC;IACpD,OAAO,EAAE,qBAAqB,CAAC,mBAAmB,CAAC;IACnD,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE;IACjC,QAAQ,EAAE,cAAc;IACxB,KAAK,EAAE,kBAAkB;IACzB,6FAA6F;IAC7F,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE;IAC3E;;;;;;;;;OASG;IACH,WAAW,EAAE,CAAC;SACX,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,gBAAgB,CAAC;SACrB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC,cAAc,EAAE,EAAE;QACrD,KAAK,EAAE,kBAAkB,CAAC,iBAAiB;KAC5C,CAAC;SACD,QAAQ,EAAE;CACd,CAAC,CAAC;AAGH,gFAAgF;AAEhF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,QAAQ,EAAE,cAAc;IACxB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB;yEACqE;IACrE,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC7B,mDAAmD;IACnD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAC;AAGH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACrC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;CAC5C,CAAC,CAAC;AAGH,gFAAgF;AAEhF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,QAAQ,EAAE,aAAa,CAAC,QAAQ,EAAE;IAClC,CAAC,EAAE,aAAa,CAAC,QAAQ,EAAE;IAC3B,SAAS,EAAE,aAAa,CAAC,QAAQ,EAAE;IACnC,MAAM,EAAE,aAAa,CAAC,QAAQ,EAAE;IAChC,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAC;AAGH;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,QAAQ,EAAE,cAAc;IACxB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC3D,QAAQ,EAAE,qBAAqB,CAAC,YAAY,CAAC;IAC7C,KAAK,EAAE,qBAAqB,CAAC,SAAS,CAAC;IACvC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC7B;;;;;OAKG;IACH,MAAM,EAAE,gBAAgB,CAAC,QAAQ,EAAE;IACnC,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE;IACnC,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE;IACjC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACxD,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC9D,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;IACrC;;;;OAIG;IACH,YAAY,EAAE,yBAAyB;IACvC,oEAAoE;IACpE,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACvC,+EAA+E;IAC/E,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACnC,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE;IAC3B,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAC;AAGH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,IAAI,CAAC;IACzD,EAAE,EAAE,IAAI;IACR;;;OAGG;IACH,MAAM,EAAE,IAAI;IACZ,QAAQ,EAAE,IAAI;IACd,WAAW,EAAE,IAAI;IACjB,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,YAAY,EAAE,IAAI;CACnB,CAAC,CAAC;AAGH,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAU,CAAC;AAG3F,yFAAyF;AACzF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE;IAClB,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE;IAClB,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;IACnB,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE;CACtB,CAAC,CAAC;AAGH;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACpC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;CACvC,CAAC,CAAC;AAGH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,oBAAoB;KACpD,IAAI,CAAC;IACJ,EAAE,EAAE,IAAI;IACR,MAAM,EAAE,IAAI;IACZ,QAAQ,EAAE,IAAI;IACd,WAAW,EAAE,IAAI;IACjB,QAAQ,EAAE,IAAI;IACd,KAAK,EAAE,IAAI;IACX,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,YAAY,EAAE,IAAI;IAClB,SAAS,EAAE,IAAI;CAChB,CAAC;KACD,MAAM,CAAC;IACN,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC5B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC5B,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE;QAC/B,QAAQ,EAAE,oBAAoB,CAAC,QAAQ,EAAE;KAC1C,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;CACnE,CAAC,CAAC;AAGL,yDAAyD;AACzD,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;AAG/E,gFAAgF;AAEhF;;;;;;;;;;;;;GAaG;AACH,MAAM,aAAa,GAAG,CAAC,SAAiB,EAAE,EAAE,CAC1C,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC;AAElG;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC,MAAM,CAAC;IACrD,WAAW,EAAE,iBAAiB,CAAC,QAAQ,EAAE;IACzC,QAAQ,EAAE,aAAa,CAAC,YAAY,CAAC;IACrC,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC9C;;;OAGG;IACH,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC5C,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE;IACvD,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;IAC7D,sEAAsE;IACtE,KAAK,EAAE,kBAAkB,CAAC,QAAQ,EAAE;CACrC,CAAC,CAAC;AAGH;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,oBAAoB,EAAE,CAAC,CAAC;AAGrF,4FAA4F;AAC5F,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;AAGtF,oDAAoD;AACpD,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,QAAQ,EAAE,cAAc;IACxB,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;IACtB,uDAAuD;IACvD,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE;CACjD,CAAC,CAAC;AAGH,+EAA+E;AAE/E;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,wDAAwD;IACxD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,2EAA2E;IAC3E,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,0EAA0E;IAC1E,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE;IAC/B;;;;OAIG;IACH,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,0FAA0F;IAC1F,UAAU,EAAE,uBAAuB;CACpC,CAAC,CAAC;AAGH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC,CAAC,MAAM,CAAC;IACxD,WAAW,EAAE,iBAAiB,CAAC,QAAQ,EAAE;IACzC,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE;IAC7B,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE;IAC/B;;;;OAIG;IACH,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC9C,+CAA+C;IAC/C,UAAU,EAAE,uBAAuB,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACzD,CAAC,CAAC;AAGH,gFAAgF;AAEhF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC","sourcesContent":["/**\n * founder-schema — The founder profile\n *\n * One member, one profile. The central auth account owns identity (email,\n * verification, deletion); this owns everything Founder Circle shows.\n *\n * @module founder-schema/domains/profile\n */\n\nimport { z } from 'zod';\nimport {\n chosenUsernameSchema,\n displayNameSchema,\n GOAL_VALUES,\n genderSchema,\n goalSchema,\n httpUrlSchema,\n industrySchema,\n locationSchema,\n objectIdSchema,\n optionalTrimmedString,\n phoneSchema,\n skillSchema,\n startupStageSchema,\n usernameSchema,\n} from '../../core/common.js';\nimport {\n ABOUT_MAX,\n DISPLAY_NAME_MAX,\n FOUNDED_YEAR_MIN,\n HEADLINE_MAX,\n SKILLS_MAX,\n TEAM_SIZE_MAX,\n TEAM_SIZE_MIN,\n VENTURE_NAME_MAX,\n VENTURE_TAGLINE_MAX,\n} from '../../core/limits.js';\nimport { VALIDATION_MESSAGE } from '../../core/validation.js';\nimport { mediaImageSchema } from '../media/media.js';\n\n// ─── Venture ─────────────────────────────────────────────────────────────────\n\n/**\n * ⚠ NUMBERS ARE NUMBERS, never coerced. This is a BODY, which arrives as JSON\n * and already carries types. `z.coerce.number()` here accepted `teamSize: true`\n * as 1 and `\" \"` as 0, and made the schema's input type `unknown`, so a form\n * typed against it could put anything in the field. Coercion belongs to query\n * strings, where everything is text; a form converts its text input before it\n * builds the body.\n */\nexport const ventureSchema = z.object({\n name: z.string().trim().min(1).max(VENTURE_NAME_MAX),\n tagline: optionalTrimmedString(VENTURE_TAGLINE_MAX),\n website: httpUrlSchema.optional(),\n industry: industrySchema,\n stage: startupStageSchema,\n /** Team size including the founder. Optional: a solo pre-idea founder has none to report. */\n teamSize: z.number().int().min(TEAM_SIZE_MIN).max(TEAM_SIZE_MAX).optional(),\n /**\n * Not in the future. The bound is read per parse, never captured once.\n *\n * `.max(new Date().getUTCFullYear())` looks equivalent and is not: it is\n * evaluated when this module is imported, so a server process still up on\n * 1 January rejects the new year until somebody restarts it. The backend's\n * Mongoose model deliberately carries no upper bound for the same reason, a\n * `max` there being frozen at schema construction. This is where the ceiling\n * lives.\n */\n foundedYear: z\n .number()\n .int()\n .min(FOUNDED_YEAR_MIN)\n .refine((year) => year <= new Date().getUTCFullYear(), {\n error: VALIDATION_MESSAGE.foundedYearFuture,\n })\n .optional(),\n});\nexport type Venture = z.infer<typeof ventureSchema>;\n\n// ─── A member as other surfaces name them ────────────────────────────────────\n\n/**\n * A member as a byline renders them: on a post (`feedAuthorSchema` is this), a\n * product's team, a review, a notification, the top-helpers list.\n *\n * Every field is LIVE, joined against the profile at read time rather than\n * frozen onto the post or review at write time. So a renamed handle, a new\n * photo or an edited headline updates everywhere, the link always targets the\n * current username, and nothing personal survives in other people's rows once\n * an account is deleted.\n */\nexport const memberBylineSchema = z.object({\n userId: z.string(),\n username: usernameSchema,\n displayName: z.string(),\n /** Server-generated or from the login provider, never member-typed, so a\n * plain URL check. Same reasoning as `avatarUrl` on the profile. */\n avatarUrl: z.url().optional(),\n /** The member's one-line headline, live-joined. */\n headline: z.string().optional(),\n});\nexport type MemberByline = z.infer<typeof memberBylineSchema>;\n\n/**\n * What a member has given the community, on their profile and card.\n *\n * `score` is points earned from OTHER members' recognition only: a product's\n * team marking your feedback helpful, confirming you tested their product,\n * and members finding your review helpful (writing one earns nothing by\n * itself). Nothing a member\n * does to their own product counts, so the score cannot be bought by having a\n * popular one. `helpedCount` is how many different founders recognised that\n * help (\"Helped 12 founders\"). See `domains/contributions`.\n */\nexport const contributionSummarySchema = z.object({\n score: z.number().int().nonnegative(),\n helpedCount: z.number().int().nonnegative(),\n});\nexport type ContributionSummary = z.infer<typeof contributionSummarySchema>;\n\n// ─── Profile ─────────────────────────────────────────────────────────────────\n\n/**\n * The founder's off-platform links. ONE shape: onboarding's contact step picks\n * its three from this, so a link one side knows can never be missing on the\n * other. (It was written twice until 0.2.0, and the profile side lacked\n * Instagram, which onboarding collected.)\n *\n * Defined without a default, because the read side wants one and the write\n * side must not have one; each adds its own.\n */\nexport const founderLinksSchema = z.object({\n linkedin: httpUrlSchema.optional(),\n x: httpUrlSchema.optional(),\n instagram: httpUrlSchema.optional(),\n github: httpUrlSchema.optional(),\n website: httpUrlSchema.optional(),\n});\nexport type FounderLinks = z.infer<typeof founderLinksSchema>;\n\n/**\n * The profile as the owner sees it. A peer sees the redacted projection\n * (`founderCardSchema`), which is built on the server and never by dropping\n * fields on the client.\n */\nexport const founderProfileSchema = z.object({\n id: z.string(),\n userId: z.string(),\n username: usernameSchema,\n displayName: z.string().trim().min(1).max(DISPLAY_NAME_MAX),\n headline: optionalTrimmedString(HEADLINE_MAX),\n about: optionalTrimmedString(ABOUT_MAX),\n /**\n * Plain `z.url()`, NOT `httpUrlSchema`, and the difference is deliberate.\n *\n * No member can write this field: it appears in no write body, and\n * `public-surface.test.ts` asserts that and will fail the day somebody adds it\n * to a form. So the scheme restriction would be defending a field that takes\n * no member input, while refusing hosts we legitimately serve avatars from,\n * our own dev host among them. A read schema that rejects our own response is\n * a self-inflicted outage.\n *\n * ⚠️ That argument holds only while nothing member-supplied reaches this\n * field. Two sources write an avatar today and NEITHER is a member typing a\n * URL: our own upload path, and the central-auth `user.created` /\n * `user.updated` webhook, which carries the Google OAuth picture. If a\n * \"paste a link to your photo\" control is ever added, this goes back to\n * `httpUrlSchema` and the ruling behind it is void.\n *\n * WHICH picture: the member's uploaded photo at its small size (192, see\n * `MEDIA_SIZES.avatar`), else their sign-in provider's picture, else absent.\n * Every surface that shows this member resolves it the same way.\n */\n avatarUrl: z.url().optional(),\n /**\n * The uploaded photo itself, every size, when the member has one. Absent\n * means `avatarUrl` (if any) is the sign-in provider's picture, so a client\n * offers \"Remove photo\" only when this is present. Not on `founderCardSchema`:\n * a card needs one small picture, not the set.\n */\n avatar: mediaImageSchema.optional(),\n location: locationSchema.optional(),\n venture: ventureSchema.optional(),\n skills: z.array(skillSchema).max(SKILLS_MAX).default([]),\n goals: z.array(goalSchema).max(GOAL_VALUES.length).default([]),\n links: founderLinksSchema.default({}),\n /**\n * Their contribution to other founders. Server-computed, never written by a\n * member. REQUIRED, no default: a read-side default would let a server that\n * forgot the field pass as a real zero.\n */\n contribution: contributionSummarySchema,\n /** Onboarding is finished and the member is visible in Discover. */\n isOnboarded: z.boolean().default(false),\n /** Member paused their own profile. Hidden from Discover, keeps their data. */\n isActive: z.boolean().default(true),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n});\nexport type FounderProfile = z.infer<typeof founderProfileSchema>;\n\n/**\n * What one founder sees of another in Discover and on a profile page.\n *\n * Built server-side. Keep it a strict subset of `founderProfileSchema` — if a\n * private field ever needs to show here, that is a product decision, not an\n * accident of spreading the full document.\n */\nexport const founderCardSchema = founderProfileSchema.pick({\n id: true,\n /**\n * The MEMBER's id (0.6.0): what a team invitation, a chat and every byline\n * key on. `id` is the profile's own id, which nothing takes as input.\n */\n userId: true,\n username: true,\n displayName: true,\n headline: true,\n avatarUrl: true,\n location: true,\n venture: true,\n skills: true,\n goals: true,\n contribution: true,\n});\nexport type FounderCard = z.infer<typeof founderCardSchema>;\n\n// ─── What a member chooses to show (0.11.0) ──────────────────────────────────\n\n/**\n * The four personal details a member MAY show on their profile page (the\n * user's ruling, 2026-10-11). Each is PRIVATE until its owner turns it on;\n * everything else on a profile is public as before. Changed only through\n * `PATCH /profiles/me/personal`.\n */\nexport const CONTACT_VISIBILITY_FIELDS = ['email', 'phone', 'gender', 'birthday'] as const;\nexport type ContactVisibilityField = (typeof CONTACT_VISIBILITY_FIELDS)[number];\n\n/** Which of the four the member shows. Every key present on a read: false is private. */\nexport const contactVisibilitySchema = z.object({\n email: z.boolean(),\n phone: z.boolean(),\n gender: z.boolean(),\n birthday: z.boolean(),\n});\nexport type ContactVisibility = z.infer<typeof contactVisibilitySchema>;\n\n/**\n * A birthday as OTHERS see it: day and month, NEVER the year (the user's\n * ruling). The year would give away the age and, with the name, the full date\n * of birth that identity checks ask for. The year is never on the wire.\n */\nexport const publicBirthdaySchema = z.object({\n day: z.number().int().min(1).max(31),\n month: z.number().int().min(1).max(12),\n});\nexport type PublicBirthday = z.infer<typeof publicBirthdaySchema>;\n\n/**\n * `GET /api/v1/founders/by-username/:username` (0.11.0): one member's profile\n * page, as a signed-in member (or the member themself) sees it.\n *\n * The card's fields, what only a page has room for (about, links, member\n * since), and `shown`: the personal details this member has CHOSEN to show,\n * and nothing else. Email and phone go to members only, never to an account\n * without membership (the coming viewer tier); the server decides, and a\n * client renders what arrives. Built field by field on the server\n * (`toMemberPublic`), never by dropping fields from a fuller document.\n *\n * `viewer.canMessage` is the server's answer to \"offer Message\": the tap\n * opens a conversation, or (0.13.0) the sheet that makes one possible (the\n * membership for a viewer, the plans for a member without one). Who may\n * message whom follows membership and plans, so no client works it out.\n */\nexport const memberProfileSchema = founderProfileSchema\n .pick({\n id: true,\n userId: true,\n username: true,\n displayName: true,\n headline: true,\n about: true,\n avatarUrl: true,\n location: true,\n venture: true,\n skills: true,\n goals: true,\n links: true,\n contribution: true,\n createdAt: true,\n })\n .extend({\n shown: z.object({\n email: z.string().optional(),\n phone: z.string().optional(),\n gender: genderSchema.optional(),\n birthday: publicBirthdaySchema.optional(),\n }),\n viewer: z.object({ isSelf: z.boolean(), canMessage: z.boolean() }),\n });\nexport type MemberProfile = z.infer<typeof memberProfileSchema>;\n\n/** The member page's address: `/discover/<username>`. */\nexport const memberHandleParamsSchema = z.object({ username: usernameSchema });\nexport type MemberHandleParams = z.infer<typeof memberHandleParamsSchema>;\n\n// ─── Write bodies ────────────────────────────────────────────────────────────\n\n/**\n * A text field the member is allowed to empty.\n *\n * Three states, and they are deliberately distinct:\n * absent do not touch this field\n * null clear it (the backend turns this into an `$unset`)\n * \"\" REJECTED\n *\n * The empty string is refused on purpose. A form that forgets to convert a\n * cleared input to `null` then fails loudly at the boundary, instead of being\n * silently dropped and leaving the member staring at text they just deleted.\n * `optionalTrimmedString` does the dropping, which is right for a create body\n * and wrong for a patch.\n */\nconst clearableText = (maxLength: number) =>\n z.string().trim().min(1, VALIDATION_MESSAGE.clearWithNull).max(maxLength).nullable().optional();\n\n/**\n * Patch body for the Me tab. Only the keys the member actually changed.\n *\n * ⚠️ Written as its own object ON PURPOSE. Do NOT rebuild it as\n * `founderProfileSchema.pick({...}).partial()`: `.partial()` does not switch\n * off `.default()`, so `skills`, `goals` and `links` would materialise as\n * `[]`, `[]` and `{}` on every request, including an empty one. Under a `$set`\n * that wipes a member's skills and every one of their links the moment they\n * edit their display name. `tsc` cannot see it and the request looks correct in\n * the network tab.\n *\n * The rule this comes from: defaults belong on the READ side. A write body\n * states what the caller sent and nothing else.\n */\nexport const updateFounderProfileBodySchema = z.object({\n displayName: displayNameSchema.optional(),\n headline: clearableText(HEADLINE_MAX),\n about: clearableText(ABOUT_MAX),\n /**\n * Carries the whole location; `locationSchema` has no default to fill a gap.\n * `null` removes it (0.10.0): a member may stop showing their city on\n * Discover, and nothing else would take it off once given.\n */\n location: locationSchema.nullable().optional(),\n /**\n * The whole venture, or `null` to remove it (0.10.0), its business type\n * with it: a member whose venture closed is no longer building it.\n */\n venture: ventureSchema.nullable().optional(),\n skills: z.array(skillSchema).max(SKILLS_MAX).optional(),\n goals: z.array(goalSchema).max(GOAL_VALUES.length).optional(),\n /** Sent whole. To drop one link, send the object without that key. */\n links: founderLinksSchema.optional(),\n});\nexport type UpdateFounderProfileBody = z.infer<typeof updateFounderProfileBodySchema>;\n\n/**\n * Username change. Separate from the profile patch because it needs a\n * uniqueness check, and it refuses a reserved handle (`chosenUsernameSchema`).\n */\nexport const updateUsernameBodySchema = z.object({ username: chosenUsernameSchema });\nexport type UpdateUsernameBody = z.infer<typeof updateUsernameBodySchema>;\n\n/** `GET /api/v1/profiles/username-available?username=` (0.13.0): the handle asked about. */\nexport const usernameAvailabilityQuerySchema = z.object({ username: usernameSchema });\nexport type UsernameAvailabilityQuery = z.infer<typeof usernameAvailabilityQuerySchema>;\n\n/** Availability probe behind the username field. */\nexport const usernameAvailabilitySchema = z.object({\n username: usernameSchema,\n available: z.boolean(),\n /** Present when unavailable: `taken` or `reserved`. */\n reason: z.enum(['taken', 'reserved']).optional(),\n});\nexport type UsernameAvailability = z.infer<typeof usernameAvailabilitySchema>;\n\n// ─── The member's own personal details ──────────────────────────────────────\n\n/**\n * `GET /api/v1/profiles/me/personal` (0.10.0): what ONLY the member sees of\n * themselves, the \"Personal details\" card of the Me tab's Profile.\n *\n * ⚠ OWNER ONLY, and kept OFF `founderProfileSchema` on purpose. Email, phone,\n * gender and date of birth are personal data: they appear on no card, no\n * search, no team list, no byline and no audit detail. The profile is read on\n * every page by the app shell; these do not travel with it, they are asked\n * for only where they are shown.\n *\n * Read shapes are plain where the stored value may predate today's rule (a\n * phone seeded from the sign-in provider in another format): a read schema\n * that rejects our own stored value is a self-inflicted outage. The write\n * body holds the rules.\n */\nexport const myPersonalDetailsSchema = z.object({\n /** The profile's display name: the card's first row. */\n displayName: z.string(),\n /** The sign-in account's. Changed there (Account settings), never here. */\n email: z.string().optional(),\n /** Ten digits as stored on the account mirror; display adds the `+91`. */\n phone: z.string().optional(),\n gender: genderSchema.optional(),\n /**\n * `YYYY-MM-DD`. READ ONLY: it is the 18+ check's input, given once at\n * onboarding. A date of birth that could be edited later would be an age\n * gate anyone could walk around.\n */\n dateOfBirth: z.string().optional(),\n /** Which of email, phone, gender and birthday the member shows on their page (0.11.0). */\n visibility: contactVisibilitySchema,\n});\nexport type MyPersonalDetails = z.infer<typeof myPersonalDetailsSchema>;\n\n/**\n * `PATCH /api/v1/profiles/me/personal` (0.10.0): name, phone and gender. Only\n * the keys the member changed; answers with `myPersonalDetailsSchema`.\n *\n * ONE RULE PER FIELD: the very schemas onboarding finishes with (the display\n * name, the ten-digit phone, the gender enum with prefer-not-to-say), so a\n * value one accepts the other can never refuse.\n *\n * ⚠ NO `.default()` and no `.partial()` of a read shape (see\n * `updateFounderProfileBodySchema`): absent means unchanged, and a default\n * would overwrite what is stored. No `dateOfBirth`: read only, above. No\n * `email`: the sign-in account owns it.\n *\n * Name and phone are PRODUCT-OWNED on Founder Circle's account mirror: the\n * sign-in service seeds them once and never overwrites them, so this edits\n * Founder Circle's copy and never calls the sign-in service.\n */\nexport const updateMyPersonalDetailsBodySchema = z.object({\n displayName: displayNameSchema.optional(),\n phone: phoneSchema.optional(),\n gender: genderSchema.optional(),\n /**\n * The city, or `null` to remove it (0.11.0): it moved to the Personal\n * Details card, so its editor saves it here, with the rest, in one\n * transaction. `PATCH /profiles/me` still takes it too.\n */\n location: locationSchema.nullable().optional(),\n /** Only the switches that changed (0.11.0). */\n visibility: contactVisibilitySchema.partial().optional(),\n});\nexport type UpdateMyPersonalDetailsBody = z.infer<typeof updateMyPersonalDetailsBodySchema>;\n\n// ─── The member's own photo ──────────────────────────────────────────────────\n\n/**\n * `PUT /api/v1/profiles/me/avatar`: use a completed upload (purpose `avatar`)\n * as the member's photo. Answers with the updated `founderProfileSchema`.\n *\n * The previous photo is deleted from storage, not merely unlinked, so its old\n * address stops working. `DELETE /api/v1/profiles/me/avatar` removes the photo\n * the same way and the member falls back to their sign-in provider's picture.\n */\nexport const setAvatarBodySchema = z.object({ mediaId: objectIdSchema });\nexport type SetAvatarBody = z.infer<typeof setAvatarBodySchema>;\n"]}
@@ -59,6 +59,7 @@ export declare const reviewViewerSchema: z.ZodObject<{
59
59
  canEdit: z.ZodBoolean;
60
60
  canDelete: z.ZodBoolean;
61
61
  canReply: z.ZodBoolean;
62
+ canRemoveReply: z.ZodBoolean;
62
63
  canVoteHelpful: z.ZodBoolean;
63
64
  canReport: z.ZodBoolean;
64
65
  }, z.core.$strip>;
@@ -97,6 +98,7 @@ export declare const productReviewSchema: z.ZodObject<{
97
98
  canEdit: z.ZodBoolean;
98
99
  canDelete: z.ZodBoolean;
99
100
  canReply: z.ZodBoolean;
101
+ canRemoveReply: z.ZodBoolean;
100
102
  canVoteHelpful: z.ZodBoolean;
101
103
  canReport: z.ZodBoolean;
102
104
  }, z.core.$strip>>;
@@ -137,6 +139,7 @@ export declare const reviewPageSchema: z.ZodObject<{
137
139
  canEdit: z.ZodBoolean;
138
140
  canDelete: z.ZodBoolean;
139
141
  canReply: z.ZodBoolean;
142
+ canRemoveReply: z.ZodBoolean;
140
143
  canVoteHelpful: z.ZodBoolean;
141
144
  canReport: z.ZodBoolean;
142
145
  }, z.core.$strip>>;
@@ -1 +1 @@
1
- {"version":3,"file":"reviews.d.ts","sourceRoot":"","sources":["../../../src/domains/reviews/reviews.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,mBAAmB;AACnB,eAAO,MAAM,kBAAkB,aAAiC,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,8CAA8C;AAC9C,eAAO,MAAM,kBAAkB,6BAA8B,CAAC;AAC9D,eAAO,MAAM,gBAAgB;;;EAA6B,CAAC;AAC3D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB;;;;;;;;;;;iBAM5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,oEAAoE;AACpE,eAAO,MAAM,kBAAkB;;;;;;;;iBAU7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAa9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAuC,CAAC;AACrE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,kBAAkB;;;;;;;iBAE7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEnE,eAAO,MAAM,kBAAkB;;iBAAyC,CAAC;AACzE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D,eAAO,MAAM,sBAAsB;;;iBAGjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,wFAAwF;AACxF,eAAO,MAAM,sBAAsB;;;iBAGjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,gFAAgF;AAChF,eAAO,MAAM,qBAAqB;;iBAEhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,sFAAsF;AACtF,eAAO,MAAM,2BAA2B;;;;iBAItC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC"}
1
+ {"version":3,"file":"reviews.d.ts","sourceRoot":"","sources":["../../../src/domains/reviews/reviews.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,mBAAmB;AACnB,eAAO,MAAM,kBAAkB,aAAiC,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,8CAA8C;AAC9C,eAAO,MAAM,kBAAkB,6BAA8B,CAAC;AAC9D,eAAO,MAAM,gBAAgB;;;EAA6B,CAAC;AAC3D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB;;;;;;;;;;;iBAM5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,oEAAoE;AACpE,eAAO,MAAM,kBAAkB;;;;;;;;;iBAe7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAa9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAuC,CAAC;AACrE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,kBAAkB;;;;;;;iBAE7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEnE,eAAO,MAAM,kBAAkB;;iBAAyC,CAAC;AACzE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D,eAAO,MAAM,sBAAsB;;;iBAGjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,wFAAwF;AACxF,eAAO,MAAM,sBAAsB;;;iBAGjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,gFAAgF;AAChF,eAAO,MAAM,qBAAqB;;iBAEhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,sFAAsF;AACtF,eAAO,MAAM,2BAA2B;;;;iBAItC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC"}
@@ -51,8 +51,13 @@ export const reviewViewerSchema = z.object({
51
51
  votedHelpful: z.boolean(),
52
52
  canEdit: z.boolean(),
53
53
  canDelete: z.boolean(),
54
- /** On the product's team: write, edit or remove the team's reply. */
54
+ /** On the product's team, taking part: write or edit the team's reply. */
55
55
  canReply: z.boolean(),
56
+ /**
57
+ * On the product's team, member or not, whatever the product's state:
58
+ * take the team's reply back (0.12.0). Taking back is never paid.
59
+ */
60
+ canRemoveReply: z.boolean(),
56
61
  /** Not the writer. */
57
62
  canVoteHelpful: z.boolean(),
58
63
  canReport: z.boolean(),