@mohasinac/appkit 4.3.2 → 4.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/dist/_internal/client/features/maintenance/views/AnalysisRunnerView.js +1 -1
  2. package/dist/_internal/client/features/maintenance/views/CloudLogsListView.js +1 -1
  3. package/dist/_internal/client/features/maintenance/views/MaintenanceDashboardView.js +1 -1
  4. package/dist/_internal/client/features/maintenance/views/ServerErrorDetailView.js +1 -1
  5. package/dist/_internal/client/features/maintenance/views/ServerErrorsListView.js +1 -1
  6. package/dist/_internal/server/jobs/core/assignSpinPrize.d.ts +14 -3
  7. package/dist/_internal/server/jobs/core/assignSpinPrize.js +95 -56
  8. package/dist/_internal/server/jobs/handlers/assignSpinPrize.js +8 -2
  9. package/dist/_internal/shared/actions/action-registry.js +15 -0
  10. package/dist/_internal/shared/features/brands/schema.d.ts +4 -4
  11. package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +4 -4
  12. package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
  13. package/dist/_internal/shared/features/reviews/schema.d.ts +2 -2
  14. package/dist/client.d.ts +36 -0
  15. package/dist/client.js +30 -0
  16. package/dist/constants/api-endpoints.d.ts +6 -0
  17. package/dist/constants/api-endpoints.js +2 -0
  18. package/dist/constants/field-names.d.ts +7 -0
  19. package/dist/constants/field-names.js +8 -0
  20. package/dist/features/about/components/DeveloperView.d.ts +16 -0
  21. package/dist/features/about/components/DeveloperView.js +29 -0
  22. package/dist/features/about/index.d.ts +2 -0
  23. package/dist/features/about/index.js +1 -0
  24. package/dist/features/account/schemas/index.d.ts +16 -16
  25. package/dist/features/addresses/schemas/index.d.ts +8 -8
  26. package/dist/features/admin/components/AdminAddressesView.js +1 -1
  27. package/dist/features/admin/components/AdminAllEventEntriesView.js +2 -2
  28. package/dist/features/admin/components/AdminArtView.js +1 -1
  29. package/dist/features/admin/components/AdminBidsView.js +2 -2
  30. package/dist/features/admin/components/AdminBlogView.js +2 -2
  31. package/dist/features/admin/components/AdminBrandsView.js +2 -2
  32. package/dist/features/admin/components/AdminBundlesView.js +2 -2
  33. package/dist/features/admin/components/AdminCartsView.js +2 -2
  34. package/dist/features/admin/components/AdminCategoriesView.js +2 -2
  35. package/dist/features/admin/components/AdminClassifiedView.js +1 -1
  36. package/dist/features/admin/components/AdminContactView.js +2 -2
  37. package/dist/features/admin/components/AdminCouponsView.js +2 -2
  38. package/dist/features/admin/components/AdminDigitalCodesView.js +1 -1
  39. package/dist/features/admin/components/AdminFaqsView.js +2 -2
  40. package/dist/features/admin/components/AdminFeaturesView.js +1 -1
  41. package/dist/features/admin/components/AdminGroupedListingsView.js +1 -1
  42. package/dist/features/admin/components/AdminHistoryView.js +1 -1
  43. package/dist/features/admin/components/AdminLiveView.js +1 -1
  44. package/dist/features/admin/components/AdminNewsletterView.js +2 -2
  45. package/dist/features/admin/components/AdminNotificationsView.js +2 -2
  46. package/dist/features/admin/components/AdminOrdersView.js +2 -2
  47. package/dist/features/admin/components/AdminPaymentMethodsView.js +1 -1
  48. package/dist/features/admin/components/AdminPayoutsView.js +2 -2
  49. package/dist/features/admin/components/AdminPrizeDrawsView.js +2 -2
  50. package/dist/features/admin/components/AdminProductsView.js +2 -2
  51. package/dist/features/admin/components/AdminReturnRequestsView.js +1 -1
  52. package/dist/features/admin/components/AdminReviewsView.js +2 -2
  53. package/dist/features/admin/components/AdminScammersView.js +2 -2
  54. package/dist/features/admin/components/AdminSessionsView.js +2 -2
  55. package/dist/features/admin/components/AdminStickersView.js +1 -1
  56. package/dist/features/admin/components/AdminStoreAddressesView.js +1 -1
  57. package/dist/features/admin/components/AdminStoresView.js +2 -2
  58. package/dist/features/admin/components/AdminSublistingCategoriesView.js +1 -1
  59. package/dist/features/admin/components/AdminSupportTicketsView.js +2 -2
  60. package/dist/features/admin/components/AdminTeamView.js +2 -2
  61. package/dist/features/admin/components/AdminTesterChecklistView.js +2 -2
  62. package/dist/features/admin/components/AdminUsersView.js +2 -2
  63. package/dist/features/admin/components/AdminWishlistsView.js +1 -1
  64. package/dist/features/admin/hooks/useAdminListing.d.ts +1 -1
  65. package/dist/features/auth/hooks/useAuth.d.ts +1 -1
  66. package/dist/features/blog/actions/blog-actions.d.ts +14 -14
  67. package/dist/features/blog/schemas/index.d.ts +14 -14
  68. package/dist/features/cart/hooks/useAddToCart.d.ts +6 -2
  69. package/dist/features/cart/hooks/useAddToCart.js +20 -3
  70. package/dist/features/cart/schemas/index.d.ts +3 -3
  71. package/dist/features/cart/utils/pending-ops.d.ts +20 -0
  72. package/dist/features/cart/utils/pending-ops.js +22 -0
  73. package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +1 -1
  74. package/dist/features/categories/components/CategoryBundlesListing.js +1 -1
  75. package/dist/features/categories/components/CategoryFilters.js +1 -1
  76. package/dist/features/categories/components/CategoryTree.js +1 -1
  77. package/dist/features/categories/schemas/index.d.ts +16 -16
  78. package/dist/features/events/actions/event-actions.d.ts +21 -1
  79. package/dist/features/events/actions/event-actions.js +85 -3
  80. package/dist/features/events/components/AdminEventEditorView.js +11 -2
  81. package/dist/features/events/components/AdminEventEntriesView.js +37 -4
  82. package/dist/features/events/components/AdminEventsView.js +2 -2
  83. package/dist/features/events/components/EventLeaderboard.d.ts +12 -2
  84. package/dist/features/events/components/EventLeaderboard.js +4 -1
  85. package/dist/features/events/components/EventRafflesSection.js +2 -2
  86. package/dist/features/events/repository/event-entry.repository.d.ts +39 -0
  87. package/dist/features/events/repository/event-entry.repository.js +153 -0
  88. package/dist/features/events/schemas/firestore.d.ts +28 -1
  89. package/dist/features/events/schemas/firestore.js +9 -0
  90. package/dist/features/events/schemas/index.d.ts +13 -13
  91. package/dist/features/events/types/index.d.ts +26 -0
  92. package/dist/features/faq/actions/faq-actions.d.ts +8 -8
  93. package/dist/features/faq/schemas/index.d.ts +22 -22
  94. package/dist/features/grouped/schemas/index.d.ts +2 -2
  95. package/dist/features/homepage/components/AnnouncementBar.d.ts +9 -1
  96. package/dist/features/homepage/components/AnnouncementBar.js +6 -3
  97. package/dist/features/homepage/components/MarketplaceHomepageView.js +2 -2
  98. package/dist/features/homepage/components/SectionCarousel.js +5 -1
  99. package/dist/features/homepage/components/WelcomeSection.js +2 -2
  100. package/dist/features/homepage/schemas/index.d.ts +2 -2
  101. package/dist/features/layout/BottomNavbar.js +8 -6
  102. package/dist/features/lottery/schemas/zod.d.ts +10 -10
  103. package/dist/features/media/MediaVideo.js +11 -3
  104. package/dist/features/orders/schemas/index.d.ts +52 -52
  105. package/dist/features/products/components/CompareOverlay.d.ts +9 -0
  106. package/dist/features/products/components/CompareOverlay.js +28 -3
  107. package/dist/features/products/components/InteractiveProductCard.js +9 -3
  108. package/dist/features/products/components/MakeOfferForm.js +1 -1
  109. package/dist/features/products/components/PlaceBidForm.js +1 -1
  110. package/dist/features/products/components/PrizeDrawCollage.js +1 -1
  111. package/dist/features/products/components/PrizeDrawsSection.js +2 -2
  112. package/dist/features/products/components/ProductDetailActions.js +3 -1
  113. package/dist/features/products/components/ProductGrid.js +1 -1
  114. package/dist/features/products/components/ProductInfo.js +1 -1
  115. package/dist/features/products/components/ProductsIndexListing.js +12 -2
  116. package/dist/features/products/hooks/useRelatedProducts.js +1 -1
  117. package/dist/features/products/schemas/index.d.ts +10 -10
  118. package/dist/features/promotions/schemas/index.d.ts +8 -8
  119. package/dist/features/reviews/schemas/index.d.ts +12 -12
  120. package/dist/features/scams/schemas/index.d.ts +6 -6
  121. package/dist/features/seller/components/CouponInlineSelect.js +1 -1
  122. package/dist/features/seller/components/SellerArtView.js +2 -2
  123. package/dist/features/seller/components/SellerAuctionsView.js +2 -2
  124. package/dist/features/seller/components/SellerBidsView.js +2 -2
  125. package/dist/features/seller/components/SellerBundlesView.js +1 -1
  126. package/dist/features/seller/components/SellerClassifiedView.js +2 -2
  127. package/dist/features/seller/components/SellerCouponsView.js +2 -2
  128. package/dist/features/seller/components/SellerDigitalCodesView.js +2 -2
  129. package/dist/features/seller/components/SellerGroupedListingsView.js +1 -1
  130. package/dist/features/seller/components/SellerLiveView.js +2 -2
  131. package/dist/features/seller/components/SellerOffersView.js +2 -2
  132. package/dist/features/seller/components/SellerOrdersView.js +2 -2
  133. package/dist/features/seller/components/SellerPayoutMethodsView.js +2 -2
  134. package/dist/features/seller/components/SellerPayoutsView.js +2 -2
  135. package/dist/features/seller/components/SellerPreOrdersView.js +2 -2
  136. package/dist/features/seller/components/SellerPrizeDrawsView.js +2 -2
  137. package/dist/features/seller/components/SellerProductsView.js +2 -2
  138. package/dist/features/seller/components/SellerShippingConfigsView.js +2 -2
  139. package/dist/features/seller/components/SellerStickersView.js +2 -2
  140. package/dist/features/seller/components/SellerStoreCategoriesView.js +1 -1
  141. package/dist/features/seller/components/SublistingInlineSelect.js +1 -1
  142. package/dist/features/seller/hooks/useSellerListingData.d.ts +1 -1
  143. package/dist/features/seller/schemas/index.d.ts +16 -16
  144. package/dist/features/server-errors/schemas/index.d.ts +4 -4
  145. package/dist/features/shell/StepForm.d.ts +1 -1
  146. package/dist/features/shipments/components/AdminShipmentsView.js +2 -2
  147. package/dist/features/stores/components/StoreProductsView.js +1 -1
  148. package/dist/features/stores/components/StoresIndexListing.js +1 -1
  149. package/dist/features/stores/schemas/index.d.ts +32 -32
  150. package/dist/features/support/schemas/index.d.ts +2 -2
  151. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +68 -1
  152. package/dist/features/whatsapp-bot/helpers/payment-proof-message.d.ts +14 -0
  153. package/dist/features/whatsapp-bot/helpers/payment-proof-message.js +17 -0
  154. package/dist/features/whatsapp-bot/helpers/whatsapp.d.ts +2 -8
  155. package/dist/features/whatsapp-bot/helpers/whatsapp.js +4 -11
  156. package/dist/features/wishlist/repository/user-wishlist.repository.d.ts +11 -0
  157. package/dist/features/wishlist/repository/user-wishlist.repository.js +33 -0
  158. package/dist/index.d.ts +7 -12
  159. package/dist/index.js +16 -28
  160. package/dist/next/components/ErrorView.js +1 -1
  161. package/dist/next/components/NotFoundView.js +1 -1
  162. package/dist/next/components/UnauthorizedView.js +1 -1
  163. package/dist/next/routing/route-map.d.ts +4 -0
  164. package/dist/next/routing/route-map.js +2 -0
  165. package/dist/react/contexts/SessionContext.d.ts +1 -1
  166. package/dist/react/hooks/use-action-dispatch.d.ts +1 -1
  167. package/dist/react/hooks/useFormStatePreservation.d.ts +1 -1
  168. package/dist/schemas/registry.d.ts +238 -238
  169. package/dist/schemas/webhooks/razorpay.d.ts +100 -100
  170. package/dist/security/index.d.ts +1 -1
  171. package/dist/security/index.js +1 -1
  172. package/dist/security/rate-limit.d.ts +10 -0
  173. package/dist/security/rate-limit.js +13 -1
  174. package/dist/seed/events-seed-data.js +52 -1
  175. package/dist/server.d.ts +6 -0
  176. package/dist/server.js +8 -0
  177. package/dist/styles.css +25 -1
  178. package/dist/tailwind-utilities.css +1 -1
  179. package/dist/ui/components/HorizontalScroller.d.ts +7 -1
  180. package/dist/ui/components/HorizontalScroller.js +2 -2
  181. package/dist/ui/components/HorizontalScroller.style.css +24 -0
  182. package/dist/validation/schemas.d.ts +12 -12
  183. package/package.json +1 -1
@@ -2,7 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { normalizeError } from "../../../../../errors/normalize";
4
4
  import * as React from "react";
5
- import { Button, Div, Heading, Input, Li, Section, Span, Table, Tbody, Td, Text, Th, Thead, Tr, Ul } from "@mohasinac/appkit";
5
+ import { Button, Div, Heading, Input, Li, Section, Span, Table, Tbody, Td, Text, Th, Thead, Tr, Ul } from "@mohasinac/appkit/client";
6
6
  import { Select } from "@mohasinac/appkit/ui";
7
7
  import { ADMIN_ENDPOINTS } from "../../../../../constants/api-endpoints";
8
8
  export function AnalysisRunnerView() {
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
- import { Button, Div, Heading, Span, Table, Tbody, Td, Text, Th, Thead, Tr } from "@mohasinac/appkit";
4
+ import { Button, Div, Heading, Span, Table, Tbody, Td, Text, Th, Thead, Tr } from "@mohasinac/appkit/client";
5
5
  import { ADMIN_ENDPOINTS } from "../../../../../constants/api-endpoints";
6
6
  import { normalizeError } from "../../../../../errors/normalize";
7
7
  const BORDER_STYLE = "1px solid var(--appkit-color-border)";
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Anchor, Div, Heading, Li, Nav, Section, Span, Text, Ul } from "@mohasinac/appkit";
2
+ import { Anchor, Div, Heading, Li, Nav, Section, Span, Text, Ul } from "@mohasinac/appkit/client";
3
3
  const card = {
4
4
  padding: "1rem 1.25rem",
5
5
  border: "1px solid var(--appkit-color-border)",
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Anchor, Div, Heading, Li, Pre, Section, Text, Ul } from "@mohasinac/appkit";
2
+ import { Anchor, Div, Heading, Li, Pre, Section, Text, Ul } from "@mohasinac/appkit/client";
3
3
  function fmt(t) {
4
4
  return new Date(t).toISOString().replace("T", " ").slice(0, 19);
5
5
  }
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
- import { Anchor, Div, Heading, Input, Label, Span, Table, Tbody, Td, Text, Th, Thead, Tr } from "@mohasinac/appkit";
4
+ import { Anchor, Div, Heading, Input, Label, Span, Table, Tbody, Td, Text, Th, Thead, Tr } from "@mohasinac/appkit/client";
5
5
  const BORDER_STYLE = "1px solid var(--appkit-color-border)";
6
6
  const COLUMNS = [
7
7
  { key: "occurredAtFmt", label: "When", width: "180px" },
@@ -1,15 +1,26 @@
1
1
  /**
2
2
  * Core: weighted random selection from an event's `spinPrizes` config using
3
- * `crypto.randomInt`. Enforces one spin per user.
3
+ * `crypto.randomInt`. Enforces `spinMaxPerUser` (per identity — user or
4
+ * guest) and the optional `spinWindowStart`/`spinWindowEnd` window.
5
+ *
6
+ * Find-or-create is intentional: the spin UI never calls `enterEvent()`
7
+ * first (unlike poll/survey/raffle), so this function owns creating the
8
+ * backing `eventEntries` doc the first time an identity spins. The whole
9
+ * find/create/assign/mark-used sequence runs inside a single Firestore
10
+ * transaction so two rapid spins from the same identity can't both win a
11
+ * prize (the old read-then-`ref.update()` version had this race).
4
12
  */
5
13
  import type { JobContext } from "../runtime/types";
6
14
  export interface AssignSpinPrizeInput {
7
15
  eventId: string;
8
- userId: string;
16
+ /** Logged-in identity. Exactly one of userId/guestIpHash must be set. */
17
+ userId?: string;
18
+ /** Hashed guest identity (see `hashGuestIdentity` in security/rate-limit.ts) — never a raw IP. */
19
+ guestIpHash?: string;
9
20
  }
10
21
  export interface AssignSpinPrizeResult {
11
22
  eventId: string;
12
- userId: string;
23
+ userId?: string;
13
24
  spinPrizeId?: string;
14
25
  spinPrizeTitle?: string;
15
26
  spinPrizeCouponCode?: string;
@@ -1,9 +1,18 @@
1
1
  /**
2
2
  * Core: weighted random selection from an event's `spinPrizes` config using
3
- * `crypto.randomInt`. Enforces one spin per user.
3
+ * `crypto.randomInt`. Enforces `spinMaxPerUser` (per identity — user or
4
+ * guest) and the optional `spinWindowStart`/`spinWindowEnd` window.
5
+ *
6
+ * Find-or-create is intentional: the spin UI never calls `enterEvent()`
7
+ * first (unlike poll/survey/raffle), so this function owns creating the
8
+ * backing `eventEntries` doc the first time an identity spins. The whole
9
+ * find/create/assign/mark-used sequence runs inside a single Firestore
10
+ * transaction so two rapid spins from the same identity can't both win a
11
+ * prize (the old read-then-`ref.update()` version had this race).
4
12
  */
5
13
  import crypto from "node:crypto";
6
14
  import { EVENT_ENTRY_FIELDS, COMMON_FIELDS } from "../../../../constants/field-names";
15
+ import { resolveDate } from "../../../../utils";
7
16
  const EVENTS_COLLECTION = "events";
8
17
  const EVENT_ENTRIES_COLLECTION = "eventEntries";
9
18
  const COUPONS_COLLECTION = "coupons";
@@ -12,75 +21,105 @@ export async function runAssignSpinPrize(input, ctx) {
12
21
  ctx.logger.info("FEATURE_PRIZE_DRAWS disabled — skipping spin prize assignment");
13
22
  return { eventId: input.eventId, userId: input.userId, reason: "feature_disabled" };
14
23
  }
15
- const { eventId, userId } = input;
24
+ const { eventId, userId, guestIpHash } = input;
25
+ if (!userId && !guestIpHash) {
26
+ return { eventId, userId, reason: "identity_required" };
27
+ }
16
28
  const eventSnap = await ctx.db.collection(EVENTS_COLLECTION).doc(eventId).get();
17
29
  if (!eventSnap.exists) {
18
30
  return { eventId, userId, reason: "event_not_found" };
19
31
  }
20
32
  const event = eventSnap.data();
33
+ if (!userId && !event.allowGuestParticipation) {
34
+ return { eventId, userId, reason: "login_required" };
35
+ }
21
36
  const prizes = Array.isArray(event.spinPrizes) ? event.spinPrizes : [];
22
37
  const totalWeight = prizes.reduce((s, p) => s + (p.weight ?? 0), 0);
23
38
  if (totalWeight <= 0) {
24
39
  return { eventId, userId, reason: "no_prizes_configured" };
25
40
  }
26
- const entriesSnap = await ctx.db
27
- .collection(EVENT_ENTRIES_COLLECTION)
28
- .where(EVENT_ENTRY_FIELDS.EVENT_ID, "==", eventId)
29
- .where(EVENT_ENTRY_FIELDS.USER_ID, "==", userId)
30
- .limit(1)
31
- .get();
32
- if (entriesSnap.empty) {
33
- return { eventId, userId, reason: "entry_not_found" };
41
+ const windowStart = resolveDate(event.spinWindowStart);
42
+ const windowEnd = resolveDate(event.spinWindowEnd);
43
+ if ((windowStart && ctx.now < windowStart) || (windowEnd && ctx.now > windowEnd)) {
44
+ return { eventId, userId, reason: "outside_spin_window" };
34
45
  }
35
- const entryDoc = entriesSnap.docs[0];
36
- const entry = entryDoc.data();
37
- if (entry.spinUsed) {
46
+ const maxPerUser = typeof event.spinMaxPerUser === "number" && event.spinMaxPerUser > 0
47
+ ? event.spinMaxPerUser
48
+ : 1;
49
+ const identityField = userId ? EVENT_ENTRY_FIELDS.USER_ID : EVENT_ENTRY_FIELDS.GUEST_IP_HASH;
50
+ const identityValue = (userId ?? guestIpHash);
51
+ return ctx.db.runTransaction(async (tx) => {
52
+ const entriesQuery = ctx.db
53
+ .collection(EVENT_ENTRIES_COLLECTION)
54
+ .where(EVENT_ENTRY_FIELDS.EVENT_ID, "==", eventId)
55
+ .where(identityField, "==", identityValue)
56
+ .limit(1);
57
+ const entriesSnap = await tx.get(entriesQuery);
58
+ const existingDoc = entriesSnap.empty ? null : entriesSnap.docs[0];
59
+ const existingData = existingDoc?.data();
60
+ const priorSpinCount = existingData?.spinCount ?? (existingData?.spinUsed ? 1 : 0);
61
+ if (priorSpinCount >= maxPerUser) {
62
+ return {
63
+ eventId,
64
+ userId,
65
+ spinPrizeId: existingData?.spinPrizeId,
66
+ alreadyUsed: true,
67
+ };
68
+ }
69
+ const roll = crypto.randomInt(0, totalWeight);
70
+ let cumulative = 0;
71
+ let pick;
72
+ for (const p of prizes) {
73
+ cumulative += p.weight ?? 0;
74
+ if (roll < cumulative) {
75
+ pick = p;
76
+ break;
77
+ }
78
+ }
79
+ if (!pick)
80
+ pick = prizes[prizes.length - 1];
81
+ let spinPrizeCouponCode;
82
+ if (pick.couponId) {
83
+ const coupSnap = await tx.get(ctx.db.collection(COUPONS_COLLECTION).doc(pick.couponId));
84
+ if (coupSnap.exists) {
85
+ spinPrizeCouponCode = coupSnap.data().code;
86
+ }
87
+ }
88
+ const nextSpinCount = priorSpinCount + 1;
89
+ const spinFields = {
90
+ [EVENT_ENTRY_FIELDS.SPIN_USED]: true,
91
+ [EVENT_ENTRY_FIELDS.SPIN_COUNT]: nextSpinCount,
92
+ [EVENT_ENTRY_FIELDS.SPIN_PRIZE_ID]: pick.id,
93
+ [EVENT_ENTRY_FIELDS.SPIN_WON_AT]: ctx.now,
94
+ [EVENT_ENTRY_FIELDS.SPIN_PRIZE_COUPON_CODE]: spinPrizeCouponCode ?? null,
95
+ [COMMON_FIELDS.UPDATED_AT]: ctx.now,
96
+ };
97
+ if (existingDoc) {
98
+ tx.update(existingDoc.ref, spinFields);
99
+ }
100
+ else {
101
+ const newRef = ctx.db.collection(EVENT_ENTRIES_COLLECTION).doc();
102
+ tx.set(newRef, {
103
+ [EVENT_ENTRY_FIELDS.EVENT_ID]: eventId,
104
+ ...(userId
105
+ ? { [EVENT_ENTRY_FIELDS.USER_ID]: userId }
106
+ : { [EVENT_ENTRY_FIELDS.GUEST_IP_HASH]: guestIpHash }),
107
+ reviewStatus: "approved",
108
+ submittedAt: ctx.now,
109
+ ...spinFields,
110
+ });
111
+ }
112
+ ctx.logger.info("Spin prize assigned", {
113
+ eventId,
114
+ userId: userId ?? "guest",
115
+ spinPrizeId: pick.id,
116
+ });
38
117
  return {
39
118
  eventId,
40
119
  userId,
41
- spinPrizeId: entry.spinPrizeId,
42
- alreadyUsed: true,
120
+ spinPrizeId: pick.id,
121
+ spinPrizeTitle: pick.label,
122
+ spinPrizeCouponCode,
43
123
  };
44
- }
45
- const roll = crypto.randomInt(0, totalWeight);
46
- let cumulative = 0;
47
- let pick;
48
- for (const p of prizes) {
49
- cumulative += p.weight ?? 0;
50
- if (roll < cumulative) {
51
- pick = p;
52
- break;
53
- }
54
- }
55
- if (!pick)
56
- pick = prizes[prizes.length - 1];
57
- let spinPrizeCouponCode;
58
- if (pick.couponId) {
59
- const coupSnap = await ctx.db
60
- .collection(COUPONS_COLLECTION)
61
- .doc(pick.couponId)
62
- .get();
63
- if (coupSnap.exists) {
64
- spinPrizeCouponCode = coupSnap.data().code;
65
- }
66
- }
67
- await entryDoc.ref.update({
68
- [EVENT_ENTRY_FIELDS.SPIN_USED]: true,
69
- [EVENT_ENTRY_FIELDS.SPIN_PRIZE_ID]: pick.id,
70
- [EVENT_ENTRY_FIELDS.SPIN_WON_AT]: ctx.now,
71
- [EVENT_ENTRY_FIELDS.SPIN_PRIZE_COUPON_CODE]: spinPrizeCouponCode ?? null,
72
- [COMMON_FIELDS.UPDATED_AT]: ctx.now,
73
- });
74
- ctx.logger.info("Spin prize assigned", {
75
- eventId,
76
- userId,
77
- spinPrizeId: pick.id,
78
124
  });
79
- return {
80
- eventId,
81
- userId,
82
- spinPrizeId: pick.id,
83
- spinPrizeTitle: pick.title,
84
- spinPrizeCouponCode,
85
- };
86
125
  }
@@ -9,8 +9,14 @@ export const assignSpinPrizeHandler = async (input, ctx) => {
9
9
  if (result.reason === "event_not_found") {
10
10
  throw httpError("Event not found", 404);
11
11
  }
12
- if (result.reason === "entry_not_found") {
13
- throw httpError("No event entry found for this user", 404);
12
+ if (result.reason === "identity_required") {
13
+ throw httpError("No user or guest identity provided", 400);
14
+ }
15
+ if (result.reason === "login_required") {
16
+ throw httpError("You must be logged in to spin this wheel", 401);
17
+ }
18
+ if (result.reason === "outside_spin_window") {
19
+ throw httpError("This spin wheel is not open right now", 403);
14
20
  }
15
21
  if (result.reason === "no_prizes_configured") {
16
22
  throw httpError("No spin prizes configured for this event", 422);
@@ -94,6 +94,13 @@ export const ACTIONS = {
94
94
  description: "Remove this listing from the buyer's wishlist.",
95
95
  kind: "ghost",
96
96
  },
97
+ "sync-wishlist-item": {
98
+ id: "product.sync-wishlist-item",
99
+ label: "Sync",
100
+ ariaLabel: "Sync this wishlist item with the latest product data",
101
+ description: "Refreshes the wishlist entry's stored price/title/image against the live listing, removing it if the listing is no longer available.",
102
+ kind: "ghost",
103
+ },
97
104
  "share": {
98
105
  id: "product.share",
99
106
  label: "Share",
@@ -1324,6 +1331,14 @@ export const ACTIONS = {
1324
1331
  kind: "ghost",
1325
1332
  permissions: ["admin"],
1326
1333
  },
1334
+ "export-event-entries": {
1335
+ id: "admin.export-event-entries",
1336
+ label: "Download Report",
1337
+ ariaLabel: "Download this event's entries as a Markdown report",
1338
+ description: "Download an event's entries as a Markdown file — a per-option vote tally for polls, or individual entries (submitter, status, points, responses) for every other event type.",
1339
+ kind: "ghost",
1340
+ permissions: ["admin"],
1341
+ },
1327
1342
  "create-checklist-item": {
1328
1343
  id: "admin.create-checklist-item",
1329
1344
  label: "Add Test Case",
@@ -17,9 +17,9 @@ export declare const brandInputSchema: z.ZodObject<{
17
17
  displayOrder: number;
18
18
  country?: string | undefined;
19
19
  description?: string | undefined;
20
- website?: string | undefined;
21
20
  logoURL?: string | undefined;
22
21
  bannerURL?: string | undefined;
22
+ website?: string | undefined;
23
23
  founded?: number | undefined;
24
24
  }, {
25
25
  name: string;
@@ -27,10 +27,10 @@ export declare const brandInputSchema: z.ZodObject<{
27
27
  country?: string | undefined;
28
28
  description?: string | undefined;
29
29
  isActive?: boolean | undefined;
30
- website?: string | undefined;
31
30
  displayOrder?: number | undefined;
32
31
  logoURL?: string | undefined;
33
32
  bannerURL?: string | undefined;
33
+ website?: string | undefined;
34
34
  founded?: number | undefined;
35
35
  }>;
36
36
  export declare const brandUpdateSchema: z.ZodObject<Omit<{
@@ -49,20 +49,20 @@ export declare const brandUpdateSchema: z.ZodObject<Omit<{
49
49
  name?: string | undefined;
50
50
  description?: string | undefined;
51
51
  isActive?: boolean | undefined;
52
- website?: string | undefined;
53
52
  displayOrder?: number | undefined;
54
53
  logoURL?: string | undefined;
55
54
  bannerURL?: string | undefined;
55
+ website?: string | undefined;
56
56
  founded?: number | undefined;
57
57
  }, {
58
58
  country?: string | undefined;
59
59
  name?: string | undefined;
60
60
  description?: string | undefined;
61
61
  isActive?: boolean | undefined;
62
- website?: string | undefined;
63
62
  displayOrder?: number | undefined;
64
63
  logoURL?: string | undefined;
65
64
  bannerURL?: string | undefined;
65
+ website?: string | undefined;
66
66
  founded?: number | undefined;
67
67
  }>;
68
68
  export type BrandInput = z.infer<typeof brandInputSchema>;
@@ -161,8 +161,8 @@ export declare const bundleCreateSchema: z.ZodObject<{
161
161
  isActive: z.ZodOptional<z.ZodBoolean>;
162
162
  }, "strip", z.ZodTypeAny, {
163
163
  name: string;
164
- bundleProductIds: string[];
165
164
  bundleKind: "brand" | "special";
165
+ bundleProductIds: string[];
166
166
  bundlePrice: number;
167
167
  bundleQueryRule: {
168
168
  type: "static";
@@ -192,8 +192,8 @@ export declare const bundleCreateSchema: z.ZodObject<{
192
192
  }[] | undefined;
193
193
  }, {
194
194
  name: string;
195
- bundleProductIds: string[];
196
195
  bundleKind: "brand" | "special";
196
+ bundleProductIds: string[];
197
197
  bundlePrice: number;
198
198
  bundleQueryRule: {
199
199
  type: "static";
@@ -312,8 +312,8 @@ export declare const bundleUpdateSchema: z.ZodObject<{
312
312
  name?: string | undefined;
313
313
  description?: string | undefined;
314
314
  isActive?: boolean | undefined;
315
- bundleProductIds?: string[] | undefined;
316
315
  bundleKind?: "brand" | "special" | undefined;
316
+ bundleProductIds?: string[] | undefined;
317
317
  bundleItemDetails?: {
318
318
  productId: string;
319
319
  drawCount?: number | undefined;
@@ -342,8 +342,8 @@ export declare const bundleUpdateSchema: z.ZodObject<{
342
342
  name?: string | undefined;
343
343
  description?: string | undefined;
344
344
  isActive?: boolean | undefined;
345
- bundleProductIds?: string[] | undefined;
346
345
  bundleKind?: "brand" | "special" | undefined;
346
+ bundleProductIds?: string[] | undefined;
347
347
  bundleItemDetails?: {
348
348
  productId: string;
349
349
  drawCount?: number | undefined;
@@ -25,18 +25,18 @@ export declare const createOrderSchema: z.ZodObject<{
25
25
  }, "strip", z.ZodTypeAny, {
26
26
  country: string;
27
27
  phone: string;
28
- state: string;
29
28
  city: string;
30
- addressLine1: string;
29
+ state: string;
31
30
  fullName: string;
31
+ addressLine1: string;
32
32
  pincode: string;
33
33
  addressLine2?: string | undefined;
34
34
  }, {
35
35
  phone: string;
36
- state: string;
37
36
  city: string;
38
- addressLine1: string;
37
+ state: string;
39
38
  fullName: string;
39
+ addressLine1: string;
40
40
  pincode: string;
41
41
  country?: string | undefined;
42
42
  addressLine2?: string | undefined;
@@ -53,10 +53,10 @@ export declare const createOrderSchema: z.ZodObject<{
53
53
  shippingAddress: {
54
54
  country: string;
55
55
  phone: string;
56
- state: string;
57
56
  city: string;
58
- addressLine1: string;
57
+ state: string;
59
58
  fullName: string;
59
+ addressLine1: string;
60
60
  pincode: string;
61
61
  addressLine2?: string | undefined;
62
62
  };
@@ -70,10 +70,10 @@ export declare const createOrderSchema: z.ZodObject<{
70
70
  }[];
71
71
  shippingAddress: {
72
72
  phone: string;
73
- state: string;
74
73
  city: string;
75
- addressLine1: string;
74
+ state: string;
76
75
  fullName: string;
76
+ addressLine1: string;
77
77
  pincode: string;
78
78
  country?: string | undefined;
79
79
  addressLine2?: string | undefined;
@@ -12,15 +12,15 @@ export declare const createReviewSchema: z.ZodObject<{
12
12
  body: string;
13
13
  storeId: string;
14
14
  images: string[];
15
- productId: string;
16
15
  rating: number;
16
+ productId: string;
17
17
  orderId?: string | undefined;
18
18
  }, {
19
19
  title: string;
20
20
  body: string;
21
21
  storeId: string;
22
- productId: string;
23
22
  rating: number;
23
+ productId: string;
24
24
  orderId?: string | undefined;
25
25
  images?: string[] | undefined;
26
26
  }>;
package/dist/client.d.ts CHANGED
@@ -147,6 +147,8 @@ export { Heading } from "./ui/components/Typography";
147
147
  export { Label, Text, Span, Caption } from "./ui/components/Typography";
148
148
  export { TextLink } from "./ui/components/TextLink";
149
149
  export type { TextLinkProps } from "./ui/components/TextLink";
150
+ export { Anchor } from "./ui/components/Anchor";
151
+ export { IconButton } from "./ui/index";
150
152
  export { Textarea } from "./ui/components/Textarea";
151
153
  export { GlobalError } from "./next/components/GlobalError";
152
154
  export { AppLayoutShell, LocaleSwitcher, useDashboardNav, BottomActionsProvider, useBottomActions, DashboardNavProvider, LayoutClient } from "./features/layout/index";
@@ -358,3 +360,37 @@ export { SCHEMAS, lookupApiSchema, lookupFirestoreSchema, } from "./schemas/inde
358
360
  export type { ApiRouteKey, ApiRouteSchema, FirestoreDocument, FirestoreValue, FormFieldValue, FormValues, HttpVerb, JsonArray, JsonObject, JsonObjectWithUndefined, JsonPrimitive, JsonValue, JsonValueWithUndefined, RegisteredApiRouteKey, RegisteredFirestoreCollection, RegisteredFormId, RegisteredRtdbChannel, RegisteredSieveCollection, RegisteredStorageOp, RegisteredWebhookProvider, RegistryEntry, SchemaRegistry, SchemasShape, WebhookSchemaBucket, } from "./schemas/index";
359
361
  export { normalizeError, getErrorMessage, isApiNormalized, isAppNormalized, isFirebaseAuthNormalized, isFirebaseFirestoreNormalized, isFirebaseStorageNormalized, isNativeNormalized, isNetworkNormalized, isUnknownNormalized, isZodNormalized, } from "./errors/normalize";
360
362
  export type { NormalizedError, NormalizedApiError, NormalizedAppError, NormalizedFirebaseAuthError, NormalizedFirebaseFirestoreError, NormalizedFirebaseStorageError, NormalizedNativeError, NormalizedNetworkError, NormalizedUnknownThrownValue, NormalizedZodError, } from "./errors/normalize";
363
+ export { buildPaymentProofReviewMessage } from "./features/whatsapp-bot/helpers/payment-proof-message";
364
+ export type { PaymentProofReviewMessageInput } from "./features/whatsapp-bot/types";
365
+ export type { AdminNotificationDocument, ItemRequestDocument, ModerationQueueDocument, ReportDocument, CustomRoleDocument, AnalyticsCardDocument, ListingTemplateDocument, } from "./features/store-extensions/index";
366
+ export { CommandPalette, useCommandPaletteHotkey } from "./features/shell/index";
367
+ export type { CommandPaletteGroup } from "./features/shell/index";
368
+ export { AdminBlogEditorView, AdminBundleEditorView, AdminCarouselEditorView, AdminCategoryEditorView, AdminCouponEditorView, AdminFaqEditorView, AdminOrderEditorView, AdminProductEditorView, AdminScammerEditorView, AdminSublistingCategoryEditorView, AdminSupportTicketDetailView, } from "./features/admin/index";
369
+ export { ADMIN_CHECKOUT_BYPASS_FLAG_KEY } from "./features/admin/schemas/firestore";
370
+ export { SpinWheelView, EventRaffleEntryForm } from "./features/events/index";
371
+ export { Card, CardBody } from "./ui/index";
372
+ export { SellerCouponsView, SellerCreateProductView, SellerEditProductView, useBecomeSeller, } from "./features/seller/index";
373
+ export type { BecomeSellerResult, SellerCreateProductViewProps, SellerEditProductViewProps, } from "./features/seller/index";
374
+ export { BecomeSellerView } from "./features/account/index";
375
+ export type { BidDocument } from "./features/auctions/index";
376
+ export type { ClaimedCouponDocument } from "./features/promotions/schemas";
377
+ export { groupOrderItemsByBundle } from "./features/orders/index";
378
+ export type { BundleOrderGroup, OutOfStockPolicy } from "./features/orders/index";
379
+ export { MediaUploadField } from "./features/media/index";
380
+ export { PrizeRevealModal } from "./features/products/components/PrizeRevealModal";
381
+ export { useProduct } from "./features/products/index";
382
+ export type { ProductDocument } from "./features/products/index";
383
+ export { BUNDLE_COPY } from "./_internal/shared/features/categories/bundle-copy";
384
+ export { useSiteSettings } from "./core/index";
385
+ export { checkEmiEligibility, computeEmiSchedule, } from "./_internal/shared/features/emi/schedule";
386
+ export type { EmiSettings } from "./_internal/shared/features/emi/schedule";
387
+ export { computeCodHandlingFee } from "./_internal/shared/fees/calculator";
388
+ export type { CodHandlingFeeRates, WhatsAppNotifyFeeRates, GiftWrapFeeRates, ShipmentProtectionFeeRates, } from "./_internal/shared/fees/calculator";
389
+ export { FAQPageContent } from "./features/faq/index";
390
+ export type { FAQCategory, FAQCategoryItem, FAQSortOption } from "./features/faq/index";
391
+ export { CategoryInlineSelect } from "./features/seller/components/CategoryInlineSelect";
392
+ export { BrandInlineSelect } from "./features/seller/components/BrandInlineSelect";
393
+ export { API_ENDPOINTS } from "./constants/index";
394
+ export { SELLER_LISTING_TABS, type SellerListingTabId, } from "./features/products/constants/listing-tabs";
395
+ export { ALL_TAB, EMPTY_TAB, ADMIN_PRODUCT_STATUS_TABS, ADMIN_PRODUCT_LISTING_TYPE_TABS, ADMIN_BLOG_STATUS_TABS, ADMIN_USER_STATUS_TABS, ADMIN_USER_ROLE_TABS, ADMIN_STORE_STATUS_TABS, ADMIN_PAYOUT_STATUS_TABS, ADMIN_ORDER_STATUS_TABS, ADMIN_REVIEW_STATUS_TABS, ADMIN_REVIEW_RATING_TABS, ADMIN_BID_STATUS_TABS, ADMIN_CONTACT_STATUS_TABS, ADMIN_NEWSLETTER_STATUS_TABS, ADMIN_EVENT_ENTRY_STATUS_TABS, ADMIN_EVENT_STATUS_TABS, ADMIN_CART_OWNERSHIP_TABS, ADMIN_COUPON_TYPE_TABS, SELLER_PRODUCT_STATUS_TABS, SELLER_AUCTION_STATUS_TABS, SELLER_ORDER_STATUS_TABS, SELLER_OFFER_STATUS_TABS, SELLER_BID_STATUS_TABS, } from "./features/admin/constants/filter-tabs";
396
+ export { PRODUCT_FIELDS, PRODUCT_STATUS_TRANSITIONS, ORDER_FIELDS, REVIEW_FIELDS, BID_FIELDS, AD_FIELDS, EVENT_FIELDS, EVENT_ENTRY_FIELDS, PAYOUT_FIELDS, STORE_FIELDS, CATEGORY_FIELDS, BLOG_FIELDS, USER_FIELDS, ADDRESS_FIELDS, BRAND_FIELDS, CART_FIELDS, WISHLIST_FIELDS, HISTORY_FIELDS, NOTIFICATION_FIELDS, SESSION_FIELDS, COUPON_USAGE_FIELDS, CONVERSATION_FIELDS, SCAMMER_FIELDS, SUPPORT_TICKET_FIELDS, CAROUSEL_FIELDS, COUPON_FIELDS, FAQ_FIELDS, HOMEPAGE_SECTION_FIELDS, SITE_SETTINGS_FIELDS, COMMON_FIELDS, OAUTH_STATE_VALUES, SCHEMA_DEFAULTS, } from "./constants/field-names";
package/dist/client.js CHANGED
@@ -194,6 +194,8 @@ export { Select } from "./ui/components/Select";
194
194
  export { Heading } from "./ui/components/Typography";
195
195
  export { Label, Text, Span, Caption } from "./ui/components/Typography";
196
196
  export { TextLink } from "./ui/components/TextLink";
197
+ export { Anchor } from "./ui/components/Anchor";
198
+ export { IconButton } from "./ui/index";
197
199
  export { Textarea } from "./ui/components/Textarea";
198
200
  export { GlobalError } from "./next/components/GlobalError";
199
201
  export { AppLayoutShell, LocaleSwitcher, useDashboardNav, BottomActionsProvider, useBottomActions, DashboardNavProvider, LayoutClient } from "./features/layout/index";
@@ -345,3 +347,31 @@ export { SellerLiveView } from "./features/seller/components/SellerLiveView";
345
347
  export { SCHEMAS, lookupApiSchema, lookupFirestoreSchema, } from "./schemas/index";
346
348
  // ── W3 catch-clause normalizer ──────────────────────────────────────────────
347
349
  export { normalizeError, getErrorMessage, isApiNormalized, isAppNormalized, isFirebaseAuthNormalized, isFirebaseFirestoreNormalized, isFirebaseStorageNormalized, isNativeNormalized, isNetworkNormalized, isUnknownNormalized, isZodNormalized, } from "./errors/normalize";
350
+ // [CLIENT-SAFE] Pure wa.me share-link message builder — imported directly
351
+ // from its isolated file (not ./whatsapp-bot/server) so this barrel's graph
352
+ // never touches the sibling crypto-importing helpers.
353
+ export { buildPaymentProofReviewMessage } from "./features/whatsapp-bot/helpers/payment-proof-message";
354
+ export { CommandPalette, useCommandPaletteHotkey } from "./features/shell/index";
355
+ export { AdminBlogEditorView, AdminBundleEditorView, AdminCarouselEditorView, AdminCategoryEditorView, AdminCouponEditorView, AdminFaqEditorView, AdminOrderEditorView, AdminProductEditorView, AdminScammerEditorView, AdminSublistingCategoryEditorView, AdminSupportTicketDetailView, } from "./features/admin/index";
356
+ export { ADMIN_CHECKOUT_BYPASS_FLAG_KEY } from "./features/admin/schemas/firestore";
357
+ export { SpinWheelView, EventRaffleEntryForm } from "./features/events/index";
358
+ export { Card, CardBody } from "./ui/index";
359
+ export { SellerCouponsView, SellerCreateProductView, SellerEditProductView, useBecomeSeller, } from "./features/seller/index";
360
+ export { BecomeSellerView } from "./features/account/index";
361
+ export { groupOrderItemsByBundle } from "./features/orders/index";
362
+ export { MediaUploadField } from "./features/media/index";
363
+ export { PrizeRevealModal } from "./features/products/components/PrizeRevealModal";
364
+ export { useProduct } from "./features/products/index";
365
+ export { BUNDLE_COPY } from "./_internal/shared/features/categories/bundle-copy";
366
+ export { useSiteSettings } from "./core/index";
367
+ export { checkEmiEligibility, computeEmiSchedule, } from "./_internal/shared/features/emi/schedule";
368
+ export { computeCodHandlingFee } from "./_internal/shared/fees/calculator"; // reexport-from-internal-ok: pure fee-calc utility consumed directly by public checkout UI (CheckoutRouteClient.tsx), same category as the sibling computeEmiSchedule/checkEmiEligibility re-export two lines above
369
+ export { FAQPageContent } from "./features/faq/index";
370
+ export { CategoryInlineSelect } from "./features/seller/components/CategoryInlineSelect";
371
+ export { BrandInlineSelect } from "./features/seller/components/BrandInlineSelect";
372
+ export { API_ENDPOINTS } from "./constants/index";
373
+ // [CLIENT-SAFE] Pure, zero-import constant files — dashboard filter-tab
374
+ // sets and Firestore field-name maps. No server dependency of any kind.
375
+ export { SELLER_LISTING_TABS, } from "./features/products/constants/listing-tabs";
376
+ export { ALL_TAB, EMPTY_TAB, ADMIN_PRODUCT_STATUS_TABS, ADMIN_PRODUCT_LISTING_TYPE_TABS, ADMIN_BLOG_STATUS_TABS, ADMIN_USER_STATUS_TABS, ADMIN_USER_ROLE_TABS, ADMIN_STORE_STATUS_TABS, ADMIN_PAYOUT_STATUS_TABS, ADMIN_ORDER_STATUS_TABS, ADMIN_REVIEW_STATUS_TABS, ADMIN_REVIEW_RATING_TABS, ADMIN_BID_STATUS_TABS, ADMIN_CONTACT_STATUS_TABS, ADMIN_NEWSLETTER_STATUS_TABS, ADMIN_EVENT_ENTRY_STATUS_TABS, ADMIN_EVENT_STATUS_TABS, ADMIN_CART_OWNERSHIP_TABS, ADMIN_COUPON_TYPE_TABS, SELLER_PRODUCT_STATUS_TABS, SELLER_AUCTION_STATUS_TABS, SELLER_ORDER_STATUS_TABS, SELLER_OFFER_STATUS_TABS, SELLER_BID_STATUS_TABS, } from "./features/admin/constants/filter-tabs";
377
+ export { PRODUCT_FIELDS, PRODUCT_STATUS_TRANSITIONS, ORDER_FIELDS, REVIEW_FIELDS, BID_FIELDS, AD_FIELDS, EVENT_FIELDS, EVENT_ENTRY_FIELDS, PAYOUT_FIELDS, STORE_FIELDS, CATEGORY_FIELDS, BLOG_FIELDS, USER_FIELDS, ADDRESS_FIELDS, BRAND_FIELDS, CART_FIELDS, WISHLIST_FIELDS, HISTORY_FIELDS, NOTIFICATION_FIELDS, SESSION_FIELDS, COUPON_USAGE_FIELDS, CONVERSATION_FIELDS, SCAMMER_FIELDS, SUPPORT_TICKET_FIELDS, CAROUSEL_FIELDS, COUPON_FIELDS, FAQ_FIELDS, HOMEPAGE_SECTION_FIELDS, SITE_SETTINGS_FIELDS, COMMON_FIELDS, OAUTH_STATE_VALUES, SCHEMA_DEFAULTS, } from "./constants/field-names";
@@ -45,6 +45,7 @@ export declare const ACCOUNT_ENDPOINTS: {
45
45
  readonly ORDER_BY_ID: (orderId: string) => string;
46
46
  readonly WISHLIST: "/api/user/wishlist";
47
47
  readonly WISHLIST_ITEM_BY_ID: (itemId: string) => string;
48
+ readonly WISHLIST_ITEM_SYNC: (itemId: string) => string;
48
49
  readonly WISHLIST_VALIDATE: "/api/user/wishlist/validate";
49
50
  readonly HISTORY: "/api/user/history";
50
51
  readonly HISTORY_ITEM: (productId: string) => string;
@@ -147,6 +148,7 @@ export declare const ADMIN_ENDPOINTS: {
147
148
  readonly EVENT_STATUS: (id: string) => string;
148
149
  readonly EVENT_STATS: (id: string) => string;
149
150
  readonly EVENT_ENTRIES: (id: string) => string;
151
+ readonly EVENT_ENTRIES_EXPORT: (id: string) => string;
150
152
  readonly EVENT_ENTRY_BY_ID: (eventId: string, entryId: string) => string;
151
153
  readonly EVENT_TRIGGER_RAFFLE: (id: string) => string;
152
154
  readonly COUPONS: "/api/admin/coupons";
@@ -492,6 +494,7 @@ export declare const API_ENDPOINTS: {
492
494
  readonly ORDER_BY_ID: (orderId: string) => string;
493
495
  readonly WISHLIST: "/api/user/wishlist";
494
496
  readonly WISHLIST_ITEM_BY_ID: (itemId: string) => string;
497
+ readonly WISHLIST_ITEM_SYNC: (itemId: string) => string;
495
498
  readonly WISHLIST_VALIDATE: "/api/user/wishlist/validate";
496
499
  readonly HISTORY: "/api/user/history";
497
500
  readonly HISTORY_ITEM: (productId: string) => string;
@@ -594,6 +597,7 @@ export declare const API_ENDPOINTS: {
594
597
  readonly EVENT_STATUS: (id: string) => string;
595
598
  readonly EVENT_STATS: (id: string) => string;
596
599
  readonly EVENT_ENTRIES: (id: string) => string;
600
+ readonly EVENT_ENTRIES_EXPORT: (id: string) => string;
597
601
  readonly EVENT_ENTRY_BY_ID: (eventId: string, entryId: string) => string;
598
602
  readonly EVENT_TRIGGER_RAFFLE: (id: string) => string;
599
603
  readonly COUPONS: "/api/admin/coupons";
@@ -941,6 +945,7 @@ export declare const API_ROUTES: {
941
945
  readonly ORDER_BY_ID: (orderId: string) => string;
942
946
  readonly WISHLIST: "/api/user/wishlist";
943
947
  readonly WISHLIST_ITEM_BY_ID: (itemId: string) => string;
948
+ readonly WISHLIST_ITEM_SYNC: (itemId: string) => string;
944
949
  readonly WISHLIST_VALIDATE: "/api/user/wishlist/validate";
945
950
  readonly HISTORY: "/api/user/history";
946
951
  readonly HISTORY_ITEM: (productId: string) => string;
@@ -1043,6 +1048,7 @@ export declare const API_ROUTES: {
1043
1048
  readonly EVENT_STATUS: (id: string) => string;
1044
1049
  readonly EVENT_STATS: (id: string) => string;
1045
1050
  readonly EVENT_ENTRIES: (id: string) => string;
1051
+ readonly EVENT_ENTRIES_EXPORT: (id: string) => string;
1046
1052
  readonly EVENT_ENTRY_BY_ID: (eventId: string, entryId: string) => string;
1047
1053
  readonly EVENT_TRIGGER_RAFFLE: (id: string) => string;
1048
1054
  readonly COUPONS: "/api/admin/coupons";
@@ -60,6 +60,7 @@ export const ACCOUNT_ENDPOINTS = {
60
60
  ORDER_BY_ID: (orderId) => `/api/user/orders/${orderId}`,
61
61
  WISHLIST: "/api/user/wishlist",
62
62
  WISHLIST_ITEM_BY_ID: (itemId) => `/api/user/wishlist/${encodeURIComponent(itemId)}`,
63
+ WISHLIST_ITEM_SYNC: (itemId) => `/api/user/wishlist/${encodeURIComponent(itemId)}/sync`,
63
64
  WISHLIST_VALIDATE: "/api/user/wishlist/validate",
64
65
  HISTORY: "/api/user/history",
65
66
  HISTORY_ITEM: (productId) => `/api/user/history/${encodeURIComponent(productId)}`,
@@ -174,6 +175,7 @@ export const ADMIN_ENDPOINTS = {
174
175
  EVENT_STATUS: (id) => `/api/admin/events/${id}/status`,
175
176
  EVENT_STATS: (id) => `/api/admin/events/${id}/stats`,
176
177
  EVENT_ENTRIES: (id) => `/api/admin/events/${id}/entries`,
178
+ EVENT_ENTRIES_EXPORT: (id) => `/api/admin/events/${id}/entries/export`,
177
179
  EVENT_ENTRY_BY_ID: (eventId, entryId) => `/api/admin/events/${eventId}/entries/${entryId}`,
178
180
  // SB9-D — admin manual raffle trigger
179
181
  EVENT_TRIGGER_RAFFLE: (id) => `/api/admin/events/${id}/trigger-raffle`,