@aglyn/plugins-commerce 1.0.0-beta.284 → 1.0.0-beta.287

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 (420) hide show
  1. package/README.md +1 -1
  2. package/package.json +13 -13
  3. package/src/lib/components/cart.js +25 -12
  4. package/src/lib/components/cart.js.map +1 -1
  5. package/src/lib/components/commerce-console-page.js +70 -13
  6. package/src/lib/components/commerce-console-page.js.map +1 -1
  7. package/src/lib/components/console/order-detail-dialog.component.js +2 -1
  8. package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
  9. package/src/lib/components/console/payment-methods-card.component.js +1 -1
  10. package/src/lib/components/console/payment-methods-card.component.js.map +1 -1
  11. package/src/lib/components/console/pos/pos-cart-panel.component.d.ts +5 -0
  12. package/src/lib/components/console/pos/pos-cart-panel.component.js +18 -12
  13. package/src/lib/components/console/pos/pos-cart-panel.component.js.map +1 -1
  14. package/src/lib/components/console/pos/pos-hardware-api.d.ts +76 -5
  15. package/src/lib/components/console/pos/pos-hardware-api.js +53 -11
  16. package/src/lib/components/console/pos/pos-hardware-api.js.map +1 -1
  17. package/src/lib/components/console/pos/pos-hardware-buyer.component.d.ts +18 -0
  18. package/src/lib/components/console/pos/pos-hardware-buyer.component.js +629 -0
  19. package/src/lib/components/console/pos/pos-hardware-buyer.component.js.map +1 -0
  20. package/src/lib/components/console/pos/pos-hardware-sale-api.d.ts +162 -0
  21. package/src/lib/components/console/pos/pos-hardware-sale-api.js +122 -0
  22. package/src/lib/components/console/pos/pos-hardware-sale-api.js.map +1 -0
  23. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.d.ts +39 -0
  24. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js +251 -0
  25. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js.map +1 -0
  26. package/src/lib/components/console/pos/use-pos-display.js +50 -0
  27. package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
  28. package/src/lib/components/console/pos-cellular-control.component.d.ts +41 -0
  29. package/src/lib/components/console/pos-cellular-control.component.js +211 -0
  30. package/src/lib/components/console/pos-cellular-control.component.js.map +1 -0
  31. package/src/lib/components/console/pos-devices-card.component.d.ts +9 -1
  32. package/src/lib/components/console/pos-devices-card.component.js +47 -15
  33. package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
  34. package/src/lib/components/console/pos-display/pos-display-api.d.ts +6 -0
  35. package/src/lib/components/console/pos-display/pos-display-api.js +8 -1
  36. package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
  37. package/src/lib/components/console/pos-display-page.component.d.ts +13 -0
  38. package/src/lib/components/console/pos-display-page.component.js +44 -2
  39. package/src/lib/components/console/pos-display-page.component.js.map +1 -1
  40. package/src/lib/components/console/pos-hardware-card.component.d.ts +12 -4
  41. package/src/lib/components/console/pos-hardware-card.component.js +157 -36
  42. package/src/lib/components/console/pos-hardware-card.component.js.map +1 -1
  43. package/src/lib/components/console/pos-hardware-orders-staff-page.component.js +360 -80
  44. package/src/lib/components/console/pos-hardware-orders-staff-page.component.js.map +1 -1
  45. package/src/lib/components/console/pos-hardware-terms-page.component.d.ts +34 -0
  46. package/src/lib/components/console/pos-hardware-terms-page.component.js +257 -0
  47. package/src/lib/components/console/pos-hardware-terms-page.component.js.map +1 -0
  48. package/src/lib/components/console/pos-hardware-terms-sign-page.component.d.ts +27 -0
  49. package/src/lib/components/console/pos-hardware-terms-sign-page.component.js +104 -0
  50. package/src/lib/components/console/pos-hardware-terms-sign-page.component.js.map +1 -0
  51. package/src/lib/components/console/pos-hardware-waiting-card.component.d.ts +24 -0
  52. package/src/lib/components/console/pos-hardware-waiting-card.component.js +205 -0
  53. package/src/lib/components/console/pos-hardware-waiting-card.component.js.map +1 -0
  54. package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js +297 -201
  55. package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js.map +1 -1
  56. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.d.ts +3 -0
  57. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js +260 -92
  58. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js.map +1 -1
  59. package/src/lib/components/console/pos-ops/pos-operations-bar.component.d.ts +9 -0
  60. package/src/lib/components/console/pos-ops/pos-operations-bar.component.js +15 -6
  61. package/src/lib/components/console/pos-ops/pos-operations-bar.component.js.map +1 -1
  62. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.d.ts +25 -0
  63. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js +136 -0
  64. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js.map +1 -0
  65. package/src/lib/components/console/pos-ops/pos-shift-panel.component.d.ts +6 -0
  66. package/src/lib/components/console/pos-ops/pos-shift-panel.component.js +48 -31
  67. package/src/lib/components/console/pos-ops/pos-shift-panel.component.js.map +1 -1
  68. package/src/lib/components/console/pos-page.component.d.ts +1 -1
  69. package/src/lib/components/console/pos-page.component.js +63 -12
  70. package/src/lib/components/console/pos-page.component.js.map +1 -1
  71. package/src/lib/components/console/pos-reader-splash-setting.component.js +1 -1
  72. package/src/lib/components/console/pos-reader-splash-setting.component.js.map +1 -1
  73. package/src/lib/components/console/product-check-in-fields.component.d.ts +4 -2
  74. package/src/lib/components/console/product-check-in-fields.component.js +60 -14
  75. package/src/lib/components/console/product-check-in-fields.component.js.map +1 -1
  76. package/src/lib/components/console/product-editor-dialog.component.js +44 -1
  77. package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
  78. package/src/lib/components/console/product-hardware-sku-field.component.d.ts +19 -0
  79. package/src/lib/components/console/product-hardware-sku-field.component.js +92 -0
  80. package/src/lib/components/console/product-hardware-sku-field.component.js.map +1 -0
  81. package/src/lib/components/console/product-kiosk-offer-field.component.d.ts +22 -0
  82. package/src/lib/components/console/product-kiosk-offer-field.component.js +94 -0
  83. package/src/lib/components/console/product-kiosk-offer-field.component.js.map +1 -0
  84. package/src/lib/components/console/product-register-fields.component.d.ts +4 -0
  85. package/src/lib/components/console/product-register-fields.component.js +31 -2
  86. package/src/lib/components/console/product-register-fields.component.js.map +1 -1
  87. package/src/lib/components/console/products-hub-card.component.js +11 -2
  88. package/src/lib/components/console/products-hub-card.component.js.map +1 -1
  89. package/src/lib/components/console/register-hardware-card.component.d.ts +11 -0
  90. package/src/lib/components/console/register-hardware-card.component.js +56 -27
  91. package/src/lib/components/console/register-hardware-card.component.js.map +1 -1
  92. package/src/lib/components/console/reservation-guests-dialog.component.d.ts +28 -0
  93. package/src/lib/components/console/reservation-guests-dialog.component.js +189 -0
  94. package/src/lib/components/console/reservation-guests-dialog.component.js.map +1 -0
  95. package/src/lib/components/console/reservations-card.component.d.ts +9 -0
  96. package/src/lib/components/console/reservations-card.component.js +158 -23
  97. package/src/lib/components/console/reservations-card.component.js.map +1 -1
  98. package/src/lib/components/console/shippingeasy-card.component.js +1 -1
  99. package/src/lib/components/console/shippingeasy-card.component.js.map +1 -1
  100. package/src/lib/components/console/shipstation-card.component.d.ts +1 -1
  101. package/src/lib/components/console/shipstation-card.component.js +3 -3
  102. package/src/lib/components/console/shipstation-card.component.js.map +1 -1
  103. package/src/lib/components/product-detail.d.ts +4 -0
  104. package/src/lib/components/product-detail.js +40 -5
  105. package/src/lib/components/product-detail.js.map +1 -1
  106. package/src/lib/components/product-reviews.js +28 -11
  107. package/src/lib/components/product-reviews.js.map +1 -1
  108. package/src/lib/components/reservation-widget.js +28 -5
  109. package/src/lib/components/reservation-widget.js.map +1 -1
  110. package/src/lib/components/use-day-picker.d.ts +25 -0
  111. package/src/lib/components/use-day-picker.js +57 -0
  112. package/src/lib/components/use-day-picker.js.map +1 -0
  113. package/src/lib/constants/operator-alerts.d.ts +55 -0
  114. package/src/lib/constants/operator-alerts.js +156 -1
  115. package/src/lib/constants/operator-alerts.js.map +1 -1
  116. package/src/lib/declarations.console-server.js +54 -1
  117. package/src/lib/declarations.console-server.js.map +1 -1
  118. package/src/lib/declarations.d.ts +4 -2
  119. package/src/lib/declarations.js +11 -4
  120. package/src/lib/declarations.js.map +1 -1
  121. package/src/lib/declarations.server.js +9 -0
  122. package/src/lib/declarations.server.js.map +1 -1
  123. package/src/lib/model/commerce-cart.d.ts +9 -1
  124. package/src/lib/model/commerce-cart.js +4 -3
  125. package/src/lib/model/commerce-cart.js.map +1 -1
  126. package/src/lib/model/commerce-check-in-product.d.ts +26 -0
  127. package/src/lib/model/commerce-check-in-product.js +64 -2
  128. package/src/lib/model/commerce-check-in-product.js.map +1 -1
  129. package/src/lib/model/commerce-check-in-record.d.ts +127 -0
  130. package/src/lib/model/commerce-check-in-record.js +36 -0
  131. package/src/lib/model/commerce-check-in-record.js.map +1 -0
  132. package/src/lib/model/commerce-check-in.d.ts +91 -87
  133. package/src/lib/model/commerce-check-in.js +186 -62
  134. package/src/lib/model/commerce-check-in.js.map +1 -1
  135. package/src/lib/model/commerce-kiosk-offer.d.ts +31 -0
  136. package/src/lib/model/commerce-kiosk-offer.js +35 -0
  137. package/src/lib/model/commerce-kiosk-offer.js.map +1 -0
  138. package/src/lib/model/commerce-orders.d.ts +76 -0
  139. package/src/lib/model/commerce-orders.js +6 -0
  140. package/src/lib/model/commerce-orders.js.map +1 -1
  141. package/src/lib/model/commerce-pos-day-report.d.ts +54 -1
  142. package/src/lib/model/commerce-pos-day-report.js +39 -2
  143. package/src/lib/model/commerce-pos-day-report.js.map +1 -1
  144. package/src/lib/model/commerce-pos-offline.d.ts +1 -1
  145. package/src/lib/model/commerce-pos-offline.js +6 -1
  146. package/src/lib/model/commerce-pos-offline.js.map +1 -1
  147. package/src/lib/model/commerce-pos-ops.js +3 -2
  148. package/src/lib/model/commerce-pos-ops.js.map +1 -1
  149. package/src/lib/model/commerce-pos.d.ts +36 -3
  150. package/src/lib/model/commerce-pos.js +14 -6
  151. package/src/lib/model/commerce-pos.js.map +1 -1
  152. package/src/lib/model/commerce-receipt.js +3 -2
  153. package/src/lib/model/commerce-receipt.js.map +1 -1
  154. package/src/lib/model/commerce-reservations.d.ts +69 -4
  155. package/src/lib/model/commerce-reservations.js +57 -5
  156. package/src/lib/model/commerce-reservations.js.map +1 -1
  157. package/src/lib/model/commerce.d.ts +66 -0
  158. package/src/lib/model/commerce.js +15 -0
  159. package/src/lib/model/commerce.js.map +1 -1
  160. package/src/lib/model/order-list-fields.d.ts +11 -0
  161. package/src/lib/model/order-list-fields.js +17 -1
  162. package/src/lib/model/order-list-fields.js.map +1 -1
  163. package/src/lib/model/own-store-tax-summary.d.ts +152 -0
  164. package/src/lib/model/own-store-tax-summary.js +288 -0
  165. package/src/lib/model/own-store-tax-summary.js.map +1 -0
  166. package/src/lib/model/plugin-permissions.d.ts +67 -0
  167. package/src/lib/model/plugin-permissions.js +224 -7
  168. package/src/lib/model/plugin-permissions.js.map +1 -1
  169. package/src/lib/model/pos-cellular.d.ts +223 -0
  170. package/src/lib/model/pos-cellular.js +293 -0
  171. package/src/lib/model/pos-cellular.js.map +1 -0
  172. package/src/lib/model/pos-hardware-in-person.d.ts +98 -0
  173. package/src/lib/model/pos-hardware-in-person.js +224 -0
  174. package/src/lib/model/pos-hardware-in-person.js.map +1 -0
  175. package/src/lib/model/pos-hardware-tax-summary.d.ts +166 -0
  176. package/src/lib/model/pos-hardware-tax-summary.js +225 -0
  177. package/src/lib/model/pos-hardware-tax-summary.js.map +1 -0
  178. package/src/lib/model/pos-hardware-terms.d.ts +74 -0
  179. package/src/lib/model/pos-hardware-terms.js +115 -0
  180. package/src/lib/model/pos-hardware-terms.js.map +1 -0
  181. package/src/lib/model/pos-hardware.d.ts +349 -7
  182. package/src/lib/model/pos-hardware.js +291 -20
  183. package/src/lib/model/pos-hardware.js.map +1 -1
  184. package/src/lib/model/product-write.d.ts +10 -0
  185. package/src/lib/model/product-write.js +4 -2
  186. package/src/lib/model/product-write.js.map +1 -1
  187. package/src/lib/plugin.js +16 -0
  188. package/src/lib/plugin.js.map +1 -1
  189. package/src/lib/server/billing-webhook.js +25 -1
  190. package/src/lib/server/billing-webhook.js.map +1 -1
  191. package/src/lib/server/cancel-order.js +7 -5
  192. package/src/lib/server/cancel-order.js.map +1 -1
  193. package/src/lib/server/cart-checkout.js +20 -8
  194. package/src/lib/server/cart-checkout.js.map +1 -1
  195. package/src/lib/server/cart.js +29 -0
  196. package/src/lib/server/cart.js.map +1 -1
  197. package/src/lib/server/checkout.js +42 -13
  198. package/src/lib/server/checkout.js.map +1 -1
  199. package/src/lib/server/collection-membership.d.ts +4 -0
  200. package/src/lib/server/collection-membership.js +5 -10
  201. package/src/lib/server/collection-membership.js.map +1 -1
  202. package/src/lib/server/commerce-site-keys.d.ts +29 -0
  203. package/src/lib/server/commerce-site-keys.js +40 -0
  204. package/src/lib/server/commerce-site-keys.js.map +1 -0
  205. package/src/lib/server/draft-order.js +8 -5
  206. package/src/lib/server/draft-order.js.map +1 -1
  207. package/src/lib/server/fulfill-order.js +7 -5
  208. package/src/lib/server/fulfill-order.js.map +1 -1
  209. package/src/lib/server/gift-cards.js +8 -5
  210. package/src/lib/server/gift-cards.js.map +1 -1
  211. package/src/lib/server/local-fulfillment-status.js +9 -6
  212. package/src/lib/server/local-fulfillment-status.js.map +1 -1
  213. package/src/lib/server/member-post.js +6 -5
  214. package/src/lib/server/member-post.js.map +1 -1
  215. package/src/lib/server/membership-admin-password.d.ts +4 -2
  216. package/src/lib/server/membership-admin-password.js +10 -8
  217. package/src/lib/server/membership-admin-password.js.map +1 -1
  218. package/src/lib/server/membership-admin-remove.d.ts +7 -5
  219. package/src/lib/server/membership-admin-remove.js +9 -9
  220. package/src/lib/server/membership-admin-remove.js.map +1 -1
  221. package/src/lib/server/order-notifications.js +5 -2
  222. package/src/lib/server/order-notifications.js.map +1 -1
  223. package/src/lib/server/order-print.js +7 -5
  224. package/src/lib/server/order-print.js.map +1 -1
  225. package/src/lib/server/order-receipt-send.js +8 -5
  226. package/src/lib/server/order-receipt-send.js.map +1 -1
  227. package/src/lib/server/orders-shipping-prepare.js +9 -6
  228. package/src/lib/server/orders-shipping-prepare.js.map +1 -1
  229. package/src/lib/server/own-store-tax-return-source.d.ts +47 -0
  230. package/src/lib/server/own-store-tax-return-source.js +312 -0
  231. package/src/lib/server/own-store-tax-return-source.js.map +1 -0
  232. package/src/lib/server/payment-methods.js +13 -9
  233. package/src/lib/server/payment-methods.js.map +1 -1
  234. package/src/lib/server/pos-auth.d.ts +37 -6
  235. package/src/lib/server/pos-auth.js +40 -15
  236. package/src/lib/server/pos-auth.js.map +1 -1
  237. package/src/lib/server/pos-cellular-billing.d.ts +81 -0
  238. package/src/lib/server/pos-cellular-billing.js +711 -0
  239. package/src/lib/server/pos-cellular-billing.js.map +1 -0
  240. package/src/lib/server/pos-cellular-notify.d.ts +47 -0
  241. package/src/lib/server/pos-cellular-notify.js +150 -0
  242. package/src/lib/server/pos-cellular-notify.js.map +1 -0
  243. package/src/lib/server/pos-cellular.d.ts +88 -0
  244. package/src/lib/server/pos-cellular.js +339 -0
  245. package/src/lib/server/pos-cellular.js.map +1 -0
  246. package/src/lib/server/pos-check-in.d.ts +5 -1
  247. package/src/lib/server/pos-check-in.js +296 -28
  248. package/src/lib/server/pos-check-in.js.map +1 -1
  249. package/src/lib/server/pos-day-report.js +29 -3
  250. package/src/lib/server/pos-day-report.js.map +1 -1
  251. package/src/lib/server/pos-display.d.ts +16 -0
  252. package/src/lib/server/pos-display.js +129 -2
  253. package/src/lib/server/pos-display.js.map +1 -1
  254. package/src/lib/server/pos-hardware-admin.d.ts +10 -1
  255. package/src/lib/server/pos-hardware-admin.js +250 -84
  256. package/src/lib/server/pos-hardware-admin.js.map +1 -1
  257. package/src/lib/server/pos-hardware-attach.d.ts +105 -0
  258. package/src/lib/server/pos-hardware-attach.js +443 -0
  259. package/src/lib/server/pos-hardware-attach.js.map +1 -0
  260. package/src/lib/server/pos-hardware-buyer-lookup.d.ts +58 -0
  261. package/src/lib/server/pos-hardware-buyer-lookup.js +180 -0
  262. package/src/lib/server/pos-hardware-buyer-lookup.js.map +1 -0
  263. package/src/lib/server/pos-hardware-buyer-record.d.ts +29 -0
  264. package/src/lib/server/pos-hardware-buyer-record.js +86 -0
  265. package/src/lib/server/pos-hardware-buyer-record.js.map +1 -0
  266. package/src/lib/server/pos-hardware-cancel.d.ts +58 -0
  267. package/src/lib/server/pos-hardware-cancel.js +147 -0
  268. package/src/lib/server/pos-hardware-cancel.js.map +1 -0
  269. package/src/lib/server/pos-hardware-closure-notices.d.ts +27 -0
  270. package/src/lib/server/pos-hardware-closure-notices.js +85 -0
  271. package/src/lib/server/pos-hardware-closure-notices.js.map +1 -0
  272. package/src/lib/server/pos-hardware-closure.d.ts +60 -0
  273. package/src/lib/server/pos-hardware-closure.js +153 -0
  274. package/src/lib/server/pos-hardware-closure.js.map +1 -0
  275. package/src/lib/server/pos-hardware-in-person.d.ts +61 -0
  276. package/src/lib/server/pos-hardware-in-person.js +236 -0
  277. package/src/lib/server/pos-hardware-in-person.js.map +1 -0
  278. package/src/lib/server/pos-hardware-notify.d.ts +40 -2
  279. package/src/lib/server/pos-hardware-notify.js +195 -14
  280. package/src/lib/server/pos-hardware-notify.js.map +1 -1
  281. package/src/lib/server/pos-hardware-readers.d.ts +115 -0
  282. package/src/lib/server/pos-hardware-readers.js +430 -0
  283. package/src/lib/server/pos-hardware-readers.js.map +1 -0
  284. package/src/lib/server/pos-hardware-returns.d.ts +116 -0
  285. package/src/lib/server/pos-hardware-returns.js +502 -0
  286. package/src/lib/server/pos-hardware-returns.js.map +1 -0
  287. package/src/lib/server/pos-hardware-sale-fields.d.ts +28 -0
  288. package/src/lib/server/pos-hardware-sale-fields.js +44 -0
  289. package/src/lib/server/pos-hardware-sale-fields.js.map +1 -0
  290. package/src/lib/server/pos-hardware-sale.d.ts +54 -0
  291. package/src/lib/server/pos-hardware-sale.js +369 -0
  292. package/src/lib/server/pos-hardware-sale.js.map +1 -0
  293. package/src/lib/server/pos-hardware-tax-return-source.d.ts +99 -0
  294. package/src/lib/server/pos-hardware-tax-return-source.js +462 -0
  295. package/src/lib/server/pos-hardware-tax-return-source.js.map +1 -0
  296. package/src/lib/server/pos-hardware-terms.d.ts +64 -0
  297. package/src/lib/server/pos-hardware-terms.js +154 -0
  298. package/src/lib/server/pos-hardware-terms.js.map +1 -0
  299. package/src/lib/server/pos-hardware-user-eraser.d.ts +3 -0
  300. package/src/lib/server/pos-hardware-user-eraser.js +31 -7
  301. package/src/lib/server/pos-hardware-user-eraser.js.map +1 -1
  302. package/src/lib/server/pos-hardware-webhook.d.ts +5 -0
  303. package/src/lib/server/pos-hardware-webhook.js +51 -6
  304. package/src/lib/server/pos-hardware-webhook.js.map +1 -1
  305. package/src/lib/server/pos-hardware.d.ts +74 -1
  306. package/src/lib/server/pos-hardware.js +175 -10
  307. package/src/lib/server/pos-hardware.js.map +1 -1
  308. package/src/lib/server/pos-kiosk.d.ts +2 -0
  309. package/src/lib/server/pos-kiosk.js +17 -12
  310. package/src/lib/server/pos-kiosk.js.map +1 -1
  311. package/src/lib/server/pos-offline-card-order.d.ts +64 -0
  312. package/src/lib/server/pos-offline-card-order.js +102 -0
  313. package/src/lib/server/pos-offline-card-order.js.map +1 -0
  314. package/src/lib/server/pos-offline-card-reconcile.d.ts +67 -1
  315. package/src/lib/server/pos-offline-card-reconcile.js +215 -18
  316. package/src/lib/server/pos-offline-card-reconcile.js.map +1 -1
  317. package/src/lib/server/pos-offline-sync.d.ts +39 -0
  318. package/src/lib/server/pos-offline-sync.js +190 -55
  319. package/src/lib/server/pos-offline-sync.js.map +1 -1
  320. package/src/lib/server/pos-ops-gate.d.ts +15 -4
  321. package/src/lib/server/pos-ops-gate.js +42 -9
  322. package/src/lib/server/pos-ops-gate.js.map +1 -1
  323. package/src/lib/server/pos-ops-routes.js +24 -0
  324. package/src/lib/server/pos-ops-routes.js.map +1 -1
  325. package/src/lib/server/pos-order-refund-ids.d.ts +28 -0
  326. package/src/lib/server/pos-order-refund-ids.js +31 -0
  327. package/src/lib/server/pos-order-refund-ids.js.map +1 -0
  328. package/src/lib/server/pos-order.js +52 -49
  329. package/src/lib/server/pos-order.js.map +1 -1
  330. package/src/lib/server/pos-payment.js +1 -1
  331. package/src/lib/server/pos-payment.js.map +1 -1
  332. package/src/lib/server/pos-reader-splash-admin.js +30 -32
  333. package/src/lib/server/pos-reader-splash-admin.js.map +1 -1
  334. package/src/lib/server/pos-reader-splash-images-route.d.ts +17 -0
  335. package/src/lib/server/pos-reader-splash-images-route.js +113 -0
  336. package/src/lib/server/pos-reader-splash-images-route.js.map +1 -0
  337. package/src/lib/server/pos-reader-splash-images.d.ts +51 -0
  338. package/src/lib/server/pos-reader-splash-images.js +123 -0
  339. package/src/lib/server/pos-reader-splash-images.js.map +1 -0
  340. package/src/lib/server/pos-reader-splash.d.ts +68 -1
  341. package/src/lib/server/pos-reader-splash.js +182 -11
  342. package/src/lib/server/pos-reader-splash.js.map +1 -1
  343. package/src/lib/server/pos-readers.d.ts +29 -0
  344. package/src/lib/server/pos-readers.js +134 -35
  345. package/src/lib/server/pos-readers.js.map +1 -1
  346. package/src/lib/server/pos-return.d.ts +10 -0
  347. package/src/lib/server/pos-return.js +26 -1
  348. package/src/lib/server/pos-return.js.map +1 -1
  349. package/src/lib/server/pos-sale.js +6 -1
  350. package/src/lib/server/pos-sale.js.map +1 -1
  351. package/src/lib/server/pos-shift.js +11 -0
  352. package/src/lib/server/pos-shift.js.map +1 -1
  353. package/src/lib/server/pos-staff-pin.js +25 -20
  354. package/src/lib/server/pos-staff-pin.js.map +1 -1
  355. package/src/lib/server/pos-terminal.d.ts +14 -4
  356. package/src/lib/server/pos-terminal.js +34 -38
  357. package/src/lib/server/pos-terminal.js.map +1 -1
  358. package/src/lib/server/printers.d.ts +7 -3
  359. package/src/lib/server/printers.js +18 -12
  360. package/src/lib/server/printers.js.map +1 -1
  361. package/src/lib/server/product-drafts.d.ts +11 -1
  362. package/src/lib/server/product-drafts.js +12 -8
  363. package/src/lib/server/product-drafts.js.map +1 -1
  364. package/src/lib/server/product.d.ts +15 -1
  365. package/src/lib/server/product.js +16 -3
  366. package/src/lib/server/product.js.map +1 -1
  367. package/src/lib/server/products-write.d.ts +26 -2
  368. package/src/lib/server/products-write.js +19 -7
  369. package/src/lib/server/products-write.js.map +1 -1
  370. package/src/lib/server/refund.js +34 -11
  371. package/src/lib/server/refund.js.map +1 -1
  372. package/src/lib/server/reservation-availability-query.d.ts +8 -0
  373. package/src/lib/server/reservation-availability-query.js +11 -1
  374. package/src/lib/server/reservation-availability-query.js.map +1 -1
  375. package/src/lib/server/reservation-availability.d.ts +1 -1
  376. package/src/lib/server/reservation-availability.js +7 -2
  377. package/src/lib/server/reservation-availability.js.map +1 -1
  378. package/src/lib/server/reservation-guests.d.ts +32 -0
  379. package/src/lib/server/reservation-guests.js +285 -0
  380. package/src/lib/server/reservation-guests.js.map +1 -0
  381. package/src/lib/server/reservation-walk-in.d.ts +11 -1
  382. package/src/lib/server/reservation-walk-in.js +56 -12
  383. package/src/lib/server/reservation-walk-in.js.map +1 -1
  384. package/src/lib/server/reserve.js +18 -5
  385. package/src/lib/server/reserve.js.map +1 -1
  386. package/src/lib/server/returns.js +9 -6
  387. package/src/lib/server/returns.js.map +1 -1
  388. package/src/lib/server/reviews.d.ts +22 -2
  389. package/src/lib/server/reviews.js +88 -20
  390. package/src/lib/server/reviews.js.map +1 -1
  391. package/src/lib/server/shipping-connectors.js +10 -11
  392. package/src/lib/server/shipping-connectors.js.map +1 -1
  393. package/src/lib/server/site-page-resolver.js +20 -3
  394. package/src/lib/server/site-page-resolver.js.map +1 -1
  395. package/src/lib/server/store-day.d.ts +33 -0
  396. package/src/lib/server/store-day.js +46 -0
  397. package/src/lib/server/store-day.js.map +1 -0
  398. package/src/lib/server/store-setup-ai-writer.d.ts +2 -1
  399. package/src/lib/server/store-setup-ai-writer.js +5 -6
  400. package/src/lib/server/store-setup-ai-writer.js.map +1 -1
  401. package/src/lib/server/storefront-tax.d.ts +13 -0
  402. package/src/lib/server/storefront-tax.js +8 -1
  403. package/src/lib/server/storefront-tax.js.map +1 -1
  404. package/src/lib/server/tax-return-source.d.ts +32 -3
  405. package/src/lib/server/tax-return-source.js +99 -20
  406. package/src/lib/server/tax-return-source.js.map +1 -1
  407. package/src/lib/server.js +100 -2
  408. package/src/lib/server.js.map +1 -1
  409. package/src/lib/testing/fake-firestore.js +58 -16
  410. package/src/lib/testing/fake-firestore.js.map +1 -1
  411. package/src/lib/testing/pos-ops-memory-firestore.js +18 -4
  412. package/src/lib/testing/pos-ops-memory-firestore.js.map +1 -1
  413. package/src/lib/testing/site-register-permissions.d.ts +29 -0
  414. package/src/lib/testing/site-register-permissions.js +38 -0
  415. package/src/lib/testing/site-register-permissions.js.map +1 -0
  416. package/src/lib/transfer/tracking.server.js +8 -5
  417. package/src/lib/transfer/tracking.server.js.map +1 -1
  418. package/src/lib/utils/add-to-cart.d.ts +2 -0
  419. package/src/lib/utils/add-to-cart.js +6 -3
  420. package/src/lib/utils/add-to-cart.js.map +1 -1
@@ -95,12 +95,167 @@ export const COMMERCE_FEE_REPRICE_REFUSED = {
95
95
  dedupeWindowMinutes: 30 * DAY,
96
96
  defaultEnabled: true
97
97
  };
98
+ /**
99
+ * A card taken offline on the Aglyn POS app's reader reached Stripe, but the
100
+ * sale it belongs to never synced (AGL-4039). Raised by the hourly sweep once
101
+ * the intent has waited past `POS_OFFLINE_CARD_UNSYNCED_ALERT_MS`, while there
102
+ * is still time to sync it before Stripe's authorization lapses.
103
+ */ export const COMMERCE_POS_OFFLINE_CARD_UNSYNCED = {
104
+ type: 'commerce.posOfflineCardUnsynced',
105
+ pluginId: BUNDLE_ID,
106
+ label: 'Offline card sale never synced',
107
+ description: 'A card taken offline on a register reached Stripe, but its sale never reached the store. An authorized card is never captured and lapses after about two days; a charged one has no order. The site’s managers are told too.',
108
+ tier: 'should',
109
+ category: 'payments',
110
+ title: 'A {{amount}} card taken offline has no sale',
111
+ body: 'Payment {{paymentIntentId}} ({{status}}) for site {{site}} was taken offline on register {{registerId}} {{age}} ago, and its sale never synced. Ask the store to open that register signed in as the member who rang it so the sale syncs. An authorized card that is not captured lapses about two days after it was taken.',
112
+ delivery: 'immediate',
113
+ dedupeWindowMinutes: 30 * DAY,
114
+ defaultEnabled: true
115
+ };
116
+ /**
117
+ * A card taken offline was made out to a Stripe account that is not the
118
+ * store's (AGL-4039): a stale offline kit, or a register that was tampered
119
+ * with. The sync never captures it and records the order unpaid.
120
+ */ export const COMMERCE_POS_OFFLINE_CARD_WRONG_ACCOUNT = {
121
+ type: 'commerce.posOfflineCardWrongAccount',
122
+ pluginId: BUNDLE_ID,
123
+ label: 'Offline card made out to another Stripe account',
124
+ description: 'A card taken offline on a register was set to pay a Stripe account that is not the store’s. The sale was recorded unpaid and the card was not captured. Check whether the account is the store’s own previous one before capturing it in Stripe, or let the authorization lapse.',
125
+ tier: 'must',
126
+ category: 'payments',
127
+ title: 'A {{amount}} offline card was made out to another Stripe account',
128
+ body: 'Payment {{paymentIntentId}} ({{status}}) on order {{orderId}} for site {{site}} pays account {{destination}}, but the store’s account is {{expected}}. The order is recorded unpaid and nothing was captured. If the payment already succeeded, the money is in that other account: recover or refund it in Stripe.',
129
+ delivery: 'immediate',
130
+ dedupeWindowMinutes: 30 * DAY,
131
+ defaultEnabled: true
132
+ };
133
+ /**
134
+ * A hardware order already placed with Stripe was canceled and refunded
135
+ * because its workspace was deleted or the account that placed it closed
136
+ * (AGL-4038). The merchant has their money back; the platform has paid Stripe
137
+ * for hardware that is still on its way unless someone cancels it there.
138
+ */ export const COMMERCE_POS_HARDWARE_CANCELED_AFTER_ORDERING = {
139
+ type: 'commerce.posHardwareCanceledAfterOrdering',
140
+ pluginId: BUNDLE_ID,
141
+ label: 'Hardware order canceled after it was placed with Stripe',
142
+ description: 'A workspace was deleted, or the account that placed a hardware order was closed, after staff had placed the order with Stripe. The merchant was refunded in full. Cancel the order in the Stripe Dashboard’s Terminal hardware shop before it ships, or arrange its return with Stripe.',
143
+ tier: 'must',
144
+ category: 'payments',
145
+ title: 'Cancel hardware order {{orderNumber}} with Stripe',
146
+ // `{{stripeOrder}}` is ` (Stripe order …)` or blank, so the sentence reads
147
+ // either way.
148
+ body: 'Hardware order {{orderNumber}} ({{amount}}: {{items}}) was canceled and refunded in full to the merchant because {{reason}}, but it had already been placed with Stripe{{stripeOrder}}. Cancel it in the Stripe Dashboard’s Terminal hardware shop before it ships; if it has shipped, arrange its return with Stripe.',
149
+ link: '/admin/hardware-orders',
150
+ delivery: 'immediate',
151
+ dedupeWindowMinutes: 30 * DAY,
152
+ defaultEnabled: true
153
+ };
154
+ /**
155
+ * Stripe refused the refund of an unshipped hardware order while its
156
+ * workspace or its buyer's account was closing (AGL-4038). The closure went
157
+ * ahead, as decided, so the order may be gone from the staff page with the
158
+ * merchant's money still held.
159
+ */ export const COMMERCE_POS_HARDWARE_REFUND_FAILED = {
160
+ type: 'commerce.posHardwareRefundFailed',
161
+ pluginId: BUNDLE_ID,
162
+ label: 'Hardware refund failed when a workspace or account closed',
163
+ description: 'A hardware order had not shipped when its workspace was deleted or the account that placed it was closed, and Stripe refused its refund. The closure went ahead without it. Refund the payment in full in the Stripe Dashboard.',
164
+ tier: 'must',
165
+ category: 'payments',
166
+ title: 'Refund hardware order {{orderNumber}} by hand: {{amount}}',
167
+ body: 'Hardware order {{orderNumber}} ({{amount}}) had not shipped when {{reason}}, and Stripe refused its refund: {{error}}. The closure went ahead. Refund payment {{paymentIntentId}} in full in the Stripe Dashboard{{orderedNote}}.',
168
+ delivery: 'immediate',
169
+ dedupeWindowMinutes: 30 * DAY,
170
+ defaultEnabled: true
171
+ };
172
+ /**
173
+ * A buyer asked to return a card reader they bought in person at the
174
+ * platform's own store (AGL-4038), from their own purchase history. Staff
175
+ * refund it from Staff → Hardware orders, or decline it there.
176
+ */ export const COMMERCE_POS_HARDWARE_RETURN_REQUESTED = {
177
+ type: 'commerce.posHardwareReturnRequested',
178
+ pluginId: BUNDLE_ID,
179
+ label: 'Card reader return requested',
180
+ description: 'A workspace asked to return card reader hardware it bought in person. Arrange the return under Stripe’s hardware terms, then refund it or decline it on Staff → Hardware orders, under Return requested.',
181
+ tier: 'should',
182
+ category: 'payments',
183
+ title: 'Return requested for hardware order {{orderNumber}} ({{amount}})',
184
+ body: 'Workspace {{orgId}} asked to return {{items}} from hardware order {{orderNumber}} ({{amount}}), bought in person: “{{reason}}”. Refund it or decline it on Staff → Hardware orders, under Return requested.',
185
+ link: '/admin/hardware-orders',
186
+ delivery: 'immediate',
187
+ dedupeWindowMinutes: 30 * DAY,
188
+ defaultEnabled: true
189
+ };
190
+ /**
191
+ * A workspace's monthly 4G charge for its Stripe Reader S710s did not
192
+ * collect (AGL-4038): the card declined or asked for authentication (the
193
+ * invoice is left open on their Billing page, which nothing retries), or
194
+ * the workspace has no Stripe customer to bill. Stripe still bills the
195
+ * platform for those readers' cellular service.
196
+ */ export const COMMERCE_POS_CELLULAR_CHARGE_FAILED = {
197
+ type: 'commerce.posCellularChargeFailed',
198
+ pluginId: BUNDLE_ID,
199
+ label: '4G charge for card readers not collected',
200
+ description: 'A workspace’s monthly charge for 4G on its Stripe Reader S710s did not collect. Stripe still bills the platform for those readers. Follow up with the workspace, or turn 4G off for its stores.',
201
+ tier: 'should',
202
+ category: 'payments',
203
+ title: '4G charge for {{month}} not collected: {{amount}}',
204
+ body: 'Workspace {{orgId}} had 4G on {{readers}} card reader(s) in {{month}}, and its charge of {{amount}} was not collected: {{reason}}. Stripe still bills the platform for those readers.',
205
+ delivery: 'immediate',
206
+ dedupeWindowMinutes: 30 * DAY,
207
+ defaultEnabled: true
208
+ };
209
+ /**
210
+ * 4G could not be turned off at Stripe for a store that is gone (AGL-4038):
211
+ * its workspace was deleted, or the store was, while its S710s had 4G. The
212
+ * readers stay on the platform's Stripe account with cellular on, which
213
+ * Stripe keeps billing the platform for, and nobody is charged for it.
214
+ */ export const COMMERCE_POS_CELLULAR_TURN_OFF_FAILED = {
215
+ type: 'commerce.posCellularTurnOffFailed',
216
+ pluginId: BUNDLE_ID,
217
+ label: '4G not turned off for a deleted store',
218
+ description: 'A store with 4G on its Stripe Reader S710s was deleted, with its workspace or on its own, and Stripe refused to turn cellular off on its Terminal configuration. Turn it off in the Stripe Dashboard, or Stripe keeps billing the platform for it.',
219
+ tier: 'must',
220
+ category: 'payments',
221
+ title: 'Turn off 4G on Terminal configuration {{configurationId}}',
222
+ body: 'Store {{hostId}} of workspace {{orgId}} was deleted while its card readers had 4G, and Stripe refused to turn cellular off on Terminal configuration {{configurationId}}. Turn it off in the Stripe Dashboard (Terminal → Locations), or Stripe keeps billing the platform for those readers.',
223
+ delivery: 'immediate',
224
+ dedupeWindowMinutes: 30 * DAY,
225
+ defaultEnabled: true
226
+ };
227
+ /**
228
+ * A workspace's monthly 4G charge stayed unpaid past the grace period
229
+ * (AGL-4038), so 4G was turned off at Stripe for every one of its stores and
230
+ * the members who manage its billing were emailed. Paying does not turn it
231
+ * back on; the merchant does, once it is paid.
232
+ */ export const COMMERCE_POS_CELLULAR_TURNED_OFF_UNPAID = {
233
+ type: 'commerce.posCellularTurnedOffUnpaid',
234
+ pluginId: BUNDLE_ID,
235
+ label: '4G turned off for an unpaid charge',
236
+ description: 'A workspace’s monthly 4G charge for its Stripe Reader S710s was still unpaid after the grace period, so 4G was turned off for its stores and the people who manage its billing were emailed. Follow up if the workspace asks; it turns 4G on again itself once the invoice is paid.',
237
+ tier: 'should',
238
+ category: 'payments',
239
+ title: '4G turned off for workspace {{orgId}}: {{month}} unpaid ({{amount}})',
240
+ body: 'Workspace {{orgId}} left its 4G charge of {{amount}} for {{month}} unpaid for {{graceDays}} days, so 4G was turned off at Stripe for its stores and the people who manage its billing were emailed. The invoice stays open on its Billing page.',
241
+ delivery: 'immediate',
242
+ dedupeWindowMinutes: 30 * DAY,
243
+ defaultEnabled: true
244
+ };
98
245
  export const COMMERCE_OPERATOR_ALERTS = [
99
246
  COMMERCE_CHARGEBACK_UNROUTABLE,
100
247
  COMMERCE_TAX_NOT_REVERSED,
101
248
  COMMERCE_SELLER_SHARE_NOT_REVERSED,
102
249
  COMMERCE_FEE_REPRICE_REFUSED,
103
- COMMERCE_POS_HARDWARE_ORDER
250
+ COMMERCE_POS_HARDWARE_ORDER,
251
+ COMMERCE_POS_OFFLINE_CARD_UNSYNCED,
252
+ COMMERCE_POS_OFFLINE_CARD_WRONG_ACCOUNT,
253
+ COMMERCE_POS_HARDWARE_CANCELED_AFTER_ORDERING,
254
+ COMMERCE_POS_HARDWARE_REFUND_FAILED,
255
+ COMMERCE_POS_HARDWARE_RETURN_REQUESTED,
256
+ COMMERCE_POS_CELLULAR_CHARGE_FAILED,
257
+ COMMERCE_POS_CELLULAR_TURN_OFF_FAILED,
258
+ COMMERCE_POS_CELLULAR_TURNED_OFF_UNPAID
104
259
  ];
105
260
 
106
261
  //# sourceMappingURL=operator-alerts.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/constants/operator-alerts.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { OperatorAlertDefinition } from '@aglyn/aglyn/app-utils/operator-alerts'\nimport { BUNDLE_ID } from './bundle-common'\n\n/**\n * The storefront's operator alerts (AGL-3377): the money faults only this\n * plugin can see, declared in the registry's shape and registered from\n * `declarations.server`, so core lists none of them and an install without\n * commerce shows none of them on Staff → Operator alerts.\n *\n * Each is raised through `raiseOperatorAlert` with its definition, which\n * also registers it in a process whose declarations have not loaded yet.\n */\nconst DAY = 24 * 60\n\nexport const COMMERCE_CHARGEBACK_UNROUTABLE: OperatorAlertDefinition = {\n type: 'commerce.chargebackUnroutable',\n pluginId: BUNDLE_ID,\n label: 'Storefront chargeback could not be routed',\n description:\n 'A storefront chargeback matched no order, or more than one, so no order was flagged, no seller share reversed and no merchant told. A missing index means every storefront chargeback is being ignored.',\n tier: 'must',\n category: 'payments',\n title: 'A {{amount}} chargeback could not be routed to an order',\n body: '{{detail}}',\n delivery: 'immediate',\n dedupeWindowMinutes: DAY,\n defaultEnabled: true,\n}\n\nexport const COMMERCE_TAX_NOT_REVERSED: OperatorAlertDefinition = {\n type: 'commerce.taxNotReversed',\n pluginId: BUNDLE_ID,\n label: 'Subscription sales tax not reversed',\n description:\n 'Sales tax collected on a storefront subscription stayed with the merchant instead of coming back to the platform, which files and remits it. The platform may owe tax it does not hold.',\n tier: 'must',\n category: 'payments',\n title: 'Sales tax not reversed on invoice {{invoiceId}}',\n // `{{site}}` is the site's name and id (AGL-3432), so staff need not look\n // it up; the last sentence is the consequence the description states.\n body:\n '{{amount}} of sales tax on invoice {{invoiceId}} for site {{site}} was not pulled back from the merchant: {{reason}}. The platform files and remits that tax, so it may owe tax it does not hold.',\n delivery: 'immediate',\n dedupeWindowMinutes: 7 * DAY,\n defaultEnabled: true,\n}\n\nexport const COMMERCE_SELLER_SHARE_NOT_REVERSED: OperatorAlertDefinition = {\n type: 'commerce.sellerShareNotReversed',\n pluginId: BUNDLE_ID,\n label: 'Seller share not reversed on a lost dispute',\n description:\n 'A storefront dispute was lost and the merchant’s share could not be pulled back, so the platform is out the principal. Recover it by hand in Stripe.',\n tier: 'must',\n category: 'payments',\n title: 'Seller share not reversed on dispute {{disputeId}}',\n body:\n 'The lost dispute {{disputeId}} on order {{orderId}} from site {{site}} cost {{amount}}, and the merchant’s share was not reversed: {{reason}}. The platform is out that share until it is recovered by hand in Stripe.',\n delivery: 'immediate',\n dedupeWindowMinutes: 30 * DAY,\n defaultEnabled: true,\n}\n\nexport const COMMERCE_FEE_REPRICE_REFUSED: OperatorAlertDefinition = {\n type: 'commerce.feeRepriceRefused',\n pluginId: BUNDLE_ID,\n label: 'Platform fee correction refused',\n description:\n 'Stripe refused to change a storefront subscription’s platform fee, or to refund the part of a fee charged on the wrong base. The merchant is being charged a fee the plan does not set.',\n tier: 'must',\n category: 'payments',\n title: 'Platform fee not corrected on {{subject}}',\n body:\n 'The platform fee on {{subject}} for site {{site}} could not be corrected: {{reason}}. Until it is, the merchant is charged a fee its plan does not set.',\n delivery: 'immediate',\n dedupeWindowMinutes: 7 * DAY,\n defaultEnabled: true,\n}\n\n/**\n * A merchant paid for card readers in the POS hardware shop (AGL-4038). In\n * phase 1 a person places the order in Stripe's Terminal hardware shop, so\n * every paid order is work waiting on staff until it is marked ordered.\n */\nexport const COMMERCE_POS_HARDWARE_ORDER: OperatorAlertDefinition = {\n type: 'commerce.posHardwareOrder',\n pluginId: BUNDLE_ID,\n label: 'New hardware order',\n description:\n 'A workspace paid for card readers or accessories in the POS hardware shop. Place the order in the Stripe Dashboard’s Terminal hardware shop, shipping to the merchant’s address, then record the Stripe order id on Staff → Hardware orders.',\n tier: 'should',\n category: 'payments',\n title: 'New hardware order {{orderNumber}} for {{amount}}',\n body:\n 'Site {{site}} ordered {{items}} ({{amount}}, {{shipping}}). Place it in the Stripe Dashboard’s Terminal hardware shop, shipping to the address on the order, and record the Stripe order id on Staff → Hardware orders.',\n link: '/admin/hardware-orders',\n delivery: 'immediate',\n dedupeWindowMinutes: 30 * DAY,\n defaultEnabled: true,\n}\n\nexport const COMMERCE_OPERATOR_ALERTS: readonly OperatorAlertDefinition[] = [\n COMMERCE_CHARGEBACK_UNROUTABLE,\n COMMERCE_TAX_NOT_REVERSED,\n COMMERCE_SELLER_SHARE_NOT_REVERSED,\n COMMERCE_FEE_REPRICE_REFUSED,\n COMMERCE_POS_HARDWARE_ORDER,\n]\n"],"names":["BUNDLE_ID","DAY","COMMERCE_CHARGEBACK_UNROUTABLE","type","pluginId","label","description","tier","category","title","body","delivery","dedupeWindowMinutes","defaultEnabled","COMMERCE_TAX_NOT_REVERSED","COMMERCE_SELLER_SHARE_NOT_REVERSED","COMMERCE_FEE_REPRICE_REFUSED","COMMERCE_POS_HARDWARE_ORDER","link","COMMERCE_OPERATOR_ALERTS"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAGD,SAASA,SAAS,QAAQ,qBAAiB;AAE3C;;;;;;;;CAQC,GACD,MAAMC,MAAM,KAAK;AAEjB,OAAO,MAAMC,iCAA0D;IACrEC,MAAM;IACNC,UAAUJ;IACVK,OAAO;IACPC,aACE;IACFC,MAAM;IACNC,UAAU;IACVC,OAAO;IACPC,MAAM;IACNC,UAAU;IACVC,qBAAqBX;IACrBY,gBAAgB;AAClB,EAAC;AAED,OAAO,MAAMC,4BAAqD;IAChEX,MAAM;IACNC,UAAUJ;IACVK,OAAO;IACPC,aACE;IACFC,MAAM;IACNC,UAAU;IACVC,OAAO;IACP,0EAA0E;IAC1E,sEAAsE;IACtEC,MACE;IACFC,UAAU;IACVC,qBAAqB,IAAIX;IACzBY,gBAAgB;AAClB,EAAC;AAED,OAAO,MAAME,qCAA8D;IACzEZ,MAAM;IACNC,UAAUJ;IACVK,OAAO;IACPC,aACE;IACFC,MAAM;IACNC,UAAU;IACVC,OAAO;IACPC,MACE;IACFC,UAAU;IACVC,qBAAqB,KAAKX;IAC1BY,gBAAgB;AAClB,EAAC;AAED,OAAO,MAAMG,+BAAwD;IACnEb,MAAM;IACNC,UAAUJ;IACVK,OAAO;IACPC,aACE;IACFC,MAAM;IACNC,UAAU;IACVC,OAAO;IACPC,MACE;IACFC,UAAU;IACVC,qBAAqB,IAAIX;IACzBY,gBAAgB;AAClB,EAAC;AAED;;;;CAIC,GACD,OAAO,MAAMI,8BAAuD;IAClEd,MAAM;IACNC,UAAUJ;IACVK,OAAO;IACPC,aACE;IACFC,MAAM;IACNC,UAAU;IACVC,OAAO;IACPC,MACE;IACFQ,MAAM;IACNP,UAAU;IACVC,qBAAqB,KAAKX;IAC1BY,gBAAgB;AAClB,EAAC;AAED,OAAO,MAAMM,2BAA+D;IAC1EjB;IACAY;IACAC;IACAC;IACAC;CACD,CAAA"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/constants/operator-alerts.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { OperatorAlertDefinition } from '@aglyn/aglyn/app-utils/operator-alerts'\nimport { BUNDLE_ID } from './bundle-common'\n\n/**\n * The storefront's operator alerts (AGL-3377): the money faults only this\n * plugin can see, declared in the registry's shape and registered from\n * `declarations.server`, so core lists none of them and an install without\n * commerce shows none of them on Staff → Operator alerts.\n *\n * Each is raised through `raiseOperatorAlert` with its definition, which\n * also registers it in a process whose declarations have not loaded yet.\n */\nconst DAY = 24 * 60\n\nexport const COMMERCE_CHARGEBACK_UNROUTABLE: OperatorAlertDefinition = {\n type: 'commerce.chargebackUnroutable',\n pluginId: BUNDLE_ID,\n label: 'Storefront chargeback could not be routed',\n description:\n 'A storefront chargeback matched no order, or more than one, so no order was flagged, no seller share reversed and no merchant told. A missing index means every storefront chargeback is being ignored.',\n tier: 'must',\n category: 'payments',\n title: 'A {{amount}} chargeback could not be routed to an order',\n body: '{{detail}}',\n delivery: 'immediate',\n dedupeWindowMinutes: DAY,\n defaultEnabled: true,\n}\n\nexport const COMMERCE_TAX_NOT_REVERSED: OperatorAlertDefinition = {\n type: 'commerce.taxNotReversed',\n pluginId: BUNDLE_ID,\n label: 'Subscription sales tax not reversed',\n description:\n 'Sales tax collected on a storefront subscription stayed with the merchant instead of coming back to the platform, which files and remits it. The platform may owe tax it does not hold.',\n tier: 'must',\n category: 'payments',\n title: 'Sales tax not reversed on invoice {{invoiceId}}',\n // `{{site}}` is the site's name and id (AGL-3432), so staff need not look\n // it up; the last sentence is the consequence the description states.\n body:\n '{{amount}} of sales tax on invoice {{invoiceId}} for site {{site}} was not pulled back from the merchant: {{reason}}. The platform files and remits that tax, so it may owe tax it does not hold.',\n delivery: 'immediate',\n dedupeWindowMinutes: 7 * DAY,\n defaultEnabled: true,\n}\n\nexport const COMMERCE_SELLER_SHARE_NOT_REVERSED: OperatorAlertDefinition = {\n type: 'commerce.sellerShareNotReversed',\n pluginId: BUNDLE_ID,\n label: 'Seller share not reversed on a lost dispute',\n description:\n 'A storefront dispute was lost and the merchant’s share could not be pulled back, so the platform is out the principal. Recover it by hand in Stripe.',\n tier: 'must',\n category: 'payments',\n title: 'Seller share not reversed on dispute {{disputeId}}',\n body:\n 'The lost dispute {{disputeId}} on order {{orderId}} from site {{site}} cost {{amount}}, and the merchant’s share was not reversed: {{reason}}. The platform is out that share until it is recovered by hand in Stripe.',\n delivery: 'immediate',\n dedupeWindowMinutes: 30 * DAY,\n defaultEnabled: true,\n}\n\nexport const COMMERCE_FEE_REPRICE_REFUSED: OperatorAlertDefinition = {\n type: 'commerce.feeRepriceRefused',\n pluginId: BUNDLE_ID,\n label: 'Platform fee correction refused',\n description:\n 'Stripe refused to change a storefront subscription’s platform fee, or to refund the part of a fee charged on the wrong base. The merchant is being charged a fee the plan does not set.',\n tier: 'must',\n category: 'payments',\n title: 'Platform fee not corrected on {{subject}}',\n body:\n 'The platform fee on {{subject}} for site {{site}} could not be corrected: {{reason}}. Until it is, the merchant is charged a fee its plan does not set.',\n delivery: 'immediate',\n dedupeWindowMinutes: 7 * DAY,\n defaultEnabled: true,\n}\n\n/**\n * A merchant paid for card readers in the POS hardware shop (AGL-4038). In\n * phase 1 a person places the order in Stripe's Terminal hardware shop, so\n * every paid order is work waiting on staff until it is marked ordered.\n */\nexport const COMMERCE_POS_HARDWARE_ORDER: OperatorAlertDefinition = {\n type: 'commerce.posHardwareOrder',\n pluginId: BUNDLE_ID,\n label: 'New hardware order',\n description:\n 'A workspace paid for card readers or accessories in the POS hardware shop. Place the order in the Stripe Dashboard’s Terminal hardware shop, shipping to the merchant’s address, then record the Stripe order id on Staff → Hardware orders.',\n tier: 'should',\n category: 'payments',\n title: 'New hardware order {{orderNumber}} for {{amount}}',\n body:\n 'Site {{site}} ordered {{items}} ({{amount}}, {{shipping}}). Place it in the Stripe Dashboard’s Terminal hardware shop, shipping to the address on the order, and record the Stripe order id on Staff → Hardware orders.',\n link: '/admin/hardware-orders',\n delivery: 'immediate',\n dedupeWindowMinutes: 30 * DAY,\n defaultEnabled: true,\n}\n\n/**\n * A card taken offline on the Aglyn POS app's reader reached Stripe, but the\n * sale it belongs to never synced (AGL-4039). Raised by the hourly sweep once\n * the intent has waited past `POS_OFFLINE_CARD_UNSYNCED_ALERT_MS`, while there\n * is still time to sync it before Stripe's authorization lapses.\n */\nexport const COMMERCE_POS_OFFLINE_CARD_UNSYNCED: OperatorAlertDefinition = {\n type: 'commerce.posOfflineCardUnsynced',\n pluginId: BUNDLE_ID,\n label: 'Offline card sale never synced',\n description:\n 'A card taken offline on a register reached Stripe, but its sale never reached the store. An authorized card is never captured and lapses after about two days; a charged one has no order. The site’s managers are told too.',\n tier: 'should',\n category: 'payments',\n title: 'A {{amount}} card taken offline has no sale',\n body:\n 'Payment {{paymentIntentId}} ({{status}}) for site {{site}} was taken offline on register {{registerId}} {{age}} ago, and its sale never synced. Ask the store to open that register signed in as the member who rang it so the sale syncs. An authorized card that is not captured lapses about two days after it was taken.',\n delivery: 'immediate',\n dedupeWindowMinutes: 30 * DAY,\n defaultEnabled: true,\n}\n\n/**\n * A card taken offline was made out to a Stripe account that is not the\n * store's (AGL-4039): a stale offline kit, or a register that was tampered\n * with. The sync never captures it and records the order unpaid.\n */\nexport const COMMERCE_POS_OFFLINE_CARD_WRONG_ACCOUNT: OperatorAlertDefinition = {\n type: 'commerce.posOfflineCardWrongAccount',\n pluginId: BUNDLE_ID,\n label: 'Offline card made out to another Stripe account',\n description:\n 'A card taken offline on a register was set to pay a Stripe account that is not the store’s. The sale was recorded unpaid and the card was not captured. Check whether the account is the store’s own previous one before capturing it in Stripe, or let the authorization lapse.',\n tier: 'must',\n category: 'payments',\n title: 'A {{amount}} offline card was made out to another Stripe account',\n body:\n 'Payment {{paymentIntentId}} ({{status}}) on order {{orderId}} for site {{site}} pays account {{destination}}, but the store’s account is {{expected}}. The order is recorded unpaid and nothing was captured. If the payment already succeeded, the money is in that other account: recover or refund it in Stripe.',\n delivery: 'immediate',\n dedupeWindowMinutes: 30 * DAY,\n defaultEnabled: true,\n}\n\n/**\n * A hardware order already placed with Stripe was canceled and refunded\n * because its workspace was deleted or the account that placed it closed\n * (AGL-4038). The merchant has their money back; the platform has paid Stripe\n * for hardware that is still on its way unless someone cancels it there.\n */\nexport const COMMERCE_POS_HARDWARE_CANCELED_AFTER_ORDERING: OperatorAlertDefinition = {\n type: 'commerce.posHardwareCanceledAfterOrdering',\n pluginId: BUNDLE_ID,\n label: 'Hardware order canceled after it was placed with Stripe',\n description:\n 'A workspace was deleted, or the account that placed a hardware order was closed, after staff had placed the order with Stripe. The merchant was refunded in full. Cancel the order in the Stripe Dashboard’s Terminal hardware shop before it ships, or arrange its return with Stripe.',\n tier: 'must',\n category: 'payments',\n title: 'Cancel hardware order {{orderNumber}} with Stripe',\n // `{{stripeOrder}}` is ` (Stripe order …)` or blank, so the sentence reads\n // either way.\n body:\n 'Hardware order {{orderNumber}} ({{amount}}: {{items}}) was canceled and refunded in full to the merchant because {{reason}}, but it had already been placed with Stripe{{stripeOrder}}. Cancel it in the Stripe Dashboard’s Terminal hardware shop before it ships; if it has shipped, arrange its return with Stripe.',\n link: '/admin/hardware-orders',\n delivery: 'immediate',\n dedupeWindowMinutes: 30 * DAY,\n defaultEnabled: true,\n}\n\n/**\n * Stripe refused the refund of an unshipped hardware order while its\n * workspace or its buyer's account was closing (AGL-4038). The closure went\n * ahead, as decided, so the order may be gone from the staff page with the\n * merchant's money still held.\n */\nexport const COMMERCE_POS_HARDWARE_REFUND_FAILED: OperatorAlertDefinition = {\n type: 'commerce.posHardwareRefundFailed',\n pluginId: BUNDLE_ID,\n label: 'Hardware refund failed when a workspace or account closed',\n description:\n 'A hardware order had not shipped when its workspace was deleted or the account that placed it was closed, and Stripe refused its refund. The closure went ahead without it. Refund the payment in full in the Stripe Dashboard.',\n tier: 'must',\n category: 'payments',\n title: 'Refund hardware order {{orderNumber}} by hand: {{amount}}',\n body:\n 'Hardware order {{orderNumber}} ({{amount}}) had not shipped when {{reason}}, and Stripe refused its refund: {{error}}. The closure went ahead. Refund payment {{paymentIntentId}} in full in the Stripe Dashboard{{orderedNote}}.',\n delivery: 'immediate',\n dedupeWindowMinutes: 30 * DAY,\n defaultEnabled: true,\n}\n\n/**\n * A buyer asked to return a card reader they bought in person at the\n * platform's own store (AGL-4038), from their own purchase history. Staff\n * refund it from Staff → Hardware orders, or decline it there.\n */\nexport const COMMERCE_POS_HARDWARE_RETURN_REQUESTED: OperatorAlertDefinition = {\n type: 'commerce.posHardwareReturnRequested',\n pluginId: BUNDLE_ID,\n label: 'Card reader return requested',\n description:\n 'A workspace asked to return card reader hardware it bought in person. Arrange the return under Stripe’s hardware terms, then refund it or decline it on Staff → Hardware orders, under Return requested.',\n tier: 'should',\n category: 'payments',\n title: 'Return requested for hardware order {{orderNumber}} ({{amount}})',\n body:\n 'Workspace {{orgId}} asked to return {{items}} from hardware order {{orderNumber}} ({{amount}}), bought in person: “{{reason}}”. Refund it or decline it on Staff → Hardware orders, under Return requested.',\n link: '/admin/hardware-orders',\n delivery: 'immediate',\n dedupeWindowMinutes: 30 * DAY,\n defaultEnabled: true,\n}\n\n/**\n * A workspace's monthly 4G charge for its Stripe Reader S710s did not\n * collect (AGL-4038): the card declined or asked for authentication (the\n * invoice is left open on their Billing page, which nothing retries), or\n * the workspace has no Stripe customer to bill. Stripe still bills the\n * platform for those readers' cellular service.\n */\nexport const COMMERCE_POS_CELLULAR_CHARGE_FAILED: OperatorAlertDefinition = {\n type: 'commerce.posCellularChargeFailed',\n pluginId: BUNDLE_ID,\n label: '4G charge for card readers not collected',\n description:\n 'A workspace’s monthly charge for 4G on its Stripe Reader S710s did not collect. Stripe still bills the platform for those readers. Follow up with the workspace, or turn 4G off for its stores.',\n tier: 'should',\n category: 'payments',\n title: '4G charge for {{month}} not collected: {{amount}}',\n body:\n 'Workspace {{orgId}} had 4G on {{readers}} card reader(s) in {{month}}, and its charge of {{amount}} was not collected: {{reason}}. Stripe still bills the platform for those readers.',\n delivery: 'immediate',\n dedupeWindowMinutes: 30 * DAY,\n defaultEnabled: true,\n}\n\n/**\n * 4G could not be turned off at Stripe for a store that is gone (AGL-4038):\n * its workspace was deleted, or the store was, while its S710s had 4G. The\n * readers stay on the platform's Stripe account with cellular on, which\n * Stripe keeps billing the platform for, and nobody is charged for it.\n */\nexport const COMMERCE_POS_CELLULAR_TURN_OFF_FAILED: OperatorAlertDefinition = {\n type: 'commerce.posCellularTurnOffFailed',\n pluginId: BUNDLE_ID,\n label: '4G not turned off for a deleted store',\n description:\n 'A store with 4G on its Stripe Reader S710s was deleted, with its workspace or on its own, and Stripe refused to turn cellular off on its Terminal configuration. Turn it off in the Stripe Dashboard, or Stripe keeps billing the platform for it.',\n tier: 'must',\n category: 'payments',\n title: 'Turn off 4G on Terminal configuration {{configurationId}}',\n body:\n 'Store {{hostId}} of workspace {{orgId}} was deleted while its card readers had 4G, and Stripe refused to turn cellular off on Terminal configuration {{configurationId}}. Turn it off in the Stripe Dashboard (Terminal → Locations), or Stripe keeps billing the platform for those readers.',\n delivery: 'immediate',\n dedupeWindowMinutes: 30 * DAY,\n defaultEnabled: true,\n}\n\n/**\n * A workspace's monthly 4G charge stayed unpaid past the grace period\n * (AGL-4038), so 4G was turned off at Stripe for every one of its stores and\n * the members who manage its billing were emailed. Paying does not turn it\n * back on; the merchant does, once it is paid.\n */\nexport const COMMERCE_POS_CELLULAR_TURNED_OFF_UNPAID: OperatorAlertDefinition = {\n type: 'commerce.posCellularTurnedOffUnpaid',\n pluginId: BUNDLE_ID,\n label: '4G turned off for an unpaid charge',\n description:\n 'A workspace’s monthly 4G charge for its Stripe Reader S710s was still unpaid after the grace period, so 4G was turned off for its stores and the people who manage its billing were emailed. Follow up if the workspace asks; it turns 4G on again itself once the invoice is paid.',\n tier: 'should',\n category: 'payments',\n title: '4G turned off for workspace {{orgId}}: {{month}} unpaid ({{amount}})',\n body:\n 'Workspace {{orgId}} left its 4G charge of {{amount}} for {{month}} unpaid for {{graceDays}} days, so 4G was turned off at Stripe for its stores and the people who manage its billing were emailed. The invoice stays open on its Billing page.',\n delivery: 'immediate',\n dedupeWindowMinutes: 30 * DAY,\n defaultEnabled: true,\n}\n\nexport const COMMERCE_OPERATOR_ALERTS: readonly OperatorAlertDefinition[] = [\n COMMERCE_CHARGEBACK_UNROUTABLE,\n COMMERCE_TAX_NOT_REVERSED,\n COMMERCE_SELLER_SHARE_NOT_REVERSED,\n COMMERCE_FEE_REPRICE_REFUSED,\n COMMERCE_POS_HARDWARE_ORDER,\n COMMERCE_POS_OFFLINE_CARD_UNSYNCED,\n COMMERCE_POS_OFFLINE_CARD_WRONG_ACCOUNT,\n COMMERCE_POS_HARDWARE_CANCELED_AFTER_ORDERING,\n COMMERCE_POS_HARDWARE_REFUND_FAILED,\n COMMERCE_POS_HARDWARE_RETURN_REQUESTED,\n COMMERCE_POS_CELLULAR_CHARGE_FAILED,\n COMMERCE_POS_CELLULAR_TURN_OFF_FAILED,\n COMMERCE_POS_CELLULAR_TURNED_OFF_UNPAID,\n]\n"],"names":["BUNDLE_ID","DAY","COMMERCE_CHARGEBACK_UNROUTABLE","type","pluginId","label","description","tier","category","title","body","delivery","dedupeWindowMinutes","defaultEnabled","COMMERCE_TAX_NOT_REVERSED","COMMERCE_SELLER_SHARE_NOT_REVERSED","COMMERCE_FEE_REPRICE_REFUSED","COMMERCE_POS_HARDWARE_ORDER","link","COMMERCE_POS_OFFLINE_CARD_UNSYNCED","COMMERCE_POS_OFFLINE_CARD_WRONG_ACCOUNT","COMMERCE_POS_HARDWARE_CANCELED_AFTER_ORDERING","COMMERCE_POS_HARDWARE_REFUND_FAILED","COMMERCE_POS_HARDWARE_RETURN_REQUESTED","COMMERCE_POS_CELLULAR_CHARGE_FAILED","COMMERCE_POS_CELLULAR_TURN_OFF_FAILED","COMMERCE_POS_CELLULAR_TURNED_OFF_UNPAID","COMMERCE_OPERATOR_ALERTS"],"mappings":"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"}
@@ -16,13 +16,18 @@
16
16
  */ // The registry's own module, not the data layer's barrel: boot needs the
17
17
  // registry, not the whole server surface.
18
18
  import { registerApiV1SiteResource } from "@aglyn/tenant-data-admin/server/api-v1-resources";
19
+ import { registerPluginOrgEraser } from "@aglyn/aglyn/plugin-manager/plugin-org-erasure";
19
20
  import { registerPluginPersonEraser } from "@aglyn/aglyn/plugin-manager/plugin-person-erasure";
20
21
  import { registerPluginUserEraser } from "@aglyn/aglyn/plugin-manager/plugin-user-erasure";
21
22
  import { registerPluginService } from "@aglyn/aglyn/plugin-manager/plugin-services";
23
+ import { registerClosureNoticeSource } from "@aglyn/aglyn/plugin-manager/plugin-closure-notices";
24
+ import { registerCustomerDisplayVerifier } from "@aglyn/aglyn/plugin-manager/plugin-customer-display-verifier";
25
+ import { registerPluginEventHandler } from "@aglyn/aglyn/plugin-manager/plugin-events";
22
26
  import { registerPluginSearchSources } from "@aglyn/aglyn/plugin-manager/plugin-search-sources";
23
27
  import { COMMERCE_SERVER_SEARCH_SOURCES } from "./model/commerce-server-search-sources.js";
24
28
  import { BUNDLE_ID } from "./constants/bundle-common.js";
25
29
  import { ORDER_HISTORY_CONTRACT } from "./model/order-history.js";
30
+ import { parsePosHardwareInPersonConfig } from "./model/pos-hardware.js";
26
31
  import { registerCommerceTransferResources } from "./transfer/register-transfer-resources.js";
27
32
  /**
28
33
  * The commerce plugin's CONSOLE-ONLY server declarations, named under
@@ -52,11 +57,59 @@ import { registerCommerceTransferResources } from "./transfer/register-transfer-
52
57
  pluginId: BUNDLE_ID
53
58
  });
54
59
  // Commerce's share of an ACCOUNT erasure (AGL-4038): every POS hardware
55
- // order the person placed keeps its amounts and its tax region, with the
60
+ // order the person placed that has not shipped is canceled and refunded in
61
+ // full, then every one keeps its amounts and its tax region, with the
56
62
  // buyer taken off it. Loaded with the first erasure.
57
63
  registerPluginUserEraser(async (request)=>(await import("./server/pos-hardware-user-eraser.js")).posHardwareUserEraser(request), {
58
64
  pluginId: BUNDLE_ID
59
65
  });
66
+ // Commerce's share of a WORKSPACE erasure (AGL-4038): every hardware order
67
+ // the workspace bought that has not shipped is canceled and refunded in
68
+ // full before the erasure deletes it, and the buyer and staff are told.
69
+ // Never fails the erasure. Loaded with the first erasure.
70
+ registerPluginOrgEraser(async (request)=>(await import("./server/pos-hardware-closure.js")).posHardwareOrgEraser(request), {
71
+ pluginId: BUNDLE_ID
72
+ });
73
+ // A workspace erasure turns 4G off at Stripe for every one of its stores
74
+ // that had it (AGL-4038), so the platform stops paying for readers nobody
75
+ // will be charged for. Never fails the erasure. Loaded with the first one.
76
+ registerPluginOrgEraser(async (request)=>(await import("./server/pos-cellular-billing.js")).posCellularOrgEraser(request), {
77
+ pluginId: BUNDLE_ID
78
+ });
79
+ // …and says so BEFORE the closure (AGL-4038): the delete-workspace and
80
+ // close-account screens list the unshipped hardware orders a closure will
81
+ // cancel and refund. Loaded with the first screen that asks.
82
+ registerClosureNoticeSource({
83
+ notices: async (subject)=>(await import("./server/pos-hardware-closure-notices.js")).posHardwareClosureNoticeSource.notices(subject)
84
+ }, {
85
+ pluginId: BUNDLE_ID
86
+ });
87
+ // A card reader bought in person before its buyer had a workspace
88
+ // (AGL-4038) joins the workspace they create, by their account or their
89
+ // verified address. Loaded with the first workspace created while the
90
+ // in-person sale is on.
91
+ registerPluginEventHandler('org.created', async (payload)=>{
92
+ const config = parsePosHardwareInPersonConfig(process.env);
93
+ if (!config) return;
94
+ const { claimPosHardwareForNewWorkspace } = await import("./server/pos-hardware-attach.js");
95
+ await claimPosHardwareForNewWorkspace({
96
+ config,
97
+ orgId: payload.orgId,
98
+ ownerUid: payload.owner.uid,
99
+ ownerEmail: payload.owner.email,
100
+ emailVerified: payload.owner.emailVerified
101
+ });
102
+ }, {
103
+ pluginId: BUNDLE_ID
104
+ });
105
+ // Who a paired customer display is (AGL-4042), for another plugin's
106
+ // server acting for the screen the register put on it: the display's own
107
+ // token is the credential. Loaded with the first screen that asks.
108
+ registerCustomerDisplayVerifier({
109
+ verify: async (credential)=>(await import("./server/pos-display.js")).verifyPosCustomerDisplay(credential)
110
+ }, {
111
+ pluginId: BUNDLE_ID
112
+ });
60
113
  // A site's earlier orders, for a plugin that reads history behind the
61
114
  // order events (AGL-3614); the reader is loaded with the first page asked.
62
115
  registerPluginService(ORDER_HISTORY_CONTRACT, {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../libs/plugins/commerce/src/lib/declarations.console-server.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// The registry's own module, not the data layer's barrel: boot needs the\n// registry, not the whole server surface.\nimport { registerApiV1SiteResource } from '@aglyn/tenant-data-admin/server/api-v1-resources'\nimport { registerPluginPersonEraser } from '@aglyn/aglyn/plugin-manager/plugin-person-erasure'\nimport { registerPluginUserEraser } from '@aglyn/aglyn/plugin-manager/plugin-user-erasure'\nimport { registerPluginService } from '@aglyn/aglyn/plugin-manager/plugin-services'\nimport { registerPluginSearchSources } from '@aglyn/aglyn/plugin-manager/plugin-search-sources'\nimport { COMMERCE_SERVER_SEARCH_SOURCES } from './model/commerce-server-search-sources'\nimport { BUNDLE_ID } from './constants/bundle-common'\nimport { ORDER_HISTORY_CONTRACT } from './model/order-history'\nimport { registerCommerceTransferResources } from './transfer/register-transfer-resources'\n\n/**\n * The commerce plugin's CONSOLE-ONLY server declarations, named under\n * `consoleServerDeclarations` in `plugins.config.json` and run at the\n * console's boot. The tenant runtime registers none of it.\n *\n * It serves a site's products and orders on the customer REST API,\n * `/v1/sites/{siteId}/products/…` and `/v1/sites/{siteId}/orders/…`: the\n * console's router owns the pipeline in front — the key, the plan's API\n * access, the quota, the rate limit, the error envelope — and the site's\n * ownership, and hands every request under each resource here.\n *\n * No plan feature is named on the registrations, though both need\n * `commerce`: the handlers ask the key's scope FIRST and the plan second\n * (AGL-900, AGL-1928), so a key without the scope is told about the scope\n * whatever plan its organization is on, and the router would ask in the\n * opposite order.\n *\n * Light at boot: the handlers are imported with their first request and the\n * descriptions when the document is first built. Registering again replaces\n * this plugin's own entries.\n */\nexport function registerCommerceConsoleServerDeclarations(): void {\n // Commerce's share of a person erasure (AGL-2623, AGL-3080): every order the\n // person placed keeps its amounts, with the buyer taken off it. Required,\n // and loaded with the first erasure.\n registerPluginPersonEraser(\n async (request) => (await import('./server/person-eraser')).commercePersonEraser(request),\n { pluginId: BUNDLE_ID },\n )\n // Commerce's share of an ACCOUNT erasure (AGL-4038): every POS hardware\n // order the person placed keeps its amounts and its tax region, with the\n // buyer taken off it. Loaded with the first erasure.\n registerPluginUserEraser(\n async (request) => (await import('./server/pos-hardware-user-eraser')).posHardwareUserEraser(request),\n { pluginId: BUNDLE_ID },\n )\n // A site's earlier orders, for a plugin that reads history behind the\n // order events (AGL-3614); the reader is loaded with the first page asked.\n registerPluginService(\n ORDER_HISTORY_CONTRACT,\n { listOrders: async (request) => (await import('./server/order-history')).listOrderHistory(request) },\n { pluginId: BUNDLE_ID },\n )\n registerApiV1SiteResource(\n 'products',\n {\n handle: async (...args) =>\n (await import('./server/api-v1/orders-and-products')).handleProducts(...args),\n describe: async () =>\n (await import('./server/api-v1/openapi')).PRODUCTS_API_V1_DESCRIPTION,\n },\n { pluginId: BUNDLE_ID },\n )\n registerApiV1SiteResource(\n 'orders',\n {\n handle: async (...args) =>\n (await import('./server/api-v1/orders-and-products')).handleOrders(...args),\n describe: async () =>\n (await import('./server/api-v1/openapi')).ORDERS_API_V1_DESCRIPTION,\n },\n { pluginId: BUNDLE_ID },\n )\n // Products, categories, orders, discounts, coupons and gift cards on the\n // import wizard and the export dialog (AGL-3531): the transfer routes are\n // the console's alone, so they register here.\n registerCommerceTransferResources()\n // What the native apps' one box finds in a store (AGL-3943): products and\n // orders, each under its own plan flag and, for orders, the site role that\n // reads them.\n registerPluginSearchSources(COMMERCE_SERVER_SEARCH_SOURCES, { pluginId: BUNDLE_ID })\n}\n"],"names":["registerApiV1SiteResource","registerPluginPersonEraser","registerPluginUserEraser","registerPluginService","registerPluginSearchSources","COMMERCE_SERVER_SEARCH_SOURCES","BUNDLE_ID","ORDER_HISTORY_CONTRACT","registerCommerceTransferResources","registerCommerceConsoleServerDeclarations","request","commercePersonEraser","pluginId","posHardwareUserEraser","listOrders","listOrderHistory","handle","args","handleProducts","describe","PRODUCTS_API_V1_DESCRIPTION","handleOrders","ORDERS_API_V1_DESCRIPTION"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,yEAAyE;AACzE,0CAA0C;AAC1C,SAASA,yBAAyB,QAAQ,mDAAkD;AAC5F,SAASC,0BAA0B,QAAQ,oDAAmD;AAC9F,SAASC,wBAAwB,QAAQ,kDAAiD;AAC1F,SAASC,qBAAqB,QAAQ,8CAA6C;AACnF,SAASC,2BAA2B,QAAQ,oDAAmD;AAC/F,SAASC,8BAA8B,QAAQ,4CAAwC;AACvF,SAASC,SAAS,QAAQ,+BAA2B;AACrD,SAASC,sBAAsB,QAAQ,2BAAuB;AAC9D,SAASC,iCAAiC,QAAQ,4CAAwC;AAE1F;;;;;;;;;;;;;;;;;;;;CAoBC,GACD,OAAO,SAASC;IACd,6EAA6E;IAC7E,0EAA0E;IAC1E,qCAAqC;IACrCR,2BACE,OAAOS,UAAY,AAAC,CAAA,MAAM,MAAM,CAAC,4BAAwB,EAAGC,oBAAoB,CAACD,UACjF;QAAEE,UAAUN;IAAU;IAExB,wEAAwE;IACxE,yEAAyE;IACzE,qDAAqD;IACrDJ,yBACE,OAAOQ,UAAY,AAAC,CAAA,MAAM,MAAM,CAAC,uCAAmC,EAAGG,qBAAqB,CAACH,UAC7F;QAAEE,UAAUN;IAAU;IAExB,sEAAsE;IACtE,2EAA2E;IAC3EH,sBACEI,wBACA;QAAEO,YAAY,OAAOJ,UAAY,AAAC,CAAA,MAAM,MAAM,CAAC,4BAAwB,EAAGK,gBAAgB,CAACL;IAAS,GACpG;QAAEE,UAAUN;IAAU;IAExBN,0BACE,YACA;QACEgB,QAAQ,OAAO,GAAGC,OAChB,AAAC,CAAA,MAAM,MAAM,CAAC,yCAAqC,EAAGC,cAAc,IAAID;QAC1EE,UAAU,UACR,AAAC,CAAA,MAAM,MAAM,CAAC,6BAAyB,EAAGC,2BAA2B;IACzE,GACA;QAAER,UAAUN;IAAU;IAExBN,0BACE,UACA;QACEgB,QAAQ,OAAO,GAAGC,OAChB,AAAC,CAAA,MAAM,MAAM,CAAC,yCAAqC,EAAGI,YAAY,IAAIJ;QACxEE,UAAU,UACR,AAAC,CAAA,MAAM,MAAM,CAAC,6BAAyB,EAAGG,yBAAyB;IACvE,GACA;QAAEV,UAAUN;IAAU;IAExB,yEAAyE;IACzE,0EAA0E;IAC1E,8CAA8C;IAC9CE;IACA,0EAA0E;IAC1E,2EAA2E;IAC3E,cAAc;IACdJ,4BAA4BC,gCAAgC;QAAEO,UAAUN;IAAU;AACpF"}
1
+ {"version":3,"sources":["../../../../../../libs/plugins/commerce/src/lib/declarations.console-server.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// The registry's own module, not the data layer's barrel: boot needs the\n// registry, not the whole server surface.\nimport { registerApiV1SiteResource } from '@aglyn/tenant-data-admin/server/api-v1-resources'\nimport { registerPluginOrgEraser } from '@aglyn/aglyn/plugin-manager/plugin-org-erasure'\nimport { registerPluginPersonEraser } from '@aglyn/aglyn/plugin-manager/plugin-person-erasure'\nimport { registerPluginUserEraser } from '@aglyn/aglyn/plugin-manager/plugin-user-erasure'\nimport { registerPluginService } from '@aglyn/aglyn/plugin-manager/plugin-services'\nimport { registerClosureNoticeSource } from '@aglyn/aglyn/plugin-manager/plugin-closure-notices'\nimport { registerCustomerDisplayVerifier } from '@aglyn/aglyn/plugin-manager/plugin-customer-display-verifier'\nimport { registerPluginEventHandler } from '@aglyn/aglyn/plugin-manager/plugin-events'\nimport { registerPluginSearchSources } from '@aglyn/aglyn/plugin-manager/plugin-search-sources'\nimport { COMMERCE_SERVER_SEARCH_SOURCES } from './model/commerce-server-search-sources'\nimport { BUNDLE_ID } from './constants/bundle-common'\nimport { ORDER_HISTORY_CONTRACT } from './model/order-history'\nimport { parsePosHardwareInPersonConfig } from './model/pos-hardware'\nimport { registerCommerceTransferResources } from './transfer/register-transfer-resources'\n\n/**\n * The commerce plugin's CONSOLE-ONLY server declarations, named under\n * `consoleServerDeclarations` in `plugins.config.json` and run at the\n * console's boot. The tenant runtime registers none of it.\n *\n * It serves a site's products and orders on the customer REST API,\n * `/v1/sites/{siteId}/products/…` and `/v1/sites/{siteId}/orders/…`: the\n * console's router owns the pipeline in front — the key, the plan's API\n * access, the quota, the rate limit, the error envelope — and the site's\n * ownership, and hands every request under each resource here.\n *\n * No plan feature is named on the registrations, though both need\n * `commerce`: the handlers ask the key's scope FIRST and the plan second\n * (AGL-900, AGL-1928), so a key without the scope is told about the scope\n * whatever plan its organization is on, and the router would ask in the\n * opposite order.\n *\n * Light at boot: the handlers are imported with their first request and the\n * descriptions when the document is first built. Registering again replaces\n * this plugin's own entries.\n */\nexport function registerCommerceConsoleServerDeclarations(): void {\n // Commerce's share of a person erasure (AGL-2623, AGL-3080): every order the\n // person placed keeps its amounts, with the buyer taken off it. Required,\n // and loaded with the first erasure.\n registerPluginPersonEraser(\n async (request) => (await import('./server/person-eraser')).commercePersonEraser(request),\n { pluginId: BUNDLE_ID },\n )\n // Commerce's share of an ACCOUNT erasure (AGL-4038): every POS hardware\n // order the person placed that has not shipped is canceled and refunded in\n // full, then every one keeps its amounts and its tax region, with the\n // buyer taken off it. Loaded with the first erasure.\n registerPluginUserEraser(\n async (request) => (await import('./server/pos-hardware-user-eraser')).posHardwareUserEraser(request),\n { pluginId: BUNDLE_ID },\n )\n // Commerce's share of a WORKSPACE erasure (AGL-4038): every hardware order\n // the workspace bought that has not shipped is canceled and refunded in\n // full before the erasure deletes it, and the buyer and staff are told.\n // Never fails the erasure. Loaded with the first erasure.\n registerPluginOrgEraser(\n async (request) => (await import('./server/pos-hardware-closure')).posHardwareOrgEraser(request),\n { pluginId: BUNDLE_ID },\n )\n // A workspace erasure turns 4G off at Stripe for every one of its stores\n // that had it (AGL-4038), so the platform stops paying for readers nobody\n // will be charged for. Never fails the erasure. Loaded with the first one.\n registerPluginOrgEraser(\n async (request) => (await import('./server/pos-cellular-billing')).posCellularOrgEraser(request),\n { pluginId: BUNDLE_ID },\n )\n // …and says so BEFORE the closure (AGL-4038): the delete-workspace and\n // close-account screens list the unshipped hardware orders a closure will\n // cancel and refund. Loaded with the first screen that asks.\n registerClosureNoticeSource(\n {\n notices: async (subject) =>\n (await import('./server/pos-hardware-closure-notices')).posHardwareClosureNoticeSource.notices(subject),\n },\n { pluginId: BUNDLE_ID },\n )\n // A card reader bought in person before its buyer had a workspace\n // (AGL-4038) joins the workspace they create, by their account or their\n // verified address. Loaded with the first workspace created while the\n // in-person sale is on.\n registerPluginEventHandler(\n 'org.created',\n async (payload) => {\n const config = parsePosHardwareInPersonConfig(process.env)\n if (!config) return\n const { claimPosHardwareForNewWorkspace } = await import('./server/pos-hardware-attach')\n await claimPosHardwareForNewWorkspace({\n config,\n orgId: payload.orgId,\n ownerUid: payload.owner.uid,\n ownerEmail: payload.owner.email,\n emailVerified: payload.owner.emailVerified,\n })\n },\n { pluginId: BUNDLE_ID },\n )\n // Who a paired customer display is (AGL-4042), for another plugin's\n // server acting for the screen the register put on it: the display's own\n // token is the credential. Loaded with the first screen that asks.\n registerCustomerDisplayVerifier(\n { verify: async (credential) => (await import('./server/pos-display')).verifyPosCustomerDisplay(credential) },\n { pluginId: BUNDLE_ID },\n )\n // A site's earlier orders, for a plugin that reads history behind the\n // order events (AGL-3614); the reader is loaded with the first page asked.\n registerPluginService(\n ORDER_HISTORY_CONTRACT,\n { listOrders: async (request) => (await import('./server/order-history')).listOrderHistory(request) },\n { pluginId: BUNDLE_ID },\n )\n registerApiV1SiteResource(\n 'products',\n {\n handle: async (...args) =>\n (await import('./server/api-v1/orders-and-products')).handleProducts(...args),\n describe: async () =>\n (await import('./server/api-v1/openapi')).PRODUCTS_API_V1_DESCRIPTION,\n },\n { pluginId: BUNDLE_ID },\n )\n registerApiV1SiteResource(\n 'orders',\n {\n handle: async (...args) =>\n (await import('./server/api-v1/orders-and-products')).handleOrders(...args),\n describe: async () =>\n (await import('./server/api-v1/openapi')).ORDERS_API_V1_DESCRIPTION,\n },\n { pluginId: BUNDLE_ID },\n )\n // Products, categories, orders, discounts, coupons and gift cards on the\n // import wizard and the export dialog (AGL-3531): the transfer routes are\n // the console's alone, so they register here.\n registerCommerceTransferResources()\n // What the native apps' one box finds in a store (AGL-3943): products and\n // orders, each under its own plan flag and, for orders, the site role that\n // reads them.\n registerPluginSearchSources(COMMERCE_SERVER_SEARCH_SOURCES, { pluginId: BUNDLE_ID })\n}\n"],"names":["registerApiV1SiteResource","registerPluginOrgEraser","registerPluginPersonEraser","registerPluginUserEraser","registerPluginService","registerClosureNoticeSource","registerCustomerDisplayVerifier","registerPluginEventHandler","registerPluginSearchSources","COMMERCE_SERVER_SEARCH_SOURCES","BUNDLE_ID","ORDER_HISTORY_CONTRACT","parsePosHardwareInPersonConfig","registerCommerceTransferResources","registerCommerceConsoleServerDeclarations","request","commercePersonEraser","pluginId","posHardwareUserEraser","posHardwareOrgEraser","posCellularOrgEraser","notices","subject","posHardwareClosureNoticeSource","payload","config","process","env","claimPosHardwareForNewWorkspace","orgId","ownerUid","owner","uid","ownerEmail","email","emailVerified","verify","credential","verifyPosCustomerDisplay","listOrders","listOrderHistory","handle","args","handleProducts","describe","PRODUCTS_API_V1_DESCRIPTION","handleOrders","ORDERS_API_V1_DESCRIPTION"],"mappings":"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"}
@@ -15,8 +15,10 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  /**
18
- * The plugin's DECLARATIONS (AGL-4047): its permission keys (the point of sale key (`managePos`)), which
19
- * the one permission catalog lists beside the core keys. Loaded eagerly by
18
+ * The plugin's DECLARATIONS (AGL-4047): its permission keys (the point of
19
+ * sale's `managePos` and its finer keys, and the reservation keys whose
20
+ * preset is the site role), which the one permission catalog lists beside
21
+ * the core keys. Loaded eagerly by
20
22
  * the console (client and server) and the tenant's server through the
21
23
  * generated declarations manifest, so the role editor offers the keys, a
22
24
  * custom role or a per-member override keeps them, and a route resolves
@@ -13,12 +13,15 @@
13
13
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
- */ import { registerPluginPermissions } from "@aglyn/aglyn/plugin-manager/plugin-permissions";
17
- import { COMMERCE_PERMISSIONS } from "./model/plugin-permissions.js";
16
+ */ import { registerPluginEntitlements } from "@aglyn/aglyn/plugin-manager/plugin-entitlements";
17
+ import { registerPluginPermissions } from "@aglyn/aglyn/plugin-manager/plugin-permissions";
18
+ import { COMMERCE_PERMISSIONS, COMMERCE_SITE_PERMISSIONS } from "./model/plugin-permissions.js";
18
19
  let declared = false;
19
20
  /**
20
- * The plugin's DECLARATIONS (AGL-4047): its permission keys (the point of sale key (`managePos`)), which
21
- * the one permission catalog lists beside the core keys. Loaded eagerly by
21
+ * The plugin's DECLARATIONS (AGL-4047): its permission keys (the point of
22
+ * sale's `managePos` and its finer keys, and the reservation keys whose
23
+ * preset is the site role), which the one permission catalog lists beside
24
+ * the core keys. Loaded eagerly by
22
25
  * the console (client and server) and the tenant's server through the
23
26
  * generated declarations manifest, so the role editor offers the keys, a
24
27
  * custom role or a per-member override keeps them, and a route resolves
@@ -27,6 +30,10 @@ let declared = false;
27
30
  */ export function registerCommerceDeclarations() {
28
31
  if (declared) return;
29
32
  declared = true;
33
+ registerPluginEntitlements({
34
+ pluginId: 'commerce',
35
+ orgPermissions: COMMERCE_SITE_PERMISSIONS
36
+ });
30
37
  registerPluginPermissions(COMMERCE_PERMISSIONS);
31
38
  }
32
39
  registerCommerceDeclarations();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../libs/plugins/commerce/src/lib/declarations.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerPluginPermissions } from '@aglyn/aglyn/plugin-manager/plugin-permissions'\nimport { COMMERCE_PERMISSIONS } from './model/plugin-permissions'\n\nlet declared = false\n\n/**\n * The plugin's DECLARATIONS (AGL-4047): its permission keys (the point of sale key (`managePos`)), which\n * the one permission catalog lists beside the core keys. Loaded eagerly by\n * the console (client and server) and the tenant's server through the\n * generated declarations manifest, so the role editor offers the keys, a\n * custom role or a per-member override keeps them, and a route resolves\n * them whether or not a request has touched the plugin yet. Light by\n * construction: nothing here reaches a provider, Firestore or React.\n */\nexport function registerCommerceDeclarations(): void {\n if (declared) return\n declared = true\n registerPluginPermissions(COMMERCE_PERMISSIONS)\n}\n\nregisterCommerceDeclarations()\n"],"names":["registerPluginPermissions","COMMERCE_PERMISSIONS","declared","registerCommerceDeclarations"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,yBAAyB,QAAQ,iDAAgD;AAC1F,SAASC,oBAAoB,QAAQ,gCAA4B;AAEjE,IAAIC,WAAW;AAEf;;;;;;;;CAQC,GACD,OAAO,SAASC;IACd,IAAID,UAAU;IACdA,WAAW;IACXF,0BAA0BC;AAC5B;AAEAE"}
1
+ {"version":3,"sources":["../../../../../../libs/plugins/commerce/src/lib/declarations.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerPluginEntitlements } from '@aglyn/aglyn/plugin-manager/plugin-entitlements'\nimport { registerPluginPermissions } from '@aglyn/aglyn/plugin-manager/plugin-permissions'\nimport { COMMERCE_PERMISSIONS, COMMERCE_SITE_PERMISSIONS } from './model/plugin-permissions'\n\nlet declared = false\n\n/**\n * The plugin's DECLARATIONS (AGL-4047): its permission keys (the point of\n * sale's `managePos` and its finer keys, and the reservation keys whose\n * preset is the site role), which the one permission catalog lists beside\n * the core keys. Loaded eagerly by\n * the console (client and server) and the tenant's server through the\n * generated declarations manifest, so the role editor offers the keys, a\n * custom role or a per-member override keeps them, and a route resolves\n * them whether or not a request has touched the plugin yet. Light by\n * construction: nothing here reaches a provider, Firestore or React.\n */\nexport function registerCommerceDeclarations(): void {\n if (declared) return\n declared = true\n registerPluginEntitlements({ pluginId: 'commerce', orgPermissions: COMMERCE_SITE_PERMISSIONS })\n registerPluginPermissions(COMMERCE_PERMISSIONS)\n}\n\nregisterCommerceDeclarations()\n"],"names":["registerPluginEntitlements","registerPluginPermissions","COMMERCE_PERMISSIONS","COMMERCE_SITE_PERMISSIONS","declared","registerCommerceDeclarations","pluginId","orgPermissions"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,0BAA0B,QAAQ,kDAAiD;AAC5F,SAASC,yBAAyB,QAAQ,iDAAgD;AAC1F,SAASC,oBAAoB,EAAEC,yBAAyB,QAAQ,gCAA4B;AAE5F,IAAIC,WAAW;AAEf;;;;;;;;;;CAUC,GACD,OAAO,SAASC;IACd,IAAID,UAAU;IACdA,WAAW;IACXJ,2BAA2B;QAAEM,UAAU;QAAYC,gBAAgBJ;IAA0B;IAC7FF,0BAA0BC;AAC5B;AAEAG"}
@@ -70,6 +70,15 @@ import { registerCommerceEventTriggers } from "./server/order-event-triggers.js"
70
70
  registerPluginEventHandler('host.domain.released', async (payload)=>(await import("./server/payment-method-domains.js")).onHostDomainReleased(payload), {
71
71
  pluginId: BUNDLE_ID
72
72
  });
73
+ // A logo saved on the workspace's profile or brand reaches its stores'
74
+ // card readers now (AGL-4048), once the save has answered; the
75
+ // `pos-reader-splash-refresh` beat stays the backstop. The drawing and the
76
+ // Stripe calls arrive with the first event, not with the boot.
77
+ registerPluginEventHandler('org.logo.changed', async (payload)=>{
78
+ await (await import("./server/pos-reader-splash.js")).onOrgLogoChanged(payload);
79
+ }, {
80
+ pluginId: BUNDLE_ID
81
+ });
73
82
  // The store's catalog, as a shopping-channel feed reads it (AGL-3637).
74
83
  registerPluginProductCatalog(lazyCatalog, {
75
84
  pluginId: BUNDLE_ID
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../libs/plugins/commerce/src/lib/declarations.server.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// The seam from its own module, not the plugin-manager barrel: boot needs the\n// registry and nothing else, and the barrel reaches the client contexts.\nimport { registerOperatorAlerts } from '@aglyn/aglyn/plugin-manager/operator-alerts'\nimport { registerPluginEventHandler } from '@aglyn/aglyn/plugin-manager/plugin-events'\nimport {\n registerPluginRecordIndex,\n type PluginRecordIndex,\n} from '@aglyn/aglyn/plugin-manager/plugin-record-index'\nimport {\n registerPluginShipmentRecords,\n type PluginShipmentRecords,\n} from '@aglyn/aglyn/plugin-manager/plugin-shipment-records'\nimport {\n registerPluginLocalDeliveryRecords,\n type PluginLocalDeliveryRecords,\n} from '@aglyn/aglyn/plugin-manager/plugin-local-deliveries'\nimport {\n registerPluginProductCatalog,\n type PluginProductCatalog,\n} from '@aglyn/aglyn/plugin-manager/plugin-product-catalog'\nimport {\n registerPluginStockLevels,\n type PluginStockLevels,\n} from '@aglyn/aglyn/plugin-manager/plugin-stock-levels'\nimport {\n registerPluginChannelOrders,\n type PluginChannelOrders,\n} from '@aglyn/aglyn/plugin-manager/plugin-channel-orders'\nimport {\n registerPluginProductWriter,\n type PluginProductWriter,\n} from '@aglyn/aglyn/plugin-manager/plugin-product-writer'\nimport { BUNDLE_ID } from './constants/bundle-common'\nimport { COMMERCE_OPERATOR_ALERTS } from './constants/operator-alerts'\nimport { registerCommerceEventTriggers } from './server/order-event-triggers'\n\n/**\n * The commerce plugin's server declarations: the light registrations core\n * reads at boot, before any surface loads — among them its orders as a label\n * buyer reads and writes them, through core's `core.shipment-records`.\n *\n * Its operator alerts (AGL-3377), so Staff → Operator alerts lists them and\n * staff can switch them before the first one is ever raised; and the indexes\n * of its products and categories, so another plugin reads them without\n * reaching for this plugin's collections.\n */\nexport function registerCommerceServerDeclarations(): void {\n registerOperatorAlerts(COMMERCE_OPERATOR_ALERTS, { pluginId: BUNDLE_ID })\n // Its order and return events (AGL-3611), and each as a workflow trigger.\n registerCommerceEventTriggers()\n // Products and categories, as another plugin reads them (AGL-3080). The\n // readers and the Admin SDK arrive with the first read, not with the boot.\n registerPluginRecordIndex('product', lazyIndex('productRecordIndex'), { pluginId: BUNDLE_ID })\n registerPluginRecordIndex('productCategory', lazyIndex('productCategoryRecordIndex'), {\n pluginId: BUNDLE_ID,\n })\n // Orders, as a label buyer reads and writes them (AGL-3612): read the\n // lines and the address, write a shipment, record tracking. The module and\n // the Admin SDK load with the first call.\n registerPluginShipmentRecords(lazyShipmentRecords, { pluginId: BUNDLE_ID })\n // Local deliveries, as a courier plugin reads and writes them (AGL-3695):\n // the drop's two ends, and the courier's run and the step it brings.\n registerPluginLocalDeliveryRecords(lazyLocalDeliveries, { pluginId: BUNDLE_ID })\n // A site's domains as Stripe payment method domains (AGL-3629), so Apple\n // Pay and the other wallets show on the merchant's own domain. The Stripe\n // calls arrive with the first event, not with the boot.\n registerPluginEventHandler(\n 'host.domain.attached',\n async (payload) =>\n (await import('./server/payment-method-domains')).onHostDomainAttached(payload),\n { pluginId: BUNDLE_ID },\n )\n registerPluginEventHandler(\n 'host.domain.released',\n async (payload) =>\n (await import('./server/payment-method-domains')).onHostDomainReleased(payload),\n { pluginId: BUNDLE_ID },\n )\n // The store's catalog, as a shopping-channel feed reads it (AGL-3637).\n registerPluginProductCatalog(lazyCatalog, { pluginId: BUNDLE_ID })\n // Counts another warehouse keeps, applied as a stock-take (AGL-3634): a\n // fulfillment network says how many it can ship and the products say so.\n registerPluginStockLevels(lazyStockLevels, { pluginId: BUNDLE_ID })\n // Products another plugin brings from a source of its own (AGL-3641),\n // written through the store's own rules.\n registerPluginProductWriter(lazyProductWriter, { pluginId: BUNDLE_ID })\n // Orders a marketplace sold (AGL-3638), recorded as this plugin's own:\n // numbered, their units off the same shelf in the same write, announced.\n registerPluginChannelOrders(lazyChannelOrders, { pluginId: BUNDLE_ID })\n}\n\n/** Outside orders, with the Admin SDK and the model arriving on the first call. */\nconst loadChannelOrders = async () => (await import('./server/channel-orders')).commerceChannelOrders\n\nconst lazyChannelOrders: PluginChannelOrders = {\n importOrder: async (order) => (await loadChannelOrders()).importOrder(order),\n cancelOrder: async (request) => (await loadChannelOrders()).cancelOrder(request),\n recordFees: async (request) => (await loadChannelOrders()).recordFees(request),\n}\n\n/** Stock counts, with the Admin SDK and the model arriving on the first call. */\nconst lazyStockLevels: PluginStockLevels = {\n setAvailable: async (request) => (await import('./server/stock-levels')).commerceStockLevels.setAvailable(request),\n}\n\n/** The writer, with the Admin SDK and the model arriving on the first write. */\nconst lazyProductWriter: PluginProductWriter = {\n upsertSourced: async (write) => (await import('./server/product-writer')).commerceProductWriter.upsertSourced(write),\n}\n\nconst loadShipmentRecords = async () =>\n (await import('./server/shipment-records')).commerceShipmentRecords\n\nconst lazyShipmentRecords: PluginShipmentRecords = {\n read: async (hostId, recordId) => (await loadShipmentRecords()).read(hostId, recordId),\n recordShipment: async (write) => (await loadShipmentRecords()).recordShipment(write),\n recordTracking: async (update) => (await loadShipmentRecords()).recordTracking(update),\n shipFromAddresses: async (hostId) => (await loadShipmentRecords()).shipFromAddresses(hostId),\n}\n\nconst loadLocalDeliveries = async () =>\n (await import('./server/local-delivery-records')).commerceLocalDeliveryRecords\n\nconst lazyLocalDeliveries: PluginLocalDeliveryRecords = {\n read: async (hostId, recordId) => (await loadLocalDeliveries()).read(hostId, recordId),\n recordCourier: async (write) => (await loadLocalDeliveries()).recordCourier(write),\n}\n\n/** The catalog, with the Admin SDK and the model arriving on the first read. */\nconst lazyCatalog: PluginProductCatalog = {\n store: async (hostId) => (await import('./server/product-catalog')).productCatalog.store(hostId),\n page: async (request) => (await import('./server/product-catalog')).productCatalog.page(request),\n}\n\ntype IndexName = 'productRecordIndex' | 'productCategoryRecordIndex'\n\nfunction lazyIndex(name: IndexName): PluginRecordIndex {\n const load = async () => (await import('./server/product-record-index'))[name]\n return {\n list: async (request) => (await load()).list(request),\n get: async (request) => (await load()).get(request),\n }\n}\n"],"names":["registerOperatorAlerts","registerPluginEventHandler","registerPluginRecordIndex","registerPluginShipmentRecords","registerPluginLocalDeliveryRecords","registerPluginProductCatalog","registerPluginStockLevels","registerPluginChannelOrders","registerPluginProductWriter","BUNDLE_ID","COMMERCE_OPERATOR_ALERTS","registerCommerceEventTriggers","registerCommerceServerDeclarations","pluginId","lazyIndex","lazyShipmentRecords","lazyLocalDeliveries","payload","onHostDomainAttached","onHostDomainReleased","lazyCatalog","lazyStockLevels","lazyProductWriter","lazyChannelOrders","loadChannelOrders","commerceChannelOrders","importOrder","order","cancelOrder","request","recordFees","setAvailable","commerceStockLevels","upsertSourced","write","commerceProductWriter","loadShipmentRecords","commerceShipmentRecords","read","hostId","recordId","recordShipment","recordTracking","update","shipFromAddresses","loadLocalDeliveries","commerceLocalDeliveryRecords","recordCourier","store","productCatalog","page","name","load","list","get"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../libs/plugins/commerce/src/lib/declarations.server.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// The seam from its own module, not the plugin-manager barrel: boot needs the\n// registry and nothing else, and the barrel reaches the client contexts.\nimport { registerOperatorAlerts } from '@aglyn/aglyn/plugin-manager/operator-alerts'\nimport { registerPluginEventHandler } from '@aglyn/aglyn/plugin-manager/plugin-events'\nimport {\n registerPluginRecordIndex,\n type PluginRecordIndex,\n} from '@aglyn/aglyn/plugin-manager/plugin-record-index'\nimport {\n registerPluginShipmentRecords,\n type PluginShipmentRecords,\n} from '@aglyn/aglyn/plugin-manager/plugin-shipment-records'\nimport {\n registerPluginLocalDeliveryRecords,\n type PluginLocalDeliveryRecords,\n} from '@aglyn/aglyn/plugin-manager/plugin-local-deliveries'\nimport {\n registerPluginProductCatalog,\n type PluginProductCatalog,\n} from '@aglyn/aglyn/plugin-manager/plugin-product-catalog'\nimport {\n registerPluginStockLevels,\n type PluginStockLevels,\n} from '@aglyn/aglyn/plugin-manager/plugin-stock-levels'\nimport {\n registerPluginChannelOrders,\n type PluginChannelOrders,\n} from '@aglyn/aglyn/plugin-manager/plugin-channel-orders'\nimport {\n registerPluginProductWriter,\n type PluginProductWriter,\n} from '@aglyn/aglyn/plugin-manager/plugin-product-writer'\nimport { BUNDLE_ID } from './constants/bundle-common'\nimport { COMMERCE_OPERATOR_ALERTS } from './constants/operator-alerts'\nimport { registerCommerceEventTriggers } from './server/order-event-triggers'\n\n/**\n * The commerce plugin's server declarations: the light registrations core\n * reads at boot, before any surface loads — among them its orders as a label\n * buyer reads and writes them, through core's `core.shipment-records`.\n *\n * Its operator alerts (AGL-3377), so Staff → Operator alerts lists them and\n * staff can switch them before the first one is ever raised; and the indexes\n * of its products and categories, so another plugin reads them without\n * reaching for this plugin's collections.\n */\nexport function registerCommerceServerDeclarations(): void {\n registerOperatorAlerts(COMMERCE_OPERATOR_ALERTS, { pluginId: BUNDLE_ID })\n // Its order and return events (AGL-3611), and each as a workflow trigger.\n registerCommerceEventTriggers()\n // Products and categories, as another plugin reads them (AGL-3080). The\n // readers and the Admin SDK arrive with the first read, not with the boot.\n registerPluginRecordIndex('product', lazyIndex('productRecordIndex'), { pluginId: BUNDLE_ID })\n registerPluginRecordIndex('productCategory', lazyIndex('productCategoryRecordIndex'), {\n pluginId: BUNDLE_ID,\n })\n // Orders, as a label buyer reads and writes them (AGL-3612): read the\n // lines and the address, write a shipment, record tracking. The module and\n // the Admin SDK load with the first call.\n registerPluginShipmentRecords(lazyShipmentRecords, { pluginId: BUNDLE_ID })\n // Local deliveries, as a courier plugin reads and writes them (AGL-3695):\n // the drop's two ends, and the courier's run and the step it brings.\n registerPluginLocalDeliveryRecords(lazyLocalDeliveries, { pluginId: BUNDLE_ID })\n // A site's domains as Stripe payment method domains (AGL-3629), so Apple\n // Pay and the other wallets show on the merchant's own domain. The Stripe\n // calls arrive with the first event, not with the boot.\n registerPluginEventHandler(\n 'host.domain.attached',\n async (payload) =>\n (await import('./server/payment-method-domains')).onHostDomainAttached(payload),\n { pluginId: BUNDLE_ID },\n )\n registerPluginEventHandler(\n 'host.domain.released',\n async (payload) =>\n (await import('./server/payment-method-domains')).onHostDomainReleased(payload),\n { pluginId: BUNDLE_ID },\n )\n // A logo saved on the workspace's profile or brand reaches its stores'\n // card readers now (AGL-4048), once the save has answered; the\n // `pos-reader-splash-refresh` beat stays the backstop. The drawing and the\n // Stripe calls arrive with the first event, not with the boot.\n registerPluginEventHandler(\n 'org.logo.changed',\n async (payload) => {\n await (await import('./server/pos-reader-splash')).onOrgLogoChanged(payload)\n },\n { pluginId: BUNDLE_ID },\n )\n // The store's catalog, as a shopping-channel feed reads it (AGL-3637).\n registerPluginProductCatalog(lazyCatalog, { pluginId: BUNDLE_ID })\n // Counts another warehouse keeps, applied as a stock-take (AGL-3634): a\n // fulfillment network says how many it can ship and the products say so.\n registerPluginStockLevels(lazyStockLevels, { pluginId: BUNDLE_ID })\n // Products another plugin brings from a source of its own (AGL-3641),\n // written through the store's own rules.\n registerPluginProductWriter(lazyProductWriter, { pluginId: BUNDLE_ID })\n // Orders a marketplace sold (AGL-3638), recorded as this plugin's own:\n // numbered, their units off the same shelf in the same write, announced.\n registerPluginChannelOrders(lazyChannelOrders, { pluginId: BUNDLE_ID })\n}\n\n/** Outside orders, with the Admin SDK and the model arriving on the first call. */\nconst loadChannelOrders = async () => (await import('./server/channel-orders')).commerceChannelOrders\n\nconst lazyChannelOrders: PluginChannelOrders = {\n importOrder: async (order) => (await loadChannelOrders()).importOrder(order),\n cancelOrder: async (request) => (await loadChannelOrders()).cancelOrder(request),\n recordFees: async (request) => (await loadChannelOrders()).recordFees(request),\n}\n\n/** Stock counts, with the Admin SDK and the model arriving on the first call. */\nconst lazyStockLevels: PluginStockLevels = {\n setAvailable: async (request) => (await import('./server/stock-levels')).commerceStockLevels.setAvailable(request),\n}\n\n/** The writer, with the Admin SDK and the model arriving on the first write. */\nconst lazyProductWriter: PluginProductWriter = {\n upsertSourced: async (write) => (await import('./server/product-writer')).commerceProductWriter.upsertSourced(write),\n}\n\nconst loadShipmentRecords = async () =>\n (await import('./server/shipment-records')).commerceShipmentRecords\n\nconst lazyShipmentRecords: PluginShipmentRecords = {\n read: async (hostId, recordId) => (await loadShipmentRecords()).read(hostId, recordId),\n recordShipment: async (write) => (await loadShipmentRecords()).recordShipment(write),\n recordTracking: async (update) => (await loadShipmentRecords()).recordTracking(update),\n shipFromAddresses: async (hostId) => (await loadShipmentRecords()).shipFromAddresses(hostId),\n}\n\nconst loadLocalDeliveries = async () =>\n (await import('./server/local-delivery-records')).commerceLocalDeliveryRecords\n\nconst lazyLocalDeliveries: PluginLocalDeliveryRecords = {\n read: async (hostId, recordId) => (await loadLocalDeliveries()).read(hostId, recordId),\n recordCourier: async (write) => (await loadLocalDeliveries()).recordCourier(write),\n}\n\n/** The catalog, with the Admin SDK and the model arriving on the first read. */\nconst lazyCatalog: PluginProductCatalog = {\n store: async (hostId) => (await import('./server/product-catalog')).productCatalog.store(hostId),\n page: async (request) => (await import('./server/product-catalog')).productCatalog.page(request),\n}\n\ntype IndexName = 'productRecordIndex' | 'productCategoryRecordIndex'\n\nfunction lazyIndex(name: IndexName): PluginRecordIndex {\n const load = async () => (await import('./server/product-record-index'))[name]\n return {\n list: async (request) => (await load()).list(request),\n get: async (request) => (await load()).get(request),\n }\n}\n"],"names":["registerOperatorAlerts","registerPluginEventHandler","registerPluginRecordIndex","registerPluginShipmentRecords","registerPluginLocalDeliveryRecords","registerPluginProductCatalog","registerPluginStockLevels","registerPluginChannelOrders","registerPluginProductWriter","BUNDLE_ID","COMMERCE_OPERATOR_ALERTS","registerCommerceEventTriggers","registerCommerceServerDeclarations","pluginId","lazyIndex","lazyShipmentRecords","lazyLocalDeliveries","payload","onHostDomainAttached","onHostDomainReleased","onOrgLogoChanged","lazyCatalog","lazyStockLevels","lazyProductWriter","lazyChannelOrders","loadChannelOrders","commerceChannelOrders","importOrder","order","cancelOrder","request","recordFees","setAvailable","commerceStockLevels","upsertSourced","write","commerceProductWriter","loadShipmentRecords","commerceShipmentRecords","read","hostId","recordId","recordShipment","recordTracking","update","shipFromAddresses","loadLocalDeliveries","commerceLocalDeliveryRecords","recordCourier","store","productCatalog","page","name","load","list","get"],"mappings":"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"}
@@ -26,6 +26,12 @@ export interface CartLine {
26
26
  /** Absent = the product's default variant. */
27
27
  variantId?: string;
28
28
  quantity: number;
29
+ /**
30
+ * The day the shopper chose to use a check-in item (AGL-4043),
31
+ * `YYYY-MM-DD` on the store's calendar. Absent: the day they buy. Two
32
+ * different days of one pass are two lines.
33
+ */
34
+ useDayKey?: string;
29
35
  }
30
36
  /** `hosts/{hostId}/carts/{cartId}` doc. */
31
37
  export interface HostCart {
@@ -37,12 +43,14 @@ export interface HostCart {
37
43
  }
38
44
  export declare const CART_MAX_LINES = 50;
39
45
  export declare const CART_MAX_QUANTITY = 99;
46
+ /** One cart line's identity: product, variant and use day. */
47
+ export declare function cartLineKey(line: Pick<CartLine, 'productId' | 'variantId' | 'useDayKey'>): string;
40
48
  /**
41
49
  * Adds/merges a line (quantities accumulate), clamped to per-line and
42
50
  * line-count caps. Quantity ≤ 0 removes the line.
43
51
  */
44
52
  export declare function upsertCartLine(cart: Pick<HostCart, 'lines'>, line: CartLine, mode?: 'add' | 'set'): CartLine[];
45
- export declare function removeCartLine(cart: Pick<HostCart, 'lines'>, line: Pick<CartLine, 'productId' | 'variantId'>): CartLine[];
53
+ export declare function removeCartLine(cart: Pick<HostCart, 'lines'>, line: Pick<CartLine, 'productId' | 'variantId' | 'useDayKey'>): CartLine[];
46
54
  /** Total units across lines (the mini-cart badge). */
47
55
  export declare function cartCount(cart: Pick<HostCart, 'lines'> | undefined): number;
48
56
  /**
@@ -22,10 +22,11 @@
22
22
  */ import { _ as _extends } from "@swc/helpers/_/_extends";
23
23
  export const CART_MAX_LINES = 50;
24
24
  export const CART_MAX_QUANTITY = 99;
25
- function lineKey(line) {
26
- var _line_variantId;
27
- return `${line.productId}:${(_line_variantId = line.variantId) != null ? _line_variantId : ''}`;
25
+ /** One cart line's identity: product, variant and use day. */ export function cartLineKey(line) {
26
+ var _line_variantId, _line_useDayKey;
27
+ return `${line.productId}:${(_line_variantId = line.variantId) != null ? _line_variantId : ''}:${(_line_useDayKey = line.useDayKey) != null ? _line_useDayKey : ''}`;
28
28
  }
29
+ const lineKey = cartLineKey;
29
30
  /**
30
31
  * A line quantity, coerced to a whole finite number (AGL-2285).
31
32
  *
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/model/commerce-cart.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Cart v1 (AGL-293): a server-backed cart doc at\n * `hosts/{hostId}/carts/{cartId}`, keyed by an httpOnly cookie. Lines\n * store only ids + quantity — display data and prices resolve from the\n * product docs at read/checkout time, so a stale cart can never charge\n * a stale price. Pure helpers; the cart API owns I/O.\n */\n\nexport interface CartLine {\n productId: string\n /** Absent = the product's default variant. */\n variantId?: string\n quantity: number\n}\n\n/** `hosts/{hostId}/carts/{cartId}` doc. */\nexport interface HostCart {\n lines: CartLine[]\n /** Storefront customer once signed in (AGL-294 merge). */\n customerId?: string\n updatedAtMs?: number\n createdAtMs?: number\n}\n\nexport const CART_MAX_LINES = 50\nexport const CART_MAX_QUANTITY = 99\n\nfunction lineKey(line: Pick<CartLine, 'productId' | 'variantId'>): string {\n return `${line.productId}:${line.variantId ?? ''}`\n}\n\n/**\n * A line quantity, coerced to a whole finite number (AGL-2285).\n *\n * `Math.round(line.quantity)` was the whole sanitiser, and `Math.round(NaN)` is\n * `NaN` — which then walked past the guard below, because `NaN <= 0` is\n * `false`. A cart line with `quantity: NaN` (a legal Firestore double) was\n * stored, and from there `cartCount` reported `NaN` in the mini-cart badge and\n * `cart-checkout.ts` computed `itemsCents`, the platform fee and the Stripe\n * `line_items[n][quantity]` as `NaN` too — so Stripe 400s and the shopper\n * cannot check out AT ALL until they find the poisoned line and remove it.\n *\n * Answering 0 is what makes the existing `<= 0` guard do its job: an\n * unusable quantity removes the line (or refuses to add one) rather than\n * writing a value nothing downstream can compare against. The same lesson as\n * AGL-2229 one collection over — `Math.max`/`Math.min`/`Math.round` propagate\n * `NaN`, they do not discard it.\n */\nfunction wholeQuantity(value: unknown): number {\n const quantity = Math.round(Number(value ?? 0))\n return Number.isFinite(quantity) ? quantity : 0\n}\n\n/**\n * Adds/merges a line (quantities accumulate), clamped to per-line and\n * line-count caps. Quantity ≤ 0 removes the line.\n */\nexport function upsertCartLine(\n cart: Pick<HostCart, 'lines'>,\n line: CartLine,\n mode: 'add' | 'set' = 'add',\n): CartLine[] {\n const quantity = wholeQuantity(line.quantity)\n const key = lineKey(line)\n const existing = cart.lines.find((item) => lineKey(item) === key)\n if (!existing) {\n if (quantity <= 0) return cart.lines\n if (cart.lines.length >= CART_MAX_LINES) return cart.lines\n return [\n ...cart.lines,\n { ...line, quantity: Math.min(CART_MAX_QUANTITY, quantity) },\n ]\n }\n // The STORED side is coerced too (AGL-2285): a line written before this\n // guard, or by any other writer, can still hold a non-finite quantity, and\n // adding to it would carry that forward forever.\n const nextQuantity =\n mode === 'add' ? wholeQuantity(existing.quantity) + quantity : quantity\n if (nextQuantity <= 0) {\n return cart.lines.filter((item) => lineKey(item) !== key)\n }\n return cart.lines.map((item) =>\n lineKey(item) === key\n ? { ...item, quantity: Math.min(CART_MAX_QUANTITY, nextQuantity) }\n : item,\n )\n}\n\nexport function removeCartLine(\n cart: Pick<HostCart, 'lines'>,\n line: Pick<CartLine, 'productId' | 'variantId'>,\n): CartLine[] {\n const key = lineKey(line)\n return cart.lines.filter((item) => lineKey(item) !== key)\n}\n\n/** Total units across lines (the mini-cart badge). */\nexport function cartCount(cart: Pick<HostCart, 'lines'> | undefined): number {\n // Coerced per line (AGL-2285) so one stored `NaN` cannot make the badge read\n // `NaN` for a cart that otherwise has real items in it.\n return (cart?.lines ?? []).reduce(\n (sum, line) => sum + wholeQuantity(line?.quantity),\n 0,\n )\n}\n\n/**\n * Merges a guest cart into a customer cart on sign-in (AGL-294):\n * quantities accumulate per line, capped as usual.\n */\nexport function mergeCarts(\n customerCart: Pick<HostCart, 'lines'>,\n guestCart: Pick<HostCart, 'lines'>,\n): CartLine[] {\n let lines = [...customerCart.lines]\n for (const line of guestCart.lines) {\n lines = upsertCartLine({ lines }, line, 'add')\n }\n return lines\n}\n"],"names":["CART_MAX_LINES","CART_MAX_QUANTITY","lineKey","line","productId","variantId","wholeQuantity","value","quantity","Math","round","Number","isFinite","upsertCartLine","cart","mode","key","existing","lines","find","item","length","min","nextQuantity","filter","map","removeCartLine","cartCount","reduce","sum","mergeCarts","customerCart","guestCart"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;CAMC;AAkBD,OAAO,MAAMA,iBAAiB,GAAE;AAChC,OAAO,MAAMC,oBAAoB,GAAE;AAEnC,SAASC,QAAQC,IAA+C;QAClCA;IAA5B,OAAO,GAAGA,KAAKC,SAAS,CAAC,CAAC,GAAED,kBAAAA,KAAKE,SAAS,YAAdF,kBAAkB,IAAI;AACpD;AAEA;;;;;;;;;;;;;;;;CAgBC,GACD,SAASG,cAAcC,KAAc;IACnC,MAAMC,WAAWC,KAAKC,KAAK,CAACC,OAAOJ,gBAAAA,QAAS;IAC5C,OAAOI,OAAOC,QAAQ,CAACJ,YAAYA,WAAW;AAChD;AAEA;;;CAGC,GACD,OAAO,SAASK,eACdC,IAA6B,EAC7BX,IAAc,EACdY,OAAsB,KAAK;IAE3B,MAAMP,WAAWF,cAAcH,KAAKK,QAAQ;IAC5C,MAAMQ,MAAMd,QAAQC;IACpB,MAAMc,WAAWH,KAAKI,KAAK,CAACC,IAAI,CAAC,CAACC,OAASlB,QAAQkB,UAAUJ;IAC7D,IAAI,CAACC,UAAU;QACb,IAAIT,YAAY,GAAG,OAAOM,KAAKI,KAAK;QACpC,IAAIJ,KAAKI,KAAK,CAACG,MAAM,IAAIrB,gBAAgB,OAAOc,KAAKI,KAAK;QAC1D,OAAO;eACFJ,KAAKI,KAAK;YACb,aAAKf;gBAAMK,UAAUC,KAAKa,GAAG,CAACrB,mBAAmBO;;SAClD;IACH;IACA,wEAAwE;IACxE,2EAA2E;IAC3E,iDAAiD;IACjD,MAAMe,eACJR,SAAS,QAAQT,cAAcW,SAAST,QAAQ,IAAIA,WAAWA;IACjE,IAAIe,gBAAgB,GAAG;QACrB,OAAOT,KAAKI,KAAK,CAACM,MAAM,CAAC,CAACJ,OAASlB,QAAQkB,UAAUJ;IACvD;IACA,OAAOF,KAAKI,KAAK,CAACO,GAAG,CAAC,CAACL,OACrBlB,QAAQkB,UAAUJ,MACd,aAAKI;YAAMZ,UAAUC,KAAKa,GAAG,CAACrB,mBAAmBsB;aACjDH;AAER;AAEA,OAAO,SAASM,eACdZ,IAA6B,EAC7BX,IAA+C;IAE/C,MAAMa,MAAMd,QAAQC;IACpB,OAAOW,KAAKI,KAAK,CAACM,MAAM,CAAC,CAACJ,OAASlB,QAAQkB,UAAUJ;AACvD;AAEA,oDAAoD,GACpD,OAAO,SAASW,UAAUb,IAAyC;;IACjE,6EAA6E;IAC7E,wDAAwD;IACxD,OAAO,SAACA,wBAAAA,KAAMI,KAAK,mBAAI,EAAE,EAAEU,MAAM,CAC/B,CAACC,KAAK1B,OAAS0B,MAAMvB,cAAcH,wBAAAA,KAAMK,QAAQ,GACjD;AAEJ;AAEA;;;CAGC,GACD,OAAO,SAASsB,WACdC,YAAqC,EACrCC,SAAkC;IAElC,IAAId,QAAQ;WAAIa,aAAab,KAAK;KAAC;IACnC,KAAK,MAAMf,QAAQ6B,UAAUd,KAAK,CAAE;QAClCA,QAAQL,eAAe;YAAEK;QAAM,GAAGf,MAAM;IAC1C;IACA,OAAOe;AACT"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/model/commerce-cart.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Cart v1 (AGL-293): a server-backed cart doc at\n * `hosts/{hostId}/carts/{cartId}`, keyed by an httpOnly cookie. Lines\n * store only ids + quantity — display data and prices resolve from the\n * product docs at read/checkout time, so a stale cart can never charge\n * a stale price. Pure helpers; the cart API owns I/O.\n */\n\nexport interface CartLine {\n productId: string\n /** Absent = the product's default variant. */\n variantId?: string\n quantity: number\n /**\n * The day the shopper chose to use a check-in item (AGL-4043),\n * `YYYY-MM-DD` on the store's calendar. Absent: the day they buy. Two\n * different days of one pass are two lines.\n */\n useDayKey?: string\n}\n\n/** `hosts/{hostId}/carts/{cartId}` doc. */\nexport interface HostCart {\n lines: CartLine[]\n /** Storefront customer once signed in (AGL-294 merge). */\n customerId?: string\n updatedAtMs?: number\n createdAtMs?: number\n}\n\nexport const CART_MAX_LINES = 50\nexport const CART_MAX_QUANTITY = 99\n\n/** One cart line's identity: product, variant and use day. */\nexport function cartLineKey(line: Pick<CartLine, 'productId' | 'variantId' | 'useDayKey'>): string {\n return `${line.productId}:${line.variantId ?? ''}:${line.useDayKey ?? ''}`\n}\n\nconst lineKey = cartLineKey\n\n/**\n * A line quantity, coerced to a whole finite number (AGL-2285).\n *\n * `Math.round(line.quantity)` was the whole sanitiser, and `Math.round(NaN)` is\n * `NaN` — which then walked past the guard below, because `NaN <= 0` is\n * `false`. A cart line with `quantity: NaN` (a legal Firestore double) was\n * stored, and from there `cartCount` reported `NaN` in the mini-cart badge and\n * `cart-checkout.ts` computed `itemsCents`, the platform fee and the Stripe\n * `line_items[n][quantity]` as `NaN` too — so Stripe 400s and the shopper\n * cannot check out AT ALL until they find the poisoned line and remove it.\n *\n * Answering 0 is what makes the existing `<= 0` guard do its job: an\n * unusable quantity removes the line (or refuses to add one) rather than\n * writing a value nothing downstream can compare against. The same lesson as\n * AGL-2229 one collection over — `Math.max`/`Math.min`/`Math.round` propagate\n * `NaN`, they do not discard it.\n */\nfunction wholeQuantity(value: unknown): number {\n const quantity = Math.round(Number(value ?? 0))\n return Number.isFinite(quantity) ? quantity : 0\n}\n\n/**\n * Adds/merges a line (quantities accumulate), clamped to per-line and\n * line-count caps. Quantity ≤ 0 removes the line.\n */\nexport function upsertCartLine(\n cart: Pick<HostCart, 'lines'>,\n line: CartLine,\n mode: 'add' | 'set' = 'add',\n): CartLine[] {\n const quantity = wholeQuantity(line.quantity)\n const key = lineKey(line)\n const existing = cart.lines.find((item) => lineKey(item) === key)\n if (!existing) {\n if (quantity <= 0) return cart.lines\n if (cart.lines.length >= CART_MAX_LINES) return cart.lines\n return [\n ...cart.lines,\n { ...line, quantity: Math.min(CART_MAX_QUANTITY, quantity) },\n ]\n }\n // The STORED side is coerced too (AGL-2285): a line written before this\n // guard, or by any other writer, can still hold a non-finite quantity, and\n // adding to it would carry that forward forever.\n const nextQuantity =\n mode === 'add' ? wholeQuantity(existing.quantity) + quantity : quantity\n if (nextQuantity <= 0) {\n return cart.lines.filter((item) => lineKey(item) !== key)\n }\n return cart.lines.map((item) =>\n lineKey(item) === key\n ? { ...item, quantity: Math.min(CART_MAX_QUANTITY, nextQuantity) }\n : item,\n )\n}\n\nexport function removeCartLine(\n cart: Pick<HostCart, 'lines'>,\n line: Pick<CartLine, 'productId' | 'variantId' | 'useDayKey'>,\n): CartLine[] {\n const key = lineKey(line)\n return cart.lines.filter((item) => lineKey(item) !== key)\n}\n\n/** Total units across lines (the mini-cart badge). */\nexport function cartCount(cart: Pick<HostCart, 'lines'> | undefined): number {\n // Coerced per line (AGL-2285) so one stored `NaN` cannot make the badge read\n // `NaN` for a cart that otherwise has real items in it.\n return (cart?.lines ?? []).reduce(\n (sum, line) => sum + wholeQuantity(line?.quantity),\n 0,\n )\n}\n\n/**\n * Merges a guest cart into a customer cart on sign-in (AGL-294):\n * quantities accumulate per line, capped as usual.\n */\nexport function mergeCarts(\n customerCart: Pick<HostCart, 'lines'>,\n guestCart: Pick<HostCart, 'lines'>,\n): CartLine[] {\n let lines = [...customerCart.lines]\n for (const line of guestCart.lines) {\n lines = upsertCartLine({ lines }, line, 'add')\n }\n return lines\n}\n"],"names":["CART_MAX_LINES","CART_MAX_QUANTITY","cartLineKey","line","productId","variantId","useDayKey","lineKey","wholeQuantity","value","quantity","Math","round","Number","isFinite","upsertCartLine","cart","mode","key","existing","lines","find","item","length","min","nextQuantity","filter","map","removeCartLine","cartCount","reduce","sum","mergeCarts","customerCart","guestCart"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;CAMC;AAwBD,OAAO,MAAMA,iBAAiB,GAAE;AAChC,OAAO,MAAMC,oBAAoB,GAAE;AAEnC,4DAA4D,GAC5D,OAAO,SAASC,YAAYC,IAA6D;QAC3DA,iBAAwBA;IAApD,OAAO,GAAGA,KAAKC,SAAS,CAAC,CAAC,GAAED,kBAAAA,KAAKE,SAAS,YAAdF,kBAAkB,GAAG,CAAC,GAAEA,kBAAAA,KAAKG,SAAS,YAAdH,kBAAkB,IAAI;AAC5E;AAEA,MAAMI,UAAUL;AAEhB;;;;;;;;;;;;;;;;CAgBC,GACD,SAASM,cAAcC,KAAc;IACnC,MAAMC,WAAWC,KAAKC,KAAK,CAACC,OAAOJ,gBAAAA,QAAS;IAC5C,OAAOI,OAAOC,QAAQ,CAACJ,YAAYA,WAAW;AAChD;AAEA;;;CAGC,GACD,OAAO,SAASK,eACdC,IAA6B,EAC7Bb,IAAc,EACdc,OAAsB,KAAK;IAE3B,MAAMP,WAAWF,cAAcL,KAAKO,QAAQ;IAC5C,MAAMQ,MAAMX,QAAQJ;IACpB,MAAMgB,WAAWH,KAAKI,KAAK,CAACC,IAAI,CAAC,CAACC,OAASf,QAAQe,UAAUJ;IAC7D,IAAI,CAACC,UAAU;QACb,IAAIT,YAAY,GAAG,OAAOM,KAAKI,KAAK;QACpC,IAAIJ,KAAKI,KAAK,CAACG,MAAM,IAAIvB,gBAAgB,OAAOgB,KAAKI,KAAK;QAC1D,OAAO;eACFJ,KAAKI,KAAK;YACb,aAAKjB;gBAAMO,UAAUC,KAAKa,GAAG,CAACvB,mBAAmBS;;SAClD;IACH;IACA,wEAAwE;IACxE,2EAA2E;IAC3E,iDAAiD;IACjD,MAAMe,eACJR,SAAS,QAAQT,cAAcW,SAAST,QAAQ,IAAIA,WAAWA;IACjE,IAAIe,gBAAgB,GAAG;QACrB,OAAOT,KAAKI,KAAK,CAACM,MAAM,CAAC,CAACJ,OAASf,QAAQe,UAAUJ;IACvD;IACA,OAAOF,KAAKI,KAAK,CAACO,GAAG,CAAC,CAACL,OACrBf,QAAQe,UAAUJ,MACd,aAAKI;YAAMZ,UAAUC,KAAKa,GAAG,CAACvB,mBAAmBwB;aACjDH;AAER;AAEA,OAAO,SAASM,eACdZ,IAA6B,EAC7Bb,IAA6D;IAE7D,MAAMe,MAAMX,QAAQJ;IACpB,OAAOa,KAAKI,KAAK,CAACM,MAAM,CAAC,CAACJ,OAASf,QAAQe,UAAUJ;AACvD;AAEA,oDAAoD,GACpD,OAAO,SAASW,UAAUb,IAAyC;;IACjE,6EAA6E;IAC7E,wDAAwD;IACxD,OAAO,SAACA,wBAAAA,KAAMI,KAAK,mBAAI,EAAE,EAAEU,MAAM,CAC/B,CAACC,KAAK5B,OAAS4B,MAAMvB,cAAcL,wBAAAA,KAAMO,QAAQ,GACjD;AAEJ;AAEA;;;CAGC,GACD,OAAO,SAASsB,WACdC,YAAqC,EACrCC,SAAkC;IAElC,IAAId,QAAQ;WAAIa,aAAab,KAAK;KAAC;IACnC,KAAK,MAAMjB,QAAQ+B,UAAUd,KAAK,CAAE;QAClCA,QAAQL,eAAe;YAAEK;QAAM,GAAGjB,MAAM;IAC1C;IACA,OAAOiB;AACT"}