spree_api 5.6.1 → 6.0.0.beta1

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 (540) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +28 -0
  3. data/Rakefile +1 -1
  4. data/app/controllers/concerns/spree/api/v3/address_params.rb +17 -0
  5. data/app/controllers/concerns/spree/api/v3/admin/product_listing.rb +46 -0
  6. data/app/controllers/concerns/spree/api/v3/admin/product_membership.rb +110 -0
  7. data/app/controllers/concerns/spree/api/v3/admin/receivable_actions.rb +68 -0
  8. data/app/controllers/concerns/spree/api/v3/admin/reporting_authorization.rb +27 -0
  9. data/app/controllers/concerns/spree/api/v3/admin/role_grant_guard.rb +69 -33
  10. data/app/controllers/concerns/spree/api/v3/admin/stock_receipt_actions.rb +86 -0
  11. data/app/controllers/concerns/spree/api/v3/admin/store_context.rb +97 -0
  12. data/app/controllers/concerns/spree/api/v3/admin/subclassed_resource.rb +12 -6
  13. data/app/controllers/concerns/spree/api/v3/admin/validation_details.rb +91 -0
  14. data/app/controllers/concerns/spree/api/v3/admin_authentication.rb +9 -5
  15. data/app/controllers/concerns/spree/api/v3/api_key_authentication.rb +41 -5
  16. data/app/controllers/concerns/spree/api/v3/authentication_strategies.rb +48 -0
  17. data/app/controllers/concerns/spree/api/v3/bulk_operations.rb +4 -6
  18. data/app/controllers/concerns/spree/api/v3/cart_resolvable.rb +52 -16
  19. data/app/controllers/concerns/spree/api/v3/company_address_writes.rb +37 -0
  20. data/app/controllers/concerns/spree/api/v3/current_password_confirmation.rb +41 -0
  21. data/app/controllers/concerns/spree/api/v3/direct_uploads.rb +35 -0
  22. data/app/controllers/concerns/spree/api/v3/error_handler.rb +53 -11
  23. data/app/controllers/concerns/spree/api/v3/idempotent.rb +10 -4
  24. data/app/controllers/concerns/spree/api/v3/items_payload.rb +54 -0
  25. data/app/controllers/concerns/spree/api/v3/jwt_authentication.rb +23 -3
  26. data/app/controllers/concerns/spree/api/v3/key_store_context.rb +31 -0
  27. data/app/controllers/concerns/spree/api/v3/locale_and_currency.rb +3 -3
  28. data/app/controllers/concerns/spree/api/v3/order_lock.rb +22 -3
  29. data/app/controllers/concerns/spree/api/v3/orders/claim_actions.rb +112 -0
  30. data/app/controllers/concerns/spree/api/v3/orders/delivery_actions.rb +105 -0
  31. data/app/controllers/concerns/spree/api/v3/orders/exchange_actions.rb +117 -0
  32. data/app/controllers/concerns/spree/api/v3/orders/fulfillment_actions.rb +157 -0
  33. data/app/controllers/concerns/spree/api/v3/orders/post_sale_actions.rb +76 -0
  34. data/app/controllers/concerns/spree/api/v3/orders/return_actions.rb +116 -0
  35. data/app/controllers/concerns/spree/api/v3/orders/shipping_label_actions.rb +128 -0
  36. data/app/controllers/concerns/spree/api/v3/params_normalizer.rb +7 -4
  37. data/app/controllers/concerns/spree/api/v3/permission_serialization.rb +42 -0
  38. data/app/controllers/concerns/spree/api/v3/rate_limit_headers.rb +40 -6
  39. data/app/controllers/concerns/spree/api/v3/scoped_authorization.rb +80 -26
  40. data/app/controllers/concerns/spree/api/v3/seller/auth_cookies.rb +62 -0
  41. data/app/controllers/concerns/spree/api/v3/seller/seller_context.rb +127 -0
  42. data/app/controllers/concerns/spree/api/v3/seller_authentication.rb +40 -0
  43. data/app/controllers/concerns/spree/api/v3/storefront_access.rb +38 -0
  44. data/app/controllers/concerns/spree/api/v3/streams_shipping_label.rb +37 -0
  45. data/app/controllers/concerns/spree/api/v3/tax_identifier_validation.rb +41 -0
  46. data/app/controllers/spree/api/v3/admin/admin_users_controller.rb +11 -14
  47. data/app/controllers/spree/api/v3/admin/allowed_origins_controller.rb +1 -1
  48. data/app/controllers/spree/api/v3/admin/api_keys_controller.rb +16 -7
  49. data/app/controllers/spree/api/v3/admin/auth_controller.rb +138 -22
  50. data/app/controllers/spree/api/v3/admin/base_controller.rb +2 -0
  51. data/app/controllers/spree/api/v3/admin/catalog_assignments_controller.rb +27 -0
  52. data/app/controllers/spree/api/v3/admin/catalogs/base_controller.rb +29 -0
  53. data/app/controllers/spree/api/v3/admin/catalogs/order_minimums_controller.rb +40 -0
  54. data/app/controllers/spree/api/v3/admin/catalogs/products_controller.rb +107 -0
  55. data/app/controllers/spree/api/v3/admin/catalogs/quantity_rules_controller.rb +75 -0
  56. data/app/controllers/spree/api/v3/admin/catalogs_controller.rb +191 -0
  57. data/app/controllers/spree/api/v3/admin/categories/products_controller.rb +28 -41
  58. data/app/controllers/spree/api/v3/admin/categories_controller.rb +16 -7
  59. data/app/controllers/spree/api/v3/admin/channels_controller.rb +50 -2
  60. data/app/controllers/spree/api/v3/admin/claim_reasons_controller.rb +25 -0
  61. data/app/controllers/spree/api/v3/admin/claims_controller.rb +31 -0
  62. data/app/controllers/spree/api/v3/admin/collection_rules_controller.rb +40 -0
  63. data/app/controllers/spree/api/v3/admin/collections/products_controller.rb +101 -0
  64. data/app/controllers/spree/api/v3/admin/collections_controller.rb +56 -0
  65. data/app/controllers/spree/api/v3/admin/commission_lines_controller.rb +39 -0
  66. data/app/controllers/spree/api/v3/admin/commission_rates_controller.rb +174 -0
  67. data/app/controllers/spree/api/v3/admin/companies/addresses_controller.rb +65 -0
  68. data/app/controllers/spree/api/v3/admin/companies/base_controller.rb +29 -0
  69. data/app/controllers/spree/api/v3/admin/companies/invitations_controller.rb +56 -0
  70. data/app/controllers/spree/api/v3/admin/companies/memberships_controller.rb +66 -0
  71. data/app/controllers/spree/api/v3/admin/companies/tax_exemption_certificates_controller.rb +137 -0
  72. data/app/controllers/spree/api/v3/admin/companies/tax_identifiers_controller.rb +46 -0
  73. data/app/controllers/spree/api/v3/admin/companies_controller.rb +59 -0
  74. data/app/controllers/spree/api/v3/admin/concerns/external_references.rb +166 -0
  75. data/app/controllers/spree/api/v3/admin/consent_records_controller.rb +31 -0
  76. data/app/controllers/spree/api/v3/admin/countries_controller.rb +12 -4
  77. data/app/controllers/spree/api/v3/admin/custom_field_definitions_controller.rb +19 -4
  78. data/app/controllers/spree/api/v3/admin/custom_fields_controller.rb +5 -5
  79. data/app/controllers/spree/api/v3/admin/customer_groups_controller.rb +1 -1
  80. data/app/controllers/spree/api/v3/admin/customers/addresses_controller.rb +4 -4
  81. data/app/controllers/spree/api/v3/admin/customers/base_controller.rb +1 -1
  82. data/app/controllers/spree/api/v3/admin/customers/store_credits_controller.rb +2 -3
  83. data/app/controllers/spree/api/v3/admin/customers/tax_identifiers_controller.rb +43 -0
  84. data/app/controllers/spree/api/v3/admin/customers_controller.rb +190 -11
  85. data/app/controllers/spree/api/v3/admin/dashboard_controller.rb +24 -20
  86. data/app/controllers/spree/api/v3/admin/data_requests_controller.rb +60 -0
  87. data/app/controllers/spree/api/v3/admin/delivery_method_rules_controller.rb +54 -0
  88. data/app/controllers/spree/api/v3/admin/delivery_methods/rules_controller.rb +114 -0
  89. data/app/controllers/spree/api/v3/admin/delivery_methods_controller.rb +243 -0
  90. data/app/controllers/spree/api/v3/admin/delivery_profiles/origin_groups_controller.rb +80 -0
  91. data/app/controllers/spree/api/v3/admin/delivery_profiles_controller.rb +107 -0
  92. data/app/controllers/spree/api/v3/admin/delivery_zones_controller.rb +116 -0
  93. data/app/controllers/spree/api/v3/admin/digital_links_controller.rb +48 -0
  94. data/app/controllers/spree/api/v3/admin/direct_uploads_controller.rb +17 -3
  95. data/app/controllers/spree/api/v3/admin/exchanges_controller.rb +31 -0
  96. data/app/controllers/spree/api/v3/admin/exports_controller.rb +2 -2
  97. data/app/controllers/spree/api/v3/admin/gift_card_batches_controller.rb +1 -1
  98. data/app/controllers/spree/api/v3/admin/gift_cards_controller.rb +3 -2
  99. data/app/controllers/spree/api/v3/admin/imports_controller.rb +71 -8
  100. data/app/controllers/spree/api/v3/admin/integrations_controller.rb +67 -0
  101. data/app/controllers/spree/api/v3/admin/invitation_acceptances_controller.rb +5 -5
  102. data/app/controllers/spree/api/v3/admin/invitations_controller.rb +5 -1
  103. data/app/controllers/spree/api/v3/admin/locales_controller.rb +3 -1
  104. data/app/controllers/spree/api/v3/admin/markets_controller.rb +9 -5
  105. data/app/controllers/spree/api/v3/admin/me_controller.rb +4 -30
  106. data/app/controllers/spree/api/v3/admin/media_controller.rb +88 -38
  107. data/app/controllers/spree/api/v3/admin/media_library_controller.rb +156 -0
  108. data/app/controllers/spree/api/v3/admin/option_types_controller.rb +1 -0
  109. data/app/controllers/spree/api/v3/admin/order_cancellation_reasons_controller.rb +25 -0
  110. data/app/controllers/spree/api/v3/admin/order_groups_controller.rb +43 -0
  111. data/app/controllers/spree/api/v3/admin/order_routing_rules_controller.rb +1 -1
  112. data/app/controllers/spree/api/v3/admin/orders/claims_controller.rb +56 -0
  113. data/app/controllers/spree/api/v3/admin/orders/deliveries_controller.rb +66 -0
  114. data/app/controllers/spree/api/v3/admin/orders/discount_codes_controller.rb +86 -0
  115. data/app/controllers/spree/api/v3/admin/orders/discounts_controller.rb +99 -0
  116. data/app/controllers/spree/api/v3/admin/orders/exchanges_controller.rb +62 -0
  117. data/app/controllers/spree/api/v3/admin/orders/fees_controller.rb +83 -0
  118. data/app/controllers/spree/api/v3/admin/orders/fulfillments_controller.rb +45 -67
  119. data/app/controllers/spree/api/v3/admin/orders/items_controller.rb +40 -22
  120. data/app/controllers/spree/api/v3/admin/orders/labels_controller.rb +75 -0
  121. data/app/controllers/spree/api/v3/admin/orders/payments_controller.rb +36 -18
  122. data/app/controllers/spree/api/v3/admin/orders/refunds_controller.rb +39 -18
  123. data/app/controllers/spree/api/v3/admin/orders/returns_controller.rb +70 -0
  124. data/app/controllers/spree/api/v3/admin/orders/store_credits_controller.rb +2 -2
  125. data/app/controllers/spree/api/v3/admin/orders/tax_identifiers_controller.rb +41 -0
  126. data/app/controllers/spree/api/v3/admin/orders/tax_lines_controller.rb +32 -0
  127. data/app/controllers/spree/api/v3/admin/orders_controller.rb +157 -32
  128. data/app/controllers/spree/api/v3/admin/package_types_controller.rb +39 -0
  129. data/app/controllers/spree/api/v3/admin/password_resets_controller.rb +1 -1
  130. data/app/controllers/spree/api/v3/admin/payment_methods_controller.rb +15 -4
  131. data/app/controllers/spree/api/v3/admin/payout_providers_controller.rb +27 -0
  132. data/app/controllers/spree/api/v3/admin/permissions_controller.rb +30 -0
  133. data/app/controllers/spree/api/v3/admin/policies_controller.rb +42 -0
  134. data/app/controllers/spree/api/v3/admin/price_lists/products_controller.rb +93 -0
  135. data/app/controllers/spree/api/v3/admin/price_lists_controller.rb +43 -29
  136. data/app/controllers/spree/api/v3/admin/prices_controller.rb +41 -4
  137. data/app/controllers/spree/api/v3/admin/product_types_controller.rb +93 -0
  138. data/app/controllers/spree/api/v3/admin/products/digital_assets_controller.rb +148 -0
  139. data/app/controllers/spree/api/v3/admin/products/variants_controller.rb +24 -3
  140. data/app/controllers/spree/api/v3/admin/products_controller.rb +149 -33
  141. data/app/controllers/spree/api/v3/admin/promotion_actions_controller.rb +6 -2
  142. data/app/controllers/spree/api/v3/admin/promotion_rules_controller.rb +1 -1
  143. data/app/controllers/spree/api/v3/admin/promotions_controller.rb +1 -5
  144. data/app/controllers/spree/api/v3/admin/purchase_orders/stock_receipts_controller.rb +32 -0
  145. data/app/controllers/spree/api/v3/admin/purchase_orders_controller.rb +161 -0
  146. data/app/controllers/spree/api/v3/admin/refund_reasons_controller.rb +25 -0
  147. data/app/controllers/spree/api/v3/admin/reporting/saved_reports_controller.rb +45 -0
  148. data/app/controllers/spree/api/v3/admin/reporting_controller.rb +95 -0
  149. data/app/controllers/spree/api/v3/admin/resource_controller.rb +27 -10
  150. data/app/controllers/spree/api/v3/admin/return_reasons_controller.rb +25 -0
  151. data/app/controllers/spree/api/v3/admin/returns_controller.rb +31 -0
  152. data/app/controllers/spree/api/v3/admin/roles_controller.rb +50 -6
  153. data/app/controllers/spree/api/v3/admin/seller_payouts_controller.rb +83 -0
  154. data/app/controllers/spree/api/v3/admin/seller_requirement_submissions_controller.rb +139 -0
  155. data/app/controllers/spree/api/v3/admin/seller_requirements_controller.rb +115 -0
  156. data/app/controllers/spree/api/v3/admin/seller_transfers_controller.rb +36 -0
  157. data/app/controllers/spree/api/v3/admin/sellers/balances_controller.rb +44 -0
  158. data/app/controllers/spree/api/v3/admin/sellers/invitations_controller.rb +77 -0
  159. data/app/controllers/spree/api/v3/admin/sellers/payouts_controller.rb +107 -0
  160. data/app/controllers/spree/api/v3/admin/sellers/team_controller.rb +64 -0
  161. data/app/controllers/spree/api/v3/admin/sellers_controller.rb +197 -0
  162. data/app/controllers/spree/api/v3/admin/setup_controller.rb +231 -0
  163. data/app/controllers/spree/api/v3/admin/stock_levels_controller.rb +172 -0
  164. data/app/controllers/spree/api/v3/admin/stock_locations_controller.rb +3 -2
  165. data/app/controllers/spree/api/v3/admin/stock_movements_controller.rb +37 -0
  166. data/app/controllers/spree/api/v3/admin/stock_reservations_controller.rb +1 -1
  167. data/app/controllers/spree/api/v3/admin/stock_transfers/stock_receipts_controller.rb +31 -0
  168. data/app/controllers/spree/api/v3/admin/stock_transfers_controller.rb +134 -38
  169. data/app/controllers/spree/api/v3/admin/store_controller.rb +65 -0
  170. data/app/controllers/spree/api/v3/admin/store_credits/events_controller.rb +47 -0
  171. data/app/controllers/spree/api/v3/admin/store_credits_controller.rb +87 -0
  172. data/app/controllers/spree/api/v3/admin/suppliers_controller.rb +30 -0
  173. data/app/controllers/spree/api/v3/admin/tags_controller.rb +2 -2
  174. data/app/controllers/spree/api/v3/admin/tax_categories_controller.rb +4 -0
  175. data/app/controllers/spree/api/v3/admin/tax_providers_controller.rb +25 -0
  176. data/app/controllers/spree/api/v3/admin/tax_rates_controller.rb +33 -0
  177. data/app/controllers/spree/api/v3/admin/tracking_carriers_controller.rb +33 -0
  178. data/app/controllers/spree/api/v3/admin/translatable_resources_controller.rb +37 -9
  179. data/app/controllers/spree/api/v3/admin/translations_controller.rb +10 -5
  180. data/app/controllers/spree/api/v3/admin/translations_coverage_controller.rb +150 -0
  181. data/app/controllers/spree/api/v3/admin/variants_controller.rb +11 -4
  182. data/app/controllers/spree/api/v3/admin/webhook_endpoints_controller.rb +1 -1
  183. data/app/controllers/spree/api/v3/base_controller.rb +59 -16
  184. data/app/controllers/spree/api/v3/resource_controller.rb +154 -38
  185. data/app/controllers/spree/api/v3/seller/auth_controller.rb +169 -0
  186. data/app/controllers/spree/api/v3/seller/balances_controller.rb +35 -0
  187. data/app/controllers/spree/api/v3/seller/base_controller.rb +25 -0
  188. data/app/controllers/spree/api/v3/seller/claim_reasons_controller.rb +20 -0
  189. data/app/controllers/spree/api/v3/seller/countries_controller.rb +38 -0
  190. data/app/controllers/spree/api/v3/seller/delivery_methods_controller.rb +265 -0
  191. data/app/controllers/spree/api/v3/seller/delivery_profiles_controller.rb +65 -0
  192. data/app/controllers/spree/api/v3/seller/delivery_zones_controller.rb +41 -0
  193. data/app/controllers/spree/api/v3/seller/direct_uploads_controller.rb +21 -0
  194. data/app/controllers/spree/api/v3/seller/exports_controller.rb +195 -0
  195. data/app/controllers/spree/api/v3/seller/import_rows_controller.rb +49 -0
  196. data/app/controllers/spree/api/v3/seller/imports_controller.rb +317 -0
  197. data/app/controllers/spree/api/v3/seller/invitation_acceptances_controller.rb +152 -0
  198. data/app/controllers/spree/api/v3/seller/invitations_controller.rb +71 -0
  199. data/app/controllers/spree/api/v3/seller/me_controller.rb +72 -0
  200. data/app/controllers/spree/api/v3/seller/onboarding_controller.rb +111 -0
  201. data/app/controllers/spree/api/v3/seller/order_cancellation_reasons_controller.rb +25 -0
  202. data/app/controllers/spree/api/v3/seller/orders/base_controller.rb +44 -0
  203. data/app/controllers/spree/api/v3/seller/orders/claims_controller.rb +45 -0
  204. data/app/controllers/spree/api/v3/seller/orders/deliveries_controller.rb +38 -0
  205. data/app/controllers/spree/api/v3/seller/orders/exchanges_controller.rb +50 -0
  206. data/app/controllers/spree/api/v3/seller/orders/fulfillments_controller.rb +79 -0
  207. data/app/controllers/spree/api/v3/seller/orders/labels_controller.rb +55 -0
  208. data/app/controllers/spree/api/v3/seller/orders/notes_controller.rb +82 -0
  209. data/app/controllers/spree/api/v3/seller/orders/returns_controller.rb +44 -0
  210. data/app/controllers/spree/api/v3/seller/orders_controller.rb +199 -0
  211. data/app/controllers/spree/api/v3/seller/package_types_controller.rb +100 -0
  212. data/app/controllers/spree/api/v3/seller/password_resets_controller.rb +155 -0
  213. data/app/controllers/spree/api/v3/seller/payouts_controller.rb +47 -0
  214. data/app/controllers/spree/api/v3/seller/policies_controller.rb +57 -0
  215. data/app/controllers/spree/api/v3/seller/product_types_controller.rb +35 -0
  216. data/app/controllers/spree/api/v3/seller/products_controller.rb +394 -0
  217. data/app/controllers/spree/api/v3/seller/profile_controller.rb +137 -0
  218. data/app/controllers/spree/api/v3/seller/reasons_controller.rb +45 -0
  219. data/app/controllers/spree/api/v3/seller/requirement_submissions_controller.rb +95 -0
  220. data/app/controllers/spree/api/v3/seller/resource_controller.rb +75 -0
  221. data/app/controllers/spree/api/v3/seller/return_reasons_controller.rb +20 -0
  222. data/app/controllers/spree/api/v3/seller/stock_locations_controller.rb +56 -0
  223. data/app/controllers/spree/api/v3/seller/tax_identifiers_controller.rb +48 -0
  224. data/app/controllers/spree/api/v3/seller/team_controller.rb +103 -0
  225. data/app/controllers/spree/api/v3/seller/tracking_carriers_controller.rb +35 -0
  226. data/app/controllers/spree/api/v3/seller/transfers_controller.rb +43 -0
  227. data/app/controllers/spree/api/v3/store/account/companies_controller.rb +42 -0
  228. data/app/controllers/spree/api/v3/store/auth_controller.rb +21 -34
  229. data/app/controllers/spree/api/v3/store/base_controller.rb +4 -0
  230. data/app/controllers/spree/api/v3/store/carts/discount_codes_controller.rb +24 -2
  231. data/app/controllers/spree/api/v3/store/carts/fulfillments_controller.rb +41 -15
  232. data/app/controllers/spree/api/v3/store/carts/items_controller.rb +53 -20
  233. data/app/controllers/spree/api/v3/store/carts/payment_sessions_controller.rb +36 -20
  234. data/app/controllers/spree/api/v3/store/carts/po_documents_controller.rb +111 -0
  235. data/app/controllers/spree/api/v3/store/carts/store_credits_controller.rb +2 -2
  236. data/app/controllers/spree/api/v3/store/carts/tax_identifiers_controller.rb +96 -0
  237. data/app/controllers/spree/api/v3/store/carts_controller.rb +57 -12
  238. data/app/controllers/spree/api/v3/store/categories_controller.rb +6 -3
  239. data/app/controllers/spree/api/v3/store/collections/products_controller.rb +59 -0
  240. data/app/controllers/spree/api/v3/store/collections_controller.rb +36 -0
  241. data/app/controllers/spree/api/v3/store/companies/addresses_controller.rb +81 -0
  242. data/app/controllers/spree/api/v3/store/companies/base_controller.rb +24 -0
  243. data/app/controllers/spree/api/v3/store/companies/invitations_controller.rb +50 -0
  244. data/app/controllers/spree/api/v3/store/companies/members_controller.rb +66 -0
  245. data/app/controllers/spree/api/v3/store/companies/orders_controller.rb +28 -0
  246. data/app/controllers/spree/api/v3/store/companies_controller.rb +47 -0
  247. data/app/controllers/spree/api/v3/store/company_invitations_controller.rb +90 -0
  248. data/app/controllers/spree/api/v3/store/countries_controller.rb +8 -6
  249. data/app/controllers/spree/api/v3/store/customer/addresses_controller.rb +3 -1
  250. data/app/controllers/spree/api/v3/store/customer/data_requests_controller.rb +78 -0
  251. data/app/controllers/spree/api/v3/store/customer/digital_links_controller.rb +52 -0
  252. data/app/controllers/spree/api/v3/store/customer/orders_controller.rb +6 -0
  253. data/app/controllers/spree/api/v3/store/customer/password_resets_controller.rb +7 -3
  254. data/app/controllers/spree/api/v3/store/customer/payment_setup_sessions_controller.rb +3 -3
  255. data/app/controllers/spree/api/v3/store/customer/store_credits_controller.rb +0 -3
  256. data/app/controllers/spree/api/v3/store/customer/tax_identifiers_controller.rb +91 -0
  257. data/app/controllers/spree/api/v3/store/customers_controller.rb +26 -31
  258. data/app/controllers/spree/api/v3/store/data_feeds_controller.rb +11 -0
  259. data/app/controllers/spree/api/v3/store/data_request_downloads_controller.rb +58 -0
  260. data/app/controllers/spree/api/v3/store/delivery_methods_controller.rb +108 -0
  261. data/app/controllers/spree/api/v3/store/digital_links_controller.rb +105 -0
  262. data/app/controllers/spree/api/v3/store/markets/countries_controller.rb +5 -9
  263. data/app/controllers/spree/api/v3/store/markets_controller.rb +4 -4
  264. data/app/controllers/spree/api/v3/store/newsletter_subscribers_controller.rb +8 -9
  265. data/app/controllers/spree/api/v3/store/orders/claims_controller.rb +94 -0
  266. data/app/controllers/spree/api/v3/store/orders/returns_controller.rb +116 -0
  267. data/app/controllers/spree/api/v3/store/orders/tax_identifiers_controller.rb +46 -0
  268. data/app/controllers/spree/api/v3/store/orders_controller.rb +12 -15
  269. data/app/controllers/spree/api/v3/store/products/filters_controller.rb +10 -3
  270. data/app/controllers/spree/api/v3/store/products_controller.rb +25 -6
  271. data/app/controllers/spree/api/v3/store/resource_controller.rb +2 -0
  272. data/app/controllers/spree/api/v3/store/sellers_controller.rb +43 -0
  273. data/app/controllers/spree/api/v3/store/wishlist_items_controller.rb +9 -6
  274. data/app/controllers/spree/api/v3/store/wishlists_controller.rb +3 -3
  275. data/app/controllers/spree/api/v3/webhooks/fulfillments_controller.rb +88 -0
  276. data/app/controllers/spree/api/v3/webhooks/payments_controller.rb +5 -2
  277. data/app/controllers/spree/api/v3/webhooks/payouts_controller.rb +61 -0
  278. data/app/models/spree/api/data_request_urls.rb +25 -0
  279. data/app/models/spree/api/digital_link_urls.rb +26 -0
  280. data/app/serializers/spree/api/v3/address_serializer.rb +17 -5
  281. data/app/serializers/spree/api/v3/admin/address_serializer.rb +27 -4
  282. data/app/serializers/spree/api/v3/admin/admin_user_serializer.rb +13 -10
  283. data/app/serializers/spree/api/v3/admin/api_key_serializer.rb +1 -1
  284. data/app/serializers/spree/api/v3/admin/applied_promotion_serializer.rb +15 -0
  285. data/app/serializers/spree/api/v3/admin/cart_serializer.rb +34 -0
  286. data/app/serializers/spree/api/v3/admin/catalog_assignment_serializer.rb +32 -0
  287. data/app/serializers/spree/api/v3/admin/catalog_order_minimum_serializer.rb +23 -0
  288. data/app/serializers/spree/api/v3/admin/catalog_price_serializer.rb +48 -0
  289. data/app/serializers/spree/api/v3/admin/catalog_price_tier_serializer.rb +23 -0
  290. data/app/serializers/spree/api/v3/admin/catalog_product_serializer.rb +57 -0
  291. data/app/serializers/spree/api/v3/admin/catalog_product_term_serializer.rb +38 -0
  292. data/app/serializers/spree/api/v3/admin/catalog_quantity_rule_serializer.rb +37 -0
  293. data/app/serializers/spree/api/v3/admin/catalog_serializer.rb +46 -0
  294. data/app/serializers/spree/api/v3/admin/category_serializer.rb +3 -2
  295. data/app/serializers/spree/api/v3/admin/channel_serializer.rb +15 -1
  296. data/app/serializers/spree/api/v3/admin/claim_line_item_serializer.rb +16 -0
  297. data/app/serializers/spree/api/v3/admin/claim_reason_serializer.rb +21 -0
  298. data/app/serializers/spree/api/v3/admin/claim_serializer.rb +29 -0
  299. data/app/serializers/spree/api/v3/admin/collection_rule_serializer.rb +22 -0
  300. data/app/serializers/spree/api/v3/admin/collection_serializer.rb +29 -0
  301. data/app/serializers/spree/api/v3/admin/commission_line_serializer.rb +67 -0
  302. data/app/serializers/spree/api/v3/admin/commission_rate_serializer.rb +69 -0
  303. data/app/serializers/spree/api/v3/admin/commission_rule_serializer.rb +61 -0
  304. data/app/serializers/spree/api/v3/admin/company_invitation_serializer.rb +15 -0
  305. data/app/serializers/spree/api/v3/admin/company_membership_serializer.rb +11 -0
  306. data/app/serializers/spree/api/v3/admin/company_serializer.rb +37 -0
  307. data/app/serializers/spree/api/v3/admin/concerns/external_references_attribute.rb +33 -0
  308. data/app/serializers/spree/api/v3/admin/consent_record_serializer.rb +28 -0
  309. data/app/serializers/spree/api/v3/admin/country_serializer.rb +2 -2
  310. data/app/serializers/spree/api/v3/admin/credit_card_serializer.rb +1 -1
  311. data/app/serializers/spree/api/v3/admin/custom_field_definition_serializer.rb +2 -2
  312. data/app/serializers/spree/api/v3/admin/custom_field_serializer.rb +2 -2
  313. data/app/serializers/spree/api/v3/admin/customer_serializer.rb +23 -22
  314. data/app/serializers/spree/api/v3/admin/dashboard_counter_serializer.rb +24 -0
  315. data/app/serializers/spree/api/v3/admin/data_request_serializer.rb +36 -0
  316. data/app/serializers/spree/api/v3/admin/delivery_method_rule_serializer.rb +32 -0
  317. data/app/serializers/spree/api/v3/admin/delivery_method_serializer.rb +66 -1
  318. data/app/serializers/spree/api/v3/admin/delivery_method_service_serializer.rb +15 -0
  319. data/app/serializers/spree/api/v3/admin/delivery_origin_group_serializer.rb +34 -0
  320. data/app/serializers/spree/api/v3/admin/delivery_profile_serializer.rb +65 -0
  321. data/app/serializers/spree/api/v3/admin/delivery_rate_serializer.rb +10 -1
  322. data/app/serializers/spree/api/v3/admin/delivery_serializer.rb +20 -0
  323. data/app/serializers/spree/api/v3/admin/delivery_zone_member_serializer.rb +11 -0
  324. data/app/serializers/spree/api/v3/admin/delivery_zone_serializer.rb +29 -0
  325. data/app/serializers/spree/api/v3/admin/digital_asset_serializer.rb +59 -0
  326. data/app/serializers/spree/api/v3/admin/discount_serializer.rb +3 -4
  327. data/app/serializers/spree/api/v3/admin/exchange_line_item_serializer.rb +16 -0
  328. data/app/serializers/spree/api/v3/admin/exchange_serializer.rb +35 -0
  329. data/app/serializers/spree/api/v3/admin/export_serializer.rb +20 -1
  330. data/app/serializers/spree/api/v3/admin/fee_serializer.rb +14 -0
  331. data/app/serializers/spree/api/v3/admin/freight_summary_line_serializer.rb +46 -0
  332. data/app/serializers/spree/api/v3/admin/freight_summary_serializer.rb +16 -0
  333. data/app/serializers/spree/api/v3/admin/fulfillment_item_serializer.rb +39 -0
  334. data/app/serializers/spree/api/v3/admin/fulfillment_serializer.rb +31 -9
  335. data/app/serializers/spree/api/v3/admin/gift_card_serializer.rb +2 -3
  336. data/app/serializers/spree/api/v3/admin/import_serializer.rb +15 -2
  337. data/app/serializers/spree/api/v3/admin/integration_serializer.rb +32 -0
  338. data/app/serializers/spree/api/v3/admin/invitation_serializer.rb +4 -4
  339. data/app/serializers/spree/api/v3/admin/line_item_serializer.rb +19 -5
  340. data/app/serializers/spree/api/v3/admin/market_serializer.rb +5 -1
  341. data/app/serializers/spree/api/v3/admin/media_serializer.rb +50 -2
  342. data/app/serializers/spree/api/v3/admin/membership_product_serializer.rb +29 -0
  343. data/app/serializers/spree/api/v3/admin/order_cancellation_reason_serializer.rb +29 -0
  344. data/app/serializers/spree/api/v3/admin/order_group_serializer.rb +50 -0
  345. data/app/serializers/spree/api/v3/admin/order_routing_rule_serializer.rb +2 -6
  346. data/app/serializers/spree/api/v3/admin/order_serializer.rb +131 -19
  347. data/app/serializers/spree/api/v3/admin/package_type_serializer.rb +53 -0
  348. data/app/serializers/spree/api/v3/admin/payment_method_serializer.rb +8 -2
  349. data/app/serializers/spree/api/v3/admin/payment_serializer.rb +6 -0
  350. data/app/serializers/spree/api/v3/admin/payment_split_serializer.rb +41 -0
  351. data/app/serializers/spree/api/v3/admin/permission_serializer.rb +39 -0
  352. data/app/serializers/spree/api/v3/admin/policy_serializer.rb +11 -0
  353. data/app/serializers/spree/api/v3/admin/price_adjustment_tier_serializer.rb +22 -0
  354. data/app/serializers/spree/api/v3/admin/price_list_product_serializer.rb +32 -0
  355. data/app/serializers/spree/api/v3/admin/price_list_serializer.rb +20 -8
  356. data/app/serializers/spree/api/v3/admin/price_rule_serializer.rb +2 -12
  357. data/app/serializers/spree/api/v3/admin/price_serializer.rb +3 -0
  358. data/app/serializers/spree/api/v3/admin/product_serializer.rb +54 -8
  359. data/app/serializers/spree/api/v3/admin/product_submission_serializer.rb +39 -0
  360. data/app/serializers/spree/api/v3/admin/product_type_custom_field_definition_serializer.rb +44 -0
  361. data/app/serializers/spree/api/v3/admin/product_type_serializer.rb +34 -0
  362. data/app/serializers/spree/api/v3/admin/promotion_action_serializer.rb +6 -12
  363. data/app/serializers/spree/api/v3/admin/promotion_rule_serializer.rb +17 -15
  364. data/app/serializers/spree/api/v3/admin/purchase_order_item_serializer.rb +80 -0
  365. data/app/serializers/spree/api/v3/admin/purchase_order_serializer.rb +94 -0
  366. data/app/serializers/spree/api/v3/admin/refund_reason_serializer.rb +27 -0
  367. data/app/serializers/spree/api/v3/admin/refund_serializer.rb +0 -5
  368. data/app/serializers/spree/api/v3/admin/reporting_result_serializer.rb +72 -0
  369. data/app/serializers/spree/api/v3/admin/return_line_item_serializer.rb +16 -0
  370. data/app/serializers/spree/api/v3/admin/return_reason_serializer.rb +21 -0
  371. data/app/serializers/spree/api/v3/admin/return_serializer.rb +59 -0
  372. data/app/serializers/spree/api/v3/admin/role_serializer.rb +24 -6
  373. data/app/serializers/spree/api/v3/admin/saved_report_serializer.rb +33 -0
  374. data/app/serializers/spree/api/v3/admin/seller_balance_serializer.rb +37 -0
  375. data/app/serializers/spree/api/v3/admin/seller_payout_serializer.rb +46 -0
  376. data/app/serializers/spree/api/v3/admin/seller_requirement_serializer.rb +68 -0
  377. data/app/serializers/spree/api/v3/admin/seller_requirement_status_serializer.rb +48 -0
  378. data/app/serializers/spree/api/v3/admin/seller_requirement_submission_serializer.rb +57 -0
  379. data/app/serializers/spree/api/v3/admin/seller_serializer.rb +92 -0
  380. data/app/serializers/spree/api/v3/admin/seller_team_member_serializer.rb +29 -0
  381. data/app/serializers/spree/api/v3/admin/seller_transfer_serializer.rb +53 -0
  382. data/app/serializers/spree/api/v3/admin/shipping_label_serializer.rb +82 -0
  383. data/app/serializers/spree/api/v3/admin/state_serializer.rb +1 -1
  384. data/app/serializers/spree/api/v3/admin/stock_level_serializer.rb +65 -0
  385. data/app/serializers/spree/api/v3/admin/stock_location_serializer.rb +20 -4
  386. data/app/serializers/spree/api/v3/admin/stock_movement_serializer.rb +116 -0
  387. data/app/serializers/spree/api/v3/admin/stock_receipt_item_serializer.rb +57 -0
  388. data/app/serializers/spree/api/v3/admin/stock_receipt_serializer.rb +49 -0
  389. data/app/serializers/spree/api/v3/admin/stock_reservation_serializer.rb +5 -5
  390. data/app/serializers/spree/api/v3/admin/stock_transfer_item_serializer.rb +57 -0
  391. data/app/serializers/spree/api/v3/admin/stock_transfer_serializer.rb +36 -16
  392. data/app/serializers/spree/api/v3/admin/store_credit_event_serializer.rb +32 -0
  393. data/app/serializers/spree/api/v3/admin/store_credit_serializer.rb +42 -7
  394. data/app/serializers/spree/api/v3/admin/store_serializer.rb +63 -1
  395. data/app/serializers/spree/api/v3/admin/supplier_serializer.rb +39 -0
  396. data/app/serializers/spree/api/v3/admin/tax_exemption_certificate_serializer.rb +67 -0
  397. data/app/serializers/spree/api/v3/admin/tax_identifier_serializer.rb +43 -0
  398. data/app/serializers/spree/api/v3/admin/tax_line_serializer.rb +21 -0
  399. data/app/serializers/spree/api/v3/admin/tax_rate_serializer.rb +49 -0
  400. data/app/serializers/spree/api/v3/admin/variant_serializer.rb +49 -8
  401. data/app/serializers/spree/api/v3/applied_promotion_serializer.rb +23 -0
  402. data/app/serializers/spree/api/v3/base_serializer.rb +39 -2
  403. data/app/serializers/spree/api/v3/cart_serializer.rb +90 -12
  404. data/app/serializers/spree/api/v3/category_serializer.rb +3 -3
  405. data/app/serializers/spree/api/v3/claim_line_item_serializer.rb +50 -0
  406. data/app/serializers/spree/api/v3/claim_reason_serializer.rb +20 -0
  407. data/app/serializers/spree/api/v3/claim_serializer.rb +62 -0
  408. data/app/serializers/spree/api/v3/collection_serializer.rb +41 -0
  409. data/app/serializers/spree/api/v3/company_invitation_serializer.rb +28 -0
  410. data/app/serializers/spree/api/v3/company_membership_serializer.rb +28 -0
  411. data/app/serializers/spree/api/v3/company_serializer.rb +33 -0
  412. data/app/serializers/spree/api/v3/custom_field_serializer.rb +2 -2
  413. data/app/serializers/spree/api/v3/customer_serializer.rb +9 -1
  414. data/app/serializers/spree/api/v3/data_request_event_serializer.rb +30 -0
  415. data/app/serializers/spree/api/v3/data_request_serializer.rb +40 -0
  416. data/app/serializers/spree/api/v3/delivery_method_serializer.rb +12 -2
  417. data/app/serializers/spree/api/v3/delivery_rate_serializer.rb +34 -17
  418. data/app/serializers/spree/api/v3/delivery_serializer.rb +29 -0
  419. data/app/serializers/spree/api/v3/delivery_zone_member_serializer.rb +29 -0
  420. data/app/serializers/spree/api/v3/delivery_zone_serializer.rb +13 -0
  421. data/app/serializers/spree/api/v3/digital_asset_serializer.rb +23 -0
  422. data/app/serializers/spree/api/v3/digital_link_serializer.rb +6 -2
  423. data/app/serializers/spree/api/v3/discount_serializer.rb +21 -7
  424. data/app/serializers/spree/api/v3/exchange_line_item_serializer.rb +53 -0
  425. data/app/serializers/spree/api/v3/exchange_serializer.rb +61 -0
  426. data/app/serializers/spree/api/v3/fee_serializer.rb +27 -0
  427. data/app/serializers/spree/api/v3/freight_summary_serializer.rb +38 -0
  428. data/app/serializers/spree/api/v3/fulfillment_serializer.rb +28 -15
  429. data/app/serializers/spree/api/v3/gift_card_serializer.rb +2 -2
  430. data/app/serializers/spree/api/v3/import_row_serializer.rb +1 -1
  431. data/app/serializers/spree/api/v3/import_serializer.rb +18 -4
  432. data/app/serializers/spree/api/v3/invitation_serializer.rb +1 -1
  433. data/app/serializers/spree/api/v3/line_item_serializer.rb +18 -1
  434. data/app/serializers/spree/api/v3/market_serializer.rb +2 -2
  435. data/app/serializers/spree/api/v3/{asset_serializer.rb → media_event_serializer.rb} +4 -4
  436. data/app/serializers/spree/api/v3/media_serializer.rb +48 -7
  437. data/app/serializers/spree/api/v3/newsletter_subscriber_serializer.rb +1 -1
  438. data/app/serializers/spree/api/v3/option_type_serializer.rb +1 -1
  439. data/app/serializers/spree/api/v3/order_group_serializer.rb +60 -0
  440. data/app/serializers/spree/api/v3/order_serializer.rb +58 -6
  441. data/app/serializers/spree/api/v3/payment_method_serializer.rb +1 -1
  442. data/app/serializers/spree/api/v3/payment_serializer.rb +2 -6
  443. data/app/serializers/spree/api/v3/payment_session_serializer.rb +10 -3
  444. data/app/serializers/spree/api/v3/payment_setup_session_serializer.rb +1 -1
  445. data/app/serializers/spree/api/v3/policy_serializer.rb +7 -2
  446. data/app/serializers/spree/api/v3/product_filter_option_serializer.rb +1 -1
  447. data/app/serializers/spree/api/v3/product_serializer.rb +42 -10
  448. data/app/serializers/spree/api/v3/product_type_serializer.rb +17 -0
  449. data/app/serializers/spree/api/v3/purchase_order_event_serializer.rb +11 -0
  450. data/app/serializers/spree/api/v3/refund_serializer.rb +9 -3
  451. data/app/serializers/spree/api/v3/return_line_item_serializer.rb +42 -0
  452. data/app/serializers/spree/api/v3/return_reason_serializer.rb +20 -0
  453. data/app/serializers/spree/api/v3/return_serializer.rb +62 -0
  454. data/app/serializers/spree/api/v3/seller/balance_serializer.rb +35 -0
  455. data/app/serializers/spree/api/v3/seller/claim_line_item_serializer.rb +21 -0
  456. data/app/serializers/spree/api/v3/seller/claim_serializer.rb +25 -0
  457. data/app/serializers/spree/api/v3/seller/delivery_method_rule_serializer.rb +32 -0
  458. data/app/serializers/spree/api/v3/seller/delivery_method_serializer.rb +59 -0
  459. data/app/serializers/spree/api/v3/seller/delivery_profile_serializer.rb +26 -0
  460. data/app/serializers/spree/api/v3/seller/delivery_rate_serializer.rb +35 -0
  461. data/app/serializers/spree/api/v3/seller/delivery_serializer.rb +17 -0
  462. data/app/serializers/spree/api/v3/seller/delivery_zone_serializer.rb +26 -0
  463. data/app/serializers/spree/api/v3/seller/exchange_line_item_serializer.rb +29 -0
  464. data/app/serializers/spree/api/v3/seller/exchange_serializer.rb +30 -0
  465. data/app/serializers/spree/api/v3/seller/export_serializer.rb +44 -0
  466. data/app/serializers/spree/api/v3/seller/fulfillment_item_serializer.rb +43 -0
  467. data/app/serializers/spree/api/v3/seller/fulfillment_serializer.rb +76 -0
  468. data/app/serializers/spree/api/v3/seller/import_mapping_serializer.rb +20 -0
  469. data/app/serializers/spree/api/v3/seller/import_row_serializer.rb +17 -0
  470. data/app/serializers/spree/api/v3/seller/import_serializer.rb +77 -0
  471. data/app/serializers/spree/api/v3/seller/invitation_serializer.rb +29 -0
  472. data/app/serializers/spree/api/v3/seller/media_serializer.rb +26 -0
  473. data/app/serializers/spree/api/v3/seller/order_line_item_serializer.rb +44 -0
  474. data/app/serializers/spree/api/v3/seller/order_serializer.rb +119 -0
  475. data/app/serializers/spree/api/v3/seller/package_type_serializer.rb +52 -0
  476. data/app/serializers/spree/api/v3/seller/payment_split_serializer.rb +34 -0
  477. data/app/serializers/spree/api/v3/seller/payout_serializer.rb +36 -0
  478. data/app/serializers/spree/api/v3/seller/policy_serializer.rb +11 -0
  479. data/app/serializers/spree/api/v3/seller/product_serializer.rb +60 -0
  480. data/app/serializers/spree/api/v3/seller/product_submission_serializer.rb +30 -0
  481. data/app/serializers/spree/api/v3/seller/product_type_serializer.rb +29 -0
  482. data/app/serializers/spree/api/v3/seller/profile_serializer.rb +77 -0
  483. data/app/serializers/spree/api/v3/seller/reason_serializer.rb +24 -0
  484. data/app/serializers/spree/api/v3/seller/requirement_custom_field_serializer.rb +36 -0
  485. data/app/serializers/spree/api/v3/seller/requirement_status_serializer.rb +62 -0
  486. data/app/serializers/spree/api/v3/seller/requirement_submission_serializer.rb +33 -0
  487. data/app/serializers/spree/api/v3/seller/return_line_item_serializer.rb +24 -0
  488. data/app/serializers/spree/api/v3/seller/return_serializer.rb +51 -0
  489. data/app/serializers/spree/api/v3/seller/shipping_label_serializer.rb +23 -0
  490. data/app/serializers/spree/api/v3/seller/stock_level_serializer.rb +27 -0
  491. data/app/serializers/spree/api/v3/seller/stock_location_serializer.rb +17 -0
  492. data/app/serializers/spree/api/v3/seller/tax_identifier_serializer.rb +15 -0
  493. data/app/serializers/spree/api/v3/seller/team_member_serializer.rb +22 -0
  494. data/app/serializers/spree/api/v3/seller/transfer_serializer.rb +49 -0
  495. data/app/serializers/spree/api/v3/seller/variant_serializer.rb +71 -0
  496. data/app/serializers/spree/api/v3/seller_serializer.rb +50 -0
  497. data/app/serializers/spree/api/v3/shipping_label_event_serializer.rb +11 -0
  498. data/app/serializers/spree/api/v3/{stock_item_serializer.rb → stock_level_serializer.rb} +5 -5
  499. data/app/serializers/spree/api/v3/stock_location_serializer.rb +11 -7
  500. data/app/serializers/spree/api/v3/stock_movement_serializer.rb +8 -15
  501. data/app/serializers/spree/api/v3/stock_receipt_event_serializer.rb +11 -0
  502. data/app/serializers/spree/api/v3/stock_transfer_serializer.rb +6 -6
  503. data/app/serializers/spree/api/v3/store_credit_event_serializer.rb +29 -0
  504. data/app/serializers/spree/api/v3/supplier_event_serializer.rb +11 -0
  505. data/app/serializers/spree/api/v3/tax_identifier_serializer.rb +15 -0
  506. data/app/serializers/spree/api/v3/tax_line_serializer.rb +37 -0
  507. data/app/serializers/spree/api/v3/variant_serializer.rb +52 -2
  508. data/app/serializers/spree/api/v3/wishlist_item_serializer.rb +6 -6
  509. data/app/serializers/spree/api/v3/wishlist_serializer.rb +1 -1
  510. data/app/services/spree/api/v3/filters_aggregator.rb +14 -12
  511. data/app/services/spree/webhooks/deliver_webhook.rb +62 -26
  512. data/app/subscribers/spree/webhook_event_subscriber.rb +9 -5
  513. data/config/brakeman.ignore +1 -1
  514. data/config/initializers/typelizer.rb +51 -4
  515. data/config/locales/en.yml +5 -0
  516. data/config/routes.rb +730 -22
  517. data/lib/spree/api/configuration.rb +2 -7
  518. data/lib/spree/api/dependencies.rb +173 -227
  519. data/lib/spree/api/openapi/schema_helper.rb +179 -13
  520. data/lib/spree/api/testing_support/v3/base.rb +45 -15
  521. data/lib/spree/api.rb +10 -4
  522. data/lib/typelizer/open_enums.rb +35 -0
  523. metadata +341 -27
  524. data/app/controllers/spree/api/v3/admin/orders/adjustments_controller.rb +0 -25
  525. data/app/controllers/spree/api/v3/admin/stock_items_controller.rb +0 -42
  526. data/app/controllers/spree/api/v3/admin/store_credit_categories_controller.rb +0 -21
  527. data/app/controllers/spree/api/v3/store/digitals_controller.rb +0 -38
  528. data/app/serializers/spree/api/v3/admin/adjustment_serializer.rb +0 -24
  529. data/app/serializers/spree/api/v3/admin/dashboard_analytics_serializer.rb +0 -143
  530. data/app/serializers/spree/api/v3/admin/reimbursement_serializer.rb +0 -15
  531. data/app/serializers/spree/api/v3/admin/return_authorization_serializer.rb +0 -19
  532. data/app/serializers/spree/api/v3/admin/stock_item_serializer.rb +0 -34
  533. data/app/serializers/spree/api/v3/admin/store_credit_category_serializer.rb +0 -19
  534. data/app/serializers/spree/api/v3/customer_return_serializer.rb +0 -17
  535. data/app/serializers/spree/api/v3/digital_serializer.rb +0 -17
  536. data/app/serializers/spree/api/v3/reimbursement_serializer.rb +0 -27
  537. data/app/serializers/spree/api/v3/report_serializer.rb +0 -34
  538. data/app/serializers/spree/api/v3/return_authorization_serializer.rb +0 -31
  539. data/app/serializers/spree/api/v3/return_item_serializer.rb +0 -53
  540. data/app/serializers/spree/api/v3/shipping_category_serializer.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4feafcfd958681a7548cc9a2e043d7748e98d40fb34426c2aac5cbdc17599472
4
- data.tar.gz: fce6786a2b4f6a41c32a26c34510172032ad9d57095058729261ea90cfc28f1f
3
+ metadata.gz: cd13b5167236c50754b03e48d4e7ab4ff5f1c24cdfd13b5a1ea45ff7a2961dd7
4
+ data.tar.gz: 77ab648d62775d22902a30ff8dbb4927fd0dab1b93668caad957c99a88bcd1fa
5
5
  SHA512:
6
- metadata.gz: 975ceabf8977c54e813177f08cf270e8688dc64e6e446d176e46310696ffc8672dcfb940c19eb0f4c7eace5b765e5883932eca08d973c432e4389539b27709af
7
- data.tar.gz: 9c0ad20112afb852ff2cedd8421f6853a5ce098b0feb435d6346ca015d1190ac891ac38138f98e526bfc973e6f16afb27aadc0917065c236d33ea4023fe34f30
6
+ metadata.gz: 36a716f02b07837cf6360d19cb914ef28a1de1e5cef02b0d6cb503bcc11d89afa6f00f36bd1613d0e9de6962197af6830c8068d03963ca257ac6f59c7ab2fa95
7
+ data.tar.gz: 388abb4801575690aa02e55a907a1851a1d88570a55681c60dc870f693a784024ed7d352e8fcedf493666bd2999269822e9d7abb579d13f3b8345ea9bb340ae2
data/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026-present, Vendo Sp. z o.o., Vendo Connect Inc.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice,
9
+ this list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/Rakefile CHANGED
@@ -37,7 +37,7 @@ namespace :rswag do
37
37
  require 'spree/api/openapi/path_sorter'
38
38
 
39
39
  docs = File.expand_path('../../docs/api-reference', __dir__)
40
- %w[admin.yaml store.yaml].each do |name|
40
+ %w[admin.yaml store.yaml seller.yaml].each do |name|
41
41
  path = File.join(docs, name)
42
42
  next unless File.exist?(path)
43
43
 
@@ -0,0 +1,17 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ # The writable attributes of a nested address.
5
+ #
6
+ # One list rather than one per controller: an address is the same record
7
+ # wherever it hangs, so a column added on one write path but missed on
8
+ # another is dropped silently.
9
+ module AddressParams
10
+ ADDRESS_KEYS = [
11
+ :first_name, :last_name, :company, :address1, :address2, :city,
12
+ :postal_code, :zipcode, :phone, :country_code, :state_code, :state_name, :label
13
+ ].freeze
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,46 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ # Preloads for any controller that serializes products through
6
+ # `Spree.api.admin_product_serializer` — the products index itself and
7
+ # the nested membership listings (a category's or a collection's
8
+ # products).
9
+ #
10
+ # The serializer walks variants, prices, stock items and media for every
11
+ # row, so a listing without these preloads issues a few hundred queries
12
+ # per page instead of a flat couple of dozen.
13
+ module ProductListing
14
+ extend ActiveSupport::Concern
15
+
16
+ protected
17
+
18
+ # Applied to the paginated index. The search provider builds its own
19
+ # relation, so `ProductsController` passes this to it explicitly.
20
+ def collection_includes
21
+ product_listing_includes
22
+ end
23
+
24
+ # Applied to the single-resource lookup by the base controller.
25
+ def scope_includes
26
+ product_listing_includes
27
+ end
28
+
29
+ private
30
+
31
+ def product_listing_includes
32
+ [
33
+ :tax_category,
34
+ :product_type,
35
+ :external_references,
36
+ { product_publications: :channel },
37
+ { primary_media: [attachment_attachment: :blob, poster_attachment: :blob] },
38
+ { default_variant: [:prices, { stock_levels: [:stock_location, :active_stock_reservations] }] },
39
+ { variants: [:prices, { stock_levels: [:stock_location, :active_stock_reservations] }] }
40
+ ]
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,110 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ # The uniform nested products surface every product-curating parent
6
+ # exposes — categories, collections, catalogs and price lists all
7
+ # speak the same protocol:
8
+ #
9
+ # GET /{parents}/:parent_id/products — paginated members
10
+ # POST /{parents}/:parent_id/products — { product_ids: [...] } → 201 { added_count }
11
+ # DELETE /{parents}/:parent_id/products — { product_ids: [...] } → 200 { removed_count }
12
+ # PATCH /{parents}/:parent_id/products/:id/reposition — positioned parents only
13
+ #
14
+ # Both writes are bulk: one request adds or removes any number of
15
+ # products. Ids that don't resolve to a product in the current store
16
+ # are silently dropped, already-present ids don't fail an add, and
17
+ # non-member ids don't fail a remove — the counts report what actually
18
+ # changed. Declared in routes through the +:product_membership+
19
+ # routing concern.
20
+ #
21
+ # A host controller implements:
22
+ # +set_parent+ — load + authorize the parent record
23
+ # +scope+ — the parent's member products
24
+ # +add_member_products+ — persist membership for the given products
25
+ # +remove_member_products+ — remove membership for the given products
26
+ module ProductMembership
27
+ extend ActiveSupport::Concern
28
+
29
+ included do
30
+ include Spree::Api::V3::Admin::ProductListing
31
+
32
+ # Membership actions resolve products themselves; the base
33
+ # single-resource load has nothing to look up.
34
+ skip_before_action :set_resource
35
+ end
36
+
37
+ # POST /{parents}/:parent_id/products
38
+ def create
39
+ products = requested_products(product_scope)
40
+ existing_ids = scope.where(id: products.map(&:id)).pluck(:id).to_set
41
+ new_products = products.reject { |product| existing_ids.include?(product.id) }
42
+
43
+ # Counted by re-reading membership rather than trusting the check
44
+ # above: a concurrent request can claim one of these rows in
45
+ # between, and the caller is told what actually changed.
46
+ added = 0
47
+ if new_products.any?
48
+ add_member_products(new_products)
49
+ added = scope.where(id: new_products.map(&:id)).reorder(nil).distinct.count
50
+ end
51
+
52
+ render json: { added_count: added }, status: :created
53
+ end
54
+
55
+ # DELETE /{parents}/:parent_id/products
56
+ def destroy
57
+ products = requested_products(scope)
58
+
59
+ removed = 0
60
+ if products.any?
61
+ remove_member_products(products)
62
+ # Counted from what is left, for the same reason as `create`.
63
+ still_members = scope.where(id: products.map(&:id)).reorder(nil).distinct.count
64
+ removed = products.size - still_members
65
+ end
66
+
67
+ render json: { removed_count: removed }
68
+ end
69
+
70
+ protected
71
+
72
+ def model_class
73
+ Spree::Product
74
+ end
75
+
76
+ def serializer_class
77
+ Spree.api.admin_product_serializer
78
+ end
79
+
80
+ # @abstract Persist membership for products verified as new members.
81
+ def add_member_products(_products)
82
+ raise NotImplementedError
83
+ end
84
+
85
+ # @abstract Remove membership for products verified as members.
86
+ def remove_member_products(_products)
87
+ raise NotImplementedError
88
+ end
89
+
90
+ # Products the caller may act on, regardless of membership.
91
+ def product_scope
92
+ current_store.products.accessible_by(current_ability, :show)
93
+ end
94
+
95
+ private
96
+
97
+ # Resolves the request's `product_ids` against the given relation.
98
+ # Reordered: a positioned membership scope orders by a join-table
99
+ # column, which PostgreSQL rejects under the DISTINCT needed here —
100
+ # a derived scope (a price list's products through its price rows)
101
+ # can join a product several times.
102
+ def requested_products(relation)
103
+ ids = decode_prefixed_ids(Array(params.require(:product_ids)))
104
+ relation.reorder(nil).where(id: ids).distinct.to_a
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,68 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ # What a stock transfer and a purchase order have in common as
6
+ # endpoints: resolving the lines, warehouses and variants a flat
7
+ # payload names (docs/plans/6.0-inventory-operations.md). The status
8
+ # workflows themselves are run by the actions, which is where the
9
+ # keyword each one takes the document under stays visible.
10
+ #
11
+ # Every id a payload names is resolved through the store — or through
12
+ # the document itself, for its own lines — so an id belonging to
13
+ # another tenant answers 404 rather than being acted on. That is also
14
+ # why nothing here assigns a `*_id` from the payload, and why the lines
15
+ # come from the raw payload rather than `permitted_params`: the latter
16
+ # decodes prefixed ids into primary keys, and a decoded key carries no
17
+ # evidence of whose record it is.
18
+ module ReceivableActions
19
+ extend ActiveSupport::Concern
20
+ include Spree::Api::V3::ItemsPayload
21
+
22
+ protected
23
+
24
+ # What rendering a line actually reads: the variant, the product it
25
+ # belongs to — for the name and the link — and whichever image the
26
+ # thumbnail falls back to, with the blobs the URL helper needs.
27
+ def line_includes
28
+ media = { primary_media: [attachment_attachment: :blob, poster_attachment: :blob] }
29
+ { items: { variant: [media, { product: media }] } }
30
+ end
31
+
32
+ # The lines a create or update named, or nil when the payload said
33
+ # nothing about them — which on an update means "leave them alone".
34
+ #
35
+ # @param attribute_keys [Array<Symbol>] the per-line attributes this
36
+ # document accepts beyond the variant (`:quantity_shipped`,
37
+ # `:quantity_ordered`, `:unit_cost`)
38
+ # @return [Array<Hash>, nil]
39
+ def items_from_params(*attribute_keys)
40
+ sent = items_payload([:variant_id, *attribute_keys])
41
+ return nil if sent.nil?
42
+
43
+ sent.map do |item|
44
+ attributes = { variant: variants_scope.find_by_prefix_id!(item[:variant_id]) }
45
+ attribute_keys.each { |key| attributes[key] = item[key] if item.key?(key.to_s) }
46
+ attributes
47
+ end
48
+ end
49
+
50
+ # Any of the store's warehouses the caller may see, or nil when the
51
+ # payload did not name one.
52
+ #
53
+ # @return [Spree::StockLocation, nil]
54
+ def stock_location_from(key)
55
+ id = params[key]
56
+ return nil if id.blank?
57
+
58
+ current_store.stock_locations.accessible_by(current_ability, :show).find_by_prefix_id!(id)
59
+ end
60
+
61
+ def variants_scope
62
+ current_store.variants.accessible_by(current_ability, :show)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,27 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ # Per-member authorization for the reporting vocabulary. Metrics,
6
+ # dimensions and counters all declare a `subject` (checked for JWT
7
+ # staff through CanCanCan) paired with a `key_scope` (checked for
8
+ # secret keys), so one predicate answers for every member and every
9
+ # surface that lists them — the schema, a query, the home screen's
10
+ # counters — filters by the same rule.
11
+ module ReportingAuthorization
12
+ extend ActiveSupport::Concern
13
+
14
+ private
15
+
16
+ def member_allowed?(member)
17
+ if current_api_key.present?
18
+ member.key_scope.blank? || current_api_key.has_scope?(member.key_scope)
19
+ else
20
+ member.subject.nil? || can?(:read, member.subject.call)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -2,18 +2,15 @@ module Spree
2
2
  module Api
3
3
  module V3
4
4
  module Admin
5
- # Shared guard for staff role grants (admin_users#update and
6
- # invitations#create). A grant is rejected when, in order:
5
+ # Shared anti-amplification guards for everything that hands out
6
+ # authority: role grants (admin_users#update, invitations#create),
7
+ # role permission edits (roles#create/#update), and API-key minting.
7
8
  #
8
- # 1. (opt-in) the caller can't `:create` a Spree::RoleUser i.e. lacks
9
- # the RoleManagement permission set;
10
- # 2. it includes the literal `admin` role and the caller does not hold
11
- # it on the current store;
12
- # 3. it includes any role whose permission sets exceed the caller's own
13
- # (catches SuperUser-equivalent custom roles the name check misses).
14
- #
15
- # API-key principals hold no roles, so they can grant only roles that
16
- # activate no permission sets.
9
+ # The common rule: a caller may only grant authority they effectively
10
+ # hold, compared as expanded catalog keys. A JWT staffer's grant is the
11
+ # union of their store-scoped roles' keys; a secret key's grant is its
12
+ # scopes. Admin-role holders are unbounded; the literal `admin` role is
13
+ # additionally grantable only by admins.
17
14
  module RoleGrantGuard
18
15
  extend ActiveSupport::Concern
19
16
 
@@ -34,7 +31,7 @@ module Spree
34
31
  # past a caller without role-management authority.
35
32
  return true if require_role_management && reject_without_role_management!
36
33
 
37
- roles = Spree::Role.where(id: role_ids.map(&:to_s)).to_a
34
+ roles = current_store.roles.where(id: role_ids.map(&:to_s)).to_a
38
35
  return false if roles.empty?
39
36
 
40
37
  return true if reject_admin_role_grant!(roles)
@@ -43,6 +40,32 @@ module Spree
43
40
  false
44
41
  end
45
42
 
43
+ # Rejects granting permission keys beyond the caller's own — used by
44
+ # roles#create/#update on the requested `permissions` array.
45
+ #
46
+ # @param keys [Array<String>]
47
+ # @return [Boolean] true if the request was rejected
48
+ def reject_unauthorized_permission_grant!(keys)
49
+ excess = excess_permission_keys(keys)
50
+ return false if excess.empty?
51
+
52
+ deny_role_grant!(
53
+ "You cannot grant permissions beyond your own: #{excess.join(', ')}",
54
+ details: { excess_permissions: excess }
55
+ )
56
+ end
57
+
58
+ # The requested keys (expanded) the caller does not hold. Empty when
59
+ # the caller is unbounded.
60
+ #
61
+ # @param keys [Array<String>]
62
+ # @return [Array<String>]
63
+ def excess_permission_keys(keys)
64
+ return [] if caller_holds_admin_role?
65
+
66
+ Spree.permissions.expand_keys(keys) - caller_permission_keys
67
+ end
68
+
46
69
  # For API-key principals CanCanCan is permissive (ScopedAuthorization is
47
70
  # their gate), so this only constrains JWT admins.
48
71
  def reject_without_role_management!
@@ -53,55 +76,68 @@ module Spree
53
76
  end
54
77
 
55
78
  def reject_admin_role_grant!(roles)
56
- return false unless roles.any? { |role| role.name == Spree::Role::ADMIN_ROLE }
79
+ return false unless roles.any?(&:admin?)
57
80
  return false if caller_holds_admin_role?
58
81
 
59
82
  deny_role_grant!('You cannot grant the admin role.')
60
83
  end
61
84
 
62
- # A caller holding the admin role bounds nothing; the literal admin role
63
- # is already gated by reject_admin_role_grant!.
85
+ # A role is grantable when the caller holds every key it carries.
64
86
  def reject_privilege_escalating_grant!(roles)
65
87
  return false if caller_holds_admin_role?
66
88
 
67
- caller_sets = Spree.permissions.permission_sets_for_roles(caller_role_names)
68
- escalating = roles.reject { |role| grantable_within?(role, caller_sets) }
89
+ escalating = roles.reject { |role| excess_permission_keys(role.permissions).empty? }
69
90
  return false if escalating.empty?
70
91
 
71
92
  deny_role_grant!("You cannot grant roles beyond your own privileges: #{escalating.map(&:name).join(', ')}")
72
93
  end
73
94
 
74
- # A role is grantable when every permission set it activates is one the
75
- # caller already holds.
76
- def grantable_within?(role, caller_sets)
77
- (Spree.permissions.permission_sets_for(role.name) - caller_sets).empty?
95
+ # The caller's effective grant as expanded catalog keys. A JWT
96
+ # staffer contributes their store-scoped roles' keys; a secret-key
97
+ # principal contributes its scopes (aliases expand against the
98
+ # catalog).
99
+ #
100
+ # @return [Array<String>]
101
+ def caller_permission_keys
102
+ @caller_permission_keys ||=
103
+ if scope_limited_principal?
104
+ Spree.permissions.expand_keys(current_api_key.scopes)
105
+ else
106
+ Spree.permissions.expand_keys(caller_roles.flat_map(&:permissions))
107
+ end
78
108
  end
79
109
 
80
- # The caller's store-scoped role names, fetched once per request.
81
- # Scoped by store_id so the caller's own privileges are recognized even
82
- # when their role is held on a non-store resource bound to this store.
83
- def caller_role_names
84
- return @caller_role_names if defined?(@caller_role_names)
110
+ # The caller's roles on this store, fetched once per request,
111
+ # mirroring `Spree::Ability#staff_roles`: a role owned by another
112
+ # resource (a marketplace seller) confers no store-admin authority
113
+ # and must not widen what the caller may grant.
114
+ #
115
+ # @return [Array<Spree::Role>]
116
+ def caller_roles
117
+ return @caller_roles if defined?(@caller_roles)
85
118
 
86
119
  user = try_spree_current_user
87
- @caller_role_names =
88
- if user.respond_to?(:role_users)
89
- user.role_users.where(store: current_store).joins(:role).
90
- pluck("#{Spree::Role.table_name}.name")
120
+ @caller_roles =
121
+ if user.respond_to?(:spree_roles)
122
+ user.spree_roles.for_resource(current_store).to_a
91
123
  else
92
124
  []
93
125
  end
94
126
  end
95
127
 
96
128
  def caller_holds_admin_role?
97
- caller_role_names.include?(Spree::Role::ADMIN_ROLE)
129
+ return current_api_key.has_scope?('write_all') if scope_limited_principal?
130
+
131
+ caller_roles.any?(&:admin?) ||
132
+ try_spree_current_user.try(:spree_admin?, current_store)
98
133
  end
99
134
 
100
- def deny_role_grant!(message)
135
+ def deny_role_grant!(message, details: nil)
101
136
  render_error(
102
137
  code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:access_denied],
103
138
  message: message,
104
- status: :forbidden
139
+ status: :forbidden,
140
+ details: details
105
141
  )
106
142
  true
107
143
  end
@@ -0,0 +1,86 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ # The deliveries nested under a purchase order or a transfer. Listing
6
+ # and showing come from the base controller; recording one runs the
7
+ # document's receive workflow, which the including controller names
8
+ # along with the keyword it takes the document under.
9
+ #
10
+ # Every line a payload names is resolved through the document itself,
11
+ # so a line from another order or transfer cannot be received here.
12
+ module StockReceiptActions
13
+ extend ActiveSupport::Concern
14
+ include Spree::Api::V3::ItemsPayload
15
+
16
+ included do
17
+ before_action :authorize_parent_access!
18
+ end
19
+
20
+ protected
21
+
22
+ def model_class
23
+ Spree::StockReceipt
24
+ end
25
+
26
+ def serializer_class
27
+ Spree.api.admin_stock_receipt_serializer
28
+ end
29
+
30
+ def parent_association
31
+ :stock_receipts
32
+ end
33
+
34
+ def scope
35
+ @parent.stock_receipts
36
+ end
37
+
38
+ def collection_includes
39
+ [items: :line]
40
+ end
41
+
42
+ def resource_permitted_attributes
43
+ [:received_at, :reference, :notes]
44
+ end
45
+
46
+ def create_workflow_arguments
47
+ {
48
+ receivable_keyword => @parent,
49
+ items: items_for_receipt,
50
+ received_at: params[:received_at],
51
+ reference: params[:reference],
52
+ notes: params[:notes],
53
+ received_by: try_spree_current_user
54
+ }
55
+ end
56
+
57
+ # What this delivery brought, per line. An omitted `items` means
58
+ # "everything still outstanding arrived intact"; an explicit list —
59
+ # even an empty one — is what the dock counted, and nothing more.
60
+ #
61
+ # @return [Array<Hash>, nil]
62
+ def items_for_receipt
63
+ sent = items_payload(%i[id quantity_accepted quantity_rejected rejection_reason notes])
64
+ return nil if sent.nil?
65
+
66
+ sent.map do |item|
67
+ {
68
+ item: @parent.items.find_by_prefix_id!(item[:id]),
69
+ quantity_accepted: item[:quantity_accepted],
70
+ quantity_rejected: item[:quantity_rejected],
71
+ rejection_reason: item[:rejection_reason],
72
+ notes: item[:notes]
73
+ }
74
+ end
75
+ end
76
+
77
+ # Reading receipts needs only to see the document; booking one is a
78
+ # change to it.
79
+ def authorize_parent_access!
80
+ authorize_parent!(@parent)
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,97 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ # Admin API store context (docs/plans/6.0-store-context-and-first-run-setup.md):
6
+ # a secret key selects its bound store; JWT staff sessions select via
7
+ # the +X-Spree-Store-Id+ header (the admin SDK sends it on every
8
+ # request) and are membership-checked against the store resolved here
9
+ # by AdminAuthentication#require_store_membership!. The request host
10
+ # is never consulted.
11
+ #
12
+ # Included in both Admin API branch anchors (Admin::BaseController and
13
+ # Admin::ResourceController) alongside AdminAuthentication.
14
+ module StoreContext
15
+ extend ActiveSupport::Concern
16
+
17
+ STORE_HEADER = 'X-Spree-Store-Id'.freeze
18
+
19
+ included do
20
+ # Prepended so Spree::Current.store reflects the requested store
21
+ # before any other callback (locale/currency fallbacks, resource
22
+ # lookups) reads it. The store-presence guard 404s an unknown
23
+ # header ID right after this runs.
24
+ prepend_before_action :set_current_store_context
25
+
26
+ # Once-per-process latch for the missing-header notice.
27
+ class_attribute :missing_store_header_warned, default: false, instance_accessor: false
28
+ end
29
+
30
+ # Resolution order: the secret key's bound store, then the header,
31
+ # then the default store — deprecated for JWT requests; the header
32
+ # becomes required in 6.1.
33
+ #
34
+ # @return [Spree::Store, nil]
35
+ def current_store
36
+ return @current_store if defined?(@current_store)
37
+
38
+ @current_store = resolve_admin_store
39
+ end
40
+
41
+ private
42
+
43
+ def set_current_store_context
44
+ if secret_api_key && store_id_header && secret_api_key.store&.prefixed_id != store_id_header
45
+ render_error(
46
+ code: ErrorHandler::ERROR_CODES[:access_denied],
47
+ message: Spree.t('api.errors.store_mismatch', default: 'The requested store does not match the store this API key belongs to.'),
48
+ status: :forbidden
49
+ )
50
+ return
51
+ end
52
+
53
+ # Assigned even when nil: an unknown store id renders 404 further
54
+ # down the chain, and leaving Spree::Current.store holding the
55
+ # previous request's value on this thread would expose another
56
+ # store to anything reading it before that 404 lands.
57
+ Spree::Current.store = current_store
58
+ end
59
+
60
+ def resolve_admin_store
61
+ return secret_api_key.store if secret_api_key
62
+
63
+ if store_id_header
64
+ Spree::Store.find_by_prefix_id(store_id_header)
65
+ else
66
+ # Only warn for authenticated staff traffic — credential-less
67
+ # requests (login, refresh, invitation acceptance) are
68
+ # store-agnostic and legitimately send no header.
69
+ warn_missing_store_header if request.authorization.present?
70
+ Spree::Store.default
71
+ end
72
+ end
73
+
74
+ def store_id_header
75
+ request.headers[STORE_HEADER].presence
76
+ end
77
+
78
+ # A plain once-per-process log line, deliberately NOT
79
+ # Spree::Deprecation: some endpoints structurally cannot carry the
80
+ # header (`/me` runs before any store is selected — it is how the
81
+ # dashboard discovers the user's stores), so a per-request
82
+ # deprecation would be pure noise and would 500 every login
83
+ # bootstrap for apps running deprecations-as-errors.
84
+ def warn_missing_store_header
85
+ return if self.class.missing_store_header_warned
86
+ self.class.missing_store_header_warned = true
87
+
88
+ Rails.logger&.info(
89
+ "Admin API v3 requests without an #{STORE_HEADER} header fall back to the default store. " \
90
+ 'Multi-store clients should send the header; store-agnostic endpoints (/me, auth) are exempt.'
91
+ )
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end