@fiado/type-kit 3.538.0 → 3.540.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 (94) hide show
  1. package/_test_/unit/retailCustomer/ensureCustomerByPhoneRequest.test.ts +30 -0
  2. package/_test_/unit/retailWizard/accessorySaleRequests.test.ts +108 -0
  3. package/_test_/unit/retailWizard/cancelSaleConditions.test.ts +2 -1
  4. package/_test_/unit/retailWizard/portalCancelSaleRequest.test.ts +34 -0
  5. package/bin/index.d.ts +1 -0
  6. package/bin/index.js +3 -1
  7. package/bin/retailCustomer/dtos/requests/EnsureCustomerByPhoneRequest.d.ts +9 -0
  8. package/bin/retailCustomer/dtos/requests/EnsureCustomerByPhoneRequest.js +34 -0
  9. package/bin/retailCustomer/dtos/responses/EnsureCustomerByPhoneResponse.d.ts +5 -0
  10. package/bin/retailCustomer/dtos/responses/EnsureCustomerByPhoneResponse.js +2 -0
  11. package/bin/retailCustomer/index.d.ts +2 -0
  12. package/bin/retailCustomer/index.js +2 -0
  13. package/bin/retailWizard/dtos/AccessorySaleLine.d.ts +7 -0
  14. package/bin/retailWizard/dtos/AccessorySaleLine.js +38 -0
  15. package/bin/retailWizard/dtos/Sale.d.ts +5 -1
  16. package/bin/retailWizard/dtos/requests/CreateAccessorySaleRequest.d.ts +18 -0
  17. package/bin/retailWizard/dtos/requests/CreateAccessorySaleRequest.js +69 -0
  18. package/bin/retailWizard/dtos/requests/PortalCancelSaleRequest.d.ts +12 -0
  19. package/bin/retailWizard/dtos/requests/PortalCancelSaleRequest.js +43 -0
  20. package/bin/retailWizard/dtos/requests/SendAccessoryOtpRequest.d.ts +4 -0
  21. package/bin/retailWizard/dtos/requests/SendAccessoryOtpRequest.js +25 -0
  22. package/bin/retailWizard/dtos/requests/VerifyAccessoryOtpRequest.d.ts +4 -0
  23. package/bin/retailWizard/dtos/requests/VerifyAccessoryOtpRequest.js +24 -0
  24. package/bin/retailWizard/dtos/responses/AccessoryOtpChallenge.d.ts +7 -0
  25. package/bin/retailWizard/dtos/responses/AccessoryOtpChallenge.js +2 -0
  26. package/bin/retailWizard/dtos/responses/VerifyAccessoryOtpResponse.d.ts +7 -0
  27. package/bin/retailWizard/dtos/responses/VerifyAccessoryOtpResponse.js +2 -0
  28. package/bin/retailWizard/enums/SaleChannelEnum.d.ts +5 -0
  29. package/bin/retailWizard/enums/SaleChannelEnum.js +9 -0
  30. package/bin/retailWizard/index.d.ts +8 -0
  31. package/bin/retailWizard/index.js +8 -0
  32. package/bin/rules/constants/RulesLimits.d.ts +8 -0
  33. package/bin/rules/constants/RulesLimits.js +11 -0
  34. package/bin/rules/dtos/EvaluateRulesRequest.d.ts +30 -0
  35. package/bin/rules/dtos/EvaluateRulesRequest.js +84 -0
  36. package/bin/rules/dtos/EvaluateRulesResponse.d.ts +17 -0
  37. package/bin/rules/dtos/EvaluateRulesResponse.js +11 -0
  38. package/bin/rules/dtos/GenerateRulesRequest.d.ts +20 -0
  39. package/bin/rules/dtos/GenerateRulesRequest.js +60 -0
  40. package/bin/rules/dtos/GenerateRulesResponse.d.ts +12 -0
  41. package/bin/rules/dtos/GenerateRulesResponse.js +7 -0
  42. package/bin/rules/dtos/RulesCatalogResponse.d.ts +36 -0
  43. package/bin/rules/dtos/RulesCatalogResponse.js +14 -0
  44. package/bin/rules/dtos/RulesChatMessage.d.ts +6 -0
  45. package/bin/rules/dtos/RulesChatMessage.js +32 -0
  46. package/bin/rules/dtos/RulesTraceResponse.d.ts +32 -0
  47. package/bin/rules/dtos/RulesTraceResponse.js +17 -0
  48. package/bin/rules/dtos/ValidateRulesRequest.d.ts +15 -0
  49. package/bin/rules/dtos/ValidateRulesRequest.js +44 -0
  50. package/bin/rules/dtos/ValidateRulesResponse.d.ts +6 -0
  51. package/bin/rules/dtos/ValidateRulesResponse.js +7 -0
  52. package/bin/rules/enums/RulesChatRoleEnum.d.ts +5 -0
  53. package/bin/rules/enums/RulesChatRoleEnum.js +9 -0
  54. package/bin/rules/enums/RulesErrorCodeEnum.d.ts +7 -0
  55. package/bin/rules/enums/RulesErrorCodeEnum.js +11 -0
  56. package/bin/rules/enums/RulesGenerationStatusEnum.d.ts +6 -0
  57. package/bin/rules/enums/RulesGenerationStatusEnum.js +10 -0
  58. package/bin/rules/enums/RulesOutcomeEnum.d.ts +6 -0
  59. package/bin/rules/enums/RulesOutcomeEnum.js +10 -0
  60. package/bin/rules/enums/RulesValueTypeEnum.d.ts +9 -0
  61. package/bin/rules/enums/RulesValueTypeEnum.js +13 -0
  62. package/bin/rules/index.d.ts +15 -0
  63. package/bin/rules/index.js +34 -0
  64. package/package.json +1 -1
  65. package/src/index.ts +3 -0
  66. package/src/retailCustomer/dtos/requests/EnsureCustomerByPhoneRequest.ts +20 -0
  67. package/src/retailCustomer/dtos/responses/EnsureCustomerByPhoneResponse.ts +6 -0
  68. package/src/retailCustomer/index.ts +2 -0
  69. package/src/retailWizard/dtos/AccessorySaleLine.ts +23 -0
  70. package/src/retailWizard/dtos/Sale.ts +5 -1
  71. package/src/retailWizard/dtos/requests/CreateAccessorySaleRequest.ts +64 -0
  72. package/src/retailWizard/dtos/requests/PortalCancelSaleRequest.ts +29 -0
  73. package/src/retailWizard/dtos/requests/SendAccessoryOtpRequest.ts +11 -0
  74. package/src/retailWizard/dtos/requests/VerifyAccessoryOtpRequest.ts +10 -0
  75. package/src/retailWizard/dtos/responses/AccessoryOtpChallenge.ts +7 -0
  76. package/src/retailWizard/dtos/responses/VerifyAccessoryOtpResponse.ts +7 -0
  77. package/src/retailWizard/enums/SaleChannelEnum.ts +5 -0
  78. package/src/retailWizard/index.ts +8 -0
  79. package/src/rules/constants/RulesLimits.ts +8 -0
  80. package/src/rules/dtos/EvaluateRulesRequest.ts +67 -0
  81. package/src/rules/dtos/EvaluateRulesResponse.ts +19 -0
  82. package/src/rules/dtos/GenerateRulesRequest.ts +49 -0
  83. package/src/rules/dtos/GenerateRulesResponse.ts +11 -0
  84. package/src/rules/dtos/RulesCatalogResponse.ts +35 -0
  85. package/src/rules/dtos/RulesChatMessage.ts +17 -0
  86. package/src/rules/dtos/RulesTraceResponse.ts +32 -0
  87. package/src/rules/dtos/ValidateRulesRequest.ts +33 -0
  88. package/src/rules/dtos/ValidateRulesResponse.ts +6 -0
  89. package/src/rules/enums/RulesChatRoleEnum.ts +5 -0
  90. package/src/rules/enums/RulesErrorCodeEnum.ts +7 -0
  91. package/src/rules/enums/RulesGenerationStatusEnum.ts +6 -0
  92. package/src/rules/enums/RulesOutcomeEnum.ts +6 -0
  93. package/src/rules/enums/RulesValueTypeEnum.ts +9 -0
  94. package/src/rules/index.ts +20 -0
@@ -0,0 +1,6 @@
1
+ /** Resultado de evaluar una regla para un sujeto (`POST /evaluate`). */
2
+ export declare enum RulesOutcomeEnum {
3
+ MATCH = "MATCH",
4
+ NO_MATCH = "NO_MATCH",
5
+ ERROR = "ERROR"
6
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RulesOutcomeEnum = void 0;
4
+ /** Resultado de evaluar una regla para un sujeto (`POST /evaluate`). */
5
+ var RulesOutcomeEnum;
6
+ (function (RulesOutcomeEnum) {
7
+ RulesOutcomeEnum["MATCH"] = "MATCH";
8
+ RulesOutcomeEnum["NO_MATCH"] = "NO_MATCH";
9
+ RulesOutcomeEnum["ERROR"] = "ERROR";
10
+ })(RulesOutcomeEnum || (exports.RulesOutcomeEnum = RulesOutcomeEnum = {}));
@@ -0,0 +1,9 @@
1
+ /** Tipo de valor de un campo del catálogo de reglas (`GET /catalog`). */
2
+ export declare enum RulesValueTypeEnum {
3
+ NUMBER = "NUMBER",
4
+ STRING = "STRING",
5
+ BOOLEAN = "BOOLEAN",
6
+ DATE = "DATE",
7
+ /** Lista de textos (ej. `directory.scope`). */
8
+ STRING_LIST = "STRING_LIST"
9
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RulesValueTypeEnum = void 0;
4
+ /** Tipo de valor de un campo del catálogo de reglas (`GET /catalog`). */
5
+ var RulesValueTypeEnum;
6
+ (function (RulesValueTypeEnum) {
7
+ RulesValueTypeEnum["NUMBER"] = "NUMBER";
8
+ RulesValueTypeEnum["STRING"] = "STRING";
9
+ RulesValueTypeEnum["BOOLEAN"] = "BOOLEAN";
10
+ RulesValueTypeEnum["DATE"] = "DATE";
11
+ /** Lista de textos (ej. `directory.scope`). */
12
+ RulesValueTypeEnum["STRING_LIST"] = "STRING_LIST";
13
+ })(RulesValueTypeEnum || (exports.RulesValueTypeEnum = RulesValueTypeEnum = {}));
@@ -0,0 +1,15 @@
1
+ export * from './enums/RulesOutcomeEnum';
2
+ export * from './enums/RulesGenerationStatusEnum';
3
+ export * from './enums/RulesChatRoleEnum';
4
+ export * from './enums/RulesValueTypeEnum';
5
+ export * from './enums/RulesErrorCodeEnum';
6
+ export * from './constants/RulesLimits';
7
+ export * from './dtos/RulesCatalogResponse';
8
+ export * from './dtos/ValidateRulesRequest';
9
+ export * from './dtos/ValidateRulesResponse';
10
+ export * from './dtos/RulesChatMessage';
11
+ export * from './dtos/GenerateRulesRequest';
12
+ export * from './dtos/GenerateRulesResponse';
13
+ export * from './dtos/RulesTraceResponse';
14
+ export * from './dtos/EvaluateRulesRequest';
15
+ export * from './dtos/EvaluateRulesResponse';
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ //Enums
18
+ __exportStar(require("./enums/RulesOutcomeEnum"), exports);
19
+ __exportStar(require("./enums/RulesGenerationStatusEnum"), exports);
20
+ __exportStar(require("./enums/RulesChatRoleEnum"), exports);
21
+ __exportStar(require("./enums/RulesValueTypeEnum"), exports);
22
+ __exportStar(require("./enums/RulesErrorCodeEnum"), exports);
23
+ //Constants
24
+ __exportStar(require("./constants/RulesLimits"), exports);
25
+ //DTOs
26
+ __exportStar(require("./dtos/RulesCatalogResponse"), exports);
27
+ __exportStar(require("./dtos/ValidateRulesRequest"), exports);
28
+ __exportStar(require("./dtos/ValidateRulesResponse"), exports);
29
+ __exportStar(require("./dtos/RulesChatMessage"), exports);
30
+ __exportStar(require("./dtos/GenerateRulesRequest"), exports);
31
+ __exportStar(require("./dtos/GenerateRulesResponse"), exports);
32
+ __exportStar(require("./dtos/RulesTraceResponse"), exports);
33
+ __exportStar(require("./dtos/EvaluateRulesRequest"), exports);
34
+ __exportStar(require("./dtos/EvaluateRulesResponse"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.538.0",
3
+ "version": "3.540.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
package/src/index.ts CHANGED
@@ -213,3 +213,6 @@ export * as DatalakeReports from './datalakeReports';
213
213
 
214
214
  // PdfRender: DTOs del lambda pdf-render-business (plantilla HTML → PDF multitenant y su backoffice).
215
215
  export * as PdfRender from './pdfRender';
216
+
217
+ // Rules: DTOs del lambda central rules-business (catálogo, validación, generación con IA y evaluación de reglas).
218
+ export * as Rules from './rules';
@@ -0,0 +1,20 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsString, Matches, MinLength } from 'class-validator';
3
+ import { regexPhoneMx } from '../../../helpers/constans/regex';
4
+
5
+ /**
6
+ * POST /private/customers/ensure-by-phone — da de alta al cliente solo con su celular verificado,
7
+ * o devuelve el que ya existe con ese número.
8
+ */
9
+ export class EnsureCustomerByPhoneRequest {
10
+ @Expose()
11
+ @IsString()
12
+ @Matches(regexPhoneMx, { message: 'phone debe tener 10 dígitos' })
13
+ phone!: string;
14
+
15
+ /** Tienda del primer contacto; no cambia si el cliente ya existía. */
16
+ @Expose()
17
+ @IsString()
18
+ @MinLength(1)
19
+ originStoreId!: string;
20
+ }
@@ -0,0 +1,6 @@
1
+ import { CustomerResponse } from './CustomerResponse';
2
+
3
+ /** Cliente resuelto por celular; `created` dice si esta llamada lo dio de alta. */
4
+ export interface EnsureCustomerByPhoneResponse extends CustomerResponse {
5
+ created: boolean;
6
+ }
@@ -24,6 +24,7 @@ export * from './dtos/requests/KycReviewRequest';
24
24
  export * from './dtos/requests/WelcomeAccreditationRequest';
25
25
  export * from './dtos/requests/WelcomeAccreditationResultRequest';
26
26
  export * from './dtos/requests/UpsertPromotionBonusRequest';
27
+ export * from './dtos/requests/EnsureCustomerByPhoneRequest';
27
28
 
28
29
  // Response DTOs
29
30
  export * from './dtos/responses/CustomerResponse';
@@ -31,6 +32,7 @@ export * from './dtos/responses/Customer360Response';
31
32
  export * from './dtos/responses/WelcomeBonusResponse';
32
33
  export * from './dtos/responses/WelcomeAccreditationResponse';
33
34
  export * from './dtos/responses/PromotionBonusEntryResponse';
35
+ export * from './dtos/responses/EnsureCustomerByPhoneResponse';
34
36
 
35
37
  // Contratos de eventos (PascalCase + sufijo V1)
36
38
  export * from './events/CustomerCreatedV1';
@@ -0,0 +1,23 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { ArrayMaxSize, IsArray, IsInt, IsOptional, IsString, Min, MinLength } from 'class-validator';
3
+
4
+ /** Línea del carrito de accesorios; el precio lo pone el catálogo, no el request. */
5
+ export class AccessorySaleLine {
6
+ @Expose()
7
+ @IsString()
8
+ @MinLength(1)
9
+ sku!: string;
10
+
11
+ @Expose()
12
+ @IsInt()
13
+ @Min(1)
14
+ qty!: number;
15
+
16
+ /** Serie de cada pieza cuando el SKU se rastrea por pieza; ausente si se rastrea por cantidad. */
17
+ @Expose()
18
+ @IsOptional()
19
+ @IsArray()
20
+ @ArrayMaxSize(100)
21
+ @IsString({ each: true })
22
+ identifiers?: string[];
23
+ }
@@ -1,6 +1,7 @@
1
1
  import type { SaleTypeEnum } from '../enums/SaleTypeEnum';
2
2
  import type { SaleStatusEnum } from '../enums/SaleStatusEnum';
3
3
  import type { SalePaymentMethodEnum } from '../enums/SalePaymentMethodEnum';
4
+ import type { SaleChannelEnum } from '../enums/SaleChannelEnum';
4
5
  import type { ExternalProviderEnum } from '../enums/ExternalProviderEnum';
5
6
  import type { CentralSyncStatusEnum } from '../enums/CentralSyncStatusEnum';
6
7
  import type { SalePaymentDetail } from './SalePaymentDetail';
@@ -18,7 +19,10 @@ export interface Sale {
18
19
  storeId: string;
19
20
  sellerRetailUserId: string;
20
21
  retailCustomerId: string;
21
- wizardSessionId: string;
22
+ /** Sesión del wizard que cerró la venta; ausente en la venta de mostrador. */
23
+ wizardSessionId?: string;
24
+ /** Canal de la venta; ausente = `WIZARD` (ventas anteriores al campo). */
25
+ saleChannel?: SaleChannelEnum;
22
26
  type: SaleTypeEnum;
23
27
  externalProvider: ExternalProviderEnum | null;
24
28
  /** SKU del teléfono de la venta; `null` en la venta sin teléfono (en DDB se omite). */
@@ -0,0 +1,64 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import {
3
+ ArrayMaxSize,
4
+ ArrayMinSize,
5
+ IsArray,
6
+ IsBoolean,
7
+ IsDefined,
8
+ IsEnum,
9
+ IsInt,
10
+ IsOptional,
11
+ IsString,
12
+ Min,
13
+ MinLength,
14
+ ValidateNested,
15
+ } from 'class-validator';
16
+ import { SalePaymentMethodEnum } from '../../enums/SalePaymentMethodEnum';
17
+ import { SalePaymentDetail } from '../SalePaymentDetail';
18
+ import { AccessorySaleLine } from '../AccessorySaleLine';
19
+
20
+ /**
21
+ * POST /wizard/accessory-sales — cierra la venta de mostrador con el celular ya verificado.
22
+ * `amountCents` es lo cobrado en caja y debe igualar la suma del catálogo.
23
+ */
24
+ export class CreateAccessorySaleRequest {
25
+ @Expose()
26
+ @IsString()
27
+ @MinLength(1)
28
+ otpChallengeId!: string;
29
+
30
+ @Expose()
31
+ @IsArray()
32
+ @ArrayMinSize(1)
33
+ @ArrayMaxSize(50)
34
+ @ValidateNested({ each: true })
35
+ @Type(() => AccessorySaleLine)
36
+ lines!: AccessorySaleLine[];
37
+
38
+ @Expose()
39
+ @IsEnum(SalePaymentMethodEnum)
40
+ paymentMethod!: SalePaymentMethodEnum;
41
+
42
+ @Expose()
43
+ @IsInt()
44
+ @Min(0)
45
+ amountCents!: number;
46
+
47
+ @Expose()
48
+ @IsDefined()
49
+ @ValidateNested()
50
+ @Type(() => SalePaymentDetail)
51
+ paymentDetail!: SalePaymentDetail;
52
+
53
+ /** El cliente aceptó el aviso de privacidad; sin `true` el back responde 400 PRIVACY_NOTICE_REQUIRED. */
54
+ @Expose()
55
+ @IsOptional()
56
+ @IsBoolean()
57
+ privacyNoticeAccepted?: boolean;
58
+
59
+ /** Versión del aviso de privacidad que se mostró. */
60
+ @Expose()
61
+ @IsString()
62
+ @MinLength(1)
63
+ privacyNoticeVersion!: string;
64
+ }
@@ -0,0 +1,29 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import { IsArray, IsBoolean, IsOptional, IsString, MaxLength, MinLength, ValidateNested } from 'class-validator';
3
+ import { ReturnPieceCondition } from '../../../retailCatalog/dtos/requests/ReturnPieceCondition';
4
+
5
+ /**
6
+ * POST /portal/sales/:saleId/cancel — el vendedor cancela una venta cerrada de su tienda, dentro de la
7
+ * ventana. Mismas validaciones que `BackofficeCancelSaleRequest`, sin la excepción de cancelación tardía.
8
+ */
9
+ export class PortalCancelSaleRequest {
10
+ @Expose()
11
+ @IsString()
12
+ @MinLength(10)
13
+ @MaxLength(200)
14
+ reason!: string;
15
+
16
+ /** Equipo o piezas confirmados en tienda; ausente cuenta como no confirmado. */
17
+ @Expose()
18
+ @IsOptional()
19
+ @IsBoolean()
20
+ equipmentVerified?: boolean;
21
+
22
+ /** Condición de cada pieza que regresa al inventario; las no listadas vuelven GOOD. */
23
+ @Expose()
24
+ @IsOptional()
25
+ @IsArray()
26
+ @ValidateNested({ each: true })
27
+ @Type(() => ReturnPieceCondition)
28
+ returnConditions?: ReturnPieceCondition[];
29
+ }
@@ -0,0 +1,11 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsString, Matches } from 'class-validator';
3
+ import { regexPhoneMx } from '../../../helpers/constans/regex';
4
+
5
+ /** POST /wizard/accessory-sales/otp — manda el OTP al celular del cliente del mostrador. */
6
+ export class SendAccessoryOtpRequest {
7
+ @Expose()
8
+ @IsString()
9
+ @Matches(regexPhoneMx, { message: 'phone debe tener 10 dígitos' })
10
+ phone!: string;
11
+ }
@@ -0,0 +1,10 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsString, Length } from 'class-validator';
3
+
4
+ /** POST /wizard/accessory-sales/otp/{otpChallengeId}/verify — código que dicta el cliente. */
5
+ export class VerifyAccessoryOtpRequest {
6
+ @Expose()
7
+ @IsString()
8
+ @Length(4, 8)
9
+ code!: string;
10
+ }
@@ -0,0 +1,7 @@
1
+ /** Reto OTP del mostrador de accesorios (send y resend). `phoneMasked` muestra solo los últimos 4 dígitos. */
2
+ export interface AccessoryOtpChallenge {
3
+ otpChallengeId: string;
4
+ phoneMasked: string;
5
+ expiresAt: string;
6
+ resendAvailableAt: string;
7
+ }
@@ -0,0 +1,7 @@
1
+ /** Reto verificado: ampara una sola venta hasta `usableUntil`. */
2
+ export interface VerifyAccessoryOtpResponse {
3
+ otpChallengeId: string;
4
+ verified: true;
5
+ verifiedAt: string;
6
+ usableUntil: string;
7
+ }
@@ -0,0 +1,5 @@
1
+ /** Canal por el que se cerró la venta: el wizard por sesión o el mostrador de accesorios. */
2
+ export enum SaleChannelEnum {
3
+ WIZARD = 'WIZARD',
4
+ ACCESSORY_COUNTER = 'ACCESSORY_COUNTER',
5
+ }
@@ -32,6 +32,7 @@ export * from './enums/WizardLineStatusEnum';
32
32
  export * from './enums/LinePaymentTypeEnum';
33
33
  export * from './enums/WizardLineRoleEnum';
34
34
  export * from './enums/EmailStateEnum';
35
+ export * from './enums/SaleChannelEnum';
35
36
 
36
37
  // DTOs anidados
37
38
  export * from './dtos/WizardConsents';
@@ -57,6 +58,7 @@ export * from './dtos/WizardFinancingPreview';
57
58
  export * from './dtos/WizardReservedLine';
58
59
  export * from './dtos/WizardGiftLine';
59
60
  export * from './dtos/SaleLine';
61
+ export * from './dtos/AccessorySaleLine';
60
62
 
61
63
  // Entidades principales (shapes de estado/persistencia — planas)
62
64
  export * from './dtos/WizardSession';
@@ -108,6 +110,9 @@ export * from './dtos/requests/CompleteSaleRequest';
108
110
  export * from './dtos/requests/SuggestIdentifiersQuery';
109
111
  export * from './dtos/requests/SendEmailOtpRequest';
110
112
  export * from './dtos/requests/VerifyEmailOtpRequest';
113
+ export * from './dtos/requests/SendAccessoryOtpRequest';
114
+ export * from './dtos/requests/VerifyAccessoryOtpRequest';
115
+ export * from './dtos/requests/CreateAccessorySaleRequest';
111
116
 
112
117
  // Response DTOs (output tipado por endpoint)
113
118
  export * from './dtos/responses/KycPrepareResponse';
@@ -128,6 +133,8 @@ export * from './dtos/responses/ProspectResumeResponse';
128
133
  export * from './dtos/responses/CancelOtherStoreSaleResponse';
129
134
  export * from './dtos/responses/ProspectByPhoneResponse';
130
135
  export * from './dtos/responses/AppOnboardingResponse';
136
+ export * from './dtos/responses/AccessoryOtpChallenge';
137
+ export * from './dtos/responses/VerifyAccessoryOtpResponse';
131
138
 
132
139
  // ── F3 · Backoffice VentasLuga ────────────────────────────────────────────────
133
140
  // Enums
@@ -160,6 +167,7 @@ export * from './dtos/requests/ApplySaleExceptionRequest';
160
167
  export * from './dtos/requests/AddSaleExceptionNoteRequest';
161
168
  export * from './dtos/requests/RunSalesReportRequest';
162
169
  export * from './dtos/requests/BackofficeCancelSaleRequest';
170
+ export * from './dtos/requests/PortalCancelSaleRequest';
163
171
 
164
172
  // Responses
165
173
  export * from './dtos/responses/BackofficeSalesStatsResponse';
@@ -0,0 +1,8 @@
1
+ /** Máximo de sujetos por llamada a `POST /evaluate` (si no, 400 `TOO_MANY_SUBJECTS`). */
2
+ export const RULES_MAX_SUBJECTS_PER_CALL = 100;
3
+ /** Fuente especial: datos que el llamador manda en la llamada, no se resuelven ni se piden en `items`. */
4
+ export const RULES_INPUT_SOURCE = 'input';
5
+ /** Máximo de campos del contrato de `input`. */
6
+ export const RULES_MAX_INPUT_CONTRACT = 30;
7
+ /** Largo máximo (caracteres) del contenido de un turno del chat de `POST /generate`. */
8
+ export const RULES_CHAT_TURN_MAX_LENGTH = 4000;
@@ -0,0 +1,67 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import { IsArray, IsISO8601, IsObject, IsOptional, IsString, ValidateNested } from 'class-validator';
3
+ import { JsonValue } from '../../common';
4
+ import { DynamicFormValue } from '../../dynamicForm/types/DynamicFormValue';
5
+
6
+ /** A quién se le evalúa la regla. */
7
+ export class RulesEvaluationSubject {
8
+ @Expose()
9
+ @IsString()
10
+ directoryId: string;
11
+
12
+ /** Otros participantes del evento: llegan al motor como `ctx.subjects[key] = { directoryId }`. */
13
+ @Expose()
14
+ @IsOptional()
15
+ @IsObject()
16
+ subjects?: Record<string, { directoryId: string }>;
17
+
18
+ /** Datos escalares del evento: forman la fuente `input`. */
19
+ @Expose()
20
+ @IsOptional()
21
+ @IsObject()
22
+ inputs?: Record<string, DynamicFormValue>;
23
+ }
24
+
25
+ export class RuleToEvaluate {
26
+ @Expose()
27
+ @IsString()
28
+ id: string;
29
+
30
+ /** La regla (`{ match, groups[] }`). */
31
+ @Expose()
32
+ @IsObject()
33
+ rule: { [key: string]: JsonValue };
34
+ }
35
+
36
+ /** `POST /evaluate`. El límite de 100 sujetos lo valida el lambda (400 `TOO_MANY_SUBJECTS`), no el DTO. */
37
+ export class EvaluateRulesRequest {
38
+ /** Quién llama (solo logs y métricas). */
39
+ @Expose()
40
+ @IsOptional()
41
+ @IsString()
42
+ consumer?: string;
43
+
44
+ /** Ids de ítems del catálogo (`source:key`) que las reglas pueden usar. */
45
+ @Expose()
46
+ @IsArray()
47
+ @IsString({ each: true })
48
+ items: string[];
49
+
50
+ @Expose()
51
+ @IsArray()
52
+ @ValidateNested({ each: true })
53
+ @Type(() => RuleToEvaluate)
54
+ rules: RuleToEvaluate[];
55
+
56
+ @Expose()
57
+ @IsArray()
58
+ @ValidateNested({ each: true })
59
+ @Type(() => RulesEvaluationSubject)
60
+ subjects: RulesEvaluationSubject[];
61
+
62
+ /** Fecha ISO 8601; por defecto, el momento de la llamada. */
63
+ @Expose()
64
+ @IsOptional()
65
+ @IsISO8601()
66
+ referenceAt?: string;
67
+ }
@@ -0,0 +1,19 @@
1
+ import { RulesOutcomeEnum } from '../enums/RulesOutcomeEnum';
2
+ import { RulesTraceResponse } from './RulesTraceResponse';
3
+
4
+ /** Resultado de una regla para un sujeto. */
5
+ export class RuleEvaluationResult {
6
+ ruleId: string;
7
+ /** Posición del sujeto en `EvaluateRulesRequest.subjects`. */
8
+ subjectIndex: number;
9
+ directoryId: string;
10
+ outcome: RulesOutcomeEnum;
11
+ trace?: RulesTraceResponse;
12
+ /** Solo si `outcome` es `ERROR`. */
13
+ errorMessage?: string;
14
+ }
15
+
16
+ /** `POST /evaluate`: ordenado por regla y, dentro de cada regla, por `subjectIndex`. */
17
+ export class EvaluateRulesResponse {
18
+ results: RuleEvaluationResult[];
19
+ }
@@ -0,0 +1,49 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import { ArrayMaxSize, ArrayMinSize, IsArray, IsObject, IsOptional, IsString, ValidateNested } from 'class-validator';
3
+ import { JsonValue } from '../../common';
4
+ import { InputField } from '../../dynamicForm/dtos/InputField';
5
+ import { RULES_MAX_INPUT_CONTRACT } from '../constants/RulesLimits';
6
+ import { RulesChatMessage } from './RulesChatMessage';
7
+
8
+ /** `POST /generate`: el chat que genera una regla con IA sobre el catálogo de los ítems indicados. */
9
+ export class GenerateRulesRequest {
10
+ /** Quién llama (solo logs y métricas). */
11
+ @Expose()
12
+ @IsOptional()
13
+ @IsString()
14
+ consumer?: string;
15
+
16
+ /** Ids de ítems del catálogo (`source:key`) que la IA puede usar. */
17
+ @Expose()
18
+ @IsArray()
19
+ @IsString({ each: true })
20
+ items: string[];
21
+
22
+ /** Contrato de la fuente `input` (`InputField[]`, dominio `dynamicForm`). */
23
+ @Expose()
24
+ @IsOptional()
25
+ @IsArray()
26
+ @ArrayMaxSize(RULES_MAX_INPUT_CONTRACT)
27
+ @IsObject({ each: true })
28
+ inputContract?: InputField[];
29
+
30
+ /** Del turno más viejo al más nuevo; el último es del usuario. */
31
+ @Expose()
32
+ @IsArray()
33
+ @ArrayMinSize(1)
34
+ @ValidateNested({ each: true })
35
+ @Type(() => RulesChatMessage)
36
+ messages: RulesChatMessage[];
37
+
38
+ /** Contexto libre del llamador para el prompt. */
39
+ @Expose()
40
+ @IsOptional()
41
+ @IsString()
42
+ context?: string;
43
+
44
+ /** La regla que el editor tiene ahora, para refinarla. Ausente = regla nueva. */
45
+ @Expose()
46
+ @IsOptional()
47
+ @IsObject()
48
+ currentRule?: { [key: string]: JsonValue };
49
+ }
@@ -0,0 +1,11 @@
1
+ import { JsonValue } from '../../common';
2
+ import { RulesGenerationStatusEnum } from '../enums/RulesGenerationStatusEnum';
3
+
4
+ /** Resultado de `POST /generate`. `status: OK` con `rule: null` = la IA hizo una pregunta (sin regla). */
5
+ export class GenerateRulesResponse {
6
+ status: RulesGenerationStatusEnum;
7
+ rule: { [key: string]: JsonValue } | null;
8
+ explanation: string;
9
+ /** Problemas de validación (vacío salvo `FAILED`). */
10
+ errors: string[];
11
+ }
@@ -0,0 +1,35 @@
1
+ import { InputField } from '../../dynamicForm/dtos/InputField';
2
+ import { RulesValueTypeEnum } from '../enums/RulesValueTypeEnum';
3
+
4
+ /** Un campo que un ítem del catálogo resuelve para las reglas. */
5
+ export class RulesCatalogFieldResponse {
6
+ field: string;
7
+ label: string;
8
+ valueType: RulesValueTypeEnum;
9
+ /** Operadores válidos para este campo (`GT`, `LTE`, `IN`…). */
10
+ operators: string[];
11
+ /** Params del campo (ej. ventana y moneda de `sumAmount`), como formulario dinámico. */
12
+ params?: InputField[];
13
+ /** Valores posibles si es un enum (con qué significa cada uno, si se sabe). */
14
+ options?: { value: string; label: string; description?: string }[];
15
+ /** Qué es este campo, en una frase. */
16
+ description?: string;
17
+ /** Frases de ejemplo que típicamente piden este campo (ayuda del chat de IA). */
18
+ examplePhrases?: string[];
19
+ }
20
+
21
+ /** Un ítem del catálogo: una fuente + una llave de búsqueda (`source:key`). */
22
+ export class RulesCatalogItemResponse {
23
+ id: string;
24
+ source: string;
25
+ key: string;
26
+ label: string;
27
+ description: string;
28
+ fields: RulesCatalogFieldResponse[];
29
+ }
30
+
31
+ export class RulesCatalogResponse {
32
+ items: RulesCatalogItemResponse[];
33
+ /** Etiqueta legible de cada operador (`GTE` → «≥»). */
34
+ operators: Record<string, string>;
35
+ }
@@ -0,0 +1,17 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsEnum, IsNotEmpty, IsString, MaxLength } from 'class-validator';
3
+ import { RULES_CHAT_TURN_MAX_LENGTH } from '../constants/RulesLimits';
4
+ import { RulesChatRoleEnum } from '../enums/RulesChatRoleEnum';
5
+
6
+ /** Un turno del chat que genera reglas con IA. */
7
+ export class RulesChatMessage {
8
+ @Expose()
9
+ @IsEnum(RulesChatRoleEnum)
10
+ role: RulesChatRoleEnum;
11
+
12
+ @Expose()
13
+ @IsString()
14
+ @IsNotEmpty()
15
+ @MaxLength(RULES_CHAT_TURN_MAX_LENGTH)
16
+ content: string;
17
+ }
@@ -0,0 +1,32 @@
1
+ import { JsonValue } from '../../common';
2
+ import { RulesOutcomeEnum } from '../enums/RulesOutcomeEnum';
3
+
4
+ /**
5
+ * Una condición evaluada: qué se esperaba y qué se encontró.
6
+ * Sin `origin`/`asOf`: el central no sabe de dónde salió el dato; el consumidor (rewards) los agrega.
7
+ */
8
+ export class RulesTraceConditionResponse {
9
+ source: string;
10
+ subject?: string;
11
+ field: string;
12
+ params?: Record<string, string | number | boolean>;
13
+ op: string;
14
+ expected: JsonValue;
15
+ actual?: JsonValue;
16
+ outcome: RulesOutcomeEnum;
17
+ /** Solo si `outcome` es `ERROR`. */
18
+ error?: { code: string; message: string };
19
+ }
20
+
21
+ export class RulesTraceGroupResponse {
22
+ match: 'ALL' | 'ANY';
23
+ outcome: RulesOutcomeEnum;
24
+ conditions: RulesTraceConditionResponse[];
25
+ }
26
+
27
+ /** Traza completa de una evaluación: por qué cumplió o no. */
28
+ export class RulesTraceResponse {
29
+ match: 'ALL' | 'ANY';
30
+ outcome: RulesOutcomeEnum;
31
+ groups: RulesTraceGroupResponse[];
32
+ }