@gigapay-dev/contracts 1.8.2 → 1.8.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.
Files changed (36) hide show
  1. package/build/commands/index.js +1 -1
  2. package/build/commands/orders/create.js +23 -6
  3. package/build/commands/orders/enums.js +18 -1
  4. package/build/commands/orders/index.js +1 -0
  5. package/build/commands/orders/query.js +16 -4
  6. package/build/commands/orders/read.js +67 -12
  7. package/build/commands/orders/update.js +7 -5
  8. package/build/commands/products/create.js +122 -0
  9. package/build/commands/products/endpoints.js +99 -0
  10. package/build/commands/products/enums.js +27 -0
  11. package/build/commands/products/index.js +22 -0
  12. package/build/commands/products/query.js +55 -0
  13. package/build/commands/products/read.js +176 -0
  14. package/build/commands/products/update.js +10 -0
  15. package/commands/index.ts +2 -2
  16. package/commands/orders/create.ts +30 -11
  17. package/commands/orders/endpoints.ts +38 -42
  18. package/commands/orders/enums.ts +20 -2
  19. package/commands/orders/index.ts +6 -5
  20. package/commands/orders/query.ts +30 -17
  21. package/commands/orders/read.ts +78 -21
  22. package/commands/orders/update.ts +12 -10
  23. package/commands/products/create.ts +134 -0
  24. package/commands/products/endpoints.ts +108 -0
  25. package/commands/products/enums.ts +33 -0
  26. package/commands/products/index.ts +6 -0
  27. package/commands/products/query.ts +52 -0
  28. package/commands/products/read.ts +205 -0
  29. package/commands/products/update.ts +11 -0
  30. package/commands/stats/endpoints.ts +4 -2
  31. package/commands/stats/query.ts +14 -14
  32. package/commands/stats/read.ts +8 -8
  33. package/package.json +1 -1
  34. package/commands/status/endpoints.ts +0 -40
  35. package/commands/status/index.ts +0 -2
  36. package/commands/status/read.ts +0 -9
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.KeysCountResponseSchema = exports.ProductDetailResponseSchema = exports.ProductCatalogResponseSchema = exports.DlcBriefSchema = exports.SystemRequirementsResponseSchema = exports.MediaResponseSchema = exports.VariantDetailSchema = exports.VariantCatalogSchema = exports.RegionResponseSchema = exports.RegionBriefSchema = exports.TagBriefSchema = exports.GenreResponseSchema = exports.GenreBriefSchema = exports.CategoryResponseSchema = exports.CategoryBriefSchema = void 0;
7
+ const zod_1 = __importDefault(require("zod"));
8
+ // === Вложенные схемы ===
9
+ /** Категория (краткая) */
10
+ exports.CategoryBriefSchema = zod_1.default.object({
11
+ slug: zod_1.default.string(),
12
+ name: zod_1.default.string(),
13
+ });
14
+ /** Категория (полная, для списка категорий) */
15
+ exports.CategoryResponseSchema = zod_1.default.object({
16
+ id: zod_1.default.number(),
17
+ slug: zod_1.default.string(),
18
+ name: zod_1.default.string(),
19
+ description: zod_1.default.string().nullable(),
20
+ iconUrl: zod_1.default.string().nullable(),
21
+ _count: zod_1.default.object({
22
+ products: zod_1.default.number(),
23
+ }),
24
+ });
25
+ /** Жанр (краткий, без ID) */
26
+ exports.GenreBriefSchema = zod_1.default.object({
27
+ slug: zod_1.default.string(),
28
+ name: zod_1.default.string(),
29
+ });
30
+ /** Жанр (полный, для списка жанров) */
31
+ exports.GenreResponseSchema = zod_1.default.object({
32
+ id: zod_1.default.number(),
33
+ slug: zod_1.default.string(),
34
+ name: zod_1.default.string(),
35
+ _count: zod_1.default.object({
36
+ products: zod_1.default.number(),
37
+ }),
38
+ });
39
+ /** Тег */
40
+ exports.TagBriefSchema = zod_1.default.object({
41
+ id: zod_1.default.number(),
42
+ slug: zod_1.default.string(),
43
+ name: zod_1.default.string(),
44
+ });
45
+ /** Регион (краткий, без ID) */
46
+ exports.RegionBriefSchema = zod_1.default.object({
47
+ code: zod_1.default.string(),
48
+ name: zod_1.default.string(),
49
+ });
50
+ /** Регион (полный, для списка регионов) */
51
+ exports.RegionResponseSchema = zod_1.default.object({
52
+ id: zod_1.default.number(),
53
+ code: zod_1.default.string(),
54
+ name: zod_1.default.string(),
55
+ _count: zod_1.default.object({
56
+ products: zod_1.default.number(),
57
+ }),
58
+ });
59
+ /** Вариант в каталоге (краткий) */
60
+ exports.VariantCatalogSchema = zod_1.default.object({
61
+ id: zod_1.default.number(),
62
+ name: zod_1.default.string(),
63
+ price: zod_1.default.string(),
64
+ originalPrice: zod_1.default.string().nullable(),
65
+ platform: zod_1.default.string().nullable(),
66
+ regionCode: zod_1.default.string().nullable(),
67
+ });
68
+ /** Вариант в детальной карточке */
69
+ exports.VariantDetailSchema = zod_1.default.object({
70
+ id: zod_1.default.number(),
71
+ name: zod_1.default.string(),
72
+ sku: zod_1.default.string(),
73
+ price: zod_1.default.string(),
74
+ originalPrice: zod_1.default.string().nullable(),
75
+ topupAmount: zod_1.default.string().nullable(),
76
+ currency: zod_1.default.string().nullable(),
77
+ durationDays: zod_1.default.number().nullable(),
78
+ platform: zod_1.default.string().nullable(),
79
+ regionCode: zod_1.default.string().nullable(),
80
+ deliveryType: zod_1.default.string(),
81
+ inStock: zod_1.default.boolean(),
82
+ });
83
+ /** Медиа */
84
+ exports.MediaResponseSchema = zod_1.default.object({
85
+ id: zod_1.default.number(),
86
+ type: zod_1.default.string(),
87
+ url: zod_1.default.string(),
88
+ alt: zod_1.default.string().nullable(),
89
+ });
90
+ /** Системные требования */
91
+ exports.SystemRequirementsResponseSchema = zod_1.default.object({
92
+ type: zod_1.default.string(),
93
+ os: zod_1.default.string().nullable(),
94
+ processor: zod_1.default.string().nullable(),
95
+ memory: zod_1.default.string().nullable(),
96
+ graphics: zod_1.default.string().nullable(),
97
+ storage: zod_1.default.string().nullable(),
98
+ directx: zod_1.default.string().nullable(),
99
+ network: zod_1.default.string().nullable(),
100
+ additional: zod_1.default.string().nullable(),
101
+ });
102
+ /** DLC в детальной карточке */
103
+ exports.DlcBriefSchema = zod_1.default.object({
104
+ id: zod_1.default.number(),
105
+ slug: zod_1.default.string(),
106
+ title: zod_1.default.string(),
107
+ coverImageUrl: zod_1.default.string().nullable(),
108
+ variants: zod_1.default.array(zod_1.default.object({
109
+ price: zod_1.default.any(),
110
+ originalPrice: zod_1.default.any(),
111
+ })),
112
+ });
113
+ // === Основные схемы ответов ===
114
+ /** Продукт в каталоге (карточка) */
115
+ exports.ProductCatalogResponseSchema = zod_1.default.object({
116
+ id: zod_1.default.number(),
117
+ slug: zod_1.default.string(),
118
+ title: zod_1.default.string(),
119
+ type: zod_1.default.string(),
120
+ shortDescription: zod_1.default.string().nullable(),
121
+ coverImageUrl: zod_1.default.string().nullable(),
122
+ steamRating: zod_1.default.number().nullable(),
123
+ hasMultiplayer: zod_1.default.boolean(),
124
+ hasCoop: zod_1.default.boolean(),
125
+ salesCount: zod_1.default.number(),
126
+ publisher: zod_1.default.string().nullable(),
127
+ releaseDate: zod_1.default.coerce.date().nullable(),
128
+ category: exports.CategoryBriefSchema,
129
+ genres: zod_1.default.array(exports.GenreBriefSchema),
130
+ regions: zod_1.default.array(exports.RegionBriefSchema),
131
+ variants: zod_1.default.array(exports.VariantCatalogSchema),
132
+ minPrice: zod_1.default.string().nullable(),
133
+ hasDiscount: zod_1.default.boolean(),
134
+ });
135
+ /** Продукт (полная детальная карточка) */
136
+ exports.ProductDetailResponseSchema = zod_1.default.object({
137
+ id: zod_1.default.number(),
138
+ slug: zod_1.default.string(),
139
+ title: zod_1.default.string(),
140
+ originalTitle: zod_1.default.string().nullable(),
141
+ type: zod_1.default.string(),
142
+ status: zod_1.default.string(),
143
+ description: zod_1.default.string().nullable(),
144
+ customDescription: zod_1.default.string().nullable(),
145
+ shortDescription: zod_1.default.string().nullable(),
146
+ coverImageUrl: zod_1.default.string().nullable(),
147
+ developer: zod_1.default.string().nullable(),
148
+ publisher: zod_1.default.string().nullable(),
149
+ releaseDate: zod_1.default.coerce.date().nullable(),
150
+ steamAppId: zod_1.default.number().nullable(),
151
+ steamRating: zod_1.default.number().nullable(),
152
+ hasMultiplayer: zod_1.default.boolean(),
153
+ hasCoop: zod_1.default.boolean(),
154
+ hasSinglePlayer: zod_1.default.boolean(),
155
+ metaTitle: zod_1.default.string().nullable(),
156
+ metaDescription: zod_1.default.string().nullable(),
157
+ salesCount: zod_1.default.number(),
158
+ viewsCount: zod_1.default.number(),
159
+ category: exports.CategoryBriefSchema.extend({ id: zod_1.default.number() }),
160
+ variants: zod_1.default.array(exports.VariantDetailSchema),
161
+ media: zod_1.default.array(exports.MediaResponseSchema),
162
+ genres: zod_1.default.array(exports.TagBriefSchema),
163
+ tags: zod_1.default.array(exports.TagBriefSchema),
164
+ regions: zod_1.default.array(exports.RegionResponseSchema.omit({ _count: true })),
165
+ systemRequirements: zod_1.default.array(exports.SystemRequirementsResponseSchema),
166
+ dlcs: zod_1.default.array(exports.DlcBriefSchema),
167
+ createdAt: zod_1.default.coerce.date(),
168
+ updatedAt: zod_1.default.coerce.date(),
169
+ });
170
+ /** Статистика ключей по варианту */
171
+ exports.KeysCountResponseSchema = zod_1.default.object({
172
+ available: zod_1.default.number(),
173
+ sold: zod_1.default.number(),
174
+ reserved: zod_1.default.number(),
175
+ total: zod_1.default.number(),
176
+ });
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProductUpdateRequestSchema = void 0;
4
+ const create_1 = require("./create");
5
+ const enums_1 = require("./enums");
6
+ /** Запрос на обновление продукта (частичное) */
7
+ exports.ProductUpdateRequestSchema = create_1.ProductCreateRequestSchema.partial().extend({
8
+ /** Статус продукта */
9
+ status: enums_1.ProductStatus.optional(),
10
+ });
package/commands/index.ts CHANGED
@@ -9,5 +9,5 @@ export * from './payment-methods';
9
9
  export * from './api-response';
10
10
  export * from './users';
11
11
  export * from './stats';
12
- export * from './status';
13
- export * from './settings';
12
+ export * from './settings';
13
+ export * from './products';
@@ -1,22 +1,41 @@
1
1
  import z from "zod";
2
2
  import { OrderType } from "./enums";
3
3
 
4
+ export const OrderItemInputSchema = z.object({
5
+ variantId: z.coerce.number().int().positive(),
6
+ quantity: z.coerce.number().int().min(1).default(1),
7
+ gameUsername: z.string().max(255).optional(),
8
+ gameUsernameType: z.string().max(64).optional(),
9
+ });
10
+
11
+ /** Запрос на создание заказа */
4
12
  export const OrderCreateRequestSchema = z.object({
5
- email: z.string().email(),
6
- steamUsername: z.string(),
7
- amount: z.coerce.number().nonnegative(),
8
- userId: z.coerce.number().positive().optional(),
9
- paymentMethodId: z.coerce.number().positive(),
10
- promocodeId: z.coerce.number().positive().optional(),
11
- type: OrderType.optional().default('MAIN'),
12
- utmSource: z.string().optional(),
13
+ /** Email покупателя */
14
+ email: z.string().email(),
15
+ /** ID способа оплаты */
16
+ paymentMethodId: z.coerce.number().positive(),
17
+ /** Список товаров в заказе (минимум 1) */
18
+ items: z.array(OrderItemInputSchema).min(1),
19
+ /** ID промокода (опционально) */
20
+ promocodeId: z.coerce.number().positive().optional(),
21
+ /** ID существующего пользователя (опционально) */
22
+ userId: z.coerce.number().positive().optional(),
23
+ /** Telegram ID покупателя (опционально) */
24
+ telegramId: z.string().optional(),
25
+ /** UTM-метка источника трафика */
26
+ utmSource: z.string().optional(),
27
+ /** Тип дизайна формы оплаты */
13
28
  designType: z.string().optional(),
14
- telegramId: z.string().optional(),
29
+ /** Тип заказа: MAIN (сайт) или WEBAPP (Telegram Mini App) */
30
+ type: OrderType.optional().default("MAIN"),
15
31
  });
16
32
 
33
+ /** Ответ на создание заказа — ссылка для оплаты */
17
34
  export const OrderCreateResponseSchema = z.object({
18
- redirectUrl: z.string(),
35
+ /** URL для редиректа на платёжную страницу */
36
+ redirectUrl: z.string(),
19
37
  });
20
38
 
39
+ export type OrderItemInput = z.infer<typeof OrderItemInputSchema>;
21
40
  export type OrderCreateRequest = z.infer<typeof OrderCreateRequestSchema>;
22
- export type OrderCreateResponse = z.infer<typeof OrderCreateResponseSchema>;
41
+ export type OrderCreateResponse = z.infer<typeof OrderCreateResponseSchema>;
@@ -1,55 +1,51 @@
1
1
  import z from "zod";
2
-
3
- import {
4
- OrderReadResponseSchema,
5
- } from "./read";
6
-
2
+ import { OrderReadResponseSchema } from "./read";
7
3
  import { EndpointContract } from "../../types";
8
4
  import { OrderCreateRequestSchema, OrderCreateResponseSchema } from "./create";
9
5
  import { OrdersListQuerySchema } from "./query";
10
6
 
11
7
  export const OrderEndpoints = {
12
- create: {
13
- method: "POST",
14
- path: "/orders",
15
- request: OrderCreateRequestSchema,
16
- response: OrderCreateResponseSchema,
17
- },
18
- list: {
19
- method: "GET",
20
- path: "/orders",
21
- request: OrdersListQuerySchema,
22
- response: z.array(OrderReadResponseSchema),
23
- },
24
- getById: {
25
- method: "GET",
26
- path: "/orders/:id",
27
- request: z.object({
28
- id: z.coerce.number().positive(),
29
- }),
30
- response: OrderReadResponseSchema,
31
- },
32
- getUserOrders: {
33
- method: "GET",
34
- path: "/orders/user",
35
- request: OrdersListQuerySchema,
36
- response: z.array(OrderReadResponseSchema),
37
- },
38
- getUserOrderById: {
39
- method: "GET",
40
- path: "/orders/user/:userId/:orderId",
41
- request: z.object({
42
- userId: z.coerce.number().positive(),
43
- orderId: z.coerce.number().positive(),
44
- }),
45
- response: OrderReadResponseSchema,
46
- },
8
+ create: {
9
+ method: "POST",
10
+ path: "/orders",
11
+ request: OrderCreateRequestSchema,
12
+ response: OrderCreateResponseSchema,
13
+ },
14
+ list: {
15
+ method: "GET",
16
+ path: "/orders",
17
+ request: OrdersListQuerySchema,
18
+ response: z.array(OrderReadResponseSchema),
19
+ },
20
+ getById: {
21
+ method: "GET",
22
+ path: "/orders/:id",
23
+ request: z.object({
24
+ id: z.coerce.number().positive(),
25
+ }),
26
+ response: OrderReadResponseSchema,
27
+ },
28
+ getUserOrders: {
29
+ method: "GET",
30
+ path: "/orders/user",
31
+ request: OrdersListQuerySchema,
32
+ response: z.array(OrderReadResponseSchema),
33
+ },
34
+ getUserOrderById: {
35
+ method: "GET",
36
+ path: "/orders/user/:userId/:orderId",
37
+ request: z.object({
38
+ userId: z.coerce.number().positive(),
39
+ orderId: z.coerce.number().positive(),
40
+ }),
41
+ response: OrderReadResponseSchema,
42
+ },
47
43
  } satisfies Record<string, EndpointContract>;
48
44
 
49
45
  export type OrderEndpointKey = keyof typeof OrderEndpoints;
50
46
 
51
47
  export type GetOrderRequest<K extends OrderEndpointKey> =
52
- z.infer<typeof OrderEndpoints[K]["request"]>;
48
+ z.infer<typeof OrderEndpoints[K]["request"]>;
53
49
 
54
50
  export type GetOrderResponse<K extends OrderEndpointKey> =
55
- z.infer<typeof OrderEndpoints[K]["response"]>;
51
+ z.infer<typeof OrderEndpoints[K]["response"]>;
@@ -1,7 +1,25 @@
1
1
  import z from "zod";
2
2
 
3
3
  export const OrderType = z.enum(["MAIN", "WEBAPP"]);
4
-
5
4
  export type OrderType = z.infer<typeof OrderType>;
6
-
7
5
 
6
+ export const OrderStatus = z.enum([
7
+ "PENDING",
8
+ "AWAITING_PAYMENT",
9
+ "PAID",
10
+ "PROCESSING",
11
+ "SUCCESS",
12
+ "FAILED",
13
+ "REFUNDED",
14
+ "CANCELLED",
15
+ ]);
16
+ export type OrderStatus = z.infer<typeof OrderStatus>;
17
+
18
+ export const OrderItemStatus = z.enum([
19
+ "PENDING",
20
+ "PROCESSING",
21
+ "DELIVERED",
22
+ "FAILED",
23
+ "REFUNDED",
24
+ ]);
25
+ export type OrderItemStatus = z.infer<typeof OrderItemStatus>;
@@ -1,5 +1,6 @@
1
- export * from './create'
2
- export * from './update'
3
- export * from './read'
4
- export * from './query'
5
- export * from './endpoints'
1
+ export * from "./enums";
2
+ export * from "./create";
3
+ export * from "./update";
4
+ export * from "./read";
5
+ export * from "./query";
6
+ export * from "./endpoints";
@@ -1,33 +1,46 @@
1
1
  import z from "zod";
2
2
  import { PaginationQuery } from "../pagination";
3
+ import { OrderStatus } from "./enums";
3
4
 
5
+ /** Фильтр по периоду (базовая схема без refinements для merge) */
4
6
  const OrdersPeriodBase = z.object({
5
- period: z.enum(["day", "week", "month", "year", "custom"]).optional(),
6
- start: z.string().datetime().optional(),
7
- end: z.string().datetime().optional(),
7
+ /** Предустановленный период: day, week, month, year, custom */
8
+ period: z.enum(["day", "week", "month", "year", "custom"]).optional(),
9
+ /** Начало периода (ISO datetime, обязателен при period=custom) */
10
+ start: z.string().datetime().optional(),
11
+ /** Конец периода (ISO datetime, обязателен при period=custom) */
12
+ end: z.string().datetime().optional(),
8
13
  });
14
+
15
+ /** Фильтр по периоду с валидацией custom-диапазона */
9
16
  export const OrdersPeriodSchema = OrdersPeriodBase
10
- .refine(v => v.period !== "custom" || (v.start && v.end), {
11
- message: "start/end обязательны при period=custom",
12
- })
13
- .refine(v => v.period !== "custom" || new Date(v.start!) < new Date(v.end!), {
14
- message: "start должен быть раньше end",
15
- });
17
+ .refine(v => v.period !== "custom" || (v.start && v.end), {
18
+ message: "start/end обязательны при period=custom",
19
+ })
20
+ .refine(v => v.period !== "custom" || new Date(v.start!) < new Date(v.end!), {
21
+ message: "start должен быть раньше end",
22
+ });
16
23
 
24
+ /** Фильтры списка заказов */
17
25
  export const OrdersFiltersSchema = z.object({
18
- email: z.string().email().optional(),
19
- steamUsername: z.string().min(1).optional(),
20
- status: z.enum(["PENDING", "SUCCESS", "FAILED", "CANCELED"]).optional(),
26
+ /** Фильтр по email покупателя (частичное совпадение) */
27
+ email: z.string().optional(),
28
+ /** Фильтр по статусу заказа */
29
+ status: OrderStatus.optional(),
21
30
  });
22
31
 
32
+ /** Сортировка списка заказов */
23
33
  export const OrdersSortSchema = z.object({
24
- sortBy: z.string().default("createdAt"),
25
- sortDir: z.enum(["asc", "desc"]).default("desc"),
34
+ /** Поле для сортировки: createdAt, updatedAt, total, subtotal */
35
+ sortBy: z.enum(["createdAt", "updatedAt", "total", "subtotal"]).default("createdAt"),
36
+ /** Направление сортировки */
37
+ sortDir: z.enum(["asc", "desc"]).default("desc"),
26
38
  });
27
39
 
40
+ /** Объединённая схема запроса списка заказов */
28
41
  export const OrdersListQuerySchema = PaginationQuery
29
- .merge(OrdersFiltersSchema)
30
- .merge(OrdersSortSchema)
31
- .merge(OrdersPeriodBase);
42
+ .merge(OrdersFiltersSchema)
43
+ .merge(OrdersSortSchema)
44
+ .merge(OrdersPeriodBase);
32
45
 
33
46
  export type OrdersListQuery = z.infer<typeof OrdersListQuerySchema>;
@@ -1,26 +1,83 @@
1
1
  import { z } from "zod";
2
- import { OrderType } from "./enums";
2
+ import { OrderType, OrderStatus, OrderItemStatus } from "./enums";
3
3
 
4
+ /** Элемент заказа в ответе */
5
+ export const OrderItemResponseSchema = z.object({
6
+ /** ID элемента заказа */
7
+ id: z.number(),
8
+ /** ID товара */
9
+ productId: z.number(),
10
+ /** ID варианта товара */
11
+ variantId: z.number(),
12
+ /** Количество */
13
+ quantity: z.number(),
14
+ /** Цена на момент покупки (строка, Decimal) */
15
+ price: z.string(),
16
+ /** Игровой логин для доставки */
17
+ gameUsername: z.string().nullable(),
18
+ /** Тип игрового логина */
19
+ gameUsernameType: z.string().nullable(),
20
+ /** Выданный ключ (если автоматическая доставка) */
21
+ deliveredKey: z.string().nullable(),
22
+ /** Дата доставки */
23
+ deliveredAt: z.coerce.date().nullable(),
24
+ /** Статус элемента заказа */
25
+ status: OrderItemStatus,
26
+ /** Название товара */
27
+ productTitle: z.string().optional(),
28
+ /** Название варианта */
29
+ variantName: z.string().optional(),
30
+ });
31
+
32
+ /** Полная информация о заказе */
4
33
  export const OrderReadResponseSchema = z.object({
5
- id: z.coerce.number().positive(),
6
- userId: z.coerce.number().positive().optional(),
7
- promocodeId: z.coerce.number().nonnegative().optional(),
8
- email: z.string(),
9
- status: z.string(),
10
- steamUsername: z.string(),
11
- paymentId: z.coerce.number().nonnegative(),
12
- paymentMethodId: z.coerce.number().nonnegative().optional(),
13
- paymentMethodName: z.string(),
14
- promocodeValue: z.string().nullable(),
15
- promocodeDiscount: z.string().nullable(),
16
- amount: z.coerce.number().nonnegative(),
17
- type: OrderType,
18
- designType: z.string().nullable(),
19
- utmSource: z.string().nullable(),
20
- serviceCommissionPercent: z.coerce.number().nonnegative().optional(),
21
- acquiringCommissionPercent: z.coerce.number().nonnegative().optional(),
22
- createdAt: z.coerce.date().default(() => new Date()),
23
- updatedAt: z.coerce.date().default(() => new Date()),
34
+ /** ID заказа */
35
+ id: z.coerce.number().positive(),
36
+ /** ID пользователя (null для гостевых заказов) */
37
+ userId: z.coerce.number().positive().nullable().optional(),
38
+ /** ID промокода */
39
+ promocodeId: z.coerce.number().nonnegative().nullable().optional(),
40
+ /** ID способа оплаты */
41
+ paymentMethodId: z.coerce.number().nonnegative().nullable().optional(),
42
+ /** Email покупателя */
43
+ email: z.string(),
44
+ /** Статус заказа */
45
+ status: OrderStatus,
46
+ /** Тип заказа */
47
+ type: OrderType,
48
+ /** Сумма товаров до скидки и комиссий (строка, Decimal) */
49
+ subtotal: z.string(),
50
+ /** Сумма скидки (строка, Decimal) */
51
+ discount: z.string(),
52
+ /** Комиссия эквайринга (строка, Decimal) */
53
+ commission: z.string(),
54
+ /** Комиссия сервиса (строка, Decimal) */
55
+ serviceCommission: z.string(),
56
+ /** Итого к оплате (строка, Decimal) */
57
+ total: z.string(),
58
+ /** IP-адрес покупателя */
59
+ ipAddress: z.string().nullable().optional(),
60
+ /** UTM-метка источника трафика */
61
+ utmSource: z.string().nullable(),
62
+ /** Тип дизайна формы оплаты */
63
+ designType: z.string().nullable(),
64
+ /** Название способа оплаты */
65
+ paymentMethodName: z.string().nullable(),
66
+ /** Значение промокода */
67
+ promocodeValue: z.string().nullable(),
68
+ /** Скидка промокода в процентах (строка, Decimal) */
69
+ promocodeDiscount: z.string().nullable(),
70
+ /** Процент комиссии сервиса (serviceComission + secretComission) */
71
+ serviceCommissionPercent: z.coerce.number().nonnegative().optional(),
72
+ /** Процент комиссии эквайринга */
73
+ acquiringCommissionPercent: z.coerce.number().nonnegative().optional(),
74
+ /** Элементы заказа */
75
+ items: z.array(OrderItemResponseSchema).optional(),
76
+ /** Дата создания */
77
+ createdAt: z.coerce.date().default(() => new Date()),
78
+ /** Дата обновления */
79
+ updatedAt: z.coerce.date().default(() => new Date()),
24
80
  });
25
81
 
26
- export type OrderReadResponse = z.infer<typeof OrderReadResponseSchema>;
82
+ export type OrderItemResponse = z.infer<typeof OrderItemResponseSchema>;
83
+ export type OrderReadResponse = z.infer<typeof OrderReadResponseSchema>;
@@ -1,14 +1,16 @@
1
1
  import { z } from "zod";
2
+ import { OrderStatus } from "./enums";
2
3
 
4
+ /** Запрос на обновление заказа (администратором) */
3
5
  export const OrderUpdateRequestSchema = z.object({
4
- email: z.string().email().optional(),
5
- amount: z.coerce.number().nonnegative().optional(),
6
- steamUsername: z.string().optional(),
7
- userId: z.coerce.number().positive().optional(),
8
- paymentMethodId: z.coerce.number().positive().optional(),
9
- paymentId: z.coerce.number().positive().optional(),
10
- promocodeId: z.coerce.number().positive().optional(),
11
- comission: z.coerce.number().nonnegative().optional(),
12
- })
6
+ /** Новый статус заказа */
7
+ status: OrderStatus.optional(),
8
+ /** Email покупателя */
9
+ email: z.string().email().optional(),
10
+ /** ID способа оплаты */
11
+ paymentMethodId: z.coerce.number().positive().optional(),
12
+ /** ID промокода */
13
+ promocodeId: z.coerce.number().positive().optional(),
14
+ });
13
15
 
14
- export type OrderUpdateRequest = z.infer<typeof OrderUpdateRequestSchema>
16
+ export type OrderUpdateRequest = z.infer<typeof OrderUpdateRequestSchema>;