@zyacreatives/shared 2.2.95 → 2.2.97

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.
@@ -191,6 +191,12 @@ export declare const JOB_STATUS: {
191
191
  readonly ARCHIVED: "ARCHIVED";
192
192
  readonly DELETED: "DELETED";
193
193
  };
194
+ export declare const PRODUCT_STATUS: {
195
+ readonly ACTIVE: "ACTIVE";
196
+ readonly DRAFT: "DRAFT";
197
+ readonly ARCHIVED: "ARCHIVED";
198
+ readonly DELETED: "DELETED";
199
+ };
194
200
  export declare const MESSAGE_REQUEST_STATUS: {
195
201
  readonly PENDING: "PENDING";
196
202
  readonly ACCEPTED: "ACCEPTED";
@@ -299,6 +305,7 @@ export type PostBadgeType = (typeof POST_BADGE_TYPES)[keyof typeof POST_BADGE_TY
299
305
  export type JobSections = (typeof JOB_SECTIONS)[keyof typeof JOB_SECTIONS];
300
306
  export type WagesCurrency = (typeof WAGES_CURRENCY)[keyof typeof WAGES_CURRENCY];
301
307
  export type JobStatus = (typeof JOB_STATUS)[keyof typeof JOB_STATUS];
308
+ export type ProductStatus = (typeof PRODUCT_STATUS)[keyof typeof PRODUCT_STATUS];
302
309
  export type Role = (typeof ROLES)[keyof typeof ROLES];
303
310
  export type JobType = (typeof JOB_TYPE)[keyof typeof JOB_TYPE];
304
311
  export type WorkMode = (typeof WORK_MODE)[keyof typeof WORK_MODE];
package/dist/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ANALYTICS_EVENTS = exports.DEFAULT_DISCIPLINES = exports.API_ROUTES = exports.DISCOUNT_TYPES = exports.PRICING_MODELS = exports.GATEWAY_PROVIDER = exports.COUNTRY_OF_OPERATION = exports.SIGNAL_STATUS = exports.SIGNAL_INTEREST_TYPES = exports.VENTURE_STAGES = exports.NOTIFICATION_TYPES = exports.APPLICATION_STATUS = exports.LINK_TYPES = exports.ACTIVITY_TYPES = exports.POST_BADGE_TYPES = exports.PROJECT_STATUS = exports.MESSAGE_REQUEST_STATUS = exports.JOB_STATUS = exports.WAGES_CURRENCY = exports.GIG_TYPE = exports.MESSAGE_TYPES = exports.JOB_LOCATIONS = exports.JOB_SECTIONS = exports.WAGE_TYPES = exports.JOB_AVAILABILITY_TYPES = exports.EMPLOYMENT_TYPE = exports.WORK_MODE = exports.JOB_TYPE = exports.POST_TYPES = exports.ACTIVITY_PARENT_TYPES = exports.INVESTOR_VERIFICATION_DOCUMENT_TYPES = exports.INVESTOR_VERIFICATION_DOCUMENT_STATUSES = exports.GEOGRAPHIC_FOCUS = exports.INVESTMENT_SIZES = exports.INVESTOR_TYPES = exports.ONBOARDING_PAGES = exports.PAYMENT_METHOD_STATUS = exports.SELLER_STATUS = exports.EXPERIENCE_LEVELS = exports.CLIENT_TYPES = exports.USER_STATUSES = exports.ROLES = void 0;
3
+ exports.ANALYTICS_EVENTS = exports.DEFAULT_DISCIPLINES = exports.API_ROUTES = exports.DISCOUNT_TYPES = exports.PRICING_MODELS = exports.GATEWAY_PROVIDER = exports.COUNTRY_OF_OPERATION = exports.SIGNAL_STATUS = exports.SIGNAL_INTEREST_TYPES = exports.VENTURE_STAGES = exports.NOTIFICATION_TYPES = exports.APPLICATION_STATUS = exports.LINK_TYPES = exports.ACTIVITY_TYPES = exports.POST_BADGE_TYPES = exports.PROJECT_STATUS = exports.MESSAGE_REQUEST_STATUS = exports.PRODUCT_STATUS = exports.JOB_STATUS = exports.WAGES_CURRENCY = exports.GIG_TYPE = exports.MESSAGE_TYPES = exports.JOB_LOCATIONS = exports.JOB_SECTIONS = exports.WAGE_TYPES = exports.JOB_AVAILABILITY_TYPES = exports.EMPLOYMENT_TYPE = exports.WORK_MODE = exports.JOB_TYPE = exports.POST_TYPES = exports.ACTIVITY_PARENT_TYPES = exports.INVESTOR_VERIFICATION_DOCUMENT_TYPES = exports.INVESTOR_VERIFICATION_DOCUMENT_STATUSES = exports.GEOGRAPHIC_FOCUS = exports.INVESTMENT_SIZES = exports.INVESTOR_TYPES = exports.ONBOARDING_PAGES = exports.PAYMENT_METHOD_STATUS = exports.SELLER_STATUS = exports.EXPERIENCE_LEVELS = exports.CLIENT_TYPES = exports.USER_STATUSES = exports.ROLES = void 0;
4
4
  exports.ROLES = {
5
5
  CREATIVE: "CREATIVE",
6
6
  BRAND: "BRAND",
@@ -189,6 +189,7 @@ exports.JOB_STATUS = {
189
189
  ARCHIVED: "ARCHIVED",
190
190
  DELETED: "DELETED",
191
191
  };
192
+ exports.PRODUCT_STATUS = exports.JOB_STATUS;
192
193
  exports.MESSAGE_REQUEST_STATUS = {
193
194
  PENDING: "PENDING",
194
195
  ACCEPTED: "ACCEPTED",
@@ -37,6 +37,12 @@ export declare const BaseProductSchema: z.ZodObject<{
37
37
  createdAt: z.ZodDate;
38
38
  updatedAt: z.ZodDate;
39
39
  deletedAt: z.ZodNullable<z.ZodDate>;
40
+ status: z.ZodDefault<z.ZodEnum<{
41
+ readonly ACTIVE: "ACTIVE";
42
+ readonly DRAFT: "DRAFT";
43
+ readonly ARCHIVED: "ARCHIVED";
44
+ readonly DELETED: "DELETED";
45
+ }>>;
40
46
  sellerId: z.ZodCUID2;
41
47
  title: z.ZodString;
42
48
  description: z.ZodString;
@@ -53,7 +59,18 @@ export declare const BaseProductSchema: z.ZodObject<{
53
59
  readonly FIXED: "Fixed";
54
60
  readonly PWYW: "Pay What You Want";
55
61
  }>;
56
- currency: z.ZodString;
62
+ currency: z.ZodEnum<{
63
+ readonly USD: "USD (United States Dollar)";
64
+ readonly EUR: "EUR (Euro)";
65
+ readonly GBP: "GBP (British Pound Sterling)";
66
+ readonly NGN: "NGN (Nigerian Naira)";
67
+ readonly CAD: "CAD (Canadian Dollar)";
68
+ readonly AUD: "AUD (Australian Dollar)";
69
+ readonly JPY: "JPY (Japanese Yen)";
70
+ readonly CHF: "CHF (Swiss Franc)";
71
+ readonly INR: "INR (Indian Rupee)";
72
+ readonly ZAR: "ZAR (South African Rand)";
73
+ }>;
57
74
  price: z.ZodNullable<z.ZodNumber>;
58
75
  suggestedPrice: z.ZodNullable<z.ZodNumber>;
59
76
  discounts: z.ZodNullable<z.ZodArray<z.ZodObject<{
@@ -72,6 +89,12 @@ export declare const CreateProductInputSchema: z.ZodObject<{
72
89
  title: z.ZodString;
73
90
  description: z.ZodString;
74
91
  keyFeatures: z.ZodString;
92
+ status: z.ZodDefault<z.ZodEnum<{
93
+ readonly ACTIVE: "ACTIVE";
94
+ readonly DRAFT: "DRAFT";
95
+ readonly ARCHIVED: "ARCHIVED";
96
+ readonly DELETED: "DELETED";
97
+ }>>;
75
98
  category: z.ZodString;
76
99
  subcategory: z.ZodOptional<z.ZodString>;
77
100
  tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -81,6 +104,18 @@ export declare const CreateProductInputSchema: z.ZodObject<{
81
104
  isThumbnail: z.ZodDefault<z.ZodBoolean>;
82
105
  order: z.ZodDefault<z.ZodNumber>;
83
106
  }, z.core.$strip>>;
107
+ currency: z.ZodEnum<{
108
+ readonly USD: "USD (United States Dollar)";
109
+ readonly EUR: "EUR (Euro)";
110
+ readonly GBP: "GBP (British Pound Sterling)";
111
+ readonly NGN: "NGN (Nigerian Naira)";
112
+ readonly CAD: "CAD (Canadian Dollar)";
113
+ readonly AUD: "AUD (Australian Dollar)";
114
+ readonly JPY: "JPY (Japanese Yen)";
115
+ readonly CHF: "CHF (Swiss Franc)";
116
+ readonly INR: "INR (Indian Rupee)";
117
+ readonly ZAR: "ZAR (South African Rand)";
118
+ }>;
84
119
  productFiles: z.ZodDefault<z.ZodArray<z.ZodObject<{
85
120
  key: z.ZodString;
86
121
  mimeType: z.ZodString;
@@ -95,7 +130,6 @@ export declare const CreateProductInputSchema: z.ZodObject<{
95
130
  readonly FIXED: "Fixed";
96
131
  readonly PWYW: "Pay What You Want";
97
132
  }>>;
98
- currency: z.ZodDefault<z.ZodString>;
99
133
  price: z.ZodOptional<z.ZodNumber>;
100
134
  suggestedPrice: z.ZodOptional<z.ZodNumber>;
101
135
  discounts: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -120,6 +154,12 @@ export declare const UpdateProductInputSchema: z.ZodObject<{
120
154
  title: z.ZodOptional<z.ZodString>;
121
155
  description: z.ZodOptional<z.ZodString>;
122
156
  keyFeatures: z.ZodOptional<z.ZodString>;
157
+ status: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
158
+ readonly ACTIVE: "ACTIVE";
159
+ readonly DRAFT: "DRAFT";
160
+ readonly ARCHIVED: "ARCHIVED";
161
+ readonly DELETED: "DELETED";
162
+ }>>>;
123
163
  category: z.ZodOptional<z.ZodString>;
124
164
  subcategory: z.ZodOptional<z.ZodOptional<z.ZodString>>;
125
165
  tags: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
@@ -129,6 +169,18 @@ export declare const UpdateProductInputSchema: z.ZodObject<{
129
169
  isThumbnail: z.ZodDefault<z.ZodBoolean>;
130
170
  order: z.ZodDefault<z.ZodNumber>;
131
171
  }, z.core.$strip>>>;
172
+ currency: z.ZodOptional<z.ZodEnum<{
173
+ readonly USD: "USD (United States Dollar)";
174
+ readonly EUR: "EUR (Euro)";
175
+ readonly GBP: "GBP (British Pound Sterling)";
176
+ readonly NGN: "NGN (Nigerian Naira)";
177
+ readonly CAD: "CAD (Canadian Dollar)";
178
+ readonly AUD: "AUD (Australian Dollar)";
179
+ readonly JPY: "JPY (Japanese Yen)";
180
+ readonly CHF: "CHF (Swiss Franc)";
181
+ readonly INR: "INR (Indian Rupee)";
182
+ readonly ZAR: "ZAR (South African Rand)";
183
+ }>>;
132
184
  productFiles: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
133
185
  key: z.ZodString;
134
186
  mimeType: z.ZodString;
@@ -143,7 +195,6 @@ export declare const UpdateProductInputSchema: z.ZodObject<{
143
195
  readonly FIXED: "Fixed";
144
196
  readonly PWYW: "Pay What You Want";
145
197
  }>>>;
146
- currency: z.ZodOptional<z.ZodDefault<z.ZodString>>;
147
198
  price: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
148
199
  suggestedPrice: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
149
200
  discounts: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -171,6 +222,12 @@ export declare const ProductEntitySchema: z.ZodObject<{
171
222
  title: z.ZodString;
172
223
  description: z.ZodString;
173
224
  keyFeatures: z.ZodString;
225
+ status: z.ZodDefault<z.ZodEnum<{
226
+ readonly ACTIVE: "ACTIVE";
227
+ readonly DRAFT: "DRAFT";
228
+ readonly ARCHIVED: "ARCHIVED";
229
+ readonly DELETED: "DELETED";
230
+ }>>;
174
231
  category: z.ZodString;
175
232
  subcategory: z.ZodNullable<z.ZodOptional<z.ZodString>>;
176
233
  tags: z.ZodArray<z.ZodString>;
@@ -189,7 +246,18 @@ export declare const ProductEntitySchema: z.ZodObject<{
189
246
  readonly FIXED: "Fixed";
190
247
  readonly PWYW: "Pay What You Want";
191
248
  }>;
192
- currency: z.ZodString;
249
+ currency: z.ZodEnum<{
250
+ readonly USD: "USD (United States Dollar)";
251
+ readonly EUR: "EUR (Euro)";
252
+ readonly GBP: "GBP (British Pound Sterling)";
253
+ readonly NGN: "NGN (Nigerian Naira)";
254
+ readonly CAD: "CAD (Canadian Dollar)";
255
+ readonly AUD: "AUD (Australian Dollar)";
256
+ readonly JPY: "JPY (Japanese Yen)";
257
+ readonly CHF: "CHF (Swiss Franc)";
258
+ readonly INR: "INR (Indian Rupee)";
259
+ readonly ZAR: "ZAR (South African Rand)";
260
+ }>;
193
261
  price: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
194
262
  suggestedPrice: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
195
263
  discounts: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -46,6 +46,7 @@ exports.BaseProductSchema = zod_openapi_1.z.object({
46
46
  createdAt: zod_openapi_1.z.date(),
47
47
  updatedAt: zod_openapi_1.z.date(),
48
48
  deletedAt: zod_openapi_1.z.date().nullable(),
49
+ status: zod_openapi_1.z.enum(constants_1.PRODUCT_STATUS).default("DRAFT"),
49
50
  sellerId: zod_openapi_1.z.cuid2(),
50
51
  title: zod_openapi_1.z.string(),
51
52
  description: zod_openapi_1.z.string(),
@@ -55,7 +56,7 @@ exports.BaseProductSchema = zod_openapi_1.z.object({
55
56
  tags: zod_openapi_1.z.array(zod_openapi_1.z.string()).nullable(),
56
57
  productLinks: zod_openapi_1.z.array(exports.ProductLinkSchema).nullable(),
57
58
  pricingModel: zod_openapi_1.z.enum(constants_1.PRICING_MODELS),
58
- currency: zod_openapi_1.z.string(),
59
+ currency: zod_openapi_1.z.enum(constants_1.WAGES_CURRENCY),
59
60
  price: zod_openapi_1.z.number().nullable(),
60
61
  suggestedPrice: zod_openapi_1.z.number().nullable(),
61
62
  discounts: zod_openapi_1.z
@@ -74,18 +75,18 @@ const ProductCoreInputSchema = zod_openapi_1.z.object({
74
75
  title: zod_openapi_1.z.string().min(1, "Title is required").max(255),
75
76
  description: zod_openapi_1.z.string().min(1, "Description is required"),
76
77
  keyFeatures: zod_openapi_1.z.string(),
78
+ status: zod_openapi_1.z.enum(constants_1.PRODUCT_STATUS).default("DRAFT"),
77
79
  category: zod_openapi_1.z.string().min(1, "Category is required"),
78
80
  subcategory: zod_openapi_1.z.string().optional(),
79
81
  tags: zod_openapi_1.z.array(zod_openapi_1.z.string()).max(10, "Keep tags to a maximum of 10").default([]),
80
- // Swapped to the new direct-upload input schemas
81
82
  coverImages: zod_openapi_1.z
82
83
  .array(exports.CoverImageInputSchema)
83
84
  .min(1, "At least one cover image is required")
84
85
  .max(3, "Maximum of 3 cover images allowed"),
86
+ currency: zod_openapi_1.z.enum(constants_1.WAGES_CURRENCY),
85
87
  productFiles: zod_openapi_1.z.array(exports.DeliveryFileInputSchema).default([]),
86
88
  productLinks: zod_openapi_1.z.array(exports.ProductLinkSchema).default([]),
87
89
  pricingModel: zod_openapi_1.z.enum(constants_1.PRICING_MODELS).default(constants_1.PRICING_MODELS.FIXED),
88
- currency: zod_openapi_1.z.string().default("USD").openapi({ example: "USD" }),
89
90
  price: zod_openapi_1.z.number().int("Must be in cents").min(0).optional(),
90
91
  suggestedPrice: zod_openapi_1.z.number().int("Must be in cents").min(0).optional(),
91
92
  discounts: zod_openapi_1.z.array(exports.ProductDiscountEntitySchema).default([]),
@@ -99,15 +100,15 @@ exports.CreateProductInputSchema = ProductCoreInputSchema.superRefine((data, ctx
99
100
  path: ["price"],
100
101
  });
101
102
  }
102
- if (data.pricingModel === constants_1.PRICING_MODELS.PWYW) {
103
- if (data.suggestedPrice !== undefined && data.price !== undefined) {
104
- if (data.suggestedPrice < data.price) {
105
- ctx.addIssue({
106
- code: "custom",
107
- message: "Suggested price cannot be lower than the minimum price.",
108
- path: ["suggestedPrice"],
109
- });
110
- }
103
+ if (data.pricingModel === constants_1.PRICING_MODELS.PWYW &&
104
+ data.suggestedPrice !== undefined &&
105
+ data.price !== undefined) {
106
+ if (data.suggestedPrice < data.price) {
107
+ ctx.addIssue({
108
+ code: "custom",
109
+ message: "Suggested price cannot be lower than the minimum price.",
110
+ path: ["suggestedPrice"],
111
+ });
111
112
  }
112
113
  }
113
114
  if (data.pricingModel === constants_1.PRICING_MODELS.FREE &&
@@ -134,6 +135,26 @@ exports.CreateProductInputSchema = ProductCoreInputSchema.superRefine((data, ctx
134
135
  path: ["coverImages"],
135
136
  });
136
137
  }
138
+ data.discounts.forEach((discount, index) => {
139
+ const isPercentage = String(discount.discountType).toUpperCase() === "PERCENTAGE";
140
+ const isFixed = String(discount.discountType).toUpperCase() === "FIXED";
141
+ if (isPercentage && discount.amount >= 100) {
142
+ ctx.addIssue({
143
+ code: "custom",
144
+ message: "Percentage discounts must be less than 100%.",
145
+ path: ["discounts", index, "amount"],
146
+ });
147
+ }
148
+ if (isFixed && data.price !== undefined) {
149
+ if (discount.amount >= data.price) {
150
+ ctx.addIssue({
151
+ code: "custom",
152
+ message: "Fixed discount amounts must be less than the product price.",
153
+ path: ["discounts", index, "amount"],
154
+ });
155
+ }
156
+ }
157
+ });
137
158
  });
138
159
  exports.ProductServiceAndComplianceInputSchema = zod_openapi_1.z.object({
139
160
  id: zod_openapi_1.z.cuid2().openapi({ description: "ID of the product" }),
@@ -160,6 +181,7 @@ exports.ProductEntitySchema = zod_openapi_1.z
160
181
  title: zod_openapi_1.z.string(),
161
182
  description: zod_openapi_1.z.string(),
162
183
  keyFeatures: zod_openapi_1.z.string(),
184
+ status: zod_openapi_1.z.enum(constants_1.PRODUCT_STATUS).default("DRAFT"),
163
185
  category: zod_openapi_1.z.string(),
164
186
  subcategory: zod_openapi_1.z.string().optional().nullable(),
165
187
  tags: zod_openapi_1.z.array(zod_openapi_1.z.string()),
@@ -167,7 +189,7 @@ exports.ProductEntitySchema = zod_openapi_1.z
167
189
  productFiles: zod_openapi_1.z.array(exports.ProductDeliveryFileEntitySchema).default([]),
168
190
  productLinks: zod_openapi_1.z.array(zod_openapi_1.z.url()).default([]),
169
191
  pricingModel: zod_openapi_1.z.enum(constants_1.PRICING_MODELS),
170
- currency: zod_openapi_1.z.string(),
192
+ currency: zod_openapi_1.z.enum(constants_1.WAGES_CURRENCY),
171
193
  price: zod_openapi_1.z.number().int().optional().nullable(),
172
194
  suggestedPrice: zod_openapi_1.z.number().int().optional().nullable(),
173
195
  discounts: zod_openapi_1.z.array(exports.ProductDiscountEntitySchema).default([]),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zyacreatives/shared",
3
- "version": "2.2.95",
3
+ "version": "2.2.97",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/constants.ts CHANGED
@@ -217,6 +217,8 @@ export const JOB_STATUS = {
217
217
  DELETED: "DELETED",
218
218
  } as const;
219
219
 
220
+ export const PRODUCT_STATUS = JOB_STATUS;
221
+
220
222
  export const MESSAGE_REQUEST_STATUS = {
221
223
  PENDING: "PENDING",
222
224
  ACCEPTED: "ACCEPTED",
@@ -345,6 +347,8 @@ export type JobSections = (typeof JOB_SECTIONS)[keyof typeof JOB_SECTIONS];
345
347
  export type WagesCurrency =
346
348
  (typeof WAGES_CURRENCY)[keyof typeof WAGES_CURRENCY];
347
349
  export type JobStatus = (typeof JOB_STATUS)[keyof typeof JOB_STATUS];
350
+ export type ProductStatus =
351
+ (typeof PRODUCT_STATUS)[keyof typeof PRODUCT_STATUS];
348
352
  export type Role = (typeof ROLES)[keyof typeof ROLES];
349
353
  export type JobType = (typeof JOB_TYPE)[keyof typeof JOB_TYPE];
350
354
  export type WorkMode = (typeof WORK_MODE)[keyof typeof WORK_MODE];
@@ -1,5 +1,10 @@
1
1
  import { z } from "@hono/zod-openapi";
2
- import { DISCOUNT_TYPES, PRICING_MODELS } from "../constants";
2
+ import {
3
+ DISCOUNT_TYPES,
4
+ PRICING_MODELS,
5
+ PRODUCT_STATUS,
6
+ WAGES_CURRENCY,
7
+ } from "../constants";
3
8
 
4
9
  // --- File Input Schemas ---
5
10
 
@@ -53,9 +58,8 @@ export const BaseProductSchema = z.object({
53
58
  createdAt: z.date(),
54
59
  updatedAt: z.date(),
55
60
  deletedAt: z.date().nullable(),
56
-
61
+ status: z.enum(PRODUCT_STATUS).default("DRAFT"),
57
62
  sellerId: z.cuid2(),
58
-
59
63
  title: z.string(),
60
64
  description: z.string(),
61
65
  keyFeatures: z.string(),
@@ -66,7 +70,7 @@ export const BaseProductSchema = z.object({
66
70
 
67
71
  productLinks: z.array(ProductLinkSchema).nullable(),
68
72
  pricingModel: z.enum(PRICING_MODELS),
69
- currency: z.string(),
73
+ currency: z.enum(WAGES_CURRENCY),
70
74
  price: z.number().nullable(),
71
75
  suggestedPrice: z.number().nullable(),
72
76
 
@@ -91,23 +95,21 @@ const ProductCoreInputSchema = z.object({
91
95
  title: z.string().min(1, "Title is required").max(255),
92
96
  description: z.string().min(1, "Description is required"),
93
97
  keyFeatures: z.string(),
94
-
98
+ status: z.enum(PRODUCT_STATUS).default("DRAFT"),
95
99
  category: z.string().min(1, "Category is required"),
96
100
  subcategory: z.string().optional(),
97
101
  tags: z.array(z.string()).max(10, "Keep tags to a maximum of 10").default([]),
98
102
 
99
- // Swapped to the new direct-upload input schemas
100
103
  coverImages: z
101
104
  .array(CoverImageInputSchema)
102
105
  .min(1, "At least one cover image is required")
103
106
  .max(3, "Maximum of 3 cover images allowed"),
104
-
107
+ currency: z.enum(WAGES_CURRENCY),
105
108
  productFiles: z.array(DeliveryFileInputSchema).default([]),
106
109
 
107
110
  productLinks: z.array(ProductLinkSchema).default([]),
108
111
 
109
112
  pricingModel: z.enum(PRICING_MODELS).default(PRICING_MODELS.FIXED),
110
- currency: z.string().default("USD").openapi({ example: "USD" }),
111
113
 
112
114
  price: z.number().int("Must be in cents").min(0).optional(),
113
115
  suggestedPrice: z.number().int("Must be in cents").min(0).optional(),
@@ -128,15 +130,17 @@ export const CreateProductInputSchema = ProductCoreInputSchema.superRefine(
128
130
  });
129
131
  }
130
132
 
131
- if (data.pricingModel === PRICING_MODELS.PWYW) {
132
- if (data.suggestedPrice !== undefined && data.price !== undefined) {
133
- if (data.suggestedPrice < data.price) {
134
- ctx.addIssue({
135
- code: "custom",
136
- message: "Suggested price cannot be lower than the minimum price.",
137
- path: ["suggestedPrice"],
138
- });
139
- }
133
+ if (
134
+ data.pricingModel === PRICING_MODELS.PWYW &&
135
+ data.suggestedPrice !== undefined &&
136
+ data.price !== undefined
137
+ ) {
138
+ if (data.suggestedPrice < data.price) {
139
+ ctx.addIssue({
140
+ code: "custom",
141
+ message: "Suggested price cannot be lower than the minimum price.",
142
+ path: ["suggestedPrice"],
143
+ });
140
144
  }
141
145
  }
142
146
 
@@ -169,6 +173,31 @@ export const CreateProductInputSchema = ProductCoreInputSchema.superRefine(
169
173
  path: ["coverImages"],
170
174
  });
171
175
  }
176
+
177
+ data.discounts.forEach((discount, index) => {
178
+ const isPercentage =
179
+ String(discount.discountType).toUpperCase() === "PERCENTAGE";
180
+ const isFixed = String(discount.discountType).toUpperCase() === "FIXED";
181
+
182
+ if (isPercentage && discount.amount >= 100) {
183
+ ctx.addIssue({
184
+ code: "custom",
185
+ message: "Percentage discounts must be less than 100%.",
186
+ path: ["discounts", index, "amount"],
187
+ });
188
+ }
189
+
190
+ if (isFixed && data.price !== undefined) {
191
+ if (discount.amount >= data.price) {
192
+ ctx.addIssue({
193
+ code: "custom",
194
+ message:
195
+ "Fixed discount amounts must be less than the product price.",
196
+ path: ["discounts", index, "amount"],
197
+ });
198
+ }
199
+ }
200
+ });
172
201
  },
173
202
  );
174
203
 
@@ -210,7 +239,7 @@ export const ProductEntitySchema = z
210
239
  title: z.string(),
211
240
  description: z.string(),
212
241
  keyFeatures: z.string(),
213
-
242
+ status: z.enum(PRODUCT_STATUS).default("DRAFT"),
214
243
  category: z.string(),
215
244
  subcategory: z.string().optional().nullable(),
216
245
  tags: z.array(z.string()),
@@ -220,7 +249,7 @@ export const ProductEntitySchema = z
220
249
  productLinks: z.array(z.url()).default([]),
221
250
 
222
251
  pricingModel: z.enum(PRICING_MODELS),
223
- currency: z.string(),
252
+ currency: z.enum(WAGES_CURRENCY),
224
253
  price: z.number().int().optional().nullable(),
225
254
  suggestedPrice: z.number().int().optional().nullable(),
226
255