@mohasinac/appkit 4.52.5 → 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 (630) 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 +11 -0
  336. package/dist/features/layout/AppLayoutShell.js +64 -12
  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.js +1 -1
  348. package/dist/features/layout/cta-anchor.d.ts +31 -0
  349. package/dist/features/layout/cta-anchor.js +31 -0
  350. package/dist/features/layout/hooks/useBottomActions.d.ts +7 -0
  351. package/dist/features/layout/hooks/useBottomActions.js +6 -1
  352. package/dist/features/layout/index.d.ts +9 -1
  353. package/dist/features/layout/index.js +9 -1
  354. package/dist/features/layout/useCtaReveal.d.ts +24 -0
  355. package/dist/features/layout/useCtaReveal.js +82 -0
  356. package/dist/features/layout/useHoldToOpen.d.ts +41 -0
  357. package/dist/features/layout/useHoldToOpen.js +84 -0
  358. package/dist/features/lottery/repository/lottery-entry.repository.d.ts +18 -3
  359. package/dist/features/lottery/repository/lottery-entry.repository.js +48 -6
  360. package/dist/features/lottery/schemas/firestore.d.ts +33 -5
  361. package/dist/features/loyalty/api/balance/route.js +1 -1
  362. package/dist/features/loyalty/api/history/route.js +1 -1
  363. package/dist/features/media/MediaImage.js +0 -1
  364. package/dist/features/media/MediaPickerModal.js +7 -1
  365. package/dist/features/media/modals/ImageEditor.js +5 -1
  366. package/dist/features/media/modals/VideoThumbnailSelector.js +17 -1
  367. package/dist/features/media/repository/media-assets.repository.d.ts +19 -0
  368. package/dist/features/media/upload/CameraCapture.js +16 -1
  369. package/dist/features/media/upload/ImageUpload.js +42 -4
  370. package/dist/features/media/upload/MediaUploadField.js +69 -13
  371. package/dist/features/media/upload/downscale-image.d.ts +56 -0
  372. package/dist/features/media/upload/downscale-image.js +150 -0
  373. package/dist/features/messages/components/ConversationThreadView.js +45 -2
  374. package/dist/features/messages/components/MessageSellerButton.d.ts +15 -1
  375. package/dist/features/messages/components/MessageSellerButton.js +10 -2
  376. package/dist/features/messages/schemas/firestore.d.ts +15 -0
  377. package/dist/features/orders/hooks/useOrders.js +4 -2
  378. package/dist/features/orders/repository/orders.repository.d.ts +15 -4
  379. package/dist/features/orders/repository/orders.repository.js +52 -20
  380. package/dist/features/orders/schemas/firestore.d.ts +15 -4
  381. package/dist/features/orders/schemas/index.d.ts +8 -8
  382. package/dist/features/orders/types/index.d.ts +2 -2
  383. package/dist/features/payments/repository/payments.repository.js +2 -2
  384. package/dist/features/payments/repository/payout.repository.d.ts +23 -6
  385. package/dist/features/payments/repository/payout.repository.js +63 -23
  386. package/dist/features/payments/repository/saved-payment-methods.repository.d.ts +17 -6
  387. package/dist/features/payments/repository/saved-payment-methods.repository.js +59 -11
  388. package/dist/features/payments/schemas/firestore.d.ts +14 -3
  389. package/dist/features/payments/schemas/saved-methods-firestore.d.ts +12 -1
  390. package/dist/features/pre-orders/api/[slug]/route.js +1 -1
  391. package/dist/features/pre-orders/api/admin/route.js +1 -1
  392. package/dist/features/pre-orders/api/route.js +1 -1
  393. package/dist/features/pre-orders/repository/pre-orders.repository.d.ts +3 -3
  394. package/dist/features/pre-orders/repository/pre-orders.repository.js +6 -6
  395. package/dist/features/products/api/[id]/route.js +1 -1
  396. package/dist/features/products/components/ListingBottomActions.js +4 -0
  397. package/dist/features/products/components/ProductDetailPageView.js +2 -1
  398. package/dist/features/products/components/ProductGalleryClient.js +2 -2
  399. package/dist/features/products/components/ProductGrid.js +12 -1
  400. package/dist/features/products/components/index.d.ts +0 -2
  401. package/dist/features/products/components/index.js +0 -1
  402. package/dist/features/products/config/listing-type-listing-config.d.ts +0 -3
  403. package/dist/features/products/config/listing-type-listing-config.js +27 -2
  404. package/dist/features/products/constants/listing-tabs.d.ts +9 -0
  405. package/dist/features/products/constants/listing-tabs.js +3 -2
  406. package/dist/features/products/hooks/useProducts.js +2 -2
  407. package/dist/features/products/repository/products.repository.js +13 -1
  408. package/dist/features/products/schemas/index.d.ts +2 -2
  409. package/dist/features/products/types/index.d.ts +1 -1
  410. package/dist/features/promotions/api/route.js +1 -1
  411. package/dist/features/reviews/actions/review-actions.d.ts +6 -6
  412. package/dist/features/reviews/actions/review-actions.js +22 -8
  413. package/dist/features/reviews/components/ReviewDetailPageView.js +13 -1
  414. package/dist/features/reviews/components/ReviewsIndexPageView.js +21 -4
  415. package/dist/features/reviews/repository/reviews.repository.d.ts +19 -7
  416. package/dist/features/reviews/repository/reviews.repository.js +63 -12
  417. package/dist/features/reviews/schemas/firestore.d.ts +13 -2
  418. package/dist/features/reviews/schemas/index.d.ts +2 -2
  419. package/dist/features/scams/actions/scam-actions.js +16 -4
  420. package/dist/features/search/components/SearchResultsPageView.js +2 -1
  421. package/dist/features/search/hooks/useSearchIndex.d.ts +34 -0
  422. package/dist/features/search/hooks/useSearchIndex.js +172 -0
  423. package/dist/features/search/repository/search.repository.js +2 -2
  424. package/dist/features/seller/actions/offer-actions.d.ts +5 -5
  425. package/dist/features/seller/actions/offer-actions.js +38 -8
  426. package/dist/features/seller/actions/seller-actions.js +34 -7
  427. package/dist/features/seller/api/coupons/route.js +1 -1
  428. package/dist/features/seller/api/products/route.js +1 -1
  429. package/dist/features/seller/api/store/route.js +1 -1
  430. package/dist/features/seller/components/SellerBidsView.js +1 -1
  431. package/dist/features/seller/components/SellerCouponsView.js +1 -1
  432. package/dist/features/seller/components/SellerListingTypeView.js +9 -1
  433. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  434. package/dist/features/seller/components/SellerPayoutSettingsView.js +0 -1
  435. package/dist/features/seller/components/SellerPayoutsView.js +1 -1
  436. package/dist/features/seller/components/SellerProductShell.js +0 -1
  437. package/dist/features/seller/components/SellerProductsView.js +1 -1
  438. package/dist/features/seller/components/SellerShippingView.js +0 -1
  439. package/dist/features/seller/components/SellerStorefrontView.js +0 -1
  440. package/dist/features/seller/components/index.d.ts +0 -4
  441. package/dist/features/seller/components/index.js +0 -2
  442. package/dist/features/seller/repository/offer.repository.d.ts +15 -3
  443. package/dist/features/seller/repository/offer.repository.js +43 -7
  444. package/dist/features/seller/schemas/firestore.d.ts +14 -3
  445. package/dist/features/seller/schemas/index.d.ts +4 -4
  446. package/dist/features/seller/schemas/order-forms.d.ts +39 -0
  447. package/dist/features/seller/schemas/order-forms.js +37 -0
  448. package/dist/features/shell/FormShell.js +6 -2
  449. package/dist/features/shell/QuickFormDrawer.js +15 -1
  450. package/dist/features/shipments/components/AdminShipmentEditorView.js +0 -1
  451. package/dist/features/shipments/components/AdminShipmentsView.js +1 -1
  452. package/dist/features/sticker-trace/components/StickerCommitPanel.d.ts +30 -0
  453. package/dist/features/sticker-trace/components/StickerCommitPanel.js +93 -0
  454. package/dist/features/sticker-trace/components/StickerPrintPanel.d.ts +33 -0
  455. package/dist/features/sticker-trace/components/StickerPrintPanel.js +104 -0
  456. package/dist/features/sticker-trace/components/StickerRetryPanel.d.ts +20 -0
  457. package/dist/features/sticker-trace/components/StickerRetryPanel.js +128 -0
  458. package/dist/features/sticker-trace/components/StickerRunHistoryPanel.d.ts +45 -0
  459. package/dist/features/sticker-trace/components/StickerRunHistoryPanel.js +84 -0
  460. package/dist/features/sticker-trace/components/StickerTraceStudio.d.ts +27 -0
  461. package/dist/features/sticker-trace/components/StickerTraceStudio.js +171 -0
  462. package/dist/features/sticker-trace/constants/help-content.d.ts +23 -0
  463. package/dist/features/sticker-trace/constants/help-content.js +172 -0
  464. package/dist/features/sticker-trace/hooks/useLiveTrace.d.ts +27 -0
  465. package/dist/features/sticker-trace/hooks/useLiveTrace.js +160 -0
  466. package/dist/features/sticker-trace/hooks/useStickerTraceProgress.d.ts +22 -0
  467. package/dist/features/sticker-trace/hooks/useStickerTraceProgress.js +106 -0
  468. package/dist/features/sticker-trace/repository/sticker-sheets.repository.d.ts +113 -0
  469. package/dist/features/sticker-trace/repository/sticker-sheets.repository.js +146 -0
  470. package/dist/features/sticker-trace/repository/sticker-trace-runs.repository.d.ts +132 -0
  471. package/dist/features/sticker-trace/repository/sticker-trace-runs.repository.js +174 -0
  472. package/dist/features/sticker-trace/schemas/firestore.d.ts +248 -0
  473. package/dist/features/sticker-trace/schemas/firestore.js +79 -0
  474. package/dist/features/sticker-trace/server.d.ts +8 -0
  475. package/dist/features/sticker-trace/server.js +51 -0
  476. package/dist/features/stores/actions/store-query-actions.d.ts +2 -2
  477. package/dist/features/stores/actions/store-query-actions.js +7 -2
  478. package/dist/features/stores/api/[storeSlug]/auctions/route.js +3 -3
  479. package/dist/features/stores/api/[storeSlug]/products/route.js +3 -3
  480. package/dist/features/stores/api/[storeSlug]/reviews/route.js +1 -1
  481. package/dist/features/stores/api/[storeSlug]/route.js +1 -1
  482. package/dist/features/stores/components/StoreNavTabs.js +17 -2
  483. package/dist/features/stores/manifest.js +8 -4
  484. package/dist/features/support/repository/support.repository.d.ts +14 -3
  485. package/dist/features/support/repository/support.repository.js +93 -13
  486. package/dist/features/support/schemas/firestore.d.ts +16 -5
  487. package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.js +61 -19
  488. package/dist/features/tester/seed-data/authored/buying__browsing-search.js +19 -3
  489. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.d.ts +2 -0
  490. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +243 -0
  491. package/dist/features/tester/seed-data/authored/content-discovery__events.js +36 -10
  492. package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.d.ts +2 -0
  493. package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.js +209 -0
  494. package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.d.ts +2 -0
  495. package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.js +90 -0
  496. package/dist/features/tester/seed-data/authored/index.js +8 -0
  497. package/dist/features/tester/seed-data/authored/selling__media-limits.js +19 -17
  498. package/dist/features/tester/seed-data/authored/selling__product-upload-details.js +10 -5
  499. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.d.ts +2 -0
  500. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.js +283 -0
  501. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +192 -22
  502. package/dist/index.d.ts +10 -23
  503. package/dist/index.js +27 -19
  504. package/dist/next/api/routeHandler.js +9 -0
  505. package/dist/next/routing/require-record.d.ts +13 -0
  506. package/dist/next/routing/require-record.js +62 -0
  507. package/dist/next/routing/route-map.d.ts +4 -4
  508. package/dist/next/routing/route-map.js +25 -3
  509. package/dist/providers/db-firebase/base.d.ts +4 -2
  510. package/dist/providers/db-firebase/base.js +21 -5
  511. package/dist/providers/db-firebase/base.repository.d.ts +11 -9
  512. package/dist/providers/db-firebase/base.repository.js +19 -0
  513. package/dist/providers/db-firebase/rtdb-paths.d.ts +12 -0
  514. package/dist/providers/db-firebase/rtdb-paths.js +12 -0
  515. package/dist/react/ErrorBoundary.js +6 -1
  516. package/dist/react/hooks/realtime-event-constants.d.ts +1 -0
  517. package/dist/react/hooks/realtime-event-constants.js +8 -0
  518. package/dist/react/hooks/useEntityDelete.js +5 -1
  519. package/dist/react/hooks/useMessage.js +5 -1
  520. package/dist/repositories/index.d.ts +2 -2
  521. package/dist/repositories/index.js +6 -1
  522. package/dist/schemas/registry.d.ts +13 -20
  523. package/dist/schemas/registry.js +31 -14
  524. package/dist/schemas/webhooks/google-oauth.d.ts +2 -2
  525. package/dist/security/encrypted.d.ts +117 -0
  526. package/dist/security/encrypted.js +100 -0
  527. package/dist/security/index.d.ts +5 -2
  528. package/dist/security/index.js +16 -2
  529. package/dist/security/pii-accessors.d.ts +71 -0
  530. package/dist/security/pii-accessors.js +150 -0
  531. package/dist/security/pii-encrypt.d.ts +0 -8
  532. package/dist/security/pii-encrypt.js +22 -15
  533. package/dist/security/pii-mask.d.ts +18 -0
  534. package/dist/security/pii-mask.js +27 -0
  535. package/dist/seed/_helpers/search-txt-wrappers.d.ts +6 -6
  536. package/dist/seed/_helpers/search-txt-wrappers.js +22 -0
  537. package/dist/seed/addresses-seed-data.d.ts +2 -2
  538. package/dist/seed/authenticity-knowledge-seed-data.d.ts +34 -0
  539. package/dist/seed/authenticity-knowledge-seed-data.js +1277 -0
  540. package/dist/seed/bids-seed-data.d.ts +2 -2
  541. package/dist/seed/bids-seed-data.js +23 -2
  542. package/dist/seed/events-seed-data.d.ts +2 -2
  543. package/dist/seed/events-seed-data.js +5 -0
  544. package/dist/seed/faq-seed-data.js +175 -5
  545. package/dist/seed/homepage-sections-seed-data.js +39 -23
  546. package/dist/seed/index.d.ts +1 -0
  547. package/dist/seed/index.js +1 -0
  548. package/dist/seed/lottery-entries-seed-data.d.ts +2 -2
  549. package/dist/seed/offers-seed-data.d.ts +2 -2
  550. package/dist/seed/offers-seed-data.js +1 -1
  551. package/dist/seed/orders-seed-data.d.ts +2 -2
  552. package/dist/seed/payouts-seed-data.d.ts +2 -2
  553. package/dist/seed/payouts-seed-data.js +1 -1
  554. package/dist/seed/reviews-seed-data.d.ts +1 -2
  555. package/dist/seed/seed-purpose.js +7 -0
  556. package/dist/seed/sessions-seed-data.d.ts +2 -2
  557. package/dist/seed/sessions-seed-data.js +5 -0
  558. package/dist/seed/site-settings-seed-data.js +1 -1
  559. package/dist/seed/support-tickets-seed-data.d.ts +2 -2
  560. package/dist/seed/support-tickets-seed-data.js +1 -1
  561. package/dist/seed/users-seed-data.d.ts +2 -2
  562. package/dist/seed/users-seed-data.js +1 -1
  563. package/dist/seo/json-ld.js +5 -1
  564. package/dist/server.d.ts +18 -3
  565. package/dist/server.js +59 -3
  566. package/dist/styles.css +237 -1
  567. package/dist/tailwind-utilities.css +1 -1
  568. package/dist/ui/components/Button.js +7 -1
  569. package/dist/ui/components/FilterChipGroup.d.ts +11 -0
  570. package/dist/ui/components/FilterChipGroup.js +1 -1
  571. package/dist/ui/components/ImageGallery.js +6 -1
  572. package/dist/ui/components/ListingLayout.js +14 -8
  573. package/dist/ui/components/OverflowRow.d.ts +92 -0
  574. package/dist/ui/components/OverflowRow.js +203 -0
  575. package/dist/ui/components/OverflowRow.style.css +235 -0
  576. package/dist/ui/components/RecordDetailModal.js +14 -1
  577. package/dist/ui/components/RowActionMenu.js +5 -1
  578. package/dist/ui/components/SideDrawer.js +5 -1
  579. package/dist/ui/components/SideModal.js +9 -1
  580. package/dist/ui/components/TabBarShell.d.ts +12 -1
  581. package/dist/ui/components/TabBarShell.js +3 -2
  582. package/dist/ui/components/Tabs.js +36 -24
  583. package/dist/ui/components/Toast.d.ts +3 -24
  584. package/dist/ui/components/Toast.js +2 -19
  585. package/dist/ui/components/TopBannerPortal.d.ts +15 -0
  586. package/dist/ui/components/TopBannerPortal.js +19 -0
  587. package/dist/ui/components/UnsavedChangesModal.js +5 -1
  588. package/dist/ui/components/index.style.css +1 -0
  589. package/dist/ui/components/row-collapse.d.ts +15 -0
  590. package/dist/ui/components/row-collapse.js +127 -0
  591. package/dist/ui/components/toast-context.d.ts +63 -0
  592. package/dist/ui/components/toast-context.js +48 -0
  593. package/dist/ui/components/top-banner-slot.d.ts +37 -0
  594. package/dist/ui/components/top-banner-slot.js +45 -0
  595. package/dist/ui/icons/icon-registry.d.ts +6 -0
  596. package/dist/ui/icons/icon-registry.js +17 -1
  597. package/dist/ui/index.d.ts +2 -0
  598. package/dist/ui/index.js +1 -0
  599. package/dist/utils/array.helper.d.ts +2 -2
  600. package/dist/utils/array.helper.js +5 -5
  601. package/dist/utils/id-generators.d.ts +6 -0
  602. package/dist/utils/id-generators.js +10 -0
  603. package/dist/utils/media-url.js +0 -2
  604. package/dist/utils/search-txt-builders.d.ts +28 -4
  605. package/dist/utils/search-txt-builders.js +41 -1
  606. package/dist/validation/schemas.d.ts +8 -8
  607. package/package.json +6 -2
  608. package/scripts/seed-cli.mjs +3 -0
  609. package/dist/features/account/components/UserAddressesView.d.ts +0 -13
  610. package/dist/features/account/components/UserAddressesView.js +0 -5
  611. package/dist/features/account/components/UserNotificationsView.d.ts +0 -15
  612. package/dist/features/account/components/UserNotificationsView.js +0 -12
  613. package/dist/features/account/components/UserSettingsView.d.ts +0 -16
  614. package/dist/features/account/components/UserSettingsView.js +0 -13
  615. package/dist/features/account/components/UserSupportView.d.ts +0 -3
  616. package/dist/features/account/components/UserSupportView.js +0 -166
  617. package/dist/features/admin/components/DemoSeedView.d.ts +0 -11
  618. package/dist/features/admin/components/DemoSeedView.js +0 -5
  619. package/dist/features/auth/components/AuthStatusPanel.d.ts +0 -10
  620. package/dist/features/auth/components/AuthStatusPanel.js +0 -22
  621. package/dist/features/categories/components/CategoryProductsView.d.ts +0 -45
  622. package/dist/features/categories/components/CategoryProductsView.js +0 -21
  623. package/dist/features/homepage/components/HowItWorksInfoView.d.ts +0 -36
  624. package/dist/features/homepage/components/HowItWorksInfoView.js +0 -10
  625. package/dist/features/layout/BottomActions.d.ts +0 -1
  626. package/dist/features/layout/BottomActions.js +0 -311
  627. package/dist/features/products/components/ProductsView.d.ts +0 -6
  628. package/dist/features/products/components/ProductsView.js +0 -5
  629. package/dist/features/seller/components/SellerStoreView.d.ts +0 -8
  630. package/dist/features/seller/components/SellerStoreView.js +0 -8
@@ -0,0 +1,100 @@
1
+ /**
2
+ * `Encrypted<T>` — the FORCING FUNCTION for ciphertext-by-default.
3
+ *
4
+ * ## The problem this exists to solve
5
+ *
6
+ * `audit-pii-coverage`'s R3 stages fourteen repositories whose `mapDoc`
7
+ * decrypts PII on EVERY read. The prescription — copy `SiteSettingsRepository`:
8
+ * leave `mapDoc` alone and expose plaintext through a NAMED getter with a
9
+ * masked variant — is right, and the migration had been staged for one reason:
10
+ *
11
+ * **`tsc` cannot find the call sites.**
12
+ *
13
+ * Measured 2026-10-17: 147 distinct files touch a staged repository. And
14
+ * `PayoutDocument.sellerEmail` is declared `string` whether the value in it is
15
+ * ciphertext or plaintext, so a call site that gets the wrong one COMPILES. It
16
+ * then either renders `enc:v1:…` to an admin or publishes a decrypted email.
17
+ * There is no compile error, no runtime error, and nothing to grep for.
18
+ *
19
+ * Compare the `perPage` → `pageSize` rename done the same day: renaming one
20
+ * interface member turned all 65 consumers into compile errors and `tsc`
21
+ * handed over the list. That is the difference between a safe sweep and a
22
+ * 147-file guess, and it is purely a property of the TYPE.
23
+ *
24
+ * ## How it works
25
+ *
26
+ * A branded string. `Encrypted<string>` is assignable FROM nothing but itself,
27
+ * so every reader that wants a plain `string` must go through one of the two
28
+ * named accessors below — and until it does, it is a compile error naming the
29
+ * exact file and line.
30
+ *
31
+ * ```ts
32
+ * // payout.sellerEmail → Encrypted<string> (what Firestore holds)
33
+ * // plaintext(payout.sellerEmail) → string (opt-in, named, auditable)
34
+ * // maskedEmail(payout.sellerEmail) → string (the UI default)
35
+ * ```
36
+ *
37
+ * The brand is erased at runtime: `Encrypted<string>` IS a string, so nothing
38
+ * changes about what is stored, sent or compared. It exists only to make the
39
+ * compiler ask the question at every site.
40
+ *
41
+ * ## 🛑 Branding a field is HALF a change, never a whole one
42
+ *
43
+ * The type must be made true in the same commit, by removing that
44
+ * repository's unconditional `mapDoc` decrypt. Branding a field whose value is
45
+ * still decrypted on read asserts something false, and the first `plaintext()`
46
+ * call would then double-decrypt — `decryptValue` passes a non-`enc:v1:`
47
+ * string through unchanged, so it would silently "work" and hide the lie.
48
+ *
49
+ * Convert ONE repository per change, smallest consumer count first. `tsc` then
50
+ * enumerates only that repository's readers, which is the whole point: a
51
+ * reviewable list per step instead of 147 at once.
52
+ */
53
+ /**
54
+ * Mark a value as ciphertext. For a repository's own read path, where the value
55
+ * genuinely came out of Firestore encrypted.
56
+ *
57
+ * 🛑 Not for widening a plaintext value to satisfy a type. If a caller has
58
+ * plaintext and the field wants `Encrypted`, the value needs ENCRYPTING, not
59
+ * re-labelling — `encryptPii` is the function for that.
60
+ */
61
+ export const asEncrypted = (value) =>
62
+ /*
63
+ * `as unknown as` is REQUIRED here, and only here.
64
+ *
65
+ * With the nominal brand, `Encrypted<T>` is not a string type, so a direct
66
+ * cast is a TS2352 ("neither type sufficiently overlaps"). That error is
67
+ * correct and is the entire point of the nominal shape — this one function
68
+ * is the sanctioned crossing, which is why the double cast is confined to it
69
+ * rather than appearing at call sites.
70
+ *
71
+ * Its four real callers all pass `""` to BLANK a field on a display-only
72
+ * read, not to relabel a secret.
73
+ */
74
+ value;
75
+ /**
76
+ * Narrow a possibly-undefined ciphertext field. Saves every call site writing
77
+ * the same `value === undefined ? undefined : …` dance.
78
+ */
79
+ export const asEncryptedMaybe = (value) => value === undefined || value === null ? undefined : asEncrypted(value);
80
+ /*
81
+ * 🛑 There is deliberately NO `plaintext(value)` helper in this module.
82
+ *
83
+ * The first draft had one, and it was a lie of exactly the kind this whole
84
+ * sweep exists to remove: it took an `Encrypted<string>` and returned
85
+ * `string` by casting — so a function named `plaintext` handed back
86
+ * CIPHERTEXT, and every caller would have rendered `enc:v1:…` while the types
87
+ * said everything was fine. `decryptValue` passes a non-`enc:v1:` string
88
+ * through unchanged, so it would even have "worked" on the rows that were
89
+ * never encrypted, and failed only on the ones that were.
90
+ *
91
+ * Decryption needs the key and `node:crypto`, which belong to the server; this
92
+ * module is types-only so it stays importable from a client bundle (Root Cause
93
+ * #24). So the plaintext path lives where the decryption actually happens:
94
+ *
95
+ * on the REPOSITORY, as a named method, following `SiteSettingsRepository` —
96
+ * `getDecryptedCredentials()` / `getCredentialsMasked()`.
97
+ *
98
+ * Masked is the default a UI should reach for; plaintext is opt-in and named,
99
+ * so it shows up both in review and in a grep.
100
+ */
@@ -4,7 +4,10 @@ export type { RateLimitConfig, RateLimitResult } from "./rate-limit";
4
4
  export { requireAuth, requireRole, requireOwnership, requireEmailVerified, requireActiveAccount, canChangeRole, getRoleLevel, } from "./authorization";
5
5
  export type { UserRole } from "./authorization";
6
6
  export { redactPii, safeDisplayName, safeDisplayEmail, maskIp } from "./pii-redact";
7
- export { encryptValue, decryptValue, hmacBlindIndex, encryptPiiFields, decryptPiiFields, encryptPii, decryptPii, piiBlindIndex, piiIndicesFor, getPiiConfigError, encryptPayoutDetails, decryptPayoutDetails, encryptShippingConfig, decryptShippingConfig, encryptPayoutBankAccount, decryptPayoutBankAccount, } from "./pii-encrypt";
8
- export { isPiiEncrypted, maskName, maskEmail, maskPublicReview, maskPublicBid, maskPublicEventEntry, maskOfferForSeller, ENC_PREFIX, HMAC_PREFIX, } from "./pii-mask";
7
+ export { asEncrypted, asEncryptedMaybe } from "./encrypted";
8
+ export type { Encrypted } from "./encrypted";
9
+ export { encryptValue, decryptValue, hmacBlindIndex, encryptPiiFields, decryptPiiFields, encryptPii, decryptPii, piiBlindIndex, piiIndicesFor, getPiiConfigError, encryptPayoutDetails, decryptPayoutDetails, encryptShippingConfig, decryptShippingConfig, } from "./pii-encrypt";
10
+ export { revealPii, maskPii, revealPiiAll, maskPiiAll } from "./pii-accessors";
11
+ export { isPiiEncrypted, maskName, maskEmail, maskPhone, maskPublicReview, maskPublicBid, maskPublicEventEntry, maskOfferForSeller, ENC_PREFIX, HMAC_PREFIX, } from "./pii-mask";
9
12
  export { USER_PII_FIELDS, USER_PII_INDEX_MAP, ADDRESS_PII_FIELDS, ORDER_PII_FIELDS, PAYOUT_PII_FIELDS, PAYOUT_PII_INDEX_MAP, BID_PII_FIELDS, TOKEN_PII_FIELDS, TOKEN_PII_INDEX_MAP, REVIEW_PII_FIELDS, REVIEW_PII_INDEX_MAP, OFFER_PII_FIELDS, EVENT_ENTRY_PII_FIELDS, LOTTERY_ENTRY_PII_FIELDS, PAYMENT_METHOD_PII_FIELDS, CONVERSATION_PII_FIELDS, MESSAGE_PII_FIELDS, } from "./pii-schemas";
10
13
  export { encryptSecret, decryptSecret, isSecretEncrypted, maskSecret, } from "./settings-encryption";
@@ -2,11 +2,25 @@ export { generateNonce, buildCSP } from "./csp.js";
2
2
  export { rateLimit, applyRateLimit, rateLimitByIdentifier, RateLimitPresets, clearRateLimitStore, getClientIP, hashGuestIdentity, } from "./rate-limit.js";
3
3
  export { requireAuth, requireRole, requireOwnership, requireEmailVerified, requireActiveAccount, canChangeRole, getRoleLevel, } from "./authorization.js";
4
4
  export { redactPii, safeDisplayName, safeDisplayEmail, maskIp } from "./pii-redact.js";
5
- export { encryptValue, decryptValue, hmacBlindIndex, encryptPiiFields, decryptPiiFields, encryptPii, decryptPii, piiBlindIndex, piiIndicesFor, getPiiConfigError, encryptPayoutDetails, decryptPayoutDetails, encryptShippingConfig, decryptShippingConfig, encryptPayoutBankAccount, decryptPayoutBankAccount, } from "./pii-encrypt.js";
5
+ /*
6
+ * The ciphertext-by-default forcing function. Types + two labelling helpers
7
+ * only — no crypto — so this stays safe in the universal barrel (Root Cause
8
+ * #24). See `encrypted.ts` for why `tsc` has to be the thing that enumerates
9
+ * the 147 call sites, and why there is no `plaintext()` free function.
10
+ */
11
+ export { asEncrypted, asEncryptedMaybe } from "./encrypted.js";
12
+ export { encryptValue, decryptValue, hmacBlindIndex, encryptPiiFields, decryptPiiFields, encryptPii, decryptPii, piiBlindIndex, piiIndicesFor, getPiiConfigError, encryptPayoutDetails, decryptPayoutDetails, encryptShippingConfig, decryptShippingConfig, } from "./pii-encrypt.js";
13
+ /*
14
+ * The two NAMED PII accessors that replace an unconditional `mapDoc` decrypt.
15
+ * Server-only — they import `pii-encrypt`, which reaches node:crypto through a
16
+ * bare runtime require (Root Cause #24), so this must never be re-exported
17
+ * from the universal client entry.
18
+ */
19
+ export { revealPii, maskPii, revealPiiAll, maskPiiAll } from "./pii-accessors.js";
6
20
  // Crypto-free display-masking helpers -- sourced from pii-mask.ts (not
7
21
  // pii-encrypt.ts) so this barrel stays safe to re-export from the
8
22
  // universal client+server index.ts. See pii-mask.ts's header comment.
9
- export { isPiiEncrypted, maskName, maskEmail, maskPublicReview, maskPublicBid, maskPublicEventEntry, maskOfferForSeller, ENC_PREFIX, HMAC_PREFIX, } from "./pii-mask.js";
23
+ export { isPiiEncrypted, maskName, maskEmail, maskPhone, maskPublicReview, maskPublicBid, maskPublicEventEntry, maskOfferForSeller, ENC_PREFIX, HMAC_PREFIX, } from "./pii-mask.js";
10
24
  export { USER_PII_FIELDS, USER_PII_INDEX_MAP, ADDRESS_PII_FIELDS, ORDER_PII_FIELDS, PAYOUT_PII_FIELDS, PAYOUT_PII_INDEX_MAP, BID_PII_FIELDS, TOKEN_PII_FIELDS, TOKEN_PII_INDEX_MAP, REVIEW_PII_FIELDS, REVIEW_PII_INDEX_MAP, OFFER_PII_FIELDS, EVENT_ENTRY_PII_FIELDS, LOTTERY_ENTRY_PII_FIELDS, PAYMENT_METHOD_PII_FIELDS, CONVERSATION_PII_FIELDS, MESSAGE_PII_FIELDS, } from "./pii-schemas.js";
11
25
  export { encryptSecret, decryptSecret, isSecretEncrypted, maskSecret, } from "./settings-encryption.js";
12
26
  // RBAC system — DELETED 2026-08-29.
@@ -0,0 +1,71 @@
1
+ /**
2
+ * The two NAMED accessors that replace an unconditional `mapDoc` decrypt.
3
+ *
4
+ * ## Why this module exists
5
+ *
6
+ * `audit-pii-coverage`'s R3 stages fourteen repositories whose `mapDoc`
7
+ * decrypted PII on every read, so ciphertext never left the database and every
8
+ * caller silently handled plaintext. The prescription — copy
9
+ * `SiteSettingsRepository`: leave `mapDoc` alone and expose plaintext through a
10
+ * NAMED getter with a masked variant — is per-repository, and writing it
11
+ * fourteen times would be fourteen chances for the field→mask mapping to
12
+ * drift (Root Cause #75). So the rule lives here once and each repository
13
+ * delegates.
14
+ *
15
+ * ```ts
16
+ * repo.findById(id) → PII fields are Encrypted<string>
17
+ * repo.revealFor(doc) → plaintext, opt-in and named
18
+ * repo.maskedFor(doc) → masked, the UI default
19
+ * ```
20
+ *
21
+ * ## 🛑 Masking must DECRYPT FIRST
22
+ *
23
+ * This is the trap worth stating, because getting it wrong is silent and looks
24
+ * like success. `maskName`/`maskEmail` in `pii-mask.ts` both begin with
25
+ * `if (hasEncPrefix(value)) return "Anonymous" / "***@***.***"` — a deliberate
26
+ * guard so ciphertext can never reach a UI. Once `mapDoc` stops decrypting,
27
+ * handing a stored field straight to `maskName` therefore returns "Anonymous"
28
+ * for EVERY row: no error, no ciphertext leak, and a masked column that is
29
+ * uniformly useless instead of showing "R*** K***". `maskPii` decrypts and
30
+ * then masks.
31
+ *
32
+ * ## Field → mask is by NAME CLASS, deliberately
33
+ *
34
+ * An email masks differently from a phone from a person's name, and the field
35
+ * lists these repositories already declare (`*_PII_FIELDS`) carry no type
36
+ * information. Classifying on the field name is the only signal available, and
37
+ * it is the same approach `pii-redact.ts` has always used for logs — the
38
+ * difference being that this module uses the USER-FACING masks from
39
+ * `pii-mask.ts` rather than the log-oriented ones.
40
+ *
41
+ * 🛑 The fallback is `maskName`, not "return as-is". An unrecognised PII field
42
+ * name must degrade toward LESS disclosure; returning the plaintext would make
43
+ * a new field silently public the moment someone adds it to a `*_PII_FIELDS`
44
+ * list without touching this file.
45
+ *
46
+ * @tag domain:security
47
+ * @tag layer:security
48
+ * @tag access:server-only
49
+ * @tag sideEffects:none
50
+ */
51
+ /**
52
+ * Decrypt the named PII fields. **Opt-in and named**: every call site is a
53
+ * deliberate decision that shows up in review and in a grep.
54
+ *
55
+ * The return type is the caller's plaintext-facing shape. That cast is the one
56
+ * place it is legitimate: this function performs the decryption that makes the
57
+ * `Encrypted<…>` brand false, which is exactly what the brand is for.
58
+ */
59
+ export declare function revealPii<Plain extends object>(doc: object, piiFields: readonly string[]): Plain;
60
+ /**
61
+ * Decrypt, then mask. **The default a UI should reach for.**
62
+ *
63
+ * Returns the same shape as `revealPii` because a masked value is still a
64
+ * displayable string — the difference is in what it contains, which is why the
65
+ * two accessors must be separately named rather than one taking a boolean.
66
+ */
67
+ export declare function maskPii<Plain extends object>(doc: object, piiFields: readonly string[]): Plain;
68
+ /** Array form of `revealPii`, for list reads. */
69
+ export declare function revealPiiAll<Plain extends object>(docs: readonly object[], piiFields: readonly string[]): Plain[];
70
+ /** Array form of `maskPii`, for list reads. */
71
+ export declare function maskPiiAll<Plain extends object>(docs: readonly object[], piiFields: readonly string[]): Plain[];
@@ -0,0 +1,150 @@
1
+ /**
2
+ * The two NAMED accessors that replace an unconditional `mapDoc` decrypt.
3
+ *
4
+ * ## Why this module exists
5
+ *
6
+ * `audit-pii-coverage`'s R3 stages fourteen repositories whose `mapDoc`
7
+ * decrypted PII on every read, so ciphertext never left the database and every
8
+ * caller silently handled plaintext. The prescription — copy
9
+ * `SiteSettingsRepository`: leave `mapDoc` alone and expose plaintext through a
10
+ * NAMED getter with a masked variant — is per-repository, and writing it
11
+ * fourteen times would be fourteen chances for the field→mask mapping to
12
+ * drift (Root Cause #75). So the rule lives here once and each repository
13
+ * delegates.
14
+ *
15
+ * ```ts
16
+ * repo.findById(id) → PII fields are Encrypted<string>
17
+ * repo.revealFor(doc) → plaintext, opt-in and named
18
+ * repo.maskedFor(doc) → masked, the UI default
19
+ * ```
20
+ *
21
+ * ## 🛑 Masking must DECRYPT FIRST
22
+ *
23
+ * This is the trap worth stating, because getting it wrong is silent and looks
24
+ * like success. `maskName`/`maskEmail` in `pii-mask.ts` both begin with
25
+ * `if (hasEncPrefix(value)) return "Anonymous" / "***@***.***"` — a deliberate
26
+ * guard so ciphertext can never reach a UI. Once `mapDoc` stops decrypting,
27
+ * handing a stored field straight to `maskName` therefore returns "Anonymous"
28
+ * for EVERY row: no error, no ciphertext leak, and a masked column that is
29
+ * uniformly useless instead of showing "R*** K***". `maskPii` decrypts and
30
+ * then masks.
31
+ *
32
+ * ## Field → mask is by NAME CLASS, deliberately
33
+ *
34
+ * An email masks differently from a phone from a person's name, and the field
35
+ * lists these repositories already declare (`*_PII_FIELDS`) carry no type
36
+ * information. Classifying on the field name is the only signal available, and
37
+ * it is the same approach `pii-redact.ts` has always used for logs — the
38
+ * difference being that this module uses the USER-FACING masks from
39
+ * `pii-mask.ts` rather than the log-oriented ones.
40
+ *
41
+ * 🛑 The fallback is `maskName`, not "return as-is". An unrecognised PII field
42
+ * name must degrade toward LESS disclosure; returning the plaintext would make
43
+ * a new field silently public the moment someone adds it to a `*_PII_FIELDS`
44
+ * list without touching this file.
45
+ *
46
+ * @tag domain:security
47
+ * @tag layer:security
48
+ * @tag access:server-only
49
+ * @tag sideEffects:none
50
+ */
51
+ import { decryptPiiFields } from "./pii-encrypt.js";
52
+ import { maskEmail, maskName, maskPhone } from "./pii-mask.js";
53
+ /** Dotted/`[]` path → its leaf key, which is what the name class reads. */
54
+ function leafKey(path) {
55
+ const afterArray = path.includes("[]") ? path.slice(path.indexOf("[]") + 2) : path;
56
+ const parts = afterArray.replace(/^\./, "").split(".");
57
+ return parts[parts.length - 1] || path;
58
+ }
59
+ function maskByName(key, value) {
60
+ const k = leafKey(key).toLowerCase();
61
+ if (k.includes("email"))
62
+ return maskEmail(value);
63
+ if (k.includes("phone") || k.includes("mobile") || k.includes("contact")) {
64
+ return maskPhone(value);
65
+ }
66
+ // Everything else — names, addresses, UPI handles, account numbers — gets
67
+ // the most conservative mask available rather than passing through.
68
+ return maskName(value);
69
+ }
70
+ /**
71
+ * Decrypt the named PII fields. **Opt-in and named**: every call site is a
72
+ * deliberate decision that shows up in review and in a grep.
73
+ *
74
+ * The return type is the caller's plaintext-facing shape. That cast is the one
75
+ * place it is legitimate: this function performs the decryption that makes the
76
+ * `Encrypted<…>` brand false, which is exactly what the brand is for.
77
+ */
78
+ export function revealPii(doc, piiFields) {
79
+ return decryptPiiFields({ ...doc }, [...piiFields]);
80
+ }
81
+ /**
82
+ * Decrypt, then mask. **The default a UI should reach for.**
83
+ *
84
+ * Returns the same shape as `revealPii` because a masked value is still a
85
+ * displayable string — the difference is in what it contains, which is why the
86
+ * two accessors must be separately named rather than one taking a boolean.
87
+ */
88
+ export function maskPii(doc, piiFields) {
89
+ /*
90
+ * `FirestoreDocument`, not `Record<string, unknown>`.
91
+ *
92
+ * It is the shape this genuinely has — `decryptPiiFields` already works in
93
+ * `Record<string, FirestoreValue>` internally — and `unknown` here would
94
+ * push an `as` cast onto every leaf read below, which is what
95
+ * `audit-unknown-leakage` exists to stop.
96
+ */
97
+ const revealed = revealPii(doc, piiFields);
98
+ for (const field of piiFields) {
99
+ /*
100
+ * 🛑 DOTTED PATHS ARE MASKED, not skipped.
101
+ *
102
+ * The first draft skipped them, with a note saying a repository needing
103
+ * nested masking should override the method. Then `sessions` turned out to
104
+ * declare `deviceInfo.ip`, `deviceInfo.userAgent` and `location.city` —
105
+ * ALL THREE of its PII fields are nested. So the "exception" was the first
106
+ * real subject, and a `maskPii` returning those three DECRYPTED would be
107
+ * the `maskPublicBid`-returning-`{...bid}` defect exactly: a function whose
108
+ * name is the only evidence it masked anything (Root Cause #50).
109
+ *
110
+ * `[]` array paths are still skipped, because a per-element mask needs the
111
+ * array's own shape and guessing it would be the same lie one level down.
112
+ */
113
+ if (field.includes("[]"))
114
+ continue;
115
+ maskAtPath(revealed, field);
116
+ }
117
+ return revealed;
118
+ }
119
+ /**
120
+ * Mask the string at a dotted path, in place. A missing intermediate object or
121
+ * a non-string leaf is left alone — this walks what is there rather than
122
+ * creating structure to mask.
123
+ */
124
+ function maskAtPath(root, path) {
125
+ const parts = path.split(".");
126
+ let node = root;
127
+ for (let i = 0; i < parts.length - 1; i++) {
128
+ const next = node[parts[i]];
129
+ if (typeof next !== "object" || next === null || Array.isArray(next))
130
+ return;
131
+ // Clone on the way down: `revealPii` shallow-copies, so mutating a nested
132
+ // object would write through to the caller's document.
133
+ const copy = { ...next };
134
+ node[parts[i]] = copy;
135
+ node = copy;
136
+ }
137
+ const leaf = parts[parts.length - 1];
138
+ const value = node[leaf];
139
+ if (typeof value !== "string" || value.length === 0)
140
+ return;
141
+ node[leaf] = maskByName(leaf, value);
142
+ }
143
+ /** Array form of `revealPii`, for list reads. */
144
+ export function revealPiiAll(docs, piiFields) {
145
+ return docs.map((d) => revealPii(d, piiFields));
146
+ }
147
+ /** Array form of `maskPii`, for list reads. */
148
+ export function maskPiiAll(docs, piiFields) {
149
+ return docs.map((d) => maskPii(d, piiFields));
150
+ }
@@ -70,11 +70,3 @@ export declare function encryptShippingConfig<T extends object>(config: T | unde
70
70
  * Decrypt PII inside seller shippingConfig.pickupAddress after reading.
71
71
  */
72
72
  export declare function decryptShippingConfig<T extends object>(config: T | undefined | null): T | undefined | null;
73
- /**
74
- * Encrypt PII on a payout bankAccount sub-object for the payouts collection.
75
- */
76
- export declare function encryptPayoutBankAccount<T extends object>(bank: T | undefined | null): T | undefined | null;
77
- /**
78
- * Decrypt PII on a payout bankAccount sub-object from the payouts collection.
79
- */
80
- export declare function decryptPayoutBankAccount<T extends object>(bank: T | undefined | null): T | undefined | null;
@@ -428,19 +428,26 @@ export function decryptShippingConfig(config) {
428
428
  }
429
429
  return result;
430
430
  }
431
- /**
432
- * Encrypt PII on a payout bankAccount sub-object for the payouts collection.
433
- */
434
- export function encryptPayoutBankAccount(bank) {
435
- if (!bank)
436
- return bank;
437
- return encryptPiiFields({ ...bank }, []);
438
- }
439
- /**
440
- * Decrypt PII on a payout bankAccount sub-object from the payouts collection.
431
+ /*
432
+ * 🛑 `encryptPayoutBankAccount` / `decryptPayoutBankAccount` were DELETED
433
+ * 2026-10-18. Do not reintroduce them.
434
+ *
435
+ * Both were `encryptPiiFields({ ...bank }, [])` — an EMPTY field list, so a
436
+ * function named "encrypt" encrypted nothing and its decrypt twin undid
437
+ * nothing. That is R1's own defect (`EMPTY_PII_LIST`) one indirection away
438
+ * from where R1 looks, which is why no audit caught it.
439
+ *
440
+ * They had nothing to protect. `PayoutBankAccount` declares exactly
441
+ * `accountHolderName`, `accountNumberMasked`, `ifscCode`, `bankName` — the
442
+ * number is masked by definition and the rest are public bank identifiers. The
443
+ * real `accountNumber` lives on `UserDocument.payoutDetails`, encrypted there
444
+ * by `encryptPayoutDetails`, and is deliberately NOT copied onto a payout.
445
+ *
446
+ * The danger was the name: it read as protection, so a caller could reasonably
447
+ * pass a real account number through it and believe it had been encrypted.
448
+ * `seller-actions.ts` did exactly that — it copied the whole `bankAccount`,
449
+ * including the encrypted `accountNumber`, and the no-op stored the ciphertext
450
+ * verbatim where nothing would ever unwrap it.
451
+ *
452
+ * `accountHolderName` is still masked for list views, by `maskedPayout`.
441
453
  */
442
- export function decryptPayoutBankAccount(bank) {
443
- if (!bank)
444
- return bank;
445
- return decryptPiiFields({ ...bank }, []);
446
- }
@@ -70,6 +70,24 @@ export declare function maskName(name: string | null | undefined): string;
70
70
  * "john.doe@example.com" → "j***@***.com"
71
71
  */
72
72
  export declare function maskEmail(email: string | null | undefined): string;
73
+ /**
74
+ * Mask a phone number for display. Keeps the last four digits, which is the
75
+ * convention every support flow in this codebase already reads out loud.
76
+ *
77
+ * "+91 98765 43210" → "***43210" (digits only, so formatting cannot leak)
78
+ *
79
+ * 🛑 Same `hasEncPrefix` guard as its siblings: if the value is still a
80
+ * ciphertext blob, return a fully-masked placeholder rather than a prefix of
81
+ * base64. Without it, "***" + the last four characters of an `enc:v1:` payload
82
+ * would read as a real phone number and be wrong in a way nobody could spot.
83
+ *
84
+ * A private copy of this already existed in `pii-redact.ts` for LOG redaction.
85
+ * That one is deliberately left alone: it has no encryption guard because logs
86
+ * are written from plaintext in memory, and giving the two one implementation
87
+ * would mean one of the callers getting a guard it does not need or losing one
88
+ * it does.
89
+ */
90
+ export declare function maskPhone(phone: string | null | undefined): string;
73
91
  /**
74
92
  * Return a copy of a review document with PII fields masked for public display.
75
93
  * Admin/owner endpoints should NOT call this — use the raw document instead.
@@ -87,6 +87,33 @@ export function maskEmail(email) {
87
87
  const domainMasked = dotIdx > 0 ? "***" + domain.slice(dotIdx) : "***";
88
88
  return (local[0] ?? "*") + "***@" + domainMasked;
89
89
  }
90
+ /**
91
+ * Mask a phone number for display. Keeps the last four digits, which is the
92
+ * convention every support flow in this codebase already reads out loud.
93
+ *
94
+ * "+91 98765 43210" → "***43210" (digits only, so formatting cannot leak)
95
+ *
96
+ * 🛑 Same `hasEncPrefix` guard as its siblings: if the value is still a
97
+ * ciphertext blob, return a fully-masked placeholder rather than a prefix of
98
+ * base64. Without it, "***" + the last four characters of an `enc:v1:` payload
99
+ * would read as a real phone number and be wrong in a way nobody could spot.
100
+ *
101
+ * A private copy of this already existed in `pii-redact.ts` for LOG redaction.
102
+ * That one is deliberately left alone: it has no encryption guard because logs
103
+ * are written from plaintext in memory, and giving the two one implementation
104
+ * would mean one of the callers getting a guard it does not need or losing one
105
+ * it does.
106
+ */
107
+ export function maskPhone(phone) {
108
+ if (!phone || typeof phone !== "string")
109
+ return "***";
110
+ if (hasEncPrefix(phone))
111
+ return "***";
112
+ const digits = phone.replace(/\D/g, "");
113
+ if (digits.length < 4)
114
+ return "***";
115
+ return `***${digits.slice(-4)}`;
116
+ }
90
117
  /**
91
118
  * Return a copy of a review document with PII fields masked for public display.
92
119
  * Admin/owner endpoints should NOT call this — use the raw document instead.
@@ -3,10 +3,10 @@ import type { StoreDocument } from "../../features/stores/schemas/firestore";
3
3
  import type { ScammerDocument } from "../../features/scams/schemas/firestore";
4
4
  import type { EventDocument } from "../../features/events/schemas/firestore";
5
5
  import type { BlogPostDocument } from "../../features/blog/schemas/firestore";
6
- import type { ReviewDocument } from "../../features/reviews/schemas/firestore";
7
- import type { OrderDocument } from "../../features/orders/schemas/firestore";
6
+ import type { ReviewPlain } from "../../features/reviews/schemas/firestore";
7
+ import type { OrderPlain } from "../../features/orders/schemas/firestore";
8
8
  import type { CouponDocument } from "../../features/promotions/schemas/firestore";
9
- import type { OfferDocument } from "../../features/seller/schemas/firestore";
9
+ import type { OfferPlain } from "../../features/seller/schemas/firestore";
10
10
  /**
11
11
  * 🛑 Apply AFTER `buildCategoryTree`, never before.
12
12
  *
@@ -19,8 +19,8 @@ export declare function withCategorySearchTxt<T extends Partial<CategoryDocument
19
19
  export declare function withStoreSearchTxt<T extends Partial<StoreDocument>>(p: T): T;
20
20
  export declare function withEventSearchTxt<T extends Partial<EventDocument>>(p: T): T;
21
21
  export declare function withBlogSearchTxt<T extends Partial<BlogPostDocument>>(p: T): T;
22
- export declare function withReviewSearchTxt<T extends Partial<ReviewDocument>>(p: T): T;
23
- export declare function withOrderSearchTxt<T extends Partial<OrderDocument>>(p: T): T;
22
+ export declare function withReviewSearchTxt<T extends Partial<ReviewPlain>>(p: T): T;
23
+ export declare function withOrderSearchTxt<T extends Partial<OrderPlain>>(p: T): T;
24
24
  export declare function withCouponSearchTxt<T extends Partial<CouponDocument>>(p: T): T;
25
- export declare function withOfferSearchTxt<T extends Partial<OfferDocument>>(p: T): T;
25
+ export declare function withOfferSearchTxt<T extends Partial<OfferPlain>>(p: T): T;
26
26
  export declare function withScammerSearchTxt<T extends Partial<ScammerDocument>>(p: T): T;
@@ -19,15 +19,37 @@ export function withEventSearchTxt(p) {
19
19
  export function withBlogSearchTxt(p) {
20
20
  return { ...p, searchTxt: buildBlogSearchTxt(p) };
21
21
  }
22
+ /*
23
+ * Bounded by `ReviewPlain` for the same reason as the offer wrapper: seed
24
+ * fixtures hold plaintext and `seed-cli` encrypts on write, and
25
+ * `string`/`Encrypted<string>` are incompatible in both directions.
26
+ * `buildReviewSearchTxt` deliberately does NOT read `userName` — it is
27
+ * encrypted, and indexing it would undo the encryption (D1).
28
+ */
22
29
  export function withReviewSearchTxt(p) {
23
30
  return { ...p, searchTxt: buildReviewSearchTxt(p) };
24
31
  }
32
+ /*
33
+ * Bounded by `OrderPlain`: seed fixtures hold plaintext and `seed-cli`
34
+ * encrypts on write. `buildOrderSearchTxt` reads the product, store, tracking
35
+ * number, items and location — never `userEmail` (D1).
36
+ */
25
37
  export function withOrderSearchTxt(p) {
26
38
  return { ...p, searchTxt: buildOrderSearchTxt(p) };
27
39
  }
28
40
  export function withCouponSearchTxt(p) {
29
41
  return { ...p, searchTxt: buildCouponSearchTxt(p) };
30
42
  }
43
+ /*
44
+ * Bounded by `OfferPlain`, not `OfferDocument`.
45
+ *
46
+ * Seed fixtures hold plaintext and `seed-cli` encrypts on write, so the array
47
+ * this maps over is `Partial<OfferPlain>[]`. `string` and `Encrypted<string>`
48
+ * are incompatible in both directions, so a document-bounded generic rejects
49
+ * the plain shape outright. The function reads `buyerName` for tokens and does
50
+ * not care which it gets — and `buildOfferSearchTxt` is deliberately given the
51
+ * PLAINTEXT one: tokenising ciphertext would index base64.
52
+ */
31
53
  export function withOfferSearchTxt(p) {
32
54
  return { ...p, searchTxt: buildOfferSearchTxt(p) };
33
55
  }
@@ -1,2 +1,2 @@
1
- import type { AddressDocument } from "../features/addresses/schemas/firestore";
2
- export declare const addressesSeedData: AddressDocument[];
1
+ import type { AddressPlain } from "../features/addresses/schemas/firestore";
2
+ export declare const addressesSeedData: AddressPlain[];
@@ -0,0 +1,34 @@
1
+ export declare const AUTHENTICITY_KNOWLEDGE_COLLECTION = "authenticityKnowledge";
2
+ /** A date-code row, a generation summary, or (future) a marque. */
3
+ export type AuthenticityKnowledgeKind = "date-code" | "generation" | "marque";
4
+ /**
5
+ * What the community has recorded about a box code.
6
+ *
7
+ * 🛑 `recorded-midfake` is a statement about a BATCH, never about a seller, and
8
+ * never "counterfeit". A midfake is Takara-Tomy-blueprint product of reduced
9
+ * quality and there is no official Takara Tomy statement acknowledging the runs.
10
+ */
11
+ export type AuthenticityCodeVerdict = "recorded-original" | "recorded-midfake" | "unresolved";
12
+ export interface AuthenticityKnowledgeDocument {
13
+ id: string;
14
+ kind: AuthenticityKnowledgeKind;
15
+ seedPurpose: "permanent";
16
+ /** date-code rows only. */
17
+ code?: string;
18
+ verdict?: AuthenticityCodeVerdict;
19
+ products?: string[];
20
+ distributors?: string[];
21
+ /** Derived FROM the code under the disputed month-day-year reading. */
22
+ derivedDate?: string | null;
23
+ /** True where the source's own written date contradicts its own stated rule. */
24
+ sourceDateDiffers?: boolean;
25
+ generation?: string;
26
+ /** generation rows only. */
27
+ canonicalReleaseCount?: number;
28
+ releasesWithRetailCode?: number;
29
+ exampleCodes?: string[];
30
+ hasDateCodeTable?: boolean;
31
+ }
32
+ export declare const authenticityKnowledgeSeedData: AuthenticityKnowledgeDocument[];
33
+ /** Asserted downstream so a silent drop is loud. */
34
+ export declare const AUTHENTICITY_KNOWLEDGE_COUNT = 104;