@mohasinac/appkit 4.52.4 → 4.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (633) hide show
  1. package/dist/.build-stamp.json +4 -4
  2. package/dist/_internal/client/features/sticker-trace/canvas-codec.d.ts +2 -0
  3. package/dist/_internal/client/features/sticker-trace/canvas-codec.js +148 -0
  4. package/dist/_internal/server/features/auctions/actions.js +1 -1
  5. package/dist/_internal/server/features/categories/data.js +23 -7
  6. package/dist/_internal/server/features/checkout/actions.js +10 -3
  7. package/dist/_internal/server/features/checkout/data.d.ts +15 -0
  8. package/dist/_internal/server/features/checkout/data.js +20 -3
  9. package/dist/_internal/server/features/lottery/actions.js +9 -1
  10. package/dist/_internal/server/features/lottery/og.d.ts +40 -0
  11. package/dist/_internal/server/features/lottery/og.js +79 -0
  12. package/dist/_internal/server/features/messages/actions.js +4 -0
  13. package/dist/_internal/server/features/offers/adapters.js +17 -3
  14. package/dist/_internal/server/features/orders/actions.js +7 -2
  15. package/dist/_internal/server/features/raffle/actions.d.ts +19 -0
  16. package/dist/_internal/server/features/raffle/actions.js +25 -0
  17. package/dist/_internal/server/features/reviews/actions.js +1 -1
  18. package/dist/_internal/server/features/reviews/data.d.ts +1 -1
  19. package/dist/_internal/server/features/search/index-build/artifact-store.d.ts +89 -0
  20. package/dist/_internal/server/features/search/index-build/artifact-store.js +208 -0
  21. package/dist/_internal/server/features/search/index-build/build.d.ts +57 -0
  22. package/dist/_internal/server/features/search/index-build/build.js +285 -0
  23. package/dist/_internal/server/features/search/index-build/sources.d.ts +53 -0
  24. package/dist/_internal/server/features/search/index-build/sources.js +385 -0
  25. package/dist/_internal/server/features/search/search-sources.d.ts +0 -15
  26. package/dist/_internal/server/features/search/search-sources.js +142 -7
  27. package/dist/_internal/server/features/seo/robots.js +21 -1
  28. package/dist/_internal/server/features/seo/sitemap.js +1 -1
  29. package/dist/_internal/server/features/shared/listing-data-factory.js +16 -4
  30. package/dist/_internal/server/features/site-settings/adapters.d.ts +1 -1
  31. package/dist/_internal/server/features/site-settings/adapters.js +26 -0
  32. package/dist/_internal/server/features/sticker-trace/actions.d.ts +109 -0
  33. package/dist/_internal/server/features/sticker-trace/actions.js +172 -0
  34. package/dist/_internal/server/features/sticker-trace/adapters.d.ts +80 -0
  35. package/dist/_internal/server/features/sticker-trace/adapters.js +174 -0
  36. package/dist/_internal/server/features/sticker-trace/build-cut-file.d.ts +26 -0
  37. package/dist/_internal/server/features/sticker-trace/build-cut-file.js +127 -0
  38. package/dist/_internal/server/features/sticker-trace/coordinator.d.ts +27 -0
  39. package/dist/_internal/server/features/sticker-trace/coordinator.js +169 -0
  40. package/dist/_internal/server/features/sticker-trace/fanout.d.ts +43 -0
  41. package/dist/_internal/server/features/sticker-trace/fanout.js +180 -0
  42. package/dist/_internal/server/features/sticker-trace/finalizer.d.ts +25 -0
  43. package/dist/_internal/server/features/sticker-trace/finalizer.js +123 -0
  44. package/dist/_internal/server/features/sticker-trace/mosaic-inputs.d.ts +30 -0
  45. package/dist/_internal/server/features/sticker-trace/mosaic-inputs.js +112 -0
  46. package/dist/_internal/server/features/sticker-trace/progress.d.ts +81 -0
  47. package/dist/_internal/server/features/sticker-trace/progress.js +198 -0
  48. package/dist/_internal/server/features/sticker-trace/promote.d.ts +23 -0
  49. package/dist/_internal/server/features/sticker-trace/promote.js +193 -0
  50. package/dist/_internal/server/features/sticker-trace/shard.d.ts +50 -0
  51. package/dist/_internal/server/features/sticker-trace/shard.js +174 -0
  52. package/dist/_internal/server/features/sticker-trace/sheet-actions.d.ts +141 -0
  53. package/dist/_internal/server/features/sticker-trace/sheet-actions.js +279 -0
  54. package/dist/_internal/server/features/sticker-trace/storage.d.ts +135 -0
  55. package/dist/_internal/server/features/sticker-trace/storage.js +282 -0
  56. package/dist/_internal/server/functions/scheduled.d.ts +2 -1
  57. package/dist/_internal/server/functions/scheduled.js +25 -1
  58. package/dist/_internal/server/jobs/core/_event-ref.d.ts +51 -0
  59. package/dist/_internal/server/jobs/core/_event-ref.js +63 -0
  60. package/dist/_internal/server/jobs/core/assignSpinPrize.d.ts +18 -0
  61. package/dist/_internal/server/jobs/core/assignSpinPrize.js +77 -16
  62. package/dist/_internal/server/jobs/core/auctionSettlement.js +13 -4
  63. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +44 -15
  64. package/dist/_internal/server/jobs/core/bundleStockSync.js +3 -4
  65. package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +44 -0
  66. package/dist/_internal/server/jobs/core/event-draw-reasons.d.ts +78 -0
  67. package/dist/_internal/server/jobs/core/event-draw-reasons.js +133 -0
  68. package/dist/_internal/server/jobs/core/listingProcessor.js +28 -8
  69. package/dist/_internal/server/jobs/core/onOrderCreate.js +12 -1
  70. package/dist/_internal/server/jobs/core/onScamReportCreate.js +13 -2
  71. package/dist/_internal/server/jobs/core/onScamReportRejected.js +8 -2
  72. package/dist/_internal/server/jobs/core/onScamReportVerified.js +8 -2
  73. package/dist/_internal/server/jobs/core/onStoreWrite.js +11 -4
  74. package/dist/_internal/server/jobs/core/prizeDrawAssignWinner.js +5 -4
  75. package/dist/_internal/server/jobs/core/prizeDrawExpiryReveal.js +1 -4
  76. package/dist/_internal/server/jobs/core/prizeDrawSoldOutReveal.js +1 -2
  77. package/dist/_internal/server/jobs/core/promotions.js +7 -4
  78. package/dist/_internal/server/jobs/core/searchIndexBuild.d.ts +7 -0
  79. package/dist/_internal/server/jobs/core/searchIndexBuild.js +211 -0
  80. package/dist/_internal/server/jobs/core/triggerEventRaffle.d.ts +35 -0
  81. package/dist/_internal/server/jobs/core/triggerEventRaffle.js +213 -31
  82. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +20 -14
  83. package/dist/_internal/server/jobs/handlers/assignSpinPrize.d.ts +8 -0
  84. package/dist/_internal/server/jobs/handlers/assignSpinPrize.js +15 -15
  85. package/dist/_internal/server/jobs/handlers/index.d.ts +1 -0
  86. package/dist/_internal/server/jobs/handlers/index.js +1 -0
  87. package/dist/_internal/server/jobs/handlers/onCategoryWrite.js +18 -0
  88. package/dist/_internal/server/jobs/handlers/onProductWrite.js +18 -0
  89. package/dist/_internal/server/jobs/handlers/onReviewWrite.js +18 -0
  90. package/dist/_internal/server/jobs/handlers/onScamReportUpdate.js +18 -0
  91. package/dist/_internal/server/jobs/handlers/onStoreWrite.js +18 -0
  92. package/dist/_internal/server/jobs/handlers/searchIndexBuild.d.ts +2 -0
  93. package/dist/_internal/server/jobs/handlers/searchIndexBuild.js +2 -0
  94. package/dist/_internal/server/jobs/handlers/triggerEventRaffle.d.ts +8 -0
  95. package/dist/_internal/server/jobs/handlers/triggerEventRaffle.js +15 -6
  96. package/dist/_internal/shared/actions/action-registry.js +29 -0
  97. package/dist/_internal/shared/cache/revalidate-targets.d.ts +0 -1
  98. package/dist/_internal/shared/cache/revalidate-targets.js +10 -8
  99. package/dist/_internal/shared/features/events/config.d.ts +14 -0
  100. package/dist/_internal/shared/features/events/config.js +14 -0
  101. package/dist/_internal/shared/features/notifications/action-url.js +8 -0
  102. package/dist/_internal/shared/features/site-settings/types.d.ts +11 -0
  103. package/dist/_internal/shared/features/sticker-trace/codec.d.ts +81 -0
  104. package/dist/_internal/shared/features/sticker-trace/codec.js +30 -0
  105. package/dist/_internal/shared/features/sticker-trace/config.d.ts +81 -0
  106. package/dist/_internal/shared/features/sticker-trace/config.js +177 -0
  107. package/dist/_internal/shared/features/sticker-trace/cut-contour.d.ts +20 -0
  108. package/dist/_internal/shared/features/sticker-trace/cut-contour.js +60 -0
  109. package/dist/_internal/shared/features/sticker-trace/export/build-export-set.d.ts +65 -0
  110. package/dist/_internal/shared/features/sticker-trace/export/build-export-set.js +176 -0
  111. package/dist/_internal/shared/features/sticker-trace/export/cut-svg.d.ts +56 -0
  112. package/dist/_internal/shared/features/sticker-trace/export/cut-svg.js +120 -0
  113. package/dist/_internal/shared/features/sticker-trace/export/machine-profiles.d.ts +92 -0
  114. package/dist/_internal/shared/features/sticker-trace/export/machine-profiles.js +153 -0
  115. package/dist/_internal/shared/features/sticker-trace/export/nesting.d.ts +51 -0
  116. package/dist/_internal/shared/features/sticker-trace/export/nesting.js +110 -0
  117. package/dist/_internal/shared/features/sticker-trace/export/page-sizes.d.ts +68 -0
  118. package/dist/_internal/shared/features/sticker-trace/export/page-sizes.js +223 -0
  119. package/dist/_internal/shared/features/sticker-trace/export/part-tiling.d.ts +51 -0
  120. package/dist/_internal/shared/features/sticker-trace/export/part-tiling.js +178 -0
  121. package/dist/_internal/shared/features/sticker-trace/export/simplify-budget.d.ts +26 -0
  122. package/dist/_internal/shared/features/sticker-trace/export/simplify-budget.js +134 -0
  123. package/dist/_internal/shared/features/sticker-trace/export/vectorise-art.d.ts +40 -0
  124. package/dist/_internal/shared/features/sticker-trace/export/vectorise-art.js +195 -0
  125. package/dist/_internal/shared/features/sticker-trace/index.d.ts +2 -0
  126. package/dist/_internal/shared/features/sticker-trace/index.js +59 -0
  127. package/dist/_internal/shared/features/sticker-trace/math/catmull-rom.d.ts +11 -0
  128. package/dist/_internal/shared/features/sticker-trace/math/catmull-rom.js +66 -0
  129. package/dist/_internal/shared/features/sticker-trace/math/edt.d.ts +27 -0
  130. package/dist/_internal/shared/features/sticker-trace/math/edt.js +165 -0
  131. package/dist/_internal/shared/features/sticker-trace/math/label.d.ts +15 -0
  132. package/dist/_internal/shared/features/sticker-trace/math/label.js +156 -0
  133. package/dist/_internal/shared/features/sticker-trace/math/marching-squares.d.ts +16 -0
  134. package/dist/_internal/shared/features/sticker-trace/math/marching-squares.js +242 -0
  135. package/dist/_internal/shared/features/sticker-trace/math/morphology.d.ts +46 -0
  136. package/dist/_internal/shared/features/sticker-trace/math/morphology.js +168 -0
  137. package/dist/_internal/shared/features/sticker-trace/math/rasterize-path.d.ts +88 -0
  138. package/dist/_internal/shared/features/sticker-trace/math/rasterize-path.js +286 -0
  139. package/dist/_internal/shared/features/sticker-trace/math/rdp.d.ts +10 -0
  140. package/dist/_internal/shared/features/sticker-trace/math/rdp.js +74 -0
  141. package/dist/_internal/shared/features/sticker-trace/resume.d.ts +50 -0
  142. package/dist/_internal/shared/features/sticker-trace/resume.js +160 -0
  143. package/dist/_internal/shared/features/sticker-trace/trace/cluster.d.ts +20 -0
  144. package/dist/_internal/shared/features/sticker-trace/trace/cluster.js +132 -0
  145. package/dist/_internal/shared/features/sticker-trace/trace/cross-profile.d.ts +28 -0
  146. package/dist/_internal/shared/features/sticker-trace/trace/cross-profile.js +120 -0
  147. package/dist/_internal/shared/features/sticker-trace/trace/flood.d.ts +21 -0
  148. package/dist/_internal/shared/features/sticker-trace/trace/flood.js +104 -0
  149. package/dist/_internal/shared/features/sticker-trace/trace/geometry.d.ts +3 -0
  150. package/dist/_internal/shared/features/sticker-trace/trace/geometry.js +140 -0
  151. package/dist/_internal/shared/features/sticker-trace/trace/line-filter.d.ts +15 -0
  152. package/dist/_internal/shared/features/sticker-trace/trace/line-filter.js +138 -0
  153. package/dist/_internal/shared/features/sticker-trace/trace/merge.d.ts +27 -0
  154. package/dist/_internal/shared/features/sticker-trace/trace/merge.js +187 -0
  155. package/dist/_internal/shared/features/sticker-trace/trace/paper.d.ts +32 -0
  156. package/dist/_internal/shared/features/sticker-trace/trace/paper.js +147 -0
  157. package/dist/_internal/shared/features/sticker-trace/trace/prefilter.d.ts +30 -0
  158. package/dist/_internal/shared/features/sticker-trace/trace/prefilter.js +125 -0
  159. package/dist/_internal/shared/features/sticker-trace/trace/quantise.d.ts +10 -0
  160. package/dist/_internal/shared/features/sticker-trace/trace/quantise.js +153 -0
  161. package/dist/_internal/shared/features/sticker-trace/trace/ridge.d.ts +88 -0
  162. package/dist/_internal/shared/features/sticker-trace/trace/ridge.js +344 -0
  163. package/dist/_internal/shared/features/sticker-trace/trace/segment.d.ts +10 -0
  164. package/dist/_internal/shared/features/sticker-trace/trace/segment.js +251 -0
  165. package/dist/_internal/shared/features/sticker-trace/types.d.ts +197 -0
  166. package/dist/_internal/shared/features/sticker-trace/types.js +49 -0
  167. package/dist/_internal/shared/listing-types/_registry.d.ts +11 -0
  168. package/dist/_internal/shared/listing-types/art/config.d.ts +1 -0
  169. package/dist/_internal/shared/listing-types/art/config.js +1 -0
  170. package/dist/_internal/shared/listing-types/auction/config.d.ts +1 -0
  171. package/dist/_internal/shared/listing-types/auction/config.js +1 -0
  172. package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -0
  173. package/dist/_internal/shared/listing-types/classified/config.js +1 -0
  174. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -0
  175. package/dist/_internal/shared/listing-types/digital-code/config.js +1 -0
  176. package/dist/_internal/shared/listing-types/feature-flags.d.ts +7 -0
  177. package/dist/_internal/shared/listing-types/feature-flags.js +9 -0
  178. package/dist/_internal/shared/listing-types/live/config.d.ts +1 -0
  179. package/dist/_internal/shared/listing-types/live/config.js +1 -0
  180. package/dist/_internal/shared/listing-types/pre-order/config.d.ts +1 -0
  181. package/dist/_internal/shared/listing-types/pre-order/config.js +1 -0
  182. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -0
  183. package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -0
  184. package/dist/_internal/shared/listing-types/standard/config.d.ts +1 -0
  185. package/dist/_internal/shared/listing-types/standard/config.js +1 -0
  186. package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -0
  187. package/dist/_internal/shared/listing-types/stickers/config.js +1 -0
  188. package/dist/_internal/shared/media/limits.d.ts +12 -2
  189. package/dist/_internal/shared/media/limits.js +12 -2
  190. package/dist/_internal/shared/search/artifact-url.d.ts +35 -0
  191. package/dist/_internal/shared/search/artifact-url.js +119 -0
  192. package/dist/_internal/shared/search/index-record.d.ts +68 -0
  193. package/dist/_internal/shared/search/index-record.js +96 -0
  194. package/dist/_internal/shared/search/match.d.ts +65 -0
  195. package/dist/_internal/shared/search/match.js +263 -0
  196. package/dist/client.d.ts +8 -7
  197. package/dist/client.js +12 -5
  198. package/dist/configs/eslint.js +22 -2
  199. package/dist/constants/api-endpoints.d.ts +68 -0
  200. package/dist/constants/api-endpoints.js +32 -0
  201. package/dist/constants/field-names.d.ts +7 -1
  202. package/dist/constants/field-names.js +36 -1
  203. package/dist/contracts/repository.d.ts +8 -7
  204. package/dist/contracts/search.d.ts +2 -2
  205. package/dist/contracts/table.d.ts +3 -3
  206. package/dist/contracts/table.js +3 -3
  207. package/dist/core/contact-submissions.repository.js +2 -2
  208. package/dist/core/integration-keys.js +7 -1
  209. package/dist/core/newsletter.repository.js +2 -2
  210. package/dist/core/site-config.js +1 -1
  211. package/dist/errors/error-codes.d.ts +30 -0
  212. package/dist/errors/error-codes.js +30 -0
  213. package/dist/errors/error-display-map.js +40 -1
  214. package/dist/features/account/api/[userId]/addresses/route.js +1 -1
  215. package/dist/features/account/components/UserBidsView.js +1 -1
  216. package/dist/features/account/components/index.d.ts +0 -8
  217. package/dist/features/account/components/index.js +0 -4
  218. package/dist/features/addresses/repository/addresses.repository.d.ts +17 -6
  219. package/dist/features/addresses/repository/addresses.repository.js +65 -9
  220. package/dist/features/addresses/schemas/firestore.d.ts +17 -6
  221. package/dist/features/admin/actions/notification-actions.js +15 -6
  222. package/dist/features/admin/api/bids/route.js +1 -1
  223. package/dist/features/admin/api/coupons/route.js +1 -1
  224. package/dist/features/admin/api/products/route.js +1 -1
  225. package/dist/features/admin/api/reviews/route.js +1 -1
  226. package/dist/features/admin/components/AdminAdEditorView.js +19 -5
  227. package/dist/features/admin/components/AdminAuditLogView.js +1 -1
  228. package/dist/features/admin/components/AdminBlogEditorView.js +0 -1
  229. package/dist/features/admin/components/AdminBlogView.js +1 -1
  230. package/dist/features/admin/components/AdminBrandsView.js +17 -1
  231. package/dist/features/admin/components/AdminCategoryEditorView.js +0 -1
  232. package/dist/features/admin/components/AdminContactView.js +1 -1
  233. package/dist/features/admin/components/AdminEmployeeEditorView.js +1 -3
  234. package/dist/features/admin/components/AdminNewsletterView.js +1 -1
  235. package/dist/features/admin/components/AdminOrdersView.js +9 -2
  236. package/dist/features/admin/components/AdminPayoutsView.js +1 -1
  237. package/dist/features/admin/components/AdminPrizeDrawsView.js +11 -0
  238. package/dist/features/admin/components/AdminProductEditorView.d.ts +10 -1
  239. package/dist/features/admin/components/AdminProductEditorView.js +24 -37
  240. package/dist/features/admin/components/AdminProductsView.js +10 -3
  241. package/dist/features/admin/components/AdminScammersView.js +1 -1
  242. package/dist/features/admin/components/AdminSectionsView.js +21 -5
  243. package/dist/features/admin/components/AdminSessionsView.js +1 -1
  244. package/dist/features/admin/components/AdminSublistingCategoriesView.js +22 -1
  245. package/dist/features/admin/components/AdminTeamView.js +1 -1
  246. package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +0 -1
  247. package/dist/features/admin/components/AdminUsersView.js +1 -1
  248. package/dist/features/admin/components/DataListingView.d.ts +2 -1
  249. package/dist/features/admin/components/DataListingView.js +9 -4
  250. package/dist/features/admin/components/analytics/AdminPageViewsReportView.js +0 -2
  251. package/dist/features/admin/hooks/useAdminListing.d.ts +1 -1
  252. package/dist/features/admin/repository/site-settings.repository.js +8 -3
  253. package/dist/features/admin/schemas/firestore.d.ts +62 -1
  254. package/dist/features/admin/schemas/firestore.js +32 -0
  255. package/dist/features/admin/types/index.d.ts +1 -1
  256. package/dist/features/auctions/actions/bid-actions.d.ts +2 -2
  257. package/dist/features/auctions/actions/bid-actions.js +16 -4
  258. package/dist/features/auctions/api/route.js +1 -1
  259. package/dist/features/auctions/components/AuctionBottomActions.js +4 -0
  260. package/dist/features/auctions/repository/bid.repository.d.ts +46 -4
  261. package/dist/features/auctions/repository/bid.repository.js +114 -13
  262. package/dist/features/auctions/schemas/firestore.d.ts +24 -4
  263. package/dist/features/auctions/schemas/firestore.js +1 -0
  264. package/dist/features/auth/actions/profile-actions.js +30 -4
  265. package/dist/features/auth/components/index.d.ts +0 -1
  266. package/dist/features/auth/components/index.js +0 -1
  267. package/dist/features/auth/repository/session.repository.d.ts +17 -3
  268. package/dist/features/auth/repository/session.repository.js +46 -5
  269. package/dist/features/auth/repository/token.repository.d.ts +27 -4
  270. package/dist/features/auth/repository/token.repository.js +65 -11
  271. package/dist/features/auth/repository/user.repository.d.ts +33 -7
  272. package/dist/features/auth/repository/user.repository.js +100 -15
  273. package/dist/features/auth/schemas/firestore.d.ts +63 -12
  274. package/dist/features/auth/schemas/firestore.js +11 -0
  275. package/dist/features/before-after/api/route.js +1 -1
  276. package/dist/features/blog/components/BlogListView.js +16 -3
  277. package/dist/features/blog/components/BlogPostView.js +1 -1
  278. package/dist/features/blog/schemas/index.d.ts +2 -2
  279. package/dist/features/cart/api/route.js +1 -1
  280. package/dist/features/catalogue/repository/catalogue.repository.d.ts +7 -7
  281. package/dist/features/catalogue/repository/catalogue.repository.js +28 -10
  282. package/dist/features/catalogue/schemas/firestore.d.ts +11 -0
  283. package/dist/features/categories/api/route.js +10 -10
  284. package/dist/features/categories/components/CategoryDetailPageView.js +35 -5
  285. package/dist/features/categories/components/CategorySelectorCreate.js +0 -1
  286. package/dist/features/categories/components/index.d.ts +0 -2
  287. package/dist/features/categories/components/index.js +0 -1
  288. package/dist/features/categories/repository/categories.repository.d.ts +1 -0
  289. package/dist/features/categories/repository/categories.repository.js +31 -1
  290. package/dist/features/categories/schemas/index.d.ts +2 -2
  291. package/dist/features/categories/utils/taxonomy-visual.d.ts +21 -0
  292. package/dist/features/categories/utils/taxonomy-visual.js +58 -0
  293. package/dist/features/checkout/actions/checkout-value-otp-actions.js +8 -1
  294. package/dist/features/collections/api/[slug]/route.js +3 -3
  295. package/dist/features/collections/api/route.js +1 -1
  296. package/dist/features/consultation/api/route.js +1 -1
  297. package/dist/features/consultation/repository/consultations.repository.js +1 -1
  298. package/dist/features/consultation/types/index.d.ts +1 -1
  299. package/dist/features/contact/components/ContactForm.js +1 -3
  300. package/dist/features/corporate/api/route.js +1 -1
  301. package/dist/features/corporate/repository/corporate.repository.js +1 -1
  302. package/dist/features/corporate/types/index.d.ts +1 -1
  303. package/dist/features/cron/jobs/auction-expiry.job.js +1 -1
  304. package/dist/features/cron/jobs/preorder-reminder.job.js +1 -1
  305. package/dist/features/events/actions/event-actions.d.ts +14 -0
  306. package/dist/features/events/actions/event-actions.js +82 -3
  307. package/dist/features/events/api/[id]/route.js +2 -2
  308. package/dist/features/events/components/AdminEventEditorView.js +22 -3
  309. package/dist/features/events/components/AdminEventsView.js +32 -8
  310. package/dist/features/events/components/EventRafflesSection.d.ts +34 -1
  311. package/dist/features/events/components/EventRafflesSection.js +52 -3
  312. package/dist/features/events/components/SpinWheelView.d.ts +2 -2
  313. package/dist/features/events/components/SpinWheelView.js +41 -4
  314. package/dist/features/events/repository/event-entry.repository.d.ts +14 -2
  315. package/dist/features/events/repository/event-entry.repository.js +41 -7
  316. package/dist/features/events/schemas/firestore.d.ts +17 -4
  317. package/dist/features/events/types/index.d.ts +37 -0
  318. package/dist/features/faq/repository/faqs.repository.js +1 -1
  319. package/dist/features/faq/schemas/index.d.ts +5 -2
  320. package/dist/features/faq/schemas/index.js +6 -0
  321. package/dist/features/faq/types/index.d.ts +0 -1
  322. package/dist/features/grouped/components/GroupedListingEditorView.js +17 -2
  323. package/dist/features/homepage/api/carousel/[id]/route.js +1 -1
  324. package/dist/features/homepage/api/carousel/route.js +4 -4
  325. package/dist/features/homepage/api/route.js +2 -2
  326. package/dist/features/homepage/api/sections/route.js +1 -1
  327. package/dist/features/homepage/components/AnnouncementBar.d.ts +1 -9
  328. package/dist/features/homepage/components/AnnouncementBar.js +13 -19
  329. package/dist/features/homepage/components/MarketplaceHomepageView.js +6 -1
  330. package/dist/features/homepage/components/index.d.ts +0 -2
  331. package/dist/features/homepage/components/index.js +0 -1
  332. package/dist/features/homepage/repository/homepage.repository.js +1 -1
  333. package/dist/features/homepage/schemas/firestore.d.ts +6 -0
  334. package/dist/features/homepage/schemas/index.d.ts +10 -10
  335. package/dist/features/layout/AppLayoutShell.d.ts +12 -3
  336. package/dist/features/layout/AppLayoutShell.js +65 -13
  337. package/dist/features/layout/BottomActionsContext.d.ts +16 -0
  338. package/dist/features/layout/BottomActionsContext.js +5 -0
  339. package/dist/features/layout/BottomChrome.js +48 -9
  340. package/dist/features/layout/BottomNavbar.d.ts +14 -0
  341. package/dist/features/layout/BottomNavbar.js +43 -3
  342. package/dist/features/layout/MainNavbar.d.ts +11 -0
  343. package/dist/features/layout/NavbarLayout.d.ts +3 -0
  344. package/dist/features/layout/NavbarLayout.js +88 -11
  345. package/dist/features/layout/SideActionDock.d.ts +1 -0
  346. package/dist/features/layout/SideActionDock.js +219 -0
  347. package/dist/features/layout/TitleBarLayout.d.ts +1 -3
  348. package/dist/features/layout/TitleBarLayout.js +3 -4
  349. package/dist/features/layout/cta-anchor.d.ts +31 -0
  350. package/dist/features/layout/cta-anchor.js +31 -0
  351. package/dist/features/layout/hooks/useBottomActions.d.ts +7 -0
  352. package/dist/features/layout/hooks/useBottomActions.js +6 -1
  353. package/dist/features/layout/index.d.ts +9 -1
  354. package/dist/features/layout/index.js +9 -1
  355. package/dist/features/layout/useCtaReveal.d.ts +24 -0
  356. package/dist/features/layout/useCtaReveal.js +82 -0
  357. package/dist/features/layout/useHoldToOpen.d.ts +41 -0
  358. package/dist/features/layout/useHoldToOpen.js +84 -0
  359. package/dist/features/lottery/repository/lottery-entry.repository.d.ts +18 -3
  360. package/dist/features/lottery/repository/lottery-entry.repository.js +48 -6
  361. package/dist/features/lottery/schemas/firestore.d.ts +33 -5
  362. package/dist/features/loyalty/api/balance/route.js +1 -1
  363. package/dist/features/loyalty/api/history/route.js +1 -1
  364. package/dist/features/media/MediaImage.js +0 -1
  365. package/dist/features/media/MediaPickerModal.js +7 -1
  366. package/dist/features/media/modals/ImageEditor.js +5 -1
  367. package/dist/features/media/modals/VideoThumbnailSelector.js +17 -1
  368. package/dist/features/media/repository/media-assets.repository.d.ts +19 -0
  369. package/dist/features/media/upload/CameraCapture.js +16 -1
  370. package/dist/features/media/upload/ImageUpload.js +42 -4
  371. package/dist/features/media/upload/MediaUploadField.js +69 -13
  372. package/dist/features/media/upload/downscale-image.d.ts +56 -0
  373. package/dist/features/media/upload/downscale-image.js +150 -0
  374. package/dist/features/messages/components/ConversationThreadView.js +45 -2
  375. package/dist/features/messages/components/MessageSellerButton.d.ts +15 -1
  376. package/dist/features/messages/components/MessageSellerButton.js +10 -2
  377. package/dist/features/messages/schemas/firestore.d.ts +15 -0
  378. package/dist/features/orders/hooks/useOrders.js +4 -2
  379. package/dist/features/orders/repository/orders.repository.d.ts +15 -4
  380. package/dist/features/orders/repository/orders.repository.js +52 -20
  381. package/dist/features/orders/schemas/firestore.d.ts +15 -4
  382. package/dist/features/orders/schemas/index.d.ts +8 -8
  383. package/dist/features/orders/types/index.d.ts +2 -2
  384. package/dist/features/payments/repository/payments.repository.js +2 -2
  385. package/dist/features/payments/repository/payout.repository.d.ts +23 -6
  386. package/dist/features/payments/repository/payout.repository.js +63 -23
  387. package/dist/features/payments/repository/saved-payment-methods.repository.d.ts +17 -6
  388. package/dist/features/payments/repository/saved-payment-methods.repository.js +59 -11
  389. package/dist/features/payments/schemas/firestore.d.ts +14 -3
  390. package/dist/features/payments/schemas/saved-methods-firestore.d.ts +12 -1
  391. package/dist/features/pre-orders/api/[slug]/route.js +1 -1
  392. package/dist/features/pre-orders/api/admin/route.js +1 -1
  393. package/dist/features/pre-orders/api/route.js +1 -1
  394. package/dist/features/pre-orders/repository/pre-orders.repository.d.ts +3 -3
  395. package/dist/features/pre-orders/repository/pre-orders.repository.js +6 -6
  396. package/dist/features/products/api/[id]/route.js +1 -1
  397. package/dist/features/products/components/ListingBottomActions.js +4 -0
  398. package/dist/features/products/components/ProductDetailPageView.js +2 -1
  399. package/dist/features/products/components/ProductGalleryClient.js +2 -2
  400. package/dist/features/products/components/ProductGrid.js +12 -1
  401. package/dist/features/products/components/index.d.ts +0 -2
  402. package/dist/features/products/components/index.js +0 -1
  403. package/dist/features/products/config/listing-type-listing-config.d.ts +0 -3
  404. package/dist/features/products/config/listing-type-listing-config.js +27 -2
  405. package/dist/features/products/constants/listing-tabs.d.ts +9 -0
  406. package/dist/features/products/constants/listing-tabs.js +3 -2
  407. package/dist/features/products/hooks/useProducts.js +2 -2
  408. package/dist/features/products/repository/products.repository.js +13 -1
  409. package/dist/features/products/schemas/index.d.ts +2 -2
  410. package/dist/features/products/types/index.d.ts +1 -1
  411. package/dist/features/promotions/api/route.js +1 -1
  412. package/dist/features/reviews/actions/review-actions.d.ts +6 -6
  413. package/dist/features/reviews/actions/review-actions.js +22 -8
  414. package/dist/features/reviews/components/ReviewDetailPageView.js +13 -1
  415. package/dist/features/reviews/components/ReviewsIndexPageView.js +21 -4
  416. package/dist/features/reviews/repository/reviews.repository.d.ts +19 -7
  417. package/dist/features/reviews/repository/reviews.repository.js +63 -12
  418. package/dist/features/reviews/schemas/firestore.d.ts +13 -2
  419. package/dist/features/reviews/schemas/index.d.ts +2 -2
  420. package/dist/features/scams/actions/scam-actions.js +16 -4
  421. package/dist/features/search/components/SearchResultsPageView.js +2 -1
  422. package/dist/features/search/hooks/useSearchIndex.d.ts +34 -0
  423. package/dist/features/search/hooks/useSearchIndex.js +172 -0
  424. package/dist/features/search/repository/search.repository.js +2 -2
  425. package/dist/features/seller/actions/offer-actions.d.ts +5 -5
  426. package/dist/features/seller/actions/offer-actions.js +38 -8
  427. package/dist/features/seller/actions/seller-actions.js +34 -7
  428. package/dist/features/seller/api/coupons/route.js +1 -1
  429. package/dist/features/seller/api/products/route.js +1 -1
  430. package/dist/features/seller/api/store/route.js +1 -1
  431. package/dist/features/seller/components/SellerBidsView.js +1 -1
  432. package/dist/features/seller/components/SellerCouponsView.js +1 -1
  433. package/dist/features/seller/components/SellerListingTypeView.js +9 -1
  434. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  435. package/dist/features/seller/components/SellerPayoutSettingsView.js +0 -1
  436. package/dist/features/seller/components/SellerPayoutsView.js +1 -1
  437. package/dist/features/seller/components/SellerProductShell.js +0 -1
  438. package/dist/features/seller/components/SellerProductsView.js +1 -1
  439. package/dist/features/seller/components/SellerShippingView.js +0 -1
  440. package/dist/features/seller/components/SellerStorefrontView.js +0 -1
  441. package/dist/features/seller/components/index.d.ts +0 -4
  442. package/dist/features/seller/components/index.js +0 -2
  443. package/dist/features/seller/repository/offer.repository.d.ts +15 -3
  444. package/dist/features/seller/repository/offer.repository.js +43 -7
  445. package/dist/features/seller/schemas/firestore.d.ts +14 -3
  446. package/dist/features/seller/schemas/index.d.ts +4 -4
  447. package/dist/features/seller/schemas/order-forms.d.ts +39 -0
  448. package/dist/features/seller/schemas/order-forms.js +37 -0
  449. package/dist/features/shell/FormShell.js +6 -2
  450. package/dist/features/shell/QuickFormDrawer.js +15 -1
  451. package/dist/features/shipments/components/AdminShipmentEditorView.js +0 -1
  452. package/dist/features/shipments/components/AdminShipmentsView.js +1 -1
  453. package/dist/features/sticker-trace/components/StickerCommitPanel.d.ts +30 -0
  454. package/dist/features/sticker-trace/components/StickerCommitPanel.js +93 -0
  455. package/dist/features/sticker-trace/components/StickerPrintPanel.d.ts +33 -0
  456. package/dist/features/sticker-trace/components/StickerPrintPanel.js +104 -0
  457. package/dist/features/sticker-trace/components/StickerRetryPanel.d.ts +20 -0
  458. package/dist/features/sticker-trace/components/StickerRetryPanel.js +128 -0
  459. package/dist/features/sticker-trace/components/StickerRunHistoryPanel.d.ts +45 -0
  460. package/dist/features/sticker-trace/components/StickerRunHistoryPanel.js +84 -0
  461. package/dist/features/sticker-trace/components/StickerTraceStudio.d.ts +27 -0
  462. package/dist/features/sticker-trace/components/StickerTraceStudio.js +171 -0
  463. package/dist/features/sticker-trace/constants/help-content.d.ts +23 -0
  464. package/dist/features/sticker-trace/constants/help-content.js +172 -0
  465. package/dist/features/sticker-trace/hooks/useLiveTrace.d.ts +27 -0
  466. package/dist/features/sticker-trace/hooks/useLiveTrace.js +160 -0
  467. package/dist/features/sticker-trace/hooks/useStickerTraceProgress.d.ts +22 -0
  468. package/dist/features/sticker-trace/hooks/useStickerTraceProgress.js +106 -0
  469. package/dist/features/sticker-trace/repository/sticker-sheets.repository.d.ts +113 -0
  470. package/dist/features/sticker-trace/repository/sticker-sheets.repository.js +146 -0
  471. package/dist/features/sticker-trace/repository/sticker-trace-runs.repository.d.ts +132 -0
  472. package/dist/features/sticker-trace/repository/sticker-trace-runs.repository.js +174 -0
  473. package/dist/features/sticker-trace/schemas/firestore.d.ts +248 -0
  474. package/dist/features/sticker-trace/schemas/firestore.js +79 -0
  475. package/dist/features/sticker-trace/server.d.ts +8 -0
  476. package/dist/features/sticker-trace/server.js +51 -0
  477. package/dist/features/stores/actions/store-query-actions.d.ts +2 -2
  478. package/dist/features/stores/actions/store-query-actions.js +7 -2
  479. package/dist/features/stores/api/[storeSlug]/auctions/route.js +3 -3
  480. package/dist/features/stores/api/[storeSlug]/products/route.js +3 -3
  481. package/dist/features/stores/api/[storeSlug]/reviews/route.js +1 -1
  482. package/dist/features/stores/api/[storeSlug]/route.js +1 -1
  483. package/dist/features/stores/components/StoreNavTabs.js +17 -2
  484. package/dist/features/stores/manifest.js +8 -4
  485. package/dist/features/support/repository/support.repository.d.ts +14 -3
  486. package/dist/features/support/repository/support.repository.js +93 -13
  487. package/dist/features/support/schemas/firestore.d.ts +16 -5
  488. package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.js +61 -19
  489. package/dist/features/tester/seed-data/authored/buying__browsing-search.js +19 -3
  490. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.d.ts +2 -0
  491. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +243 -0
  492. package/dist/features/tester/seed-data/authored/content-discovery__events.js +36 -10
  493. package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.d.ts +2 -0
  494. package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.js +209 -0
  495. package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.d.ts +2 -0
  496. package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.js +90 -0
  497. package/dist/features/tester/seed-data/authored/design-ux__header-controls-and-messages.d.ts +2 -0
  498. package/dist/features/tester/seed-data/authored/design-ux__header-controls-and-messages.js +85 -0
  499. package/dist/features/tester/seed-data/authored/index.js +10 -0
  500. package/dist/features/tester/seed-data/authored/selling__media-limits.js +19 -17
  501. package/dist/features/tester/seed-data/authored/selling__product-upload-details.js +10 -5
  502. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.d.ts +2 -0
  503. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.js +283 -0
  504. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +235 -22
  505. package/dist/index.d.ts +10 -23
  506. package/dist/index.js +27 -19
  507. package/dist/next/api/routeHandler.js +9 -0
  508. package/dist/next/routing/require-record.d.ts +13 -0
  509. package/dist/next/routing/require-record.js +62 -0
  510. package/dist/next/routing/route-map.d.ts +4 -4
  511. package/dist/next/routing/route-map.js +25 -3
  512. package/dist/providers/db-firebase/base.d.ts +4 -2
  513. package/dist/providers/db-firebase/base.js +21 -5
  514. package/dist/providers/db-firebase/base.repository.d.ts +11 -9
  515. package/dist/providers/db-firebase/base.repository.js +19 -0
  516. package/dist/providers/db-firebase/rtdb-paths.d.ts +12 -0
  517. package/dist/providers/db-firebase/rtdb-paths.js +12 -0
  518. package/dist/react/ErrorBoundary.js +6 -1
  519. package/dist/react/hooks/realtime-event-constants.d.ts +1 -0
  520. package/dist/react/hooks/realtime-event-constants.js +8 -0
  521. package/dist/react/hooks/useEntityDelete.js +5 -1
  522. package/dist/react/hooks/useMessage.js +5 -1
  523. package/dist/repositories/index.d.ts +2 -2
  524. package/dist/repositories/index.js +6 -1
  525. package/dist/schemas/registry.d.ts +13 -20
  526. package/dist/schemas/registry.js +31 -14
  527. package/dist/schemas/webhooks/google-oauth.d.ts +2 -2
  528. package/dist/security/encrypted.d.ts +117 -0
  529. package/dist/security/encrypted.js +100 -0
  530. package/dist/security/index.d.ts +5 -2
  531. package/dist/security/index.js +16 -2
  532. package/dist/security/pii-accessors.d.ts +71 -0
  533. package/dist/security/pii-accessors.js +150 -0
  534. package/dist/security/pii-encrypt.d.ts +0 -8
  535. package/dist/security/pii-encrypt.js +22 -15
  536. package/dist/security/pii-mask.d.ts +18 -0
  537. package/dist/security/pii-mask.js +27 -0
  538. package/dist/seed/_helpers/search-txt-wrappers.d.ts +6 -6
  539. package/dist/seed/_helpers/search-txt-wrappers.js +22 -0
  540. package/dist/seed/addresses-seed-data.d.ts +2 -2
  541. package/dist/seed/authenticity-knowledge-seed-data.d.ts +34 -0
  542. package/dist/seed/authenticity-knowledge-seed-data.js +1277 -0
  543. package/dist/seed/bids-seed-data.d.ts +2 -2
  544. package/dist/seed/bids-seed-data.js +23 -2
  545. package/dist/seed/events-seed-data.d.ts +2 -2
  546. package/dist/seed/events-seed-data.js +5 -0
  547. package/dist/seed/faq-seed-data.js +175 -5
  548. package/dist/seed/homepage-sections-seed-data.js +39 -23
  549. package/dist/seed/index.d.ts +1 -0
  550. package/dist/seed/index.js +1 -0
  551. package/dist/seed/lottery-entries-seed-data.d.ts +2 -2
  552. package/dist/seed/offers-seed-data.d.ts +2 -2
  553. package/dist/seed/offers-seed-data.js +1 -1
  554. package/dist/seed/orders-seed-data.d.ts +2 -2
  555. package/dist/seed/payouts-seed-data.d.ts +2 -2
  556. package/dist/seed/payouts-seed-data.js +1 -1
  557. package/dist/seed/reviews-seed-data.d.ts +1 -2
  558. package/dist/seed/seed-purpose.js +7 -0
  559. package/dist/seed/sessions-seed-data.d.ts +2 -2
  560. package/dist/seed/sessions-seed-data.js +5 -0
  561. package/dist/seed/site-settings-seed-data.js +1 -1
  562. package/dist/seed/support-tickets-seed-data.d.ts +2 -2
  563. package/dist/seed/support-tickets-seed-data.js +1 -1
  564. package/dist/seed/users-seed-data.d.ts +2 -2
  565. package/dist/seed/users-seed-data.js +1 -1
  566. package/dist/seo/json-ld.js +5 -1
  567. package/dist/server.d.ts +18 -3
  568. package/dist/server.js +59 -3
  569. package/dist/styles.css +237 -1
  570. package/dist/tailwind-utilities.css +1 -1
  571. package/dist/ui/components/Button.js +7 -1
  572. package/dist/ui/components/FilterChipGroup.d.ts +11 -0
  573. package/dist/ui/components/FilterChipGroup.js +1 -1
  574. package/dist/ui/components/ImageGallery.js +6 -1
  575. package/dist/ui/components/ListingLayout.js +14 -8
  576. package/dist/ui/components/OverflowRow.d.ts +92 -0
  577. package/dist/ui/components/OverflowRow.js +203 -0
  578. package/dist/ui/components/OverflowRow.style.css +235 -0
  579. package/dist/ui/components/RecordDetailModal.js +14 -1
  580. package/dist/ui/components/RowActionMenu.js +5 -1
  581. package/dist/ui/components/SideDrawer.js +5 -1
  582. package/dist/ui/components/SideModal.js +9 -1
  583. package/dist/ui/components/TabBarShell.d.ts +12 -1
  584. package/dist/ui/components/TabBarShell.js +3 -2
  585. package/dist/ui/components/Tabs.js +36 -24
  586. package/dist/ui/components/Toast.d.ts +3 -24
  587. package/dist/ui/components/Toast.js +2 -19
  588. package/dist/ui/components/TopBannerPortal.d.ts +15 -0
  589. package/dist/ui/components/TopBannerPortal.js +19 -0
  590. package/dist/ui/components/UnsavedChangesModal.js +5 -1
  591. package/dist/ui/components/index.style.css +1 -0
  592. package/dist/ui/components/row-collapse.d.ts +15 -0
  593. package/dist/ui/components/row-collapse.js +127 -0
  594. package/dist/ui/components/toast-context.d.ts +63 -0
  595. package/dist/ui/components/toast-context.js +48 -0
  596. package/dist/ui/components/top-banner-slot.d.ts +37 -0
  597. package/dist/ui/components/top-banner-slot.js +45 -0
  598. package/dist/ui/icons/icon-registry.d.ts +6 -0
  599. package/dist/ui/icons/icon-registry.js +17 -1
  600. package/dist/ui/index.d.ts +2 -0
  601. package/dist/ui/index.js +1 -0
  602. package/dist/utils/array.helper.d.ts +2 -2
  603. package/dist/utils/array.helper.js +5 -5
  604. package/dist/utils/id-generators.d.ts +6 -0
  605. package/dist/utils/id-generators.js +10 -0
  606. package/dist/utils/media-url.js +0 -2
  607. package/dist/utils/search-txt-builders.d.ts +28 -4
  608. package/dist/utils/search-txt-builders.js +41 -1
  609. package/dist/validation/schemas.d.ts +8 -8
  610. package/package.json +6 -2
  611. package/scripts/seed-cli.mjs +3 -0
  612. package/dist/features/account/components/UserAddressesView.d.ts +0 -13
  613. package/dist/features/account/components/UserAddressesView.js +0 -5
  614. package/dist/features/account/components/UserNotificationsView.d.ts +0 -15
  615. package/dist/features/account/components/UserNotificationsView.js +0 -12
  616. package/dist/features/account/components/UserSettingsView.d.ts +0 -16
  617. package/dist/features/account/components/UserSettingsView.js +0 -13
  618. package/dist/features/account/components/UserSupportView.d.ts +0 -3
  619. package/dist/features/account/components/UserSupportView.js +0 -166
  620. package/dist/features/admin/components/DemoSeedView.d.ts +0 -11
  621. package/dist/features/admin/components/DemoSeedView.js +0 -5
  622. package/dist/features/auth/components/AuthStatusPanel.d.ts +0 -10
  623. package/dist/features/auth/components/AuthStatusPanel.js +0 -22
  624. package/dist/features/categories/components/CategoryProductsView.d.ts +0 -45
  625. package/dist/features/categories/components/CategoryProductsView.js +0 -21
  626. package/dist/features/homepage/components/HowItWorksInfoView.d.ts +0 -36
  627. package/dist/features/homepage/components/HowItWorksInfoView.js +0 -10
  628. package/dist/features/layout/BottomActions.d.ts +0 -1
  629. package/dist/features/layout/BottomActions.js +0 -311
  630. package/dist/features/products/components/ProductsView.d.ts +0 -6
  631. package/dist/features/products/components/ProductsView.js +0 -5
  632. package/dist/features/seller/components/SellerStoreView.d.ts +0 -8
  633. package/dist/features/seller/components/SellerStoreView.js +0 -8
@@ -5,8 +5,9 @@
5
5
  */
6
6
  import { BaseRepository, parseSieveDateValue } from "../../../providers/db-firebase";
7
7
  import type { DocumentReference, WriteBatch } from "firebase-admin/firestore";
8
+ import type { JsonValue } from "../../../schemas/types";
8
9
  import type { SieveModel, FirebaseSieveResult } from "../../../providers/db-firebase";
9
- import type { BidDocument, BidCreateInput, BidUpdateInput, BidAdminUpdateInput, BidStatus } from "../schemas";
10
+ import type { BidDocument, BidPlain, BidCreateInput, BidUpdateInput, BidAdminUpdateInput, BidStatus } from "../schemas";
10
11
  import { type HistoryActor } from "../../../_internal/shared/history/index";
11
12
  /** Who/why for a bid write that lands in `statusHistory`. */
12
13
  export interface BidWriteContext {
@@ -37,11 +38,23 @@ export declare class BidRepository extends BaseRepository<BidDocument> {
37
38
  */
38
39
  protected piiFields: readonly ["userEmail"];
39
40
  /** Override mapDoc to auto-decrypt PII on every bid read */
40
- protected mapDoc<D = BidDocument>(snap: import("../../../providers/db-firebase").DocumentSnapshot): D;
41
+ /** Plaintext PII. **Opt-in and named** — shows up in review and in a grep. */
42
+ revealBid(doc: BidDocument): BidPlain;
43
+ /** As `revealBid`, for a list read. */
44
+ revealBids(docs: readonly BidDocument[]): BidPlain[];
45
+ /**
46
+ * Masked PII — **the default for any surface that only needs to identify a
47
+ * row to a human.** Decrypts first, then masks: the mask helpers refuse
48
+ * ciphertext by design, so passing a stored field straight in would return
49
+ * "Anonymous" for every row.
50
+ */
51
+ maskedBid(doc: BidDocument): BidPlain;
52
+ /** As `maskedBid`, for a list read. */
53
+ maskedBids(docs: readonly BidDocument[]): BidPlain[];
41
54
  /**
42
55
  * Create new bid with auto-generated ID
43
56
  */
44
- create(input: BidCreateInput): Promise<BidDocument>;
57
+ createBid(input: BidCreateInput): Promise<BidPlain>;
45
58
  /**
46
59
  * Find bids by product ID
47
60
  */
@@ -179,6 +192,10 @@ export declare class BidRepository extends BaseRepository<BidDocument> {
179
192
  canFilter: boolean;
180
193
  canSort: boolean;
181
194
  };
195
+ searchTxt: {
196
+ canFilter: boolean;
197
+ canSort: boolean;
198
+ };
182
199
  userEmail: {
183
200
  canFilter: boolean;
184
201
  canSort: boolean;
@@ -209,6 +226,31 @@ export declare class BidRepository extends BaseRepository<BidDocument> {
209
226
  /**
210
227
  * Paginated, Firestore-native bid list (admin use).
211
228
  */
212
- list(model: SieveModel): Promise<FirebaseSieveResult<BidDocument>>;
229
+ /** Derived on every write path via `applyWriteHooks`. */
230
+ protected buildSearchTxtFor(data: Record<string, JsonValue>): string[] | null;
231
+ /**
232
+ * `opts.search` is a searchTxt PUSHDOWN, not a Sieve clause.
233
+ *
234
+ * ## What this replaces, on both of its two surfaces
235
+ *
236
+ * `/api/store/bids` searched the bidder with `userName@=`, a CASE-SENSITIVE
237
+ * prefix — the only thing Firestore can do for a prefix — so a seller typing
238
+ * "ravi" did not find "Ravi", and "kumar" never found anyone at all.
239
+ * `/api/user/bids` filtered `productTitle.includes(q)` in memory AFTER
240
+ * paging, so a match on page 2 was unreachable.
241
+ *
242
+ * Token search fixes both: `buildSearchTxt` normalises case and indexes word
243
+ * prefixes, so the query and the index meet on tokens rather than on a
244
+ * substring of one field.
245
+ *
246
+ * 🛑 `planSearchTxt`'s `empty` guard is the load-bearing part. A query that
247
+ * normalises to no usable token (`"!!!"`, `"—"`) MUST return nothing —
248
+ * emitting no clause instead returns the whole collection and calls it a
249
+ * search result, which is the shape of every silent-search bug in this
250
+ * codebase.
251
+ */
252
+ list(model: SieveModel, opts?: {
253
+ search?: string;
254
+ }): Promise<FirebaseSieveResult<BidDocument>>;
213
255
  }
214
256
  export declare const bidRepository: BidRepository;
@@ -4,11 +4,13 @@ import { normalizeError } from "../../../errors/normalize.js";
4
4
  *
5
5
  * Data access layer for bid documents in Firestore
6
6
  */
7
- import { BaseRepository, getFirestoreCount, prepareForFirestore, parseSieveDateValue, } from "../../../providers/db-firebase/index.js";
7
+ import { BaseRepository, getFirestoreCount, prepareForFirestore, parseSieveDateValue, applySieveToFirestore, } from "../../../providers/db-firebase/index.js";
8
8
  import { DatabaseError } from "../../../errors/index.js";
9
+ import { buildBidSearchTxt } from "../../../utils/search-txt-builders.js";
10
+ import { planSearchTxt, beginSearchWindow, emptySearchResult, } from "../../../utils/search-txt-query.js";
9
11
  import { BID_COLLECTION, BID_TRACKED_FIELDS, BID_HISTORY_PII_FIELDS, createBidId } from "../schemas/index.js";
10
12
  import { withHistory } from "../../../_internal/shared/history/index.js";
11
- import { decryptPiiFields, BID_PII_FIELDS, } from "../../../security/index.js";
13
+ import { BID_PII_FIELDS, maskPii, revealPii, } from "../../../security/index.js";
12
14
  import { BID_FIELDS } from "../../../constants/field-names.js";
13
15
  export class BidRepository extends BaseRepository {
14
16
  constructor() {
@@ -34,22 +36,64 @@ export class BidRepository extends BaseRepository {
34
36
  this.piiFields = BID_PII_FIELDS;
35
37
  }
36
38
  /** Override mapDoc to auto-decrypt PII on every bid read */
37
- mapDoc(snap) {
38
- const raw = super.mapDoc(snap);
39
- return decryptPiiFields(raw, [
40
- ...BID_PII_FIELDS,
41
- ]);
39
+ /*
40
+ * 🛑 `mapDoc` is NOT overridden, and that absence IS the change.
41
+ *
42
+ * It used to decrypt on every read, so ciphertext never left the database
43
+ * and every caller handled plaintext without ever saying so. Following
44
+ * `SiteSettingsRepository`: reads return what Firestore holds, and plaintext
45
+ * requires one of the two named methods below.
46
+ *
47
+ * A convention would not hold this. `BidDocument`'s PII fields are
48
+ * `Encrypted<string>`, assignable to nothing that wants a plain `string`, so
49
+ * a reader that skips both accessors is a compile error naming file and line.
50
+ */
51
+ /** Plaintext PII. **Opt-in and named** — shows up in review and in a grep. */
52
+ revealBid(doc) {
53
+ return revealPii(doc, BID_PII_FIELDS);
54
+ }
55
+ /** As `revealBid`, for a list read. */
56
+ revealBids(docs) {
57
+ return docs.map((d) => this.revealBid(d));
58
+ }
59
+ /**
60
+ * Masked PII — **the default for any surface that only needs to identify a
61
+ * row to a human.** Decrypts first, then masks: the mask helpers refuse
62
+ * ciphertext by design, so passing a stored field straight in would return
63
+ * "Anonymous" for every row.
64
+ */
65
+ maskedBid(doc) {
66
+ return maskPii(doc, BID_PII_FIELDS);
67
+ }
68
+ /** As `maskedBid`, for a list read. */
69
+ maskedBids(docs) {
70
+ return docs.map((d) => this.maskedBid(d));
42
71
  }
43
72
  /**
44
73
  * Create new bid with auto-generated ID
45
74
  */
46
- async create(input) {
75
+ /*
76
+ * 🛑 NOT an `override` of `create`, and the rename is forced rather than
77
+ * stylistic.
78
+ *
79
+ * `BaseRepository.create` is declared `(data: Partial<Doc> | FirestoreDocument)`,
80
+ * i.e. it promises to accept the CIPHERTEXT shape. This method accepts
81
+ * PLAINTEXT and encrypts. `string` and `Encrypted<string>` are incompatible
82
+ * in both directions, so an override is a TS2416 no matter which way the
83
+ * check runs — and it should be, because the two signatures genuinely
84
+ * disagree about what the caller is holding.
85
+ *
86
+ * Five call sites across both repositories; `create` remains inherited for
87
+ * anything that legitimately has ciphertext already.
88
+ */
89
+ async createBid(input) {
47
90
  const bidIdInput = {
48
91
  productName: input.productTitle,
49
92
  userFirstName: input.userName.split(" ")[0] || input.userName,
50
93
  date: new Date(),
51
94
  };
52
95
  const id = createBidId(bidIdInput);
96
+ // Plain in, ciphertext out — the write hook encrypts below.
53
97
  const bidData = {
54
98
  ...input,
55
99
  status: "active",
@@ -64,7 +108,16 @@ export class BidRepository extends BaseRepository {
64
108
  .collection(this.collection)
65
109
  .doc(id)
66
110
  .set(prepareForFirestore(encrypted));
67
- return { id, ...bidData }; // return plaintext to caller
111
+ /*
112
+ * Returns `BidPlain`, and the declared type now says so.
113
+ *
114
+ * This line's own comment has always read "return plaintext to caller"
115
+ * while the signature promised `BidDocument` — the exact mismatch
116
+ * `Encrypted<string>` exists to surface. It echoes the input rather than
117
+ * re-reading, which is deliberate (a read-after-write costs a Firestore
118
+ * read on every bid), so what comes back is the plaintext that went in.
119
+ */
120
+ return { id, ...bidData };
68
121
  }
69
122
  /**
70
123
  * Find bids by product ID
@@ -441,11 +494,53 @@ export class BidRepository extends BaseRepository {
441
494
  /**
442
495
  * Paginated, Firestore-native bid list (admin use).
443
496
  */
444
- async list(model) {
445
- return this.sieveQuery(model, BidRepository.SIEVE_FIELDS, {
446
- defaultPageSize: 50,
447
- maxPageSize: 200,
497
+ /** Derived on every write path via `applyWriteHooks`. */
498
+ buildSearchTxtFor(data) {
499
+ return buildBidSearchTxt(data);
500
+ }
501
+ /**
502
+ * `opts.search` is a searchTxt PUSHDOWN, not a Sieve clause.
503
+ *
504
+ * ## What this replaces, on both of its two surfaces
505
+ *
506
+ * `/api/store/bids` searched the bidder with `userName@=`, a CASE-SENSITIVE
507
+ * prefix — the only thing Firestore can do for a prefix — so a seller typing
508
+ * "ravi" did not find "Ravi", and "kumar" never found anyone at all.
509
+ * `/api/user/bids` filtered `productTitle.includes(q)` in memory AFTER
510
+ * paging, so a match on page 2 was unreachable.
511
+ *
512
+ * Token search fixes both: `buildSearchTxt` normalises case and indexes word
513
+ * prefixes, so the query and the index meet on tokens rather than on a
514
+ * substring of one field.
515
+ *
516
+ * 🛑 `planSearchTxt`'s `empty` guard is the load-bearing part. A query that
517
+ * normalises to no usable token (`"!!!"`, `"—"`) MUST return nothing —
518
+ * emitting no clause instead returns the whole collection and calls it a
519
+ * search result, which is the shape of every silent-search bug in this
520
+ * codebase.
521
+ */
522
+ async list(model, opts) {
523
+ const plan = planSearchTxt(opts?.search);
524
+ if (plan.empty)
525
+ return emptySearchResult();
526
+ if (!plan.head) {
527
+ return this.sieveQuery(model, BidRepository.SIEVE_FIELDS, {
528
+ defaultPageSize: 50,
529
+ maxPageSize: 200,
530
+ });
531
+ }
532
+ const baseQuery = this.getCollection().where("searchTxt", "array-contains", plan.head);
533
+ // One bounded window, one raised maxPageSize, one page slice — hand-rolling
534
+ // the three is how other repositories each ended up with two of them.
535
+ const win = beginSearchWindow(model, plan);
536
+ const result = await applySieveToFirestore({
537
+ baseQuery,
538
+ model: win.model,
539
+ options: { maxPageSize: win.maxPageSize(200) },
540
+ fields: BidRepository.SIEVE_FIELDS,
541
+ mapDoc: (snap) => this.mapDoc(snap),
448
542
  });
543
+ return win.finish(result);
449
544
  }
450
545
  }
451
546
  // ---------------------------------------------------------------------------
@@ -457,6 +552,12 @@ BidRepository.SIEVE_FIELDS = {
457
552
  productTitle: { canFilter: true, canSort: true },
458
553
  userId: { canFilter: true, canSort: false },
459
554
  userName: { canFilter: true, canSort: true },
555
+ /*
556
+ * Filterable so the grammar admits it; the real read is an
557
+ * `array-contains` pushdown in `list()`, not a Sieve clause — Sieve cannot
558
+ * express array membership.
559
+ */
560
+ searchTxt: { canFilter: true, canSort: false },
460
561
  // Encrypted (BID_PII_FIELDS). Filtering compares plaintext against
461
562
  // `enc:v1:…` and matches ZERO rows with a 200; sorting orders by base64
462
563
  // noise. It appeared to work only because the column was still
@@ -4,6 +4,7 @@
4
4
  import { type GenerateBidIdInput } from "../../../utils/id-generators";
5
5
  import type { StatusChangeEntry } from "../../../_internal/shared/history/types";
6
6
  import type { BaseDocument } from "../../../_internal/shared/types/base-document";
7
+ import type { Encrypted, Plaintext } from "../../../security/encrypted";
7
8
  export type BidStatus = "active" | "outbid" | "won" | "lost" | "cancelled"
8
9
  /** Won, then the buyer let the 48h payment window lapse. */
9
10
  | "forfeited";
@@ -16,12 +17,22 @@ export declare const BidStatusValues: {
16
17
  readonly CANCELLED: "cancelled";
17
18
  readonly FORFEITED: "forfeited";
18
19
  };
20
+ /**
21
+ * `BidDocument` with its PII as plain `string` — what the named repository
22
+ * accessors return, and what a WRITE path accepts (the repository encrypts).
23
+ *
24
+ * `Plaintext<T>` is the one definition of this shape; see `security/encrypted.ts`.
25
+ * It is deliberately NOT distinguishable from a MASKED value — `maskPii`
26
+ * returns plain strings too, and no type can express "these characters are
27
+ * asterisks". The distinction is which named method you called.
28
+ */
29
+ export type BidPlain = Plaintext<BidDocument>;
19
30
  export interface BidDocument extends BaseDocument {
20
31
  productId: string;
21
32
  productTitle: string;
22
33
  userId: string;
23
34
  userName: string;
24
- userEmail: string;
35
+ userEmail: Encrypted<string>;
25
36
  bidAmount: number;
26
37
  currency: string;
27
38
  status: BidStatus;
@@ -29,6 +40,15 @@ export interface BidDocument extends BaseDocument {
29
40
  previousBidAmount?: number;
30
41
  bidDate: Date;
31
42
  autoMaxBid?: number;
43
+ /**
44
+ * Token index over `productTitle` + `userName`, derived on every write.
45
+ *
46
+ * 🛑 `userEmail` is deliberately ABSENT — it is the one entry in
47
+ * `BID_PII_FIELDS`, and a searchTxt over an encrypted field IS that field in
48
+ * plaintext (decision D1). `userName` is not in that registry and is already
49
+ * in `BID_PUBLIC_FIELDS`, so indexing it discloses nothing new.
50
+ */
51
+ searchTxt?: string[];
32
52
  /**
33
53
  * The order this winning bid was settled into. Written by
34
54
  * `finalizeLockedLines` once the winner actually pays; absent on a won-but-
@@ -65,13 +85,13 @@ export interface BidDocument extends BaseDocument {
65
85
  statusHistoryTruncated?: number;
66
86
  }
67
87
  export declare const BID_COLLECTION: "bids";
68
- export declare const BID_INDEXED_FIELDS: readonly ["productId", "userId", "status", "isWinning", "bidDate", "createdAt"];
88
+ export declare const BID_INDEXED_FIELDS: readonly ["productId", "userId", "status", "isWinning", "bidDate", "createdAt", "searchTxt"];
69
89
  export declare const DEFAULT_BID_DATA: Partial<BidDocument>;
70
90
  export declare const BID_PUBLIC_FIELDS: readonly ["id", "productId", "productTitle", "userName", "bidAmount", "currency", "bidDate", "isWinning", "createdAt"];
71
91
  export declare const BID_UPDATABLE_FIELDS: readonly ["autoMaxBid"];
72
- export type BidCreateInput = Omit<BidDocument, "id" | "createdAt" | "updatedAt" | "status" | "isWinning">;
92
+ export type BidCreateInput = Omit<BidPlain, "id" | "createdAt" | "updatedAt" | "status" | "isWinning">;
73
93
  export type BidUpdateInput = Partial<Pick<BidDocument, (typeof BID_UPDATABLE_FIELDS)[number]>>;
74
- export type BidAdminUpdateInput = Partial<Omit<BidDocument, "id" | "createdAt">>;
94
+ export type BidAdminUpdateInput = Partial<Omit<BidPlain, "id" | "createdAt">>;
75
95
  export declare const bidQueryHelpers: {
76
96
  readonly byProduct: (productId: string) => readonly ["productId", "==", string];
77
97
  readonly byUser: (userId: string) => readonly ["userId", "==", string];
@@ -19,6 +19,7 @@ export const BID_INDEXED_FIELDS = [
19
19
  "isWinning",
20
20
  "bidDate",
21
21
  "createdAt",
22
+ "searchTxt",
22
23
  ];
23
24
  export const DEFAULT_BID_DATA = {
24
25
  status: "active",
@@ -5,7 +5,6 @@
5
5
  * Auth, rate-limiting, and Next.js specifics are handled by the consumer.
6
6
  */
7
7
  import { cache } from "react";
8
- import { maskPublicReview } from "../../../security/index.js";
9
8
  import { safeRead } from "../../../errors/safe-read.js";
10
9
  import { finalizeStagedMediaField } from "../../media/finalize.js";
11
10
  import { userRepository } from "../repository/user.repository.js";
@@ -86,7 +85,16 @@ export async function getSellerReviews(storeId) {
86
85
  productId: r.productId,
87
86
  productTitle: r.productTitle,
88
87
  userId: r.userId,
89
- userName: maskPublicReview(r).userName,
88
+ /*
89
+ * 🛑 `maskedReview`, not `maskPublicReview`.
90
+ *
91
+ * `maskPublicReview` calls `maskName`, which refuses a ciphertext input by
92
+ * design and answers "Anonymous". Since `ReviewRepository.mapDoc` stopped
93
+ * decrypting, `r.userName` IS ciphertext — so this rendered every reviewer
94
+ * on every public profile as "Anonymous". `maskedReview` decrypts first,
95
+ * then masks, which is the whole reason it exists.
96
+ */
97
+ userName: reviewRepository.maskedReview(r).userName,
90
98
  userAvatar: r.userAvatar,
91
99
  rating: r.rating,
92
100
  title: r.title,
@@ -117,7 +125,16 @@ export async function getReviewsAuthoredBy(userId) {
117
125
  productId: r.productId,
118
126
  productTitle: r.productTitle,
119
127
  userId: r.userId,
120
- userName: maskPublicReview(r).userName,
128
+ /*
129
+ * 🛑 `maskedReview`, not `maskPublicReview`.
130
+ *
131
+ * `maskPublicReview` calls `maskName`, which refuses a ciphertext input by
132
+ * design and answers "Anonymous". Since `ReviewRepository.mapDoc` stopped
133
+ * decrypting, `r.userName` IS ciphertext — so this rendered every reviewer
134
+ * on every public profile as "Anonymous". `maskedReview` decrypts first,
135
+ * then masks, which is the whole reason it exists.
136
+ */
137
+ userName: reviewRepository.maskedReview(r).userName,
121
138
  userAvatar: r.userAvatar,
122
139
  rating: r.rating,
123
140
  title: r.title,
@@ -142,7 +159,16 @@ export async function getReviewsReceivedBy(userId) {
142
159
  productId: r.productId,
143
160
  productTitle: r.productTitle,
144
161
  userId: r.userId,
145
- userName: maskPublicReview(r).userName,
162
+ /*
163
+ * 🛑 `maskedReview`, not `maskPublicReview`.
164
+ *
165
+ * `maskPublicReview` calls `maskName`, which refuses a ciphertext input by
166
+ * design and answers "Anonymous". Since `ReviewRepository.mapDoc` stopped
167
+ * decrypting, `r.userName` IS ciphertext — so this rendered every reviewer
168
+ * on every public profile as "Anonymous". `maskedReview` decrypts first,
169
+ * then masks, which is the whole reason it exists.
170
+ */
171
+ userName: reviewRepository.maskedReview(r).userName,
146
172
  userAvatar: r.userAvatar,
147
173
  rating: r.rating,
148
174
  title: r.title,
@@ -1,7 +1,6 @@
1
1
  export { RoleGate, ProtectedRoute } from "./Guards";
2
2
  export type { RoleGateProps, ProtectedRouteProps, AuthGuardUser, AuthRouteConfig, } from "./Guards";
3
3
  export { SocialAuthButtons } from "./SocialAuthButtons";
4
- export { AuthStatusPanel } from "./AuthStatusPanel";
5
4
  export { LoginForm } from "./LoginForm";
6
5
  export type { LoginFormProps, LoginFormValues } from "./LoginForm";
7
6
  export { RegisterForm } from "./RegisterForm";
@@ -1,6 +1,5 @@
1
1
  export { RoleGate, ProtectedRoute } from "./Guards.js";
2
2
  export { SocialAuthButtons } from "./SocialAuthButtons.js";
3
- export { AuthStatusPanel } from "./AuthStatusPanel.js";
4
3
  export { LoginForm } from "./LoginForm.js";
5
4
  export { RegisterForm } from "./RegisterForm.js";
6
5
  export { ForgotPasswordView } from "./ForgotPasswordView.js";
@@ -1,6 +1,6 @@
1
- import type { DocumentReference, DocumentSnapshot } from "firebase-admin/firestore";
1
+ import type { DocumentReference } from "firebase-admin/firestore";
2
2
  import { BaseRepository, type FirebaseSieveFields, type FirebaseSieveResult, type SieveModel } from "../../../providers/db-firebase";
3
- import { type SessionCreateInput, type SessionDocument, type SessionUpdateInput } from "../schemas";
3
+ import { type SessionCreateInput, type SessionDocument, type SessionPlain, type SessionUpdateInput } from "../schemas";
4
4
  export declare class SessionRepository extends BaseRepository<SessionDocument> {
5
5
  static readonly SIEVE_FIELDS: FirebaseSieveFields;
6
6
  /**
@@ -18,7 +18,21 @@ export declare class SessionRepository extends BaseRepository<SessionDocument> {
18
18
  protected piiFields: readonly ["deviceInfo.ip", "deviceInfo.userAgent", "location.city"];
19
19
  constructor();
20
20
  /** Decrypt on read so callers see the same shape they wrote. */
21
- protected mapDoc<D = SessionDocument>(snap: DocumentSnapshot): D;
21
+ /**
22
+ * Plaintext PII. **Opt-in and named** — for the security page that shows a
23
+ * user their own sessions, and for abuse investigation.
24
+ */
25
+ revealSession(doc: SessionDocument): SessionPlain;
26
+ /** As `revealSession`, for a list read. */
27
+ revealSessions(docs: readonly SessionDocument[]): SessionPlain[];
28
+ /**
29
+ * Masked PII — the default. `deviceInfo.ip` becomes a last-four mask, which
30
+ * is what every admin surface here actually needs: enough to tell two
31
+ * sessions apart, not enough to geolocate a person.
32
+ */
33
+ maskedSession(doc: SessionDocument): SessionPlain;
34
+ /** As `maskedSession`, for a list read. */
35
+ maskedSessions(docs: readonly SessionDocument[]): SessionPlain[];
22
36
  list(model: SieveModel): Promise<FirebaseSieveResult<SessionDocument>>;
23
37
  listForUser(userId: string, model: SieveModel): Promise<FirebaseSieveResult<SessionDocument>>;
24
38
  createSession(userId: string, data: Omit<SessionCreateInput, "userId" | "expiresAt" | "isActive">): Promise<SessionDocument>;
@@ -3,7 +3,7 @@ import { DatabaseError } from "../../../errors/index.js";
3
3
  import { serverLogger } from "../../../monitoring/index.js";
4
4
  import { BaseRepository, parseSieveDateValue, } from "../../../providers/db-firebase/index.js";
5
5
  import { generateSessionId } from "../token-helpers.js";
6
- import { decryptPiiFields } from "../../../security/pii-encrypt.js";
6
+ import { maskPii, revealPii } from "../../../security/pii-accessors.js";
7
7
  import { SESSION_COLLECTION, SESSION_EXPIRATION_MS, SESSION_FIELDS, } from "../schemas/index.js";
8
8
  export class SessionRepository extends BaseRepository {
9
9
  constructor() {
@@ -27,9 +27,36 @@ export class SessionRepository extends BaseRepository {
27
27
  ];
28
28
  }
29
29
  /** Decrypt on read so callers see the same shape they wrote. */
30
- mapDoc(snap) {
31
- const raw = super.mapDoc(snap);
32
- return decryptPiiFields(raw, [...this.piiFields]);
30
+ /*
31
+ * 🛑 `mapDoc` is NOT overridden — it used to decrypt on every read, so the
32
+ * device IP and user-agent of every session left the database in the clear.
33
+ *
34
+ * All three PII fields here are NESTED, which is why `maskPii` had to learn
35
+ * dotted paths rather than skip them: a masked session that returned the real
36
+ * IP would be a function whose name is the only evidence it did anything.
37
+ */
38
+ /**
39
+ * Plaintext PII. **Opt-in and named** — for the security page that shows a
40
+ * user their own sessions, and for abuse investigation.
41
+ */
42
+ revealSession(doc) {
43
+ return revealPii(doc, this.piiFields);
44
+ }
45
+ /** As `revealSession`, for a list read. */
46
+ revealSessions(docs) {
47
+ return docs.map((d) => this.revealSession(d));
48
+ }
49
+ /**
50
+ * Masked PII — the default. `deviceInfo.ip` becomes a last-four mask, which
51
+ * is what every admin surface here actually needs: enough to tell two
52
+ * sessions apart, not enough to geolocate a person.
53
+ */
54
+ maskedSession(doc) {
55
+ return maskPii(doc, this.piiFields);
56
+ }
57
+ /** As `maskedSession`, for a list read. */
58
+ maskedSessions(docs) {
59
+ return docs.map((d) => this.maskedSession(d));
33
60
  }
34
61
  async list(model) {
35
62
  return this.sieveQuery(model, SessionRepository.SIEVE_FIELDS);
@@ -43,6 +70,8 @@ export class SessionRepository extends BaseRepository {
43
70
  const now = new Date();
44
71
  const expiresAt = new Date(now.getTime() + SESSION_EXPIRATION_MS);
45
72
  const sessionId = generateSessionId();
73
+ // Plain in, ciphertext out — the write hook encrypts the three nested
74
+ // `piiFields` paths below.
46
75
  const sessionData = {
47
76
  userId,
48
77
  deviceInfo: data.deviceInfo,
@@ -69,7 +98,19 @@ export class SessionRepository extends BaseRepository {
69
98
  // that supplies a location — the hot activity ping stays a single write.
70
99
  if (data?.location) {
71
100
  const current = await this.findById(sessionId); // mapDoc → already decrypted
72
- updateData.location = { ...(current?.location ?? {}), ...data.location };
101
+ /*
102
+ * Merged off the REVEALED current session, not the stored one.
103
+ *
104
+ * `location.city` is one of this repository's three nested PII paths, so
105
+ * `current.location` holds ciphertext — spreading it into a plaintext
106
+ * patch would re-encrypt the city on the way down and make it
107
+ * permanently unreadable, the same defect as the payout crons.
108
+ */
109
+ const currentPlain = current ? this.revealSession(current) : null;
110
+ updateData.location = {
111
+ ...(currentPlain?.location ?? {}),
112
+ ...data.location,
113
+ };
73
114
  }
74
115
  try {
75
116
  await this.update(sessionId, updateData);
@@ -1,6 +1,5 @@
1
- import type { DocumentSnapshot } from "../../../providers/db-firebase";
2
1
  import { BaseRepository } from "../../../providers/db-firebase";
3
- import { type EmailVerificationTokenDocument, type PasswordResetTokenDocument } from "../schemas";
2
+ import { type EmailVerificationTokenDocument, type EmailVerificationTokenPlain, type PasswordResetTokenDocument, type PasswordResetTokenPlain } from "../schemas";
4
3
  export declare class EmailVerificationTokenRepository extends BaseRepository<EmailVerificationTokenDocument> {
5
4
  constructor();
6
5
  /**
@@ -19,7 +18,19 @@ export declare class EmailVerificationTokenRepository extends BaseRepository<Ema
19
18
  */
20
19
  protected piiFields: readonly ["email"];
21
20
  protected piiIndexMap: Record<string, string>;
22
- protected mapDoc<D = EmailVerificationTokenDocument>(snap: DocumentSnapshot): D;
21
+ /** Plaintext PII. **Opt-in and named** — shows up in review and in a grep. */
22
+ revealToken(doc: EmailVerificationTokenDocument): EmailVerificationTokenPlain;
23
+ /** As `revealToken`, for a list read. */
24
+ revealTokens(docs: readonly EmailVerificationTokenDocument[]): EmailVerificationTokenPlain[];
25
+ /**
26
+ * Masked PII — **the default for any surface that only needs to identify a
27
+ * row to a human.** Decrypts first, then masks: the mask helpers refuse
28
+ * ciphertext by design, so passing a stored field straight in would return
29
+ * "Anonymous" for every row.
30
+ */
31
+ maskedToken(doc: EmailVerificationTokenDocument): EmailVerificationTokenPlain;
32
+ /** As `maskedToken`, for a list read. */
33
+ maskedTokens(docs: readonly EmailVerificationTokenDocument[]): EmailVerificationTokenPlain[];
23
34
  findByToken(token: string): Promise<EmailVerificationTokenDocument | null>;
24
35
  findByUserId(userId: string): Promise<EmailVerificationTokenDocument[]>;
25
36
  findByEmail(email: string): Promise<EmailVerificationTokenDocument[]>;
@@ -39,7 +50,19 @@ export declare class PasswordResetTokenRepository extends BaseRepository<Passwor
39
50
  */
40
51
  protected piiFields: readonly ["email"];
41
52
  protected piiIndexMap: Record<string, string>;
42
- protected mapDoc<D = PasswordResetTokenDocument>(snap: DocumentSnapshot): D;
53
+ /** Plaintext PII. **Opt-in and named** — shows up in review and in a grep. */
54
+ revealResetToken(doc: PasswordResetTokenDocument): PasswordResetTokenPlain;
55
+ /** As `revealResetToken`, for a list read. */
56
+ revealResetTokens(docs: readonly PasswordResetTokenDocument[]): PasswordResetTokenPlain[];
57
+ /**
58
+ * Masked PII — **the default for any surface that only needs to identify a
59
+ * row to a human.** Decrypts first, then masks: the mask helpers refuse
60
+ * ciphertext by design, so passing a stored field straight in would return
61
+ * "Anonymous" for every row.
62
+ */
63
+ maskedResetToken(doc: PasswordResetTokenDocument): PasswordResetTokenPlain;
64
+ /** As `maskedResetToken`, for a list read. */
65
+ maskedResetTokens(docs: readonly PasswordResetTokenDocument[]): PasswordResetTokenPlain[];
43
66
  findByToken(token: string): Promise<PasswordResetTokenDocument | null>;
44
67
  findByUserId(userId: string): Promise<PasswordResetTokenDocument[]>;
45
68
  findByEmail(email: string): Promise<PasswordResetTokenDocument[]>;