@doswiftly/storefront-operations 9.1.0 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -27,10 +27,10 @@ consumer's `codegen.ts` references this package's `.graphql` files as
27
27
  live in the consumer's repo.
28
28
 
29
29
  <!-- AUTOGEN:STATS:BEGIN — auto-regenerated, do not edit by hand -->
30
- - **Schema version**: 9.1.0
30
+ - **Schema version**: 10.0.0
31
31
  - **Queries**: 48
32
- - **Mutations**: 44
33
- - **Fragments**: 104
32
+ - **Mutations**: 39
33
+ - **Fragments**: 99
34
34
  <!-- AUTOGEN:STATS:END -->
35
35
 
36
36
  ## Loading order
package/CHANGELOG.md CHANGED
@@ -1,5 +1,165 @@
1
1
  # Changelog
2
2
 
3
+ ## 10.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - fcd4c75: Cart GraphQL surface rebuild — Phase 3 Cluster 2 of cart unification.
8
+
9
+ **Breaking changes**:
10
+ - **`cartApplyDiscountCodes` mutation renamed to `cartDiscountCodesUpdate`**. Semantyka pozostaje replace-all (overwrite całej listy discount codes). Migration: change mutation name in your GraphQL queries; arguments + return shape unchanged. Operation name w typed client (`CartApplyDiscountCodes` → `CartDiscountCodesUpdate`).
11
+ - **`CartApplyDiscountCodesPayload` payload type renamed to `CartDiscountCodesUpdatePayload`**. Schema name + TypeScript type reference both renamed.
12
+
13
+ **New mutations** (additive, non-breaking — opt-in for new functionality):
14
+ - `cartSetShippingAddress(input: CartSetShippingAddressInput): CartSetShippingAddressPayload` — ustaw adres dostawy na koszyku.
15
+ - `cartSetBillingAddress(input: CartSetBillingAddressInput): CartSetBillingAddressPayload` — ustaw adres do faktury (jeśli różny od shipping).
16
+ - `cartSelectShippingMethod(input: CartSelectShippingMethodInput): CartSelectShippingMethodPayload` — wybierz metodę wysyłki; argument `shippingMethodId: ID!` (typed UUID, NIE String).
17
+ - `cartSelectPaymentMethod(input: CartSelectPaymentMethodInput): CartSelectPaymentMethodPayload` — wybierz integration payment provider.
18
+ - `cartApplyGiftCard(input: CartApplyGiftCardInput): CartApplyGiftCardPayload` — apply gift card code.
19
+ - `cartRemoveGiftCard(input: CartRemoveGiftCardInput): CartRemoveGiftCardPayload` — remove applied gift card.
20
+ - `cartUpdateGiftCardRecipient(input: CartUpdateGiftCardRecipientInput): CartUpdateGiftCardRecipientPayload` — set recipient info for a gift card line item (personalised delivery).
21
+ - `cartComplete(input: CartCompleteInput): CartCompletePayload` — finalize cart → create Order. Returns `{ cart, order, userErrors, warnings }`. Bez `paymentUrl` w response — wywołaj `order(id: ...)` query po `cartComplete` żeby pobrać `canCreatePayment` + `paymentMethodType` signals (cart aware payment provider selection).
22
+
23
+ **Extended types**:
24
+ - `Cart` object dostaje 7 nowych pól reprezentujących cart completion state:
25
+ - `email: String`
26
+ - `phone: String`
27
+ - `shippingAddress: MailingAddress`
28
+ - `billingAddress: MailingAddress`
29
+ - `selectedShippingMethod: CartShippingMethod` — typed jako nowy ObjectType `CartShippingMethod` (handle, title, price).
30
+ - `selectedPaymentMethod: PaymentMethod`
31
+ - `appliedGiftCards: [CartAppliedGiftCard!]!` — non-null array (empty `[]` gdy zero gift cards applied).
32
+ - `CartCreateInput` dostaje opcjonalne pola `email: String` + `shippingAddress: CartAddressInput` — pozwala utworzyć cart z initial fulfillment context w jednym round-trip (zamiast cartCreate → cartUpdateBuyerIdentity → cartSetShippingAddress fanout).
33
+ - `cartUpdateBuyerIdentity` mutation now persists `email` + `phone` fields (previously these were silently ignored — only `customerId` was persisted to the cart). Migration: jeśli storefront wysyła email/phone w `buyerIdentity` input, te wartości będą teraz trwale zapisane.
34
+
35
+ **New error codes** w `CartErrorCode` enum:
36
+ - `SHIPPING_ADDRESS_REQUIRED` — emit przez `cartComplete` gdy adres dostawy nie ustawiony.
37
+ - `SHIPPING_METHOD_REQUIRED` — emit przez `cartComplete` lub `cartSelectShippingMethod` gdy metoda wymagana.
38
+ - `PAYMENT_METHOD_REQUIRED` — emit przez `cartComplete` lub `cartSelectPaymentMethod`.
39
+ - `EMAIL_REQUIRED` — emit przez `cartComplete` gdy email nie ustawiony.
40
+ - `INVALID_ADDRESS` — emit przez address mutations dla nieprawidłowego adresu.
41
+ - `GIFT_CARD_NOT_FOUND` / `GIFT_CARD_DEPLETED` / `GIFT_CARD_UNUSABLE` — emit przez gift card mutations.
42
+
43
+ **Migration guide**:
44
+
45
+ Update GraphQL queries w storefront:
46
+
47
+ ```diff
48
+ - mutation CartApplyDiscountCodes($id: ID!, $discountCodes: [String!]!) {
49
+ - cartApplyDiscountCodes(id: $id, discountCodes: $discountCodes) {
50
+ + mutation CartDiscountCodesUpdate($id: ID!, $discountCodes: [String!]!) {
51
+ + cartDiscountCodesUpdate(id: $id, discountCodes: $discountCodes) {
52
+ cart { ...Cart }
53
+ userErrors { ...UserError }
54
+ warnings { ...CartWarning }
55
+ }
56
+ }
57
+ ```
58
+
59
+ SDK methods: regenerate typed-document via `pnpm codegen` po update do nowej wersji `@doswiftly/storefront-operations` — `CartApplyDiscountCodesDocument` zostanie zastąpiony `CartDiscountCodesUpdateDocument`. Jeśli używasz typed React hooks, sygnatury hook stays the same (`useCartDiscountCodesUpdateMutation`).
60
+
61
+ ### Minor Changes
62
+
63
+ - 95a24d3: Cart and customer operations realigned with the backend GraphQL contract + non-blocking `warnings` surface + richer type exports.
64
+
65
+ **`@doswiftly/storefront-operations`** — additive:
66
+ - `fragment Order` now includes `canCreatePayment: Boolean!` and `paymentMethodType: PaymentMethodType!`. After `cartComplete`, the storefront can read these directly from the resulting `Order` (instead of branching on hard-coded provider names) to decide whether to call `paymentCreate` or render a "complete on delivery" message.
67
+
68
+ **`@doswiftly/storefront-sdk`** — breaking, action required:
69
+
70
+ Cart mutation names, arguments, and result shapes are now aligned with the published GraphQL contract. Previous names worked against an older backend snapshot; the package now ships GraphQL documents the live API actually accepts.
71
+ - Cart line mutations renamed: `cartLinesAdd` → `cartAddLines`, `cartLinesUpdate` → `cartUpdateLines`, `cartLinesRemove` → `cartRemoveLines`.
72
+ - Cart attribute mutations renamed: `cartNoteUpdate` → `cartUpdateNote`, `cartBuyerIdentityUpdate` → `cartUpdateBuyerIdentity`.
73
+ - Cart mutation argument `cartId` renamed to `id` on six mutations: `cartAddLines`, `cartUpdateLines`, `cartRemoveLines`, `cartDiscountCodesUpdate`, `cartUpdateNote`, `cartUpdateBuyerIdentity`. (Phase 3 lifecycle mutations and `cartComplete` keep their typed `*Input!` argument unchanged.)
74
+ - All 16 cart mutations now return `warnings: [CartWarning!]!` (non-blocking advisory hints — e.g. low stock, partial availability). `CartClient` methods return `{ cart, warnings }` instead of `Cart`; storefronts can render `warnings` as soft notices without aborting the flow. `cartComplete` returns `{ cart, order, warnings }`.
75
+ - `useCartManager()` React hook methods (`addItem`, `updateItem`, `removeItem`, `updateDiscountCodes`, `updateNote`) now return `CartMutationOutcome` (`{ cart, warnings }`) to match the underlying `CartClient`.
76
+ - `cartComplete` now requests the full `Order` fragment (with `canCreatePayment` + `paymentMethodType`) — the prior local `OrderMinimal` fragment is removed. The exported `Order` type now mirrors the full fragment shape (`totals`, lifecycle timestamps, `shippingAddress`).
77
+ - `Customer` type fields match the GraphQL schema: `emailVerified` → `isEmailVerified`, `emailMarketingState` → `emailMarketing`, `ordersCount` → `orderCount`. Customer's `defaultAddress` now includes the computed `name` field.
78
+ - `CustomerCreateInput` exposes `phone`, `acceptsMarketing`, and `marketingOptInLevel` (`'SINGLE_OPT_IN' | 'CONFIRMED_OPT_IN'`) so signup forms can collect marketing consent without dropping to raw GraphQL.
79
+ - New types exported from the package root: `CartWarning`, `Order`, `PaymentMethodType`, `CartMutationOutcome`, `CartCompleteOutcome`, all Phase 3 cart-completion input types (`CartAddressInput`, `CartSetShippingAddressInput`, `CartSetBillingAddressInput`, `CartSelectShippingMethodInput`, `CartSelectPaymentMethodInput`, `CartApplyGiftCardInput`, `CartRemoveGiftCardInput`, `CartUpdateGiftCardRecipientInput`, `CartCompleteInput`), and discount-validation types (`DiscountValidationResult`, `DiscountInfo`, `DiscountValidationError`, `DiscountErrorCode`, `DiscountApplicationType`).
80
+ - `CartBuyerIdentityInput` exposes optional `languageCode` (ISO 639-1, e.g. `'PL'`) to match the backend input shape.
81
+
82
+ **Migration**
83
+
84
+ ```ts
85
+ // Before
86
+ const cart = await cartClient.addItems(cartId, [{ variantId, quantity: 1 }]);
87
+ // ^^^^ Cart
88
+
89
+ // After
90
+ const { cart, warnings } = await cartClient.addItems(cartId, [
91
+ { variantId, quantity: 1 },
92
+ ]);
93
+ for (const w of warnings) console.warn(`[${w.code}] ${w.message}`);
94
+ ```
95
+
96
+ If you were writing raw GraphQL operations rather than using `CartClient`, update mutation names and the `cartId` → `id` argument as above, and add a `warnings { message code target }` selection to each cart mutation.
97
+
98
+ If you read `customer.emailVerified` / `customer.emailMarketingState` / `customer.ordersCount` anywhere, rename to `isEmailVerified` / `emailMarketing` / `orderCount` respectively.
99
+
100
+ - ff246df: `PaymentMethodType` trimmed to the categories the API actually returns today.
101
+
102
+ `APPLE_PAY`, `GOOGLE_PAY`, and `PAYPAL` were placeholders for wallet providers that aren't deployed yet — they could never appear in a real response. They are removed from `PaymentMethodType` (both as a GraphQL enum value and as a SDK union member). The enum is now `'CARD' | 'BLIK' | 'BANK_TRANSFER' | 'CASH_ON_DELIVERY' | 'OTHER'`.
103
+
104
+ **Migration**
105
+
106
+ If your storefront branches on these values (`if (order.paymentMethodType === 'APPLE_PAY') { … }`), those branches were dead code — remove them. When wallet providers ship, the corresponding type values will be reintroduced alongside their implementation.
107
+
108
+ Unrecognized providers continue to fall through to `OTHER` — your default fallback path is unchanged.
109
+
110
+ - 270249e: CartClient extension — Phase 6 unify-cart-graphql-surface (additive over major changes from Phase 3 Cluster 2).
111
+
112
+ **9 new CartClient methods**:
113
+ - `cartClient.setShippingAddress(input)` — set shipping address on cart.
114
+ - `cartClient.setBillingAddress(input)` — set billing address.
115
+ - `cartClient.selectShippingMethod(input)` — Decision D8 typed `shippingMethodId: ID!`.
116
+ - `cartClient.selectPaymentMethod(input)` — select integration payment provider.
117
+ - `cartClient.applyGiftCard(input)` — stackable gift card application (FIFO consumption).
118
+ - `cartClient.removeGiftCard(input)` — remove applied gift card.
119
+ - `cartClient.updateGiftCardRecipient(input)` — set recipient info on gift card line item (personalised delivery — required przed `complete` dla gift card SKU).
120
+ - `cartClient.complete(input)` — finalize cart → Order (returns `{ cart, order }`). Idempotent on `idempotencyKey`. No `paymentUrl` (Decision D4) — caller wywoła osobną mutation if online payment needed.
121
+ - `cartClient.validateDiscountCode(cartId, code)` — Query (Decision D3 read-only preview). Returns `{ isValid, discount?, error? }`. NIE modifies cart state.
122
+
123
+ **Extended SDK types**:
124
+
125
+ `Cart` interface extends z fulfillment + payment + gift card fields:
126
+
127
+ ```diff
128
+ interface Cart {
129
+ id: string;
130
+ // ... existing fields ...
131
+ + email: string | null;
132
+ + phone: string | null;
133
+ + shippingAddress: MailingAddress | null;
134
+ + billingAddress: MailingAddress | null;
135
+ + selectedShippingMethod: CartShippingMethod | null;
136
+ + selectedPaymentMethod: CartSelectedPaymentMethod | null;
137
+ + appliedGiftCards: CartAppliedGiftCard[];
138
+ }
139
+ ```
140
+
141
+ `CartCreateInput` extends z `email?: string` + `shippingAddress?: CartAddressInput` (Phase 3 Task 3.2 — initial fulfillment context w jednym round-trip).
142
+
143
+ New types exported z `@doswiftly/storefront-sdk`:
144
+ - `MailingAddress`, `CartAddressInput`, `CartShippingMethod`, `CartAppliedGiftCard`, `CartSelectedPaymentMethod`, `PaymentMethodType`
145
+ - Input types: `CartSetShippingAddressInput`, `CartSetBillingAddressInput`, `CartSelectShippingMethodInput`, `CartSelectPaymentMethodInput`, `CartApplyGiftCardInput`, `CartRemoveGiftCardInput`, `CartUpdateGiftCardRecipientInput`, `CartCompleteInput`
146
+ - `Order` (minimal shape z `canCreatePayment` + `paymentMethodType` ResolveFields — Phase 4 capability signal)
147
+ - `DiscountValidationResult`, `DiscountInfo`, `DiscountValidationError`, `DiscountErrorCode`, `DiscountApplicationType`
148
+
149
+ **New GraphQL operations** (`@doswiftly/storefront-sdk/operations/cart`):
150
+
151
+ 8 mutations + 1 Query — `CART_SET_SHIPPING_ADDRESS`, `CART_SET_BILLING_ADDRESS`, `CART_SELECT_SHIPPING_METHOD`, `CART_SELECT_PAYMENT_METHOD`, `CART_APPLY_GIFT_CARD`, `CART_REMOVE_GIFT_CARD`, `CART_UPDATE_GIFT_CARD_RECIPIENT`, `CART_COMPLETE`, `CART_VALIDATE_DISCOUNT_CODE`. Wszystkie inline fragments — zero codegen w SDK.
152
+
153
+ **Caching guidance dla `validateDiscountCode`**:
154
+
155
+ Read-only Query — możesz cache'ować z TanStack Query lub fetch wrapper. Recommendation: `fetchPolicy: 'network-only'` lub cache key zawierający `cart.subtotal` (discount eligibility może zależeć od minimum order amount).
156
+
157
+ **Note for `complete()`**:
158
+
159
+ Method zwraca `{ cart, order: Order | null }`. `order.canCreatePayment` signals czy storefront może zainicjować online płatność (false dla COD/manual/bank_transfer/PAID/CANCELLED — pokaż instrukcję manualną; true dla PayU/Stripe online flow — wywołaj `paymentCreate`). `order.paymentMethodType` daje payment category (CARD/BLIK/BANK_TRANSFER/CASH_ON_DELIVERY/PAYPAL/APPLE_PAY/GOOGLE_PAY/OTHER) dla UI iconography.
160
+
161
+ **Linked storefront-operations bump**: minor `version-sync, no code change` per linked rule (Phase 3 Cluster 2 + Cluster 3 już dodały wszystkie operations w backend SSOT i synced storefront-operations npm).
162
+
3
163
  ## 9.1.0
4
164
 
5
165
  ### Minor Changes
package/README.md CHANGED
@@ -202,11 +202,11 @@ full executable body of each operation.
202
202
  | `CustomerProfile` | Lightweight customer profile (no orders, no addresses list). Use for settings / profile pages that only need basic customer info — much cheaper than `Customer`. Returns null if unauthenticated. |
203
203
  | `CustomerOrder` | Single order by `orderId`. Returns only orders that belong to the authenticated customer (cross-customer access returns null, not an error). Much cheaper than fetching the full `Customer` payload to access one order. Use on the order detail page. |
204
204
 
205
- #### Checkout
205
+ #### Discount Code Validation
206
206
 
207
207
  | Operation | Description |
208
208
  | --- | --- |
209
- | `Checkout` | Fetches a checkout session by `id`. **Important**: `checkoutId` and `cartId` are 1:1 there is no separate "checkout" record, the response is built dynamically from the cart. Returns line items, addresses, selected shipping rate, available shipping rates + payment methods, applied discount/gift cards (gift card codes are masked for security), and totals (`cost`, `tax`, `paymentDue`). Public read; ownership enforced on mutations. Refetch after every checkout mutation. |
209
+ | `CartValidateDiscountCode` | Read-only validation of a discount code against an existing cart does NOT modify cart state. Returns `{ isValid, discount, error }` (`DiscountValidationResult`) for previewing the effect of a code (inline UI feedback as the user types, before they commit to applying via `cartDiscountCodesUpdate`). Validates: discount existence + active status + customer eligibility + minimum order amount + minimum quantity met. Errors: `NOT_FOUND`, `INACTIVE`, `NOT_STARTED`, `EXPIRED`, `USAGE_LIMIT_REACHED`, `CUSTOMER_USAGE_LIMIT_REACHED`, `CUSTOMER_NOT_ELIGIBLE`, `MINIMUM_ORDER_NOT_MET`, `MINIMUM_QUANTITY_NOT_MET`. |
210
210
 
211
211
  #### Payment Methods
212
212
 
@@ -333,7 +333,7 @@ full executable body of each operation.
333
333
  | `CartAddLines` | Adds line items to a cart. Each line is `{ merchandiseId, quantity, attributes?, attributeSelections? }`. If the same variant + identical attributes are added twice, quantities merge into one row instead of duplicating. Validates stock (`INSUFFICIENT_STOCK`) and configurator attributes (`ATTRIBUTE_REQUIRED`, `ATTRIBUTE_OPTION_INVALID`). Triggers cart re-pricing including discount recalculation. |
334
334
  | `CartUpdateLines` | Updates quantity and/or attributes of existing cart lines by `id`. Setting `quantity: 0` auto-deletes the line. Passing `attributes: []` clears them; omitting the field preserves existing values. Re-validates stock and re-prices the cart after each update. |
335
335
  | `CartRemoveLines` | Removes specific lines from cart by `lineIds[]`. Internally delegates to `cartUpdateLines` with `quantity: 0` — both endpoints are functionally equivalent; this one exists for API ergonomics when intent is explicit removal. Triggers cart re-pricing. |
336
- | `CartApplyDiscountCodes` | Replaces (NOT appends) the cart's discount codes with the given list. Pass `[]` to clear all codes. Each code is validated against `discounts` table (existence, active status); invalid codes appear in `userErrors[]` as `DISCOUNT_CODE_INVALID`. Triggers cart re-pricing — discount allocations are recomputed and stored in `cart.discountAmount`. |
336
+ | `CartDiscountCodesUpdate` | Replaces (NOT appends) the cart's discount codes with the given list. Pass `[]` to clear all codes. Each code is validated against the discounts table (existence, active status); invalid codes appear in `userErrors[]` as `DISCOUNT_CODE_INVALID`. Triggers cart re-pricing — discount allocations are recomputed and stored in `cart.discountAmount`. Single canonical replace-all entry point — prior append/single-remove variants were removed in favor of this explicit caller-controlled list semantics. |
337
337
  | `CartUpdateBuyerIdentity` | Associates a customer with the cart. Despite the input shape accepting `email`, `phone`, `countryCode`, `languageCode`, only `customerId` is currently persisted — other fields are silently ignored. Does NOT trigger tax / shipping recalculation; pure cart-to-customer linking. Use during login or guest-to-account upgrade. |
338
338
  | `CartUpdateNote` | Sets a free-text note on the cart (gift message, special instructions). Pass empty string to clear. Stored on the `Cart` row, propagated to the `Order` at checkout completion, visible to merchant in admin. |
339
339
 
@@ -369,28 +369,18 @@ full executable body of each operation.
369
369
  | `CustomerActivate` | Activates a newly-created account using the 64-hex activation token from the welcome email + a chosen password. Token TTL is 24h, single-use (atomically marked `used_at`). On success: sets `email_verified=true`, transitions status `INACTIVE`→`ACTIVE`, returns a fresh JWT for auto-login. Rate-limited. |
370
370
  | `CustomerResetPassword` | Resets the password using the 64-hex reset token from the password-reset email. Token TTL is 1h, single-use (atomically marked `used_at`). On success: updates the password hash and returns a fresh JWT for auto-login (no second login step needed). Rate-limited. |
371
371
 
372
- #### Checkout Mutations
372
+ #### Cart Completion Mutations
373
373
 
374
374
  | Operation | Description |
375
375
  | --- | --- |
376
- | `CheckoutCreate` | Creates a new checkout session for the given cart (or a fresh cart if `cartId` is omitted). Inherits applied discounts and gift cards from the cart by reference (not snapshot). Errors: `CART_NOT_FOUND`, `EMPTY_CART`, `ALREADY_COMPLETED` (cart already converted to order). NOT idempotent multiple calls create multiple checkouts. |
377
- | `CheckoutUpdateShippingAddress` | Sets the shipping address (full replace, not patch). Triggers cart re-pricing. Address format is NOT validated here full validation runs at `checkoutComplete`. |
378
- | `CheckoutUpdateBillingAddress` | Sets the billing address (full replace). Independent of shipping address pass it explicitly even when "billing same as shipping". |
379
- | `CheckoutUpdateEmail` | Sets or updates the contact email on the checkout (used for guest checkout, order confirmation, and tracking emails). Validated against a regex; returns `INVALID` for malformed format. |
380
- | `CheckoutSelectShippingRate` | Selects a shipping method by `rateId` (a stable shipping-method UUID, NOT an opaque per-request token). The id comes from `availableShippingMethods` query, computed for the current address + cart subtotal at request time. |
381
- | `CheckoutApplyDiscountCode` | Appends a discount code to the cart's `discount_codes` array. Note: while multiple codes can be stored, the pricing engine currently uses **only the first applied code** codes do not stack. Validated for existence, active status, and customer usage limits. |
382
- | `CheckoutRemoveDiscountCode` | Removes a code from the cart's `discount_codes` array (filters by exact match). Triggers re-pricing. |
383
- | `CheckoutValidateDiscountCode` | READ-ONLY validation of a discount code against the current checkoutdoes NOT modify state. Returns `{ isValid, discount, error }` for previewing the effect (e.g. inline UI feedback as the user types). |
384
- | `CheckoutSelectPaymentMethod` | Selects a payment method by `paymentMethodId` (UUID from `availablePaymentMethods` query). Validates existence and active status; no pre-authorization is performed here. |
385
- | `CheckoutComplete` | Finalizes the checkout: creates the `Order`, deducts gift cards, sends order-created confirmation — all atomically. **Idempotent on `idempotencyKey`** (NOT on the checkout `id`); auto-generated if the caller omits it. The `paymentUrl` field is reserved but is NOT populated here — for hosted gateways (PayU, P24) the storefront calls a separate `paymentCreate` mutation after this returns. |
386
-
387
- #### Gift Card Checkout Mutations
388
-
389
- | Operation | Description |
390
- | --- | --- |
391
- | `CheckoutApplyGiftCard` | Applies a gift card to the cart, stackable with discount codes. Consumption is FIFO: each card consumes `min(remainingBalance, paymentDue)` against the current cart total in the order they were applied. The gift card balance is NOT debited yet — actual deduction happens atomically at `checkoutComplete`. Errors: `GIFT_CARD_NOT_FOUND`, `GIFT_CARD_DEPLETED`, `GIFT_CARD_UNUSABLE`, `GIFT_CARD_ALREADY_APPLIED`. |
392
- | `CheckoutRemoveGiftCard` | Removes a gift card from the applied list and recalculates FIFO `appliedAmount` for the remaining cards. Since gift card balances are only debited at `checkoutComplete`, removing before completion has no effect on the underlying gift card balance. |
393
- | `CheckoutUpdateGiftCardRecipient` | Sets per-line-item recipient details (name, email, message, delivery date) for digital gift card products in the cart (variants with `type: GIFT_CARD`). Required before `checkoutComplete` for any line item with a gift-card variant. Recipient details are associated with each gift-card line item and propagated to the resulting order. |
376
+ | `CartSetShippingAddress` | Phase 3 unify-cart-graphql-surface: wszystkie fulfillment + payment + completion operations teraz na Cart aggregate (zamiast Checkout dual-aggregate). Klient robi typowy checkout flow: cart create/add items setShipping/Billing/Method → selectPayment → (optional) applyGiftCard cartComplete Order created. Sets the shipping address on the cart (full replace, not patch). Triggers cart re-pricing (tax recalculation per address country/region). Address format validated against `CartAddressInput` constraints (firstName/lastName/streetLine1/city/country/postalCode required). Errors: `INVALID_ADDRESS`, `CART_NOT_FOUND`. |
377
+ | `CartSetBillingAddress` | Sets the billing address on the cart (full replace). Independent of shipping address pass it explicitly even when "billing same as shipping". Errors: `INVALID_ADDRESS`, `CART_NOT_FOUND`. |
378
+ | `CartSelectShippingMethod` | Selects a shipping method by `shippingMethodId` (typed `ID!`, a stable shipping-method UUID — NOT a per-request token). The id comes from a list of methods available for the current address + cart subtotal (queryable separately). Errors: `SHIPPING_METHOD_REQUIRED`, `ZIP_CODE_NOT_SUPPORTED`, `CART_NOT_FOUND`. |
379
+ | `CartSelectPaymentMethod` | Selects a payment method by `paymentMethodId` (UUID from `availablePaymentMethods` query). Validates existence + active status; no pre-authorization performed here. Errors: `PAYMENT_METHOD_REQUIRED`, `INVALID_PAYMENT`, `CART_NOT_FOUND`. |
380
+ | `CartApplyGiftCard` | Applies a gift card to the cart, stackable with discount codes. Consumption is FIFO: each card consumes `min(remainingBalance, paymentDue)` against the current cart total in the order they were applied. The gift card balance is NOT debited yet actual deduction happens atomically at `cartComplete`. Errors: `GIFT_CARD_NOT_FOUND`, `GIFT_CARD_DEPLETED`, `GIFT_CARD_UNUSABLE`. |
381
+ | `CartRemoveGiftCard` | Removes a gift card from the applied list and recalculates FIFO `appliedAmount` for the remaining cards. Since gift card balances are only debited at `cartComplete`, removing before completion has no effect on the underlying gift card balance. |
382
+ | `CartUpdateGiftCardRecipient` | Sets per-line-item recipient details (name, email, message) for digital gift card products in the cart (line items where the variant represents a gift-card SKU). Required before `cartComplete` for any line item with a gift-card variant. Recipient details propagated to the resulting order. |
383
+ | `CartComplete` | Finalizes the cart creates the `Order`, deducts gift cards, sends order-created confirmation all atomically. **Idempotent on `idempotencyKey`** (auto-generated from cartId + minute timestamp if caller omits it). Returns `order` field after completion. Note: `paymentUrl` is intentionally NOT in payload — for hosted gateways (online providers) the storefront calls a separate `paymentCreate` mutation after this returns (check `order.canCreatePayment` first). Errors: `EMAIL_REQUIRED`, `SHIPPING_ADDRESS_REQUIRED`, `SHIPPING_METHOD_REQUIRED`, `PAYMENT_METHOD_REQUIRED`, `INSUFFICIENT_STOCK`, `ALREADY_COMPLETED`. |
394
384
 
395
385
  #### Return Mutations
396
386
 
@@ -475,7 +465,7 @@ full executable body of each operation.
475
465
  | `MailingAddress` | `MailingAddress` | Customer mailing address — full street/city/state/country/postal code with names and phone. `isDefault` flips when this address is the default for shipping. Spread on the address book UI and order summaries. |
476
466
  | `CustomerAccessToken` | `CustomerAccessToken` | Customer access token returned by `customerLogin` / `customerSignup` / `customerActivate` / `customerResetPassword` / `customerRefreshToken`. The token's JWT TTL is 24h; cookie max-age is 30d. |
477
467
  | `Customer` | `Customer` | Customer profile — basic info plus B2B fields (`taxId`, `vatNumber`, `regon`, `companyName`), default address, lifetime stats (`orderCount`, `totalSpent`), marketing preferences. Use on profile / settings pages. |
478
- | `Order` | `Order` | Order summary — number, totals (cost / tax / shipping), payment + fulfillment status, shipping address, item count, lifecycle timestamps. Spread on the order list and order detail pages. Line items are not included here. |
468
+ | `Order` | `Order` | Order summary — number, totals (cost / tax / shipping), payment + fulfillment status, shipping address, item count, lifecycle timestamps, plus payment capability signal (`canCreatePayment` + `paymentMethodType`) the storefront uses to decide post-completion payment flow without hard-coded provider checks. Spread on the order list, order detail, and the `cartComplete` mutation result. Line items are not included here. |
479
469
 
480
470
  #### Cart
481
471
 
@@ -488,7 +478,10 @@ full executable body of each operation.
488
478
  | `CartBuyerIdentity` | `CartBuyerIdentity` | Buyer identity associated with the cart. Note: only `customerId` is currently persisted server-side; `email`, `phone`, `countryCode` are accepted in the input but ignored. |
489
479
  | `CartDiscountCode` | `CartDiscountCode` | Discount code applied to the cart with its `isApplicable` flag — false means the code was kept on the cart but does not currently qualify (e.g. minimum spend not reached). |
490
480
  | `CartDiscountAllocation` | `CartDiscountAllocation` | Allocation of a discount code to the cart total — pairs the code with the actual money discounted. Use to show "saved X with code Y" in cart UI. |
491
- | `Cart` | `Cart` | Full cart shape — totals, line items (paginated up to 100), buyer identity, applied discount codes + allocations, note, custom attributes. Spread on the cart drawer / cart page; refetch after every cart mutation. |
481
+ | `Cart` | `Cart` | Full cart shape — totals, line items (paginated up to 100), buyer identity, applied discount codes + allocations, note, custom attributes, plus fulfillment fields (email/phone/addresses/shipping method/payment method/applied gift cards). Spread on the cart drawer / cart page; refetch after every cart mutation including completion lifecycle. |
482
+ | `CartShippingMethod` | `CartShippingMethod` | Shipping method selected on a cart (D8 term unification — wcześniej ShippingRate). Returned przez `cart.selectedShippingMethod` po `cartSelectShippingMethod` mutation. |
483
+ | `CartAppliedGiftCard` | `CartAppliedGiftCard` | Gift card applied to a cart — masked code for display, last 4 chars for matching, applied amount + remaining balance. Balance NIE debited yet — actual deduction atomically at `cartComplete`. |
484
+ | `CartSelectedPaymentMethod` | `PaymentMethod` | Payment method (integration provider) selected on a cart — id, name, provider code, type category (CARD/BLIK/BANK_TRANSFER/etc.), icon, description, isDefault, supportedCurrencies. Storefront UI używa do iconography + selection display. |
492
485
 
493
486
  #### Shop
494
487
 
@@ -511,19 +504,6 @@ full executable body of each operation.
511
504
  | `PaymentMethod` | `PaymentMethod` | Single payment method enabled for the shop — type (CARD / BANK_TRANSFER / BLIK / PAYPAL / APPLE_PAY / GOOGLE_PAY / CASH_ON_DELIVERY / OTHER), provider, icon, supported currencies, default flag, sort position. Spread on the checkout payment step. |
512
505
  | `AvailablePaymentMethods` | `AvailablePaymentMethods` | Active payment methods list with the merchant's `defaultMethod`. Returned by the `availablePaymentMethods` query. |
513
506
 
514
- #### Checkout
515
-
516
- | Fragment | On Type | Description |
517
- | --- | --- | --- |
518
- | `ShippingRate` | `ShippingRate` | Single shipping rate option — `handle` is the stable id you pass to `checkoutSelectShippingRate` as `rateId`, plus title and price. |
519
- | `TaxLine` | `TaxLine` | One tax line on the checkout — title, rate (decimal, e.g. 0.23 for 23%), computed amount. Spread on the order summary. |
520
- | `DiscountAffectedItem` | `DiscountAffectedItem` | Item affected by a discount — the discounted product/variant with original + discounted prices and savings. Used on Buy-X-Get-Y promotions to highlight which items the discount applies to. |
521
- | `DiscountApplication` | `DiscountApplication` | A discount currently applied to the checkout — code, type, value, plus BXGY (Buy X Get Y) metadata when applicable (`buyQuantity`, `getQuantity`, `getDiscountPercent`, `affectedItems`). Use to render a "Discounts applied" panel. |
522
- | `DiscountCode` | `DiscountCode` | Lightweight discount code entry on the checkout — code + applicability flag. |
523
- | `CheckoutLineItem` | `CheckoutLineItem` | Single line item in the checkout — variant snapshot, quantity, unit + total prices, image. Use on the order summary panel. |
524
- | `AppliedGiftCard` | `AppliedGiftCard` | Gift card applied to the checkout — `maskedCode` (first + last 4 chars), `lastCharacters` (for display matching), the amount applied to this checkout, and remaining balance after this order would complete. |
525
- | `Checkout` | `Checkout` | Full checkout shape — line items, shipping + billing addresses, selected + available shipping rates, available payment methods, applied discounts + gift cards, tax lines, totals (`cost`, `paymentDue`, `totalGiftCardAmount`). Spread on the checkout flow; refetch after every checkout mutation. `isReady` flips to true when the checkout has all required fields to call `checkoutComplete`. |
526
-
527
507
  #### Shipments / Tracking
528
508
 
529
509
  | Fragment | On Type | Description |
package/fragments.graphql CHANGED
@@ -256,6 +256,7 @@ fragment MailingAddress on MailingAddress {
256
256
  countryCode
257
257
  firstName
258
258
  lastName
259
+ name
259
260
  phone
260
261
  state
261
262
  stateCode
@@ -296,7 +297,7 @@ fragment Customer on Customer {
296
297
  updatedAt
297
298
  }
298
299
 
299
- # Order summary — number, totals (cost / tax / shipping), payment + fulfillment status, shipping address, item count, lifecycle timestamps. Spread on the order list and order detail pages. Line items are not included here.
300
+ # Order summary — number, totals (cost / tax / shipping), payment + fulfillment status, shipping address, item count, lifecycle timestamps, plus payment capability signal (`canCreatePayment` + `paymentMethodType`) the storefront uses to decide post-completion payment flow without hard-coded provider checks. Spread on the order list, order detail, and the `cartComplete` mutation result. Line items are not included here.
300
301
  fragment Order on Order {
301
302
  id
302
303
  orderNumber
@@ -325,6 +326,8 @@ fragment Order on Order {
325
326
  ...MailingAddress
326
327
  }
327
328
  itemCount
329
+ canCreatePayment
330
+ paymentMethodType
328
331
  }
329
332
 
330
333
  # ============================================
@@ -427,7 +430,7 @@ fragment CartDiscountAllocation on CartDiscountAllocation {
427
430
  }
428
431
  }
429
432
 
430
- # Full cart shape — totals, line items (paginated up to 100), buyer identity, applied discount codes + allocations, note, custom attributes. Spread on the cart drawer / cart page; refetch after every cart mutation.
433
+ # Full cart shape — totals, line items (paginated up to 100), buyer identity, applied discount codes + allocations, note, custom attributes, plus fulfillment fields (email/phone/addresses/shipping method/payment method/applied gift cards). Spread on the cart drawer / cart page; refetch after every cart mutation including completion lifecycle.
431
434
  fragment Cart on Cart {
432
435
  id
433
436
  checkoutUrl
@@ -468,10 +471,61 @@ fragment Cart on Cart {
468
471
  key
469
472
  value
470
473
  }
474
+ email
475
+ phone
476
+ shippingAddress {
477
+ ...MailingAddress
478
+ }
479
+ billingAddress {
480
+ ...MailingAddress
481
+ }
482
+ selectedShippingMethod {
483
+ ...CartShippingMethod
484
+ }
485
+ selectedPaymentMethod {
486
+ ...CartSelectedPaymentMethod
487
+ }
488
+ appliedGiftCards {
489
+ ...CartAppliedGiftCard
490
+ }
471
491
  createdAt
472
492
  updatedAt
473
493
  }
474
494
 
495
+ # Shipping method selected on a cart (D8 term unification — wcześniej ShippingRate). Returned przez `cart.selectedShippingMethod` po `cartSelectShippingMethod` mutation.
496
+ fragment CartShippingMethod on CartShippingMethod {
497
+ handle
498
+ title
499
+ price {
500
+ ...Money
501
+ }
502
+ }
503
+
504
+ # Gift card applied to a cart — masked code for display, last 4 chars for matching, applied amount + remaining balance. Balance NIE debited yet — actual deduction atomically at `cartComplete`.
505
+ fragment CartAppliedGiftCard on CartAppliedGiftCard {
506
+ maskedCode
507
+ lastCharacters
508
+ appliedAmount {
509
+ ...Money
510
+ }
511
+ remainingBalance {
512
+ ...Money
513
+ }
514
+ }
515
+
516
+ # Payment method (integration provider) selected on a cart — id, name, provider code, type category (CARD/BLIK/BANK_TRANSFER/etc.), icon, description, isDefault, supportedCurrencies. Storefront UI używa do iconography + selection display.
517
+ fragment CartSelectedPaymentMethod on PaymentMethod {
518
+ id
519
+ name
520
+ provider
521
+ type
522
+ icon
523
+ description
524
+ isDefault
525
+ supportedCurrencies
526
+ position
527
+ }
528
+
475
529
  # ============================================
476
530
  # Shop
477
531
  # ============================================
@@ -619,161 +673,14 @@ fragment AvailablePaymentMethods on AvailablePaymentMethods {
619
673
  }
620
674
 
621
675
  # ============================================
622
- # Checkout
676
+ # Discount Code Validation
623
677
  # ============================================
624
-
625
- # Single shipping rate option — `handle` is the stable id you pass to `checkoutSelectShippingRate` as `rateId`, plus title and price.
626
- fragment ShippingRate on ShippingRate {
627
- handle
628
- title
629
- price {
630
- ...Money
631
- }
632
- }
633
-
634
- # One tax line on the checkout — title, rate (decimal, e.g. 0.23 for 23%), computed amount. Spread on the order summary.
635
- fragment TaxLine on TaxLine {
636
- title
637
- rate
638
- price {
639
- ...Money
640
- }
641
- }
642
-
643
- # Item affected by a discount — the discounted product/variant with original + discounted prices and savings. Used on Buy-X-Get-Y promotions to highlight which items the discount applies to.
644
- fragment DiscountAffectedItem on DiscountAffectedItem {
645
- productId
646
- variantId
647
- title
648
- quantity
649
- originalPrice {
650
- ...Money
651
- }
652
- discountedPrice {
653
- ...Money
654
- }
655
- savings {
656
- ...Money
657
- }
658
- isFreeItem
659
- }
660
-
661
- # A discount currently applied to the checkout — code, type, value, plus BXGY (Buy X Get Y) metadata when applicable (`buyQuantity`, `getQuantity`, `getDiscountPercent`, `affectedItems`). Use to render a "Discounts applied" panel.
662
- fragment DiscountApplication on DiscountApplication {
663
- code
664
- isApplicable
665
- type
666
- value {
667
- ...Money
668
- }
669
- title
670
- affectedItems {
671
- ...DiscountAffectedItem
672
- }
673
- buyQuantity
674
- getQuantity
675
- getDiscountPercent
676
- }
677
-
678
- # Lightweight discount code entry on the checkout — code + applicability flag.
679
- fragment DiscountCode on DiscountCode {
680
- code
681
- isApplicable
682
- }
683
-
684
- # Single line item in the checkout — variant snapshot, quantity, unit + total prices, image. Use on the order summary panel.
685
- fragment CheckoutLineItem on CheckoutLineItem {
686
- id
687
- title
688
- variantTitle
689
- quantity
690
- pricePerUnit {
691
- ...Money
692
- }
693
- total {
694
- ...Money
695
- }
696
- variantId
697
- productId
698
- sku
699
- image {
700
- ...ImageThumbnail
701
- }
702
- }
703
-
704
- # Gift card applied to the checkout — `maskedCode` (first + last 4 chars), `lastCharacters` (for display matching), the amount applied to this checkout, and remaining balance after this order would complete.
705
- fragment AppliedGiftCard on AppliedGiftCard {
706
- maskedCode
707
- lastCharacters
708
- appliedAmount {
709
- ...Money
710
- }
711
- remainingBalance {
712
- ...Money
713
- }
714
- }
715
-
716
- # Full checkout shape — line items, shipping + billing addresses, selected + available shipping rates, available payment methods, applied discounts + gift cards, tax lines, totals (`cost`, `paymentDue`, `totalGiftCardAmount`). Spread on the checkout flow; refetch after every checkout mutation. `isReady` flips to true when the checkout has all required fields to call `checkoutComplete`.
717
- fragment Checkout on Checkout {
718
- id
719
- isReady
720
- isCompleted
721
- completedOrderId
722
- webUrl
723
- lineItems {
724
- ...CheckoutLineItem
725
- }
726
- totalQuantity
727
- shippingAddress {
728
- ...MailingAddress
729
- }
730
- billingAddress {
731
- ...MailingAddress
732
- }
733
- shippingLine {
734
- ...ShippingRate
735
- }
736
- availableShippingRates {
737
- ...ShippingRate
738
- }
739
- shippingRatesReady
740
- email
741
- phone
742
- customerId
743
- discountCodes {
744
- ...DiscountCode
745
- }
746
- discountApplications {
747
- ...DiscountApplication
748
- }
749
- availablePaymentMethods {
750
- ...PaymentMethod
751
- }
752
- selectedPaymentMethodId
753
- cost {
754
- subtotal { ...Money }
755
- total { ...Money }
756
- totalTax { ...Money }
757
- totalShipping { ...Money }
758
- totalDiscounts { ...Money }
759
- }
760
- taxLines {
761
- ...TaxLine
762
- }
763
- appliedGiftCards {
764
- ...AppliedGiftCard
765
- }
766
- totalGiftCardAmount {
767
- ...Money
768
- }
769
- paymentDue {
770
- ...Money
771
- }
772
- currencyCode
773
- note
774
- createdAt
775
- updatedAt
776
- }
678
+ #
679
+ # Phase 3 unify-cart-graphql-surface: Checkout/CheckoutLineItem/AppliedGiftCard/
680
+ # ShippingRate/TaxLine fragments usunięte wraz z `Checkout` aggregate (Cluster 3).
681
+ # Cart now exposes wszystkie te informacje bezpośrednio (przez `Cart` fragment),
682
+ # bez sztucznej dualnosci. Sprawdź `Cart` fragment dla cart line items, addresses,
683
+ # shipping method (rename z rate per D8), gift cards, discount applications.
777
684
 
778
685
  # ============================================
779
686
  # Shipments / Tracking