@cloudcart/dev-mcp 0.2.6 → 0.2.8

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": "Look up the status of a bulk operation. Returns null if no operation with that `jobId` exists in the current site. Poll this 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,173 @@
17968
17995
  "name": null,
17969
17996
  "ofType": {
17970
17997
  "kind": "OBJECT",
17971
- "name": "BulkProductsResult",
17998
+ "name": "BulkOperationJob",
17999
+ "ofType": null
18000
+ }
18001
+ },
18002
+ "isDeprecated": false,
18003
+ "deprecationReason": null
18004
+ },
18005
+ {
18006
+ "name": "productsBulkAdjustPrice",
18007
+ "description": "Apply a `PriceChange` to every variant.price on every product matching the selector. Examples: `change: { op: PERCENT_DELTA, value: 10 }` = +10%, `change: { op: PERCENT_DELTA, value: -25 }` = -25%, `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.",
18008
+ "args": [
18009
+ {
18010
+ "name": "selector",
18011
+ "description": "Which products to touch (exactly one selector field).",
18012
+ "type": {
18013
+ "kind": "NON_NULL",
18014
+ "name": null,
18015
+ "ofType": {
18016
+ "kind": "INPUT_OBJECT",
18017
+ "name": "ProductSelector",
18018
+ "ofType": null
18019
+ }
18020
+ },
18021
+ "defaultValue": null
18022
+ },
18023
+ {
18024
+ "name": "change",
18025
+ "description": "How to change the price.",
18026
+ "type": {
18027
+ "kind": "NON_NULL",
18028
+ "name": null,
18029
+ "ofType": {
18030
+ "kind": "INPUT_OBJECT",
18031
+ "name": "PriceChange",
18032
+ "ofType": null
18033
+ }
18034
+ },
18035
+ "defaultValue": null
18036
+ }
18037
+ ],
18038
+ "type": {
18039
+ "kind": "NON_NULL",
18040
+ "name": null,
18041
+ "ofType": {
18042
+ "kind": "OBJECT",
18043
+ "name": "BulkOperationJob",
18044
+ "ofType": null
18045
+ }
18046
+ },
18047
+ "isDeprecated": false,
18048
+ "deprecationReason": null
18049
+ },
18050
+ {
18051
+ "name": "productsBulkApplyDiscount",
18052
+ "description": "Apply a fixed-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.",
18053
+ "args": [
18054
+ {
18055
+ "name": "selector",
18056
+ "description": "Which products to touch.",
18057
+ "type": {
18058
+ "kind": "NON_NULL",
18059
+ "name": null,
18060
+ "ofType": {
18061
+ "kind": "INPUT_OBJECT",
18062
+ "name": "ProductSelector",
18063
+ "ofType": null
18064
+ }
18065
+ },
18066
+ "defaultValue": null
18067
+ },
18068
+ {
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
+ "type": {
18072
+ "kind": "NON_NULL",
18073
+ "name": null,
18074
+ "ofType": {
18075
+ "kind": "SCALAR",
18076
+ "name": "Float",
18077
+ "ofType": null
18078
+ }
18079
+ },
18080
+ "defaultValue": null
18081
+ }
18082
+ ],
18083
+ "type": {
18084
+ "kind": "NON_NULL",
18085
+ "name": null,
18086
+ "ofType": {
18087
+ "kind": "OBJECT",
18088
+ "name": "BulkOperationJob",
18089
+ "ofType": null
18090
+ }
18091
+ },
18092
+ "isDeprecated": false,
18093
+ "deprecationReason": null
18094
+ },
18095
+ {
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
+ "args": [
18099
+ {
18100
+ "name": "selector",
18101
+ "description": "Which products to touch.",
18102
+ "type": {
18103
+ "kind": "NON_NULL",
18104
+ "name": null,
18105
+ "ofType": {
18106
+ "kind": "INPUT_OBJECT",
18107
+ "name": "ProductSelector",
18108
+ "ofType": null
18109
+ }
18110
+ },
18111
+ "defaultValue": null
18112
+ }
18113
+ ],
18114
+ "type": {
18115
+ "kind": "NON_NULL",
18116
+ "name": null,
18117
+ "ofType": {
18118
+ "kind": "OBJECT",
18119
+ "name": "BulkOperationJob",
18120
+ "ofType": null
18121
+ }
18122
+ },
18123
+ "isDeprecated": false,
18124
+ "deprecationReason": null
18125
+ },
18126
+ {
18127
+ "name": "productsBulkRoundPrices",
18128
+ "description": "Round every variant.price on every product matching the selector to a psychological-pricing endpoint (.99, .49, integer, nearest 5/10). Natural follow-up after a percent-based price increase that produced odd numbers like 170.51.",
18129
+ "args": [
18130
+ {
18131
+ "name": "selector",
18132
+ "description": "Which products to touch.",
18133
+ "type": {
18134
+ "kind": "NON_NULL",
18135
+ "name": null,
18136
+ "ofType": {
18137
+ "kind": "INPUT_OBJECT",
18138
+ "name": "ProductSelector",
18139
+ "ofType": null
18140
+ }
18141
+ },
18142
+ "defaultValue": null
18143
+ },
18144
+ {
18145
+ "name": "strategy",
18146
+ "description": "Rounding strategy.",
18147
+ "type": {
18148
+ "kind": "NON_NULL",
18149
+ "name": null,
18150
+ "ofType": {
18151
+ "kind": "ENUM",
18152
+ "name": "PriceRoundingStrategy",
18153
+ "ofType": null
18154
+ }
18155
+ },
18156
+ "defaultValue": null
18157
+ }
18158
+ ],
18159
+ "type": {
18160
+ "kind": "NON_NULL",
18161
+ "name": null,
18162
+ "ofType": {
18163
+ "kind": "OBJECT",
18164
+ "name": "BulkOperationJob",
17972
18165
  "ofType": null
17973
18166
  }
17974
18167
  },
@@ -21335,6 +21528,67 @@
21335
21528
  "isDeprecated": false,
21336
21529
  "deprecationReason": null
21337
21530
  },
21531
+ {
21532
+ "name": "productsBulkAssignProperties",
21533
+ "description": "Bulk-assign category property options to N products. Each `(property_id, option_ids)` pair in `input` is applied to every product in `productIds` independently. Existing values for properties NOT in input are PRESERVED — pass `option_ids: []` to clear a specific property from those products. Fires `ProductUpdated` + `ProductsSearchEnginesSync` per product.",
21534
+ "args": [
21535
+ {
21536
+ "name": "productIds",
21537
+ "description": "Product IDs (max 250).",
21538
+ "type": {
21539
+ "kind": "NON_NULL",
21540
+ "name": null,
21541
+ "ofType": {
21542
+ "kind": "LIST",
21543
+ "name": null,
21544
+ "ofType": {
21545
+ "kind": "NON_NULL",
21546
+ "name": null,
21547
+ "ofType": {
21548
+ "kind": "SCALAR",
21549
+ "name": "ID",
21550
+ "ofType": null
21551
+ }
21552
+ }
21553
+ }
21554
+ },
21555
+ "defaultValue": null
21556
+ },
21557
+ {
21558
+ "name": "input",
21559
+ "description": "Property/option assignments to apply to every product.",
21560
+ "type": {
21561
+ "kind": "NON_NULL",
21562
+ "name": null,
21563
+ "ofType": {
21564
+ "kind": "LIST",
21565
+ "name": null,
21566
+ "ofType": {
21567
+ "kind": "NON_NULL",
21568
+ "name": null,
21569
+ "ofType": {
21570
+ "kind": "INPUT_OBJECT",
21571
+ "name": "AssignPropertyToProductInput",
21572
+ "ofType": null
21573
+ }
21574
+ }
21575
+ }
21576
+ },
21577
+ "defaultValue": null
21578
+ }
21579
+ ],
21580
+ "type": {
21581
+ "kind": "NON_NULL",
21582
+ "name": null,
21583
+ "ofType": {
21584
+ "kind": "OBJECT",
21585
+ "name": "BulkOperationJob",
21586
+ "ofType": null
21587
+ }
21588
+ },
21589
+ "isDeprecated": false,
21590
+ "deprecationReason": null
21591
+ },
21338
21592
  {
21339
21593
  "name": "createCustomer",
21340
21594
  "description": "Create a new customer.",
@@ -41001,7 +41255,19 @@
41001
41255
  },
41002
41256
  {
41003
41257
  "name": "providerType",
41004
- "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.",
41005
41271
  "args": [],
41006
41272
  "type": {
41007
41273
  "kind": "SCALAR",
@@ -48011,6 +48277,51 @@
48011
48277
  "isDeprecated": false,
48012
48278
  "deprecationReason": null
48013
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
+ },
48014
48325
  {
48015
48326
  "name": "tags",
48016
48327
  "description": "Product tags.",
@@ -49311,6 +49622,354 @@
49311
49622
  "enumValues": null,
49312
49623
  "possibleTypes": null
49313
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`.",
49918
+ "args": [],
49919
+ "type": {
49920
+ "kind": "SCALAR",
49921
+ "name": "String",
49922
+ "ofType": null
49923
+ },
49924
+ "isDeprecated": false,
49925
+ "deprecationReason": null
49926
+ },
49927
+ {
49928
+ "name": "extra",
49929
+ "description": "Mutation-specific extras. Examples: `{ duplicatedIds: [\"...\"] }` for `productsBulkDuplicate`.",
49930
+ "args": [],
49931
+ "type": {
49932
+ "kind": "SCALAR",
49933
+ "name": "JSON",
49934
+ "ofType": null
49935
+ },
49936
+ "isDeprecated": false,
49937
+ "deprecationReason": null
49938
+ },
49939
+ {
49940
+ "name": "createdAt",
49941
+ "description": "When the job was queued.",
49942
+ "args": [],
49943
+ "type": {
49944
+ "kind": "NON_NULL",
49945
+ "name": null,
49946
+ "ofType": {
49947
+ "kind": "SCALAR",
49948
+ "name": "DateTime",
49949
+ "ofType": null
49950
+ }
49951
+ },
49952
+ "isDeprecated": false,
49953
+ "deprecationReason": null
49954
+ },
49955
+ {
49956
+ "name": "completedAt",
49957
+ "description": "When the worker finished (null until terminal).",
49958
+ "args": [],
49959
+ "type": {
49960
+ "kind": "SCALAR",
49961
+ "name": "DateTime",
49962
+ "ofType": null
49963
+ },
49964
+ "isDeprecated": false,
49965
+ "deprecationReason": null
49966
+ }
49967
+ ],
49968
+ "inputFields": null,
49969
+ "interfaces": [],
49970
+ "enumValues": null,
49971
+ "possibleTypes": null
49972
+ },
49314
49973
  {
49315
49974
  "kind": "OBJECT",
49316
49975
  "name": "SmartCollection",
@@ -52836,6 +53495,174 @@
52836
53495
  "enumValues": null,
52837
53496
  "possibleTypes": null
52838
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` and `productsBulkApplyDiscount`.",
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
+ },
52839
53666
  {
52840
53667
  "kind": "INPUT_OBJECT",
52841
53668
  "name": "CreateProductFileInput",