@floristcloud/api-lib 1.2.134 → 1.2.136

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 (65) hide show
  1. package/build/commands/attribute-normalization/analyze-attribute-normalization.query.js +19 -0
  2. package/build/commands/attribute-normalization/execute-attribute-normalization.command.js +28 -0
  3. package/build/commands/attribute-normalization/get-grower-suggestions.query.js +26 -0
  4. package/build/commands/attribute-normalization/index.js +9 -0
  5. package/build/commands/index.js +1 -0
  6. package/build/commands/product-image/analyze-product-image-merge.query.js +22 -0
  7. package/build/commands/product-image/execute-product-image-merge.command.js +25 -0
  8. package/build/commands/product-image/index.js +5 -0
  9. package/build/constant/attribute-normalization.constant.js +12 -0
  10. package/build/constant/error.js +50 -0
  11. package/build/constant/index.js +2 -0
  12. package/build/constant/product-image-merge.constant.js +11 -0
  13. package/build/enum/action-log-type.enum.js +2 -0
  14. package/build/enum/index.js +5 -0
  15. package/build/enum/normalization-decision-action.enum.js +13 -0
  16. package/build/enum/normalization-target.enum.js +12 -0
  17. package/build/enum/normalization-value-state.enum.js +13 -0
  18. package/build/enum/normalized-attribute.enum.js +10 -0
  19. package/build/enum/permission-key.enum.js +18 -0
  20. package/build/enum/product-image-duplicate-mode.enum.js +11 -0
  21. package/build/schemas/action-log/action-log-payload.schema.js +4 -0
  22. package/build/schemas/action-log/merge-product-images-action-log.schema.js +11 -0
  23. package/build/schemas/action-log/normalize-attributes-action-log.schema.js +21 -0
  24. package/build/schemas/attribute-normalization/attribute-normalization-scope.schema.js +32 -0
  25. package/build/schemas/attribute-normalization/normalization-decision.schema.js +20 -0
  26. package/build/schemas/attribute-normalization/normalization-row-count.schema.js +8 -0
  27. package/build/schemas/attribute-normalization/normalization-summary.schema.js +31 -0
  28. package/build/schemas/attribute-normalization/normalization-value.schema.js +19 -0
  29. package/build/schemas/attribute-normalization/product-image-duplicate-forecast.schema.js +15 -0
  30. package/build/schemas/index.js +8 -0
  31. package/build/schemas/product-image/product-image-merge-candidate.schema.js +22 -0
  32. package/build/schemas/product-image/product-image-merge-group.schema.js +11 -0
  33. package/commands/attribute-normalization/analyze-attribute-normalization.query.ts +24 -0
  34. package/commands/attribute-normalization/execute-attribute-normalization.command.ts +32 -0
  35. package/commands/attribute-normalization/get-grower-suggestions.query.ts +28 -0
  36. package/commands/attribute-normalization/index.ts +3 -0
  37. package/commands/index.ts +1 -0
  38. package/commands/product-image/analyze-product-image-merge.query.ts +28 -0
  39. package/commands/product-image/execute-product-image-merge.command.ts +27 -0
  40. package/commands/product-image/index.ts +2 -0
  41. package/constant/attribute-normalization.constant.ts +9 -0
  42. package/constant/error.ts +50 -0
  43. package/constant/index.ts +2 -0
  44. package/constant/product-image-merge.constant.ts +8 -0
  45. package/enum/action-log-type.enum.ts +2 -0
  46. package/enum/index.ts +5 -0
  47. package/enum/normalization-decision-action.enum.ts +9 -0
  48. package/enum/normalization-target.enum.ts +8 -0
  49. package/enum/normalization-value-state.enum.ts +9 -0
  50. package/enum/normalized-attribute.enum.ts +6 -0
  51. package/enum/permission-key.enum.ts +18 -0
  52. package/enum/product-image-duplicate-mode.enum.ts +7 -0
  53. package/package.json +1 -1
  54. package/schemas/action-log/action-log-payload.schema.ts +4 -0
  55. package/schemas/action-log/merge-product-images-action-log.schema.ts +9 -0
  56. package/schemas/action-log/normalize-attributes-action-log.schema.ts +21 -0
  57. package/schemas/attribute-normalization/attribute-normalization-scope.schema.ts +31 -0
  58. package/schemas/attribute-normalization/normalization-decision.schema.ts +18 -0
  59. package/schemas/attribute-normalization/normalization-row-count.schema.ts +6 -0
  60. package/schemas/attribute-normalization/normalization-summary.schema.ts +29 -0
  61. package/schemas/attribute-normalization/normalization-value.schema.ts +17 -0
  62. package/schemas/attribute-normalization/product-image-duplicate-forecast.schema.ts +13 -0
  63. package/schemas/index.ts +8 -0
  64. package/schemas/product-image/product-image-merge-candidate.schema.ts +20 -0
  65. package/schemas/product-image/product-image-merge-group.schema.ts +9 -0
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AnalyzeAttributeNormalizationContractQuery = void 0;
4
+ const zod_1 = require("zod");
5
+ const attribute_normalization_scope_schema_1 = require("../../schemas/attribute-normalization/attribute-normalization-scope.schema");
6
+ const normalization_value_schema_1 = require("../../schemas/attribute-normalization/normalization-value.schema");
7
+ const normalization_summary_schema_1 = require("../../schemas/attribute-normalization/normalization-summary.schema");
8
+ const AnalyzeAttributeNormalizationRequestSchema = attribute_normalization_scope_schema_1.AttributeNormalizationScopeSchema;
9
+ const AnalyzeAttributeNormalizationResponseSchema = zod_1.z.object({
10
+ data: zod_1.z.object({
11
+ values: zod_1.z.array(normalization_value_schema_1.NormalizationValueSchema),
12
+ summary: normalization_summary_schema_1.NormalizationSummarySchema,
13
+ }),
14
+ });
15
+ var AnalyzeAttributeNormalizationContractQuery;
16
+ (function (AnalyzeAttributeNormalizationContractQuery) {
17
+ AnalyzeAttributeNormalizationContractQuery.RequestSchema = AnalyzeAttributeNormalizationRequestSchema;
18
+ AnalyzeAttributeNormalizationContractQuery.ResponseSchema = AnalyzeAttributeNormalizationResponseSchema;
19
+ })(AnalyzeAttributeNormalizationContractQuery || (exports.AnalyzeAttributeNormalizationContractQuery = AnalyzeAttributeNormalizationContractQuery = {}));
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExecuteAttributeNormalizationContractCommand = void 0;
4
+ const zod_1 = require("zod");
5
+ const attribute_normalization_scope_schema_1 = require("../../schemas/attribute-normalization/attribute-normalization-scope.schema");
6
+ const normalization_decision_schema_1 = require("../../schemas/attribute-normalization/normalization-decision.schema");
7
+ const normalization_row_count_schema_1 = require("../../schemas/attribute-normalization/normalization-row-count.schema");
8
+ const ExecuteAttributeNormalizationRequestSchema = attribute_normalization_scope_schema_1.AttributeNormalizationScopeSchema.extend({
9
+ // Верхней границы нет намеренно: анализ отдаёт все написания компании, и применение обязано
10
+ // принять их целиком — иначе прогон пришлось бы дробить, а разбиение на части снова открывает
11
+ // цепочки A→B и B→C, которые валидатор ловит только внутри одного запроса.
12
+ // Объём ограничен размером тела запроса, а стоимость — чанкованием при записи.
13
+ decisions: zod_1.z.array(normalization_decision_schema_1.NormalizationDecisionSchema).min(1),
14
+ });
15
+ const ExecuteAttributeNormalizationResponseSchema = zod_1.z.object({
16
+ data: zod_1.z.object({
17
+ // Фактически изменённых строк по каждой таблице — считается по результату UPDATE,
18
+ // а не по предсказанию анализа: охват мог измениться.
19
+ updatedRows: normalization_row_count_schema_1.NormalizationRowCountSchema,
20
+ appliedDecisions: zod_1.z.number(),
21
+ actionLogUUID: zod_1.z.string().nullable(),
22
+ }),
23
+ });
24
+ var ExecuteAttributeNormalizationContractCommand;
25
+ (function (ExecuteAttributeNormalizationContractCommand) {
26
+ ExecuteAttributeNormalizationContractCommand.RequestSchema = ExecuteAttributeNormalizationRequestSchema;
27
+ ExecuteAttributeNormalizationContractCommand.ResponseSchema = ExecuteAttributeNormalizationResponseSchema;
28
+ })(ExecuteAttributeNormalizationContractCommand || (exports.ExecuteAttributeNormalizationContractCommand = ExecuteAttributeNormalizationContractCommand = {}));
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetGrowerSuggestionsContractQuery = void 0;
4
+ const zod_1 = require("zod");
5
+ const attribute_normalization_constant_1 = require("../../constant/attribute-normalization.constant");
6
+ // Автокомплит производителя на фронте: union уникальных написаний по товарам, карточкам
7
+ // и позициям коллекций. Справочника Grower нет и мы его не заводим.
8
+ const GetGrowerSuggestionsRequestSchema = zod_1.z.object({
9
+ search: zod_1.z.string().trim().min(1).max(attribute_normalization_constant_1.ATTRIBUTE_NORMALIZATION_LIMITS.MAX_VALUE_LENGTH).optional(),
10
+ count: zod_1.z.coerce
11
+ .number()
12
+ .int()
13
+ .min(1)
14
+ .max(attribute_normalization_constant_1.ATTRIBUTE_NORMALIZATION_LIMITS.MAX_GROWER_SUGGESTIONS)
15
+ .default(attribute_normalization_constant_1.ATTRIBUTE_NORMALIZATION_LIMITS.MAX_GROWER_SUGGESTIONS),
16
+ });
17
+ const GetGrowerSuggestionsResponseSchema = zod_1.z.object({
18
+ data: zod_1.z.object({
19
+ growers: zod_1.z.array(zod_1.z.string()),
20
+ }),
21
+ });
22
+ var GetGrowerSuggestionsContractQuery;
23
+ (function (GetGrowerSuggestionsContractQuery) {
24
+ GetGrowerSuggestionsContractQuery.RequestSchema = GetGrowerSuggestionsRequestSchema;
25
+ GetGrowerSuggestionsContractQuery.ResponseSchema = GetGrowerSuggestionsResponseSchema;
26
+ })(GetGrowerSuggestionsContractQuery || (exports.GetGrowerSuggestionsContractQuery = GetGrowerSuggestionsContractQuery = {}));
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetGrowerSuggestionsContractQuery = exports.ExecuteAttributeNormalizationContractCommand = exports.AnalyzeAttributeNormalizationContractQuery = void 0;
4
+ var analyze_attribute_normalization_query_1 = require("./analyze-attribute-normalization.query");
5
+ Object.defineProperty(exports, "AnalyzeAttributeNormalizationContractQuery", { enumerable: true, get: function () { return analyze_attribute_normalization_query_1.AnalyzeAttributeNormalizationContractQuery; } });
6
+ var execute_attribute_normalization_command_1 = require("./execute-attribute-normalization.command");
7
+ Object.defineProperty(exports, "ExecuteAttributeNormalizationContractCommand", { enumerable: true, get: function () { return execute_attribute_normalization_command_1.ExecuteAttributeNormalizationContractCommand; } });
8
+ var get_grower_suggestions_query_1 = require("./get-grower-suggestions.query");
9
+ Object.defineProperty(exports, "GetGrowerSuggestionsContractQuery", { enumerable: true, get: function () { return get_grower_suggestions_query_1.GetGrowerSuggestionsContractQuery; } });
@@ -84,3 +84,4 @@ var validate_ws_ticket_s2s_query_1 = require("./session/validate-ws-ticket-s2s.q
84
84
  Object.defineProperty(exports, "ValidateWsTicketS2SContractQuery", { enumerable: true, get: function () { return validate_ws_ticket_s2s_query_1.ValidateWsTicketS2SContractQuery; } });
85
85
  __exportStar(require("./consignment-transfer"), exports);
86
86
  __exportStar(require("./transfer-document"), exports);
87
+ __exportStar(require("./attribute-normalization"), exports);
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AnalyzeProductImageMergeContractQuery = void 0;
4
+ const zod_1 = require("zod");
5
+ const product_image_duplicate_mode_enum_1 = require("../../enum/product-image-duplicate-mode.enum");
6
+ const product_image_merge_group_schema_1 = require("../../schemas/product-image/product-image-merge-group.schema");
7
+ const AnalyzeProductImageMergeRequestSchema = zod_1.z.object({
8
+ mode: zod_1.z.nativeEnum(product_image_duplicate_mode_enum_1.ProductImageDuplicateModeEnum).default(product_image_duplicate_mode_enum_1.ProductImageDuplicateModeEnum.CURRENT),
9
+ });
10
+ const AnalyzeProductImageMergeResponseSchema = zod_1.z.object({
11
+ data: zod_1.z.object({
12
+ groups: zod_1.z.array(product_image_merge_group_schema_1.ProductImageMergeGroupSchema),
13
+ // Живых карточек у компании всего — чтобы фронт показал масштаб.
14
+ totalImages: zod_1.z.number(),
15
+ duplicateImages: zod_1.z.number(),
16
+ }),
17
+ });
18
+ var AnalyzeProductImageMergeContractQuery;
19
+ (function (AnalyzeProductImageMergeContractQuery) {
20
+ AnalyzeProductImageMergeContractQuery.RequestSchema = AnalyzeProductImageMergeRequestSchema;
21
+ AnalyzeProductImageMergeContractQuery.ResponseSchema = AnalyzeProductImageMergeResponseSchema;
22
+ })(AnalyzeProductImageMergeContractQuery || (exports.AnalyzeProductImageMergeContractQuery = AnalyzeProductImageMergeContractQuery = {}));
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExecuteProductImageMergeContractCommand = void 0;
4
+ const zod_1 = require("zod");
5
+ const product_image_merge_constant_1 = require("../../constant/product-image-merge.constant");
6
+ const ExecuteProductImageMergeRequestSchema = zod_1.z.object({
7
+ primaryUUID: zod_1.z.string().uuid(),
8
+ // Верхняя граница на группу: склейка идёт одной транзакцией, и неограниченный список
9
+ // упёрся бы в её таймаут. Реальные группы дублей — единицы карточек.
10
+ mergedUUIDList: zod_1.z.array(zod_1.z.string().uuid()).min(1).max(product_image_merge_constant_1.PRODUCT_IMAGE_MERGE_LIMITS.MAX_MERGED_PER_REQUEST),
11
+ });
12
+ const ExecuteProductImageMergeResponseSchema = zod_1.z.object({
13
+ data: zod_1.z.object({
14
+ relinkedProducts: zod_1.z.number(),
15
+ relinkedPreOrderCollectionItems: zod_1.z.number(),
16
+ movedAliases: zod_1.z.number(),
17
+ droppedAliases: zod_1.z.number(),
18
+ mergedImages: zod_1.z.number(),
19
+ }),
20
+ });
21
+ var ExecuteProductImageMergeContractCommand;
22
+ (function (ExecuteProductImageMergeContractCommand) {
23
+ ExecuteProductImageMergeContractCommand.RequestSchema = ExecuteProductImageMergeRequestSchema;
24
+ ExecuteProductImageMergeContractCommand.ResponseSchema = ExecuteProductImageMergeResponseSchema;
25
+ })(ExecuteProductImageMergeContractCommand || (exports.ExecuteProductImageMergeContractCommand = ExecuteProductImageMergeContractCommand = {}));
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.ExecuteProductImageMergeContractCommand = exports.AnalyzeProductImageMergeContractQuery = void 0;
17
18
  __exportStar(require("./create-product-image.command"), exports);
18
19
  __exportStar(require("./update-product-image.command"), exports);
19
20
  __exportStar(require("./delete-product-image.command"), exports);
@@ -30,3 +31,7 @@ __exportStar(require("./alias/update-product-image-alias.command"), exports);
30
31
  __exportStar(require("./alias/delete-product-image-alias.command"), exports);
31
32
  __exportStar(require("./alias/bulk-create-product-image-alias.command"), exports);
32
33
  __exportStar(require("./alias/bulk-create-product-image-alias-from-pre-order-collection-item.command"), exports);
34
+ var analyze_product_image_merge_query_1 = require("./analyze-product-image-merge.query");
35
+ Object.defineProperty(exports, "AnalyzeProductImageMergeContractQuery", { enumerable: true, get: function () { return analyze_product_image_merge_query_1.AnalyzeProductImageMergeContractQuery; } });
36
+ var execute_product_image_merge_command_1 = require("./execute-product-image-merge.command");
37
+ Object.defineProperty(exports, "ExecuteProductImageMergeContractCommand", { enumerable: true, get: function () { return execute_product_image_merge_command_1.ExecuteProductImageMergeContractCommand; } });
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ATTRIBUTE_NORMALIZATION_LIMITS = void 0;
4
+ exports.ATTRIBUTE_NORMALIZATION_LIMITS = {
5
+ // Размер чанка для UPDATE ... WHERE поле IN (...).
6
+ UPDATE_CHUNK_SIZE: 200,
7
+ // Сколько уникальных написаний производителя отдавать в автокомплит.
8
+ MAX_GROWER_SUGGESTIONS: 500,
9
+ // Колонки атрибутов — text без ограничения; без границы одно решение раскатало бы
10
+ // многомегабайтную строку по всей истории компании и осело бы в журнале действий.
11
+ MAX_VALUE_LENGTH: 255,
12
+ };
@@ -1511,4 +1511,54 @@ exports.ERRORS = {
1511
1511
  message: 'Transfer document number start cannot be decreased',
1512
1512
  httpCode: 400,
1513
1513
  },
1514
+ ATTRIBUTE_NORMALIZATION_ANALYZE_FAILED: {
1515
+ code: 'ANORM001',
1516
+ message: 'Error when analyzing attribute normalization',
1517
+ httpCode: 500,
1518
+ },
1519
+ ATTRIBUTE_NORMALIZATION_EXECUTE_FAILED: {
1520
+ code: 'ANORM002',
1521
+ message: 'Error when applying attribute normalization',
1522
+ httpCode: 500,
1523
+ },
1524
+ ATTRIBUTE_NORMALIZATION_EMPTY_SCOPE: {
1525
+ code: 'ANORM003',
1526
+ message: 'None of the selected targets stores the selected attributes',
1527
+ httpCode: 400,
1528
+ },
1529
+ PRODUCT_IMAGE_MERGE_TOO_MANY_IMAGES: {
1530
+ code: 'PI015',
1531
+ message: 'Too many product images to analyze duplicates in one pass',
1532
+ httpCode: 400,
1533
+ },
1534
+ ATTRIBUTE_NORMALIZATION_INVALID_DECISIONS: {
1535
+ code: 'ANORM006',
1536
+ message: 'Normalization decisions are inconsistent',
1537
+ httpCode: 400,
1538
+ },
1539
+ CATALOG_BULK_REWRITE_LOCK_UNAVAILABLE: {
1540
+ code: 'ANORM007',
1541
+ message: 'Cannot guarantee exclusive execution right now, try again later',
1542
+ httpCode: 503,
1543
+ },
1544
+ ATTRIBUTE_NORMALIZATION_ALREADY_RUNNING: {
1545
+ code: 'ANORM005',
1546
+ message: 'Another attribute normalization run is already in progress for this company',
1547
+ httpCode: 409,
1548
+ },
1549
+ PRODUCT_IMAGE_MERGE_NOT_DUPLICATES: {
1550
+ code: 'PI017',
1551
+ message: 'Selected product images are not duplicates of the primary one',
1552
+ httpCode: 409,
1553
+ },
1554
+ PRODUCT_IMAGE_MERGE_ALREADY_RUNNING: {
1555
+ code: 'PI016',
1556
+ message: 'Another product image merge is already in progress for this company',
1557
+ httpCode: 409,
1558
+ },
1559
+ GROWER_SUGGESTIONS_FETCH_FAILED: {
1560
+ code: 'ANORM004',
1561
+ message: 'Error when retrieving grower suggestions',
1562
+ httpCode: 500,
1563
+ },
1514
1564
  };
@@ -26,3 +26,5 @@ __exportStar(require("./okei"), exports);
26
26
  __exportStar(require("./contact-phone.constant"), exports);
27
27
  __exportStar(require("./settings.constant"), exports);
28
28
  __exportStar(require("./consignment-product-enrichment.constant"), exports);
29
+ __exportStar(require("./attribute-normalization.constant"), exports);
30
+ __exportStar(require("./product-image-merge.constant"), exports);
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PRODUCT_IMAGE_MERGE_LIMITS = void 0;
4
+ exports.PRODUCT_IMAGE_MERGE_LIMITS = {
5
+ // Поиск дублей группирует карточки в приложении, а не в SQL: канон цвета живёт в словаре
6
+ // на стороне кода. Значит все карточки компании оказываются в памяти, и объём надо ограничить
7
+ // явно — иначе на очень крупной компании анализ молча съест память процесса.
8
+ MAX_ANALYZED_IMAGES: 100000,
9
+ // Сколько карточек можно поглотить за один запрос: всё идёт одной транзакцией.
10
+ MAX_MERGED_PER_REQUEST: 200,
11
+ };
@@ -23,4 +23,6 @@ var ActionLogTypeEnum;
23
23
  ActionLogTypeEnum["DELETE_CONSIGNMENT_ITEMS"] = "DELETE_CONSIGNMENT_ITEMS";
24
24
  ActionLogTypeEnum["GROUP_UPDATE_CONSIGNMENT_ITEMS"] = "GROUP_UPDATE_CONSIGNMENT_ITEMS";
25
25
  ActionLogTypeEnum["TRANSFER_CONSIGNMENT_ITEMS"] = "TRANSFER_CONSIGNMENT_ITEMS";
26
+ ActionLogTypeEnum["NORMALIZE_ATTRIBUTES"] = "NORMALIZE_ATTRIBUTES";
27
+ ActionLogTypeEnum["MERGE_PRODUCT_IMAGES"] = "MERGE_PRODUCT_IMAGES";
26
28
  })(ActionLogTypeEnum || (exports.ActionLogTypeEnum = ActionLogTypeEnum = {}));
@@ -124,3 +124,8 @@ __exportStar(require("./transfer-document-item-kind.enum"), exports);
124
124
  __exportStar(require("./write-off-report-date-basis.enum"), exports);
125
125
  __exportStar(require("./product-enrichment-field.enum"), exports);
126
126
  __exportStar(require("./product-enrichment-field-state.enum"), exports);
127
+ __exportStar(require("./normalized-attribute.enum"), exports);
128
+ __exportStar(require("./normalization-target.enum"), exports);
129
+ __exportStar(require("./normalization-value-state.enum"), exports);
130
+ __exportStar(require("./normalization-decision-action.enum"), exports);
131
+ __exportStar(require("./product-image-duplicate-mode.enum"), exports);
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NormalizationDecisionActionEnum = void 0;
4
+ // Решение человека по одному написанию. Правила в БД не сохраняются — решение живёт один прогон.
5
+ var NormalizationDecisionActionEnum;
6
+ (function (NormalizationDecisionActionEnum) {
7
+ // Переписать на указанное значение.
8
+ NormalizationDecisionActionEnum["MAP"] = "MAP";
9
+ // Очистить поле (значение — мусор).
10
+ NormalizationDecisionActionEnum["CLEAR"] = "CLEAR";
11
+ // Оставить как есть.
12
+ NormalizationDecisionActionEnum["KEEP"] = "KEEP";
13
+ })(NormalizationDecisionActionEnum || (exports.NormalizationDecisionActionEnum = NormalizationDecisionActionEnum = {}));
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NormalizationTargetEnum = void 0;
4
+ // Таблицы, попадающие в охват нормализации. PRODUCT_CONFIGURATION сужается только компанией:
5
+ // правила кратности нормализуются целиком, иначе они разъедутся с товарами.
6
+ var NormalizationTargetEnum;
7
+ (function (NormalizationTargetEnum) {
8
+ NormalizationTargetEnum["PRODUCT"] = "PRODUCT";
9
+ NormalizationTargetEnum["PRODUCT_IMAGE"] = "PRODUCT_IMAGE";
10
+ NormalizationTargetEnum["PRE_ORDER_COLLECTION_ITEM"] = "PRE_ORDER_COLLECTION_ITEM";
11
+ NormalizationTargetEnum["PRODUCT_CONFIGURATION"] = "PRODUCT_CONFIGURATION";
12
+ })(NormalizationTargetEnum || (exports.NormalizationTargetEnum = NormalizationTargetEnum = {}));
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NormalizationValueStateEnum = void 0;
4
+ // Что анализ знает про конкретное написание атрибута.
5
+ var NormalizationValueStateEnum;
6
+ (function (NormalizationValueStateEnum) {
7
+ // Словарь (или кластеризация для производителя) предложил другое написание.
8
+ NormalizationValueStateEnum["SUGGESTED"] = "SUGGESTED";
9
+ // Значение уже каноничное, менять нечего.
10
+ NormalizationValueStateEnum["CANONICAL"] = "CANONICAL";
11
+ // Словарь значение не узнал — решение принимает человек в рамках прогона.
12
+ NormalizationValueStateEnum["UNRECOGNIZED"] = "UNRECOGNIZED";
13
+ })(NormalizationValueStateEnum || (exports.NormalizationValueStateEnum = NormalizationValueStateEnum = {}));
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NormalizedAttributeEnum = void 0;
4
+ // Справочные атрибуты, которые умеет приводить к единому написанию операция нормализации.
5
+ var NormalizedAttributeEnum;
6
+ (function (NormalizedAttributeEnum) {
7
+ NormalizedAttributeEnum["COLOR"] = "COLOR";
8
+ NormalizedAttributeEnum["COUNTRY"] = "COUNTRY";
9
+ NormalizedAttributeEnum["GROWER"] = "GROWER";
10
+ })(NormalizedAttributeEnum || (exports.NormalizedAttributeEnum = NormalizedAttributeEnum = {}));
@@ -21,6 +21,16 @@ var PermissionKeyEnum;
21
21
  PermissionKeyEnum["PAGE_PRE_ORDERS_VIEW"] = "page.pre_orders.view";
22
22
  PermissionKeyEnum["PAGE_REPORT_VIEW"] = "page.report.view";
23
23
  PermissionKeyEnum["PAGE_STAFF_VIEW"] = "page.staff.view";
24
+ PermissionKeyEnum["ORDER_CREATE"] = "order.create";
25
+ PermissionKeyEnum["ORDER_EDIT"] = "order.edit";
26
+ PermissionKeyEnum["ORDER_DELETE"] = "order.delete";
27
+ // Order-level money edits: discount and delivery cost (скидка и стоимость доставки).
28
+ PermissionKeyEnum["ORDER_PRICE_EDIT"] = "order.price.edit";
29
+ PermissionKeyEnum["ORDER_STATUS_CHANGE"] = "order.status.change";
30
+ PermissionKeyEnum["WRITE_OFF_CREATE"] = "write_off.create";
31
+ PermissionKeyEnum["WRITE_OFF_DELETE"] = "write_off.delete";
32
+ // Moving a write-off out of PENDING (принятие / отклонение списания).
33
+ PermissionKeyEnum["WRITE_OFF_APPROVE"] = "write_off.approve";
24
34
  })(PermissionKeyEnum || (exports.PermissionKeyEnum = PermissionKeyEnum = {}));
25
35
  exports.PERMISSION_KEY_LIST = [
26
36
  PermissionKeyEnum.PRODUCT_VIEW,
@@ -39,4 +49,12 @@ exports.PERMISSION_KEY_LIST = [
39
49
  PermissionKeyEnum.PAGE_PRE_ORDERS_VIEW,
40
50
  PermissionKeyEnum.PAGE_REPORT_VIEW,
41
51
  PermissionKeyEnum.PAGE_STAFF_VIEW,
52
+ PermissionKeyEnum.ORDER_CREATE,
53
+ PermissionKeyEnum.ORDER_EDIT,
54
+ PermissionKeyEnum.ORDER_DELETE,
55
+ PermissionKeyEnum.ORDER_PRICE_EDIT,
56
+ PermissionKeyEnum.ORDER_STATUS_CHANGE,
57
+ PermissionKeyEnum.WRITE_OFF_CREATE,
58
+ PermissionKeyEnum.WRITE_OFF_DELETE,
59
+ PermissionKeyEnum.WRITE_OFF_APPROVE,
42
60
  ];
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProductImageDuplicateModeEnum = void 0;
4
+ // В каком виде искать дубли карточек.
5
+ var ProductImageDuplicateModeEnum;
6
+ (function (ProductImageDuplicateModeEnum) {
7
+ // По значениям как они лежат сейчас.
8
+ ProductImageDuplicateModeEnum["CURRENT"] = "CURRENT";
9
+ // По значениям, приведённым к канону — превью того, что слипнется после нормализации.
10
+ ProductImageDuplicateModeEnum["AFTER_NORMALIZATION"] = "AFTER_NORMALIZATION";
11
+ })(ProductImageDuplicateModeEnum || (exports.ProductImageDuplicateModeEnum = ProductImageDuplicateModeEnum = {}));
@@ -20,6 +20,8 @@ const consignment_items_create_action_log_schema_1 = require("./consignment-item
20
20
  const consignment_items_delete_action_log_schema_1 = require("./consignment-items-delete-action-log.schema");
21
21
  const group_update_consignment_items_action_log_schema_1 = require("./group-update-consignment-items-action-log.schema");
22
22
  const transfer_consignment_items_action_log_schema_1 = require("./transfer-consignment-items-action-log.schema");
23
+ const normalize_attributes_action_log_schema_1 = require("./normalize-attributes-action-log.schema");
24
+ const merge_product_images_action_log_schema_1 = require("./merge-product-images-action-log.schema");
23
25
  exports.ActionLogPayloadSchema = zod_1.z.union([
24
26
  order_delete_action_log_payload_schema_1.OrderDeleteActionLogPayloadSchema,
25
27
  order_merge_action_log_schema_1.OrderMergeActionLogSchema,
@@ -39,5 +41,7 @@ exports.ActionLogPayloadSchema = zod_1.z.union([
39
41
  consignment_items_delete_action_log_schema_1.ConsignmentItemsDeleteActionLogSchema,
40
42
  group_update_consignment_items_action_log_schema_1.GroupUpdateConsignmentItemsActionLogSchema,
41
43
  transfer_consignment_items_action_log_schema_1.TransferConsignmentItemsActionLogSchema,
44
+ normalize_attributes_action_log_schema_1.NormalizeAttributesActionLogSchema,
45
+ merge_product_images_action_log_schema_1.MergeProductImagesActionLogSchema,
42
46
  zod_1.z.null(),
43
47
  ]);
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MergeProductImagesActionLogSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.MergeProductImagesActionLogSchema = zod_1.z.object({
6
+ primaryImageUUID: zod_1.z.string(),
7
+ mergedImageUUIDList: zod_1.z.array(zod_1.z.string()),
8
+ relinkedProducts: zod_1.z.number(),
9
+ relinkedPreOrderCollectionItems: zod_1.z.number(),
10
+ movedAliases: zod_1.z.number(),
11
+ });
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NormalizeAttributesActionLogSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const normalized_attribute_enum_1 = require("../../enum/normalized-attribute.enum");
6
+ const normalization_target_enum_1 = require("../../enum/normalization-target.enum");
7
+ const normalization_decision_action_enum_1 = require("../../enum/normalization-decision-action.enum");
8
+ // Одна агрегатная запись на прогон: построчный лог тут не нужен, операция работает
9
+ // на уникальных значениях, а не на строках.
10
+ exports.NormalizeAttributesActionLogSchema = zod_1.z.object({
11
+ attributes: zod_1.z.array(zod_1.z.nativeEnum(normalized_attribute_enum_1.NormalizedAttributeEnum)),
12
+ targets: zod_1.z.array(zod_1.z.nativeEnum(normalization_target_enum_1.NormalizationTargetEnum)),
13
+ decisions: zod_1.z.array(zod_1.z.object({
14
+ attribute: zod_1.z.nativeEnum(normalized_attribute_enum_1.NormalizedAttributeEnum),
15
+ raw: zod_1.z.string(),
16
+ action: zod_1.z.nativeEnum(normalization_decision_action_enum_1.NormalizationDecisionActionEnum),
17
+ value: zod_1.z.string().nullable(),
18
+ })),
19
+ updatedRows: zod_1.z.partialRecord(zod_1.z.nativeEnum(normalization_target_enum_1.NormalizationTargetEnum), zod_1.z.number()),
20
+ totalUpdatedRows: zod_1.z.number(),
21
+ });
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AttributeNormalizationScopeSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const normalized_attribute_enum_1 = require("../../enum/normalized-attribute.enum");
6
+ const normalization_target_enum_1 = require("../../enum/normalization-target.enum");
7
+ /**
8
+ * Охват прогона. Общий для анализа и применения: execute перепроверяет его заново, потому что
9
+ * между анализом и применением в таблицы могли приехать новые строки.
10
+ *
11
+ * Ограничения охвата, которые нельзя выразить схемой и которые проверяет сервис:
12
+ * - consignmentUUIDList сужает только PRODUCT — у карточек и позиций коллекций нет поставки;
13
+ * - preOrderCollectionUUIDList сужает только PRE_ORDER_COLLECTION_ITEM;
14
+ * - PRODUCT_CONFIGURATION не сужается ничем, кроме компании: правила нормализуются целиком,
15
+ * иначе часть из них разъедется с товарами.
16
+ */
17
+ // Дедупликация в схеме, а не в сервисе: списки читают и analyze, и execute, и запись в журнал —
18
+ // повтор «PRODUCT» тысячу раз означал бы тысячу полных проходов по таблице товаров.
19
+ const dedupe = (list) => Array.from(new Set(list));
20
+ exports.AttributeNormalizationScopeSchema = zod_1.z.object({
21
+ attributes: zod_1.z.array(zod_1.z.nativeEnum(normalized_attribute_enum_1.NormalizedAttributeEnum)).min(1).max(Object.keys(normalized_attribute_enum_1.NormalizedAttributeEnum).length).transform(dedupe),
22
+ targets: zod_1.z.array(zod_1.z.nativeEnum(normalization_target_enum_1.NormalizationTargetEnum)).min(1).max(Object.keys(normalization_target_enum_1.NormalizationTargetEnum).length).transform(dedupe),
23
+ // Без верхней границы: списки уходят в запрос одним параметром-массивом, длина упирается
24
+ // только в размер тела запроса.
25
+ consignmentUUIDList: zod_1.z.array(zod_1.z.string().uuid()).optional(),
26
+ preOrderCollectionUUIDList: zod_1.z.array(zod_1.z.string().uuid()).optional(),
27
+ createdFrom: zod_1.z.coerce.date().optional(),
28
+ createdTo: zod_1.z.coerce.date().optional(),
29
+ // У поставки нет признака закрытости — закрытость живёт на товаре (Product.isOpen).
30
+ // По умолчанию закрытые товары не трогаем: это распроданная история.
31
+ isIncludingClosedProducts: zod_1.z.boolean().default(false),
32
+ });
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NormalizationDecisionSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const normalized_attribute_enum_1 = require("../../enum/normalized-attribute.enum");
6
+ const normalization_decision_action_enum_1 = require("../../enum/normalization-decision-action.enum");
7
+ const attribute_normalization_constant_1 = require("../../constant/attribute-normalization.constant");
8
+ // Решение человека по одному написанию. Правила в БД не сохраняются — решение живёт один прогон.
9
+ exports.NormalizationDecisionSchema = zod_1.z
10
+ .object({
11
+ attribute: zod_1.z.nativeEnum(normalized_attribute_enum_1.NormalizedAttributeEnum),
12
+ raw: zod_1.z.string().min(1).max(attribute_normalization_constant_1.ATTRIBUTE_NORMALIZATION_LIMITS.MAX_VALUE_LENGTH),
13
+ action: zod_1.z.nativeEnum(normalization_decision_action_enum_1.NormalizationDecisionActionEnum),
14
+ // Целевое написание — обязательно и только для MAP.
15
+ value: zod_1.z.string().min(1).max(attribute_normalization_constant_1.ATTRIBUTE_NORMALIZATION_LIMITS.MAX_VALUE_LENGTH).optional(),
16
+ })
17
+ .refine(decision => (decision.action === normalization_decision_action_enum_1.NormalizationDecisionActionEnum.MAP) === (decision.value !== undefined), {
18
+ message: 'value is required for MAP and forbidden otherwise',
19
+ path: ['value'],
20
+ });
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NormalizationRowCountSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const normalization_target_enum_1 = require("../../enum/normalization-target.enum");
6
+ // Сколько строк приходится на каждую таблицу охвата. Ключи неполные: значение живёт
7
+ // не во всех таблицах сразу, а таблица может не хранить нужный атрибут.
8
+ exports.NormalizationRowCountSchema = zod_1.z.partialRecord(zod_1.z.nativeEnum(normalization_target_enum_1.NormalizationTargetEnum), zod_1.z.number());
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NormalizationSummarySchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const normalized_attribute_enum_1 = require("../../enum/normalized-attribute.enum");
6
+ const normalization_target_enum_1 = require("../../enum/normalization-target.enum");
7
+ const normalization_row_count_schema_1 = require("./normalization-row-count.schema");
8
+ const product_image_duplicate_forecast_schema_1 = require("./product-image-duplicate-forecast.schema");
9
+ // Итоги анализа: всё, что фронт показывает перед запуском необратимой операции.
10
+ exports.NormalizationSummarySchema = zod_1.z.object({
11
+ // Уникальных написаний по каждому атрибуту.
12
+ uniqueValues: zod_1.z.partialRecord(zod_1.z.nativeEnum(normalized_attribute_enum_1.NormalizedAttributeEnum), zod_1.z.number()),
13
+ // Строк к изменению по каждой таблице, если принять все предложения. Считается по строкам:
14
+ // строка, у которой меняются и цвет, и страна, — это одна строка, а не две.
15
+ affectedRows: normalization_row_count_schema_1.NormalizationRowCountSchema,
16
+ // Строк, которые прогон пропустит из-за того, что позиция закрыта. Нужно фронту, чтобы
17
+ // предложить включить их флагом: по умолчанию закрытая история не трогается.
18
+ // null означает «пропускать нечего»: либо флаг уже включён, либо ни одна таблица охвата
19
+ // не различает открытые и закрытые позиции.
20
+ skippedClosedRows: normalization_row_count_schema_1.NormalizationRowCountSchema.nullable(),
21
+ // Строк заказов, отображающих затрагиваемые товары. Нужно фронту для предупреждения:
22
+ // операция необратима, а в заказах видно старое написание.
23
+ affectedOrderProductRows: zod_1.z.number(),
24
+ // Таблицы, которых не касается сужение по выбранным поставкам и коллекциям: у карточки
25
+ // номенклатуры нет поставки, у товара нет коллекции. Для них охват остаётся широким —
26
+ // фронт обязан предупредить, иначе админ будет думать, что тронет одну поставку,
27
+ // а прогон перепишет всю компанию.
28
+ targetsIgnoringUuidScope: zod_1.z.array(zod_1.z.nativeEnum(normalization_target_enum_1.NormalizationTargetEnum)),
29
+ // null означает, что карточки в охват не входят и прогон их не трогает.
30
+ productImageDuplicatesAfterRun: product_image_duplicate_forecast_schema_1.ProductImageDuplicateForecastSchema.nullable(),
31
+ });
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NormalizationValueSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const normalized_attribute_enum_1 = require("../../enum/normalized-attribute.enum");
6
+ const normalization_value_state_enum_1 = require("../../enum/normalization-value-state.enum");
7
+ const normalization_row_count_schema_1 = require("./normalization-row-count.schema");
8
+ // Одно написание атрибута в истории компании и то, что операция про него знает.
9
+ exports.NormalizationValueSchema = zod_1.z.object({
10
+ attribute: zod_1.z.nativeEnum(normalized_attribute_enum_1.NormalizedAttributeEnum),
11
+ // Написание как оно лежит в базе — оно же ключ решения в execute.
12
+ raw: zod_1.z.string(),
13
+ // Что предлагает словарь (для производителя — кластеризация). null, если предложить нечего.
14
+ suggested: zod_1.z.string().nullable(),
15
+ state: zod_1.z.nativeEnum(normalization_value_state_enum_1.NormalizationValueStateEnum),
16
+ rowCount: normalization_row_count_schema_1.NormalizationRowCountSchema,
17
+ // Другие написания того же кластера — только для производителя, у цвета и страны словарь.
18
+ clusterRaw: zod_1.z.array(zod_1.z.string()),
19
+ });
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProductImageDuplicateForecastSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ // Прогноз по дублям карточек номенклатуры после прогона. Уникального ключа по идентичности
6
+ // у карточек нет, поэтому прогон может сделать две карточки неразличимыми, и резолвер начнёт
7
+ // выбирать между ними произвольно. Апдейт при этом не упадёт — предупредить можно только заранее.
8
+ exports.ProductImageDuplicateForecastSchema = zod_1.z.object({
9
+ // false — посчитать не удалось (карточек больше предела). Это НЕ то же самое,
10
+ // что «дублей не будет»: при false числа ниже не значат ничего.
11
+ isCounted: zod_1.z.boolean(),
12
+ total: zod_1.z.number(),
13
+ // Из них те, что сегодня ещё различимы: именно их создаст этот прогон.
14
+ new: zod_1.z.number(),
15
+ });
@@ -100,3 +100,11 @@ __exportStar(require("./positive-money.schema"), exports);
100
100
  __exportStar(require("./report/report-order-filter.schema"), exports);
101
101
  __exportStar(require("./transfer-document/transfer-document.schema"), exports);
102
102
  __exportStar(require("./transfer-document/transfer-document-detailed.schema"), exports);
103
+ __exportStar(require("./attribute-normalization/attribute-normalization-scope.schema"), exports);
104
+ __exportStar(require("./product-image/product-image-merge-candidate.schema"), exports);
105
+ __exportStar(require("./product-image/product-image-merge-group.schema"), exports);
106
+ __exportStar(require("./attribute-normalization/normalization-row-count.schema"), exports);
107
+ __exportStar(require("./attribute-normalization/normalization-value.schema"), exports);
108
+ __exportStar(require("./attribute-normalization/normalization-summary.schema"), exports);
109
+ __exportStar(require("./attribute-normalization/normalization-decision.schema"), exports);
110
+ __exportStar(require("./attribute-normalization/product-image-duplicate-forecast.schema"), exports);
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProductImageMergeCandidateSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ // Карточка — участник группы дублей, с числом ссылок на неё.
6
+ exports.ProductImageMergeCandidateSchema = zod_1.z.object({
7
+ uuid: zod_1.z.string(),
8
+ name: zod_1.z.string(),
9
+ // Ключ файла в хранилище: без него нечем показать превью фото группы, а основную
10
+ // карточку админ выбирает в том числе по картинке.
11
+ productImageUrl: zod_1.z.string(),
12
+ categoryUUID: zod_1.z.string().nullable(),
13
+ grower: zod_1.z.string().nullable(),
14
+ country: zod_1.z.string().nullable(),
15
+ color: zod_1.z.string().nullable(),
16
+ productCount: zod_1.z.number(),
17
+ preOrderCollectionItemCount: zod_1.z.number(),
18
+ aliasCount: zod_1.z.number(),
19
+ // Карточка, которую операция предлагает оставить: больше всего ссылок, при равенстве —
20
+ // меньший uuid, чтобы повторный анализ давал тот же ответ.
21
+ isPrimary: zod_1.z.boolean(),
22
+ });
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProductImageMergeGroupSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const product_image_merge_candidate_schema_1 = require("./product-image-merge-candidate.schema");
6
+ // Группа карточек, неразличимых по идентичности.
7
+ exports.ProductImageMergeGroupSchema = zod_1.z.object({
8
+ // Ключ группы — нормализованная идентичность, по которой карточки признаны одинаковыми.
9
+ key: zod_1.z.string(),
10
+ candidates: zod_1.z.array(product_image_merge_candidate_schema_1.ProductImageMergeCandidateSchema),
11
+ });