@offerkit/sdk 0.2.2 → 0.2.4

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/dist/index.mjs CHANGED
@@ -38,8 +38,9 @@ const apiKeys = {
38
38
  revoke: oc.route({
39
39
  method: "DELETE",
40
40
  path: "/api-keys/{id}",
41
- summary: "Disable an API key (cannot be re-enabled)"
42
- }).input(z.object({ id: z.string() })).output(z.object({ ok: z.literal(true) }))
41
+ summary: "Disable an API key (cannot be re-enabled)",
42
+ inputStructure: "detailed"
43
+ }).input(z.object({ params: z.object({ id: z.string() }) })).output(z.object({ ok: z.literal(true) }))
43
44
  };
44
45
  //#endregion
45
46
  //#region ../contract/src/mcp.ts
@@ -140,8 +141,9 @@ const campaigns = {
140
141
  })).route({
141
142
  method: "GET",
142
143
  path: "/campaigns/{id}",
143
- summary: "Get campaign"
144
- }).input(z.object({ id: z.string().uuid() })).output(campaignOutput),
144
+ summary: "Get campaign",
145
+ inputStructure: "detailed"
146
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(campaignOutput),
145
147
  create: oc.route({
146
148
  method: "POST",
147
149
  path: "/campaigns",
@@ -150,16 +152,18 @@ const campaigns = {
150
152
  update: oc.route({
151
153
  method: "PATCH",
152
154
  path: "/campaigns/{id}",
153
- summary: "Update campaign"
155
+ summary: "Update campaign",
156
+ inputStructure: "detailed"
154
157
  }).input(z.object({
155
- id: z.string().uuid(),
156
- patch: campaignUpdateInput
158
+ params: z.object({ id: z.string().uuid() }),
159
+ body: z.object({ patch: campaignUpdateInput })
157
160
  })).output(campaignOutput),
158
161
  delete: oc.route({
159
162
  method: "DELETE",
160
163
  path: "/campaigns/{id}",
161
- summary: "Soft-delete campaign"
162
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ ok: z.literal(true) }))
164
+ summary: "Soft-delete campaign",
165
+ inputStructure: "detailed"
166
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ ok: z.literal(true) }))
163
167
  };
164
168
  //#endregion
165
169
  //#region ../contract/src/schemas/customer.ts
@@ -226,16 +230,18 @@ const customers = {
226
230
  })).route({
227
231
  method: "GET",
228
232
  path: "/customers/{id}",
229
- summary: "Get customer"
230
- }).input(z.object({ id: z.string().uuid() })).output(customerOutput),
233
+ summary: "Get customer",
234
+ inputStructure: "detailed"
235
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(customerOutput),
231
236
  getByExternalId: oc.meta(mcpMeta({
232
237
  expose: true,
233
238
  riskLevel: "safe"
234
239
  })).route({
235
240
  method: "GET",
236
241
  path: "/customers/by-external-id/{externalId}",
237
- summary: "Get a customer by integrator-supplied externalId"
238
- }).input(z.object({ externalId: z.string().min(1).max(256) })).output(customerOutput),
242
+ summary: "Get a customer by integrator-supplied externalId",
243
+ inputStructure: "detailed"
244
+ }).input(z.object({ params: z.object({ externalId: z.string().min(1).max(256) }) })).output(customerOutput),
239
245
  create: oc.route({
240
246
  method: "POST",
241
247
  path: "/customers",
@@ -249,16 +255,18 @@ const customers = {
249
255
  update: oc.route({
250
256
  method: "PATCH",
251
257
  path: "/customers/{id}",
252
- summary: "Update customer"
258
+ summary: "Update customer",
259
+ inputStructure: "detailed"
253
260
  }).input(z.object({
254
- id: z.string().uuid(),
255
- patch: customerUpdateInput
261
+ params: z.object({ id: z.string().uuid() }),
262
+ body: z.object({ patch: customerUpdateInput })
256
263
  })).output(customerOutput),
257
264
  delete: oc.route({
258
265
  method: "DELETE",
259
266
  path: "/customers/{id}",
260
- summary: "Soft-delete customer"
261
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ ok: z.literal(true) }))
267
+ summary: "Soft-delete customer",
268
+ inputStructure: "detailed"
269
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ ok: z.literal(true) }))
262
270
  };
263
271
  //#endregion
264
272
  //#region ../contract/src/schemas/loyalty.ts
@@ -416,8 +424,9 @@ const loyalty = {
416
424
  get: oc.route({
417
425
  method: "GET",
418
426
  path: "/loyalty/programs/{id}",
419
- summary: "Get loyalty program"
420
- }).input(z.object({ id: z.string().uuid() })).output(loyaltyProgramOutput),
427
+ summary: "Get loyalty program",
428
+ inputStructure: "detailed"
429
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(loyaltyProgramOutput),
421
430
  create: oc.route({
422
431
  method: "POST",
423
432
  path: "/loyalty/programs",
@@ -426,23 +435,26 @@ const loyalty = {
426
435
  update: oc.route({
427
436
  method: "PATCH",
428
437
  path: "/loyalty/programs/{id}",
429
- summary: "Update loyalty program"
438
+ summary: "Update loyalty program",
439
+ inputStructure: "detailed"
430
440
  }).input(z.object({
431
- id: z.string().uuid(),
432
- patch: loyaltyProgramUpdateInput
441
+ params: z.object({ id: z.string().uuid() }),
442
+ body: z.object({ patch: loyaltyProgramUpdateInput })
433
443
  })).output(loyaltyProgramOutput),
434
444
  delete: oc.route({
435
445
  method: "DELETE",
436
446
  path: "/loyalty/programs/{id}",
437
- summary: "Soft-delete program"
438
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ ok: z.literal(true) }))
447
+ summary: "Soft-delete program",
448
+ inputStructure: "detailed"
449
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ ok: z.literal(true) }))
439
450
  },
440
451
  tiers: {
441
452
  list: oc.route({
442
453
  method: "GET",
443
454
  path: "/loyalty/programs/{programId}/tiers",
444
- summary: "List tiers"
445
- }).input(z.object({ programId: z.string().uuid() })).output(z.object({ data: z.array(loyaltyTierOutput) })),
455
+ summary: "List tiers",
456
+ inputStructure: "detailed"
457
+ }).input(z.object({ params: z.object({ programId: z.string().uuid() }) })).output(z.object({ data: z.array(loyaltyTierOutput) })),
446
458
  create: oc.route({
447
459
  method: "POST",
448
460
  path: "/loyalty/tiers",
@@ -451,23 +463,26 @@ const loyalty = {
451
463
  update: oc.route({
452
464
  method: "PATCH",
453
465
  path: "/loyalty/tiers/{id}",
454
- summary: "Update tier"
466
+ summary: "Update tier",
467
+ inputStructure: "detailed"
455
468
  }).input(z.object({
456
- id: z.string().uuid(),
457
- patch: loyaltyTierUpdateInput
469
+ params: z.object({ id: z.string().uuid() }),
470
+ body: z.object({ patch: loyaltyTierUpdateInput })
458
471
  })).output(loyaltyTierOutput),
459
472
  delete: oc.route({
460
473
  method: "DELETE",
461
474
  path: "/loyalty/tiers/{id}",
462
- summary: "Delete tier"
463
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ ok: z.literal(true) }))
475
+ summary: "Delete tier",
476
+ inputStructure: "detailed"
477
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ ok: z.literal(true) }))
464
478
  },
465
479
  earningRules: {
466
480
  list: oc.route({
467
481
  method: "GET",
468
482
  path: "/loyalty/programs/{programId}/earning-rules",
469
- summary: "List earning rules"
470
- }).input(z.object({ programId: z.string().uuid() })).output(z.object({ data: z.array(loyaltyEarningRuleOutput) })),
483
+ summary: "List earning rules",
484
+ inputStructure: "detailed"
485
+ }).input(z.object({ params: z.object({ programId: z.string().uuid() }) })).output(z.object({ data: z.array(loyaltyEarningRuleOutput) })),
471
486
  create: oc.route({
472
487
  method: "POST",
473
488
  path: "/loyalty/earning-rules",
@@ -476,23 +491,26 @@ const loyalty = {
476
491
  update: oc.route({
477
492
  method: "PATCH",
478
493
  path: "/loyalty/earning-rules/{id}",
479
- summary: "Update earning rule"
494
+ summary: "Update earning rule",
495
+ inputStructure: "detailed"
480
496
  }).input(z.object({
481
- id: z.string().uuid(),
482
- patch: loyaltyEarningRuleUpdateInput
497
+ params: z.object({ id: z.string().uuid() }),
498
+ body: z.object({ patch: loyaltyEarningRuleUpdateInput })
483
499
  })).output(loyaltyEarningRuleOutput),
484
500
  delete: oc.route({
485
501
  method: "DELETE",
486
502
  path: "/loyalty/earning-rules/{id}",
487
- summary: "Delete earning rule"
488
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ ok: z.literal(true) }))
503
+ summary: "Delete earning rule",
504
+ inputStructure: "detailed"
505
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ ok: z.literal(true) }))
489
506
  },
490
507
  rewards: {
491
508
  list: oc.route({
492
509
  method: "GET",
493
510
  path: "/loyalty/programs/{programId}/rewards",
494
- summary: "List rewards"
495
- }).input(z.object({ programId: z.string().uuid() })).output(z.object({ data: z.array(loyaltyRewardOutput) })),
511
+ summary: "List rewards",
512
+ inputStructure: "detailed"
513
+ }).input(z.object({ params: z.object({ programId: z.string().uuid() }) })).output(z.object({ data: z.array(loyaltyRewardOutput) })),
496
514
  create: oc.route({
497
515
  method: "POST",
498
516
  path: "/loyalty/rewards",
@@ -501,28 +519,35 @@ const loyalty = {
501
519
  update: oc.route({
502
520
  method: "PATCH",
503
521
  path: "/loyalty/rewards/{id}",
504
- summary: "Update reward"
522
+ summary: "Update reward",
523
+ inputStructure: "detailed"
505
524
  }).input(z.object({
506
- id: z.string().uuid(),
507
- patch: loyaltyRewardUpdateInput
525
+ params: z.object({ id: z.string().uuid() }),
526
+ body: z.object({ patch: loyaltyRewardUpdateInput })
508
527
  })).output(loyaltyRewardOutput),
509
528
  delete: oc.route({
510
529
  method: "DELETE",
511
530
  path: "/loyalty/rewards/{id}",
512
- summary: "Soft-delete reward"
513
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ ok: z.literal(true) }))
531
+ summary: "Soft-delete reward",
532
+ inputStructure: "detailed"
533
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ ok: z.literal(true) }))
514
534
  },
515
535
  members: {
516
536
  list: oc.route({
517
537
  method: "GET",
518
538
  path: "/loyalty/programs/{programId}/members",
519
- summary: "List members of a program"
520
- }).input(paginationInput.extend({ programId: z.string().uuid() })).output(paginatedOutput(loyaltyMemberOutput)),
539
+ summary: "List members of a program",
540
+ inputStructure: "detailed"
541
+ }).input(z.object({
542
+ params: z.object({ programId: z.string().uuid() }),
543
+ query: paginationInput
544
+ })).output(paginatedOutput(loyaltyMemberOutput)),
521
545
  get: oc.route({
522
546
  method: "GET",
523
547
  path: "/loyalty/members/{id}",
524
- summary: "Get member"
525
- }).input(z.object({ id: z.string().uuid() })).output(loyaltyMemberOutput),
548
+ summary: "Get member",
549
+ inputStructure: "detailed"
550
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(loyaltyMemberOutput),
526
551
  enroll: oc.route({
527
552
  method: "POST",
528
553
  path: "/loyalty/members",
@@ -574,8 +599,9 @@ const loyalty = {
574
599
  })).route({
575
600
  method: "GET",
576
601
  path: "/loyalty/members/{id}/transactions",
577
- summary: "Member transaction ledger"
578
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ data: z.array(loyaltyTransactionOutput) }))
602
+ summary: "Member transaction ledger",
603
+ inputStructure: "detailed"
604
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ data: z.array(loyaltyTransactionOutput) }))
579
605
  }
580
606
  };
581
607
  //#endregion
@@ -690,8 +716,9 @@ const referrals = {
690
716
  get: oc.route({
691
717
  method: "GET",
692
718
  path: "/referral-programs/{id}",
693
- summary: "Get referral program"
694
- }).input(z.object({ id: z.string().uuid() })).output(referralProgramOutput),
719
+ summary: "Get referral program",
720
+ inputStructure: "detailed"
721
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(referralProgramOutput),
695
722
  create: oc.route({
696
723
  method: "POST",
697
724
  path: "/referral-programs",
@@ -700,32 +727,43 @@ const referrals = {
700
727
  update: oc.route({
701
728
  method: "PATCH",
702
729
  path: "/referral-programs/{id}",
703
- summary: "Update referral program"
730
+ summary: "Update referral program",
731
+ inputStructure: "detailed"
704
732
  }).input(z.object({
705
- id: z.string().uuid(),
706
- patch: referralProgramUpdateInput
733
+ params: z.object({ id: z.string().uuid() }),
734
+ body: z.object({ patch: referralProgramUpdateInput })
707
735
  })).output(referralProgramOutput),
708
736
  delete: oc.route({
709
737
  method: "DELETE",
710
738
  path: "/referral-programs/{id}",
711
- summary: "Soft-delete referral program"
712
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ ok: z.literal(true) }))
739
+ summary: "Soft-delete referral program",
740
+ inputStructure: "detailed"
741
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ ok: z.literal(true) }))
713
742
  },
714
743
  listCodes: oc.route({
715
744
  method: "GET",
716
745
  path: "/referral-programs/{programId}/codes",
717
- summary: "List referral codes in a program"
718
- }).input(paginationInput.extend({ programId: z.string().uuid() })).output(paginatedOutput(referralCodeOutput)),
746
+ summary: "List referral codes in a program",
747
+ inputStructure: "detailed"
748
+ }).input(z.object({
749
+ params: z.object({ programId: z.string().uuid() }),
750
+ query: paginationInput
751
+ })).output(paginatedOutput(referralCodeOutput)),
719
752
  listConversions: oc.route({
720
753
  method: "GET",
721
754
  path: "/referral-codes/{codeId}/conversions",
722
- summary: "List conversions for a referral code"
723
- }).input(paginationInput.extend({ codeId: z.string().uuid() })).output(paginatedOutput(referralConversionOutput)),
755
+ summary: "List conversions for a referral code",
756
+ inputStructure: "detailed"
757
+ }).input(z.object({
758
+ params: z.object({ codeId: z.string().uuid() }),
759
+ query: paginationInput
760
+ })).output(paginatedOutput(referralConversionOutput)),
724
761
  getByCode: oc.route({
725
762
  method: "GET",
726
763
  path: "/referrals/{code}",
727
- summary: "Look up a referral code"
728
- }).input(z.object({ code: z.string() })).output(referralCodeOutput),
764
+ summary: "Look up a referral code",
765
+ inputStructure: "detailed"
766
+ }).input(z.object({ params: z.object({ code: z.string() }) })).output(referralCodeOutput),
729
767
  issue: oc.route({
730
768
  method: "POST",
731
769
  path: "/referrals/issue",
@@ -738,6 +776,333 @@ const referrals = {
738
776
  }).input(referralConvertInput).output(referralConvertOutput)
739
777
  };
740
778
  //#endregion
779
+ //#region ../contract/src/schemas/voucher.ts
780
+ const voucherType = z.enum(["DISCOUNT", "GIFT_CARD"]);
781
+ const voucherDiscount = z.object({
782
+ type: z.enum(["AMOUNT", "PERCENTAGE"]),
783
+ amount: z.number().int().min(0).optional(),
784
+ percent: z.number().int().min(0).max(1e4).optional(),
785
+ maxDiscountAmount: z.number().int().min(0).optional(),
786
+ appliesTo: z.object({
787
+ productIds: z.array(z.string()).optional(),
788
+ collectionIds: z.array(z.string()).optional()
789
+ }).optional()
790
+ });
791
+ const customReward = z.object({
792
+ typeKey: z.string().min(1),
793
+ payload: z.record(z.string(), z.unknown())
794
+ });
795
+ const voucherOutput = z.object({
796
+ id: z.string().uuid(),
797
+ code: z.string(),
798
+ campaignId: z.string().uuid().nullable(),
799
+ type: voucherType,
800
+ discount: voucherDiscount.nullable(),
801
+ customRewards: z.array(customReward),
802
+ giftBalance: z.number().int().nullable(),
803
+ redemptionLimit: z.number().int().nullable(),
804
+ redemptionCount: z.number().int(),
805
+ priority: z.number().int(),
806
+ exclusive: z.boolean(),
807
+ active: z.boolean(),
808
+ startDate: z.string().datetime().nullable(),
809
+ endDate: z.string().datetime().nullable(),
810
+ customerId: z.string().uuid().nullable(),
811
+ metadata: z.record(z.string(), z.unknown()),
812
+ createdAt: z.string().datetime(),
813
+ updatedAt: z.string().datetime()
814
+ });
815
+ const voucherCreateInput = z.object({
816
+ code: z.string().min(1).optional(),
817
+ campaignId: z.string().uuid().optional(),
818
+ type: voucherType,
819
+ discount: voucherDiscount.optional(),
820
+ customRewards: z.array(customReward).optional(),
821
+ giftBalance: z.number().int().min(0).optional(),
822
+ redemptionLimit: z.number().int().min(1).optional(),
823
+ priority: z.number().int().optional(),
824
+ exclusive: z.boolean().optional(),
825
+ startDate: z.string().datetime().optional(),
826
+ endDate: z.string().datetime().optional(),
827
+ customerId: z.string().uuid().optional(),
828
+ metadata: z.record(z.string(), z.unknown()).optional()
829
+ });
830
+ const voucherUpdateInput = voucherCreateInput.omit({
831
+ type: true,
832
+ code: true
833
+ }).partial().extend({ active: z.boolean().optional() });
834
+ const voucherBulkCreateInput = z.object({
835
+ campaignId: z.string().uuid(),
836
+ count: z.number().int().min(1).max(1e5)
837
+ });
838
+ //#endregion
839
+ //#region ../contract/src/schemas/redemption.ts
840
+ const orderItem$1 = z.object({
841
+ productId: z.string(),
842
+ collectionId: z.string().optional(),
843
+ quantity: z.number().int().min(1),
844
+ unitPrice: z.number().int().min(0)
845
+ });
846
+ const orderInput = z.object({
847
+ amount: z.number().int().min(0),
848
+ currency: z.string().length(3),
849
+ items: z.array(orderItem$1).optional()
850
+ });
851
+ const validateInput = z.object({
852
+ code: z.string().min(1),
853
+ customerId: z.string().uuid().optional(),
854
+ order: orderInput.optional()
855
+ });
856
+ const redeemInput = validateInput.extend({
857
+ /** uuid of an `order` row created via the orders API. */
858
+ orderId: z.string().uuid().optional(),
859
+ /** Free-form integrator order reference (Shopify id, etc). */
860
+ externalOrderId: z.string().min(1).max(120).optional(),
861
+ idempotencyKey: z.string().min(1).max(128).optional()
862
+ });
863
+ const breakdownEntry = z.object({
864
+ voucherId: z.string().uuid(),
865
+ code: z.string(),
866
+ amount: z.number().int(),
867
+ type: z.enum(["AMOUNT", "PERCENTAGE"]).optional(),
868
+ reason: z.enum(["exclusivity_lost", "zero_after_running_total"]).optional()
869
+ });
870
+ const redemptionExplanation = z.object({
871
+ code: z.enum([
872
+ "voucher_not_found",
873
+ "voucher_disabled",
874
+ "voucher_expired",
875
+ "redemption_limit_reached",
876
+ "currency_mismatch",
877
+ "gift_balance_zero",
878
+ "order_required",
879
+ "exclusivity_lost",
880
+ "zero_after_running_total",
881
+ "gift_card_stacking_unsupported"
882
+ ]),
883
+ message: z.string(),
884
+ voucherId: z.string().uuid().optional(),
885
+ voucherCode: z.string().optional(),
886
+ details: z.record(z.string(), z.union([
887
+ z.string(),
888
+ z.number(),
889
+ z.boolean(),
890
+ z.null()
891
+ ])).optional()
892
+ });
893
+ const validateOutput = z.object({
894
+ valid: z.boolean(),
895
+ code: z.string().optional(),
896
+ message: z.string().optional(),
897
+ explanations: z.array(redemptionExplanation).optional(),
898
+ preview: z.object({
899
+ amount: z.number().int(),
900
+ finalOrder: z.object({
901
+ amount: z.number().int(),
902
+ currency: z.string()
903
+ }),
904
+ breakdown: z.array(breakdownEntry)
905
+ }).optional()
906
+ });
907
+ const qualifyInput = z.object({
908
+ customerId: z.string().uuid(),
909
+ order: orderInput,
910
+ filters: z.object({
911
+ campaignIds: z.array(z.string().uuid()).max(100).optional(),
912
+ includeSkipped: z.boolean().optional()
913
+ }).optional()
914
+ });
915
+ const qualifyOutput = z.object({
916
+ eligible: z.array(z.object({
917
+ code: z.string(),
918
+ campaignId: z.string().uuid().nullable(),
919
+ discount: voucherDiscount.omit({ appliesTo: true }).nullable(),
920
+ endDate: z.string().datetime().nullable(),
921
+ preview: z.object({
922
+ amount: z.number().int(),
923
+ finalOrder: z.object({
924
+ amount: z.number().int(),
925
+ currency: z.string()
926
+ }),
927
+ breakdown: z.array(breakdownEntry)
928
+ }).optional()
929
+ })),
930
+ skipped: z.array(z.object({
931
+ code: z.string(),
932
+ campaignId: z.string().uuid().nullable(),
933
+ reason: z.string(),
934
+ message: z.string()
935
+ }))
936
+ });
937
+ const redeemOutput = z.object({
938
+ ok: z.boolean(),
939
+ redemptionId: z.string().uuid().optional(),
940
+ amount: z.number().int().optional(),
941
+ finalOrder: z.object({
942
+ amount: z.number().int(),
943
+ currency: z.string()
944
+ }).optional(),
945
+ breakdown: z.array(breakdownEntry).optional(),
946
+ idempotent: z.boolean().optional(),
947
+ code: z.string().optional(),
948
+ message: z.string().optional(),
949
+ explanations: z.array(redemptionExplanation).optional()
950
+ });
951
+ const stackRedeemInput = z.object({
952
+ codes: z.array(z.string().min(1)).min(1).max(20),
953
+ customerId: z.string().uuid().optional(),
954
+ orderId: z.string().uuid().optional(),
955
+ externalOrderId: z.string().min(1).max(120).optional(),
956
+ order: orderInput,
957
+ idempotencyKey: z.string().min(1).max(128).optional()
958
+ });
959
+ const stackEntry = z.object({
960
+ voucherCode: z.string(),
961
+ voucherId: z.string().uuid(),
962
+ redemptionId: z.string().uuid(),
963
+ amount: z.number().int()
964
+ });
965
+ const stackRedeemOutput = z.object({
966
+ ok: z.boolean(),
967
+ batchId: z.string().uuid().optional(),
968
+ amount: z.number().int().optional(),
969
+ finalOrder: z.object({
970
+ amount: z.number().int(),
971
+ currency: z.string()
972
+ }).optional(),
973
+ breakdown: z.array(breakdownEntry).optional(),
974
+ entries: z.array(stackEntry).optional(),
975
+ idempotent: z.boolean().optional(),
976
+ code: z.string().optional(),
977
+ message: z.string().optional(),
978
+ explanations: z.array(redemptionExplanation).optional()
979
+ });
980
+ //#endregion
981
+ //#region ../contract/src/schemas/promotion.ts
982
+ const promotionTierOutput = z.object({
983
+ id: z.string().uuid(),
984
+ campaignId: z.string().uuid(),
985
+ name: z.string(),
986
+ description: z.string().nullable(),
987
+ effect: voucherDiscount,
988
+ customRewards: z.array(customReward),
989
+ validationRuleId: z.string().uuid().nullable(),
990
+ active: z.boolean(),
991
+ priority: z.number().int(),
992
+ exclusive: z.boolean(),
993
+ startDate: z.string().datetime().nullable(),
994
+ endDate: z.string().datetime().nullable(),
995
+ metadata: z.record(z.string(), z.unknown()),
996
+ createdAt: z.string().datetime(),
997
+ updatedAt: z.string().datetime()
998
+ });
999
+ const promotionTierCreateInput = z.object({
1000
+ campaignId: z.string().uuid(),
1001
+ name: z.string().min(1),
1002
+ description: z.string().optional(),
1003
+ effect: voucherDiscount,
1004
+ customRewards: z.array(customReward).optional(),
1005
+ validationRuleId: z.string().uuid().optional(),
1006
+ active: z.boolean().optional(),
1007
+ priority: z.number().int().optional(),
1008
+ exclusive: z.boolean().optional(),
1009
+ startDate: z.string().datetime().optional(),
1010
+ endDate: z.string().datetime().optional(),
1011
+ metadata: z.record(z.string(), z.unknown()).optional()
1012
+ });
1013
+ const promotionTierUpdateInput = promotionTierCreateInput.omit({ campaignId: true }).partial();
1014
+ const qualificationInput = z.object({
1015
+ customerId: z.string().uuid().optional(),
1016
+ order: orderInput,
1017
+ metadata: z.record(z.string(), z.unknown()).optional(),
1018
+ filters: z.object({
1019
+ campaignIds: z.array(z.string().uuid()).optional(),
1020
+ includeSkipped: z.boolean().optional()
1021
+ }).optional()
1022
+ });
1023
+ const qualificationReason = z.enum([
1024
+ "campaign_inactive",
1025
+ "campaign_not_active",
1026
+ "promotion_inactive",
1027
+ "promotion_not_active",
1028
+ "currency_mismatch",
1029
+ "rule_failed",
1030
+ "rule_error",
1031
+ "no_discount_effect",
1032
+ "exclusivity_lost",
1033
+ "zero_after_running_total"
1034
+ ]);
1035
+ const qualifiedPromotion = z.object({
1036
+ source: z.literal("promotion"),
1037
+ campaignId: z.string().uuid(),
1038
+ promotionTierId: z.string().uuid(),
1039
+ name: z.string(),
1040
+ discount: voucherDiscount,
1041
+ customRewards: z.array(customReward),
1042
+ priority: z.number().int(),
1043
+ exclusive: z.boolean(),
1044
+ metadata: z.record(z.string(), z.unknown())
1045
+ });
1046
+ const skippedPromotion = qualifiedPromotion.extend({
1047
+ reason: qualificationReason,
1048
+ message: z.string(),
1049
+ trace: z.unknown().optional()
1050
+ });
1051
+ const qualificationOutput = z.object({
1052
+ eligible: z.array(qualifiedPromotion),
1053
+ skipped: z.array(skippedPromotion),
1054
+ preview: z.object({
1055
+ amount: z.number().int(),
1056
+ finalOrder: z.object({
1057
+ amount: z.number().int(),
1058
+ currency: z.string()
1059
+ }),
1060
+ breakdown: z.array(breakdownEntry)
1061
+ })
1062
+ });
1063
+ //#endregion
1064
+ //#region ../contract/src/routes/promotions.ts
1065
+ const promotions = {
1066
+ tiers: {
1067
+ list: oc.route({
1068
+ method: "GET",
1069
+ path: "/promotions/tiers",
1070
+ summary: "List promotion tiers"
1071
+ }).input(paginationInput.extend({
1072
+ campaignId: z.string().uuid().optional(),
1073
+ active: z.boolean().optional()
1074
+ })).output(paginatedOutput(promotionTierOutput)),
1075
+ create: oc.route({
1076
+ method: "POST",
1077
+ path: "/promotions/tiers",
1078
+ summary: "Create promotion tier"
1079
+ }).input(promotionTierCreateInput).output(promotionTierOutput),
1080
+ update: oc.route({
1081
+ method: "PATCH",
1082
+ path: "/promotions/tiers/{id}",
1083
+ summary: "Update promotion tier",
1084
+ inputStructure: "detailed"
1085
+ }).input(z.object({
1086
+ params: z.object({ id: z.string().uuid() }),
1087
+ body: z.object({ patch: promotionTierUpdateInput })
1088
+ })).output(promotionTierOutput),
1089
+ delete: oc.route({
1090
+ method: "DELETE",
1091
+ path: "/promotions/tiers/{id}",
1092
+ summary: "Soft-delete promotion tier",
1093
+ inputStructure: "detailed"
1094
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ ok: z.literal(true) }))
1095
+ },
1096
+ qualify: oc.meta(mcpMeta({
1097
+ expose: true,
1098
+ riskLevel: "safe"
1099
+ })).route({
1100
+ method: "POST",
1101
+ path: "/promotions/qualify",
1102
+ summary: "Return auto-applied promotions a cart qualifies for"
1103
+ }).input(qualificationInput).output(qualificationOutput)
1104
+ };
1105
+ //#endregion
741
1106
  //#region ../contract/src/schemas/reward-type.ts
742
1107
  const rewardTypeOutput = z.object({
743
1108
  id: z.string().uuid(),
@@ -766,8 +1131,9 @@ const rewardTypes = {
766
1131
  get: oc.route({
767
1132
  method: "GET",
768
1133
  path: "/reward-types/{id}",
769
- summary: "Get reward type"
770
- }).input(z.object({ id: z.string().uuid() })).output(rewardTypeOutput),
1134
+ summary: "Get reward type",
1135
+ inputStructure: "detailed"
1136
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(rewardTypeOutput),
771
1137
  create: oc.route({
772
1138
  method: "POST",
773
1139
  path: "/reward-types",
@@ -776,16 +1142,18 @@ const rewardTypes = {
776
1142
  update: oc.route({
777
1143
  method: "PATCH",
778
1144
  path: "/reward-types/{id}",
779
- summary: "Update reward type"
1145
+ summary: "Update reward type",
1146
+ inputStructure: "detailed"
780
1147
  }).input(z.object({
781
- id: z.string().uuid(),
782
- patch: rewardTypeUpdateInput
1148
+ params: z.object({ id: z.string().uuid() }),
1149
+ body: z.object({ patch: rewardTypeUpdateInput })
783
1150
  })).output(rewardTypeOutput),
784
1151
  delete: oc.route({
785
1152
  method: "DELETE",
786
1153
  path: "/reward-types/{id}",
787
- summary: "Soft-delete reward type"
788
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ ok: z.literal(true) }))
1154
+ summary: "Soft-delete reward type",
1155
+ inputStructure: "detailed"
1156
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ ok: z.literal(true) }))
789
1157
  };
790
1158
  //#endregion
791
1159
  //#region ../contract/src/schemas/segment.ts
@@ -815,8 +1183,9 @@ const segments = {
815
1183
  get: oc.route({
816
1184
  method: "GET",
817
1185
  path: "/segments/{id}",
818
- summary: "Get segment"
819
- }).input(z.object({ id: z.string().uuid() })).output(segmentOutput),
1186
+ summary: "Get segment",
1187
+ inputStructure: "detailed"
1188
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(segmentOutput),
820
1189
  create: oc.route({
821
1190
  method: "POST",
822
1191
  path: "/segments",
@@ -825,16 +1194,18 @@ const segments = {
825
1194
  update: oc.route({
826
1195
  method: "PATCH",
827
1196
  path: "/segments/{id}",
828
- summary: "Update segment"
1197
+ summary: "Update segment",
1198
+ inputStructure: "detailed"
829
1199
  }).input(z.object({
830
- id: z.string().uuid(),
831
- patch: segmentUpdateInput
1200
+ params: z.object({ id: z.string().uuid() }),
1201
+ body: z.object({ patch: segmentUpdateInput })
832
1202
  })).output(segmentOutput),
833
1203
  delete: oc.route({
834
1204
  method: "DELETE",
835
1205
  path: "/segments/{id}",
836
- summary: "Soft-delete segment"
837
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ ok: z.literal(true) })),
1206
+ summary: "Soft-delete segment",
1207
+ inputStructure: "detailed"
1208
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ ok: z.literal(true) })),
838
1209
  preview: oc.meta(mcpMeta({
839
1210
  expose: true,
840
1211
  riskLevel: "safe",
@@ -886,8 +1257,9 @@ const validationRules = {
886
1257
  get: oc.route({
887
1258
  method: "GET",
888
1259
  path: "/validation-rules/{id}",
889
- summary: "Get validation rule"
890
- }).input(z.object({ id: z.string().uuid() })).output(validationRuleOutput),
1260
+ summary: "Get validation rule",
1261
+ inputStructure: "detailed"
1262
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(validationRuleOutput),
891
1263
  create: oc.route({
892
1264
  method: "POST",
893
1265
  path: "/validation-rules",
@@ -896,164 +1268,20 @@ const validationRules = {
896
1268
  update: oc.route({
897
1269
  method: "PATCH",
898
1270
  path: "/validation-rules/{id}",
899
- summary: "Update validation rule"
1271
+ summary: "Update validation rule",
1272
+ inputStructure: "detailed"
900
1273
  }).input(z.object({
901
- id: z.string().uuid(),
902
- patch: validationRuleUpdateInput
1274
+ params: z.object({ id: z.string().uuid() }),
1275
+ body: z.object({ patch: validationRuleUpdateInput })
903
1276
  })).output(validationRuleOutput),
904
1277
  delete: oc.route({
905
1278
  method: "DELETE",
906
1279
  path: "/validation-rules/{id}",
907
- summary: "Soft-delete validation rule"
908
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ ok: z.literal(true) }))
1280
+ summary: "Soft-delete validation rule",
1281
+ inputStructure: "detailed"
1282
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ ok: z.literal(true) }))
909
1283
  };
910
1284
  //#endregion
911
- //#region ../contract/src/schemas/voucher.ts
912
- const voucherType = z.enum(["DISCOUNT", "GIFT_CARD"]);
913
- const voucherDiscount = z.object({
914
- type: z.enum(["AMOUNT", "PERCENTAGE"]),
915
- amount: z.number().int().min(0).optional(),
916
- percent: z.number().int().min(0).max(1e4).optional(),
917
- maxDiscountAmount: z.number().int().min(0).optional(),
918
- appliesTo: z.object({
919
- productIds: z.array(z.string()).optional(),
920
- collectionIds: z.array(z.string()).optional()
921
- }).optional()
922
- });
923
- const customReward = z.object({
924
- typeKey: z.string().min(1),
925
- payload: z.record(z.string(), z.unknown())
926
- });
927
- const voucherOutput = z.object({
928
- id: z.string().uuid(),
929
- code: z.string(),
930
- campaignId: z.string().uuid().nullable(),
931
- type: voucherType,
932
- discount: voucherDiscount.nullable(),
933
- customRewards: z.array(customReward),
934
- giftBalance: z.number().int().nullable(),
935
- redemptionLimit: z.number().int().nullable(),
936
- redemptionCount: z.number().int(),
937
- priority: z.number().int(),
938
- exclusive: z.boolean(),
939
- active: z.boolean(),
940
- startDate: z.string().datetime().nullable(),
941
- endDate: z.string().datetime().nullable(),
942
- customerId: z.string().uuid().nullable(),
943
- metadata: z.record(z.string(), z.unknown()),
944
- createdAt: z.string().datetime(),
945
- updatedAt: z.string().datetime()
946
- });
947
- const voucherCreateInput = z.object({
948
- code: z.string().min(1).optional(),
949
- campaignId: z.string().uuid().optional(),
950
- type: voucherType,
951
- discount: voucherDiscount.optional(),
952
- customRewards: z.array(customReward).optional(),
953
- giftBalance: z.number().int().min(0).optional(),
954
- redemptionLimit: z.number().int().min(1).optional(),
955
- priority: z.number().int().optional(),
956
- exclusive: z.boolean().optional(),
957
- startDate: z.string().datetime().optional(),
958
- endDate: z.string().datetime().optional(),
959
- customerId: z.string().uuid().optional(),
960
- metadata: z.record(z.string(), z.unknown()).optional()
961
- });
962
- const voucherUpdateInput = voucherCreateInput.omit({
963
- type: true,
964
- code: true
965
- }).partial().extend({ active: z.boolean().optional() });
966
- const voucherBulkCreateInput = z.object({
967
- campaignId: z.string().uuid(),
968
- count: z.number().int().min(1).max(1e5)
969
- });
970
- //#endregion
971
- //#region ../contract/src/schemas/redemption.ts
972
- const orderItem$1 = z.object({
973
- productId: z.string(),
974
- collectionId: z.string().optional(),
975
- quantity: z.number().int().min(1),
976
- unitPrice: z.number().int().min(0)
977
- });
978
- const orderInput = z.object({
979
- amount: z.number().int().min(0),
980
- currency: z.string().length(3),
981
- items: z.array(orderItem$1).optional()
982
- });
983
- const validateInput = z.object({
984
- code: z.string().min(1),
985
- customerId: z.string().uuid().optional(),
986
- order: orderInput.optional()
987
- });
988
- const redeemInput = validateInput.extend({
989
- /** uuid of an `order` row created via the orders API. */
990
- orderId: z.string().uuid().optional(),
991
- /** Free-form integrator order reference (Shopify id, etc). */
992
- externalOrderId: z.string().min(1).max(120).optional(),
993
- idempotencyKey: z.string().min(1).max(128).optional()
994
- });
995
- const breakdownEntry = z.object({
996
- voucherId: z.string().uuid(),
997
- code: z.string(),
998
- amount: z.number().int(),
999
- type: z.enum(["AMOUNT", "PERCENTAGE"]).optional(),
1000
- reason: z.enum(["exclusivity_lost", "zero_after_running_total"]).optional()
1001
- });
1002
- const validateOutput = z.object({
1003
- valid: z.boolean(),
1004
- code: z.string().optional(),
1005
- message: z.string().optional(),
1006
- preview: z.object({
1007
- amount: z.number().int(),
1008
- finalOrder: z.object({
1009
- amount: z.number().int(),
1010
- currency: z.string()
1011
- }),
1012
- breakdown: z.array(breakdownEntry)
1013
- }).optional()
1014
- });
1015
- const redeemOutput = z.object({
1016
- ok: z.boolean(),
1017
- redemptionId: z.string().uuid().optional(),
1018
- amount: z.number().int().optional(),
1019
- finalOrder: z.object({
1020
- amount: z.number().int(),
1021
- currency: z.string()
1022
- }).optional(),
1023
- breakdown: z.array(breakdownEntry).optional(),
1024
- idempotent: z.boolean().optional(),
1025
- code: z.string().optional(),
1026
- message: z.string().optional()
1027
- });
1028
- const stackRedeemInput = z.object({
1029
- codes: z.array(z.string().min(1)).min(1).max(20),
1030
- customerId: z.string().uuid().optional(),
1031
- orderId: z.string().uuid().optional(),
1032
- externalOrderId: z.string().min(1).max(120).optional(),
1033
- order: orderInput,
1034
- idempotencyKey: z.string().min(1).max(128).optional()
1035
- });
1036
- const stackEntry = z.object({
1037
- voucherCode: z.string(),
1038
- voucherId: z.string().uuid(),
1039
- redemptionId: z.string().uuid(),
1040
- amount: z.number().int()
1041
- });
1042
- const stackRedeemOutput = z.object({
1043
- ok: z.boolean(),
1044
- batchId: z.string().uuid().optional(),
1045
- amount: z.number().int().optional(),
1046
- finalOrder: z.object({
1047
- amount: z.number().int(),
1048
- currency: z.string()
1049
- }).optional(),
1050
- breakdown: z.array(breakdownEntry).optional(),
1051
- entries: z.array(stackEntry).optional(),
1052
- idempotent: z.boolean().optional(),
1053
- code: z.string().optional(),
1054
- message: z.string().optional()
1055
- });
1056
- //#endregion
1057
1285
  //#region ../contract/src/routes/vouchers.ts
1058
1286
  const vouchers = {
1059
1287
  list: oc.meta(mcpMeta({
@@ -1075,8 +1303,9 @@ const vouchers = {
1075
1303
  })).route({
1076
1304
  method: "GET",
1077
1305
  path: "/vouchers/{code}",
1078
- summary: "Get voucher by code"
1079
- }).input(z.object({ code: z.string() })).output(voucherOutput),
1306
+ summary: "Get voucher by code",
1307
+ inputStructure: "detailed"
1308
+ }).input(z.object({ params: z.object({ code: z.string() }) })).output(voucherOutput),
1080
1309
  create: oc.route({
1081
1310
  method: "POST",
1082
1311
  path: "/vouchers",
@@ -1085,16 +1314,18 @@ const vouchers = {
1085
1314
  update: oc.route({
1086
1315
  method: "PATCH",
1087
1316
  path: "/vouchers/{code}",
1088
- summary: "Update voucher"
1317
+ summary: "Update voucher",
1318
+ inputStructure: "detailed"
1089
1319
  }).input(z.object({
1090
- code: z.string(),
1091
- patch: voucherUpdateInput
1320
+ params: z.object({ code: z.string() }),
1321
+ body: z.object({ patch: voucherUpdateInput })
1092
1322
  })).output(voucherOutput),
1093
1323
  delete: oc.route({
1094
1324
  method: "DELETE",
1095
1325
  path: "/vouchers/{code}",
1096
- summary: "Soft-delete voucher"
1097
- }).input(z.object({ code: z.string() })).output(z.object({ ok: z.literal(true) })),
1326
+ summary: "Soft-delete voucher",
1327
+ inputStructure: "detailed"
1328
+ }).input(z.object({ params: z.object({ code: z.string() }) })).output(z.object({ ok: z.literal(true) })),
1098
1329
  bulk: oc.route({
1099
1330
  method: "POST",
1100
1331
  path: "/vouchers/bulk",
@@ -1110,8 +1341,20 @@ const vouchers = {
1110
1341
  })).route({
1111
1342
  method: "POST",
1112
1343
  path: "/vouchers/{code}/validate",
1113
- summary: "Validate a voucher against an optional order context"
1114
- }).input(validateInput).output(validateOutput),
1344
+ summary: "Validate a voucher against an optional order context",
1345
+ inputStructure: "detailed"
1346
+ }).input(z.object({
1347
+ params: z.object({ code: z.string().min(1) }),
1348
+ body: validateInput.omit({ code: true }).optional()
1349
+ })).output(validateOutput),
1350
+ qualify: oc.meta(mcpMeta({
1351
+ expose: true,
1352
+ riskLevel: "safe"
1353
+ })).route({
1354
+ method: "POST",
1355
+ path: "/vouchers/qualify",
1356
+ summary: "Batch-qualify customer-held voucher codes for an order"
1357
+ }).input(qualifyInput).output(qualifyOutput),
1115
1358
  redeem: oc.meta(mcpMeta({
1116
1359
  expose: true,
1117
1360
  riskLevel: "mutating",
@@ -1119,8 +1362,12 @@ const vouchers = {
1119
1362
  })).route({
1120
1363
  method: "POST",
1121
1364
  path: "/vouchers/{code}/redemption",
1122
- summary: "Redeem a voucher"
1123
- }).input(redeemInput).output(redeemOutput),
1365
+ summary: "Redeem a voucher",
1366
+ inputStructure: "detailed"
1367
+ }).input(z.object({
1368
+ params: z.object({ code: z.string().min(1) }),
1369
+ body: redeemInput.omit({ code: true }).optional()
1370
+ })).output(redeemOutput),
1124
1371
  stackRedeem: oc.meta(mcpMeta({
1125
1372
  expose: true,
1126
1373
  riskLevel: "mutating",
@@ -1133,8 +1380,9 @@ const vouchers = {
1133
1380
  transactions: oc.route({
1134
1381
  method: "GET",
1135
1382
  path: "/vouchers/{code}/transactions",
1136
- summary: "Gift card balance ledger"
1137
- }).input(z.object({ code: z.string() })).output(z.object({ data: z.array(z.object({
1383
+ summary: "Gift card balance ledger",
1384
+ inputStructure: "detailed"
1385
+ }).input(z.object({ params: z.object({ code: z.string() }) })).output(z.object({ data: z.array(z.object({
1138
1386
  id: z.string().uuid(),
1139
1387
  redemptionId: z.string().uuid().nullable(),
1140
1388
  delta: z.number().int(),
@@ -1212,8 +1460,9 @@ const webhooks$1 = {
1212
1460
  get: oc.route({
1213
1461
  method: "GET",
1214
1462
  path: "/webhooks/{id}",
1215
- summary: "Get webhook"
1216
- }).input(z.object({ id: z.string().uuid() })).output(webhookOutput),
1463
+ summary: "Get webhook",
1464
+ inputStructure: "detailed"
1465
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(webhookOutput),
1217
1466
  create: oc.route({
1218
1467
  method: "POST",
1219
1468
  path: "/webhooks",
@@ -1222,29 +1471,33 @@ const webhooks$1 = {
1222
1471
  update: oc.route({
1223
1472
  method: "PATCH",
1224
1473
  path: "/webhooks/{id}",
1225
- summary: "Update webhook"
1474
+ summary: "Update webhook",
1475
+ inputStructure: "detailed"
1226
1476
  }).input(z.object({
1227
- id: z.string().uuid(),
1228
- patch: webhookUpdateInput
1477
+ params: z.object({ id: z.string().uuid() }),
1478
+ body: z.object({ patch: webhookUpdateInput })
1229
1479
  })).output(webhookOutput),
1230
1480
  delete: oc.route({
1231
1481
  method: "DELETE",
1232
1482
  path: "/webhooks/{id}",
1233
- summary: "Soft-delete webhook"
1234
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ ok: z.literal(true) })),
1483
+ summary: "Soft-delete webhook",
1484
+ inputStructure: "detailed"
1485
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ ok: z.literal(true) })),
1235
1486
  deliveries: oc.route({
1236
1487
  method: "GET",
1237
1488
  path: "/webhooks/{id}/deliveries",
1238
- summary: "Recent deliveries for a webhook"
1489
+ summary: "Recent deliveries for a webhook",
1490
+ inputStructure: "detailed"
1239
1491
  }).input(z.object({
1240
- id: z.string().uuid(),
1241
- limit: z.number().int().min(1).max(100).default(50)
1492
+ params: z.object({ id: z.string().uuid() }),
1493
+ query: z.object({ limit: z.number().int().min(1).max(100).default(50) })
1242
1494
  })).output(z.object({ data: z.array(webhookDeliveryOutput) })),
1243
1495
  replay: oc.route({
1244
1496
  method: "POST",
1245
1497
  path: "/webhooks/deliveries/{id}/replay",
1246
- summary: "Re-enqueue a delivery (succeeded or otherwise)"
1247
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ ok: z.literal(true) }))
1498
+ summary: "Re-enqueue a delivery (succeeded or otherwise)",
1499
+ inputStructure: "detailed"
1500
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ ok: z.literal(true) }))
1248
1501
  };
1249
1502
  const events = {
1250
1503
  list: oc.route({
@@ -1255,8 +1508,9 @@ const events = {
1255
1508
  get: oc.route({
1256
1509
  method: "GET",
1257
1510
  path: "/events/{id}",
1258
- summary: "Get event"
1259
- }).input(z.object({ id: z.string().uuid() })).output(eventOutput)
1511
+ summary: "Get event",
1512
+ inputStructure: "detailed"
1513
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(eventOutput)
1260
1514
  };
1261
1515
  //#endregion
1262
1516
  //#region ../contract/src/routes/insights.ts
@@ -1335,26 +1589,30 @@ const users = {
1335
1589
  resetPassword: oc.route({
1336
1590
  method: "POST",
1337
1591
  path: "/users/{id}/reset-password",
1338
- summary: "Reset a staff user's password (admin)"
1339
- }).input(z.object({ id: z.string() })).output(userCreateOutput),
1592
+ summary: "Reset a staff user's password (admin)",
1593
+ inputStructure: "detailed"
1594
+ }).input(z.object({ params: z.object({ id: z.string() }) })).output(userCreateOutput),
1340
1595
  setRole: oc.route({
1341
1596
  method: "PATCH",
1342
1597
  path: "/users/{id}/role",
1343
- summary: "Change a staff user's role (admin)"
1598
+ summary: "Change a staff user's role (admin)",
1599
+ inputStructure: "detailed"
1344
1600
  }).input(z.object({
1345
- id: z.string(),
1346
- role: userRole
1601
+ params: z.object({ id: z.string() }),
1602
+ body: z.object({ role: userRole })
1347
1603
  })).output(userOutput),
1348
1604
  disable: oc.route({
1349
1605
  method: "POST",
1350
1606
  path: "/users/{id}/disable",
1351
- summary: "Disable a staff user (admin)"
1352
- }).input(z.object({ id: z.string() })).output(userOutput),
1607
+ summary: "Disable a staff user (admin)",
1608
+ inputStructure: "detailed"
1609
+ }).input(z.object({ params: z.object({ id: z.string() }) })).output(userOutput),
1353
1610
  enable: oc.route({
1354
1611
  method: "POST",
1355
1612
  path: "/users/{id}/enable",
1356
- summary: "Re-enable a staff user (admin)"
1357
- }).input(z.object({ id: z.string() })).output(userOutput)
1613
+ summary: "Re-enable a staff user (admin)",
1614
+ inputStructure: "detailed"
1615
+ }).input(z.object({ params: z.object({ id: z.string() }) })).output(userOutput)
1358
1616
  };
1359
1617
  //#endregion
1360
1618
  //#region ../contract/src/schemas/order.ts
@@ -1420,8 +1678,9 @@ const orders = {
1420
1678
  get: oc.route({
1421
1679
  method: "GET",
1422
1680
  path: "/orders/{id}",
1423
- summary: "Fetch one order"
1424
- }).input(z.object({ id: z.string().uuid() })).output(orderOutput),
1681
+ summary: "Fetch one order",
1682
+ inputStructure: "detailed"
1683
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(orderOutput),
1425
1684
  create: oc.route({
1426
1685
  method: "POST",
1427
1686
  path: "/orders",
@@ -1430,28 +1689,36 @@ const orders = {
1430
1689
  update: oc.route({
1431
1690
  method: "PATCH",
1432
1691
  path: "/orders/{id}",
1433
- summary: "Update an order"
1434
- }).input(orderUpdateInput).output(orderOutput),
1692
+ summary: "Update an order",
1693
+ inputStructure: "detailed"
1694
+ }).input(z.object({
1695
+ params: z.object({ id: z.string().uuid() }),
1696
+ body: orderUpdateInput.omit({ id: true })
1697
+ })).output(orderOutput),
1435
1698
  cancel: oc.route({
1436
1699
  method: "POST",
1437
1700
  path: "/orders/{id}/cancel",
1438
- summary: "Cancel an order"
1439
- }).input(z.object({ id: z.string().uuid() })).output(orderOutput),
1701
+ summary: "Cancel an order",
1702
+ inputStructure: "detailed"
1703
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(orderOutput),
1440
1704
  fulfill: oc.route({
1441
1705
  method: "POST",
1442
1706
  path: "/orders/{id}/fulfill",
1443
- summary: "Mark order fulfilled"
1444
- }).input(z.object({ id: z.string().uuid() })).output(orderOutput),
1707
+ summary: "Mark order fulfilled",
1708
+ inputStructure: "detailed"
1709
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(orderOutput),
1445
1710
  delete: oc.route({
1446
1711
  method: "DELETE",
1447
1712
  path: "/orders/{id}",
1448
- summary: "Soft-delete an order"
1449
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ ok: z.literal(true) })),
1713
+ summary: "Soft-delete an order",
1714
+ inputStructure: "detailed"
1715
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ ok: z.literal(true) })),
1450
1716
  redemptions: oc.route({
1451
1717
  method: "GET",
1452
1718
  path: "/orders/{id}/redemptions",
1453
- summary: "List redemptions attached to an order"
1454
- }).input(z.object({ id: z.string().uuid() })).output(z.object({ data: z.array(z.object({
1719
+ summary: "List redemptions attached to an order",
1720
+ inputStructure: "detailed"
1721
+ }).input(z.object({ params: z.object({ id: z.string().uuid() }) })).output(z.object({ data: z.array(z.object({
1455
1722
  id: z.string().uuid(),
1456
1723
  voucherCode: z.string(),
1457
1724
  voucherId: z.string().uuid(),
@@ -1556,6 +1823,7 @@ const contract = {
1556
1823
  customers,
1557
1824
  segments,
1558
1825
  campaigns,
1826
+ promotions,
1559
1827
  vouchers,
1560
1828
  validationRules,
1561
1829
  rewardTypes,