@cloudcart/dev-mcp 0.2.7 → 0.2.9

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/data/admin.json CHANGED
@@ -1758,6 +1758,33 @@
1758
1758
  "isDeprecated": false,
1759
1759
  "deprecationReason": null
1760
1760
  },
1761
+ {
1762
+ "name": "bulkOperationStatus",
1763
+ "description": "Poll the status of an async / queue-backed bulk operation — track progress of a background job dispatched by any `productsBulk*` mutation. Use this to check job state, monitor processedCount/totalCount, and read final affectedCount + skippedIds when the job completes. Returns null if no operation with that `jobId` exists in the current site. Poll every ~250 ms while `status` is `PENDING` or `RUNNING`; stop once it reaches `COMPLETED` or `FAILED`.",
1764
+ "args": [
1765
+ {
1766
+ "name": "jobId",
1767
+ "description": "Job id returned by any `productsBulk*` mutation.",
1768
+ "type": {
1769
+ "kind": "NON_NULL",
1770
+ "name": null,
1771
+ "ofType": {
1772
+ "kind": "SCALAR",
1773
+ "name": "ID",
1774
+ "ofType": null
1775
+ }
1776
+ },
1777
+ "defaultValue": null
1778
+ }
1779
+ ],
1780
+ "type": {
1781
+ "kind": "OBJECT",
1782
+ "name": "BulkOperationStatus",
1783
+ "ofType": null
1784
+ },
1785
+ "isDeprecated": false,
1786
+ "deprecationReason": null
1787
+ },
1761
1788
  {
1762
1789
  "name": "stockStatuses",
1763
1790
  "description": "Get all stock statuses.",
@@ -17063,7 +17090,7 @@
17063
17090
  "name": null,
17064
17091
  "ofType": {
17065
17092
  "kind": "OBJECT",
17066
- "name": "BulkDeleteProductsResult",
17093
+ "name": "BulkOperationJob",
17067
17094
  "ofType": null
17068
17095
  }
17069
17096
  },
@@ -17116,7 +17143,7 @@
17116
17143
  "name": null,
17117
17144
  "ofType": {
17118
17145
  "kind": "OBJECT",
17119
- "name": "BulkProductsResult",
17146
+ "name": "BulkOperationJob",
17120
17147
  "ofType": null
17121
17148
  }
17122
17149
  },
@@ -17169,7 +17196,7 @@
17169
17196
  "name": null,
17170
17197
  "ofType": {
17171
17198
  "kind": "OBJECT",
17172
- "name": "BulkProductsResult",
17199
+ "name": "BulkOperationJob",
17173
17200
  "ofType": null
17174
17201
  }
17175
17202
  },
@@ -17222,7 +17249,7 @@
17222
17249
  "name": null,
17223
17250
  "ofType": {
17224
17251
  "kind": "OBJECT",
17225
- "name": "BulkProductsResult",
17252
+ "name": "BulkOperationJob",
17226
17253
  "ofType": null
17227
17254
  }
17228
17255
  },
@@ -17275,7 +17302,7 @@
17275
17302
  "name": null,
17276
17303
  "ofType": {
17277
17304
  "kind": "OBJECT",
17278
- "name": "BulkProductsResult",
17305
+ "name": "BulkOperationJob",
17279
17306
  "ofType": null
17280
17307
  }
17281
17308
  },
@@ -17314,7 +17341,7 @@
17314
17341
  "name": null,
17315
17342
  "ofType": {
17316
17343
  "kind": "OBJECT",
17317
- "name": "BulkDuplicateProductsResult",
17344
+ "name": "BulkOperationJob",
17318
17345
  "ofType": null
17319
17346
  }
17320
17347
  },
@@ -17363,7 +17390,7 @@
17363
17390
  "name": null,
17364
17391
  "ofType": {
17365
17392
  "kind": "OBJECT",
17366
- "name": "BulkProductsResult",
17393
+ "name": "BulkOperationJob",
17367
17394
  "ofType": null
17368
17395
  }
17369
17396
  },
@@ -17402,7 +17429,7 @@
17402
17429
  "name": null,
17403
17430
  "ofType": {
17404
17431
  "kind": "OBJECT",
17405
- "name": "BulkProductsResult",
17432
+ "name": "BulkOperationJob",
17406
17433
  "ofType": null
17407
17434
  }
17408
17435
  },
@@ -17455,7 +17482,7 @@
17455
17482
  "name": null,
17456
17483
  "ofType": {
17457
17484
  "kind": "OBJECT",
17458
- "name": "BulkProductsResult",
17485
+ "name": "BulkOperationJob",
17459
17486
  "ofType": null
17460
17487
  }
17461
17488
  },
@@ -17504,7 +17531,7 @@
17504
17531
  "name": null,
17505
17532
  "ofType": {
17506
17533
  "kind": "OBJECT",
17507
- "name": "BulkProductsResult",
17534
+ "name": "BulkOperationJob",
17508
17535
  "ofType": null
17509
17536
  }
17510
17537
  },
@@ -17565,7 +17592,7 @@
17565
17592
  "name": null,
17566
17593
  "ofType": {
17567
17594
  "kind": "OBJECT",
17568
- "name": "BulkProductsResult",
17595
+ "name": "BulkOperationJob",
17569
17596
  "ofType": null
17570
17597
  }
17571
17598
  },
@@ -17618,7 +17645,7 @@
17618
17645
  "name": null,
17619
17646
  "ofType": {
17620
17647
  "kind": "OBJECT",
17621
- "name": "BulkProductsResult",
17648
+ "name": "BulkOperationJob",
17622
17649
  "ofType": null
17623
17650
  }
17624
17651
  },
@@ -17671,7 +17698,7 @@
17671
17698
  "name": null,
17672
17699
  "ofType": {
17673
17700
  "kind": "OBJECT",
17674
- "name": "BulkProductsResult",
17701
+ "name": "BulkOperationJob",
17675
17702
  "ofType": null
17676
17703
  }
17677
17704
  },
@@ -17724,7 +17751,7 @@
17724
17751
  "name": null,
17725
17752
  "ofType": {
17726
17753
  "kind": "OBJECT",
17727
- "name": "BulkProductsResult",
17754
+ "name": "BulkOperationJob",
17728
17755
  "ofType": null
17729
17756
  }
17730
17757
  },
@@ -17785,7 +17812,7 @@
17785
17812
  "name": null,
17786
17813
  "ofType": {
17787
17814
  "kind": "OBJECT",
17788
- "name": "BulkProductsResult",
17815
+ "name": "BulkOperationJob",
17789
17816
  "ofType": null
17790
17817
  }
17791
17818
  },
@@ -17846,7 +17873,7 @@
17846
17873
  "name": null,
17847
17874
  "ofType": {
17848
17875
  "kind": "OBJECT",
17849
- "name": "BulkProductsResult",
17876
+ "name": "BulkOperationJob",
17850
17877
  "ofType": null
17851
17878
  }
17852
17879
  },
@@ -17907,7 +17934,7 @@
17907
17934
  "name": null,
17908
17935
  "ofType": {
17909
17936
  "kind": "OBJECT",
17910
- "name": "BulkProductsResult",
17937
+ "name": "BulkOperationJob",
17911
17938
  "ofType": null
17912
17939
  }
17913
17940
  },
@@ -17968,7 +17995,7 @@
17968
17995
  "name": null,
17969
17996
  "ofType": {
17970
17997
  "kind": "OBJECT",
17971
- "name": "BulkProductsResult",
17998
+ "name": "BulkOperationJob",
17972
17999
  "ofType": null
17973
18000
  }
17974
18001
  },
@@ -17976,32 +18003,32 @@
17976
18003
  "deprecationReason": null
17977
18004
  },
17978
18005
  {
17979
- "name": "createVariant",
17980
- "description": "Create a new variant for a product.",
18006
+ "name": "productsBulkAdjustPrice",
18007
+ "description": "Bulk increase, decrease, raise, lower, change or set product prices across many products at once. Apply a `PriceChange` to every variant.price on every product matching the selector. Examples: `change: { op: PERCENT_DELTA, value: 10 }` = +10% (raise / increase), `change: { op: PERCENT_DELTA, value: -25 }` = -25% (decrease / lower / discount price), `change: { op: ABSOLUTE_DELTA, value: 5 }` = +5 (currency units), `change: { op: SET_TO, value: 99 }` = set every variant to 99. Worker bypasses client paginated fetch when the selector is by categoryId / vendorId / tagName. Refreshes `priceFrom`/`priceTo` + fires ES re-index once at end of batch. Common phrasings: increase prices, decrease prices, raise prices, lower prices, change prices, adjust prices, set prices, mass update product prices.",
17981
18008
  "args": [
17982
18009
  {
17983
- "name": "productId",
17984
- "description": "Product ID.",
18010
+ "name": "selector",
18011
+ "description": "Which products to touch (exactly one selector field).",
17985
18012
  "type": {
17986
18013
  "kind": "NON_NULL",
17987
18014
  "name": null,
17988
18015
  "ofType": {
17989
- "kind": "SCALAR",
17990
- "name": "ID",
18016
+ "kind": "INPUT_OBJECT",
18017
+ "name": "ProductSelector",
17991
18018
  "ofType": null
17992
18019
  }
17993
18020
  },
17994
18021
  "defaultValue": null
17995
18022
  },
17996
18023
  {
17997
- "name": "input",
17998
- "description": "Variant input data.",
18024
+ "name": "change",
18025
+ "description": "How to change the price.",
17999
18026
  "type": {
18000
18027
  "kind": "NON_NULL",
18001
18028
  "name": null,
18002
18029
  "ofType": {
18003
18030
  "kind": "INPUT_OBJECT",
18004
- "name": "CreateVariantInput",
18031
+ "name": "PriceChange",
18005
18032
  "ofType": null
18006
18033
  }
18007
18034
  },
@@ -18013,7 +18040,7 @@
18013
18040
  "name": null,
18014
18041
  "ofType": {
18015
18042
  "kind": "OBJECT",
18016
- "name": "Variant",
18043
+ "name": "BulkOperationJob",
18017
18044
  "ofType": null
18018
18045
  }
18019
18046
  },
@@ -18021,59 +18048,32 @@
18021
18048
  "deprecationReason": null
18022
18049
  },
18023
18050
  {
18024
- "name": "updateVariant",
18025
- "description": "Update an existing variant.",
18051
+ "name": "productsBulkApplyDiscount",
18052
+ "description": "Put many products on sale — bulk apply a fixed sale price / discount to every variant of every product matching the selector. The supplied `discountPrice` is in main currency units (e.g. `79.99`) and is set as the new `Variant.discountPrice` for any variant whose regular price is strictly greater than `discountPrice`. Variants where `regular price <= discountPrice` are skipped per-variant (would be a no-op or invalid). Routes through the canonical `Discount::addFixedDiscount()` engine + `product_to_discount` pivot — same path the admin product-edit form uses. Idempotent: rerunning with the same `discountPrice` leaves a single pivot row, not duplicates. Common phrasings: apply discount, set sale price, put products on sale, discount many products, mass discount, sale across products, give a discount, set discount on N products.",
18026
18053
  "args": [
18027
18054
  {
18028
- "name": "id",
18029
- "description": "Variant ID.",
18030
- "type": {
18031
- "kind": "NON_NULL",
18032
- "name": null,
18033
- "ofType": {
18034
- "kind": "SCALAR",
18035
- "name": "ID",
18036
- "ofType": null
18037
- }
18038
- },
18039
- "defaultValue": null
18040
- },
18041
- {
18042
- "name": "input",
18043
- "description": "Variant input data.",
18055
+ "name": "selector",
18056
+ "description": "Which products to touch.",
18044
18057
  "type": {
18045
18058
  "kind": "NON_NULL",
18046
18059
  "name": null,
18047
18060
  "ofType": {
18048
18061
  "kind": "INPUT_OBJECT",
18049
- "name": "UpdateVariantInput",
18062
+ "name": "ProductSelector",
18050
18063
  "ofType": null
18051
18064
  }
18052
18065
  },
18053
18066
  "defaultValue": null
18054
- }
18055
- ],
18056
- "type": {
18057
- "kind": "OBJECT",
18058
- "name": "Variant",
18059
- "ofType": null
18060
- },
18061
- "isDeprecated": false,
18062
- "deprecationReason": null
18063
- },
18064
- {
18065
- "name": "deleteVariant",
18066
- "description": "Delete a variant.",
18067
- "args": [
18067
+ },
18068
18068
  {
18069
- "name": "id",
18070
- "description": "Variant ID.",
18069
+ "name": "discountPrice",
18070
+ "description": "New discount price in main currency units. Must be > 0. Each variant whose regular price is `>= discountPrice` gets the discount; others are skipped per-variant.",
18071
18071
  "type": {
18072
18072
  "kind": "NON_NULL",
18073
18073
  "name": null,
18074
18074
  "ofType": {
18075
18075
  "kind": "SCALAR",
18076
- "name": "ID",
18076
+ "name": "Float",
18077
18077
  "ofType": null
18078
18078
  }
18079
18079
  },
@@ -18084,8 +18084,8 @@
18084
18084
  "kind": "NON_NULL",
18085
18085
  "name": null,
18086
18086
  "ofType": {
18087
- "kind": "SCALAR",
18088
- "name": "Boolean",
18087
+ "kind": "OBJECT",
18088
+ "name": "BulkOperationJob",
18089
18089
  "ofType": null
18090
18090
  }
18091
18091
  },
@@ -18093,18 +18093,18 @@
18093
18093
  "deprecationReason": null
18094
18094
  },
18095
18095
  {
18096
- "name": "createCategory",
18097
- "description": "Create a new category.",
18096
+ "name": "productsBulkRemoveDiscount",
18097
+ "description": "Clear every variant-level fixed discount for products matching the selector. Symmetric to `productsBulkApplyDiscount` — both operate against `Discount::getDefaultFixedDiscount()`. Products without an active fixed discount are reported as skipped (no-op).",
18098
18098
  "args": [
18099
18099
  {
18100
- "name": "input",
18101
- "description": "Category input data.",
18100
+ "name": "selector",
18101
+ "description": "Which products to touch.",
18102
18102
  "type": {
18103
18103
  "kind": "NON_NULL",
18104
18104
  "name": null,
18105
18105
  "ofType": {
18106
18106
  "kind": "INPUT_OBJECT",
18107
- "name": "CreateCategoryInput",
18107
+ "name": "ProductSelector",
18108
18108
  "ofType": null
18109
18109
  }
18110
18110
  },
@@ -18116,7 +18116,7 @@
18116
18116
  "name": null,
18117
18117
  "ofType": {
18118
18118
  "kind": "OBJECT",
18119
- "name": "Category",
18119
+ "name": "BulkOperationJob",
18120
18120
  "ofType": null
18121
18121
  }
18122
18122
  },
@@ -18124,110 +18124,44 @@
18124
18124
  "deprecationReason": null
18125
18125
  },
18126
18126
  {
18127
- "name": "updateCategory",
18128
- "description": "Update an existing category.",
18127
+ "name": "productsBulkRoundPrices",
18128
+ "description": "Bulk round product prices to psychological-pricing endpoints (.99, .49, integer, nearest 5/10) — the natural follow-up after a percent-based price increase that produced odd numbers like 170.51. Round every variant.price on every product matching the selector. Common phrasings: round prices to .99, psychological pricing, round to nearest 5, charm pricing, fix pricing endings.",
18129
18129
  "args": [
18130
18130
  {
18131
- "name": "id",
18132
- "description": "Category ID.",
18133
- "type": {
18134
- "kind": "NON_NULL",
18135
- "name": null,
18136
- "ofType": {
18137
- "kind": "SCALAR",
18138
- "name": "ID",
18139
- "ofType": null
18140
- }
18141
- },
18142
- "defaultValue": null
18143
- },
18144
- {
18145
- "name": "input",
18146
- "description": "Category input data.",
18131
+ "name": "selector",
18132
+ "description": "Which products to touch.",
18147
18133
  "type": {
18148
18134
  "kind": "NON_NULL",
18149
18135
  "name": null,
18150
18136
  "ofType": {
18151
18137
  "kind": "INPUT_OBJECT",
18152
- "name": "UpdateCategoryInput",
18138
+ "name": "ProductSelector",
18153
18139
  "ofType": null
18154
18140
  }
18155
18141
  },
18156
18142
  "defaultValue": null
18157
- }
18158
- ],
18159
- "type": {
18160
- "kind": "OBJECT",
18161
- "name": "Category",
18162
- "ofType": null
18163
- },
18164
- "isDeprecated": false,
18165
- "deprecationReason": null
18166
- },
18167
- {
18168
- "name": "deleteCategory",
18169
- "description": "Delete a category.",
18170
- "args": [
18143
+ },
18171
18144
  {
18172
- "name": "id",
18173
- "description": "Category ID.",
18145
+ "name": "strategy",
18146
+ "description": "Rounding strategy.",
18174
18147
  "type": {
18175
18148
  "kind": "NON_NULL",
18176
18149
  "name": null,
18177
18150
  "ofType": {
18178
- "kind": "SCALAR",
18179
- "name": "ID",
18151
+ "kind": "ENUM",
18152
+ "name": "PriceRoundingStrategy",
18180
18153
  "ofType": null
18181
18154
  }
18182
18155
  },
18183
18156
  "defaultValue": null
18184
18157
  }
18185
18158
  ],
18186
- "type": {
18187
- "kind": "NON_NULL",
18188
- "name": null,
18189
- "ofType": {
18190
- "kind": "SCALAR",
18191
- "name": "Boolean",
18192
- "ofType": null
18193
- }
18194
- },
18195
- "isDeprecated": false,
18196
- "deprecationReason": null
18197
- },
18198
- {
18199
- "name": "categoriesBulkDelete",
18200
- "description": "Bulk-delete product categories. Mirrors the admin categories listing's Delete bulk action (`DELETE /admin/api/core/product-categories`). Refuses with `dependency_blocked` when any of the supplied categories still has products attached — move or reassign the products via `productsBulkSetCategory` first.",
18201
- "args": [
18202
- {
18203
- "name": "ids",
18204
- "description": "Category IDs.",
18205
- "type": {
18206
- "kind": "NON_NULL",
18207
- "name": null,
18208
- "ofType": {
18209
- "kind": "LIST",
18210
- "name": null,
18211
- "ofType": {
18212
- "kind": "NON_NULL",
18213
- "name": null,
18214
- "ofType": {
18215
- "kind": "SCALAR",
18216
- "name": "ID",
18217
- "ofType": null
18218
- }
18219
- }
18220
- }
18221
- },
18222
- "defaultValue": null
18223
- }
18224
- ],
18225
18159
  "type": {
18226
18160
  "kind": "NON_NULL",
18227
18161
  "name": null,
18228
18162
  "ofType": {
18229
18163
  "kind": "OBJECT",
18230
- "name": "BulkOperationResult",
18164
+ "name": "BulkOperationJob",
18231
18165
  "ofType": null
18232
18166
  }
18233
18167
  },
@@ -18235,12 +18169,12 @@
18235
18169
  "deprecationReason": null
18236
18170
  },
18237
18171
  {
18238
- "name": "categorySetGoogleTaxonomy",
18239
- "description": "Set the Google taxonomy mapping on a single category. Mirrors the admin `Define taxonomy` modal (`POST /admin/api/core/product-categories/{id}/update-taxonomy`). Use `googleProductCategories(query:)` to look up valid `taxonomyId` values.",
18172
+ "name": "createVariant",
18173
+ "description": "Create a new variant for a product.",
18240
18174
  "args": [
18241
18175
  {
18242
- "name": "categoryId",
18243
- "description": "Category ID.",
18176
+ "name": "productId",
18177
+ "description": "Product ID.",
18244
18178
  "type": {
18245
18179
  "kind": "NON_NULL",
18246
18180
  "name": null,
@@ -18252,91 +18186,15 @@
18252
18186
  },
18253
18187
  "defaultValue": null
18254
18188
  },
18255
- {
18256
- "name": "taxonomyId",
18257
- "description": "Google taxonomy id (from `googleProductCategories(...)`). Pass `null` to clear the mapping.",
18258
- "type": {
18259
- "kind": "SCALAR",
18260
- "name": "ID",
18261
- "ofType": null
18262
- },
18263
- "defaultValue": null
18264
- }
18265
- ],
18266
- "type": {
18267
- "kind": "NON_NULL",
18268
- "name": null,
18269
- "ofType": {
18270
- "kind": "OBJECT",
18271
- "name": "Category",
18272
- "ofType": null
18273
- }
18274
- },
18275
- "isDeprecated": false,
18276
- "deprecationReason": null
18277
- },
18278
- {
18279
- "name": "categoriesBulkSetGoogleTaxonomy",
18280
- "description": "Bulk-apply the same Google taxonomy id to N categories. Pass `taxonomyId: null` to clear the mapping on the supplied categories. Invalid taxonomy ids are rejected with `not_found` BEFORE any update is written.",
18281
- "args": [
18282
- {
18283
- "name": "ids",
18284
- "description": "Category IDs.",
18285
- "type": {
18286
- "kind": "NON_NULL",
18287
- "name": null,
18288
- "ofType": {
18289
- "kind": "LIST",
18290
- "name": null,
18291
- "ofType": {
18292
- "kind": "NON_NULL",
18293
- "name": null,
18294
- "ofType": {
18295
- "kind": "SCALAR",
18296
- "name": "ID",
18297
- "ofType": null
18298
- }
18299
- }
18300
- }
18301
- },
18302
- "defaultValue": null
18303
- },
18304
- {
18305
- "name": "taxonomyId",
18306
- "description": "Google taxonomy id (from `googleProductCategories(...)`). Pass `null` to clear.",
18307
- "type": {
18308
- "kind": "SCALAR",
18309
- "name": "ID",
18310
- "ofType": null
18311
- },
18312
- "defaultValue": null
18313
- }
18314
- ],
18315
- "type": {
18316
- "kind": "NON_NULL",
18317
- "name": null,
18318
- "ofType": {
18319
- "kind": "OBJECT",
18320
- "name": "BulkOperationResult",
18321
- "ofType": null
18322
- }
18323
- },
18324
- "isDeprecated": false,
18325
- "deprecationReason": null
18326
- },
18327
- {
18328
- "name": "createVendor",
18329
- "description": "Create a new vendor.",
18330
- "args": [
18331
18189
  {
18332
18190
  "name": "input",
18333
- "description": "Vendor input data.",
18191
+ "description": "Variant input data.",
18334
18192
  "type": {
18335
18193
  "kind": "NON_NULL",
18336
18194
  "name": null,
18337
18195
  "ofType": {
18338
18196
  "kind": "INPUT_OBJECT",
18339
- "name": "CreateVendorInput",
18197
+ "name": "CreateVariantInput",
18340
18198
  "ofType": null
18341
18199
  }
18342
18200
  },
@@ -18348,7 +18206,7 @@
18348
18206
  "name": null,
18349
18207
  "ofType": {
18350
18208
  "kind": "OBJECT",
18351
- "name": "Vendor",
18209
+ "name": "Variant",
18352
18210
  "ofType": null
18353
18211
  }
18354
18212
  },
@@ -18356,12 +18214,12 @@
18356
18214
  "deprecationReason": null
18357
18215
  },
18358
18216
  {
18359
- "name": "updateVendor",
18360
- "description": "Update an existing vendor.",
18217
+ "name": "updateVariant",
18218
+ "description": "Update an existing variant.",
18361
18219
  "args": [
18362
18220
  {
18363
18221
  "name": "id",
18364
- "description": "Vendor ID.",
18222
+ "description": "Variant ID.",
18365
18223
  "type": {
18366
18224
  "kind": "NON_NULL",
18367
18225
  "name": null,
@@ -18375,13 +18233,13 @@
18375
18233
  },
18376
18234
  {
18377
18235
  "name": "input",
18378
- "description": "Vendor input data.",
18236
+ "description": "Variant input data.",
18379
18237
  "type": {
18380
18238
  "kind": "NON_NULL",
18381
18239
  "name": null,
18382
18240
  "ofType": {
18383
18241
  "kind": "INPUT_OBJECT",
18384
- "name": "UpdateVendorInput",
18242
+ "name": "UpdateVariantInput",
18385
18243
  "ofType": null
18386
18244
  }
18387
18245
  },
@@ -18390,19 +18248,354 @@
18390
18248
  ],
18391
18249
  "type": {
18392
18250
  "kind": "OBJECT",
18393
- "name": "Vendor",
18251
+ "name": "Variant",
18394
18252
  "ofType": null
18395
18253
  },
18396
18254
  "isDeprecated": false,
18397
18255
  "deprecationReason": null
18398
18256
  },
18399
18257
  {
18400
- "name": "deleteVendor",
18401
- "description": "Delete a vendor.",
18258
+ "name": "deleteVariant",
18259
+ "description": "Delete a variant.",
18402
18260
  "args": [
18403
18261
  {
18404
18262
  "name": "id",
18405
- "description": "Vendor ID.",
18263
+ "description": "Variant ID.",
18264
+ "type": {
18265
+ "kind": "NON_NULL",
18266
+ "name": null,
18267
+ "ofType": {
18268
+ "kind": "SCALAR",
18269
+ "name": "ID",
18270
+ "ofType": null
18271
+ }
18272
+ },
18273
+ "defaultValue": null
18274
+ }
18275
+ ],
18276
+ "type": {
18277
+ "kind": "NON_NULL",
18278
+ "name": null,
18279
+ "ofType": {
18280
+ "kind": "SCALAR",
18281
+ "name": "Boolean",
18282
+ "ofType": null
18283
+ }
18284
+ },
18285
+ "isDeprecated": false,
18286
+ "deprecationReason": null
18287
+ },
18288
+ {
18289
+ "name": "createCategory",
18290
+ "description": "Create a new category.",
18291
+ "args": [
18292
+ {
18293
+ "name": "input",
18294
+ "description": "Category input data.",
18295
+ "type": {
18296
+ "kind": "NON_NULL",
18297
+ "name": null,
18298
+ "ofType": {
18299
+ "kind": "INPUT_OBJECT",
18300
+ "name": "CreateCategoryInput",
18301
+ "ofType": null
18302
+ }
18303
+ },
18304
+ "defaultValue": null
18305
+ }
18306
+ ],
18307
+ "type": {
18308
+ "kind": "NON_NULL",
18309
+ "name": null,
18310
+ "ofType": {
18311
+ "kind": "OBJECT",
18312
+ "name": "Category",
18313
+ "ofType": null
18314
+ }
18315
+ },
18316
+ "isDeprecated": false,
18317
+ "deprecationReason": null
18318
+ },
18319
+ {
18320
+ "name": "updateCategory",
18321
+ "description": "Update an existing category.",
18322
+ "args": [
18323
+ {
18324
+ "name": "id",
18325
+ "description": "Category ID.",
18326
+ "type": {
18327
+ "kind": "NON_NULL",
18328
+ "name": null,
18329
+ "ofType": {
18330
+ "kind": "SCALAR",
18331
+ "name": "ID",
18332
+ "ofType": null
18333
+ }
18334
+ },
18335
+ "defaultValue": null
18336
+ },
18337
+ {
18338
+ "name": "input",
18339
+ "description": "Category input data.",
18340
+ "type": {
18341
+ "kind": "NON_NULL",
18342
+ "name": null,
18343
+ "ofType": {
18344
+ "kind": "INPUT_OBJECT",
18345
+ "name": "UpdateCategoryInput",
18346
+ "ofType": null
18347
+ }
18348
+ },
18349
+ "defaultValue": null
18350
+ }
18351
+ ],
18352
+ "type": {
18353
+ "kind": "OBJECT",
18354
+ "name": "Category",
18355
+ "ofType": null
18356
+ },
18357
+ "isDeprecated": false,
18358
+ "deprecationReason": null
18359
+ },
18360
+ {
18361
+ "name": "deleteCategory",
18362
+ "description": "Delete a category.",
18363
+ "args": [
18364
+ {
18365
+ "name": "id",
18366
+ "description": "Category ID.",
18367
+ "type": {
18368
+ "kind": "NON_NULL",
18369
+ "name": null,
18370
+ "ofType": {
18371
+ "kind": "SCALAR",
18372
+ "name": "ID",
18373
+ "ofType": null
18374
+ }
18375
+ },
18376
+ "defaultValue": null
18377
+ }
18378
+ ],
18379
+ "type": {
18380
+ "kind": "NON_NULL",
18381
+ "name": null,
18382
+ "ofType": {
18383
+ "kind": "SCALAR",
18384
+ "name": "Boolean",
18385
+ "ofType": null
18386
+ }
18387
+ },
18388
+ "isDeprecated": false,
18389
+ "deprecationReason": null
18390
+ },
18391
+ {
18392
+ "name": "categoriesBulkDelete",
18393
+ "description": "Bulk-delete product categories. Mirrors the admin categories listing's Delete bulk action (`DELETE /admin/api/core/product-categories`). Refuses with `dependency_blocked` when any of the supplied categories still has products attached — move or reassign the products via `productsBulkSetCategory` first.",
18394
+ "args": [
18395
+ {
18396
+ "name": "ids",
18397
+ "description": "Category IDs.",
18398
+ "type": {
18399
+ "kind": "NON_NULL",
18400
+ "name": null,
18401
+ "ofType": {
18402
+ "kind": "LIST",
18403
+ "name": null,
18404
+ "ofType": {
18405
+ "kind": "NON_NULL",
18406
+ "name": null,
18407
+ "ofType": {
18408
+ "kind": "SCALAR",
18409
+ "name": "ID",
18410
+ "ofType": null
18411
+ }
18412
+ }
18413
+ }
18414
+ },
18415
+ "defaultValue": null
18416
+ }
18417
+ ],
18418
+ "type": {
18419
+ "kind": "NON_NULL",
18420
+ "name": null,
18421
+ "ofType": {
18422
+ "kind": "OBJECT",
18423
+ "name": "BulkOperationResult",
18424
+ "ofType": null
18425
+ }
18426
+ },
18427
+ "isDeprecated": false,
18428
+ "deprecationReason": null
18429
+ },
18430
+ {
18431
+ "name": "categorySetGoogleTaxonomy",
18432
+ "description": "Set the Google taxonomy mapping on a single category. Mirrors the admin `Define taxonomy` modal (`POST /admin/api/core/product-categories/{id}/update-taxonomy`). Use `googleProductCategories(query:)` to look up valid `taxonomyId` values.",
18433
+ "args": [
18434
+ {
18435
+ "name": "categoryId",
18436
+ "description": "Category ID.",
18437
+ "type": {
18438
+ "kind": "NON_NULL",
18439
+ "name": null,
18440
+ "ofType": {
18441
+ "kind": "SCALAR",
18442
+ "name": "ID",
18443
+ "ofType": null
18444
+ }
18445
+ },
18446
+ "defaultValue": null
18447
+ },
18448
+ {
18449
+ "name": "taxonomyId",
18450
+ "description": "Google taxonomy id (from `googleProductCategories(...)`). Pass `null` to clear the mapping.",
18451
+ "type": {
18452
+ "kind": "SCALAR",
18453
+ "name": "ID",
18454
+ "ofType": null
18455
+ },
18456
+ "defaultValue": null
18457
+ }
18458
+ ],
18459
+ "type": {
18460
+ "kind": "NON_NULL",
18461
+ "name": null,
18462
+ "ofType": {
18463
+ "kind": "OBJECT",
18464
+ "name": "Category",
18465
+ "ofType": null
18466
+ }
18467
+ },
18468
+ "isDeprecated": false,
18469
+ "deprecationReason": null
18470
+ },
18471
+ {
18472
+ "name": "categoriesBulkSetGoogleTaxonomy",
18473
+ "description": "Bulk-apply the same Google taxonomy id to N categories. Pass `taxonomyId: null` to clear the mapping on the supplied categories. Invalid taxonomy ids are rejected with `not_found` BEFORE any update is written.",
18474
+ "args": [
18475
+ {
18476
+ "name": "ids",
18477
+ "description": "Category IDs.",
18478
+ "type": {
18479
+ "kind": "NON_NULL",
18480
+ "name": null,
18481
+ "ofType": {
18482
+ "kind": "LIST",
18483
+ "name": null,
18484
+ "ofType": {
18485
+ "kind": "NON_NULL",
18486
+ "name": null,
18487
+ "ofType": {
18488
+ "kind": "SCALAR",
18489
+ "name": "ID",
18490
+ "ofType": null
18491
+ }
18492
+ }
18493
+ }
18494
+ },
18495
+ "defaultValue": null
18496
+ },
18497
+ {
18498
+ "name": "taxonomyId",
18499
+ "description": "Google taxonomy id (from `googleProductCategories(...)`). Pass `null` to clear.",
18500
+ "type": {
18501
+ "kind": "SCALAR",
18502
+ "name": "ID",
18503
+ "ofType": null
18504
+ },
18505
+ "defaultValue": null
18506
+ }
18507
+ ],
18508
+ "type": {
18509
+ "kind": "NON_NULL",
18510
+ "name": null,
18511
+ "ofType": {
18512
+ "kind": "OBJECT",
18513
+ "name": "BulkOperationResult",
18514
+ "ofType": null
18515
+ }
18516
+ },
18517
+ "isDeprecated": false,
18518
+ "deprecationReason": null
18519
+ },
18520
+ {
18521
+ "name": "createVendor",
18522
+ "description": "Create a new vendor.",
18523
+ "args": [
18524
+ {
18525
+ "name": "input",
18526
+ "description": "Vendor input data.",
18527
+ "type": {
18528
+ "kind": "NON_NULL",
18529
+ "name": null,
18530
+ "ofType": {
18531
+ "kind": "INPUT_OBJECT",
18532
+ "name": "CreateVendorInput",
18533
+ "ofType": null
18534
+ }
18535
+ },
18536
+ "defaultValue": null
18537
+ }
18538
+ ],
18539
+ "type": {
18540
+ "kind": "NON_NULL",
18541
+ "name": null,
18542
+ "ofType": {
18543
+ "kind": "OBJECT",
18544
+ "name": "Vendor",
18545
+ "ofType": null
18546
+ }
18547
+ },
18548
+ "isDeprecated": false,
18549
+ "deprecationReason": null
18550
+ },
18551
+ {
18552
+ "name": "updateVendor",
18553
+ "description": "Update an existing vendor.",
18554
+ "args": [
18555
+ {
18556
+ "name": "id",
18557
+ "description": "Vendor ID.",
18558
+ "type": {
18559
+ "kind": "NON_NULL",
18560
+ "name": null,
18561
+ "ofType": {
18562
+ "kind": "SCALAR",
18563
+ "name": "ID",
18564
+ "ofType": null
18565
+ }
18566
+ },
18567
+ "defaultValue": null
18568
+ },
18569
+ {
18570
+ "name": "input",
18571
+ "description": "Vendor input data.",
18572
+ "type": {
18573
+ "kind": "NON_NULL",
18574
+ "name": null,
18575
+ "ofType": {
18576
+ "kind": "INPUT_OBJECT",
18577
+ "name": "UpdateVendorInput",
18578
+ "ofType": null
18579
+ }
18580
+ },
18581
+ "defaultValue": null
18582
+ }
18583
+ ],
18584
+ "type": {
18585
+ "kind": "OBJECT",
18586
+ "name": "Vendor",
18587
+ "ofType": null
18588
+ },
18589
+ "isDeprecated": false,
18590
+ "deprecationReason": null
18591
+ },
18592
+ {
18593
+ "name": "deleteVendor",
18594
+ "description": "Delete a vendor.",
18595
+ "args": [
18596
+ {
18597
+ "name": "id",
18598
+ "description": "Vendor ID.",
18406
18599
  "type": {
18407
18600
  "kind": "NON_NULL",
18408
18601
  "name": null,
@@ -21389,7 +21582,7 @@
21389
21582
  "name": null,
21390
21583
  "ofType": {
21391
21584
  "kind": "OBJECT",
21392
- "name": "BulkProductsResult",
21585
+ "name": "BulkOperationJob",
21393
21586
  "ofType": null
21394
21587
  }
21395
21588
  },
@@ -41062,7 +41255,19 @@
41062
41255
  },
41063
41256
  {
41064
41257
  "name": "providerType",
41065
- "description": "Shipping provider type/integration key.",
41258
+ "description": "Legacy `provider_type` column on `order_shippings`. Often null on real shipments — most rows just leave it empty. Use `providerKey` instead for the canonical integration key.",
41259
+ "args": [],
41260
+ "type": {
41261
+ "kind": "SCALAR",
41262
+ "name": "String",
41263
+ "ofType": null
41264
+ },
41265
+ "isDeprecated": false,
41266
+ "deprecationReason": null
41267
+ },
41268
+ {
41269
+ "name": "providerKey",
41270
+ "description": "Canonical integration key (e.g. `econt`, `speedy`, `price`) — read from `shipping_providers.integration` via the `provider` relation. This is what the admin dispatch flow keys off (e.g. `application(key: <providerKey>)`, `shippingWaybillSchema(key: <providerKey>, …)`). Returns null if the linked provider was deleted or has no integration set.",
41066
41271
  "args": [],
41067
41272
  "type": {
41068
41273
  "kind": "SCALAR",
@@ -48072,6 +48277,51 @@
48072
48277
  "isDeprecated": false,
48073
48278
  "deprecationReason": null
48074
48279
  },
48280
+ {
48281
+ "name": "changeLog",
48282
+ "description": "Audit log for changes to this product (most recent first). Sourced from MongoDB `difference_logs`. Empty for products that have never been edited or for stores with logging disabled.",
48283
+ "args": [
48284
+ {
48285
+ "name": "limit",
48286
+ "description": "Max entries to return. Default 25, max 100.",
48287
+ "type": {
48288
+ "kind": "SCALAR",
48289
+ "name": "Int",
48290
+ "ofType": null
48291
+ },
48292
+ "defaultValue": "25"
48293
+ },
48294
+ {
48295
+ "name": "action",
48296
+ "description": "Optional `action` filter (e.g. `update`, `create`).",
48297
+ "type": {
48298
+ "kind": "SCALAR",
48299
+ "name": "String",
48300
+ "ofType": null
48301
+ },
48302
+ "defaultValue": null
48303
+ }
48304
+ ],
48305
+ "type": {
48306
+ "kind": "NON_NULL",
48307
+ "name": null,
48308
+ "ofType": {
48309
+ "kind": "LIST",
48310
+ "name": null,
48311
+ "ofType": {
48312
+ "kind": "NON_NULL",
48313
+ "name": null,
48314
+ "ofType": {
48315
+ "kind": "OBJECT",
48316
+ "name": "ProductChangeLogEntry",
48317
+ "ofType": null
48318
+ }
48319
+ }
48320
+ }
48321
+ },
48322
+ "isDeprecated": false,
48323
+ "deprecationReason": null
48324
+ },
48075
48325
  {
48076
48326
  "name": "tags",
48077
48327
  "description": "Product tags.",
@@ -49173,8 +49423,498 @@
49173
49423
  "deprecationReason": null
49174
49424
  },
49175
49425
  {
49176
- "name": "message",
49177
- "description": "Optional human-readable summary.",
49426
+ "name": "message",
49427
+ "description": "Optional human-readable summary.",
49428
+ "args": [],
49429
+ "type": {
49430
+ "kind": "SCALAR",
49431
+ "name": "String",
49432
+ "ofType": null
49433
+ },
49434
+ "isDeprecated": false,
49435
+ "deprecationReason": null
49436
+ }
49437
+ ],
49438
+ "inputFields": null,
49439
+ "interfaces": [],
49440
+ "enumValues": null,
49441
+ "possibleTypes": null
49442
+ },
49443
+ {
49444
+ "kind": "OBJECT",
49445
+ "name": "BulkProductsResult",
49446
+ "description": "Generic result for the `productsBulk*` family of mutations (set-active, set-hidden, set-new, set-featured, set-tags, set-category, set-vendor, set-sort-order, set-stock-status, tracking).",
49447
+ "fields": [
49448
+ {
49449
+ "name": "success",
49450
+ "description": "True when the operation finished without throwing.",
49451
+ "args": [],
49452
+ "type": {
49453
+ "kind": "NON_NULL",
49454
+ "name": null,
49455
+ "ofType": {
49456
+ "kind": "SCALAR",
49457
+ "name": "Boolean",
49458
+ "ofType": null
49459
+ }
49460
+ },
49461
+ "isDeprecated": false,
49462
+ "deprecationReason": null
49463
+ },
49464
+ {
49465
+ "name": "affectedCount",
49466
+ "description": "Number of products that were actually updated.",
49467
+ "args": [],
49468
+ "type": {
49469
+ "kind": "NON_NULL",
49470
+ "name": null,
49471
+ "ofType": {
49472
+ "kind": "SCALAR",
49473
+ "name": "Int",
49474
+ "ofType": null
49475
+ }
49476
+ },
49477
+ "isDeprecated": false,
49478
+ "deprecationReason": null
49479
+ },
49480
+ {
49481
+ "name": "skippedIds",
49482
+ "description": "IDs that were skipped because they don't exist (or, for `productsBulkSetOutOfStockStatus`, because the product is not tracking quantity). Empty when every input id was applicable.",
49483
+ "args": [],
49484
+ "type": {
49485
+ "kind": "NON_NULL",
49486
+ "name": null,
49487
+ "ofType": {
49488
+ "kind": "LIST",
49489
+ "name": null,
49490
+ "ofType": {
49491
+ "kind": "NON_NULL",
49492
+ "name": null,
49493
+ "ofType": {
49494
+ "kind": "SCALAR",
49495
+ "name": "ID",
49496
+ "ofType": null
49497
+ }
49498
+ }
49499
+ }
49500
+ },
49501
+ "isDeprecated": false,
49502
+ "deprecationReason": null
49503
+ },
49504
+ {
49505
+ "name": "message",
49506
+ "description": "Optional human-readable summary.",
49507
+ "args": [],
49508
+ "type": {
49509
+ "kind": "SCALAR",
49510
+ "name": "String",
49511
+ "ofType": null
49512
+ },
49513
+ "isDeprecated": false,
49514
+ "deprecationReason": null
49515
+ }
49516
+ ],
49517
+ "inputFields": null,
49518
+ "interfaces": [],
49519
+ "enumValues": null,
49520
+ "possibleTypes": null
49521
+ },
49522
+ {
49523
+ "kind": "OBJECT",
49524
+ "name": "BulkDuplicateProductsResult",
49525
+ "description": "Result of `productsBulkDuplicate` — returns ids of the freshly duplicated products.",
49526
+ "fields": [
49527
+ {
49528
+ "name": "success",
49529
+ "description": "True when the operation finished without throwing.",
49530
+ "args": [],
49531
+ "type": {
49532
+ "kind": "NON_NULL",
49533
+ "name": null,
49534
+ "ofType": {
49535
+ "kind": "SCALAR",
49536
+ "name": "Boolean",
49537
+ "ofType": null
49538
+ }
49539
+ },
49540
+ "isDeprecated": false,
49541
+ "deprecationReason": null
49542
+ },
49543
+ {
49544
+ "name": "duplicatedCount",
49545
+ "description": "Number of duplicates created (= length of `duplicatedProducts`).",
49546
+ "args": [],
49547
+ "type": {
49548
+ "kind": "NON_NULL",
49549
+ "name": null,
49550
+ "ofType": {
49551
+ "kind": "SCALAR",
49552
+ "name": "Int",
49553
+ "ofType": null
49554
+ }
49555
+ },
49556
+ "isDeprecated": false,
49557
+ "deprecationReason": null
49558
+ },
49559
+ {
49560
+ "name": "skippedIds",
49561
+ "description": "Source ids that could not be duplicated (not found).",
49562
+ "args": [],
49563
+ "type": {
49564
+ "kind": "NON_NULL",
49565
+ "name": null,
49566
+ "ofType": {
49567
+ "kind": "LIST",
49568
+ "name": null,
49569
+ "ofType": {
49570
+ "kind": "NON_NULL",
49571
+ "name": null,
49572
+ "ofType": {
49573
+ "kind": "SCALAR",
49574
+ "name": "ID",
49575
+ "ofType": null
49576
+ }
49577
+ }
49578
+ }
49579
+ },
49580
+ "isDeprecated": false,
49581
+ "deprecationReason": null
49582
+ },
49583
+ {
49584
+ "name": "duplicatedProducts",
49585
+ "description": "The newly-created Product copies, in the same order as the input ids.",
49586
+ "args": [],
49587
+ "type": {
49588
+ "kind": "NON_NULL",
49589
+ "name": null,
49590
+ "ofType": {
49591
+ "kind": "LIST",
49592
+ "name": null,
49593
+ "ofType": {
49594
+ "kind": "NON_NULL",
49595
+ "name": null,
49596
+ "ofType": {
49597
+ "kind": "OBJECT",
49598
+ "name": "Product",
49599
+ "ofType": null
49600
+ }
49601
+ }
49602
+ }
49603
+ },
49604
+ "isDeprecated": false,
49605
+ "deprecationReason": null
49606
+ },
49607
+ {
49608
+ "name": "message",
49609
+ "description": "Optional human-readable summary.",
49610
+ "args": [],
49611
+ "type": {
49612
+ "kind": "SCALAR",
49613
+ "name": "String",
49614
+ "ofType": null
49615
+ },
49616
+ "isDeprecated": false,
49617
+ "deprecationReason": null
49618
+ }
49619
+ ],
49620
+ "inputFields": null,
49621
+ "interfaces": [],
49622
+ "enumValues": null,
49623
+ "possibleTypes": null
49624
+ },
49625
+ {
49626
+ "kind": "OBJECT",
49627
+ "name": "ProductChangeLogEntry",
49628
+ "description": "A single audit-log entry for a Product change. Sourced from the MongoDB `difference_logs` collection (separate `mongodb-logging-hetzner-cloud` connection). Mirrors the data the admin UI's `ChangeLogModal` reads from `/admin/api/difference-log/Product/{id}`.",
49629
+ "fields": [
49630
+ {
49631
+ "name": "id",
49632
+ "description": "MongoDB document id (string-encoded ObjectId).",
49633
+ "args": [],
49634
+ "type": {
49635
+ "kind": "NON_NULL",
49636
+ "name": null,
49637
+ "ofType": {
49638
+ "kind": "SCALAR",
49639
+ "name": "ID",
49640
+ "ofType": null
49641
+ }
49642
+ },
49643
+ "isDeprecated": false,
49644
+ "deprecationReason": null
49645
+ },
49646
+ {
49647
+ "name": "action",
49648
+ "description": "What kind of change was logged. Common values: `update`, `create`. Other actions only appear if a resolver explicitly registered them.",
49649
+ "args": [],
49650
+ "type": {
49651
+ "kind": "SCALAR",
49652
+ "name": "String",
49653
+ "ofType": null
49654
+ },
49655
+ "isDeprecated": false,
49656
+ "deprecationReason": null
49657
+ },
49658
+ {
49659
+ "name": "initiator",
49660
+ "description": "Who initiated the change — admin id+name+type for sitecp/PAT-authenticated calls, IP/cli markers otherwise. Free-form JSON because the shape varies by call path.",
49661
+ "args": [],
49662
+ "type": {
49663
+ "kind": "SCALAR",
49664
+ "name": "JSON",
49665
+ "ofType": null
49666
+ },
49667
+ "isDeprecated": false,
49668
+ "deprecationReason": null
49669
+ },
49670
+ {
49671
+ "name": "dirty",
49672
+ "description": "Map of changed attributes — typically `{ attributes: { col: { old, new } } }` plus relation keys (e.g. `categories`, `tags`, `brand_model`). Free-form JSON since the shape varies by mutation.",
49673
+ "args": [],
49674
+ "type": {
49675
+ "kind": "SCALAR",
49676
+ "name": "JSON",
49677
+ "ofType": null
49678
+ },
49679
+ "isDeprecated": false,
49680
+ "deprecationReason": null
49681
+ },
49682
+ {
49683
+ "name": "createdAt",
49684
+ "description": "When the entry was written (server time).",
49685
+ "args": [],
49686
+ "type": {
49687
+ "kind": "SCALAR",
49688
+ "name": "DateTime",
49689
+ "ofType": null
49690
+ },
49691
+ "isDeprecated": false,
49692
+ "deprecationReason": null
49693
+ }
49694
+ ],
49695
+ "inputFields": null,
49696
+ "interfaces": [],
49697
+ "enumValues": null,
49698
+ "possibleTypes": null
49699
+ },
49700
+ {
49701
+ "kind": "ENUM",
49702
+ "name": "BulkOperationStatusEnum",
49703
+ "description": "Status of a queued bulk operation.",
49704
+ "fields": null,
49705
+ "inputFields": null,
49706
+ "interfaces": null,
49707
+ "enumValues": [
49708
+ {
49709
+ "name": "PENDING",
49710
+ "description": "Job created, not yet picked up by a worker.",
49711
+ "isDeprecated": false,
49712
+ "deprecationReason": null
49713
+ },
49714
+ {
49715
+ "name": "RUNNING",
49716
+ "description": "Worker is processing the batch.",
49717
+ "isDeprecated": false,
49718
+ "deprecationReason": null
49719
+ },
49720
+ {
49721
+ "name": "COMPLETED",
49722
+ "description": "Job finished successfully (some ids may have been skipped — see `skippedIds`).",
49723
+ "isDeprecated": false,
49724
+ "deprecationReason": null
49725
+ },
49726
+ {
49727
+ "name": "FAILED",
49728
+ "description": "Worker hit a fatal error before finishing.",
49729
+ "isDeprecated": false,
49730
+ "deprecationReason": null
49731
+ }
49732
+ ],
49733
+ "possibleTypes": null
49734
+ },
49735
+ {
49736
+ "kind": "OBJECT",
49737
+ "name": "BulkOperationJob",
49738
+ "description": "Returned by every `productsBulk*` mutation. The actual side effects run on the `tmp` queue — poll `bulkOperationStatus(jobId)` for progress / final result.",
49739
+ "fields": [
49740
+ {
49741
+ "name": "jobId",
49742
+ "description": "Use this to look up `bulkOperationStatus`.",
49743
+ "args": [],
49744
+ "type": {
49745
+ "kind": "NON_NULL",
49746
+ "name": null,
49747
+ "ofType": {
49748
+ "kind": "SCALAR",
49749
+ "name": "ID",
49750
+ "ofType": null
49751
+ }
49752
+ },
49753
+ "isDeprecated": false,
49754
+ "deprecationReason": null
49755
+ },
49756
+ {
49757
+ "name": "queuedCount",
49758
+ "description": "Number of ids accepted into the batch (post-validation).",
49759
+ "args": [],
49760
+ "type": {
49761
+ "kind": "NON_NULL",
49762
+ "name": null,
49763
+ "ofType": {
49764
+ "kind": "SCALAR",
49765
+ "name": "Int",
49766
+ "ofType": null
49767
+ }
49768
+ },
49769
+ "isDeprecated": false,
49770
+ "deprecationReason": null
49771
+ },
49772
+ {
49773
+ "name": "message",
49774
+ "description": "Optional human-readable summary.",
49775
+ "args": [],
49776
+ "type": {
49777
+ "kind": "SCALAR",
49778
+ "name": "String",
49779
+ "ofType": null
49780
+ },
49781
+ "isDeprecated": false,
49782
+ "deprecationReason": null
49783
+ }
49784
+ ],
49785
+ "inputFields": null,
49786
+ "interfaces": [],
49787
+ "enumValues": null,
49788
+ "possibleTypes": null
49789
+ },
49790
+ {
49791
+ "kind": "OBJECT",
49792
+ "name": "BulkOperationStatus",
49793
+ "description": "Live + final state of a bulk operation. `processedCount`/`affectedCount`/`skippedIds` advance over the lifetime of the job; `status` reaches a terminal value (COMPLETED or FAILED) when the worker finishes.",
49794
+ "fields": [
49795
+ {
49796
+ "name": "id",
49797
+ "description": "Same id returned by `BulkOperationJob.jobId`.",
49798
+ "args": [],
49799
+ "type": {
49800
+ "kind": "NON_NULL",
49801
+ "name": null,
49802
+ "ofType": {
49803
+ "kind": "SCALAR",
49804
+ "name": "ID",
49805
+ "ofType": null
49806
+ }
49807
+ },
49808
+ "isDeprecated": false,
49809
+ "deprecationReason": null
49810
+ },
49811
+ {
49812
+ "name": "mutation",
49813
+ "description": "Which mutation created this job (e.g. `productsBulkSetActive`).",
49814
+ "args": [],
49815
+ "type": {
49816
+ "kind": "NON_NULL",
49817
+ "name": null,
49818
+ "ofType": {
49819
+ "kind": "SCALAR",
49820
+ "name": "String",
49821
+ "ofType": null
49822
+ }
49823
+ },
49824
+ "isDeprecated": false,
49825
+ "deprecationReason": null
49826
+ },
49827
+ {
49828
+ "name": "status",
49829
+ "description": "Lifecycle state.",
49830
+ "args": [],
49831
+ "type": {
49832
+ "kind": "NON_NULL",
49833
+ "name": null,
49834
+ "ofType": {
49835
+ "kind": "ENUM",
49836
+ "name": "BulkOperationStatusEnum",
49837
+ "ofType": null
49838
+ }
49839
+ },
49840
+ "isDeprecated": false,
49841
+ "deprecationReason": null
49842
+ },
49843
+ {
49844
+ "name": "totalCount",
49845
+ "description": "Total ids the worker is processing.",
49846
+ "args": [],
49847
+ "type": {
49848
+ "kind": "NON_NULL",
49849
+ "name": null,
49850
+ "ofType": {
49851
+ "kind": "SCALAR",
49852
+ "name": "Int",
49853
+ "ofType": null
49854
+ }
49855
+ },
49856
+ "isDeprecated": false,
49857
+ "deprecationReason": null
49858
+ },
49859
+ {
49860
+ "name": "processedCount",
49861
+ "description": "Ids the worker has handled so far (advances during RUNNING).",
49862
+ "args": [],
49863
+ "type": {
49864
+ "kind": "NON_NULL",
49865
+ "name": null,
49866
+ "ofType": {
49867
+ "kind": "SCALAR",
49868
+ "name": "Int",
49869
+ "ofType": null
49870
+ }
49871
+ },
49872
+ "isDeprecated": false,
49873
+ "deprecationReason": null
49874
+ },
49875
+ {
49876
+ "name": "affectedCount",
49877
+ "description": "Ids the worker actually mutated. Meaningful when `status` is COMPLETED.",
49878
+ "args": [],
49879
+ "type": {
49880
+ "kind": "NON_NULL",
49881
+ "name": null,
49882
+ "ofType": {
49883
+ "kind": "SCALAR",
49884
+ "name": "Int",
49885
+ "ofType": null
49886
+ }
49887
+ },
49888
+ "isDeprecated": false,
49889
+ "deprecationReason": null
49890
+ },
49891
+ {
49892
+ "name": "skippedIds",
49893
+ "description": "Ids the worker did not mutate — typically because they were missing, soft-deleted, or didn't satisfy the per-mutation precondition (e.g. category linkage for `productsBulkAssignProperties`).",
49894
+ "args": [],
49895
+ "type": {
49896
+ "kind": "NON_NULL",
49897
+ "name": null,
49898
+ "ofType": {
49899
+ "kind": "LIST",
49900
+ "name": null,
49901
+ "ofType": {
49902
+ "kind": "NON_NULL",
49903
+ "name": null,
49904
+ "ofType": {
49905
+ "kind": "SCALAR",
49906
+ "name": "ID",
49907
+ "ofType": null
49908
+ }
49909
+ }
49910
+ }
49911
+ },
49912
+ "isDeprecated": false,
49913
+ "deprecationReason": null
49914
+ },
49915
+ {
49916
+ "name": "error",
49917
+ "description": "Error message if `status: FAILED`.",
49178
49918
  "args": [],
49179
49919
  "type": {
49180
49920
  "kind": "SCALAR",
@@ -49183,123 +49923,29 @@
49183
49923
  },
49184
49924
  "isDeprecated": false,
49185
49925
  "deprecationReason": null
49186
- }
49187
- ],
49188
- "inputFields": null,
49189
- "interfaces": [],
49190
- "enumValues": null,
49191
- "possibleTypes": null
49192
- },
49193
- {
49194
- "kind": "OBJECT",
49195
- "name": "BulkProductsResult",
49196
- "description": "Generic result for the `productsBulk*` family of mutations (set-active, set-hidden, set-new, set-featured, set-tags, set-category, set-vendor, set-sort-order, set-stock-status, tracking).",
49197
- "fields": [
49198
- {
49199
- "name": "success",
49200
- "description": "True when the operation finished without throwing.",
49201
- "args": [],
49202
- "type": {
49203
- "kind": "NON_NULL",
49204
- "name": null,
49205
- "ofType": {
49206
- "kind": "SCALAR",
49207
- "name": "Boolean",
49208
- "ofType": null
49209
- }
49210
- },
49211
- "isDeprecated": false,
49212
- "deprecationReason": null
49213
- },
49214
- {
49215
- "name": "affectedCount",
49216
- "description": "Number of products that were actually updated.",
49217
- "args": [],
49218
- "type": {
49219
- "kind": "NON_NULL",
49220
- "name": null,
49221
- "ofType": {
49222
- "kind": "SCALAR",
49223
- "name": "Int",
49224
- "ofType": null
49225
- }
49226
- },
49227
- "isDeprecated": false,
49228
- "deprecationReason": null
49229
49926
  },
49230
49927
  {
49231
- "name": "skippedIds",
49232
- "description": "IDs that were skipped because they don't exist (or, for `productsBulkSetOutOfStockStatus`, because the product is not tracking quantity). Empty when every input id was applicable.",
49233
- "args": [],
49234
- "type": {
49235
- "kind": "NON_NULL",
49236
- "name": null,
49237
- "ofType": {
49238
- "kind": "LIST",
49239
- "name": null,
49240
- "ofType": {
49241
- "kind": "NON_NULL",
49242
- "name": null,
49243
- "ofType": {
49244
- "kind": "SCALAR",
49245
- "name": "ID",
49246
- "ofType": null
49247
- }
49248
- }
49249
- }
49250
- },
49251
- "isDeprecated": false,
49252
- "deprecationReason": null
49253
- },
49254
- {
49255
- "name": "message",
49256
- "description": "Optional human-readable summary.",
49928
+ "name": "extra",
49929
+ "description": "Mutation-specific extras. Examples: `{ duplicatedIds: [\"...\"] }` for `productsBulkDuplicate`.",
49257
49930
  "args": [],
49258
49931
  "type": {
49259
49932
  "kind": "SCALAR",
49260
- "name": "String",
49933
+ "name": "JSON",
49261
49934
  "ofType": null
49262
49935
  },
49263
49936
  "isDeprecated": false,
49264
49937
  "deprecationReason": null
49265
- }
49266
- ],
49267
- "inputFields": null,
49268
- "interfaces": [],
49269
- "enumValues": null,
49270
- "possibleTypes": null
49271
- },
49272
- {
49273
- "kind": "OBJECT",
49274
- "name": "BulkDuplicateProductsResult",
49275
- "description": "Result of `productsBulkDuplicate` — returns ids of the freshly duplicated products.",
49276
- "fields": [
49277
- {
49278
- "name": "success",
49279
- "description": "True when the operation finished without throwing.",
49280
- "args": [],
49281
- "type": {
49282
- "kind": "NON_NULL",
49283
- "name": null,
49284
- "ofType": {
49285
- "kind": "SCALAR",
49286
- "name": "Boolean",
49287
- "ofType": null
49288
- }
49289
- },
49290
- "isDeprecated": false,
49291
- "deprecationReason": null
49292
49938
  },
49293
49939
  {
49294
- "name": "duplicatedCount",
49295
- "description": "Number of duplicates created (= length of `duplicatedProducts`).",
49940
+ "name": "createdAt",
49941
+ "description": "When the job was queued.",
49296
49942
  "args": [],
49297
49943
  "type": {
49298
49944
  "kind": "NON_NULL",
49299
49945
  "name": null,
49300
49946
  "ofType": {
49301
49947
  "kind": "SCALAR",
49302
- "name": "Int",
49948
+ "name": "DateTime",
49303
49949
  "ofType": null
49304
49950
  }
49305
49951
  },
@@ -49307,60 +49953,12 @@
49307
49953
  "deprecationReason": null
49308
49954
  },
49309
49955
  {
49310
- "name": "skippedIds",
49311
- "description": "Source ids that could not be duplicated (not found).",
49312
- "args": [],
49313
- "type": {
49314
- "kind": "NON_NULL",
49315
- "name": null,
49316
- "ofType": {
49317
- "kind": "LIST",
49318
- "name": null,
49319
- "ofType": {
49320
- "kind": "NON_NULL",
49321
- "name": null,
49322
- "ofType": {
49323
- "kind": "SCALAR",
49324
- "name": "ID",
49325
- "ofType": null
49326
- }
49327
- }
49328
- }
49329
- },
49330
- "isDeprecated": false,
49331
- "deprecationReason": null
49332
- },
49333
- {
49334
- "name": "duplicatedProducts",
49335
- "description": "The newly-created Product copies, in the same order as the input ids.",
49336
- "args": [],
49337
- "type": {
49338
- "kind": "NON_NULL",
49339
- "name": null,
49340
- "ofType": {
49341
- "kind": "LIST",
49342
- "name": null,
49343
- "ofType": {
49344
- "kind": "NON_NULL",
49345
- "name": null,
49346
- "ofType": {
49347
- "kind": "OBJECT",
49348
- "name": "Product",
49349
- "ofType": null
49350
- }
49351
- }
49352
- }
49353
- },
49354
- "isDeprecated": false,
49355
- "deprecationReason": null
49356
- },
49357
- {
49358
- "name": "message",
49359
- "description": "Optional human-readable summary.",
49956
+ "name": "completedAt",
49957
+ "description": "When the worker finished (null until terminal).",
49360
49958
  "args": [],
49361
49959
  "type": {
49362
49960
  "kind": "SCALAR",
49363
- "name": "String",
49961
+ "name": "DateTime",
49364
49962
  "ofType": null
49365
49963
  },
49366
49964
  "isDeprecated": false,
@@ -52897,6 +53495,174 @@
52897
53495
  "enumValues": null,
52898
53496
  "possibleTypes": null
52899
53497
  },
53498
+ {
53499
+ "kind": "INPUT_OBJECT",
53500
+ "name": "ProductSelector",
53501
+ "description": "How a bulk product mutation picks its target products. EXACTLY ONE of the fields below must be set — providing zero or multiple raises `validation_failed`.",
53502
+ "fields": null,
53503
+ "inputFields": [
53504
+ {
53505
+ "name": "productIds",
53506
+ "description": "Explicit list of product IDs (max 250). Use this when you already know which products to touch — e.g. from a prior `products(...)` query, an admin selection, or a join you computed elsewhere.",
53507
+ "type": {
53508
+ "kind": "LIST",
53509
+ "name": null,
53510
+ "ofType": {
53511
+ "kind": "NON_NULL",
53512
+ "name": null,
53513
+ "ofType": {
53514
+ "kind": "SCALAR",
53515
+ "name": "ID",
53516
+ "ofType": null
53517
+ }
53518
+ }
53519
+ },
53520
+ "defaultValue": null
53521
+ },
53522
+ {
53523
+ "name": "categoryId",
53524
+ "description": "All non-deleted products whose MAIN `category_id` equals this. (NOT the multi-category pivot — that's the other relationship.) Server-side resolution; safe for large categories.",
53525
+ "type": {
53526
+ "kind": "SCALAR",
53527
+ "name": "ID",
53528
+ "ofType": null
53529
+ },
53530
+ "defaultValue": null
53531
+ },
53532
+ {
53533
+ "name": "vendorId",
53534
+ "description": "All non-deleted products whose `vendor_id` equals this. Useful for 'every HANKOOK product' mass actions.",
53535
+ "type": {
53536
+ "kind": "SCALAR",
53537
+ "name": "ID",
53538
+ "ofType": null
53539
+ },
53540
+ "defaultValue": null
53541
+ },
53542
+ {
53543
+ "name": "tagName",
53544
+ "description": "All non-deleted products tagged with this tag name (case-sensitive match against `Tag.name`). Resolves via the tags pivot.",
53545
+ "type": {
53546
+ "kind": "SCALAR",
53547
+ "name": "String",
53548
+ "ofType": null
53549
+ },
53550
+ "defaultValue": null
53551
+ }
53552
+ ],
53553
+ "interfaces": null,
53554
+ "enumValues": null,
53555
+ "possibleTypes": null
53556
+ },
53557
+ {
53558
+ "kind": "INPUT_OBJECT",
53559
+ "name": "PriceChange",
53560
+ "description": "Operation + value applied to a price column. Used by `productsBulkAdjustPrice` only — `productsBulkApplyDiscount` has its own simpler `discountPrice: Float` argument.",
53561
+ "fields": null,
53562
+ "inputFields": [
53563
+ {
53564
+ "name": "op",
53565
+ "description": "How `value` is interpreted.",
53566
+ "type": {
53567
+ "kind": "NON_NULL",
53568
+ "name": null,
53569
+ "ofType": {
53570
+ "kind": "ENUM",
53571
+ "name": "PriceChangeOp",
53572
+ "ofType": null
53573
+ }
53574
+ },
53575
+ "defaultValue": null
53576
+ },
53577
+ {
53578
+ "name": "value",
53579
+ "description": "The change amount. For ABSOLUTE_DELTA / PERCENT_DELTA this is signed (negative = decrease). For SET_TO it must be >= 0.",
53580
+ "type": {
53581
+ "kind": "NON_NULL",
53582
+ "name": null,
53583
+ "ofType": {
53584
+ "kind": "SCALAR",
53585
+ "name": "Float",
53586
+ "ofType": null
53587
+ }
53588
+ },
53589
+ "defaultValue": null
53590
+ }
53591
+ ],
53592
+ "interfaces": null,
53593
+ "enumValues": null,
53594
+ "possibleTypes": null
53595
+ },
53596
+ {
53597
+ "kind": "ENUM",
53598
+ "name": "PriceChangeOp",
53599
+ "description": "Way of applying a price change.",
53600
+ "fields": null,
53601
+ "inputFields": null,
53602
+ "interfaces": null,
53603
+ "enumValues": [
53604
+ {
53605
+ "name": "ABSOLUTE_DELTA",
53606
+ "description": "Add `value` to the current price (negative `value` = subtract).",
53607
+ "isDeprecated": false,
53608
+ "deprecationReason": null
53609
+ },
53610
+ {
53611
+ "name": "PERCENT_DELTA",
53612
+ "description": "Multiply the current price by `(1 + value/100)`. `value: 10` = +10%, `value: -25` = -25%.",
53613
+ "isDeprecated": false,
53614
+ "deprecationReason": null
53615
+ },
53616
+ {
53617
+ "name": "SET_TO",
53618
+ "description": "Set the price to `value` directly. `value` must be >= 0.",
53619
+ "isDeprecated": false,
53620
+ "deprecationReason": null
53621
+ }
53622
+ ],
53623
+ "possibleTypes": null
53624
+ },
53625
+ {
53626
+ "kind": "ENUM",
53627
+ "name": "PriceRoundingStrategy",
53628
+ "description": "Strategy for rounding prices after a numeric adjustment. Useful for psychological pricing (.99 endings) after a percentage increase.",
53629
+ "fields": null,
53630
+ "inputFields": null,
53631
+ "interfaces": null,
53632
+ "enumValues": [
53633
+ {
53634
+ "name": "NEAREST_99",
53635
+ "description": "Round to nearest .99 (e.g. 170.51 → 170.99, 99.49 → 99.99).",
53636
+ "isDeprecated": false,
53637
+ "deprecationReason": null
53638
+ },
53639
+ {
53640
+ "name": "NEAREST_49",
53641
+ "description": "Round to nearest .49 (e.g. 170.51 → 170.49, 99.40 → 99.49).",
53642
+ "isDeprecated": false,
53643
+ "deprecationReason": null
53644
+ },
53645
+ {
53646
+ "name": "NEAREST_INTEGER",
53647
+ "description": "Round to nearest whole integer (e.g. 170.51 → 171.00).",
53648
+ "isDeprecated": false,
53649
+ "deprecationReason": null
53650
+ },
53651
+ {
53652
+ "name": "NEAREST_5",
53653
+ "description": "Round to nearest 5 (e.g. 172.39 → 170.00, 173.00 → 175.00).",
53654
+ "isDeprecated": false,
53655
+ "deprecationReason": null
53656
+ },
53657
+ {
53658
+ "name": "NEAREST_10",
53659
+ "description": "Round to nearest 10 (e.g. 172.39 → 170.00, 178.00 → 180.00).",
53660
+ "isDeprecated": false,
53661
+ "deprecationReason": null
53662
+ }
53663
+ ],
53664
+ "possibleTypes": null
53665
+ },
52900
53666
  {
52901
53667
  "kind": "INPUT_OBJECT",
52902
53668
  "name": "CreateProductFileInput",