founder-schema 0.15.0 → 0.16.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.
@@ -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 \"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"]}
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 */\n// ⚠ The web's Discover cache follows the member's own saves of exactly these\n// fields (`discoverChangedBy` in the web's features/profile/api.ts derives its\n// list from this shape): adding a field here is enough, there is no second list.\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"]}
@@ -0,0 +1,386 @@
1
+ /**
2
+ * The member's own answers that NOBODY ELSE sees (0.16.0): their business's
3
+ * type and registration, and their interests. The Me tab reads and writes
4
+ * them on routes of their own, like the personal details, and they travel on
5
+ * no other response: not on `founderProfileSchema` (the app shell reads that on
6
+ * every page), not on a card, a member's page, a byline or Discover.
7
+ *
8
+ * GET /api/v1/profiles/me/business `myBusinessSchema`
9
+ * PUT /api/v1/profiles/me/business `putMyBusinessBodySchema`, answers `myBusinessSchema`
10
+ * GET /api/v1/profiles/me/interests `myInterestsSchema`
11
+ * PUT /api/v1/profiles/me/interests `putMyInterestsBodySchema`, answers `myInterestsSchema`
12
+ *
13
+ * In its own file because it joins two domains: the profile's venture and
14
+ * onboarding's vocabularies (business types, registrations, topics), and
15
+ * onboarding already imports the profile.
16
+ *
17
+ * @module domains/profile/my-profile
18
+ */
19
+ import { z } from 'zod';
20
+ /**
21
+ * The member's venture as only they see it: what everyone sees
22
+ * (`ventureSchema`) plus its business type and how it is registered, which are
23
+ * PRIVATE (the Me tab marks them so). Stored together on the profile's
24
+ * venture, so they live and go with it: no business, no type, no registration.
25
+ *
26
+ * ONE RULE PER FIELD: the very schemas onboarding finishes with.
27
+ */
28
+ export declare const myVentureSchema: z.ZodObject<{
29
+ name: z.ZodString;
30
+ tagline: z.ZodPreprocess<z.ZodOptional<z.ZodString>, unknown>;
31
+ website: z.ZodOptional<z.ZodURL>;
32
+ industry: z.ZodEnum<{
33
+ agritech: "agritech";
34
+ ai_ml: "ai_ml";
35
+ b2b_saas: "b2b_saas";
36
+ consumer: "consumer";
37
+ climate: "climate";
38
+ d2c: "d2c";
39
+ deeptech: "deeptech";
40
+ edtech: "edtech";
41
+ fintech: "fintech";
42
+ gaming: "gaming";
43
+ healthtech: "healthtech";
44
+ logistics: "logistics";
45
+ manufacturing: "manufacturing";
46
+ marketplace: "marketplace";
47
+ media: "media";
48
+ mobility: "mobility";
49
+ proptech: "proptech";
50
+ robotics: "robotics";
51
+ services: "services";
52
+ space: "space";
53
+ other: "other";
54
+ }>;
55
+ stage: z.ZodEnum<{
56
+ idea: "idea";
57
+ validation: "validation";
58
+ mvp: "mvp";
59
+ pre_seed: "pre_seed";
60
+ seed: "seed";
61
+ series_a_plus: "series_a_plus";
62
+ profitable: "profitable";
63
+ exited: "exited";
64
+ }>;
65
+ teamSize: z.ZodOptional<z.ZodNumber>;
66
+ foundedYear: z.ZodOptional<z.ZodNumber>;
67
+ businessType: z.ZodOptional<z.ZodEnum<{
68
+ startup: "startup";
69
+ sme: "sme";
70
+ enterprise: "enterprise";
71
+ freelancer: "freelancer";
72
+ agency: "agency";
73
+ social_enterprise: "social_enterprise";
74
+ family_business: "family_business";
75
+ franchise: "franchise";
76
+ }>>;
77
+ legalStructure: z.ZodOptional<z.ZodEnum<{
78
+ not_registered: "not_registered";
79
+ sole_proprietorship: "sole_proprietorship";
80
+ partnership: "partnership";
81
+ llp: "llp";
82
+ opc: "opc";
83
+ private_limited: "private_limited";
84
+ public_limited: "public_limited";
85
+ section_8: "section_8";
86
+ trust_or_society: "trust_or_society";
87
+ cooperative: "cooperative";
88
+ registered_abroad: "registered_abroad";
89
+ }>>;
90
+ }, z.core.$strip>;
91
+ export type MyVenture = z.infer<typeof myVentureSchema>;
92
+ /** `GET /api/v1/profiles/me/business`: absent `venture` = no business added. */
93
+ export declare const myBusinessSchema: z.ZodObject<{
94
+ venture: z.ZodOptional<z.ZodObject<{
95
+ name: z.ZodString;
96
+ tagline: z.ZodPreprocess<z.ZodOptional<z.ZodString>, unknown>;
97
+ website: z.ZodOptional<z.ZodURL>;
98
+ industry: z.ZodEnum<{
99
+ agritech: "agritech";
100
+ ai_ml: "ai_ml";
101
+ b2b_saas: "b2b_saas";
102
+ consumer: "consumer";
103
+ climate: "climate";
104
+ d2c: "d2c";
105
+ deeptech: "deeptech";
106
+ edtech: "edtech";
107
+ fintech: "fintech";
108
+ gaming: "gaming";
109
+ healthtech: "healthtech";
110
+ logistics: "logistics";
111
+ manufacturing: "manufacturing";
112
+ marketplace: "marketplace";
113
+ media: "media";
114
+ mobility: "mobility";
115
+ proptech: "proptech";
116
+ robotics: "robotics";
117
+ services: "services";
118
+ space: "space";
119
+ other: "other";
120
+ }>;
121
+ stage: z.ZodEnum<{
122
+ idea: "idea";
123
+ validation: "validation";
124
+ mvp: "mvp";
125
+ pre_seed: "pre_seed";
126
+ seed: "seed";
127
+ series_a_plus: "series_a_plus";
128
+ profitable: "profitable";
129
+ exited: "exited";
130
+ }>;
131
+ teamSize: z.ZodOptional<z.ZodNumber>;
132
+ foundedYear: z.ZodOptional<z.ZodNumber>;
133
+ businessType: z.ZodOptional<z.ZodEnum<{
134
+ startup: "startup";
135
+ sme: "sme";
136
+ enterprise: "enterprise";
137
+ freelancer: "freelancer";
138
+ agency: "agency";
139
+ social_enterprise: "social_enterprise";
140
+ family_business: "family_business";
141
+ franchise: "franchise";
142
+ }>>;
143
+ legalStructure: z.ZodOptional<z.ZodEnum<{
144
+ not_registered: "not_registered";
145
+ sole_proprietorship: "sole_proprietorship";
146
+ partnership: "partnership";
147
+ llp: "llp";
148
+ opc: "opc";
149
+ private_limited: "private_limited";
150
+ public_limited: "public_limited";
151
+ section_8: "section_8";
152
+ trust_or_society: "trust_or_society";
153
+ cooperative: "cooperative";
154
+ registered_abroad: "registered_abroad";
155
+ }>>;
156
+ }, z.core.$strip>>;
157
+ }, z.core.$strip>;
158
+ export type MyBusiness = z.infer<typeof myBusinessSchema>;
159
+ /**
160
+ * `PUT /api/v1/profiles/me/business`: the WHOLE business as the editor holds
161
+ * it, or `null` to remove it. A key left out of the venture is removed (a
162
+ * tagline, a website, the type, the registration): PUT, not a patch, because
163
+ * the editor always holds all of it.
164
+ */
165
+ export declare const putMyBusinessBodySchema: z.ZodObject<{
166
+ venture: z.ZodNullable<z.ZodObject<{
167
+ name: z.ZodString;
168
+ tagline: z.ZodPreprocess<z.ZodOptional<z.ZodString>, unknown>;
169
+ website: z.ZodOptional<z.ZodURL>;
170
+ industry: z.ZodEnum<{
171
+ agritech: "agritech";
172
+ ai_ml: "ai_ml";
173
+ b2b_saas: "b2b_saas";
174
+ consumer: "consumer";
175
+ climate: "climate";
176
+ d2c: "d2c";
177
+ deeptech: "deeptech";
178
+ edtech: "edtech";
179
+ fintech: "fintech";
180
+ gaming: "gaming";
181
+ healthtech: "healthtech";
182
+ logistics: "logistics";
183
+ manufacturing: "manufacturing";
184
+ marketplace: "marketplace";
185
+ media: "media";
186
+ mobility: "mobility";
187
+ proptech: "proptech";
188
+ robotics: "robotics";
189
+ services: "services";
190
+ space: "space";
191
+ other: "other";
192
+ }>;
193
+ stage: z.ZodEnum<{
194
+ idea: "idea";
195
+ validation: "validation";
196
+ mvp: "mvp";
197
+ pre_seed: "pre_seed";
198
+ seed: "seed";
199
+ series_a_plus: "series_a_plus";
200
+ profitable: "profitable";
201
+ exited: "exited";
202
+ }>;
203
+ teamSize: z.ZodOptional<z.ZodNumber>;
204
+ foundedYear: z.ZodOptional<z.ZodNumber>;
205
+ businessType: z.ZodOptional<z.ZodEnum<{
206
+ startup: "startup";
207
+ sme: "sme";
208
+ enterprise: "enterprise";
209
+ freelancer: "freelancer";
210
+ agency: "agency";
211
+ social_enterprise: "social_enterprise";
212
+ family_business: "family_business";
213
+ franchise: "franchise";
214
+ }>>;
215
+ legalStructure: z.ZodOptional<z.ZodEnum<{
216
+ not_registered: "not_registered";
217
+ sole_proprietorship: "sole_proprietorship";
218
+ partnership: "partnership";
219
+ llp: "llp";
220
+ opc: "opc";
221
+ private_limited: "private_limited";
222
+ public_limited: "public_limited";
223
+ section_8: "section_8";
224
+ trust_or_society: "trust_or_society";
225
+ cooperative: "cooperative";
226
+ registered_abroad: "registered_abroad";
227
+ }>>;
228
+ }, z.core.$strip>>;
229
+ }, z.core.$strip>;
230
+ export type PutMyBusinessBody = z.infer<typeof putMyBusinessBodySchema>;
231
+ /**
232
+ * `GET /api/v1/profiles/me/interests`: the topics the member wants to read
233
+ * about. A read shape, plain: a list stored under an older rule still reads.
234
+ */
235
+ export declare const myInterestsSchema: z.ZodObject<{
236
+ interests: z.ZodArray<z.ZodEnum<{
237
+ ai_ml: "ai_ml";
238
+ b2b_saas: "b2b_saas";
239
+ d2c: "d2c";
240
+ deeptech: "deeptech";
241
+ robotics: "robotics";
242
+ growth: "growth";
243
+ sales: "sales";
244
+ marketing: "marketing";
245
+ supply_chain: "supply_chain";
246
+ fundraising: "fundraising";
247
+ social_enterprise: "social_enterprise";
248
+ mentoring: "mentoring";
249
+ leadership: "leadership";
250
+ networking: "networking";
251
+ public_speaking: "public_speaking";
252
+ teaching: "teaching";
253
+ hiring_talent: "hiring_talent";
254
+ personal_branding: "personal_branding";
255
+ career_transition: "career_transition";
256
+ remote_work: "remote_work";
257
+ blockchain: "blockchain";
258
+ crypto_web3: "crypto_web3";
259
+ data_science: "data_science";
260
+ cybersecurity: "cybersecurity";
261
+ game_dev: "game_dev";
262
+ ux_design: "ux_design";
263
+ app_development: "app_development";
264
+ open_source: "open_source";
265
+ electronics: "electronics";
266
+ space_exploration: "space_exploration";
267
+ green_tech: "green_tech";
268
+ no_code: "no_code";
269
+ entrepreneurship: "entrepreneurship";
270
+ investing: "investing";
271
+ stock_trading: "stock_trading";
272
+ personal_finance: "personal_finance";
273
+ consulting: "consulting";
274
+ ecommerce: "ecommerce";
275
+ retail: "retail";
276
+ real_estate: "real_estate";
277
+ product_management: "product_management";
278
+ meditation: "meditation";
279
+ journaling: "journaling";
280
+ self_improvement: "self_improvement";
281
+ productivity: "productivity";
282
+ reading: "reading";
283
+ online_courses: "online_courses";
284
+ philosophy: "philosophy";
285
+ psychology: "psychology";
286
+ therapy: "therapy";
287
+ sleep_optimization: "sleep_optimization";
288
+ gym: "gym";
289
+ yoga: "yoga";
290
+ photography: "photography";
291
+ writing: "writing";
292
+ graphic_design: "graphic_design";
293
+ filmmaking: "filmmaking";
294
+ digital_art: "digital_art";
295
+ content_creation: "content_creation";
296
+ blogging: "blogging";
297
+ vlogging: "vlogging";
298
+ podcasts: "podcasts";
299
+ animation: "animation";
300
+ music_production: "music_production";
301
+ volunteering: "volunteering";
302
+ ngo_work: "ngo_work";
303
+ environmental: "environmental";
304
+ women_empowerment: "women_empowerment";
305
+ community_service: "community_service";
306
+ education_access: "education_access";
307
+ }>>;
308
+ }, z.core.$strip>;
309
+ export type MyInterests = z.infer<typeof myInterestsSchema>;
310
+ /** `PUT /api/v1/profiles/me/interests`: the whole list, by onboarding's own rule (`interestsSchema`). */
311
+ export declare const putMyInterestsBodySchema: z.ZodObject<{
312
+ interests: z.ZodArray<z.ZodEnum<{
313
+ ai_ml: "ai_ml";
314
+ b2b_saas: "b2b_saas";
315
+ d2c: "d2c";
316
+ deeptech: "deeptech";
317
+ robotics: "robotics";
318
+ growth: "growth";
319
+ sales: "sales";
320
+ marketing: "marketing";
321
+ supply_chain: "supply_chain";
322
+ fundraising: "fundraising";
323
+ social_enterprise: "social_enterprise";
324
+ mentoring: "mentoring";
325
+ leadership: "leadership";
326
+ networking: "networking";
327
+ public_speaking: "public_speaking";
328
+ teaching: "teaching";
329
+ hiring_talent: "hiring_talent";
330
+ personal_branding: "personal_branding";
331
+ career_transition: "career_transition";
332
+ remote_work: "remote_work";
333
+ blockchain: "blockchain";
334
+ crypto_web3: "crypto_web3";
335
+ data_science: "data_science";
336
+ cybersecurity: "cybersecurity";
337
+ game_dev: "game_dev";
338
+ ux_design: "ux_design";
339
+ app_development: "app_development";
340
+ open_source: "open_source";
341
+ electronics: "electronics";
342
+ space_exploration: "space_exploration";
343
+ green_tech: "green_tech";
344
+ no_code: "no_code";
345
+ entrepreneurship: "entrepreneurship";
346
+ investing: "investing";
347
+ stock_trading: "stock_trading";
348
+ personal_finance: "personal_finance";
349
+ consulting: "consulting";
350
+ ecommerce: "ecommerce";
351
+ retail: "retail";
352
+ real_estate: "real_estate";
353
+ product_management: "product_management";
354
+ meditation: "meditation";
355
+ journaling: "journaling";
356
+ self_improvement: "self_improvement";
357
+ productivity: "productivity";
358
+ reading: "reading";
359
+ online_courses: "online_courses";
360
+ philosophy: "philosophy";
361
+ psychology: "psychology";
362
+ therapy: "therapy";
363
+ sleep_optimization: "sleep_optimization";
364
+ gym: "gym";
365
+ yoga: "yoga";
366
+ photography: "photography";
367
+ writing: "writing";
368
+ graphic_design: "graphic_design";
369
+ filmmaking: "filmmaking";
370
+ digital_art: "digital_art";
371
+ content_creation: "content_creation";
372
+ blogging: "blogging";
373
+ vlogging: "vlogging";
374
+ podcasts: "podcasts";
375
+ animation: "animation";
376
+ music_production: "music_production";
377
+ volunteering: "volunteering";
378
+ ngo_work: "ngo_work";
379
+ environmental: "environmental";
380
+ women_empowerment: "women_empowerment";
381
+ community_service: "community_service";
382
+ education_access: "education_access";
383
+ }>>;
384
+ }, z.core.$strip>;
385
+ export type PutMyInterestsBody = z.infer<typeof putMyInterestsBodySchema>;
386
+ //# sourceMappingURL=my-profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"my-profile.d.ts","sourceRoot":"","sources":["../../../src/domains/profile/my-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAG1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,gFAAgF;AAChF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAoD,CAAC;AAClF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAoD,CAAC;AACzF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAIxE;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgD,CAAC;AAC/E,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,yGAAyG;AACzG,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA2C,CAAC;AACjF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * The member's own answers that NOBODY ELSE sees (0.16.0): their business's
3
+ * type and registration, and their interests. The Me tab reads and writes
4
+ * them on routes of their own, like the personal details, and they travel on
5
+ * no other response: not on `founderProfileSchema` (the app shell reads that on
6
+ * every page), not on a card, a member's page, a byline or Discover.
7
+ *
8
+ * GET /api/v1/profiles/me/business `myBusinessSchema`
9
+ * PUT /api/v1/profiles/me/business `putMyBusinessBodySchema`, answers `myBusinessSchema`
10
+ * GET /api/v1/profiles/me/interests `myInterestsSchema`
11
+ * PUT /api/v1/profiles/me/interests `putMyInterestsBodySchema`, answers `myInterestsSchema`
12
+ *
13
+ * In its own file because it joins two domains: the profile's venture and
14
+ * onboarding's vocabularies (business types, registrations, topics), and
15
+ * onboarding already imports the profile.
16
+ *
17
+ * @module domains/profile/my-profile
18
+ */
19
+ import { z } from 'zod';
20
+ import { businessTypeSchema, interestsSchema, legalStructureSchema, topicSchema, } from '../onboarding/onboarding.js';
21
+ import { ventureSchema } from './founder-profile.js';
22
+ // ─── The business ────────────────────────────────────────────────────────────
23
+ /**
24
+ * The member's venture as only they see it: what everyone sees
25
+ * (`ventureSchema`) plus its business type and how it is registered, which are
26
+ * PRIVATE (the Me tab marks them so). Stored together on the profile's
27
+ * venture, so they live and go with it: no business, no type, no registration.
28
+ *
29
+ * ONE RULE PER FIELD: the very schemas onboarding finishes with.
30
+ */
31
+ export const myVentureSchema = ventureSchema.extend({
32
+ businessType: businessTypeSchema.optional(),
33
+ legalStructure: legalStructureSchema.optional(),
34
+ });
35
+ /** `GET /api/v1/profiles/me/business`: absent `venture` = no business added. */
36
+ export const myBusinessSchema = z.object({ venture: myVentureSchema.optional() });
37
+ /**
38
+ * `PUT /api/v1/profiles/me/business`: the WHOLE business as the editor holds
39
+ * it, or `null` to remove it. A key left out of the venture is removed (a
40
+ * tagline, a website, the type, the registration): PUT, not a patch, because
41
+ * the editor always holds all of it.
42
+ */
43
+ export const putMyBusinessBodySchema = z.object({ venture: myVentureSchema.nullable() });
44
+ // ─── The interests ───────────────────────────────────────────────────────────
45
+ /**
46
+ * `GET /api/v1/profiles/me/interests`: the topics the member wants to read
47
+ * about. A read shape, plain: a list stored under an older rule still reads.
48
+ */
49
+ export const myInterestsSchema = z.object({ interests: z.array(topicSchema) });
50
+ /** `PUT /api/v1/profiles/me/interests`: the whole list, by onboarding's own rule (`interestsSchema`). */
51
+ export const putMyInterestsBodySchema = z.object({ interests: interestsSchema });
52
+ //# sourceMappingURL=my-profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"my-profile.js","sourceRoot":"","sources":["../../../src/domains/profile/my-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,WAAW,GACZ,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,gFAAgF;AAEhF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAC,MAAM,CAAC;IAClD,YAAY,EAAE,kBAAkB,CAAC,QAAQ,EAAE;IAC3C,cAAc,EAAE,oBAAoB,CAAC,QAAQ,EAAE;CAChD,CAAC,CAAC;AAGH,gFAAgF;AAChF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,eAAe,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAGlF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,eAAe,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAGzF,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;AAG/E,yGAAyG;AACzG,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC","sourcesContent":["/**\n * The member's own answers that NOBODY ELSE sees (0.16.0): their business's\n * type and registration, and their interests. The Me tab reads and writes\n * them on routes of their own, like the personal details, and they travel on\n * no other response: not on `founderProfileSchema` (the app shell reads that on\n * every page), not on a card, a member's page, a byline or Discover.\n *\n * GET /api/v1/profiles/me/business `myBusinessSchema`\n * PUT /api/v1/profiles/me/business `putMyBusinessBodySchema`, answers `myBusinessSchema`\n * GET /api/v1/profiles/me/interests `myInterestsSchema`\n * PUT /api/v1/profiles/me/interests `putMyInterestsBodySchema`, answers `myInterestsSchema`\n *\n * In its own file because it joins two domains: the profile's venture and\n * onboarding's vocabularies (business types, registrations, topics), and\n * onboarding already imports the profile.\n *\n * @module domains/profile/my-profile\n */\n\nimport { z } from 'zod';\nimport {\n businessTypeSchema,\n interestsSchema,\n legalStructureSchema,\n topicSchema,\n} from '../onboarding/onboarding.js';\nimport { ventureSchema } from './founder-profile.js';\n\n// ─── The business ────────────────────────────────────────────────────────────\n\n/**\n * The member's venture as only they see it: what everyone sees\n * (`ventureSchema`) plus its business type and how it is registered, which are\n * PRIVATE (the Me tab marks them so). Stored together on the profile's\n * venture, so they live and go with it: no business, no type, no registration.\n *\n * ONE RULE PER FIELD: the very schemas onboarding finishes with.\n */\nexport const myVentureSchema = ventureSchema.extend({\n businessType: businessTypeSchema.optional(),\n legalStructure: legalStructureSchema.optional(),\n});\nexport type MyVenture = z.infer<typeof myVentureSchema>;\n\n/** `GET /api/v1/profiles/me/business`: absent `venture` = no business added. */\nexport const myBusinessSchema = z.object({ venture: myVentureSchema.optional() });\nexport type MyBusiness = z.infer<typeof myBusinessSchema>;\n\n/**\n * `PUT /api/v1/profiles/me/business`: the WHOLE business as the editor holds\n * it, or `null` to remove it. A key left out of the venture is removed (a\n * tagline, a website, the type, the registration): PUT, not a patch, because\n * the editor always holds all of it.\n */\nexport const putMyBusinessBodySchema = z.object({ venture: myVentureSchema.nullable() });\nexport type PutMyBusinessBody = z.infer<typeof putMyBusinessBodySchema>;\n\n// ─── The interests ───────────────────────────────────────────────────────────\n\n/**\n * `GET /api/v1/profiles/me/interests`: the topics the member wants to read\n * about. A read shape, plain: a list stored under an older rule still reads.\n */\nexport const myInterestsSchema = z.object({ interests: z.array(topicSchema) });\nexport type MyInterests = z.infer<typeof myInterestsSchema>;\n\n/** `PUT /api/v1/profiles/me/interests`: the whole list, by onboarding's own rule (`interestsSchema`). */\nexport const putMyInterestsBodySchema = z.object({ interests: interestsSchema });\nexport type PutMyInterestsBody = z.infer<typeof putMyInterestsBodySchema>;\n"]}
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ export { CAPABILITY_GRANTED_BY, CAPABILITY_VALUES, type Capability, canGrantCapa
13
13
  export { ACTION_VALUES, type Action, type AppAbility, actionSchema, type PackedRules, packedRulesSchema, SUBJECT_VALUES, type Subject, type SubjectFields, type SubjectInstance, subjectSchema, } from './access/permissions.js';
14
14
  export { ACTIVE_ROLE_TTL_MS, canGrantRole, isPlatformRole, MEMBER_ROLE, PLATFORM_ROLE_VALUES, type PlatformRole, platformRoleSchema, ROLE_GRANTED_BY, ROLE_VALUES, type Role, roleSchema, } from './access/roles.js';
15
15
  export { ACCESS_REASON_VALUES, type AccessReason, accessReasonOf, accessReasonSchema, STANDING_VALUES, type Standing, standingSchema, } from './access/standing.js';
16
- export { type CoordinatesQuery, type CoordinatesQueryInput, chosenUsernameSchema, coordinatesQuerySchema, displayNameSchema, emptyStringToUndefined, type FounderLocation, GENDER_VALUES, type Gender, GOAL_VALUES, type Goal, genderSchema, goalSchema, type HttpUrl, httpUrlOnHosts, httpUrlSchema, INDUSTRY_VALUES, type Industry, industrySchema, isReservedUsername, isUrlOnHost, locationSchema, multiValueQuery, type ObjectIdString, objectIdSchema, optionalTrimmedString, type PaginationQuery, type PaginationQueryInput, type Phone, paginationQuerySchema, phoneSchema, RESERVED_USERNAMES, type SafeUrl, SKILL_VALUES, type Skill, STARTUP_STAGE_VALUES, type StartupStage, type SuggestedLocation, safeUrlSchema, skillSchema, startupStageSchema, suggestedLocationSchema, USERNAME_MAX, USERNAME_MIN, type Username, usernameSchema, YOUTUBE_HOSTS, youtubeVideoId, } from './core/common.js';
16
+ export { type CoordinatesQuery, type CoordinatesQueryInput, chosenUsernameSchema, coordinatesQuerySchema, displayNameSchema, emptyStringToUndefined, type FounderLocation, GENDER_VALUES, type Gender, GOAL_VALUES, type Goal, genderSchema, goalSchema, type HttpUrl, httpUrlOnHosts, httpUrlSchema, INDUSTRY_VALUES, type Industry, industrySchema, isReservedUsername, isUrlOnHost, locationSchema, multiValueQuery, type ObjectIdString, objectIdSchema, optionalTrimmedString, type PaginationQuery, type PaginationQueryInput, type Phone, paginationQuerySchema, phoneSchema, RESERVED_USERNAMES, type SafeUrl, SKILL_VALUES, type Skill, STARTUP_STAGE_VALUES, type StartupStage, type SuggestedLocation, safeUrlSchema, skillSchema, splitFullName, startupStageSchema, suggestedLocationSchema, USERNAME_MAX, USERNAME_MIN, type Username, usernameSchema, YOUTUBE_HOSTS, youtubeVideoId, } from './core/common.js';
17
17
  export { API_ERROR_CODE, API_ERROR_CODE_VALUES, type ApiErrorCode, apiErrorCodeSchema, } from './core/errors.js';
18
18
  export { ABOUT_MAX, BILLING_ADDRESS_MAX, BILLING_NAME_MAX, BILLING_REASON_MAX, BILLING_REASON_MIN, CHAT_PARTICIPANTS_MAX, CITY_MAX, COMMUNITY_BAN_REASON_MAX, COMMUNITY_DECLINE_REASON_MAX, COMMUNITY_DECLINE_REASON_MIN, COMMUNITY_DESCRIPTION_MAX, COMMUNITY_NAME_MAX, COMMUNITY_NAME_MIN, COMMUNITY_RULE_MAX, COMMUNITY_RULES_MAX, COMMUNITY_SUGGESTION_WHY_MAX, CONTRIBUTION_LEADERBOARD_SIZE, CONTRIBUTION_PAIR_POINTS_MAX, CONTRIBUTION_RECENT_DAYS, COUNTRY_MAX, COUPON_CODE_MAX, COUPON_CODE_MIN, COUPON_LABEL_MAX, DISCOVER_FILTER_VALUES_MAX, DISCOVER_TEXT_MAX, DISPLAY_NAME_MAX, ERASURE_RETENTION_DAYS, FOUNDED_YEAR_MIN, GOALS_MIN, HEADLINE_MAX, LINK_PREVIEW_DESCRIPTION_MAX, LINK_PREVIEW_TITLE_MAX, LINK_URL_MAX, MEDIA_ALT_MAX, MEDIA_MAX_INPUT_PIXELS, MEDIA_PENDING_MAX, MEDIA_PLACEHOLDER_MAX, MEDIA_UNATTACHED_TTL_HOURS, MEMBER_SEARCH_MAX, MODERATION_EXCERPT_MAX, MODERATION_NOTE_MAX, NOTIFICATION_EXCERPT_MAX, NOTIFICATION_RETENTION_DAYS, ORDER_TTL_MINUTES, PAGE_SIZE_DEFAULT, PAGE_SIZE_MAX, PLAN_AHEAD_MAX_YEARS, PLAN_REMINDER_DAYS, PRODUCT_ASK_OPEN_DAYS, PRODUCT_CAPTION_MAX, PRODUCT_DESCRIPTION_MAX, PRODUCT_NAME_MAX, PRODUCT_SCREENSHOTS_MAX, PRODUCT_TAGLINE_MAX, PRODUCT_TEAM_SHOWN, PRODUCTS_LIVE_SAFETY_MAX, PRODUCTS_OWNED_MAX, REFUND_WINDOW_DAYS, REPORT_NOTE_MAX, REVIEW_AVERAGE_MIN_COUNT, REVIEW_HELPFUL_POINTS_MAX, REVIEW_REPLY_MAX, REVIEW_TEXT_MAX, REVIEW_TEXT_MIN, REVIEWS_REWARDED_PER_DAY, refundWindowEndsAt, SAVED_REPLIES_MAX, SAVED_REPLY_BODY_MAX, SAVED_REPLY_TITLE_MAX, SKILLS_MAX, STATE_MAX, SUSPENSION_REASON_MAX, SUSPENSION_REASON_MIN, TEAM_SIZE_MAX, TEAM_SIZE_MIN, TICKET_MESSAGE_MAX, TICKET_MESSAGES_MAX, TICKET_SUBJECT_MAX, TICKET_SUBJECT_MIN, UPLOAD_MAX_BYTES, VENTURE_NAME_MAX, VENTURE_TAGLINE_MAX, } from './core/limits.js';
19
19
  export { type ApiError, type ApiErrorDetails, apiErrorDetailsSchema, apiErrorSchema, type ErrorResponse, errorResponseSchema, type IdResponse, idResponseSchema, paginatedSchema, successResponseSchema, } from './core/responses.js';
@@ -32,9 +32,10 @@ export { MEMBER_STATUS_VALUES, type MemberDetail, type MemberDirectoryPage, type
32
32
  export { FOUNDING_PLACES, MEMBER_LIMIT_VALUES, MEMBERSHIP_KIND_VALUES, MEMBERSHIP_PRICE_PAISE, type MeMembership, type Membership, type MembershipKind, meMembershipSchema, membershipKindSchema, membershipSchema, type Paise, PLAN_PERIOD_VALUES, PLAN_SPECS, PLAN_TIER_RANK, PLAN_TIER_VALUES, type PlanBlock, type PlanCatalog, type PlanLimits, type PlanOffer, type PlanPeriod, type PlanTier, paiseSchema, planBlockSchema, planCatalogSchema, planLimitsSchema, planOfferSchema, planPeriodSchema, planTierSchema, } from './domains/membership/membership.js';
33
33
  export { MODERATION_ACTION_VALUES, MODERATION_ACTIONS_BY_TARGET_KIND, MODERATION_CONTEXT_KIND_VALUES, MODERATION_STATE_VALUES, type ModerationAction, type ModerationContentQuery, type ModerationContentQueryInput, type ModerationContextKind, type ModerationDecisionBody, type ModerationItem, type ModerationPage, type ModerationState, type ModerationTargetParams, moderationActionSchema, moderationContentQuerySchema, moderationContextKindSchema, moderationDecisionBodySchema, moderationItemSchema, moderationPageSchema, moderationStateSchema, moderationTargetParamsSchema, } from './domains/moderation/moderation.js';
34
34
  export { NOTIFICATION_KIND_VALUES, NOTIFICATION_PREFERENCE_OF, NOTIFICATION_PREFERENCE_VALUES, type Notification, type NotificationKind, type NotificationPage, type NotificationParams, type NotificationPreference, type NotificationPreferences, type NotificationUnreadCount, notificationKindSchema, notificationPageSchema, notificationParamsSchema, notificationPreferenceSchema, notificationPreferencesSchema, notificationSchema, notificationUnreadCountSchema, type UpdateNotificationPreferencesBody, updateNotificationPreferencesBodySchema, } from './domains/notifications/notifications.js';
35
- export { ageInYears, BUSINESS_TYPE_VALUES, type BusinessType, businessTypeSchema, type CompleteOnboardingBody, type CompleteOnboardingBodyInput, type CompleteOnboardingResponse, type ContactLinks, completeOnboardingBodySchema, completeOnboardingResponseSchema, contactLinksSchema, type DateOfBirth, dateOfBirthSchema, EMPTY_ONBOARDING_VENTURE, FOUNDER_ONBOARDING_STEPS, GUIDELINES_VERSION, guidelinesVersionSchema, INTERESTS_MAX, INTERESTS_MIN, type IsoDate, isoDateSchema, MAX_AGE_YEARS, MIN_AGE_YEARS, ONBOARDING_DRAFT_KEYS, ONBOARDING_STEP_FIELDS, ONBOARDING_STEP_KEYS, ONBOARDING_STEP_SCHEMAS, ONBOARDING_TOTAL_STEPS, type OnboardingDraft, type OnboardingDraftKey, type OnboardingField, type OnboardingForm, type OnboardingProgress, type OnboardingProgressUpdate, type OnboardingStatus, type OnboardingStepBody, type OnboardingStepConfig, type OnboardingStepKey, onboardingDraftKeySchema, onboardingDraftSchema, onboardingFormSchema, onboardingProgressSchema, onboardingProgressUpdateSchema, onboardingStatusSchema, readOnboardingDraft, TEAM_SIZE_DIGITS_MAX, TOPIC_CATEGORIES, TOPIC_CATEGORY_KEYS, TOPIC_VALUES, type Topic, type TopicCategory, type TopicCategoryKey, topicSchema, } from './domains/onboarding/onboarding.js';
35
+ export { ageInYears, BUSINESS_TYPE_VALUES, type BusinessType, businessTypeSchema, type CompleteOnboardingBody, type CompleteOnboardingBodyInput, type CompleteOnboardingResponse, type ContactLinks, completeOnboardingBodySchema, completeOnboardingResponseSchema, contactLinksSchema, type DateOfBirth, dateOfBirthSchema, EMPTY_ONBOARDING_VENTURE, FOUNDER_ONBOARDING_STEPS, GUIDELINES_VERSION, guidelinesVersionSchema, INTERESTS_MAX, INTERESTS_MIN, type IsoDate, interestsSchema, isoDateSchema, LEGAL_STRUCTURE_VALUES, type LegalStructure, legalStructureSchema, MAX_AGE_YEARS, MIN_AGE_YEARS, ONBOARDING_DRAFT_KEYS, ONBOARDING_STEP_FIELDS, ONBOARDING_STEP_KEYS, ONBOARDING_STEP_SCHEMAS, ONBOARDING_TOTAL_STEPS, type OnboardingDraft, type OnboardingDraftKey, type OnboardingField, type OnboardingForm, type OnboardingProgress, type OnboardingProgressUpdate, type OnboardingStatus, type OnboardingStepBody, type OnboardingStepConfig, type OnboardingStepKey, onboardingDraftKeySchema, onboardingDraftSchema, onboardingFormSchema, onboardingProgressSchema, onboardingProgressUpdateSchema, onboardingStatusSchema, readOnboardingDraft, TEAM_SIZE_DIGITS_MAX, TOPIC_CATEGORIES, TOPIC_CATEGORY_KEYS, TOPIC_VALUES, type Topic, type TopicCategory, type TopicCategoryKey, topicSchema, } from './domains/onboarding/onboarding.js';
36
36
  export { type CreateProductBody, createProductBodySchema, type InviteProductMemberBody, inviteProductMemberBodySchema, type MyProducts, myProductsSchema, PRODUCT_ASK_VALUES, PRODUCT_INVITABLE_ROLE_VALUES, PRODUCT_LISTING_REQUIREMENT_VALUES, PRODUCT_PAUSED_BY_VALUES, PRODUCT_PLATFORM_VALUES, PRODUCT_SORT_VALUES, PRODUCT_STAGE_VALUES, PRODUCT_STATUS_VALUES, PRODUCT_TEAM_ROLE_VALUES, PRODUCT_TOPICS_MAX, PRODUCT_VISIBILITY_VALUES, type Product, type ProductAsk, type ProductCard, type ProductCardPage, type ProductChip, type ProductDiscoverQuery, type ProductDiscoverQueryInput, type ProductFacets, type ProductFeedbackQuery, type ProductFeedbackQueryInput, type ProductInvitableRole, type ProductInvite, type ProductInvites, type ProductLinks, type ProductListingRequirement, type ProductMemberParams, type ProductParams, type ProductPausedBy, type ProductPendingInvite, type ProductPendingInvitePage, type ProductPlatform, type ProductRating, type ProductScreenshot, type ProductScreenshotInput, type ProductSort, type ProductStage, type ProductStatus, type ProductsByMemberParams, type ProductTeamMember, type ProductTeamPage, type ProductTeamRole, type ProductTester, type ProductTesterPage, type ProductUpvoteResponse, type ProductViewer, type ProductVisibility, productAskSchema, productCardPageSchema, productCardSchema, productCardViewerSchema, productChipSchema, productDiscoverQuerySchema, productFacetsSchema, productFeedbackQuerySchema, productInvitableRoleSchema, productInviteSchema, productInvitesSchema, productLinksSchema, productListingRequirementSchema, productMemberParamsSchema, productParamsSchema, productPausedBySchema, productPendingInvitePageSchema, productPendingInviteSchema, productPlatformSchema, productRatingSchema, productSchema, productScreenshotInputSchema, productScreenshotSchema, productSortSchema, productStageSchema, productStatusSchema, productsByMemberParamsSchema, productTeamMemberSchema, productTeamPageSchema, productTeamRoleSchema, productTesterPageSchema, productTesterSchema, productUpvoteResponseSchema, productVideoUrlSchema, productViewerSchema, productVisibilitySchema, type SetProductLiveBody, type SetProductLogoBody, type SetProductMemberRoleBody, type SetProductScreenshotsBody, type SetProductStatusBody, type SetProductVisibilityBody, setProductLiveBodySchema, setProductLogoBodySchema, setProductMemberRoleBodySchema, setProductScreenshotsBodySchema, setProductStatusBodySchema, setProductVisibilityBodySchema, type TransferProductBody, transferProductBodySchema, type UpdateProductBody, updateProductBodySchema, } from './domains/products/products.js';
37
37
  export { CONTACT_VISIBILITY_FIELDS, type ContactVisibility, type ContactVisibilityField, type ContributionSummary, contactVisibilitySchema, contributionSummarySchema, type FounderCard, type FounderLinks, type FounderProfile, founderCardSchema, founderLinksSchema, founderProfileSchema, type MemberByline, type MemberHandleParams, type MemberProfile, type MyPersonalDetails, memberBylineSchema, memberHandleParamsSchema, memberProfileSchema, myPersonalDetailsSchema, type PublicBirthday, publicBirthdaySchema, type SetAvatarBody, setAvatarBodySchema, type UpdateFounderProfileBody, type UpdateMyPersonalDetailsBody, type UpdateUsernameBody, type UsernameAvailability, type UsernameAvailabilityQuery, updateFounderProfileBodySchema, updateMyPersonalDetailsBodySchema, updateUsernameBodySchema, usernameAvailabilityQuerySchema, usernameAvailabilitySchema, type Venture, ventureSchema, } from './domains/profile/founder-profile.js';
38
+ export { type MyBusiness, type MyInterests, type MyVenture, myBusinessSchema, myInterestsSchema, myVentureSchema, type PutMyBusinessBody, type PutMyInterestsBody, putMyBusinessBodySchema, putMyInterestsBodySchema, } from './domains/profile/my-profile.js';
38
39
  export { type CreateReviewBody, createReviewBodySchema, type ProductReview, productReviewSchema, REVIEW_SORT_VALUES, type ReviewHelpfulResponse, type ReviewPage, type ReviewParams, type ReviewRating, type ReviewReply, type ReviewReplyBody, type ReviewSort, type ReviewsQuery, type ReviewsQueryInput, type ReviewViewer, reviewHelpfulResponseSchema, reviewPageSchema, reviewParamsSchema, reviewRatingSchema, reviewReplyBodySchema, reviewReplySchema, reviewSortSchema, reviewsQuerySchema, reviewViewerSchema, type UpdateReviewBody, updateReviewBodySchema, } from './domains/reviews/reviews.js';
39
40
  export { type CreateTicketBody, createTicketBodySchema, type ReplyTicketBody, replyTicketBodySchema, type SavedReply, type SavedReplyBody, type SavedReplyList, type SavedReplyParams, savedReplyBodySchema, savedReplyListSchema, savedReplyParamsSchema, savedReplySchema, TICKET_ASSIGNEE_FILTER_VALUES, TICKET_CATEGORY_VALUES, TICKET_SCOPE_VALUES, TICKET_STATUS_VALUES, type TicketAssigneeFilter, type TicketCategory, type TicketDetail, type TicketListQuery, type TicketListQueryInput, type TicketMessage, type TicketPage, type TicketParams, type TicketScope, type TicketStatus, type TicketSummary, ticketAssigneeFilterSchema, ticketCategorySchema, ticketDetailSchema, ticketListQuerySchema, ticketMessageSchema, ticketPageSchema, ticketParamsSchema, ticketScopeSchema, ticketStatusSchema, ticketSummarySchema, } from './domains/support/support.js';
40
41
  export { type SetMemberCapabilitiesBody, type SetMemberCapabilitiesResponse, type SetMemberRolesBody, type SetMemberRolesResponse, setMemberCapabilitiesBodySchema, setMemberCapabilitiesResponseSchema, setMemberRolesBodySchema, setMemberRolesResponseSchema, type TeamMember, type TeamMemberParams, type TeamPage, teamMemberParamsSchema, teamMemberSchema, teamPageSchema, } from './domains/team/team.js';