@mohasinac/appkit 2.7.49 → 2.7.52

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 (232) hide show
  1. package/dist/_internal/client/features/layout/SidebarCollapseToggle.d.ts +19 -0
  2. package/dist/_internal/client/features/layout/SidebarCollapseToggle.js +15 -0
  3. package/dist/_internal/client/features/layout/index.d.ts +2 -0
  4. package/dist/_internal/client/features/layout/index.js +1 -0
  5. package/dist/_internal/server/features/checkout/actions.js +25 -2
  6. package/dist/_internal/server/features/promotions/actions.js +3 -1
  7. package/dist/_internal/server/jobs/core/__tests__/couponExpiry.test.d.ts +1 -0
  8. package/dist/_internal/server/jobs/core/__tests__/couponExpiry.test.js +65 -0
  9. package/dist/_internal/server/jobs/core/__tests__/listingProcessor.test.d.ts +1 -0
  10. package/dist/_internal/server/jobs/core/__tests__/listingProcessor.test.js +163 -0
  11. package/dist/_internal/server/jobs/core/__tests__/mediaTmpCleanup.test.d.ts +1 -0
  12. package/dist/_internal/server/jobs/core/__tests__/mediaTmpCleanup.test.js +115 -0
  13. package/dist/_internal/server/jobs/core/__tests__/pendingOrderTimeout.test.d.ts +1 -0
  14. package/dist/_internal/server/jobs/core/__tests__/pendingOrderTimeout.test.js +96 -0
  15. package/dist/_internal/shared/actions/action-registry.js +149 -0
  16. package/dist/client.d.ts +45 -6
  17. package/dist/client.js +27 -4
  18. package/dist/constants/api-endpoints.d.ts +42 -0
  19. package/dist/constants/api-endpoints.js +14 -0
  20. package/dist/features/_guide-cls.d.ts +13 -0
  21. package/dist/features/_guide-cls.js +14 -0
  22. package/dist/features/about/components/HelpPageView.js +29 -26
  23. package/dist/features/account/components/BuyerAccountGuideView.d.ts +1 -0
  24. package/dist/features/account/components/BuyerAccountGuideView.js +39 -0
  25. package/dist/features/account/components/BuyerAuctionsGuideView.d.ts +1 -0
  26. package/dist/features/account/components/BuyerAuctionsGuideView.js +38 -0
  27. package/dist/features/account/components/BuyerOrdersGuideView.d.ts +1 -0
  28. package/dist/features/account/components/BuyerOrdersGuideView.js +48 -0
  29. package/dist/features/account/components/BuyerShoppingGuideView.d.ts +1 -0
  30. package/dist/features/account/components/BuyerShoppingGuideView.js +38 -0
  31. package/dist/features/account/components/UserSidebar.js +2 -1
  32. package/dist/features/admin/components/AdminAnalyticsGuideView.d.ts +1 -0
  33. package/dist/features/admin/components/AdminAnalyticsGuideView.js +24 -0
  34. package/dist/features/admin/components/AdminBlogEditorView.js +102 -75
  35. package/dist/features/admin/components/AdminBundleEditorView.js +20 -14
  36. package/dist/features/admin/components/AdminBundlesView.d.ts +1 -3
  37. package/dist/features/admin/components/AdminBundlesView.js +173 -52
  38. package/dist/features/admin/components/AdminCatalogGuideView.d.ts +1 -0
  39. package/dist/features/admin/components/AdminCatalogGuideView.js +28 -0
  40. package/dist/features/admin/components/AdminContentGuideView.d.ts +1 -0
  41. package/dist/features/admin/components/AdminContentGuideView.js +36 -0
  42. package/dist/features/admin/components/AdminCouponEditorView.js +1 -1
  43. package/dist/features/admin/components/AdminGuideHubView.d.ts +5 -0
  44. package/dist/features/admin/components/AdminGuideHubView.js +79 -0
  45. package/dist/features/admin/components/AdminOrdersGuideView.d.ts +1 -0
  46. package/dist/features/admin/components/AdminOrdersGuideView.js +44 -0
  47. package/dist/features/admin/components/AdminProductsView.js +8 -3
  48. package/dist/features/admin/components/AdminSidebar.js +2 -1
  49. package/dist/features/admin/components/AdminSiteConfigGuideView.d.ts +1 -0
  50. package/dist/features/admin/components/AdminSiteConfigGuideView.js +21 -0
  51. package/dist/features/admin/components/AdminStoresGuideView.d.ts +1 -0
  52. package/dist/features/admin/components/AdminStoresGuideView.js +32 -0
  53. package/dist/features/admin/components/AdminTeamGuideView.d.ts +1 -0
  54. package/dist/features/admin/components/AdminTeamGuideView.js +33 -0
  55. package/dist/features/admin/components/AdminTrustGuideView.d.ts +1 -0
  56. package/dist/features/admin/components/AdminTrustGuideView.js +40 -0
  57. package/dist/features/admin/components/AdminUsersGuideView.d.ts +1 -0
  58. package/dist/features/admin/components/AdminUsersGuideView.js +38 -0
  59. package/dist/features/auth/repository/session.repository.js +16 -1
  60. package/dist/features/cart/hooks/useAddToCart.d.ts +2 -0
  61. package/dist/features/cart/hooks/useAddToCart.js +2 -0
  62. package/dist/features/cart/hooks/useGuestCart.d.ts +2 -0
  63. package/dist/features/cart/utils/guest-cart.d.ts +7 -0
  64. package/dist/features/cart/utils/pending-ops.d.ts +6 -0
  65. package/dist/features/categories/components/CategoryBundlesListing.js +3 -25
  66. package/dist/features/categories/components/CategoryProductsListing.js +6 -10
  67. package/dist/features/categories/components/index.d.ts +0 -2
  68. package/dist/features/categories/components/index.js +0 -1
  69. package/dist/features/categories/schemas/firestore.d.ts +9 -0
  70. package/dist/features/events/components/AdminEventEditorView.js +223 -269
  71. package/dist/features/events/components/EventRaffleWinnerView.d.ts +9 -1
  72. package/dist/features/events/components/EventRaffleWinnerView.js +3 -3
  73. package/dist/features/events/components/SpinWheelView.js +3 -3
  74. package/dist/features/grouped/repository/grouped-listings.repository.d.ts +9 -0
  75. package/dist/features/grouped/repository/grouped-listings.repository.js +12 -0
  76. package/dist/features/layout/BottomNavLayout.d.ts +5 -0
  77. package/dist/features/layout/BottomNavLayout.js +21 -0
  78. package/dist/features/layout/TitleBar.js +7 -1
  79. package/dist/features/layout/TitleBarLayout.d.ts +8 -2
  80. package/dist/features/layout/TitleBarLayout.js +11 -7
  81. package/dist/features/media/upload/MediaUploadField.js +1 -1
  82. package/dist/features/orders/schemas/index.d.ts +2 -2
  83. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +12 -6
  84. package/dist/features/products/components/AuctionsIndexListing.js +3 -1
  85. package/dist/features/products/components/MarketplaceBundleCard.d.ts +21 -0
  86. package/dist/features/products/components/MarketplaceBundleCard.js +56 -0
  87. package/dist/features/products/components/PrizeDrawDetailPageView.js +1 -1
  88. package/dist/features/products/components/PrizeDrawEntryActions.d.ts +3 -1
  89. package/dist/features/products/components/PrizeDrawEntryActions.js +8 -12
  90. package/dist/features/products/components/ProductDetailActions.d.ts +5 -1
  91. package/dist/features/products/components/ProductDetailActions.js +3 -1
  92. package/dist/features/products/components/ProductDetailPageView.d.ts +2 -0
  93. package/dist/features/products/components/ProductDetailPageView.js +4 -0
  94. package/dist/features/products/components/ProductGrid.js +3 -3
  95. package/dist/features/products/components/ProductsIndexListing.js +18 -9
  96. package/dist/features/products/components/index.d.ts +2 -4
  97. package/dist/features/products/components/index.js +1 -2
  98. package/dist/features/promotions/components/CouponCard.d.ts +11 -1
  99. package/dist/features/promotions/components/CouponCard.js +36 -2
  100. package/dist/features/promotions/repository/claimed-coupons.repository.d.ts +27 -0
  101. package/dist/features/promotions/repository/claimed-coupons.repository.js +115 -0
  102. package/dist/features/promotions/schemas/firestore.d.ts +34 -0
  103. package/dist/features/promotions/schemas/firestore.js +14 -1
  104. package/dist/features/reviews/components/index.d.ts +0 -2
  105. package/dist/features/reviews/components/index.js +0 -1
  106. package/dist/features/seller/components/BrandInlineSelect.js +23 -3
  107. package/dist/features/seller/components/CategoryInlineSelect.js +20 -3
  108. package/dist/features/seller/components/SellerAddressesView.js +3 -2
  109. package/dist/features/seller/components/SellerAnalyticsAlertsView.d.ts +6 -0
  110. package/dist/features/seller/components/SellerAnalyticsAlertsView.js +124 -0
  111. package/dist/features/seller/components/SellerAnalyticsView.d.ts +2 -0
  112. package/dist/features/seller/components/SellerAnalyticsView.js +17 -9
  113. package/dist/features/seller/components/SellerBidsView.js +33 -3
  114. package/dist/features/seller/components/SellerBundlesView.d.ts +5 -0
  115. package/dist/features/seller/components/SellerBundlesView.js +104 -0
  116. package/dist/features/seller/components/SellerClassifiedView.d.ts +5 -0
  117. package/dist/features/seller/components/SellerClassifiedView.js +113 -0
  118. package/dist/features/seller/components/SellerDashboardView.js +19 -7
  119. package/dist/features/seller/components/SellerDigitalCodesView.d.ts +5 -0
  120. package/dist/features/seller/components/SellerDigitalCodesView.js +115 -0
  121. package/dist/features/seller/components/SellerGoogleReviewsView.d.ts +14 -0
  122. package/dist/features/seller/components/SellerGoogleReviewsView.js +95 -0
  123. package/dist/features/seller/components/SellerGroupedListingsView.d.ts +6 -0
  124. package/dist/features/seller/components/SellerGroupedListingsView.js +112 -0
  125. package/dist/features/seller/components/SellerLiveView.d.ts +5 -0
  126. package/dist/features/seller/components/SellerLiveView.js +113 -0
  127. package/dist/features/seller/components/SellerOrdersView.js +53 -2
  128. package/dist/features/seller/components/SellerPayoutMethodsView.d.ts +7 -0
  129. package/dist/features/seller/components/SellerPayoutMethodsView.js +120 -0
  130. package/dist/features/seller/components/SellerPayoutSettingsView.js +50 -12
  131. package/dist/features/seller/components/SellerProductShell.d.ts +3 -1
  132. package/dist/features/seller/components/SellerProductShell.js +35 -11
  133. package/dist/features/seller/components/SellerProductsCards.d.ts +19 -0
  134. package/dist/features/seller/components/SellerProductsCards.js +19 -0
  135. package/dist/features/seller/components/SellerProductsFilterDrawer.d.ts +14 -0
  136. package/dist/features/seller/components/SellerProductsFilterDrawer.js +22 -0
  137. package/dist/features/seller/components/SellerProductsView.d.ts +3 -1
  138. package/dist/features/seller/components/SellerProductsView.js +92 -49
  139. package/dist/features/seller/components/SellerReviewsView.js +67 -4
  140. package/dist/features/seller/components/SellerShippingConfigsView.d.ts +7 -0
  141. package/dist/features/seller/components/SellerShippingConfigsView.js +149 -0
  142. package/dist/features/seller/components/SellerShippingView.js +37 -10
  143. package/dist/features/seller/components/SellerSidebar.js +2 -1
  144. package/dist/features/seller/components/SellerStoreCategoriesView.d.ts +9 -0
  145. package/dist/features/seller/components/SellerStoreCategoriesView.js +122 -0
  146. package/dist/features/seller/components/SellerStorefrontView.d.ts +0 -7
  147. package/dist/features/seller/components/SellerStorefrontView.js +26 -29
  148. package/dist/features/seller/components/SellerTemplatesView.d.ts +10 -0
  149. package/dist/features/seller/components/SellerTemplatesView.js +265 -0
  150. package/dist/features/seller/components/index.d.ts +26 -0
  151. package/dist/features/seller/components/index.js +13 -0
  152. package/dist/features/seller/components/seller-products-styles.d.ts +7 -0
  153. package/dist/features/seller/components/seller-products-styles.js +14 -0
  154. package/dist/features/shell/FormShell.d.ts +7 -1
  155. package/dist/features/shell/FormShell.js +5 -2
  156. package/dist/features/store-extensions/index.d.ts +4 -0
  157. package/dist/features/store-extensions/index.js +4 -0
  158. package/dist/features/store-extensions/repository/rbac.repositories.d.ts +23 -0
  159. package/dist/features/store-extensions/repository/rbac.repositories.js +32 -0
  160. package/dist/features/store-extensions/repository/store-extensions.repositories.d.ts +91 -0
  161. package/dist/features/store-extensions/repository/store-extensions.repositories.js +127 -0
  162. package/dist/features/store-extensions/schemas/firestore.d.ts +244 -0
  163. package/dist/features/store-extensions/schemas/firestore.js +158 -0
  164. package/dist/features/store-extensions/schemas/rbac.d.ts +65 -0
  165. package/dist/features/store-extensions/schemas/rbac.js +43 -0
  166. package/dist/features/stores/api/[storeSlug]/reviews/route.js +49 -7
  167. package/dist/features/stores/components/InteractiveStoreCard.js +7 -3
  168. package/dist/features/stores/components/StoreCapabilitiesGuideView.d.ts +3 -0
  169. package/dist/features/stores/components/StoreCapabilitiesGuideView.js +101 -0
  170. package/dist/features/stores/components/StoreFinanceGuideView.d.ts +3 -0
  171. package/dist/features/stores/components/StoreFinanceGuideView.js +79 -0
  172. package/dist/features/stores/components/StoreGuideHubView.d.ts +5 -0
  173. package/dist/features/stores/components/StoreGuideHubView.js +89 -0
  174. package/dist/features/stores/components/StoreListingsGuideView.d.ts +3 -0
  175. package/dist/features/stores/components/StoreListingsGuideView.js +151 -0
  176. package/dist/features/stores/components/StoreOrdersGuideView.d.ts +3 -0
  177. package/dist/features/stores/components/StoreOrdersGuideView.js +122 -0
  178. package/dist/features/stores/components/StoreProductsListing.js +6 -10
  179. package/dist/features/stores/components/StoreReviewsListing.js +100 -23
  180. package/dist/features/stores/components/StoreSettingsGuideView.d.ts +3 -0
  181. package/dist/features/stores/components/StoreSettingsGuideView.js +56 -0
  182. package/dist/features/stores/components/index.d.ts +12 -1
  183. package/dist/features/stores/components/index.js +6 -1
  184. package/dist/features/stores/hooks/useStores.d.ts +5 -0
  185. package/dist/features/stores/hooks/useStores.js +10 -0
  186. package/dist/features/stores/manifest.js +1 -1
  187. package/dist/features/stores/schemas/firestore.d.ts +2 -0
  188. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +13 -2
  189. package/dist/index.d.ts +60 -9
  190. package/dist/index.js +66 -15
  191. package/dist/next/routing/route-map.d.ts +134 -0
  192. package/dist/next/routing/route-map.js +59 -0
  193. package/dist/providers/db-firebase/__tests__/filter-aliases.test.d.ts +1 -0
  194. package/dist/providers/db-firebase/__tests__/filter-aliases.test.js +93 -0
  195. package/dist/providers/db-firebase/sieve.d.ts +49 -0
  196. package/dist/providers/db-firebase/sieve.js +61 -8
  197. package/dist/react/hooks/useFormStatePreservation.d.ts +17 -0
  198. package/dist/react/hooks/useFormStatePreservation.js +62 -0
  199. package/dist/react/hooks/useInlineRowEdit.d.ts +24 -0
  200. package/dist/react/hooks/useInlineRowEdit.js +68 -0
  201. package/dist/react/index.d.ts +4 -0
  202. package/dist/react/index.js +4 -0
  203. package/dist/repositories/index.d.ts +5 -0
  204. package/dist/repositories/index.js +7 -0
  205. package/dist/seed/actions/demo-seed-actions.d.ts +1 -1
  206. package/dist/seed/claimed-coupons-seed-data.d.ts +13 -0
  207. package/dist/seed/claimed-coupons-seed-data.js +79 -0
  208. package/dist/seed/index.d.ts +2 -0
  209. package/dist/seed/index.js +3 -0
  210. package/dist/seed/manifest.js +17 -0
  211. package/dist/seed/store-extensions-seed-data.d.ts +19 -0
  212. package/dist/seed/store-extensions-seed-data.js +421 -0
  213. package/dist/tailwind-utilities.css +1 -1
  214. package/dist/ui/components/Button.style.css +20 -12
  215. package/dist/ui/components/ClaimCouponButton.d.ts +28 -0
  216. package/dist/ui/components/ClaimCouponButton.js +89 -0
  217. package/dist/ui/components/ListingToolbar.d.ts +8 -1
  218. package/dist/ui/components/ListingToolbar.js +4 -2
  219. package/dist/ui/components/QuickCreateModal.d.ts +15 -0
  220. package/dist/ui/components/QuickCreateModal.js +48 -0
  221. package/dist/ui/components/QuickCreateModal.style.css +84 -0
  222. package/dist/ui/components/StickyBottomBar.d.ts +22 -0
  223. package/dist/ui/components/StickyBottomBar.js +20 -0
  224. package/dist/ui/components/VacationBanner.d.ts +11 -0
  225. package/dist/ui/components/VacationBanner.js +16 -0
  226. package/dist/ui/components/__tests__/BulkActionBar.test.d.ts +1 -0
  227. package/dist/ui/components/__tests__/BulkActionBar.test.js +96 -0
  228. package/dist/ui/components/__tests__/ListingToolbar.test.d.ts +1 -0
  229. package/dist/ui/components/__tests__/ListingToolbar.test.js +125 -0
  230. package/dist/ui/index.d.ts +9 -1
  231. package/dist/ui/index.js +4 -0
  232. package/package.json +8 -2
@@ -41,6 +41,10 @@ export const DEFAULT_ROUTE_MAP = {
41
41
  CONTACT: "/contact",
42
42
  BLOG: "/blog",
43
43
  HELP: "/help",
44
+ HELP_SHOPPING: "/help/shopping",
45
+ HELP_AUCTIONS: "/help/auctions",
46
+ HELP_ORDERS: "/help/orders",
47
+ HELP_ACCOUNT: "/help/account",
44
48
  TERMS: "/terms",
45
49
  PRIVACY: "/privacy",
46
50
  SECURITY: "/security",
@@ -68,6 +72,10 @@ export const DEFAULT_ROUTE_MAP = {
68
72
  SCAMS: "/scams",
69
73
  SCAM_DETAIL: (id) => `/scams/${id}`,
70
74
  SCAM_REPORT: "/scams/report",
75
+ REPORT_ENTITY: "/report",
76
+ ITEM_REQUESTS: "/item-requests",
77
+ ITEM_REQUEST_DETAIL: (id) => `/item-requests/${id}`,
78
+ ITEM_REQUESTS_NEW: "/item-requests/new",
71
79
  SCAM_TYPES: "/scams/types",
72
80
  SCAM_FAQS: "/scams/faqs",
73
81
  CLASSIFIED: "/classified",
@@ -104,6 +112,8 @@ export const DEFAULT_ROUTE_MAP = {
104
112
  ORDER_INVOICE: (id) => `/user/orders/${id}/invoice`,
105
113
  NOTIFICATIONS: "/user/notifications",
106
114
  MESSAGES: "/user/messages",
115
+ /** Plan §10 — claimed-coupons wallet (Active / Expired / Used tabs). */
116
+ CLAIMED_COUPONS: "/user/coupons",
107
117
  BECOME_SELLER: "/user/become-seller",
108
118
  CART: "/cart",
109
119
  CHECKOUT: "/checkout",
@@ -175,6 +185,32 @@ export const DEFAULT_ROUTE_MAP = {
175
185
  LIVE_ITEMS_EDIT: (id) => `/store/live/${id}/edit`,
176
186
  PRINT_CENTER: "/store/print-center",
177
187
  INVENTORY_PRINT: "/store/inventory/print",
188
+ // S-STORE Tier — new extension routes
189
+ PAYOUT_METHODS: "/store/payout-methods",
190
+ PAYOUT_METHODS_NEW: "/store/payout-methods/new",
191
+ PAYOUT_METHODS_EDIT: (id) => `/store/payout-methods/${id}/edit`,
192
+ SHIPPING_CONFIGS: "/store/shipping-configs",
193
+ SHIPPING_CONFIGS_NEW: "/store/shipping-configs/new",
194
+ SHIPPING_CONFIGS_EDIT: (id) => `/store/shipping-configs/${id}/edit`,
195
+ ANALYTICS_CARDS: "/store/analytics/cards",
196
+ ANALYTICS_ALERTS: "/store/analytics/alerts",
197
+ GROUPED_LISTINGS: "/store/grouped-listings",
198
+ GROUPED_LISTINGS_NEW: "/store/grouped-listings/new",
199
+ GROUPED_LISTINGS_EDIT: (id) => `/store/grouped-listings/${id}/edit`,
200
+ STORE_CATEGORIES: "/store/categories",
201
+ STORE_CATEGORIES_NEW: "/store/categories/new",
202
+ STORE_CATEGORIES_EDIT: (id) => `/store/categories/${id}/edit`,
203
+ LISTING_TEMPLATES: "/store/listing-templates",
204
+ LISTING_TEMPLATES_NEW: "/store/listing-templates/new",
205
+ LISTING_TEMPLATES_EDIT: (id) => `/store/listing-templates/${id}/edit`,
206
+ GOOGLE_REVIEWS: "/store/google-reviews",
207
+ // GD1–GD6 — Store Guide Hub + sub-pages
208
+ GUIDE: "/store/guide",
209
+ GUIDE_LISTINGS: "/store/guide/listings",
210
+ GUIDE_ORDERS: "/store/guide/orders",
211
+ GUIDE_FINANCE: "/store/guide/finance",
212
+ GUIDE_CAPABILITIES: "/store/guide/capabilities",
213
+ GUIDE_SETTINGS: "/store/guide/settings",
178
214
  },
179
215
  ADMIN: {
180
216
  DASHBOARD: "/admin/dashboard",
@@ -258,6 +294,29 @@ export const DEFAULT_ROUTE_MAP = {
258
294
  SETTINGS_ACTIONS: "/admin/settings/actions",
259
295
  SETTINGS_NAVIGATION: "/admin/settings/navigation",
260
296
  PRINT_CENTER: "/admin/print-center",
297
+ // S-STORE Tier — admin moderation + reports + item requests
298
+ MODERATION: "/admin/moderation",
299
+ MODERATION_DETAIL: (id) => `/admin/moderation/${id}`,
300
+ REPORTS: "/admin/reports",
301
+ REPORT_DETAIL: (id) => `/admin/reports/${id}`,
302
+ ITEM_REQUESTS: "/admin/item-requests",
303
+ ITEM_REQUEST_DETAIL: (id) => `/admin/item-requests/${id}`,
304
+ ROLES: "/admin/roles",
305
+ ROLES_NEW: "/admin/roles/new",
306
+ ROLES_EDIT: (id) => `/admin/roles/${id}/edit`,
307
+ PERMISSIONS: "/admin/permissions",
308
+ ADMIN_NOTIFICATIONS: "/admin/admin-notifications",
309
+ // GD13–GD22 — Admin Guide Hub + sub-pages
310
+ GUIDE: "/admin/guide",
311
+ GUIDE_USERS: "/admin/guide/users",
312
+ GUIDE_CATALOG: "/admin/guide/catalog",
313
+ GUIDE_STORES: "/admin/guide/stores",
314
+ GUIDE_ORDERS: "/admin/guide/orders",
315
+ GUIDE_CONTENT: "/admin/guide/content",
316
+ GUIDE_SITE: "/admin/guide/site",
317
+ GUIDE_TEAM: "/admin/guide/team",
318
+ GUIDE_ANALYTICS: "/admin/guide/analytics",
319
+ GUIDE_TRUST: "/admin/guide/trust",
261
320
  },
262
321
  DEMO: {
263
322
  SEED: "/demo/seed",
@@ -0,0 +1,93 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { expandFilterAliases } from "../filter-aliases";
3
+ describe("expandFilterAliases", () => {
4
+ it("returns undefined when filters is undefined", () => {
5
+ const aliases = { scope: () => "status==active" };
6
+ expect(expandFilterAliases(undefined, aliases)).toBeUndefined();
7
+ });
8
+ it("returns filters unchanged when aliases is undefined", () => {
9
+ expect(expandFilterAliases("status==active", undefined)).toBe("status==active");
10
+ });
11
+ it("returns filters unchanged when aliases is empty object", () => {
12
+ expect(expandFilterAliases("status==active", {})).toBe("status==active");
13
+ });
14
+ it("expands a single alias clause", () => {
15
+ const aliases = {
16
+ scope: (value) => value === "publicAuctions" ? "status==published,listingType==auction" : "",
17
+ };
18
+ expect(expandFilterAliases("scope==publicAuctions", aliases)).toBe("status==published,listingType==auction");
19
+ });
20
+ it("passes the operator to the alias function", () => {
21
+ const received = [];
22
+ const aliases = {
23
+ myField: (value, op) => {
24
+ received.push({ value, op });
25
+ return "x==1";
26
+ },
27
+ };
28
+ expandFilterAliases("myField!=foo", aliases);
29
+ expect(received).toEqual([{ value: "foo", op: "!=" }]);
30
+ });
31
+ it("expands an alias and passes through unknown clauses", () => {
32
+ const aliases = {
33
+ scope: () => "status==published,listingType==auction",
34
+ };
35
+ const result = expandFilterAliases("scope==publicAuctions,storeId==store-abc", aliases);
36
+ expect(result).toBe("status==published,listingType==auction,storeId==store-abc");
37
+ });
38
+ it("passes through a clause whose field has no alias", () => {
39
+ const aliases = { scope: () => "status==active" };
40
+ expect(expandFilterAliases("category==brand-pokemon", aliases)).toBe("category==brand-pokemon");
41
+ });
42
+ it("drops a clause when the alias returns empty string", () => {
43
+ const aliases = {
44
+ scope: () => "",
45
+ };
46
+ expect(expandFilterAliases("scope==unknown", aliases)).toBe("");
47
+ });
48
+ it("drops an empty-expansion clause while keeping other clauses", () => {
49
+ const aliases = {
50
+ scope: (value) => (value === "known" ? "status==active" : ""),
51
+ };
52
+ const result = expandFilterAliases("scope==notknown,listingType==standard", aliases);
53
+ expect(result).toBe("listingType==standard");
54
+ });
55
+ it("handles multiple alias fields in one filter string", () => {
56
+ const aliases = {
57
+ scope: () => "status==active",
58
+ type: () => "listingType==auction",
59
+ };
60
+ const result = expandFilterAliases("scope==any,type==any", aliases);
61
+ expect(result).toBe("status==active,listingType==auction");
62
+ });
63
+ it("trims whitespace around clauses", () => {
64
+ const aliases = { scope: () => "status==active" };
65
+ const result = expandFilterAliases(" scope==x , name==foo ", aliases);
66
+ expect(result).toBe("status==active,name==foo");
67
+ });
68
+ it("passes through a clause that does not match the operator pattern", () => {
69
+ const aliases = { scope: () => "status==active" };
70
+ // A malformed clause has no operator — should pass through unchanged
71
+ expect(expandFilterAliases("malformed", aliases)).toBe("malformed");
72
+ });
73
+ it("handles @= operator", () => {
74
+ const received = [];
75
+ const aliases = {
76
+ tags: (_v, op) => { received.push(op); return "tags@=value"; },
77
+ };
78
+ expandFilterAliases("tags@=value", aliases);
79
+ expect(received[0]).toBe("@=");
80
+ });
81
+ it("handles @=* operator", () => {
82
+ const received = [];
83
+ const aliases = {
84
+ tags: (_v, op) => { received.push(op); return "tags@=*value"; },
85
+ };
86
+ expandFilterAliases("tags@=*value", aliases);
87
+ expect(received[0]).toBe("@=*");
88
+ });
89
+ it("returns empty string when all clauses expand to empty", () => {
90
+ const aliases = { scope: () => "" };
91
+ expect(expandFilterAliases("scope==x", aliases)).toBe("");
92
+ });
93
+ });
@@ -16,6 +16,55 @@
16
16
  * }, { baseQuery });
17
17
  * }
18
18
  * ```
19
+ *
20
+ * ## Known Sieve ↔ Firestore incompatibilities
21
+ *
22
+ * These Sieve DSL features are silently unsupported or produce wrong results
23
+ * when translated to Firestore queries. Document them here to avoid surprise.
24
+ *
25
+ * ### 1. String-contains `@=*` (case-insensitive full-text)
26
+ * Sieve's `title@=*query` is a substring/CI match. Firestore has no native
27
+ * LIKE or ILIKE operator. The Firebase adapter maps it to `>=` / `<` prefix
28
+ * range tricks that only work for prefix matches on ASCII strings, not
29
+ * arbitrary substrings. Use a Firebase Function or in-memory post-filter for
30
+ * real substring search; never rely on `@=*` to match mid-string.
31
+ *
32
+ * ### 2. OR across different fields (`|` pipe between clauses)
33
+ * Sieve's `field1==v1|field2==v2` (OR across two different fields) is
34
+ * translated to `whereOr` by the stock Firebase adapter. Firestore's Admin SDK
35
+ * v6+ supports `Query.where(Filter.or(...))`, but the stock adapter version
36
+ * bundled with sievejs may emit an unsupported form. The enhanced adapter in
37
+ * this file only upgrades single-field OR groups (same-field equality → `in`
38
+ * query). Multi-field OR is still unsupported — apply it in memory.
39
+ *
40
+ * ### 3. OR on the same field (`field==v1|v2`) → Firestore `in`
41
+ * The custom `createEnhancedFirebaseAdapter` in this file upgrades these to
42
+ * Firestore `.where(field, "in", [v1, v2])`. Firestore supports up to 30
43
+ * values in an `in` clause. More than 30 values will throw. The stock adapter
44
+ * would have emitted a `whereOr` call that fails entirely.
45
+ *
46
+ * ### 4. Multi-field `orderBy` without a matching composite index
47
+ * Firestore requires a composite index for every combination of `where` +
48
+ * `orderBy` fields. Sieve sorts like `-createdAt,price` translate to two
49
+ * `orderBy` calls; if the Firestore collection has no index for that
50
+ * combination the query throws `FAILED_PRECONDITION`. Add the index to
51
+ * `appkit/firebase/base/firestore.indexes.json` and deploy before shipping.
52
+ *
53
+ * ### 5. Inequality filter + `orderBy` on a different field
54
+ * Firestore's rule: if you have an inequality filter (`!=`, `<`, `>`, `<=`,
55
+ * `>=`) on field A, the first `orderBy` must also be on field A. Sieve queries
56
+ * like `price>=100 & sorts=-createdAt` translate to an inequality on `price`
57
+ * with `orderBy createdAt`, which Firestore rejects. Work-arounds:
58
+ * (a) move the inequality filter to the Firebase Function path where it can
59
+ * be handled server-side, (b) apply it in-memory in the fallback path,
60
+ * (c) restructure the sort to use the same field as the filter.
61
+ *
62
+ * ### 6. Dot-notation nested field filters (`address.city==Delhi`)
63
+ * Sieve parses the field name verbatim; the Firebase adapter passes it as the
64
+ * Firestore field path. Firestore Admin SDK supports dot-notation for nested
65
+ * fields, so `address.city==Delhi` works — but only if the field is indexed.
66
+ * Add nested-field indexes explicitly; Firestore does not auto-index nested
67
+ * paths in composite indexes declared at the root level.
19
68
  */
20
69
  import type { CollectionReference, DocumentData, Query } from "firebase-admin/firestore";
21
70
  import { FirebaseRepository } from "./base";
@@ -16,6 +16,55 @@
16
16
  * }, { baseQuery });
17
17
  * }
18
18
  * ```
19
+ *
20
+ * ## Known Sieve ↔ Firestore incompatibilities
21
+ *
22
+ * These Sieve DSL features are silently unsupported or produce wrong results
23
+ * when translated to Firestore queries. Document them here to avoid surprise.
24
+ *
25
+ * ### 1. String-contains `@=*` (case-insensitive full-text)
26
+ * Sieve's `title@=*query` is a substring/CI match. Firestore has no native
27
+ * LIKE or ILIKE operator. The Firebase adapter maps it to `>=` / `<` prefix
28
+ * range tricks that only work for prefix matches on ASCII strings, not
29
+ * arbitrary substrings. Use a Firebase Function or in-memory post-filter for
30
+ * real substring search; never rely on `@=*` to match mid-string.
31
+ *
32
+ * ### 2. OR across different fields (`|` pipe between clauses)
33
+ * Sieve's `field1==v1|field2==v2` (OR across two different fields) is
34
+ * translated to `whereOr` by the stock Firebase adapter. Firestore's Admin SDK
35
+ * v6+ supports `Query.where(Filter.or(...))`, but the stock adapter version
36
+ * bundled with sievejs may emit an unsupported form. The enhanced adapter in
37
+ * this file only upgrades single-field OR groups (same-field equality → `in`
38
+ * query). Multi-field OR is still unsupported — apply it in memory.
39
+ *
40
+ * ### 3. OR on the same field (`field==v1|v2`) → Firestore `in`
41
+ * The custom `createEnhancedFirebaseAdapter` in this file upgrades these to
42
+ * Firestore `.where(field, "in", [v1, v2])`. Firestore supports up to 30
43
+ * values in an `in` clause. More than 30 values will throw. The stock adapter
44
+ * would have emitted a `whereOr` call that fails entirely.
45
+ *
46
+ * ### 4. Multi-field `orderBy` without a matching composite index
47
+ * Firestore requires a composite index for every combination of `where` +
48
+ * `orderBy` fields. Sieve sorts like `-createdAt,price` translate to two
49
+ * `orderBy` calls; if the Firestore collection has no index for that
50
+ * combination the query throws `FAILED_PRECONDITION`. Add the index to
51
+ * `appkit/firebase/base/firestore.indexes.json` and deploy before shipping.
52
+ *
53
+ * ### 5. Inequality filter + `orderBy` on a different field
54
+ * Firestore's rule: if you have an inequality filter (`!=`, `<`, `>`, `<=`,
55
+ * `>=`) on field A, the first `orderBy` must also be on field A. Sieve queries
56
+ * like `price>=100 & sorts=-createdAt` translate to an inequality on `price`
57
+ * with `orderBy createdAt`, which Firestore rejects. Work-arounds:
58
+ * (a) move the inequality filter to the Firebase Function path where it can
59
+ * be handled server-side, (b) apply it in-memory in the fallback path,
60
+ * (c) restructure the sort to use the same field as the filter.
61
+ *
62
+ * ### 6. Dot-notation nested field filters (`address.city==Delhi`)
63
+ * Sieve parses the field name verbatim; the Firebase adapter passes it as the
64
+ * Firestore field path. Firestore Admin SDK supports dot-notation for nested
65
+ * fields, so `address.city==Delhi` works — but only if the field is indexed.
66
+ * Add nested-field indexes explicitly; Firestore does not auto-index nested
67
+ * paths in composite indexes declared at the root level.
19
68
  */
20
69
  import { SieveProcessorBase } from "@mohasinac/sievejs/services";
21
70
  import { createFirebaseAdapter } from "@mohasinac/sievejs/adapters/firebase";
@@ -81,15 +130,18 @@ export async function applySieveToFirestore(params) {
81
130
  options: merged,
82
131
  fields,
83
132
  });
133
+ const page = Math.max(1, Number(model.page ?? 1));
134
+ const pageSize = Math.min(merged.maxPageSize, Math.max(1, Number(model.pageSize ?? merged.defaultPageSize)));
135
+ // Apply filters + sorts once; count without reading docs.
84
136
  const filteredQ = processor.apply(effective, baseQuery, {
85
137
  applyPagination: false,
86
138
  });
87
139
  const total = await getFirestoreCount(filteredQ);
88
- const pagedQ = processor.apply(effective, baseQuery);
140
+ // Apply pagination on top of the already-filtered query — avoids re-applying
141
+ // the full Sieve DSL from the base.
142
+ const pagedQ = filteredQ.offset((page - 1) * pageSize).limit(pageSize);
89
143
  const snap = await pagedQ.get();
90
144
  const items = snap.docs.map((d) => deserializeTimestamps({ id: d.id, ...d.data() }));
91
- const page = Math.max(1, Number(model.page ?? 1));
92
- const pageSize = Math.min(merged.maxPageSize, Math.max(1, Number(model.pageSize ?? merged.defaultPageSize)));
93
145
  const totalPages = total === 0 ? 0 : Math.max(1, Math.ceil(total / pageSize));
94
146
  return {
95
147
  items,
@@ -120,17 +172,18 @@ export class FirebaseSieveRepository extends FirebaseRepository {
120
172
  options: merged,
121
173
  fields,
122
174
  });
123
- // Count (no docs fetched)
175
+ const page = Math.max(1, Number(model.page ?? 1));
176
+ const pageSize = Math.min(merged.maxPageSize, Math.max(1, Number(model.pageSize ?? merged.defaultPageSize)));
177
+ // Apply filters + sorts once; count without reading docs.
124
178
  const filteredQ = processor.apply(effective, base, {
125
179
  applyPagination: false,
126
180
  });
127
181
  const total = await getFirestoreCount(filteredQ);
128
- // Paginated result
129
- const pagedQ = processor.apply(effective, base);
182
+ // Apply pagination on top of the already-filtered query — avoids re-applying
183
+ // the full Sieve DSL from the base.
184
+ const pagedQ = filteredQ.offset((page - 1) * pageSize).limit(pageSize);
130
185
  const snap = await pagedQ.get();
131
186
  const items = snap.docs.map((d) => deserializeTimestamps({ id: d.id, ...d.data() }));
132
- const page = Math.max(1, Number(model.page ?? 1));
133
- const pageSize = Math.min(merged.maxPageSize, Math.max(1, Number(model.pageSize ?? merged.defaultPageSize)));
134
187
  const totalPages = total === 0 ? 0 : Math.max(1, Math.ceil(total / pageSize));
135
188
  return {
136
189
  items,
@@ -0,0 +1,17 @@
1
+ export interface FormStatePreservationOptions<TValues> {
2
+ /** Current form values to persist. */
3
+ values: TValues;
4
+ /** Callback invoked with restored values on mount (if any). */
5
+ onRestore: (values: TValues) => void;
6
+ /** Field paths whose values are stripped before encoding (PII). */
7
+ stripFields?: string[];
8
+ /** URL query-param name. Default: "_s". */
9
+ paramName?: string;
10
+ /** Debounce in ms. Default: 500. */
11
+ debounceMs?: number;
12
+ /** Disable persistence (e.g. while submitting). */
13
+ enabled?: boolean;
14
+ }
15
+ export declare function useFormStatePreservation<TValues extends Record<string, unknown>>({ values, onRestore, stripFields, paramName, debounceMs, enabled, }: FormStatePreservationOptions<TValues>): {
16
+ clearPreservedState: () => void;
17
+ };
@@ -0,0 +1,62 @@
1
+ "use client";
2
+ import { useEffect, useRef, useCallback } from "react";
3
+ const PARAM_DEFAULT = "_s";
4
+ function stripPii(values, stripFields) {
5
+ if (!stripFields.length || typeof values !== "object" || values === null) {
6
+ return values;
7
+ }
8
+ const clone = { ...values };
9
+ for (const path of stripFields) {
10
+ if (path in clone) {
11
+ delete clone[path];
12
+ }
13
+ }
14
+ return clone;
15
+ }
16
+ export function useFormStatePreservation({ values, onRestore, stripFields = [], paramName = PARAM_DEFAULT, debounceMs = 500, enabled = true, }) {
17
+ const restoredRef = useRef(false);
18
+ const timerRef = useRef(null);
19
+ useEffect(() => {
20
+ if (restoredRef.current || typeof window === "undefined")
21
+ return;
22
+ restoredRef.current = true;
23
+ const url = new URL(window.location.href);
24
+ const encoded = url.searchParams.get(paramName);
25
+ if (!encoded)
26
+ return;
27
+ try {
28
+ const decoded = JSON.parse(atob(encoded));
29
+ onRestore(decoded);
30
+ }
31
+ catch {
32
+ // ignore corrupt payloads
33
+ }
34
+ }, [paramName, onRestore]);
35
+ useEffect(() => {
36
+ if (!enabled || typeof window === "undefined" || !restoredRef.current)
37
+ return;
38
+ if (timerRef.current)
39
+ clearTimeout(timerRef.current);
40
+ timerRef.current = setTimeout(() => {
41
+ const stripped = stripPii(values, stripFields);
42
+ const encoded = btoa(JSON.stringify(stripped));
43
+ const url = new URL(window.location.href);
44
+ url.searchParams.set(paramName, encoded);
45
+ window.history.replaceState({}, "", url.toString());
46
+ }, debounceMs);
47
+ return () => {
48
+ if (timerRef.current)
49
+ clearTimeout(timerRef.current);
50
+ };
51
+ }, [values, enabled, paramName, debounceMs, stripFields]);
52
+ const clearPreservedState = useCallback(() => {
53
+ if (typeof window === "undefined")
54
+ return;
55
+ const url = new URL(window.location.href);
56
+ if (url.searchParams.has(paramName)) {
57
+ url.searchParams.delete(paramName);
58
+ window.history.replaceState({}, "", url.toString());
59
+ }
60
+ }, [paramName]);
61
+ return { clearPreservedState };
62
+ }
@@ -0,0 +1,24 @@
1
+ export interface InlineEditOptions<TValue> {
2
+ rowId: string;
3
+ field: string;
4
+ initialValue: TValue;
5
+ save: (rowId: string, field: string, value: TValue) => Promise<unknown>;
6
+ onError?: (err: unknown, previous: TValue) => void;
7
+ }
8
+ export interface InlineToggleResult {
9
+ value: boolean;
10
+ isSaving: boolean;
11
+ toggle: () => Promise<void>;
12
+ }
13
+ export declare function useInlineToggle({ rowId, field, initialValue, save, onError, }: InlineEditOptions<boolean>): InlineToggleResult;
14
+ export interface InlineTextResult {
15
+ value: string;
16
+ draft: string;
17
+ isEditing: boolean;
18
+ isSaving: boolean;
19
+ startEdit: () => void;
20
+ cancelEdit: () => void;
21
+ commitEdit: () => Promise<void>;
22
+ setDraft: (next: string) => void;
23
+ }
24
+ export declare function useInlineTextEdit({ rowId, field, initialValue, save, onError, }: InlineEditOptions<string>): InlineTextResult;
@@ -0,0 +1,68 @@
1
+ "use client";
2
+ import { useCallback, useState } from "react";
3
+ export function useInlineToggle({ rowId, field, initialValue, save, onError, }) {
4
+ const [value, setValue] = useState(initialValue);
5
+ const [isSaving, setIsSaving] = useState(false);
6
+ const toggle = useCallback(async () => {
7
+ const previous = value;
8
+ const next = !previous;
9
+ setValue(next);
10
+ setIsSaving(true);
11
+ try {
12
+ await save(rowId, field, next);
13
+ }
14
+ catch (err) {
15
+ setValue(previous);
16
+ onError?.(err, previous);
17
+ }
18
+ finally {
19
+ setIsSaving(false);
20
+ }
21
+ }, [value, save, rowId, field, onError]);
22
+ return { value, isSaving, toggle };
23
+ }
24
+ export function useInlineTextEdit({ rowId, field, initialValue, save, onError, }) {
25
+ const [value, setValue] = useState(initialValue);
26
+ const [draft, setDraft] = useState(initialValue);
27
+ const [isEditing, setIsEditing] = useState(false);
28
+ const [isSaving, setIsSaving] = useState(false);
29
+ const startEdit = useCallback(() => {
30
+ setDraft(value);
31
+ setIsEditing(true);
32
+ }, [value]);
33
+ const cancelEdit = useCallback(() => {
34
+ setDraft(value);
35
+ setIsEditing(false);
36
+ }, [value]);
37
+ const commitEdit = useCallback(async () => {
38
+ if (draft === value) {
39
+ setIsEditing(false);
40
+ return;
41
+ }
42
+ const previous = value;
43
+ setValue(draft);
44
+ setIsEditing(false);
45
+ setIsSaving(true);
46
+ try {
47
+ await save(rowId, field, draft);
48
+ }
49
+ catch (err) {
50
+ setValue(previous);
51
+ setDraft(previous);
52
+ onError?.(err, previous);
53
+ }
54
+ finally {
55
+ setIsSaving(false);
56
+ }
57
+ }, [draft, value, save, rowId, field, onError]);
58
+ return {
59
+ value,
60
+ draft,
61
+ isEditing,
62
+ isSaving,
63
+ startEdit,
64
+ cancelEdit,
65
+ commitEdit,
66
+ setDraft,
67
+ };
68
+ }
@@ -30,6 +30,10 @@ export type { UseBulkSelectionOptions, UseBulkSelectionReturn, } from "./hooks/u
30
30
  export { useSyncManager } from "../core/hooks/useSyncManager";
31
31
  export { useUrlTable } from "./hooks/useUrlTable";
32
32
  export type { UseUrlTableOptions } from "./hooks/useUrlTable";
33
+ export { useInlineToggle, useInlineTextEdit, } from "./hooks/useInlineRowEdit";
34
+ export type { InlineEditOptions, InlineToggleResult, InlineTextResult, } from "./hooks/useInlineRowEdit";
35
+ export { useFormStatePreservation } from "./hooks/useFormStatePreservation";
36
+ export type { FormStatePreservationOptions } from "./hooks/useFormStatePreservation";
33
37
  export { usePendingFilters } from "./hooks/usePendingFilters";
34
38
  export type { UsePendingFiltersOptions, UsePendingFiltersReturn, } from "./hooks/usePendingFilters";
35
39
  export { usePendingTable } from "./hooks/usePendingTable";
@@ -28,6 +28,10 @@ export { useBulkSelection } from "./hooks/useBulkSelection";
28
28
  export { useSyncManager } from "../core/hooks/useSyncManager";
29
29
  // URL-driven table / list state
30
30
  export { useUrlTable } from "./hooks/useUrlTable";
31
+ // Inline row editing (S-STORE-CROSS-B)
32
+ export { useInlineToggle, useInlineTextEdit, } from "./hooks/useInlineRowEdit";
33
+ // Form state preservation in URL (S-STORE-CROSS-C)
34
+ export { useFormStatePreservation } from "./hooks/useFormStatePreservation";
31
35
  // Staged (pending) filter management
32
36
  export { usePendingFilters } from "./hooks/usePendingFilters";
33
37
  export { usePendingTable } from "./hooks/usePendingTable";
@@ -24,9 +24,14 @@ export { carouselsRepository, CarouselsRepository } from "../features/homepage/r
24
24
  export { homepageSectionsRepository } from "../features/homepage/repository/homepage-sections.repository";
25
25
  export { CategoriesRepository, categoriesRepository, } from "../features/categories/repository/categories.repository";
26
26
  export { couponsRepository } from "../features/promotions/repository/coupons.repository";
27
+ export { ClaimedCouponsRepository, claimedCouponsRepository, } from "../features/promotions/repository/claimed-coupons.repository";
28
+ export type { ClaimedCouponCreateInput } from "../features/promotions/repository/claimed-coupons.repository";
27
29
  export { FAQsRepository, FirebaseFAQsRepository, faqsRepository, } from "../features/faq/repository/faqs.repository";
28
30
  export { BlogRepository, blogRepository, } from "../features/blog/repository/blog.repository";
29
31
  export { payoutRepository } from "../features/payments/repository/payout.repository";
32
+ export { GroupedListingsRepository, groupedListingsRepository, } from "../features/grouped/repository/grouped-listings.repository";
33
+ export { payoutMethodsRepository, shippingConfigsRepository, analyticsCardsRepository, analyticsAlertsRepository, storeCategoriesRepository, listingTemplatesRepository, moderationQueueRepository, reportsRepository, itemRequestsRepository, storeWhatsAppConfigRepository, storeGoogleConfigRepository, PayoutMethodsRepository, ShippingConfigsRepository, AnalyticsCardsRepository, AnalyticsAlertsRepository, StoreCategoriesRepository, ListingTemplatesRepository, ModerationQueueRepository, ReportsRepository, ItemRequestsRepository, StoreWhatsAppConfigRepository, StoreGoogleConfigRepository, } from "../features/store-extensions/repository/store-extensions.repositories";
34
+ export { roleOverridesRepository, customRolesRepository, adminNotificationsRepository, RoleOverridesRepository, CustomRolesRepository, AdminNotificationsRepository, } from "../features/store-extensions/repository/rbac.repositories";
30
35
  export { OfferRepository, offerRepository, } from "../features/seller/repository/offer.repository";
31
36
  export { wishlistRepository, type UserWishlistItem as WishlistItem, WishlistFullError, } from "../features/wishlist/repository/user-wishlist.repository";
32
37
  export { historyRepository, type UserHistoryItem, type HistoryProductType, } from "../features/history/repository/user-history.repository";
@@ -31,9 +31,16 @@ export { carouselsRepository, CarouselsRepository } from "../features/homepage/r
31
31
  export { homepageSectionsRepository } from "../features/homepage/repository/homepage-sections.repository";
32
32
  export { CategoriesRepository, categoriesRepository, } from "../features/categories/repository/categories.repository";
33
33
  export { couponsRepository } from "../features/promotions/repository/coupons.repository";
34
+ export { ClaimedCouponsRepository, claimedCouponsRepository, } from "../features/promotions/repository/claimed-coupons.repository";
34
35
  export { FAQsRepository, FirebaseFAQsRepository, faqsRepository, } from "../features/faq/repository/faqs.repository";
35
36
  export { BlogRepository, blogRepository, } from "../features/blog/repository/blog.repository";
36
37
  export { payoutRepository } from "../features/payments/repository/payout.repository";
38
+ // Grouped listings repository
39
+ export { GroupedListingsRepository, groupedListingsRepository, } from "../features/grouped/repository/grouped-listings.repository";
40
+ // S-STORE-CROSS — 11 new collection repositories
41
+ export { payoutMethodsRepository, shippingConfigsRepository, analyticsCardsRepository, analyticsAlertsRepository, storeCategoriesRepository, listingTemplatesRepository, moderationQueueRepository, reportsRepository, itemRequestsRepository, storeWhatsAppConfigRepository, storeGoogleConfigRepository, PayoutMethodsRepository, ShippingConfigsRepository, AnalyticsCardsRepository, AnalyticsAlertsRepository, StoreCategoriesRepository, ListingTemplatesRepository, ModerationQueueRepository, ReportsRepository, ItemRequestsRepository, StoreWhatsAppConfigRepository, StoreGoogleConfigRepository, } from "../features/store-extensions/repository/store-extensions.repositories";
42
+ // S-STORE RBAC + admin notifications
43
+ export { roleOverridesRepository, customRolesRepository, adminNotificationsRepository, RoleOverridesRepository, CustomRolesRepository, AdminNotificationsRepository, } from "../features/store-extensions/repository/rbac.repositories";
37
44
  export { OfferRepository, offerRepository, } from "../features/seller/repository/offer.repository";
38
45
  export { wishlistRepository, WishlistFullError, } from "../features/wishlist/repository/user-wishlist.repository";
39
46
  export { historyRepository, } from "../features/history/repository/user-history.repository";
@@ -6,7 +6,7 @@
6
6
  * the actual collection-specific seeding logic (800+ lines with PII encryption,
7
7
  * Auth user creation, subcollection handling, etc.).
8
8
  */
9
- export type SeedCollectionName = "users" | "addresses" | "categories" | "stores" | "products" | "orders" | "reviews" | "bids" | "coupons" | "carousels" | "carouselSlides" | "homepageSections" | "siteSettings" | "faqs" | "notifications" | "payouts" | "blogPosts" | "events" | "eventEntries" | "sessions" | "carts" | "wishlists" | "history" | "conversations" | "groupedListings" | "scammerProfiles" | "supportTickets" | "productFeatures" | "offers";
9
+ export type SeedCollectionName = "users" | "addresses" | "categories" | "stores" | "products" | "orders" | "reviews" | "bids" | "coupons" | "carousels" | "carouselSlides" | "homepageSections" | "siteSettings" | "faqs" | "notifications" | "payouts" | "blogPosts" | "events" | "eventEntries" | "sessions" | "carts" | "wishlists" | "history" | "conversations" | "groupedListings" | "scammerProfiles" | "supportTickets" | "productFeatures" | "offers" | "payoutMethods" | "shippingConfigs" | "analyticsCards" | "analyticsAlerts" | "storeCategories" | "listingTemplates" | "moderationQueue" | "reports" | "itemRequests" | "storeWhatsAppConfig" | "storeGoogleConfig" | "roleOverrides" | "customRoles" | "adminNotifications";
10
10
  export interface SeedOperationResult {
11
11
  success?: boolean;
12
12
  message: string;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Claimed Coupons Seed Data — plan §10.
3
+ *
4
+ * Top-level `claimedCoupons` collection (one doc per user × coupon). These
5
+ * rows populate the /user/coupons wallet with one example per status so the
6
+ * tabs (Active / Expired / Used) all have something to render in demo.
7
+ *
8
+ * Coupon snapshots mirror coupons-seed-data.ts (WELCOME10, POKEMON25,
9
+ * FREESHIP999) so the discount badge labels render correctly. Seed user is
10
+ * `user-mohsin-c` to match the dev-account convention used elsewhere.
11
+ */
12
+ import type { ClaimedCouponDocument } from "../features/promotions/schemas";
13
+ export declare const claimedCouponsSeedData: ClaimedCouponDocument[];