jansathi-community-schema 0.41.0 → 0.43.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.
package/dist/comment.d.ts CHANGED
@@ -19,7 +19,7 @@ export declare const communityCommentWireSchema: z.ZodObject<{
19
19
  contentKind: z.ZodEnum<{
20
20
  post: "post";
21
21
  lost_found: "lost_found";
22
- voice_box: "voice_box";
22
+ suggestions_complaints: "suggestions_complaints";
23
23
  donate_item: "donate_item";
24
24
  poll: "poll";
25
25
  crowdfunding: "crowdfunding";
@@ -2,7 +2,7 @@
2
2
  * Community crowdfunding wire shapes.
3
3
  *
4
4
  * A crowdfunding campaign is a verified civic fundraiser surfaced in
5
- * the feed alongside posts / polls / lost-found / voice-box / donate-
5
+ * the feed alongside posts / polls / lost-found / suggestions-complaints / donate-
6
6
  * item. The model is:
7
7
  *
8
8
  * 1. Creator drafts a campaign, fills bank + UPI QR + identity tier
@@ -2,7 +2,7 @@
2
2
  * Community crowdfunding wire shapes.
3
3
  *
4
4
  * A crowdfunding campaign is a verified civic fundraiser surfaced in
5
- * the feed alongside posts / polls / lost-found / voice-box / donate-
5
+ * the feed alongside posts / polls / lost-found / suggestions-complaints / donate-
6
6
  * item. The model is:
7
7
  *
8
8
  * 1. Creator drafts a campaign, fills bank + UPI QR + identity tier
@@ -1 +1 @@
1
- {"version":3,"file":"crowdfunding.js","sourceRoot":"","sources":["../src/crowdfunding.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Community crowdfunding wire shapes.\n *\n * A crowdfunding campaign is a verified civic fundraiser surfaced in\n * the feed alongside posts / polls / lost-found / voice-box / donate-\n * item. The model is:\n *\n * 1. Creator drafts a campaign, fills bank + UPI QR + identity tier\n * based on the goal amount, picks an area scope.\n * 2. A leader at the matching scope (or any leader higher up the\n * hierarchy) reviews and approves OR rejects with reason.\n * Approved campaigns transition to ACTIVE and appear in the feed.\n * 3. Donors view the card, tap \"Donate\", pay externally via UPI\n * directly to the creator's bank — the platform never sees the\n * money. After paying, the donor self-attests amount + uploads a\n * receipt screenshot (optional). Without a screenshot the\n * donation enters PENDING state — the donor can upload the\n * receipt later (anytime, from settings → My Donations).\n * 4. The live progress bar shows ONLY verified amount (receipt\n * uploaded). Pending donations are counted separately and\n * surfaced as a secondary \"₹X pending receipt\" note. This is the\n * product decision: the visible progress reflects trust-grounded\n * money, not claims.\n *\n * Privacy: bank account number, IFSC, PAN, Aadhaar last-4, and\n * supporting documents are NEVER on the wire. Only `bankAccountLast4`,\n * `bankAccountHolderName`, and a UPI QR URL surface to donors.\n *\n * @module community-schema/crowdfunding\n */\n\nimport { z } from 'zod';\nimport { areaLineageSnapshotSchema } from './area.js';\nimport {\n CROWDFUNDING_BENEFICIARY_NAME_MAX_CHARS,\n CROWDFUNDING_BENEFICIARY_RELATION_MAX_CHARS,\n CROWDFUNDING_DESCRIPTION_MAX_CHARS,\n CROWDFUNDING_DESCRIPTION_MIN_CHARS,\n CROWDFUNDING_MAX_DONATION_INR,\n CROWDFUNDING_MAX_DURATION_DAYS,\n CROWDFUNDING_MAX_GOAL_INR,\n CROWDFUNDING_MAX_IMAGES,\n CROWDFUNDING_MAX_PROOF_DOCS,\n CROWDFUNDING_MAX_SUPPORTING_DOCS,\n CROWDFUNDING_MIN_DURATION_DAYS,\n CROWDFUNDING_MIN_GOAL_INR,\n CROWDFUNDING_REJECTION_REASON_MAX_CHARS,\n CROWDFUNDING_REJECTION_REASON_MIN_CHARS,\n CROWDFUNDING_TITLE_MAX_CHARS,\n CROWDFUNDING_TITLE_MIN_CHARS,\n} from './constants.js';\nimport { voteValueSchema } from './engagement.js';\nimport { postAuthorSnapshotSchema } from './post.js';\n\n// ─── Enums ─────────────────────────────────────────────────────────────────\n\n/**\n * Top-level categories — drives the chip + icon on the card and the\n * verifier's per-category supporting-doc requirements (medical needs\n * hospital invoice; education needs admission letter; etc.).\n */\nexport const CROWDFUNDING_CATEGORY_VALUES = [\n 'medical',\n 'maternity',\n 'senior_care',\n 'special_needs',\n 'education',\n 'memorial',\n 'disaster',\n 'civic',\n 'faith',\n 'sports_talent',\n 'animal_welfare',\n 'environment',\n 'legal_aid',\n 'arts_culture',\n 'self_improvement',\n /**\n * Startup / prototype building — distinct from `self_improvement`\n * (which is now strictly skill / coursework). Covers MVP builds,\n * tooling, initial inventory, working capital, registration fees,\n * marketing for genuine first-stage entrepreneurs.\n */\n 'startup_prototype',\n 'other',\n] as const;\n\n/**\n * Who the campaign is for — drives the relation chip set and the\n * organization-specific identity asks on the composer. Captured so the\n * verifier can match the campaign narrative to the supporting docs\n * (e.g. an `organization` audience should produce 12A / 80G papers,\n * not a personal hospital bill).\n */\nexport const CROWDFUNDING_AUDIENCE_VALUES = [\n 'self',\n 'family',\n 'friend',\n 'community',\n 'organization',\n] as const;\nexport const crowdfundingAudienceSchema = z.enum(CROWDFUNDING_AUDIENCE_VALUES);\nexport type CrowdfundingAudience = z.infer<typeof crowdfundingAudienceSchema>;\n\n/**\n * Org-registration class — only meaningful when `audience ===\n * 'organization'`. Drives the verifier's expected document set\n * (12A/80G for trust, FCRA-style papers for NGO, etc.).\n */\nexport const CROWDFUNDING_ORG_KIND_VALUES = [\n 'ngo',\n 'trust',\n 'society',\n 'section_8',\n 'other',\n] as const;\nexport const crowdfundingOrgKindSchema = z.enum(CROWDFUNDING_ORG_KIND_VALUES);\nexport type CrowdfundingOrgKind = z.infer<typeof crowdfundingOrgKindSchema>;\nexport const crowdfundingCategorySchema = z.enum(CROWDFUNDING_CATEGORY_VALUES);\nexport type CrowdfundingCategory = z.infer<typeof crowdfundingCategorySchema>;\n\n/**\n * Visibility — where the campaign appears.\n *\n * v0.34 dropped the per-campaign area scope entirely. Instead the\n * creator picks one or more communities they're a member of, AND/OR\n * flips a \"show in global feed\" toggle. The campaign appears in those\n * surfaces and ONLY those surfaces (no geographic cascade).\n *\n * communityIds list of community ids the campaign is published into.\n * Empty array means \"no community-scoped publication\".\n * includesGlobal when true the campaign also appears in the global\n * feed (cross-community discovery surface).\n *\n * The Zod schema enforces at-least-one-publication at parse time so a\n * caller can't accidentally create an orphan campaign. The composer's\n * VisibilityPicker enforces the same on the UI side.\n *\n * HotScore (already present on the model) drives RANKING within these\n * feeds. The recompute job runs every few minutes and the higher-\n * scoring campaigns surface to the top of each feed surface they\n * appear in.\n */\n/**\n * v0.36: the global feed is ALWAYS selected. A campaign is implicitly\n * published to the global home feed, and the creator can optionally\n * additionally pick communities they're a member of to also publish\n * into. `includesGlobal` is kept on the wire shape for forward\n * compatibility but is forced to `true` at parse time — the creator\n * doesn't see a toggle in the composer.\n */\nexport const crowdfundingVisibilitySchema = z.object({\n communityIds: z.array(z.string()).default([]),\n includesGlobal: z\n .boolean()\n .default(true)\n // Force to true regardless of input. The field stays on the wire\n // so consumers can still pivot UI based on it (e.g. legacy rows\n // that explicitly opted out are still readable).\n .transform(() => true),\n});\nexport type CrowdfundingVisibility = z.infer<typeof crowdfundingVisibilitySchema>;\n\n/**\n * Lifecycle state.\n *\n * draft creator is filling the composer\n * submitted creator has accepted T&C and submitted; sits in\n * the area-leader verifier queue\n * awaiting_bank_link area leader has approved; creator must complete\n * Razorpay Linked Account KYC before the campaign\n * goes live. Inserted between `submitted` and\n * `active` so the post-approval payment-setup gate\n * is a first-class state, not a flag-on-active. A\n * `bankLinkDeadlineAt` countdown auto-reverts the\n * campaign to `rejected` if KYC isn't completed\n * in time.\n * rejected area leader rejected, OR bank-link deadline\n * passed, OR Razorpay KYC failed permanently.\n * Creator can edit + resubmit.\n * active publishable in the feed; donations open\n * closed_* terminal end-states with different reasons\n */\nexport const CROWDFUNDING_STATUS_VALUES = [\n 'draft',\n 'submitted',\n 'awaiting_bank_link',\n 'rejected',\n 'active',\n 'closed_success',\n 'closed_timeout',\n 'closed_by_creator',\n] as const;\nexport const crowdfundingStatusSchema = z.enum(CROWDFUNDING_STATUS_VALUES);\nexport type CrowdfundingStatus = z.infer<typeof crowdfundingStatusSchema>;\n\n/**\n * Proof document types — drives the doc-picker UI in the composer's\n * Proof Documents step (added in v0.33) AND the verifier's per-category\n * expected-doc checklist. The composer narrows the picker by category;\n * the verifier sees the full list with the user-supplied type label so\n * they can match the doc to the cause narrative.\n *\n * Per-category required-minimum mapping lives in the composer (frontend)\n * and is enforced at submit by the backend. The set here is the union of\n * what the renderer can offer across categories; some types (e.g.\n * 12a_certificate) are only useful when audience === organization, and\n * the renderer hides them otherwise.\n */\nexport const CROWDFUNDING_PROOF_DOC_TYPE_VALUES = [\n // Medical\n 'hospital_bill',\n 'diagnosis_report',\n 'doctor_letter',\n 'prescription',\n 'insurance_denial',\n // Education\n 'admission_letter',\n 'fee_schedule',\n 'scholarship_letter',\n // Community / civic / supporter-backed\n 'supporters_signed_letter',\n 'project_proposal',\n 'beneficiaries_list',\n // Disaster\n 'relief_org_letter',\n 'affected_area_photos',\n 'government_notification',\n // Organization (when audience === 'organization')\n 'org_registration_certificate',\n 'certificate_12a',\n 'certificate_80g',\n 'certificate_fcra',\n // Generic / cross-cutting\n 'identity_proof',\n 'address_proof',\n 'photo',\n 'video',\n 'other',\n] as const;\nexport const crowdfundingProofDocTypeSchema = z.enum(CROWDFUNDING_PROOF_DOC_TYPE_VALUES);\nexport type CrowdfundingProofDocType = z.infer<typeof crowdfundingProofDocTypeSchema>;\n\n/**\n * Razorpay Linked Account onboarding state, mirrored onto the campaign.\n *\n * not_started - default; creator hasn't started bank-linking yet\n * created - linked account created via Razorpay API; KYC URL\n * has been issued to the creator\n * under_review - creator has submitted KYC; Razorpay is reviewing\n * (typically 1-3 business days)\n * activated - KYC approved; campaign moves to `active`\n * rejected - KYC rejected; creator must update documents and\n * retry\n * suspended - account was activated but later suspended (fraud,\n * ToS violation, etc.); campaign halted pending review\n */\nexport const CROWDFUNDING_RAZORPAY_ACCOUNT_STATUS_VALUES = [\n 'not_started',\n 'created',\n 'under_review',\n 'activated',\n 'rejected',\n 'suspended',\n] as const;\nexport const crowdfundingRazorpayAccountStatusSchema = z.enum(\n CROWDFUNDING_RAZORPAY_ACCOUNT_STATUS_VALUES,\n);\nexport type CrowdfundingRazorpayAccountStatus = z.infer<\n typeof crowdfundingRazorpayAccountStatusSchema\n>;\n\n/**\n * Per-donation verification state. `pending` = attested but no\n * receipt. `verified` = receipt uploaded (creator confirmation\n * optional). `disputed` = creator marked \"I didn't receive this\".\n * Only `verified` rolls into the campaign's `verifiedAmountInr`\n * which drives the visible progress bar.\n */\nexport const CROWDFUNDING_DONATION_STATE_VALUES = ['pending', 'verified', 'disputed'] as const;\nexport const crowdfundingDonationStateSchema = z.enum(CROWDFUNDING_DONATION_STATE_VALUES);\nexport type CrowdfundingDonationState = z.infer<typeof crowdfundingDonationStateSchema>;\n\n// v0.34 dropped the fee-billing mode types entirely. The new flow uses\n// a flat 5 % commission via Razorpay Route at donation-disbursement\n// time — there is no creator-side billing choice to capture.\n\n// ─── Sub-shapes ────────────────────────────────────────────────────────────\n\n/**\n * One stage of the two-leader verification flow. v0.35 split the old\n * single-stage `verification` block into TWO stages: `district` (the\n * district leader for the creator's district vets authenticity) and\n * `state` (the state leader for the creator's state cosigns). Both\n * stages must be `approved` before the campaign can move on to bank\n * linking. Either stage going to `rejected` is terminal for the\n * submission — the creator edits + resubmits, which resets both\n * stages back to `pending`.\n */\nexport const crowdfundingVerificationStageSchema = z.object({\n status: z.enum(['pending', 'approved', 'rejected']),\n /** The leader who acted on this stage (display name — live-joined\n * from User at projection time). */\n verifiedByDisplayName: z.string().optional(),\n verifiedByUserId: z.string().optional(),\n /** When the leader acted. Approved + rejected both stamp this. */\n verifiedAt: z.string().datetime().optional(),\n /** Required when `status === 'rejected'`. Why the leader said no. */\n rejectionReason: z.string().optional(),\n});\nexport type CrowdfundingVerificationStage = z.infer<typeof crowdfundingVerificationStageSchema>;\n\n/**\n * Two-stage verification block. Sequential: state leader can only act\n * after district leader has approved (the queue UI hides un-vetted\n * campaigns from the state queue). Either rejection sends the whole\n * campaign to `rejected` at the campaign level.\n */\nexport const crowdfundingVerificationSchema = z.object({\n district: crowdfundingVerificationStageSchema,\n state: crowdfundingVerificationStageSchema,\n});\nexport type CrowdfundingVerification = z.infer<typeof crowdfundingVerificationSchema>;\n\n/**\n * Public-facing payment surface — what the donor sees in the Donate\n * dialog. The full account number, IFSC, PAN, Aadhaar, supporting\n * docs etc. are kept server-side; only what's needed for the donor\n * to send money + recognise the recipient is exposed.\n *\n * In v0.33 the platform shifted from \"direct UPI to creator\" to\n * \"Razorpay Linked Account split-payment\", so every field on this\n * shape is now OPTIONAL — a Linked-Account campaign carries an\n * activated `razorpayLinkedAccountId` (on the campaign root) and\n * surfaces a Razorpay-hosted checkout, not a UPI QR. Legacy campaigns\n * created before v0.33 still carry these fields; the donor card\n * renders the QR + bank info when present, the Razorpay flow when not.\n */\nexport const crowdfundingPaymentSchema = z.object({\n /** GCS URL of the UPI QR code image uploaded by the creator. The\n * Donate dialog renders this for the donor to scan. */\n upiQrUrl: z.string().url().optional(),\n /** Optional VPA — lets the donor tap a one-tap UPI deep link\n * instead of scanning the QR. e.g. \"ravi@okhdfcbank\". */\n upiId: z.string().optional(),\n /** Last 4 digits of the bank account — shown to the donor as\n * reassurance (\"ending in ••1234\"). Full number never surfaces. */\n bankAccountLast4: z.string().length(4).optional(),\n /** Account holder's name — must match the verified author display\n * name (penny-drop + UDP cross-check at submission time). */\n bankAccountHolderName: z.string().optional(),\n /** Optional bank short name surfaced on the dialog. */\n bankName: z.string().optional(),\n});\nexport type CrowdfundingPayment = z.infer<typeof crowdfundingPaymentSchema>;\n\n/**\n * A single proof document attached by the creator. Multiple instances\n * carried in `proofDocuments` on the campaign; each one has its own\n * type label + free-text description so the verifier sees \"Hospital\n * bill: AIIMS Delhi, June 2026 — ₹1.2L\" not just \"doc-1.pdf\".\n */\nexport const crowdfundingProofDocumentWireSchema = z.object({\n /** GCS signed URL of the uploaded document. */\n url: z.string().url(),\n /** What kind of proof this is. Drives the verifier's per-category\n * expected-doc checklist. */\n type: crowdfundingProofDocTypeSchema,\n /** Creator's own one-line description of the document. Surfaced\n * next to the type label on the verifier surface so they can match\n * the doc to the campaign narrative without opening every PDF. */\n description: z.string().trim().min(3).max(200),\n /** When the upload completed. Useful for the verifier to see the\n * sequence of uploads. */\n uploadedAt: z.string().datetime(),\n});\nexport type CrowdfundingProofDocumentWire = z.infer<typeof crowdfundingProofDocumentWireSchema>;\n\n/**\n * Razorpay Linked Account surface mirrored onto the campaign. Set by\n * the post-approval bank-linking flow; absent while the campaign is in\n * `draft` / `submitted` / `rejected`.\n *\n * Only the STATUS metadata surfaces on the wire — the linked-account\n * id itself stays server-side (used to route disbursements via\n * Razorpay Route, never needed by clients).\n */\nexport const crowdfundingRazorpayAccountWireSchema = z.object({\n /** Current state of the linked-account onboarding. */\n status: crowdfundingRazorpayAccountStatusSchema,\n /** ISO timestamp of when the account moved to `activated`. The\n * campaign flips to `active` at this point. */\n activatedAt: z.string().datetime().nullable().optional(),\n /** Reason Razorpay rejected the KYC submission. Surfaced to the\n * creator so they can fix and retry. */\n rejectionReason: z.string().nullable().optional(),\n /** Razorpay-hosted KYC onboarding URL. Set when status moves to\n * `created`; the creator opens this in a webview to complete KYC. */\n onboardingUrl: z.string().url().nullable().optional(),\n /** Deadline for the creator to finish bank linking. After this\n * date a scheduled job reverts the campaign to `rejected` with a\n * \"bank link deadline missed\" reason. */\n deadlineAt: z.string().datetime().nullable().optional(),\n});\nexport type CrowdfundingRazorpayAccountWire = z.infer<typeof crowdfundingRazorpayAccountWireSchema>;\n\n// ─── Wire shape — feed item ────────────────────────────────────────────────\n\n/**\n * The card-renderable wire shape. Mirrors the engagement + author +\n * area-lineage shape of other feed kinds so the existing\n * EngagementBar, AuthorByline, and feed-projection helpers slot in\n * 1:1 without per-kind branches.\n */\nexport const crowdfundingFeedItemSchema = z.object({\n _id: z.string(),\n contentKind: z.literal('crowdfunding'),\n author: postAuthorSnapshotSchema,\n\n // ─── Campaign content ────────────────────────────────────────────\n title: z.string(),\n description: z.string(),\n category: crowdfundingCategorySchema,\n beneficiaryName: z.string(),\n beneficiaryRelation: z.string().optional(),\n /** Who the campaign is for. Optional on the wire so historic\n * campaigns created before this field landed still validate. */\n audience: crowdfundingAudienceSchema.optional(),\n /** Optional explainer when `category === 'other'` — the writer's\n * short label for the custom cause (e.g. \"Wedding emergency\"). */\n categoryOther: z.string().optional(),\n /** Up to 3 sub-causes within the chosen category, e.g.\n * [\"Cancer treatment\", \"ICU / critical care\"] for `medical`. */\n subCauses: z.array(z.string()).max(3).optional(),\n /** When one of the picked sub-causes is \"Other\", this carries the\n * writer's clarification (e.g. \"Reconstructive surgery\"). */\n subCauseOther: z.string().optional(),\n /** Org-registration class. Only meaningful when\n * `audience === 'organization'`. */\n organizationKind: crowdfundingOrgKindSchema.optional(),\n /** When `organizationKind === 'other'`, the writer's clarification\n * (e.g. \"Religious body\", \"Cooperative\"). */\n organizationKindOther: z.string().optional(),\n /** Story images (separate from supporting documents, which are\n * verifier-only). Up to `CROWDFUNDING_MAX_IMAGES`. */\n images: z.array(z.string().url()).max(CROWDFUNDING_MAX_IMAGES).optional(),\n /** Optional YouTube URL surfaced as a preview/playback embed\n * alongside the story photos. Accepted forms: youtube.com/watch?v=,\n * youtu.be/, youtube.com/shorts/, youtube.com/embed/,\n * m.youtube.com/watch?v=. The wire stores whatever the creator\n * pasted; clients extract the video id themselves at render time. */\n youtubeUrl: z.string().url().optional(),\n\n // ─── Goal + progress ─────────────────────────────────────────────\n goalAmountInr: z.number().int().positive(),\n /** Sum of donations whose `verificationState === 'verified'`\n * (receipt uploaded or creator confirmed). THIS drives the visible\n * progress bar — the product decision is that only trust-grounded\n * money counts visually. */\n verifiedAmountInr: z.number().int().nonnegative(),\n /** Total attested amount — verified + pending + disputed\n * combined. Surfaced as secondary text (\"₹X pending receipt\")\n * so creator + donors can see the full attested pipeline without\n * it inflating the headline progress. */\n attestedAmountInr: z.number().int().nonnegative(),\n /** Distinct donors who attested any state. */\n donorCount: z.number().int().nonnegative(),\n /** Distinct donors whose latest donation is `verified`. The card\n * uses this for \"47 verified supporters\" copy. */\n verifiedDonorCount: z.number().int().nonnegative(),\n\n closesAt: z.string().datetime(),\n\n // ─── Visibility (v0.34+) ─────────────────────────────────────────\n /**\n * Where the campaign appears. v0.34 replaced the per-campaign area\n * scope with this explicit user choice — pick communities you're a\n * member of and/or flip the global-feed toggle. See\n * `crowdfundingVisibilitySchema` for the contract + the at-least-one-\n * publication constraint.\n */\n visibility: crowdfundingVisibilitySchema,\n\n // ─── Verification surface ────────────────────────────────────────\n verification: crowdfundingVerificationSchema,\n\n // ─── Payment surface (donor-facing) ──────────────────────────────\n payment: crowdfundingPaymentSchema,\n\n // ─── Razorpay Linked Account state (creator-facing post-approval) ─\n /**\n * Razorpay Linked Account onboarding state. Absent on `draft` /\n * `submitted` / `rejected` campaigns (nothing to link yet). Present\n * on `awaiting_bank_link` / `active` / closed campaigns. Only the\n * creator's own view of their campaign carries the full record;\n * other donors see at most a public \"verified payee\" badge derived\n * from `status === 'activated'`.\n */\n razorpayAccount: crowdfundingRazorpayAccountWireSchema.optional(),\n\n // ─── Proof documents (verifier + creator view only) ───────────────\n /**\n * Server-side attached proof documents. Surfaced to:\n * - the campaign creator (to remind them what they uploaded)\n * - the verifier on the review queue\n * - admin / moderators on the audit surface\n * Scrubbed for all other viewers (donors, feed readers).\n */\n proofDocuments: z.array(crowdfundingProofDocumentWireSchema).optional(),\n\n // ─── Lifecycle ───────────────────────────────────────────────────\n status: crowdfundingStatusSchema,\n closedAt: z.string().datetime().nullable().optional(),\n /**\n * When the creator accepted the campaign Terms & Conditions. Stamped\n * at submit time. Surfaced so the My Campaigns surface can show\n * \"Agreed to Terms v2 on …\" copy.\n */\n termsAcceptedAt: z.string().datetime().nullable().optional(),\n /**\n * Version string of the T&C the creator accepted. Lets us re-prompt\n * acceptance if the T&C are amended materially.\n */\n termsVersion: z.string().nullable().optional(),\n\n // ─── Standard engagement (same axis as other kinds) ──────────────\n score: z.number().int(),\n commentCount: z.number().int().nonnegative(),\n repostCount: z.number().int().nonnegative(),\n reactionCounts: z.record(z.string(), z.number().int().nonnegative()),\n\n /**\n * Denormalised creator location at the time the campaign was\n * created. Kept on the wire (despite v0.34 dropping the area-scope\n * concept) so the verifier surface and creator's \"My Campaigns\"\n * row can show \"from <village>, <district>\" context without a live\n * join. NOT used for visibility filtering — that lives entirely on\n * `visibility` now.\n */\n areaLineage: areaLineageSnapshotSchema,\n\n createdAt: z.string().datetime(),\n\n viewer: z\n .object({\n vote: voteValueSchema.nullable(),\n reaction: z.string().nullable(),\n bookmarked: z.boolean(),\n isAuthor: z.boolean(),\n reposted: z.boolean(),\n /** The viewer's own donation state on THIS campaign. `null`\n * means they haven't attested anything yet. Populated from\n * the latest CrowdfundingDonation row keyed by\n * (campaignId, viewerUserId). */\n donationState: crowdfundingDonationStateSchema.nullable(),\n /** Amount the viewer last attested, in ₹. Null when no\n * attestation. The card uses this to render the \"You gave\n * ₹500 — upload receipt\" prompt. */\n donationAmountInr: z.number().int().positive().nullable(),\n /** True when the viewer is eligible to verify this campaign\n * (matching-or-higher leader at the campaign's scope, viewing\n * a `submitted` campaign). Renders the in-card Verify CTA. */\n canVerify: z.boolean(),\n })\n .optional(),\n});\nexport type CrowdfundingFeedItem = z.infer<typeof crowdfundingFeedItemSchema>;\n\n// Same shape mirrored as the public \"wire\" alias for parity with the\n// other kinds whose feed envelope === detail envelope.\nexport const communityCrowdfundingWireSchema = crowdfundingFeedItemSchema;\nexport type CommunityCrowdfundingWire = z.infer<typeof communityCrowdfundingWireSchema>;\n\n// ─── Donation wire ─────────────────────────────────────────────────────────\n\n/**\n * Single donation row — surfaced on the campaign's public donor list\n * and on the donor's own \"My Donations\" surface. The full bank /\n * receipt URL stays server-side; the wire carries display info plus\n * the verification state.\n */\nexport const crowdfundingDonationWireSchema = z.object({\n _id: z.string(),\n campaignId: z.string(),\n /** Donor's userId — omitted when `isAnonymous`, so the wire is the\n * privacy boundary not the card. */\n donorUserId: z.string().optional(),\n donorDisplayName: z.string(),\n amountInr: z.number().int().positive(),\n isAnonymous: z.boolean(),\n attestedAt: z.string().datetime(),\n /** When the receipt was uploaded. Absent on pending donations. */\n receiptUploadedAt: z.string().datetime().nullable().optional(),\n /** Signed URL for the receipt screenshot. Visible only to:\n * - the donor (their own row)\n * - the campaign creator\n * - the verifier on review\n * - admin / moderators\n * The list endpoint scrubs this for all other viewers. */\n receiptUrl: z.string().url().nullable().optional(),\n verificationState: crowdfundingDonationStateSchema,\n /** Set when the creator confirmed receipt independently of a\n * receipt upload. e.g. \"I see ₹500 from Ravi in my account\". */\n creatorConfirmed: z.boolean().optional(),\n /** Set when the creator marked \"I didn't receive this\". Donor is\n * notified to upload the receipt; auto-reverts after 7 days. */\n disputeReason: z.string().optional(),\n});\nexport type CrowdfundingDonationWire = z.infer<typeof crowdfundingDonationWireSchema>;\n\n// ─── Create / update / lifecycle bodies ────────────────────────────────────\n\n/**\n * Composer payload. Identity + bank fields are tier-conditional —\n * the server cross-checks the chosen `goalAmountInr` against the\n * provided fields per the tier matrix in constants.ts.\n */\nexport const createCrowdfundingBodySchema = z.object({\n title: z.string().trim().min(CROWDFUNDING_TITLE_MIN_CHARS).max(CROWDFUNDING_TITLE_MAX_CHARS),\n description: z\n .string()\n .trim()\n .min(CROWDFUNDING_DESCRIPTION_MIN_CHARS)\n .max(CROWDFUNDING_DESCRIPTION_MAX_CHARS),\n category: crowdfundingCategorySchema,\n beneficiaryName: z.string().trim().min(2).max(CROWDFUNDING_BENEFICIARY_NAME_MAX_CHARS),\n beneficiaryRelation: z\n .string()\n .trim()\n .max(CROWDFUNDING_BENEFICIARY_RELATION_MAX_CHARS)\n .optional(),\n /** Audience picker — drives the relation chip set + the\n * organization-specific identity sub-steps on the composer. */\n audience: crowdfundingAudienceSchema.optional(),\n /** When `category === 'other'`, the writer's short label for the\n * custom cause. Bounded to keep the database column sane. */\n categoryOther: z.string().trim().max(80).optional(),\n /** Up to 3 sub-causes within the chosen category. */\n subCauses: z.array(z.string().trim().max(60)).max(3).optional(),\n /** Writer's clarification when one of the picked sub-causes is\n * \"Other\". */\n subCauseOther: z.string().trim().max(80).optional(),\n /** Org-registration class. Only set when `audience === 'organization'`. */\n organizationKind: crowdfundingOrgKindSchema.optional(),\n /** Writer's clarification when `organizationKind === 'other'`. */\n organizationKindOther: z.string().trim().max(80).optional(),\n images: z.array(z.string().url()).max(CROWDFUNDING_MAX_IMAGES).optional(),\n /** Optional YouTube video URL. Validated as a URL here; the\n * client-side validator additionally checks the host/path matches\n * a recognised YouTube shape and extracts the video id for the\n * preview component. */\n youtubeUrl: z.string().url().optional(),\n\n goalAmountInr: z.number().int().min(CROWDFUNDING_MIN_GOAL_INR).max(CROWDFUNDING_MAX_GOAL_INR),\n /** Duration in days. The server resolves `closesAt = now +\n * durationDays * 86400 * 1000` so client clock skew can't push\n * the close-time into the past. */\n durationDays: z\n .number()\n .int()\n .min(CROWDFUNDING_MIN_DURATION_DAYS)\n .max(CROWDFUNDING_MAX_DURATION_DAYS),\n\n /**\n * Where the campaign should appear. Pick communities you're a\n * member of and/or flip the global-feed toggle. Server rejects an\n * empty/global-false combination at create time.\n */\n visibility: crowdfundingVisibilitySchema,\n\n // v0.37: dropped composer-side identity collection. Razorpay's\n // hosted onboarding (on the bank-link step) handles PAN, Aadhaar,\n // bank account verification, and address proof for every payee —\n // doing it ourselves was redundant and weakened the privacy story\n // (we held copies of regulatory-sensitive data we didn't need to).\n //\n // ─── Proof documents (v0.33+ — required at submit time) ──────────\n /**\n * Typed + described proof documents the verifier reviews. Optional\n * on the create/update body so an in-progress draft can be saved\n * without docs; the submit-for-review handler enforces a non-empty\n * list (the per-category minimum is enforced server-side via the\n * `CROWDFUNDING_REQUIRED_PROOF_TYPES_BY_CATEGORY` matrix).\n */\n proofDocuments: z\n .array(\n z.object({\n url: z.string().url(),\n type: crowdfundingProofDocTypeSchema,\n description: z.string().trim().min(3).max(200),\n /** Optional on the body; server stamps `now` if absent. */\n uploadedAt: z.string().datetime().optional(),\n }),\n )\n .max(CROWDFUNDING_MAX_PROOF_DOCS)\n .optional(),\n\n // ─── Terms & Conditions acceptance ───────────────────────────────\n /**\n * Version of the T&C the creator agreed to. Set by the composer's\n * T&C step; the submit-for-review handler rejects the campaign if\n * this isn't equal to the current `CROWDFUNDING_TERMS_VERSION`.\n */\n termsVersion: z.string().optional(),\n});\nexport type CreateCrowdfundingBody = z.infer<typeof createCrowdfundingBodySchema>;\n\n/**\n * Update body — only fields that are safe to change on a `draft` or\n * `rejected` campaign before resubmission. Verification + lifecycle\n * fields cannot be updated through this endpoint. Tier + identity\n * fields stay editable so a rejected campaign can fix what the\n * verifier flagged.\n */\nexport const updateCrowdfundingBodySchema = createCrowdfundingBodySchema.partial();\nexport type UpdateCrowdfundingBody = z.infer<typeof updateCrowdfundingBodySchema>;\n\n/**\n * What the verifier sends when approving. v0.35 introduced the two-\n * stage flow (district leader then state leader); the stage being\n * acted on is INFERRED from the leader's jurisdiction at the service\n * layer, not claimed in the body. The body stays an empty strict\n * object so transports that always POST a JSON body continue to work\n * and future fields can be added without a wire-shape change.\n */\nexport const approveCrowdfundingBodySchema = z.object({}).strict();\nexport type ApproveCrowdfundingBody = z.infer<typeof approveCrowdfundingBodySchema>;\n\n/**\n * Rejection body. Reason is required and surfaces back to the creator\n * so they can fix the gap and resubmit. Either the district or the\n * state stage can reject; the stage is inferred from the leader's\n * jurisdiction.\n */\nexport const rejectCrowdfundingBodySchema = z.object({\n reason: z\n .string()\n .trim()\n .min(CROWDFUNDING_REJECTION_REASON_MIN_CHARS)\n .max(CROWDFUNDING_REJECTION_REASON_MAX_CHARS),\n});\nexport type RejectCrowdfundingBody = z.infer<typeof rejectCrowdfundingBodySchema>;\n\n/**\n * Rerun a closed-timeout campaign. The creator opens an edit flow\n * with extended duration (+ optional goal/story tweaks) and re-\n * submits; the resubmit resets BOTH verification stages to pending,\n * and the campaign re-enters the district queue from scratch.\n *\n * Body carries only the new duration — the rest of the edits ride\n * the normal `updateCrowdfundingBodySchema` path that runs alongside\n * the rerun action. Duration is required; without it the rerun makes\n * no sense (the campaign would close immediately again).\n */\nexport const requestRerunCrowdfundingBodySchema = z.object({\n durationDays: z\n .number()\n .int()\n .min(CROWDFUNDING_MIN_DURATION_DAYS)\n .max(CROWDFUNDING_MAX_DURATION_DAYS),\n});\nexport type RequestRerunCrowdfundingBody = z.infer<typeof requestRerunCrowdfundingBodySchema>;\n\n// ─── Donation bodies ───────────────────────────────────────────────────────\n\n/**\n * Donor self-attests a donation. Receipt is OPTIONAL — the\n * attestation creates a `pending` row that the donor can attach a\n * receipt to later (anytime, from settings → My Donations) which\n * promotes it to `verified` and counts toward the progress bar.\n */\nexport const attestCrowdfundingDonationBodySchema = z.object({\n amountInr: z.number().int().min(1).max(CROWDFUNDING_MAX_DONATION_INR),\n isAnonymous: z.boolean().default(false),\n /** GCS URL of the receipt screenshot. When omitted the donation\n * enters `pending` state. */\n receiptUrl: z.string().url().optional(),\n});\nexport type AttestCrowdfundingDonationBody = z.infer<typeof attestCrowdfundingDonationBodySchema>;\n\n/**\n * Upload (or re-upload) a receipt for a previously-attested donation.\n * Promotes a `pending` row to `verified`; for an already-`verified`\n * row it replaces the receipt.\n */\nexport const uploadCrowdfundingReceiptBodySchema = z.object({\n receiptUrl: z.string().url(),\n});\nexport type UploadCrowdfundingReceiptBody = z.infer<typeof uploadCrowdfundingReceiptBodySchema>;\n\n// ─── Listing query ─────────────────────────────────────────────────────────\n\nexport const listCrowdfundingDonationsQuerySchema = z.object({\n page: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(100).optional(),\n state: crowdfundingDonationStateSchema.optional(),\n});\nexport type ListCrowdfundingDonationsQuery = z.infer<typeof listCrowdfundingDonationsQuerySchema>;\n\n/**\n * Per-donor \"My Donations\" surface — different from the per-campaign\n * donor list. Returns every donation the viewer has attested, across\n * all campaigns, so the donor can spot any row that's still\n * `pending` and upload a receipt.\n */\nexport const listMyCrowdfundingDonationsQuerySchema = z.object({\n page: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(100).optional(),\n state: crowdfundingDonationStateSchema.optional(),\n});\nexport type ListMyCrowdfundingDonationsQuery = z.infer<\n typeof listMyCrowdfundingDonationsQuerySchema\n>;\n"]}
1
+ {"version":3,"file":"crowdfunding.js","sourceRoot":"","sources":["../src/crowdfunding.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Community crowdfunding wire shapes.\n *\n * A crowdfunding campaign is a verified civic fundraiser surfaced in\n * the feed alongside posts / polls / lost-found / suggestions-complaints / donate-\n * item. The model is:\n *\n * 1. Creator drafts a campaign, fills bank + UPI QR + identity tier\n * based on the goal amount, picks an area scope.\n * 2. A leader at the matching scope (or any leader higher up the\n * hierarchy) reviews and approves OR rejects with reason.\n * Approved campaigns transition to ACTIVE and appear in the feed.\n * 3. Donors view the card, tap \"Donate\", pay externally via UPI\n * directly to the creator's bank — the platform never sees the\n * money. After paying, the donor self-attests amount + uploads a\n * receipt screenshot (optional). Without a screenshot the\n * donation enters PENDING state — the donor can upload the\n * receipt later (anytime, from settings → My Donations).\n * 4. The live progress bar shows ONLY verified amount (receipt\n * uploaded). Pending donations are counted separately and\n * surfaced as a secondary \"₹X pending receipt\" note. This is the\n * product decision: the visible progress reflects trust-grounded\n * money, not claims.\n *\n * Privacy: bank account number, IFSC, PAN, Aadhaar last-4, and\n * supporting documents are NEVER on the wire. Only `bankAccountLast4`,\n * `bankAccountHolderName`, and a UPI QR URL surface to donors.\n *\n * @module community-schema/crowdfunding\n */\n\nimport { z } from 'zod';\nimport { areaLineageSnapshotSchema } from './area.js';\nimport {\n CROWDFUNDING_BENEFICIARY_NAME_MAX_CHARS,\n CROWDFUNDING_BENEFICIARY_RELATION_MAX_CHARS,\n CROWDFUNDING_DESCRIPTION_MAX_CHARS,\n CROWDFUNDING_DESCRIPTION_MIN_CHARS,\n CROWDFUNDING_MAX_DONATION_INR,\n CROWDFUNDING_MAX_DURATION_DAYS,\n CROWDFUNDING_MAX_GOAL_INR,\n CROWDFUNDING_MAX_IMAGES,\n CROWDFUNDING_MAX_PROOF_DOCS,\n CROWDFUNDING_MAX_SUPPORTING_DOCS,\n CROWDFUNDING_MIN_DURATION_DAYS,\n CROWDFUNDING_MIN_GOAL_INR,\n CROWDFUNDING_REJECTION_REASON_MAX_CHARS,\n CROWDFUNDING_REJECTION_REASON_MIN_CHARS,\n CROWDFUNDING_TITLE_MAX_CHARS,\n CROWDFUNDING_TITLE_MIN_CHARS,\n} from './constants.js';\nimport { voteValueSchema } from './engagement.js';\nimport { postAuthorSnapshotSchema } from './post.js';\n\n// ─── Enums ─────────────────────────────────────────────────────────────────\n\n/**\n * Top-level categories — drives the chip + icon on the card and the\n * verifier's per-category supporting-doc requirements (medical needs\n * hospital invoice; education needs admission letter; etc.).\n */\nexport const CROWDFUNDING_CATEGORY_VALUES = [\n 'medical',\n 'maternity',\n 'senior_care',\n 'special_needs',\n 'education',\n 'memorial',\n 'disaster',\n 'civic',\n 'faith',\n 'sports_talent',\n 'animal_welfare',\n 'environment',\n 'legal_aid',\n 'arts_culture',\n 'self_improvement',\n /**\n * Startup / prototype building — distinct from `self_improvement`\n * (which is now strictly skill / coursework). Covers MVP builds,\n * tooling, initial inventory, working capital, registration fees,\n * marketing for genuine first-stage entrepreneurs.\n */\n 'startup_prototype',\n 'other',\n] as const;\n\n/**\n * Who the campaign is for — drives the relation chip set and the\n * organization-specific identity asks on the composer. Captured so the\n * verifier can match the campaign narrative to the supporting docs\n * (e.g. an `organization` audience should produce 12A / 80G papers,\n * not a personal hospital bill).\n */\nexport const CROWDFUNDING_AUDIENCE_VALUES = [\n 'self',\n 'family',\n 'friend',\n 'community',\n 'organization',\n] as const;\nexport const crowdfundingAudienceSchema = z.enum(CROWDFUNDING_AUDIENCE_VALUES);\nexport type CrowdfundingAudience = z.infer<typeof crowdfundingAudienceSchema>;\n\n/**\n * Org-registration class — only meaningful when `audience ===\n * 'organization'`. Drives the verifier's expected document set\n * (12A/80G for trust, FCRA-style papers for NGO, etc.).\n */\nexport const CROWDFUNDING_ORG_KIND_VALUES = [\n 'ngo',\n 'trust',\n 'society',\n 'section_8',\n 'other',\n] as const;\nexport const crowdfundingOrgKindSchema = z.enum(CROWDFUNDING_ORG_KIND_VALUES);\nexport type CrowdfundingOrgKind = z.infer<typeof crowdfundingOrgKindSchema>;\nexport const crowdfundingCategorySchema = z.enum(CROWDFUNDING_CATEGORY_VALUES);\nexport type CrowdfundingCategory = z.infer<typeof crowdfundingCategorySchema>;\n\n/**\n * Visibility — where the campaign appears.\n *\n * v0.34 dropped the per-campaign area scope entirely. Instead the\n * creator picks one or more communities they're a member of, AND/OR\n * flips a \"show in global feed\" toggle. The campaign appears in those\n * surfaces and ONLY those surfaces (no geographic cascade).\n *\n * communityIds list of community ids the campaign is published into.\n * Empty array means \"no community-scoped publication\".\n * includesGlobal when true the campaign also appears in the global\n * feed (cross-community discovery surface).\n *\n * The Zod schema enforces at-least-one-publication at parse time so a\n * caller can't accidentally create an orphan campaign. The composer's\n * VisibilityPicker enforces the same on the UI side.\n *\n * HotScore (already present on the model) drives RANKING within these\n * feeds. The recompute job runs every few minutes and the higher-\n * scoring campaigns surface to the top of each feed surface they\n * appear in.\n */\n/**\n * v0.36: the global feed is ALWAYS selected. A campaign is implicitly\n * published to the global home feed, and the creator can optionally\n * additionally pick communities they're a member of to also publish\n * into. `includesGlobal` is kept on the wire shape for forward\n * compatibility but is forced to `true` at parse time — the creator\n * doesn't see a toggle in the composer.\n */\nexport const crowdfundingVisibilitySchema = z.object({\n communityIds: z.array(z.string()).default([]),\n includesGlobal: z\n .boolean()\n .default(true)\n // Force to true regardless of input. The field stays on the wire\n // so consumers can still pivot UI based on it (e.g. legacy rows\n // that explicitly opted out are still readable).\n .transform(() => true),\n});\nexport type CrowdfundingVisibility = z.infer<typeof crowdfundingVisibilitySchema>;\n\n/**\n * Lifecycle state.\n *\n * draft creator is filling the composer\n * submitted creator has accepted T&C and submitted; sits in\n * the area-leader verifier queue\n * awaiting_bank_link area leader has approved; creator must complete\n * Razorpay Linked Account KYC before the campaign\n * goes live. Inserted between `submitted` and\n * `active` so the post-approval payment-setup gate\n * is a first-class state, not a flag-on-active. A\n * `bankLinkDeadlineAt` countdown auto-reverts the\n * campaign to `rejected` if KYC isn't completed\n * in time.\n * rejected area leader rejected, OR bank-link deadline\n * passed, OR Razorpay KYC failed permanently.\n * Creator can edit + resubmit.\n * active publishable in the feed; donations open\n * closed_* terminal end-states with different reasons\n */\nexport const CROWDFUNDING_STATUS_VALUES = [\n 'draft',\n 'submitted',\n 'awaiting_bank_link',\n 'rejected',\n 'active',\n 'closed_success',\n 'closed_timeout',\n 'closed_by_creator',\n] as const;\nexport const crowdfundingStatusSchema = z.enum(CROWDFUNDING_STATUS_VALUES);\nexport type CrowdfundingStatus = z.infer<typeof crowdfundingStatusSchema>;\n\n/**\n * Proof document types — drives the doc-picker UI in the composer's\n * Proof Documents step (added in v0.33) AND the verifier's per-category\n * expected-doc checklist. The composer narrows the picker by category;\n * the verifier sees the full list with the user-supplied type label so\n * they can match the doc to the cause narrative.\n *\n * Per-category required-minimum mapping lives in the composer (frontend)\n * and is enforced at submit by the backend. The set here is the union of\n * what the renderer can offer across categories; some types (e.g.\n * 12a_certificate) are only useful when audience === organization, and\n * the renderer hides them otherwise.\n */\nexport const CROWDFUNDING_PROOF_DOC_TYPE_VALUES = [\n // Medical\n 'hospital_bill',\n 'diagnosis_report',\n 'doctor_letter',\n 'prescription',\n 'insurance_denial',\n // Education\n 'admission_letter',\n 'fee_schedule',\n 'scholarship_letter',\n // Community / civic / supporter-backed\n 'supporters_signed_letter',\n 'project_proposal',\n 'beneficiaries_list',\n // Disaster\n 'relief_org_letter',\n 'affected_area_photos',\n 'government_notification',\n // Organization (when audience === 'organization')\n 'org_registration_certificate',\n 'certificate_12a',\n 'certificate_80g',\n 'certificate_fcra',\n // Generic / cross-cutting\n 'identity_proof',\n 'address_proof',\n 'photo',\n 'video',\n 'other',\n] as const;\nexport const crowdfundingProofDocTypeSchema = z.enum(CROWDFUNDING_PROOF_DOC_TYPE_VALUES);\nexport type CrowdfundingProofDocType = z.infer<typeof crowdfundingProofDocTypeSchema>;\n\n/**\n * Razorpay Linked Account onboarding state, mirrored onto the campaign.\n *\n * not_started - default; creator hasn't started bank-linking yet\n * created - linked account created via Razorpay API; KYC URL\n * has been issued to the creator\n * under_review - creator has submitted KYC; Razorpay is reviewing\n * (typically 1-3 business days)\n * activated - KYC approved; campaign moves to `active`\n * rejected - KYC rejected; creator must update documents and\n * retry\n * suspended - account was activated but later suspended (fraud,\n * ToS violation, etc.); campaign halted pending review\n */\nexport const CROWDFUNDING_RAZORPAY_ACCOUNT_STATUS_VALUES = [\n 'not_started',\n 'created',\n 'under_review',\n 'activated',\n 'rejected',\n 'suspended',\n] as const;\nexport const crowdfundingRazorpayAccountStatusSchema = z.enum(\n CROWDFUNDING_RAZORPAY_ACCOUNT_STATUS_VALUES,\n);\nexport type CrowdfundingRazorpayAccountStatus = z.infer<\n typeof crowdfundingRazorpayAccountStatusSchema\n>;\n\n/**\n * Per-donation verification state. `pending` = attested but no\n * receipt. `verified` = receipt uploaded (creator confirmation\n * optional). `disputed` = creator marked \"I didn't receive this\".\n * Only `verified` rolls into the campaign's `verifiedAmountInr`\n * which drives the visible progress bar.\n */\nexport const CROWDFUNDING_DONATION_STATE_VALUES = ['pending', 'verified', 'disputed'] as const;\nexport const crowdfundingDonationStateSchema = z.enum(CROWDFUNDING_DONATION_STATE_VALUES);\nexport type CrowdfundingDonationState = z.infer<typeof crowdfundingDonationStateSchema>;\n\n// v0.34 dropped the fee-billing mode types entirely. The new flow uses\n// a flat 5 % commission via Razorpay Route at donation-disbursement\n// time — there is no creator-side billing choice to capture.\n\n// ─── Sub-shapes ────────────────────────────────────────────────────────────\n\n/**\n * One stage of the two-leader verification flow. v0.35 split the old\n * single-stage `verification` block into TWO stages: `district` (the\n * district leader for the creator's district vets authenticity) and\n * `state` (the state leader for the creator's state cosigns). Both\n * stages must be `approved` before the campaign can move on to bank\n * linking. Either stage going to `rejected` is terminal for the\n * submission — the creator edits + resubmits, which resets both\n * stages back to `pending`.\n */\nexport const crowdfundingVerificationStageSchema = z.object({\n status: z.enum(['pending', 'approved', 'rejected']),\n /** The leader who acted on this stage (display name — live-joined\n * from User at projection time). */\n verifiedByDisplayName: z.string().optional(),\n verifiedByUserId: z.string().optional(),\n /** When the leader acted. Approved + rejected both stamp this. */\n verifiedAt: z.string().datetime().optional(),\n /** Required when `status === 'rejected'`. Why the leader said no. */\n rejectionReason: z.string().optional(),\n});\nexport type CrowdfundingVerificationStage = z.infer<typeof crowdfundingVerificationStageSchema>;\n\n/**\n * Two-stage verification block. Sequential: state leader can only act\n * after district leader has approved (the queue UI hides un-vetted\n * campaigns from the state queue). Either rejection sends the whole\n * campaign to `rejected` at the campaign level.\n */\nexport const crowdfundingVerificationSchema = z.object({\n district: crowdfundingVerificationStageSchema,\n state: crowdfundingVerificationStageSchema,\n});\nexport type CrowdfundingVerification = z.infer<typeof crowdfundingVerificationSchema>;\n\n/**\n * Public-facing payment surface — what the donor sees in the Donate\n * dialog. The full account number, IFSC, PAN, Aadhaar, supporting\n * docs etc. are kept server-side; only what's needed for the donor\n * to send money + recognise the recipient is exposed.\n *\n * In v0.33 the platform shifted from \"direct UPI to creator\" to\n * \"Razorpay Linked Account split-payment\", so every field on this\n * shape is now OPTIONAL — a Linked-Account campaign carries an\n * activated `razorpayLinkedAccountId` (on the campaign root) and\n * surfaces a Razorpay-hosted checkout, not a UPI QR. Legacy campaigns\n * created before v0.33 still carry these fields; the donor card\n * renders the QR + bank info when present, the Razorpay flow when not.\n */\nexport const crowdfundingPaymentSchema = z.object({\n /** GCS URL of the UPI QR code image uploaded by the creator. The\n * Donate dialog renders this for the donor to scan. */\n upiQrUrl: z.string().url().optional(),\n /** Optional VPA — lets the donor tap a one-tap UPI deep link\n * instead of scanning the QR. e.g. \"ravi@okhdfcbank\". */\n upiId: z.string().optional(),\n /** Last 4 digits of the bank account — shown to the donor as\n * reassurance (\"ending in ••1234\"). Full number never surfaces. */\n bankAccountLast4: z.string().length(4).optional(),\n /** Account holder's name — must match the verified author display\n * name (penny-drop + UDP cross-check at submission time). */\n bankAccountHolderName: z.string().optional(),\n /** Optional bank short name surfaced on the dialog. */\n bankName: z.string().optional(),\n});\nexport type CrowdfundingPayment = z.infer<typeof crowdfundingPaymentSchema>;\n\n/**\n * A single proof document attached by the creator. Multiple instances\n * carried in `proofDocuments` on the campaign; each one has its own\n * type label + free-text description so the verifier sees \"Hospital\n * bill: AIIMS Delhi, June 2026 — ₹1.2L\" not just \"doc-1.pdf\".\n */\nexport const crowdfundingProofDocumentWireSchema = z.object({\n /** GCS signed URL of the uploaded document. */\n url: z.string().url(),\n /** What kind of proof this is. Drives the verifier's per-category\n * expected-doc checklist. */\n type: crowdfundingProofDocTypeSchema,\n /** Creator's own one-line description of the document. Surfaced\n * next to the type label on the verifier surface so they can match\n * the doc to the campaign narrative without opening every PDF. */\n description: z.string().trim().min(3).max(200),\n /** When the upload completed. Useful for the verifier to see the\n * sequence of uploads. */\n uploadedAt: z.string().datetime(),\n});\nexport type CrowdfundingProofDocumentWire = z.infer<typeof crowdfundingProofDocumentWireSchema>;\n\n/**\n * Razorpay Linked Account surface mirrored onto the campaign. Set by\n * the post-approval bank-linking flow; absent while the campaign is in\n * `draft` / `submitted` / `rejected`.\n *\n * Only the STATUS metadata surfaces on the wire — the linked-account\n * id itself stays server-side (used to route disbursements via\n * Razorpay Route, never needed by clients).\n */\nexport const crowdfundingRazorpayAccountWireSchema = z.object({\n /** Current state of the linked-account onboarding. */\n status: crowdfundingRazorpayAccountStatusSchema,\n /** ISO timestamp of when the account moved to `activated`. The\n * campaign flips to `active` at this point. */\n activatedAt: z.string().datetime().nullable().optional(),\n /** Reason Razorpay rejected the KYC submission. Surfaced to the\n * creator so they can fix and retry. */\n rejectionReason: z.string().nullable().optional(),\n /** Razorpay-hosted KYC onboarding URL. Set when status moves to\n * `created`; the creator opens this in a webview to complete KYC. */\n onboardingUrl: z.string().url().nullable().optional(),\n /** Deadline for the creator to finish bank linking. After this\n * date a scheduled job reverts the campaign to `rejected` with a\n * \"bank link deadline missed\" reason. */\n deadlineAt: z.string().datetime().nullable().optional(),\n});\nexport type CrowdfundingRazorpayAccountWire = z.infer<typeof crowdfundingRazorpayAccountWireSchema>;\n\n// ─── Wire shape — feed item ────────────────────────────────────────────────\n\n/**\n * The card-renderable wire shape. Mirrors the engagement + author +\n * area-lineage shape of other feed kinds so the existing\n * EngagementBar, AuthorByline, and feed-projection helpers slot in\n * 1:1 without per-kind branches.\n */\nexport const crowdfundingFeedItemSchema = z.object({\n _id: z.string(),\n contentKind: z.literal('crowdfunding'),\n author: postAuthorSnapshotSchema,\n\n // ─── Campaign content ────────────────────────────────────────────\n title: z.string(),\n description: z.string(),\n category: crowdfundingCategorySchema,\n beneficiaryName: z.string(),\n beneficiaryRelation: z.string().optional(),\n /** Who the campaign is for. Optional on the wire so historic\n * campaigns created before this field landed still validate. */\n audience: crowdfundingAudienceSchema.optional(),\n /** Optional explainer when `category === 'other'` — the writer's\n * short label for the custom cause (e.g. \"Wedding emergency\"). */\n categoryOther: z.string().optional(),\n /** Up to 3 sub-causes within the chosen category, e.g.\n * [\"Cancer treatment\", \"ICU / critical care\"] for `medical`. */\n subCauses: z.array(z.string()).max(3).optional(),\n /** When one of the picked sub-causes is \"Other\", this carries the\n * writer's clarification (e.g. \"Reconstructive surgery\"). */\n subCauseOther: z.string().optional(),\n /** Org-registration class. Only meaningful when\n * `audience === 'organization'`. */\n organizationKind: crowdfundingOrgKindSchema.optional(),\n /** When `organizationKind === 'other'`, the writer's clarification\n * (e.g. \"Religious body\", \"Cooperative\"). */\n organizationKindOther: z.string().optional(),\n /** Story images (separate from supporting documents, which are\n * verifier-only). Up to `CROWDFUNDING_MAX_IMAGES`. */\n images: z.array(z.string().url()).max(CROWDFUNDING_MAX_IMAGES).optional(),\n /** Optional YouTube URL surfaced as a preview/playback embed\n * alongside the story photos. Accepted forms: youtube.com/watch?v=,\n * youtu.be/, youtube.com/shorts/, youtube.com/embed/,\n * m.youtube.com/watch?v=. The wire stores whatever the creator\n * pasted; clients extract the video id themselves at render time. */\n youtubeUrl: z.string().url().optional(),\n\n // ─── Goal + progress ─────────────────────────────────────────────\n goalAmountInr: z.number().int().positive(),\n /** Sum of donations whose `verificationState === 'verified'`\n * (receipt uploaded or creator confirmed). THIS drives the visible\n * progress bar — the product decision is that only trust-grounded\n * money counts visually. */\n verifiedAmountInr: z.number().int().nonnegative(),\n /** Total attested amount — verified + pending + disputed\n * combined. Surfaced as secondary text (\"₹X pending receipt\")\n * so creator + donors can see the full attested pipeline without\n * it inflating the headline progress. */\n attestedAmountInr: z.number().int().nonnegative(),\n /** Distinct donors who attested any state. */\n donorCount: z.number().int().nonnegative(),\n /** Distinct donors whose latest donation is `verified`. The card\n * uses this for \"47 verified supporters\" copy. */\n verifiedDonorCount: z.number().int().nonnegative(),\n\n closesAt: z.string().datetime(),\n\n // ─── Visibility (v0.34+) ─────────────────────────────────────────\n /**\n * Where the campaign appears. v0.34 replaced the per-campaign area\n * scope with this explicit user choice — pick communities you're a\n * member of and/or flip the global-feed toggle. See\n * `crowdfundingVisibilitySchema` for the contract + the at-least-one-\n * publication constraint.\n */\n visibility: crowdfundingVisibilitySchema,\n\n // ─── Verification surface ────────────────────────────────────────\n verification: crowdfundingVerificationSchema,\n\n // ─── Payment surface (donor-facing) ──────────────────────────────\n payment: crowdfundingPaymentSchema,\n\n // ─── Razorpay Linked Account state (creator-facing post-approval) ─\n /**\n * Razorpay Linked Account onboarding state. Absent on `draft` /\n * `submitted` / `rejected` campaigns (nothing to link yet). Present\n * on `awaiting_bank_link` / `active` / closed campaigns. Only the\n * creator's own view of their campaign carries the full record;\n * other donors see at most a public \"verified payee\" badge derived\n * from `status === 'activated'`.\n */\n razorpayAccount: crowdfundingRazorpayAccountWireSchema.optional(),\n\n // ─── Proof documents (verifier + creator view only) ───────────────\n /**\n * Server-side attached proof documents. Surfaced to:\n * - the campaign creator (to remind them what they uploaded)\n * - the verifier on the review queue\n * - admin / moderators on the audit surface\n * Scrubbed for all other viewers (donors, feed readers).\n */\n proofDocuments: z.array(crowdfundingProofDocumentWireSchema).optional(),\n\n // ─── Lifecycle ───────────────────────────────────────────────────\n status: crowdfundingStatusSchema,\n closedAt: z.string().datetime().nullable().optional(),\n /**\n * When the creator accepted the campaign Terms & Conditions. Stamped\n * at submit time. Surfaced so the My Campaigns surface can show\n * \"Agreed to Terms v2 on …\" copy.\n */\n termsAcceptedAt: z.string().datetime().nullable().optional(),\n /**\n * Version string of the T&C the creator accepted. Lets us re-prompt\n * acceptance if the T&C are amended materially.\n */\n termsVersion: z.string().nullable().optional(),\n\n // ─── Standard engagement (same axis as other kinds) ──────────────\n score: z.number().int(),\n commentCount: z.number().int().nonnegative(),\n repostCount: z.number().int().nonnegative(),\n reactionCounts: z.record(z.string(), z.number().int().nonnegative()),\n\n /**\n * Denormalised creator location at the time the campaign was\n * created. Kept on the wire (despite v0.34 dropping the area-scope\n * concept) so the verifier surface and creator's \"My Campaigns\"\n * row can show \"from <village>, <district>\" context without a live\n * join. NOT used for visibility filtering — that lives entirely on\n * `visibility` now.\n */\n areaLineage: areaLineageSnapshotSchema,\n\n createdAt: z.string().datetime(),\n\n viewer: z\n .object({\n vote: voteValueSchema.nullable(),\n reaction: z.string().nullable(),\n bookmarked: z.boolean(),\n isAuthor: z.boolean(),\n reposted: z.boolean(),\n /** The viewer's own donation state on THIS campaign. `null`\n * means they haven't attested anything yet. Populated from\n * the latest CrowdfundingDonation row keyed by\n * (campaignId, viewerUserId). */\n donationState: crowdfundingDonationStateSchema.nullable(),\n /** Amount the viewer last attested, in ₹. Null when no\n * attestation. The card uses this to render the \"You gave\n * ₹500 — upload receipt\" prompt. */\n donationAmountInr: z.number().int().positive().nullable(),\n /** True when the viewer is eligible to verify this campaign\n * (matching-or-higher leader at the campaign's scope, viewing\n * a `submitted` campaign). Renders the in-card Verify CTA. */\n canVerify: z.boolean(),\n })\n .optional(),\n});\nexport type CrowdfundingFeedItem = z.infer<typeof crowdfundingFeedItemSchema>;\n\n// Same shape mirrored as the public \"wire\" alias for parity with the\n// other kinds whose feed envelope === detail envelope.\nexport const communityCrowdfundingWireSchema = crowdfundingFeedItemSchema;\nexport type CommunityCrowdfundingWire = z.infer<typeof communityCrowdfundingWireSchema>;\n\n// ─── Donation wire ─────────────────────────────────────────────────────────\n\n/**\n * Single donation row — surfaced on the campaign's public donor list\n * and on the donor's own \"My Donations\" surface. The full bank /\n * receipt URL stays server-side; the wire carries display info plus\n * the verification state.\n */\nexport const crowdfundingDonationWireSchema = z.object({\n _id: z.string(),\n campaignId: z.string(),\n /** Donor's userId — omitted when `isAnonymous`, so the wire is the\n * privacy boundary not the card. */\n donorUserId: z.string().optional(),\n donorDisplayName: z.string(),\n amountInr: z.number().int().positive(),\n isAnonymous: z.boolean(),\n attestedAt: z.string().datetime(),\n /** When the receipt was uploaded. Absent on pending donations. */\n receiptUploadedAt: z.string().datetime().nullable().optional(),\n /** Signed URL for the receipt screenshot. Visible only to:\n * - the donor (their own row)\n * - the campaign creator\n * - the verifier on review\n * - admin / moderators\n * The list endpoint scrubs this for all other viewers. */\n receiptUrl: z.string().url().nullable().optional(),\n verificationState: crowdfundingDonationStateSchema,\n /** Set when the creator confirmed receipt independently of a\n * receipt upload. e.g. \"I see ₹500 from Ravi in my account\". */\n creatorConfirmed: z.boolean().optional(),\n /** Set when the creator marked \"I didn't receive this\". Donor is\n * notified to upload the receipt; auto-reverts after 7 days. */\n disputeReason: z.string().optional(),\n});\nexport type CrowdfundingDonationWire = z.infer<typeof crowdfundingDonationWireSchema>;\n\n// ─── Create / update / lifecycle bodies ────────────────────────────────────\n\n/**\n * Composer payload. Identity + bank fields are tier-conditional —\n * the server cross-checks the chosen `goalAmountInr` against the\n * provided fields per the tier matrix in constants.ts.\n */\nexport const createCrowdfundingBodySchema = z.object({\n title: z.string().trim().min(CROWDFUNDING_TITLE_MIN_CHARS).max(CROWDFUNDING_TITLE_MAX_CHARS),\n description: z\n .string()\n .trim()\n .min(CROWDFUNDING_DESCRIPTION_MIN_CHARS)\n .max(CROWDFUNDING_DESCRIPTION_MAX_CHARS),\n category: crowdfundingCategorySchema,\n beneficiaryName: z.string().trim().min(2).max(CROWDFUNDING_BENEFICIARY_NAME_MAX_CHARS),\n beneficiaryRelation: z\n .string()\n .trim()\n .max(CROWDFUNDING_BENEFICIARY_RELATION_MAX_CHARS)\n .optional(),\n /** Audience picker — drives the relation chip set + the\n * organization-specific identity sub-steps on the composer. */\n audience: crowdfundingAudienceSchema.optional(),\n /** When `category === 'other'`, the writer's short label for the\n * custom cause. Bounded to keep the database column sane. */\n categoryOther: z.string().trim().max(80).optional(),\n /** Up to 3 sub-causes within the chosen category. */\n subCauses: z.array(z.string().trim().max(60)).max(3).optional(),\n /** Writer's clarification when one of the picked sub-causes is\n * \"Other\". */\n subCauseOther: z.string().trim().max(80).optional(),\n /** Org-registration class. Only set when `audience === 'organization'`. */\n organizationKind: crowdfundingOrgKindSchema.optional(),\n /** Writer's clarification when `organizationKind === 'other'`. */\n organizationKindOther: z.string().trim().max(80).optional(),\n images: z.array(z.string().url()).max(CROWDFUNDING_MAX_IMAGES).optional(),\n /** Optional YouTube video URL. Validated as a URL here; the\n * client-side validator additionally checks the host/path matches\n * a recognised YouTube shape and extracts the video id for the\n * preview component. */\n youtubeUrl: z.string().url().optional(),\n\n goalAmountInr: z.number().int().min(CROWDFUNDING_MIN_GOAL_INR).max(CROWDFUNDING_MAX_GOAL_INR),\n /** Duration in days. The server resolves `closesAt = now +\n * durationDays * 86400 * 1000` so client clock skew can't push\n * the close-time into the past. */\n durationDays: z\n .number()\n .int()\n .min(CROWDFUNDING_MIN_DURATION_DAYS)\n .max(CROWDFUNDING_MAX_DURATION_DAYS),\n\n /**\n * Where the campaign should appear. Pick communities you're a\n * member of and/or flip the global-feed toggle. Server rejects an\n * empty/global-false combination at create time.\n */\n visibility: crowdfundingVisibilitySchema,\n\n // v0.37: dropped composer-side identity collection. Razorpay's\n // hosted onboarding (on the bank-link step) handles PAN, Aadhaar,\n // bank account verification, and address proof for every payee —\n // doing it ourselves was redundant and weakened the privacy story\n // (we held copies of regulatory-sensitive data we didn't need to).\n //\n // ─── Proof documents (v0.33+ — required at submit time) ──────────\n /**\n * Typed + described proof documents the verifier reviews. Optional\n * on the create/update body so an in-progress draft can be saved\n * without docs; the submit-for-review handler enforces a non-empty\n * list (the per-category minimum is enforced server-side via the\n * `CROWDFUNDING_REQUIRED_PROOF_TYPES_BY_CATEGORY` matrix).\n */\n proofDocuments: z\n .array(\n z.object({\n url: z.string().url(),\n type: crowdfundingProofDocTypeSchema,\n description: z.string().trim().min(3).max(200),\n /** Optional on the body; server stamps `now` if absent. */\n uploadedAt: z.string().datetime().optional(),\n }),\n )\n .max(CROWDFUNDING_MAX_PROOF_DOCS)\n .optional(),\n\n // ─── Terms & Conditions acceptance ───────────────────────────────\n /**\n * Version of the T&C the creator agreed to. Set by the composer's\n * T&C step; the submit-for-review handler rejects the campaign if\n * this isn't equal to the current `CROWDFUNDING_TERMS_VERSION`.\n */\n termsVersion: z.string().optional(),\n});\nexport type CreateCrowdfundingBody = z.infer<typeof createCrowdfundingBodySchema>;\n\n/**\n * Update body — only fields that are safe to change on a `draft` or\n * `rejected` campaign before resubmission. Verification + lifecycle\n * fields cannot be updated through this endpoint. Tier + identity\n * fields stay editable so a rejected campaign can fix what the\n * verifier flagged.\n */\nexport const updateCrowdfundingBodySchema = createCrowdfundingBodySchema.partial();\nexport type UpdateCrowdfundingBody = z.infer<typeof updateCrowdfundingBodySchema>;\n\n/**\n * What the verifier sends when approving. v0.35 introduced the two-\n * stage flow (district leader then state leader); the stage being\n * acted on is INFERRED from the leader's jurisdiction at the service\n * layer, not claimed in the body. The body stays an empty strict\n * object so transports that always POST a JSON body continue to work\n * and future fields can be added without a wire-shape change.\n */\nexport const approveCrowdfundingBodySchema = z.object({}).strict();\nexport type ApproveCrowdfundingBody = z.infer<typeof approveCrowdfundingBodySchema>;\n\n/**\n * Rejection body. Reason is required and surfaces back to the creator\n * so they can fix the gap and resubmit. Either the district or the\n * state stage can reject; the stage is inferred from the leader's\n * jurisdiction.\n */\nexport const rejectCrowdfundingBodySchema = z.object({\n reason: z\n .string()\n .trim()\n .min(CROWDFUNDING_REJECTION_REASON_MIN_CHARS)\n .max(CROWDFUNDING_REJECTION_REASON_MAX_CHARS),\n});\nexport type RejectCrowdfundingBody = z.infer<typeof rejectCrowdfundingBodySchema>;\n\n/**\n * Rerun a closed-timeout campaign. The creator opens an edit flow\n * with extended duration (+ optional goal/story tweaks) and re-\n * submits; the resubmit resets BOTH verification stages to pending,\n * and the campaign re-enters the district queue from scratch.\n *\n * Body carries only the new duration — the rest of the edits ride\n * the normal `updateCrowdfundingBodySchema` path that runs alongside\n * the rerun action. Duration is required; without it the rerun makes\n * no sense (the campaign would close immediately again).\n */\nexport const requestRerunCrowdfundingBodySchema = z.object({\n durationDays: z\n .number()\n .int()\n .min(CROWDFUNDING_MIN_DURATION_DAYS)\n .max(CROWDFUNDING_MAX_DURATION_DAYS),\n});\nexport type RequestRerunCrowdfundingBody = z.infer<typeof requestRerunCrowdfundingBodySchema>;\n\n// ─── Donation bodies ───────────────────────────────────────────────────────\n\n/**\n * Donor self-attests a donation. Receipt is OPTIONAL — the\n * attestation creates a `pending` row that the donor can attach a\n * receipt to later (anytime, from settings → My Donations) which\n * promotes it to `verified` and counts toward the progress bar.\n */\nexport const attestCrowdfundingDonationBodySchema = z.object({\n amountInr: z.number().int().min(1).max(CROWDFUNDING_MAX_DONATION_INR),\n isAnonymous: z.boolean().default(false),\n /** GCS URL of the receipt screenshot. When omitted the donation\n * enters `pending` state. */\n receiptUrl: z.string().url().optional(),\n});\nexport type AttestCrowdfundingDonationBody = z.infer<typeof attestCrowdfundingDonationBodySchema>;\n\n/**\n * Upload (or re-upload) a receipt for a previously-attested donation.\n * Promotes a `pending` row to `verified`; for an already-`verified`\n * row it replaces the receipt.\n */\nexport const uploadCrowdfundingReceiptBodySchema = z.object({\n receiptUrl: z.string().url(),\n});\nexport type UploadCrowdfundingReceiptBody = z.infer<typeof uploadCrowdfundingReceiptBodySchema>;\n\n// ─── Listing query ─────────────────────────────────────────────────────────\n\nexport const listCrowdfundingDonationsQuerySchema = z.object({\n page: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(100).optional(),\n state: crowdfundingDonationStateSchema.optional(),\n});\nexport type ListCrowdfundingDonationsQuery = z.infer<typeof listCrowdfundingDonationsQuerySchema>;\n\n/**\n * Per-donor \"My Donations\" surface — different from the per-campaign\n * donor list. Returns every donation the viewer has attested, across\n * all campaigns, so the donor can spot any row that's still\n * `pending` and upload a receipt.\n */\nexport const listMyCrowdfundingDonationsQuerySchema = z.object({\n page: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(100).optional(),\n state: crowdfundingDonationStateSchema.optional(),\n});\nexport type ListMyCrowdfundingDonationsQuery = z.infer<\n typeof listMyCrowdfundingDonationsQuerySchema\n>;\n"]}
@@ -61,7 +61,7 @@ export declare const setVoteResponseSchema: z.ZodObject<{
61
61
  contentKind: z.ZodEnum<{
62
62
  post: "post";
63
63
  lost_found: "lost_found";
64
- voice_box: "voice_box";
64
+ suggestions_complaints: "suggestions_complaints";
65
65
  donate_item: "donate_item";
66
66
  poll: "poll";
67
67
  crowdfunding: "crowdfunding";
@@ -97,7 +97,7 @@ export declare const setReactionResponseSchema: z.ZodObject<{
97
97
  contentKind: z.ZodEnum<{
98
98
  post: "post";
99
99
  lost_found: "lost_found";
100
- voice_box: "voice_box";
100
+ suggestions_complaints: "suggestions_complaints";
101
101
  donate_item: "donate_item";
102
102
  poll: "poll";
103
103
  crowdfunding: "crowdfunding";
@@ -127,7 +127,7 @@ export declare const toggleBookmarkResponseSchema: z.ZodObject<{
127
127
  contentKind: z.ZodEnum<{
128
128
  post: "post";
129
129
  lost_found: "lost_found";
130
- voice_box: "voice_box";
130
+ suggestions_complaints: "suggestions_complaints";
131
131
  donate_item: "donate_item";
132
132
  poll: "poll";
133
133
  crowdfunding: "crowdfunding";
package/dist/enums.d.ts CHANGED
@@ -49,7 +49,7 @@ export type VisibilityLevel = z.infer<typeof visibilityLevelSchema>;
49
49
  export declare const VISIBILITY_LEVEL_RANK: Record<VisibilityLevel, number>;
50
50
  /**
51
51
  * The kinds of items that show up in the feed. `post` is the
52
- * community-native kind; `lost_found`, `voice_box`, and `donate_item`
52
+ * community-native kind; `lost_found`, `suggestions_complaints`, and `donate_item`
53
53
  * are existing legacy features surfaced into the feed via polymorphic
54
54
  * union; `poll` is the structured-choice kind backed by its own
55
55
  * `CommunityPoll` collection (votes live in a separate `PollVote`
@@ -58,11 +58,11 @@ export declare const VISIBILITY_LEVEL_RANK: Record<VisibilityLevel, number>;
58
58
  * Engagement (upvote / reaction / comment / share) is keyed by
59
59
  * (contentKind, contentId) so every kind gets the same engagement bar.
60
60
  */
61
- export declare const CONTENT_KIND_VALUES: readonly ["post", "lost_found", "voice_box", "donate_item", "poll", "crowdfunding"];
61
+ export declare const CONTENT_KIND_VALUES: readonly ["post", "lost_found", "suggestions_complaints", "donate_item", "poll", "crowdfunding"];
62
62
  export declare const contentKindSchema: z.ZodEnum<{
63
63
  post: "post";
64
64
  lost_found: "lost_found";
65
- voice_box: "voice_box";
65
+ suggestions_complaints: "suggestions_complaints";
66
66
  donate_item: "donate_item";
67
67
  poll: "poll";
68
68
  crowdfunding: "crowdfunding";
@@ -1 +1 @@
1
- {"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../src/enums.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,uBAAuB,+DAM1B,CAAC;AACX,eAAO,MAAM,qBAAqB;;;;;;EAAkC,CAAC;AACrE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAMjE,CAAC;AAIF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,qFAOtB,CAAC;AACX,eAAO,MAAM,iBAAiB;;;;;;;EAA8B,CAAC;AAC7D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAI5D;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,qEAQvB,CAAC;AACX,eAAO,MAAM,kBAAkB;;;;;;;;EAA+B,CAAC;AAC/D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,gCAAiC,CAAC;AACrE,eAAO,MAAM,oBAAoB;;;EAAiC,CAAC;AACnE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAIlE;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,yIAUvB,CAAC;AACX,eAAO,MAAM,kBAAkB;;;;;;;;;;EAA+B,CAAC;AAC/D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,6CAA6C;AAC7C,eAAO,MAAM,oBAAoB,4DAA6D,CAAC;AAC/F,eAAO,MAAM,kBAAkB;;;;;EAA+B,CAAC;AAC/D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,gCAAiC,CAAC;AAC/D,eAAO,MAAM,cAAc;;;;EAA2B,CAAC;AACvD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC"}
1
+ {"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../src/enums.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,uBAAuB,+DAM1B,CAAC;AACX,eAAO,MAAM,qBAAqB;;;;;;EAAkC,CAAC;AACrE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAMjE,CAAC;AAIF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,kGAOtB,CAAC;AACX,eAAO,MAAM,iBAAiB;;;;;;;EAA8B,CAAC;AAC7D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAI5D;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,qEAQvB,CAAC;AACX,eAAO,MAAM,kBAAkB;;;;;;;;EAA+B,CAAC;AAC/D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,gCAAiC,CAAC;AACrE,eAAO,MAAM,oBAAoB;;;EAAiC,CAAC;AACnE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAIlE;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,yIAUvB,CAAC;AACX,eAAO,MAAM,kBAAkB;;;;;;;;;;EAA+B,CAAC;AAC/D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,6CAA6C;AAC7C,eAAO,MAAM,oBAAoB,4DAA6D,CAAC;AAC/F,eAAO,MAAM,kBAAkB;;;;;EAA+B,CAAC;AAC/D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,gCAAiC,CAAC;AAC/D,eAAO,MAAM,cAAc;;;;EAA2B,CAAC;AACvD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC"}
package/dist/enums.js CHANGED
@@ -56,7 +56,7 @@ export const VISIBILITY_LEVEL_RANK = {
56
56
  // ─── Polymorphic content kind ───────────────────────────────────────────────
57
57
  /**
58
58
  * The kinds of items that show up in the feed. `post` is the
59
- * community-native kind; `lost_found`, `voice_box`, and `donate_item`
59
+ * community-native kind; `lost_found`, `suggestions_complaints`, and `donate_item`
60
60
  * are existing legacy features surfaced into the feed via polymorphic
61
61
  * union; `poll` is the structured-choice kind backed by its own
62
62
  * `CommunityPoll` collection (votes live in a separate `PollVote`
@@ -68,7 +68,7 @@ export const VISIBILITY_LEVEL_RANK = {
68
68
  export const CONTENT_KIND_VALUES = [
69
69
  'post',
70
70
  'lost_found',
71
- 'voice_box',
71
+ 'suggestions_complaints',
72
72
  'donate_item',
73
73
  'poll',
74
74
  'crowdfunding',
package/dist/enums.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"enums.js","sourceRoot":"","sources":["../src/enums.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,OAAO;IACP,UAAU;IACV,OAAO;IACP,UAAU;IACV,QAAQ;CACA,CAAC;AACX,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;AAGrE;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAoC;IACpE,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;IACX,MAAM,EAAE,CAAC;CACV,CAAC;AAEF,+EAA+E;AAE/E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,MAAM;IACN,YAAY;IACZ,WAAW;IACX,aAAa;IACb,MAAM;IACN,cAAc;CACN,CAAC;AACX,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AAG7D,+EAA+E;AAE/E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,MAAM;IACN,MAAM;IACN,MAAM;IACN,KAAK;IACL,KAAK;IACL,OAAO;IACP,SAAS;CACD,CAAC;AACX,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;AAG/D,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAU,CAAC;AACrE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;AAGnE,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,MAAM;IACN,YAAY;IACZ,aAAa;IACb,gBAAgB;IAChB,gBAAgB;IAChB,UAAU;IACV,WAAW;IACX,iBAAiB;IACjB,OAAO;CACC,CAAC;AACX,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;AAG/D,6CAA6C;AAC7C,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,CAAU,CAAC;AAC/F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;AAG/D,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAU,CAAC;AAC/D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC","sourcesContent":["/**\n * Enum value arrays shared across the community feature.\n *\n * Each enum is exported as both a `*_VALUES` tuple and the corresponding\n * Zod schema so backend Mongoose models and frontend forms validate\n * against the exact same set.\n *\n * @module community-schema/enums\n */\n\nimport { z } from 'zod';\n\n// ─── Feed viewport (viewer-side geographic filter) ─────────────────────────\n\n/**\n * Geographic scope the VIEWER chose for their feed — the area-proximity\n * cascade is gated by this value.\n *\n * Posts do NOT carry a per-post `visibilityLevel` any more. Every post\n * is implicitly global; visibility is purely a function of (a) the\n * author's `areaLineage` at write time and (b) the viewer's scope\n * choice here. The cascade walks from the viewer's locality outward\n * and includes any post whose author was inside the viewer's area at\n * ANY level the viewer's scope reaches.\n *\n * - `local` → locality + district + state + national matches\n * - `district` → district + state + national matches (no locality boost)\n * - `state` → state + national matches\n * - `national` → national matches\n * - `global` → all matches (de-facto same as `national` for an\n * India-only product, but kept for forward compat)\n *\n * Read-side ranking — see `feed.service.ts#tierBoost` — multiplies the\n * row's hotScore by an area-proximity factor: locality match 2.0,\n * district 1.2, state 0.9, national 0.7, distant 0.5. So local\n * content dominates at equal quality, while genuinely viral national\n * content still surfaces.\n */\nexport const VISIBILITY_LEVEL_VALUES = [\n 'local',\n 'district',\n 'state',\n 'national',\n 'global',\n] as const;\nexport const visibilityLevelSchema = z.enum(VISIBILITY_LEVEL_VALUES);\nexport type VisibilityLevel = z.infer<typeof visibilityLevelSchema>;\n\n/**\n * Numeric ranking used for the area-proximity cascade. `local` is the\n * deepest (most specific) feed scope, `global` the broadest. Higher\n * rank = broader scope.\n */\nexport const VISIBILITY_LEVEL_RANK: Record<VisibilityLevel, number> = {\n local: 0,\n district: 1,\n state: 2,\n national: 3,\n global: 4,\n};\n\n// ─── Polymorphic content kind ───────────────────────────────────────────────\n\n/**\n * The kinds of items that show up in the feed. `post` is the\n * community-native kind; `lost_found`, `voice_box`, and `donate_item`\n * are existing legacy features surfaced into the feed via polymorphic\n * union; `poll` is the structured-choice kind backed by its own\n * `CommunityPoll` collection (votes live in a separate `PollVote`\n * collection, see `./poll.ts`).\n *\n * Engagement (upvote / reaction / comment / share) is keyed by\n * (contentKind, contentId) so every kind gets the same engagement bar.\n */\nexport const CONTENT_KIND_VALUES = [\n 'post',\n 'lost_found',\n 'voice_box',\n 'donate_item',\n 'poll',\n 'crowdfunding',\n] as const;\nexport const contentKindSchema = z.enum(CONTENT_KIND_VALUES);\nexport type ContentKind = z.infer<typeof contentKindSchema>;\n\n// ─── Reactions ──────────────────────────────────────────────────────────────\n\n/**\n * Reaction types available on every feed item.\n *\n * `support` replaces Facebook's \"Care\" — better-suited to a civic /\n * hyperlocal context where reacting to a complaint or lost-and-found\n * post deserves a distinct \"I support you\" signal.\n */\nexport const REACTION_TYPE_VALUES = [\n 'like',\n 'love',\n 'haha',\n 'wow',\n 'sad',\n 'angry',\n 'support',\n] as const;\nexport const reactionTypeSchema = z.enum(REACTION_TYPE_VALUES);\nexport type ReactionType = z.infer<typeof reactionTypeSchema>;\n\n// ─── Profile privacy ───────────────────────────────────────────────────────\n\n/**\n * Profile-level privacy (single toggle in Settings).\n *\n * `public` — anyone the area-proximity cascade reaches sees this user's posts.\n * `private` — only the viewer's followers see this user's posts.\n */\nexport const PROFILE_PRIVACY_VALUES = ['public', 'private'] as const;\nexport const profilePrivacySchema = z.enum(PROFILE_PRIVACY_VALUES);\nexport type ProfilePrivacy = z.infer<typeof profilePrivacySchema>;\n\n// ─── Moderation ────────────────────────────────────────────────────────────\n\n/**\n * Reasons a piece of content can be reported. The list is deliberately\n * short — finer categorization can come from the optional `details`\n * free-text field on a report.\n */\nexport const REPORT_REASON_VALUES = [\n 'spam',\n 'harassment',\n 'hate_speech',\n 'misinformation',\n 'sexual_content',\n 'violence',\n 'self_harm',\n 'illegal_content',\n 'other',\n] as const;\nexport const reportReasonSchema = z.enum(REPORT_REASON_VALUES);\nexport type ReportReason = z.infer<typeof reportReasonSchema>;\n\n/** Moderator decision states on a report. */\nexport const REPORT_STATUS_VALUES = ['pending', 'reviewing', 'actioned', 'dismissed'] as const;\nexport const reportStatusSchema = z.enum(REPORT_STATUS_VALUES);\nexport type ReportStatus = z.infer<typeof reportStatusSchema>;\n\n// ─── Feed sort ─────────────────────────────────────────────────────────────\n\n/**\n * Sort options exposed in the feed UI.\n *\n * `hot` — the default. Reddit-style score blending upvotes, comment count,\n * and recency. Best surface for civic / community engagement.\n * `new` — strict reverse-chronological. Useful when the viewer wants to\n * catch up on everything fresh.\n * `top` — highest upvote count over a configurable window (defaults to\n * 24 hours on the client).\n */\nexport const FEED_SORT_VALUES = ['hot', 'new', 'top'] as const;\nexport const feedSortSchema = z.enum(FEED_SORT_VALUES);\nexport type FeedSort = z.infer<typeof feedSortSchema>;\n"]}
1
+ {"version":3,"file":"enums.js","sourceRoot":"","sources":["../src/enums.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,OAAO;IACP,UAAU;IACV,OAAO;IACP,UAAU;IACV,QAAQ;CACA,CAAC;AACX,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;AAGrE;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAoC;IACpE,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;IACX,MAAM,EAAE,CAAC;CACV,CAAC;AAEF,+EAA+E;AAE/E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,MAAM;IACN,YAAY;IACZ,wBAAwB;IACxB,aAAa;IACb,MAAM;IACN,cAAc;CACN,CAAC;AACX,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AAG7D,+EAA+E;AAE/E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,MAAM;IACN,MAAM;IACN,MAAM;IACN,KAAK;IACL,KAAK;IACL,OAAO;IACP,SAAS;CACD,CAAC;AACX,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;AAG/D,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAU,CAAC;AACrE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;AAGnE,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,MAAM;IACN,YAAY;IACZ,aAAa;IACb,gBAAgB;IAChB,gBAAgB;IAChB,UAAU;IACV,WAAW;IACX,iBAAiB;IACjB,OAAO;CACC,CAAC;AACX,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;AAG/D,6CAA6C;AAC7C,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,CAAU,CAAC;AAC/F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;AAG/D,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAU,CAAC;AAC/D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC","sourcesContent":["/**\n * Enum value arrays shared across the community feature.\n *\n * Each enum is exported as both a `*_VALUES` tuple and the corresponding\n * Zod schema so backend Mongoose models and frontend forms validate\n * against the exact same set.\n *\n * @module community-schema/enums\n */\n\nimport { z } from 'zod';\n\n// ─── Feed viewport (viewer-side geographic filter) ─────────────────────────\n\n/**\n * Geographic scope the VIEWER chose for their feed — the area-proximity\n * cascade is gated by this value.\n *\n * Posts do NOT carry a per-post `visibilityLevel` any more. Every post\n * is implicitly global; visibility is purely a function of (a) the\n * author's `areaLineage` at write time and (b) the viewer's scope\n * choice here. The cascade walks from the viewer's locality outward\n * and includes any post whose author was inside the viewer's area at\n * ANY level the viewer's scope reaches.\n *\n * - `local` → locality + district + state + national matches\n * - `district` → district + state + national matches (no locality boost)\n * - `state` → state + national matches\n * - `national` → national matches\n * - `global` → all matches (de-facto same as `national` for an\n * India-only product, but kept for forward compat)\n *\n * Read-side ranking — see `feed.service.ts#tierBoost` — multiplies the\n * row's hotScore by an area-proximity factor: locality match 2.0,\n * district 1.2, state 0.9, national 0.7, distant 0.5. So local\n * content dominates at equal quality, while genuinely viral national\n * content still surfaces.\n */\nexport const VISIBILITY_LEVEL_VALUES = [\n 'local',\n 'district',\n 'state',\n 'national',\n 'global',\n] as const;\nexport const visibilityLevelSchema = z.enum(VISIBILITY_LEVEL_VALUES);\nexport type VisibilityLevel = z.infer<typeof visibilityLevelSchema>;\n\n/**\n * Numeric ranking used for the area-proximity cascade. `local` is the\n * deepest (most specific) feed scope, `global` the broadest. Higher\n * rank = broader scope.\n */\nexport const VISIBILITY_LEVEL_RANK: Record<VisibilityLevel, number> = {\n local: 0,\n district: 1,\n state: 2,\n national: 3,\n global: 4,\n};\n\n// ─── Polymorphic content kind ───────────────────────────────────────────────\n\n/**\n * The kinds of items that show up in the feed. `post` is the\n * community-native kind; `lost_found`, `suggestions_complaints`, and `donate_item`\n * are existing legacy features surfaced into the feed via polymorphic\n * union; `poll` is the structured-choice kind backed by its own\n * `CommunityPoll` collection (votes live in a separate `PollVote`\n * collection, see `./poll.ts`).\n *\n * Engagement (upvote / reaction / comment / share) is keyed by\n * (contentKind, contentId) so every kind gets the same engagement bar.\n */\nexport const CONTENT_KIND_VALUES = [\n 'post',\n 'lost_found',\n 'suggestions_complaints',\n 'donate_item',\n 'poll',\n 'crowdfunding',\n] as const;\nexport const contentKindSchema = z.enum(CONTENT_KIND_VALUES);\nexport type ContentKind = z.infer<typeof contentKindSchema>;\n\n// ─── Reactions ──────────────────────────────────────────────────────────────\n\n/**\n * Reaction types available on every feed item.\n *\n * `support` replaces Facebook's \"Care\" — better-suited to a civic /\n * hyperlocal context where reacting to a complaint or lost-and-found\n * post deserves a distinct \"I support you\" signal.\n */\nexport const REACTION_TYPE_VALUES = [\n 'like',\n 'love',\n 'haha',\n 'wow',\n 'sad',\n 'angry',\n 'support',\n] as const;\nexport const reactionTypeSchema = z.enum(REACTION_TYPE_VALUES);\nexport type ReactionType = z.infer<typeof reactionTypeSchema>;\n\n// ─── Profile privacy ───────────────────────────────────────────────────────\n\n/**\n * Profile-level privacy (single toggle in Settings).\n *\n * `public` — anyone the area-proximity cascade reaches sees this user's posts.\n * `private` — only the viewer's followers see this user's posts.\n */\nexport const PROFILE_PRIVACY_VALUES = ['public', 'private'] as const;\nexport const profilePrivacySchema = z.enum(PROFILE_PRIVACY_VALUES);\nexport type ProfilePrivacy = z.infer<typeof profilePrivacySchema>;\n\n// ─── Moderation ────────────────────────────────────────────────────────────\n\n/**\n * Reasons a piece of content can be reported. The list is deliberately\n * short — finer categorization can come from the optional `details`\n * free-text field on a report.\n */\nexport const REPORT_REASON_VALUES = [\n 'spam',\n 'harassment',\n 'hate_speech',\n 'misinformation',\n 'sexual_content',\n 'violence',\n 'self_harm',\n 'illegal_content',\n 'other',\n] as const;\nexport const reportReasonSchema = z.enum(REPORT_REASON_VALUES);\nexport type ReportReason = z.infer<typeof reportReasonSchema>;\n\n/** Moderator decision states on a report. */\nexport const REPORT_STATUS_VALUES = ['pending', 'reviewing', 'actioned', 'dismissed'] as const;\nexport const reportStatusSchema = z.enum(REPORT_STATUS_VALUES);\nexport type ReportStatus = z.infer<typeof reportStatusSchema>;\n\n// ─── Feed sort ─────────────────────────────────────────────────────────────\n\n/**\n * Sort options exposed in the feed UI.\n *\n * `hot` — the default. Reddit-style score blending upvotes, comment count,\n * and recency. Best surface for civic / community engagement.\n * `new` — strict reverse-chronological. Useful when the viewer wants to\n * catch up on everything fresh.\n * `top` — highest upvote count over a configurable window (defaults to\n * 24 hours on the client).\n */\nexport const FEED_SORT_VALUES = ['hot', 'new', 'top'] as const;\nexport const feedSortSchema = z.enum(FEED_SORT_VALUES);\nexport type FeedSort = z.infer<typeof feedSortSchema>;\n"]}
package/dist/feed.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Feed wire shapes — polymorphic union of community posts, lost-and-
3
- * found reports, and voice-box (complaints + suggestions).
3
+ * found reports, and suggestions-complaints (complaints + suggestions).
4
4
  *
5
- * The feed is a SINGLE list typed as `FeedItem = Post | LostFound | VoiceBox`.
5
+ * The feed is a SINGLE list typed as `FeedItem = Post | LostFound | SuggestionsComplaints`.
6
6
  * The client discriminates on `contentKind` and renders the matching
7
7
  * card component.
8
8
  *
@@ -13,9 +13,9 @@
13
13
  * - Cursor-based pagination. The cursor is opaque (base64 of
14
14
  * `<sortKey>|<_id>`) so we can swap sort algorithms without a
15
15
  * breaking change.
16
- * - LostFound / VoiceBox shapes are pruned to the fields the feed
16
+ * - LostFound / SuggestionsComplaints shapes are pruned to the fields the feed
17
17
  * card needs — they keep their richer detail-page shape in their
18
- * own schemas (lost-found-schema, voice-box-schema if/when those
18
+ * own schemas (lost-found-schema, suggestions-complaints-schema if/when those
19
19
  * get factored out).
20
20
  *
21
21
  * @module community-schema/feed
@@ -486,42 +486,42 @@ export declare const donateItemFeedItemSchema: z.ZodObject<{
486
486
  }, z.core.$strip>;
487
487
  export type DonateItemFeedItem = z.infer<typeof donateItemFeedItemSchema>;
488
488
  /**
489
- * Voice-box priority — mirrors `IReformIssueReport.priority`.
489
+ * Suggestions & complaints priority — mirrors `IReformIssueReport.priority`.
490
490
  * Drives the side-stripe colour on the complaint card.
491
491
  */
492
- export declare const VOICE_BOX_PRIORITY_VALUES: readonly ["low", "medium", "high", "critical"];
493
- export declare const voiceBoxPrioritySchema: z.ZodEnum<{
492
+ export declare const SUGGESTIONS_COMPLAINTS_PRIORITY_VALUES: readonly ["low", "medium", "high", "critical"];
493
+ export declare const suggestionsComplaintsPrioritySchema: z.ZodEnum<{
494
494
  low: "low";
495
495
  medium: "medium";
496
496
  high: "high";
497
497
  critical: "critical";
498
498
  }>;
499
- export type VoiceBoxPriority = z.infer<typeof voiceBoxPrioritySchema>;
499
+ export type SuggestionsComplaintsPriority = z.infer<typeof suggestionsComplaintsPrioritySchema>;
500
500
  /**
501
- * Voice-box lifecycle status. Five states matching the model — the
501
+ * Suggestions & complaints lifecycle status. Five states matching the model — the
502
502
  * card surfaces `pending`/`under_review`/`in_progress` as in-flight
503
503
  * pills, `resolved` as a green resolution footer, `rejected` as
504
504
  * neutral with an explanation.
505
505
  */
506
- export declare const VOICE_BOX_STATUS_VALUES: readonly ["pending", "under_review", "in_progress", "resolved", "rejected"];
507
- export declare const voiceBoxStatusSchema: z.ZodEnum<{
506
+ export declare const SUGGESTIONS_COMPLAINTS_STATUS_VALUES: readonly ["pending", "under_review", "in_progress", "resolved", "rejected"];
507
+ export declare const suggestionsComplaintsStatusSchema: z.ZodEnum<{
508
508
  pending: "pending";
509
509
  rejected: "rejected";
510
510
  under_review: "under_review";
511
511
  resolved: "resolved";
512
512
  in_progress: "in_progress";
513
513
  }>;
514
- export type VoiceBoxStatus = z.infer<typeof voiceBoxStatusSchema>;
514
+ export type SuggestionsComplaintsStatus = z.infer<typeof suggestionsComplaintsStatusSchema>;
515
515
  /** Inline-playable audio attachment (voice complaint). The model
516
516
  * stores `IssueAudio` with `url + gcpPath + uploadedAt + duration`;
517
517
  * the wire is trimmed to what the card needs to render the WhatsApp-
518
518
  * style voice note bar. */
519
- export declare const voiceBoxAudioSchema: z.ZodObject<{
519
+ export declare const suggestionsComplaintsAudioSchema: z.ZodObject<{
520
520
  url: z.ZodString;
521
521
  durationSec: z.ZodNumber;
522
522
  }, z.core.$strip>;
523
523
  /** Inline-playable video attachment (single native upload). */
524
- export declare const voiceBoxVideoSchema: z.ZodObject<{
524
+ export declare const suggestionsComplaintsVideoSchema: z.ZodObject<{
525
525
  url: z.ZodString;
526
526
  thumbnailUrl: z.ZodString;
527
527
  durationSec: z.ZodNumber;
@@ -530,13 +530,13 @@ export declare const voiceBoxVideoSchema: z.ZodObject<{
530
530
  * can render the sky-blue "Official response" block without a
531
531
  * second round trip. Full text + reply audit log live on the
532
532
  * detail page. */
533
- export declare const voiceBoxOfficerResponseSchema: z.ZodObject<{
533
+ export declare const suggestionsComplaintsOfficerResponseSchema: z.ZodObject<{
534
534
  officerName: z.ZodString;
535
535
  designation: z.ZodNullable<z.ZodString>;
536
536
  text: z.ZodString;
537
537
  respondedAt: z.ZodString;
538
538
  }, z.core.$strip>;
539
- export declare const voiceBoxLocationSchema: z.ZodObject<{
539
+ export declare const suggestionsComplaintsLocationSchema: z.ZodObject<{
540
540
  country: z.ZodOptional<z.ZodString>;
541
541
  state: z.ZodOptional<z.ZodObject<{
542
542
  _id: z.ZodOptional<z.ZodString>;
@@ -623,9 +623,9 @@ export declare const voiceBoxLocationSchema: z.ZodObject<{
623
623
  landmark: z.ZodOptional<z.ZodString>;
624
624
  directions: z.ZodOptional<z.ZodString>;
625
625
  }, z.core.$strip>;
626
- export type VoiceBoxLocation = z.infer<typeof voiceBoxLocationSchema>;
626
+ export type SuggestionsComplaintsLocation = z.infer<typeof suggestionsComplaintsLocationSchema>;
627
627
  /**
628
- * Voice-box (complaint or suggestion) item projected into the feed.
628
+ * Suggestions & complaints (complaint or suggestion) item projected into the feed.
629
629
  *
630
630
  * v3 wire — extended from the v1 stub to carry every field the
631
631
  * civic-grade card renders. Privacy: `reporterPhone` is replaced by a
@@ -633,9 +633,9 @@ export type VoiceBoxLocation = z.infer<typeof voiceBoxLocationSchema>;
633
633
  * without exposing the raw number; the detail page issues the
634
634
  * authenticated read that returns the actual tel: target.
635
635
  */
636
- export declare const voiceBoxFeedItemSchema: z.ZodObject<{
636
+ export declare const suggestionsComplaintsFeedItemSchema: z.ZodObject<{
637
637
  _id: z.ZodString;
638
- contentKind: z.ZodLiteral<"voice_box">;
638
+ contentKind: z.ZodLiteral<"suggestions_complaints">;
639
639
  author: z.ZodObject<{
640
640
  userId: z.ZodString;
641
641
  username: z.ZodString;
@@ -811,7 +811,7 @@ export declare const voiceBoxFeedItemSchema: z.ZodObject<{
811
811
  reposted: z.ZodBoolean;
812
812
  }, z.core.$strip>>;
813
813
  }, z.core.$strip>;
814
- export type VoiceBoxFeedItem = z.infer<typeof voiceBoxFeedItemSchema>;
814
+ export type SuggestionsComplaintsFeedItem = z.infer<typeof suggestionsComplaintsFeedItemSchema>;
815
815
  export declare const feedItemSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
816
816
  _id: z.ZodString;
817
817
  contentKind: z.ZodLiteral<"post">;
@@ -895,7 +895,7 @@ export declare const feedItemSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
895
895
  contentKind: z.ZodEnum<{
896
896
  post: "post";
897
897
  lost_found: "lost_found";
898
- voice_box: "voice_box";
898
+ suggestions_complaints: "suggestions_complaints";
899
899
  donate_item: "donate_item";
900
900
  poll: "poll";
901
901
  crowdfunding: "crowdfunding";
@@ -1128,7 +1128,7 @@ export declare const feedItemSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1128
1128
  }, z.core.$strip>>;
1129
1129
  }, z.core.$strip>, z.ZodObject<{
1130
1130
  _id: z.ZodString;
1131
- contentKind: z.ZodLiteral<"voice_box">;
1131
+ contentKind: z.ZodLiteral<"suggestions_complaints">;
1132
1132
  author: z.ZodObject<{
1133
1133
  userId: z.ZodString;
1134
1134
  username: z.ZodString;
@@ -1773,7 +1773,7 @@ export declare const feedResponseSchema: z.ZodObject<{
1773
1773
  contentKind: z.ZodEnum<{
1774
1774
  post: "post";
1775
1775
  lost_found: "lost_found";
1776
- voice_box: "voice_box";
1776
+ suggestions_complaints: "suggestions_complaints";
1777
1777
  donate_item: "donate_item";
1778
1778
  poll: "poll";
1779
1779
  crowdfunding: "crowdfunding";
@@ -2006,7 +2006,7 @@ export declare const feedResponseSchema: z.ZodObject<{
2006
2006
  }, z.core.$strip>>;
2007
2007
  }, z.core.$strip>, z.ZodObject<{
2008
2008
  _id: z.ZodString;
2009
- contentKind: z.ZodLiteral<"voice_box">;
2009
+ contentKind: z.ZodLiteral<"suggestions_complaints">;
2010
2010
  author: z.ZodObject<{
2011
2011
  userId: z.ZodString;
2012
2012
  username: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"feed.d.ts","sourceRoot":"","sources":["../src/feed.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feed.d.ts","sourceRoot":"","sources":["../src/feed.ts"],"names":[],"mappings":"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"}