@classytic/promo 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/README.md +226 -22
  3. package/dist/{index-J5BC20DN.d.mts → constants-CrbSSQG5.d.mts} +1 -3
  4. package/dist/{constants-BVajdyL3.mjs → constants-D0Rntp2f.mjs} +1 -3
  5. package/dist/index.d.mts +763 -10
  6. package/dist/index.mjs +1721 -34
  7. package/dist/schemas/index.d.mts +253 -0
  8. package/dist/schemas/index.mjs +135 -0
  9. package/package.json +20 -35
  10. package/dist/config-iZjn_8pp.d.mts +0 -71
  11. package/dist/domain/enums/index.d.mts +0 -2
  12. package/dist/domain/enums/index.mjs +0 -2
  13. package/dist/domain/index.d.mts +0 -61
  14. package/dist/domain/index.mjs +0 -4
  15. package/dist/domain-errors-BEkXvy5O.mjs +0 -80
  16. package/dist/event-emitter.port-DaodlJSG.d.mts +0 -8
  17. package/dist/event-types-CsTV1FKX.mjs +0 -25
  18. package/dist/events/index.d.mts +0 -2
  19. package/dist/events/index.mjs +0 -3
  20. package/dist/events-CprEWlN7.mjs +0 -25
  21. package/dist/index-B7lLH19a.d.mts +0 -13
  22. package/dist/index-C52zSBkI.d.mts +0 -96
  23. package/dist/index-Cu9iwy4v.d.mts +0 -99
  24. package/dist/index-l09KqnlE.d.mts +0 -81
  25. package/dist/models/index.d.mts +0 -2
  26. package/dist/models/index.mjs +0 -2
  27. package/dist/models-DdBNae7h.mjs +0 -277
  28. package/dist/repositories/index.d.mts +0 -2
  29. package/dist/repositories/index.mjs +0 -2
  30. package/dist/repositories-DgZIY9wD.mjs +0 -295
  31. package/dist/results-Ca5ZCNbN.d.mts +0 -218
  32. package/dist/services/index.d.mts +0 -2
  33. package/dist/services/index.mjs +0 -2
  34. package/dist/services-Cz0gHrmX.mjs +0 -815
  35. package/dist/types/index.d.mts +0 -3
  36. package/dist/types/index.mjs +0 -1
  37. package/dist/unit-of-work.port-DaMW8WZK.d.mts +0 -7
  38. package/dist/voucher.port-yxfb3MHJ.d.mts +0 -146
@@ -0,0 +1,253 @@
1
+ import { a as PROGRAM_STATUSES, d as STACKING_MODES, h as VOUCHER_STATUSES, l as REWARD_TYPES, n as DISCOUNT_SCOPES, o as PROGRAM_TYPES, p as TRIGGER_MODES, t as DISCOUNT_MODES } from "../constants-CrbSSQG5.mjs";
2
+ import { z } from "zod";
3
+
4
+ //#region src/schemas/index.d.ts
5
+ declare const programCreateSchema: z.ZodObject<{
6
+ name: z.ZodString;
7
+ description: z.ZodOptional<z.ZodString>;
8
+ programType: z.ZodEnum<{
9
+ promotion: "promotion";
10
+ coupon: "coupon";
11
+ discount_code: "discount_code";
12
+ buy_x_get_y: "buy_x_get_y";
13
+ gift_card: "gift_card";
14
+ }>;
15
+ triggerMode: z.ZodEnum<{
16
+ auto: "auto";
17
+ code: "code";
18
+ }>;
19
+ stackingMode: z.ZodOptional<z.ZodEnum<{
20
+ exclusive: "exclusive";
21
+ stackable: "stackable";
22
+ }>>;
23
+ priority: z.ZodOptional<z.ZodNumber>;
24
+ startsAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
25
+ endsAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
26
+ maxUsageTotal: z.ZodOptional<z.ZodNumber>;
27
+ maxUsagePerCustomer: z.ZodOptional<z.ZodNumber>;
28
+ applicableCustomerIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
29
+ applicableCustomerTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
30
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
31
+ }, z.core.$strip>;
32
+ type ProgramCreateInput = z.infer<typeof programCreateSchema>;
33
+ declare const programUpdateSchema: z.ZodObject<{
34
+ name: z.ZodOptional<z.ZodString>;
35
+ description: z.ZodOptional<z.ZodOptional<z.ZodString>>;
36
+ programType: z.ZodOptional<z.ZodEnum<{
37
+ promotion: "promotion";
38
+ coupon: "coupon";
39
+ discount_code: "discount_code";
40
+ buy_x_get_y: "buy_x_get_y";
41
+ gift_card: "gift_card";
42
+ }>>;
43
+ triggerMode: z.ZodOptional<z.ZodEnum<{
44
+ auto: "auto";
45
+ code: "code";
46
+ }>>;
47
+ stackingMode: z.ZodOptional<z.ZodOptional<z.ZodEnum<{
48
+ exclusive: "exclusive";
49
+ stackable: "stackable";
50
+ }>>>;
51
+ priority: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
52
+ startsAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
53
+ endsAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
54
+ maxUsageTotal: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
55
+ maxUsagePerCustomer: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
56
+ applicableCustomerIds: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
57
+ applicableCustomerTags: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
58
+ metadata: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
59
+ }, z.core.$strip>;
60
+ type ProgramUpdateInput = z.infer<typeof programUpdateSchema>;
61
+ /** Body schema for `POST /:id/action { action: 'activate' | 'pause' | 'archive' }`. */
62
+ declare const programActionSchema: z.ZodObject<{
63
+ action: z.ZodEnum<{
64
+ activate: "activate";
65
+ pause: "pause";
66
+ archive: "archive";
67
+ }>;
68
+ }, z.core.$strip>;
69
+ type ProgramActionInput = z.infer<typeof programActionSchema>;
70
+ declare const ruleCreateSchema: z.ZodObject<{
71
+ name: z.ZodOptional<z.ZodString>;
72
+ minimumAmount: z.ZodOptional<z.ZodNumber>;
73
+ minimumQuantity: z.ZodOptional<z.ZodNumber>;
74
+ applicableProductIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
75
+ applicableCategories: z.ZodOptional<z.ZodArray<z.ZodString>>;
76
+ applicableSkus: z.ZodOptional<z.ZodArray<z.ZodString>>;
77
+ buyQuantity: z.ZodOptional<z.ZodNumber>;
78
+ code: z.ZodOptional<z.ZodString>;
79
+ startsAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
80
+ endsAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
81
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
82
+ }, z.core.$strip>;
83
+ type RuleCreateInput = z.infer<typeof ruleCreateSchema>;
84
+ declare const ruleUpdateSchema: z.ZodObject<{
85
+ name: z.ZodOptional<z.ZodOptional<z.ZodString>>;
86
+ minimumAmount: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
87
+ minimumQuantity: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
88
+ applicableProductIds: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
89
+ applicableCategories: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
90
+ applicableSkus: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
91
+ buyQuantity: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
92
+ code: z.ZodOptional<z.ZodOptional<z.ZodString>>;
93
+ startsAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
94
+ endsAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
95
+ metadata: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
96
+ }, z.core.$strip>;
97
+ type RuleUpdateInput = z.infer<typeof ruleUpdateSchema>;
98
+ declare const rewardCreateSchema: z.ZodObject<{
99
+ ruleId: z.ZodOptional<z.ZodString>;
100
+ rewardType: z.ZodEnum<{
101
+ discount: "discount";
102
+ free_product: "free_product";
103
+ }>;
104
+ discountMode: z.ZodOptional<z.ZodEnum<{
105
+ percentage: "percentage";
106
+ fixed: "fixed";
107
+ }>>;
108
+ discountAmount: z.ZodOptional<z.ZodNumber>;
109
+ maxDiscountAmount: z.ZodOptional<z.ZodNumber>;
110
+ discountScope: z.ZodOptional<z.ZodEnum<{
111
+ order: "order";
112
+ cheapest: "cheapest";
113
+ specific_products: "specific_products";
114
+ }>>;
115
+ applicableProductIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
116
+ freeProductId: z.ZodOptional<z.ZodString>;
117
+ freeProductSku: z.ZodOptional<z.ZodString>;
118
+ freeQuantity: z.ZodOptional<z.ZodNumber>;
119
+ giftCardAmount: z.ZodOptional<z.ZodNumber>;
120
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
121
+ }, z.core.$strip>;
122
+ type RewardCreateInput = z.infer<typeof rewardCreateSchema>;
123
+ declare const rewardUpdateSchema: z.ZodObject<{
124
+ ruleId: z.ZodOptional<z.ZodOptional<z.ZodString>>;
125
+ rewardType: z.ZodOptional<z.ZodEnum<{
126
+ discount: "discount";
127
+ free_product: "free_product";
128
+ }>>;
129
+ discountMode: z.ZodOptional<z.ZodOptional<z.ZodEnum<{
130
+ percentage: "percentage";
131
+ fixed: "fixed";
132
+ }>>>;
133
+ discountAmount: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
134
+ maxDiscountAmount: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
135
+ discountScope: z.ZodOptional<z.ZodOptional<z.ZodEnum<{
136
+ order: "order";
137
+ cheapest: "cheapest";
138
+ specific_products: "specific_products";
139
+ }>>>;
140
+ applicableProductIds: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
141
+ freeProductId: z.ZodOptional<z.ZodOptional<z.ZodString>>;
142
+ freeProductSku: z.ZodOptional<z.ZodOptional<z.ZodString>>;
143
+ freeQuantity: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
144
+ giftCardAmount: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
145
+ metadata: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
146
+ }, z.core.$strip>;
147
+ type RewardUpdateInput = z.infer<typeof rewardUpdateSchema>;
148
+ declare const voucherGenerateBatchSchema: z.ZodObject<{
149
+ programId: z.ZodString;
150
+ count: z.ZodNumber;
151
+ customerId: z.ZodOptional<z.ZodString>;
152
+ expiresAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
153
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
154
+ }, z.core.$strip>;
155
+ type VoucherGenerateBatchInput = z.infer<typeof voucherGenerateBatchSchema>;
156
+ declare const voucherGenerateSingleSchema: z.ZodObject<{
157
+ programId: z.ZodString;
158
+ code: z.ZodOptional<z.ZodString>;
159
+ customerId: z.ZodOptional<z.ZodString>;
160
+ expiresAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
161
+ initialBalance: z.ZodOptional<z.ZodNumber>;
162
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
163
+ }, z.core.$strip>;
164
+ type VoucherGenerateSingleInput = z.infer<typeof voucherGenerateSingleSchema>;
165
+ declare const voucherRedeemSchema: z.ZodObject<{
166
+ code: z.ZodString;
167
+ orderId: z.ZodString;
168
+ customerId: z.ZodOptional<z.ZodString>;
169
+ discountAmount: z.ZodNumber;
170
+ idempotencyKey: z.ZodOptional<z.ZodString>;
171
+ }, z.core.$strip>;
172
+ type VoucherRedeemInput = z.infer<typeof voucherRedeemSchema>;
173
+ declare const giftCardSpendSchema: z.ZodObject<{
174
+ code: z.ZodString;
175
+ amount: z.ZodNumber;
176
+ orderId: z.ZodString;
177
+ description: z.ZodOptional<z.ZodString>;
178
+ idempotencyKey: z.ZodOptional<z.ZodString>;
179
+ }, z.core.$strip>;
180
+ type GiftCardSpendInput = z.infer<typeof giftCardSpendSchema>;
181
+ declare const giftCardTopUpSchema: z.ZodObject<{
182
+ code: z.ZodString;
183
+ amount: z.ZodNumber;
184
+ description: z.ZodOptional<z.ZodString>;
185
+ idempotencyKey: z.ZodOptional<z.ZodString>;
186
+ }, z.core.$strip>;
187
+ type GiftCardTopUpInput = z.infer<typeof giftCardTopUpSchema>;
188
+ declare const cartItemSchema: z.ZodObject<{
189
+ productId: z.ZodString;
190
+ sku: z.ZodOptional<z.ZodString>;
191
+ categoryId: z.ZodOptional<z.ZodString>;
192
+ quantity: z.ZodNumber;
193
+ unitPrice: z.ZodNumber;
194
+ lineTotal: z.ZodOptional<z.ZodNumber>;
195
+ }, z.core.$strip>;
196
+ type CartItemInput = z.infer<typeof cartItemSchema>;
197
+ declare const evaluateSchema: z.ZodObject<{
198
+ items: z.ZodArray<z.ZodObject<{
199
+ productId: z.ZodString;
200
+ sku: z.ZodOptional<z.ZodString>;
201
+ categoryId: z.ZodOptional<z.ZodString>;
202
+ quantity: z.ZodNumber;
203
+ unitPrice: z.ZodNumber;
204
+ lineTotal: z.ZodOptional<z.ZodNumber>;
205
+ }, z.core.$strip>>;
206
+ subtotal: z.ZodNumber;
207
+ codes: z.ZodOptional<z.ZodArray<z.ZodString>>;
208
+ customerId: z.ZodOptional<z.ZodString>;
209
+ customerTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
210
+ }, z.core.$strip>;
211
+ type EvaluateInputSchema = z.infer<typeof evaluateSchema>;
212
+ declare const commitEvaluationSchema: z.ZodObject<{
213
+ orderId: z.ZodString;
214
+ }, z.core.$strip>;
215
+ type CommitEvaluationInput = z.infer<typeof commitEvaluationSchema>;
216
+ declare const programListFilterSchema: z.ZodObject<{
217
+ programType: z.ZodOptional<z.ZodEnum<{
218
+ promotion: "promotion";
219
+ coupon: "coupon";
220
+ discount_code: "discount_code";
221
+ buy_x_get_y: "buy_x_get_y";
222
+ gift_card: "gift_card";
223
+ }>>;
224
+ status: z.ZodOptional<z.ZodEnum<{
225
+ draft: "draft";
226
+ active: "active";
227
+ paused: "paused";
228
+ expired: "expired";
229
+ archived: "archived";
230
+ }>>;
231
+ triggerMode: z.ZodOptional<z.ZodEnum<{
232
+ auto: "auto";
233
+ code: "code";
234
+ }>>;
235
+ stackingMode: z.ZodOptional<z.ZodEnum<{
236
+ exclusive: "exclusive";
237
+ stackable: "stackable";
238
+ }>>;
239
+ }, z.core.$strip>;
240
+ type ProgramListFilterInput = z.infer<typeof programListFilterSchema>;
241
+ declare const voucherListFilterSchema: z.ZodObject<{
242
+ programId: z.ZodOptional<z.ZodString>;
243
+ status: z.ZodOptional<z.ZodEnum<{
244
+ active: "active";
245
+ expired: "expired";
246
+ used: "used";
247
+ cancelled: "cancelled";
248
+ }>>;
249
+ customerId: z.ZodOptional<z.ZodString>;
250
+ }, z.core.$strip>;
251
+ type VoucherListFilterInput = z.infer<typeof voucherListFilterSchema>;
252
+ //#endregion
253
+ export { CartItemInput, CommitEvaluationInput, DISCOUNT_MODES, DISCOUNT_SCOPES, EvaluateInputSchema, GiftCardSpendInput, GiftCardTopUpInput, PROGRAM_STATUSES, PROGRAM_TYPES, ProgramActionInput, ProgramCreateInput, ProgramListFilterInput, ProgramUpdateInput, REWARD_TYPES, RewardCreateInput, RewardUpdateInput, RuleCreateInput, RuleUpdateInput, STACKING_MODES, TRIGGER_MODES, VOUCHER_STATUSES, VoucherGenerateBatchInput, VoucherGenerateSingleInput, VoucherListFilterInput, VoucherRedeemInput, cartItemSchema, commitEvaluationSchema, evaluateSchema, giftCardSpendSchema, giftCardTopUpSchema, programActionSchema, programCreateSchema, programListFilterSchema, programUpdateSchema, rewardCreateSchema, rewardUpdateSchema, ruleCreateSchema, ruleUpdateSchema, voucherGenerateBatchSchema, voucherGenerateSingleSchema, voucherListFilterSchema, voucherRedeemSchema };
@@ -0,0 +1,135 @@
1
+ import { a as PROGRAM_TYPES, c as TRIGGER_MODES, l as VOUCHER_STATUSES, n as DISCOUNT_SCOPES, o as REWARD_TYPES, r as PROGRAM_STATUSES, s as STACKING_MODES, t as DISCOUNT_MODES } from "../constants-D0Rntp2f.mjs";
2
+ import { z } from "zod";
3
+ //#region src/schemas/index.ts
4
+ /**
5
+ * Zod v4 schemas — single source of truth for runtime validation + Arc OpenAPI.
6
+ *
7
+ * Import from `@classytic/promo/schemas`. Arc hosts wire these into
8
+ * `defineResource({ body: programCreateSchema })` and
9
+ * `actions: { generate: { schema: voucherGenerateSchema } }`.
10
+ *
11
+ * Shape mirrors the TypeScript input types in `src/types/inputs.ts`.
12
+ * Changes here must stay in sync — the types are inferred via `z.infer<>`.
13
+ */
14
+ const metadataSchema = z.record(z.string(), z.unknown()).optional();
15
+ const nonEmptyString = z.string().min(1);
16
+ const optionalStringArray = z.array(z.string()).optional();
17
+ const nonNegativeInt = z.number().int().min(0);
18
+ z.number().min(0).max(100);
19
+ /** Currency amount in smallest unit (paisa for BDT, cents for USD). */
20
+ const paisaAmount = z.number().int().min(0);
21
+ const programCreateSchema = z.object({
22
+ name: nonEmptyString,
23
+ description: z.string().optional(),
24
+ programType: z.enum(PROGRAM_TYPES),
25
+ triggerMode: z.enum(TRIGGER_MODES),
26
+ stackingMode: z.enum(STACKING_MODES).optional(),
27
+ priority: z.number().int().optional(),
28
+ startsAt: z.coerce.date().optional(),
29
+ endsAt: z.coerce.date().optional(),
30
+ maxUsageTotal: z.number().int().positive().optional(),
31
+ maxUsagePerCustomer: z.number().int().positive().optional(),
32
+ applicableCustomerIds: optionalStringArray,
33
+ applicableCustomerTags: optionalStringArray,
34
+ metadata: metadataSchema
35
+ });
36
+ const programUpdateSchema = programCreateSchema.partial();
37
+ /** Body schema for `POST /:id/action { action: 'activate' | 'pause' | 'archive' }`. */
38
+ const programActionSchema = z.object({ action: z.enum([
39
+ "activate",
40
+ "pause",
41
+ "archive"
42
+ ]) });
43
+ const ruleCreateSchema = z.object({
44
+ name: z.string().optional(),
45
+ minimumAmount: nonNegativeInt.optional(),
46
+ minimumQuantity: nonNegativeInt.optional(),
47
+ applicableProductIds: optionalStringArray,
48
+ applicableCategories: optionalStringArray,
49
+ applicableSkus: optionalStringArray,
50
+ buyQuantity: z.number().int().positive().optional(),
51
+ code: z.string().optional(),
52
+ startsAt: z.coerce.date().optional(),
53
+ endsAt: z.coerce.date().optional(),
54
+ metadata: metadataSchema
55
+ });
56
+ const ruleUpdateSchema = ruleCreateSchema.partial();
57
+ const rewardCreateSchema = z.object({
58
+ ruleId: z.string().optional(),
59
+ rewardType: z.enum(REWARD_TYPES),
60
+ discountMode: z.enum(DISCOUNT_MODES).optional(),
61
+ discountAmount: z.number().min(0).optional(),
62
+ maxDiscountAmount: paisaAmount.optional(),
63
+ discountScope: z.enum(DISCOUNT_SCOPES).optional(),
64
+ applicableProductIds: optionalStringArray,
65
+ freeProductId: z.string().optional(),
66
+ freeProductSku: z.string().optional(),
67
+ freeQuantity: z.number().int().positive().optional(),
68
+ giftCardAmount: paisaAmount.optional(),
69
+ metadata: metadataSchema
70
+ });
71
+ const rewardUpdateSchema = rewardCreateSchema.partial();
72
+ const voucherGenerateBatchSchema = z.object({
73
+ programId: nonEmptyString,
74
+ count: z.number().int().positive().max(1e4),
75
+ customerId: z.string().optional(),
76
+ expiresAt: z.coerce.date().optional(),
77
+ metadata: metadataSchema
78
+ });
79
+ const voucherGenerateSingleSchema = z.object({
80
+ programId: nonEmptyString,
81
+ code: z.string().optional(),
82
+ customerId: z.string().optional(),
83
+ expiresAt: z.coerce.date().optional(),
84
+ initialBalance: paisaAmount.optional(),
85
+ metadata: metadataSchema
86
+ });
87
+ const voucherRedeemSchema = z.object({
88
+ code: nonEmptyString,
89
+ orderId: nonEmptyString,
90
+ customerId: z.string().optional(),
91
+ discountAmount: paisaAmount,
92
+ idempotencyKey: z.string().optional()
93
+ });
94
+ const giftCardSpendSchema = z.object({
95
+ code: nonEmptyString,
96
+ amount: z.number().int().positive(),
97
+ orderId: nonEmptyString,
98
+ description: z.string().optional(),
99
+ idempotencyKey: z.string().optional()
100
+ });
101
+ const giftCardTopUpSchema = z.object({
102
+ code: nonEmptyString,
103
+ amount: z.number().int().positive(),
104
+ description: z.string().optional(),
105
+ idempotencyKey: z.string().optional()
106
+ });
107
+ const cartItemSchema = z.object({
108
+ productId: nonEmptyString,
109
+ sku: z.string().optional(),
110
+ categoryId: z.string().optional(),
111
+ quantity: z.number().positive(),
112
+ unitPrice: z.number().min(0),
113
+ lineTotal: z.number().min(0).optional()
114
+ });
115
+ const evaluateSchema = z.object({
116
+ items: z.array(cartItemSchema).min(1),
117
+ subtotal: z.number().min(0),
118
+ codes: optionalStringArray,
119
+ customerId: z.string().optional(),
120
+ customerTags: optionalStringArray
121
+ });
122
+ const commitEvaluationSchema = z.object({ orderId: nonEmptyString });
123
+ const programListFilterSchema = z.object({
124
+ programType: z.enum(PROGRAM_TYPES).optional(),
125
+ status: z.enum(PROGRAM_STATUSES).optional(),
126
+ triggerMode: z.enum(TRIGGER_MODES).optional(),
127
+ stackingMode: z.enum(STACKING_MODES).optional()
128
+ });
129
+ const voucherListFilterSchema = z.object({
130
+ programId: z.string().optional(),
131
+ status: z.enum(VOUCHER_STATUSES).optional(),
132
+ customerId: z.string().optional()
133
+ });
134
+ //#endregion
135
+ export { DISCOUNT_MODES, DISCOUNT_SCOPES, PROGRAM_STATUSES, PROGRAM_TYPES, REWARD_TYPES, STACKING_MODES, TRIGGER_MODES, VOUCHER_STATUSES, cartItemSchema, commitEvaluationSchema, evaluateSchema, giftCardSpendSchema, giftCardTopUpSchema, programActionSchema, programCreateSchema, programListFilterSchema, programUpdateSchema, rewardCreateSchema, rewardUpdateSchema, ruleCreateSchema, ruleUpdateSchema, voucherGenerateBatchSchema, voucherGenerateSingleSchema, voucherListFilterSchema, voucherRedeemSchema };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/promo",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Production-grade promotion, coupon, and discount engine for MongoDB — programs, rules, rewards, vouchers, gift cards, buy-x-get-y",
5
5
  "author": "Classytic",
6
6
  "homepage": "https://www.npmjs.com/package/@classytic/promo",
@@ -24,33 +24,9 @@
24
24
  "types": "./dist/index.d.mts",
25
25
  "default": "./dist/index.mjs"
26
26
  },
27
- "./domain": {
28
- "types": "./dist/domain/index.d.mts",
29
- "default": "./dist/domain/index.mjs"
30
- },
31
- "./domain/enums": {
32
- "types": "./dist/domain/enums/index.d.mts",
33
- "default": "./dist/domain/enums/index.mjs"
34
- },
35
- "./models": {
36
- "types": "./dist/models/index.d.mts",
37
- "default": "./dist/models/index.mjs"
38
- },
39
- "./repositories": {
40
- "types": "./dist/repositories/index.d.mts",
41
- "default": "./dist/repositories/index.mjs"
42
- },
43
- "./services": {
44
- "types": "./dist/services/index.d.mts",
45
- "default": "./dist/services/index.mjs"
46
- },
47
- "./events": {
48
- "types": "./dist/events/index.d.mts",
49
- "default": "./dist/events/index.mjs"
50
- },
51
- "./types": {
52
- "types": "./dist/types/index.d.mts",
53
- "default": "./dist/types/index.mjs"
27
+ "./schemas": {
28
+ "types": "./dist/schemas/index.d.mts",
29
+ "default": "./dist/schemas/index.mjs"
54
30
  }
55
31
  },
56
32
  "main": "./dist/index.mjs",
@@ -64,8 +40,11 @@
64
40
  "scripts": {
65
41
  "build": "tsdown",
66
42
  "dev": "tsdown --watch",
67
- "test": "vitest run",
68
- "test:watch": "vitest",
43
+ "test": "vitest run --project unit --project integration",
44
+ "test:unit": "vitest run --project unit",
45
+ "test:integration": "vitest run --project integration",
46
+ "test:all": "vitest run",
47
+ "test:watch": "vitest --project unit --project integration",
69
48
  "test:coverage": "vitest run --coverage",
70
49
  "typecheck": "tsc --noEmit",
71
50
  "lint": "biome check src/ tests/",
@@ -76,20 +55,26 @@
76
55
  "release": "npm run build && npm run typecheck && npm publish --access public"
77
56
  },
78
57
  "peerDependencies": {
79
- "@classytic/mongokit": ">=3.5.3",
80
- "mongoose": ">=9.0.0"
58
+ "@classytic/mongokit": ">=3.11.0",
59
+ "@classytic/primitives": ">=0.1.0",
60
+ "@classytic/repo-core": ">=0.2.0",
61
+ "mongoose": ">=9.4.1",
62
+ "zod": ">=4.0.0"
81
63
  },
82
64
  "devDependencies": {
83
65
  "@biomejs/biome": "^2.4.9",
84
- "@classytic/mongokit": "^3.5.3",
66
+ "@classytic/mongokit": ">=3.11.0",
67
+ "@classytic/primitives": ">=0.1.0",
68
+ "@classytic/repo-core": ">=0.2.0",
85
69
  "@types/node": "^25.5.0",
86
70
  "@vitest/coverage-v8": "^3.2.4",
87
71
  "knip": "^6.3.0",
88
72
  "mongodb-memory-server": "^10.2.3",
89
- "mongoose": "^9.3.3",
73
+ "mongoose": "^9.4.1",
90
74
  "tsdown": "^0.21.5",
91
75
  "typescript": "^5.7.0",
92
- "vitest": "^3.0.0"
76
+ "vitest": "^3.0.0",
77
+ "zod": "^4.3.6"
93
78
  },
94
79
  "keywords": [
95
80
  "promotion",
@@ -1,71 +0,0 @@
1
- import { t as EventEmitterPort } from "./event-emitter.port-DaodlJSG.mjs";
2
- import { Connection } from "mongoose";
3
- import { PluginType } from "@classytic/mongokit";
4
-
5
- //#region src/types/config.d.ts
6
- interface TenantEnabled {
7
- field?: string;
8
- ref?: string;
9
- type?: 'ObjectId' | 'string';
10
- contextKey?: string;
11
- }
12
- type TenantConfig = false | TenantEnabled;
13
- interface IndexDefinition {
14
- fields: Record<string, 1 | -1>;
15
- options?: Record<string, unknown>;
16
- }
17
- type ModelName = 'program' | 'rule' | 'reward' | 'voucher';
18
- type PluginType$1 = PluginType;
19
- interface RepositoryPlugins {
20
- program?: PluginType[];
21
- rule?: PluginType[];
22
- reward?: PluginType[];
23
- voucher?: PluginType[];
24
- }
25
- interface PromoConfig {
26
- mongoose: Connection;
27
- tenant?: TenantConfig;
28
- evaluation?: {
29
- maxStackablePromotions?: number;
30
- allowExclusiveAndStackable?: boolean;
31
- };
32
- voucher?: {
33
- codeLength?: number;
34
- codePrefix?: string;
35
- defaultExpiryDays?: number;
36
- };
37
- giftCard?: {
38
- allowNegativeBalance?: boolean;
39
- maxBalance?: number;
40
- };
41
- indexes?: Partial<Record<ModelName, IndexDefinition[]>>;
42
- events?: {
43
- adapter?: EventEmitterPort;
44
- };
45
- plugins?: RepositoryPlugins;
46
- }
47
- interface ResolvedTenant {
48
- enabled: boolean;
49
- field: string;
50
- ref?: string;
51
- type: 'ObjectId' | 'string';
52
- contextKey: string;
53
- }
54
- interface ResolvedConfig {
55
- evaluation: {
56
- maxStackablePromotions: number;
57
- allowExclusiveAndStackable: boolean;
58
- };
59
- voucher: {
60
- codeLength: number;
61
- codePrefix: string;
62
- defaultExpiryDays: number | null;
63
- };
64
- giftCard: {
65
- allowNegativeBalance: boolean;
66
- maxBalance: number | null;
67
- };
68
- tenant: ResolvedTenant;
69
- }
70
- //#endregion
71
- export { RepositoryPlugins as a, TenantConfig as c, PromoConfig as i, ModelName as n, ResolvedConfig as o, PluginType$1 as r, ResolvedTenant as s, IndexDefinition as t };
@@ -1,2 +0,0 @@
1
- import { a as RewardType, c as VoucherStatus, d as PROGRAM_STATUSES, f as PROGRAM_TYPES, g as VOUCHER_STATUSES, h as TRIGGER_MODES, i as ProgramType, l as DISCOUNT_MODES, m as STACKING_MODES, n as DiscountScope, o as StackingMode, p as REWARD_TYPES, r as ProgramStatus, s as TriggerMode, t as DiscountMode, u as DISCOUNT_SCOPES } from "../../index-J5BC20DN.mjs";
2
- export { DISCOUNT_MODES, DISCOUNT_SCOPES, DiscountMode, DiscountScope, PROGRAM_STATUSES, PROGRAM_TYPES, ProgramStatus, ProgramType, REWARD_TYPES, RewardType, STACKING_MODES, StackingMode, TRIGGER_MODES, TriggerMode, VOUCHER_STATUSES, VoucherStatus };
@@ -1,2 +0,0 @@
1
- import { a as PROGRAM_STATUSES, c as REWARD_TYPES, d as VOUCHER_STATUSES, i as DISCOUNT_SCOPES, l as STACKING_MODES, r as DISCOUNT_MODES, s as PROGRAM_TYPES, u as TRIGGER_MODES } from "../../constants-BVajdyL3.mjs";
2
- export { DISCOUNT_MODES, DISCOUNT_SCOPES, PROGRAM_STATUSES, PROGRAM_TYPES, REWARD_TYPES, STACKING_MODES, TRIGGER_MODES, VOUCHER_STATUSES };
@@ -1,61 +0,0 @@
1
- import { a as RewardType, c as VoucherStatus, d as PROGRAM_STATUSES, f as PROGRAM_TYPES, g as VOUCHER_STATUSES, h as TRIGGER_MODES, i as ProgramType, l as DISCOUNT_MODES, m as STACKING_MODES, n as DiscountScope, o as StackingMode, p as REWARD_TYPES, r as ProgramStatus, s as TriggerMode, t as DiscountMode, u as DISCOUNT_SCOPES } from "../index-J5BC20DN.mjs";
2
- import { a as BalanceLedgerEntry, c as Rule, i as ProgramPort, l as Reward, n as RulePort, o as Voucher, r as RewardPort, s as VoucherRedemption, t as VoucherPort, u as Program } from "../voucher.port-yxfb3MHJ.mjs";
3
- import { t as EventEmitterPort } from "../event-emitter.port-DaodlJSG.mjs";
4
- import { n as UnitOfWork, t as TransactionSession } from "../unit-of-work.port-DaMW8WZK.mjs";
5
-
6
- //#region src/domain/errors/base.d.ts
7
- declare abstract class PromoError extends Error {
8
- abstract readonly code: string;
9
- constructor(message: string);
10
- }
11
- //#endregion
12
- //#region src/domain/errors/domain-errors.d.ts
13
- declare class ValidationError extends PromoError {
14
- readonly code = "VALIDATION_ERROR";
15
- }
16
- declare class ProgramNotFoundError extends PromoError {
17
- readonly code = "PROGRAM_NOT_FOUND";
18
- constructor(id?: string);
19
- }
20
- declare class RuleNotFoundError extends PromoError {
21
- readonly code = "RULE_NOT_FOUND";
22
- constructor(id?: string);
23
- }
24
- declare class RewardNotFoundError extends PromoError {
25
- readonly code = "REWARD_NOT_FOUND";
26
- constructor(id?: string);
27
- }
28
- declare class VoucherNotFoundError extends PromoError {
29
- readonly code = "VOUCHER_NOT_FOUND";
30
- constructor(codeOrId?: string);
31
- }
32
- declare class InvalidTransitionError extends PromoError {
33
- readonly code = "INVALID_TRANSITION";
34
- constructor(from: string, to: string);
35
- }
36
- declare class VoucherExpiredError extends PromoError {
37
- readonly code = "VOUCHER_EXPIRED";
38
- constructor(code: string);
39
- }
40
- declare class VoucherExhaustedError extends PromoError {
41
- readonly code = "VOUCHER_EXHAUSTED";
42
- constructor(code: string);
43
- }
44
- declare class InsufficientBalanceError extends PromoError {
45
- readonly code = "INSUFFICIENT_BALANCE";
46
- constructor(code: string, available: number, requested: number);
47
- }
48
- declare class TenantIsolationError extends PromoError {
49
- readonly code = "TENANT_ISOLATION";
50
- constructor();
51
- }
52
- declare class DuplicateRedemptionError extends PromoError {
53
- readonly code = "DUPLICATE_REDEMPTION";
54
- constructor(key: string);
55
- }
56
- declare class EvaluationNotFoundError extends PromoError {
57
- readonly code = "EVALUATION_NOT_FOUND";
58
- constructor(id: string);
59
- }
60
- //#endregion
61
- export { BalanceLedgerEntry, DISCOUNT_MODES, DISCOUNT_SCOPES, DiscountMode, DiscountScope, DuplicateRedemptionError, EvaluationNotFoundError, EventEmitterPort, InsufficientBalanceError, InvalidTransitionError, PROGRAM_STATUSES, PROGRAM_TYPES, Program, ProgramNotFoundError, ProgramPort, ProgramStatus, ProgramType, PromoError, REWARD_TYPES, Reward, RewardNotFoundError, RewardPort, RewardType, Rule, RuleNotFoundError, RulePort, STACKING_MODES, StackingMode, TRIGGER_MODES, TenantIsolationError, TransactionSession, TriggerMode, UnitOfWork, VOUCHER_STATUSES, ValidationError, Voucher, VoucherExhaustedError, VoucherExpiredError, VoucherNotFoundError, VoucherPort, VoucherRedemption, VoucherStatus };
@@ -1,4 +0,0 @@
1
- import { a as PROGRAM_STATUSES, c as REWARD_TYPES, d as VOUCHER_STATUSES, i as DISCOUNT_SCOPES, l as STACKING_MODES, r as DISCOUNT_MODES, s as PROGRAM_TYPES, u as TRIGGER_MODES } from "../constants-BVajdyL3.mjs";
2
- import { a as ProgramNotFoundError, c as TenantIsolationError, d as VoucherExpiredError, f as VoucherNotFoundError, i as InvalidTransitionError, l as ValidationError, n as EvaluationNotFoundError, o as RewardNotFoundError, p as PromoError, r as InsufficientBalanceError, s as RuleNotFoundError, t as DuplicateRedemptionError, u as VoucherExhaustedError } from "../domain-errors-BEkXvy5O.mjs";
3
- import "./enums/index.mjs";
4
- export { DISCOUNT_MODES, DISCOUNT_SCOPES, DuplicateRedemptionError, EvaluationNotFoundError, InsufficientBalanceError, InvalidTransitionError, PROGRAM_STATUSES, PROGRAM_TYPES, ProgramNotFoundError, PromoError, REWARD_TYPES, RewardNotFoundError, RuleNotFoundError, STACKING_MODES, TRIGGER_MODES, TenantIsolationError, VOUCHER_STATUSES, ValidationError, VoucherExhaustedError, VoucherExpiredError, VoucherNotFoundError };