@fiado/type-kit 3.539.0 → 3.541.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 (174) 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/_test_/unit/rules/populationDtos.test.ts +58 -0
  6. package/_test_/unit/rules/populationMove.test.ts +31 -0
  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/rewardsEligibility/constants/SegmentLimits.d.ts +1 -5
  33. package/bin/rewardsEligibility/constants/SegmentLimits.js +15 -6
  34. package/bin/rewardsEligibility/dtos/backoffice/segments/PopulationSegmentDefinition.d.ts +1 -8
  35. package/bin/rewardsEligibility/dtos/backoffice/segments/PopulationSegmentDefinition.js +14 -37
  36. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentAggregateCondition.d.ts +1 -18
  37. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentAggregateCondition.js +14 -68
  38. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentColumnCondition.d.ts +1 -11
  39. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentColumnCondition.js +14 -43
  40. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentGroup.d.ts +1 -9
  41. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentGroup.js +14 -41
  42. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentParam.d.ts +1 -10
  43. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentParam.js +15 -5
  44. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentSchemaResponse.d.ts +1 -10
  45. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentSchemaResponse.js +15 -8
  46. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentTableSchemaResponse.d.ts +1 -12
  47. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentTableSchemaResponse.js +15 -7
  48. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentUsedColumn.d.ts +1 -5
  49. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentUsedColumn.js +15 -4
  50. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentWindow.d.ts +1 -5
  51. package/bin/rewardsEligibility/dtos/backoffice/segments/SegmentWindow.js +14 -28
  52. package/bin/rewardsEligibility/enums/SegmentAggregateFnEnum.d.ts +1 -5
  53. package/bin/rewardsEligibility/enums/SegmentAggregateFnEnum.js +15 -7
  54. package/bin/rewardsEligibility/enums/SegmentConditionKindEnum.d.ts +1 -4
  55. package/bin/rewardsEligibility/enums/SegmentConditionKindEnum.js +15 -6
  56. package/bin/rewardsEligibility/enums/SegmentMatchEnum.d.ts +1 -4
  57. package/bin/rewardsEligibility/enums/SegmentMatchEnum.js +15 -6
  58. package/bin/rewardsEligibility/enums/SegmentOperatorEnum.d.ts +1 -16
  59. package/bin/rewardsEligibility/enums/SegmentOperatorEnum.js +15 -18
  60. package/bin/rewardsEligibility/enums/SegmentParamSourceEnum.d.ts +1 -5
  61. package/bin/rewardsEligibility/enums/SegmentParamSourceEnum.js +15 -7
  62. package/bin/rewardsEligibility/enums/SegmentParamTypeEnum.d.ts +1 -7
  63. package/bin/rewardsEligibility/enums/SegmentParamTypeEnum.js +15 -9
  64. package/bin/rules/constants/SegmentLimits.d.ts +5 -0
  65. package/bin/rules/constants/SegmentLimits.js +8 -0
  66. package/bin/rules/dtos/population/PopulationCompileRequest.d.ts +6 -0
  67. package/bin/rules/dtos/population/PopulationCompileRequest.js +32 -0
  68. package/bin/rules/dtos/population/PopulationCompileResponse.d.ts +9 -0
  69. package/bin/rules/dtos/population/PopulationCompileResponse.js +6 -0
  70. package/bin/rules/dtos/population/PopulationExecutionPageResponse.d.ts +10 -0
  71. package/bin/rules/dtos/population/PopulationExecutionPageResponse.js +7 -0
  72. package/bin/rules/dtos/population/PopulationExecutionRequest.d.ts +10 -0
  73. package/bin/rules/dtos/population/PopulationExecutionRequest.js +59 -0
  74. package/bin/rules/dtos/population/PopulationExecutionResponse.d.ts +5 -0
  75. package/bin/rules/dtos/population/PopulationExecutionResponse.js +6 -0
  76. package/bin/rules/dtos/population/PopulationSegmentDefinition.d.ts +8 -0
  77. package/bin/rules/dtos/population/PopulationSegmentDefinition.js +40 -0
  78. package/bin/rules/dtos/population/PopulationTestRequest.d.ts +7 -0
  79. package/bin/rules/dtos/population/PopulationTestRequest.js +38 -0
  80. package/bin/rules/dtos/population/PopulationTestResponse.d.ts +26 -0
  81. package/bin/rules/dtos/population/PopulationTestResponse.js +13 -0
  82. package/bin/rules/dtos/population/SegmentAggregateCondition.d.ts +18 -0
  83. package/bin/rules/dtos/population/SegmentAggregateCondition.js +71 -0
  84. package/bin/rules/dtos/population/SegmentColumnCondition.d.ts +11 -0
  85. package/bin/rules/dtos/population/SegmentColumnCondition.js +46 -0
  86. package/bin/rules/dtos/population/SegmentGroup.d.ts +9 -0
  87. package/bin/rules/dtos/population/SegmentGroup.js +44 -0
  88. package/bin/rules/dtos/population/SegmentParam.d.ts +10 -0
  89. package/bin/rules/dtos/population/SegmentParam.js +7 -0
  90. package/bin/rules/dtos/population/SegmentSchemaResponse.d.ts +10 -0
  91. package/bin/rules/dtos/population/SegmentSchemaResponse.js +10 -0
  92. package/bin/rules/dtos/population/SegmentTableSchemaResponse.d.ts +12 -0
  93. package/bin/rules/dtos/population/SegmentTableSchemaResponse.js +9 -0
  94. package/bin/rules/dtos/population/SegmentUsedColumn.d.ts +5 -0
  95. package/bin/rules/dtos/population/SegmentUsedColumn.js +6 -0
  96. package/bin/rules/dtos/population/SegmentWindow.d.ts +5 -0
  97. package/bin/rules/dtos/population/SegmentWindow.js +31 -0
  98. package/bin/rules/enums/PopulationErrorCodeEnum.d.ts +12 -0
  99. package/bin/rules/enums/PopulationErrorCodeEnum.js +16 -0
  100. package/bin/rules/enums/PopulationExecutionStatusEnum.d.ts +6 -0
  101. package/bin/rules/enums/PopulationExecutionStatusEnum.js +10 -0
  102. package/bin/rules/enums/PopulationTestStatusEnum.d.ts +5 -0
  103. package/bin/rules/enums/PopulationTestStatusEnum.js +9 -0
  104. package/bin/rules/enums/SegmentAggregateFnEnum.d.ts +5 -0
  105. package/bin/rules/enums/SegmentAggregateFnEnum.js +9 -0
  106. package/bin/rules/enums/SegmentConditionKindEnum.d.ts +4 -0
  107. package/bin/rules/enums/SegmentConditionKindEnum.js +8 -0
  108. package/bin/rules/enums/SegmentMatchEnum.d.ts +4 -0
  109. package/bin/rules/enums/SegmentMatchEnum.js +8 -0
  110. package/bin/rules/enums/SegmentOperatorEnum.d.ts +16 -0
  111. package/bin/rules/enums/SegmentOperatorEnum.js +20 -0
  112. package/bin/rules/enums/SegmentParamSourceEnum.d.ts +5 -0
  113. package/bin/rules/enums/SegmentParamSourceEnum.js +9 -0
  114. package/bin/rules/enums/SegmentParamTypeEnum.d.ts +7 -0
  115. package/bin/rules/enums/SegmentParamTypeEnum.js +11 -0
  116. package/bin/rules/index.d.ts +26 -0
  117. package/bin/rules/index.js +28 -0
  118. package/package.json +1 -1
  119. package/src/retailCustomer/dtos/requests/EnsureCustomerByPhoneRequest.ts +20 -0
  120. package/src/retailCustomer/dtos/responses/EnsureCustomerByPhoneResponse.ts +6 -0
  121. package/src/retailCustomer/index.ts +2 -0
  122. package/src/retailWizard/dtos/AccessorySaleLine.ts +23 -0
  123. package/src/retailWizard/dtos/Sale.ts +5 -1
  124. package/src/retailWizard/dtos/requests/CreateAccessorySaleRequest.ts +64 -0
  125. package/src/retailWizard/dtos/requests/PortalCancelSaleRequest.ts +29 -0
  126. package/src/retailWizard/dtos/requests/SendAccessoryOtpRequest.ts +11 -0
  127. package/src/retailWizard/dtos/requests/VerifyAccessoryOtpRequest.ts +10 -0
  128. package/src/retailWizard/dtos/responses/AccessoryOtpChallenge.ts +7 -0
  129. package/src/retailWizard/dtos/responses/VerifyAccessoryOtpResponse.ts +7 -0
  130. package/src/retailWizard/enums/SaleChannelEnum.ts +5 -0
  131. package/src/retailWizard/index.ts +8 -0
  132. package/src/rewardsEligibility/constants/SegmentLimits.ts +1 -5
  133. package/src/rewardsEligibility/dtos/backoffice/segments/PopulationSegmentDefinition.ts +1 -12
  134. package/src/rewardsEligibility/dtos/backoffice/segments/SegmentAggregateCondition.ts +1 -22
  135. package/src/rewardsEligibility/dtos/backoffice/segments/SegmentColumnCondition.ts +1 -15
  136. package/src/rewardsEligibility/dtos/backoffice/segments/SegmentGroup.ts +1 -27
  137. package/src/rewardsEligibility/dtos/backoffice/segments/SegmentParam.ts +1 -11
  138. package/src/rewardsEligibility/dtos/backoffice/segments/SegmentSchemaResponse.ts +1 -11
  139. package/src/rewardsEligibility/dtos/backoffice/segments/SegmentTableSchemaResponse.ts +1 -14
  140. package/src/rewardsEligibility/dtos/backoffice/segments/SegmentUsedColumn.ts +1 -5
  141. package/src/rewardsEligibility/dtos/backoffice/segments/SegmentWindow.ts +1 -9
  142. package/src/rewardsEligibility/enums/SegmentAggregateFnEnum.ts +1 -5
  143. package/src/rewardsEligibility/enums/SegmentConditionKindEnum.ts +1 -4
  144. package/src/rewardsEligibility/enums/SegmentMatchEnum.ts +1 -4
  145. package/src/rewardsEligibility/enums/SegmentOperatorEnum.ts +1 -16
  146. package/src/rewardsEligibility/enums/SegmentParamSourceEnum.ts +1 -5
  147. package/src/rewardsEligibility/enums/SegmentParamTypeEnum.ts +1 -7
  148. package/src/rules/constants/SegmentLimits.ts +5 -0
  149. package/src/rules/dtos/population/PopulationCompileRequest.ts +9 -0
  150. package/src/rules/dtos/population/PopulationCompileResponse.ts +10 -0
  151. package/src/rules/dtos/population/PopulationExecutionPageResponse.ts +11 -0
  152. package/src/rules/dtos/population/PopulationExecutionRequest.ts +13 -0
  153. package/src/rules/dtos/population/PopulationExecutionResponse.ts +6 -0
  154. package/src/rules/dtos/population/PopulationSegmentDefinition.ts +12 -0
  155. package/src/rules/dtos/population/PopulationTestRequest.ts +10 -0
  156. package/src/rules/dtos/population/PopulationTestResponse.ts +29 -0
  157. package/src/rules/dtos/population/SegmentAggregateCondition.ts +22 -0
  158. package/src/rules/dtos/population/SegmentColumnCondition.ts +15 -0
  159. package/src/rules/dtos/population/SegmentGroup.ts +27 -0
  160. package/src/rules/dtos/population/SegmentParam.ts +11 -0
  161. package/src/rules/dtos/population/SegmentSchemaResponse.ts +11 -0
  162. package/src/rules/dtos/population/SegmentTableSchemaResponse.ts +14 -0
  163. package/src/rules/dtos/population/SegmentUsedColumn.ts +5 -0
  164. package/src/rules/dtos/population/SegmentWindow.ts +9 -0
  165. package/src/rules/enums/PopulationErrorCodeEnum.ts +12 -0
  166. package/src/rules/enums/PopulationExecutionStatusEnum.ts +6 -0
  167. package/src/rules/enums/PopulationTestStatusEnum.ts +5 -0
  168. package/src/rules/enums/SegmentAggregateFnEnum.ts +5 -0
  169. package/src/rules/enums/SegmentConditionKindEnum.ts +4 -0
  170. package/src/rules/enums/SegmentMatchEnum.ts +4 -0
  171. package/src/rules/enums/SegmentOperatorEnum.ts +16 -0
  172. package/src/rules/enums/SegmentParamSourceEnum.ts +5 -0
  173. package/src/rules/enums/SegmentParamTypeEnum.ts +7 -0
  174. package/src/rules/index.ts +30 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.539.0",
3
+ "version": "3.541.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -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';
@@ -1,5 +1 @@
1
- /** Identificador SQL permitido para tabla/columna (A§4.3 paso 1): minusculas, digitos y guion bajo; nunca texto libre. */
2
- export const SEGMENT_IDENTIFIER_PATTERN = /^[a-z_][a-z0-9_]*$/;
3
- export const SEGMENT_MAX_DAYS = 365;
4
- export const SEGMENT_MAX_PARAMS = 40;
5
- export const SEGMENT_MAX_AGGREGATES = 8;
1
+ export * from '../../rules/constants/SegmentLimits';
@@ -1,12 +1 @@
1
- import { Expose, Type } from 'class-transformer';
2
- import { ArrayMaxSize, ArrayMinSize, IsArray, IsEnum, Matches, ValidateNested } from 'class-validator';
3
- import { SEGMENT_IDENTIFIER_PATTERN } from '../../../constants/SegmentLimits';
4
- import { SegmentMatchEnum } from '../../../enums/SegmentMatchEnum';
5
- import { SegmentGroup } from './SegmentGroup';
6
-
7
- /** El constructor tal cual (A§4.1): tabla ancla (una fila -> un directoryid), TODAS/ALGUNA global y grupos con su propio TODAS/ALGUNA. */
8
- export class PopulationSegmentDefinition {
9
- @Expose() @Matches(SEGMENT_IDENTIFIER_PATTERN) baseTable: string;
10
- @Expose() @IsEnum(SegmentMatchEnum) match: SegmentMatchEnum;
11
- @Expose() @IsArray() @ArrayMinSize(1) @ArrayMaxSize(10) @ValidateNested({ each: true }) @Type(() => SegmentGroup) groups: SegmentGroup[];
12
- }
1
+ export * from '../../../../rules/dtos/population/PopulationSegmentDefinition';
@@ -1,22 +1 @@
1
- import { Expose, Type } from 'class-transformer';
2
- import { ArrayMaxSize, Equals, IsArray, IsEnum, IsNumber, IsOptional, Matches, ValidateNested } from 'class-validator';
3
- import { SEGMENT_IDENTIFIER_PATTERN } from '../../../constants/SegmentLimits';
4
- import { SegmentAggregateFnEnum } from '../../../enums/SegmentAggregateFnEnum';
5
- import { SegmentConditionKindEnum } from '../../../enums/SegmentConditionKindEnum';
6
- import { SegmentOperatorEnum } from '../../../enums/SegmentOperatorEnum';
7
- import { SegmentColumnCondition } from './SegmentColumnCondition';
8
- import { SegmentWindow } from './SegmentWindow';
9
-
10
- /** (b) Agregado con ventana relativa sobre una tabla relacionada (existe / cuenta / suma). `filters` elige QUE cuenta (estados, moneda...). */
11
- export class SegmentAggregateCondition {
12
- @Expose() @Equals(SegmentConditionKindEnum.AGGREGATE) kind: SegmentConditionKindEnum.AGGREGATE;
13
- @Expose() @Matches(SEGMENT_IDENTIFIER_PATTERN) table: string;
14
- @Expose() @IsEnum(SegmentAggregateFnEnum) fn: SegmentAggregateFnEnum;
15
- /** Solo SUM. */
16
- @Expose() @IsOptional() @Matches(SEGMENT_IDENTIFIER_PATTERN) column?: string;
17
- /** COUNT y SUM; EXISTS no lleva. */
18
- @Expose() @IsOptional() @IsEnum(SegmentOperatorEnum) op?: SegmentOperatorEnum;
19
- @Expose() @IsOptional() @IsNumber() value?: number;
20
- @Expose() @ValidateNested() @Type(() => SegmentWindow) window: SegmentWindow;
21
- @Expose() @IsArray() @ArrayMaxSize(10) @ValidateNested({ each: true }) @Type(() => SegmentColumnCondition) filters: SegmentColumnCondition[];
22
- }
1
+ export * from '../../../../rules/dtos/population/SegmentAggregateCondition';
@@ -1,15 +1 @@
1
- import { Expose } from 'class-transformer';
2
- import { Equals, IsEnum, IsOptional, Matches } from 'class-validator';
3
- import { JsonValue } from '../../../../common';
4
- import { SEGMENT_IDENTIFIER_PATTERN } from '../../../constants/SegmentLimits';
5
- import { SegmentConditionKindEnum } from '../../../enums/SegmentConditionKindEnum';
6
- import { SegmentOperatorEnum } from '../../../enums/SegmentOperatorEnum';
7
-
8
- /** (a) Columna de una tabla unida por `directoryid`. El tipo de `value` (escalar, lista o `{days}`) lo valida el compilador contra el tipo de Glue. */
9
- export class SegmentColumnCondition {
10
- @Expose() @Equals(SegmentConditionKindEnum.COLUMN) kind: SegmentConditionKindEnum.COLUMN;
11
- @Expose() @Matches(SEGMENT_IDENTIFIER_PATTERN) table: string;
12
- @Expose() @Matches(SEGMENT_IDENTIFIER_PATTERN) column: string;
13
- @Expose() @IsEnum(SegmentOperatorEnum) op: SegmentOperatorEnum;
14
- @Expose() @IsOptional() value?: JsonValue;
15
- }
1
+ export * from '../../../../rules/dtos/population/SegmentColumnCondition';
@@ -1,27 +1 @@
1
- import { Expose, Type } from 'class-transformer';
2
- import { ArrayMaxSize, ArrayMinSize, IsArray, IsEnum, ValidateNested } from 'class-validator';
3
- import { SegmentConditionKindEnum } from '../../../enums/SegmentConditionKindEnum';
4
- import { SegmentMatchEnum } from '../../../enums/SegmentMatchEnum';
5
- import { SegmentAggregateCondition } from './SegmentAggregateCondition';
6
- import { SegmentColumnCondition } from './SegmentColumnCondition';
7
-
8
- export type SegmentCondition = SegmentColumnCondition | SegmentAggregateCondition;
9
-
10
- export class SegmentGroup {
11
- @Expose() @IsEnum(SegmentMatchEnum) match: SegmentMatchEnum;
12
-
13
- /** `kind` decide la clase; un `kind` desconocido NO se instancia y la validacion lo rechaza (el objeto queda sin `@Equals` valido). */
14
- @Expose()
15
- @IsArray() @ArrayMinSize(1) @ArrayMaxSize(20) @ValidateNested({ each: true })
16
- @Type(() => Object, {
17
- keepDiscriminatorProperty: true,
18
- discriminator: {
19
- property: 'kind',
20
- subTypes: [
21
- { value: SegmentColumnCondition, name: SegmentConditionKindEnum.COLUMN },
22
- { value: SegmentAggregateCondition, name: SegmentConditionKindEnum.AGGREGATE },
23
- ],
24
- },
25
- })
26
- conditions: SegmentCondition[];
27
- }
1
+ export * from '../../../../rules/dtos/population/SegmentGroup';
@@ -1,11 +1 @@
1
- import { SegmentParamSourceEnum } from '../../../enums/SegmentParamSourceEnum';
2
- import { SegmentParamTypeEnum } from '../../../enums/SegmentParamTypeEnum';
3
-
4
- /** Un `?` del SQL, en orden. LITERAL lleva `value` como texto canonico; REFERENCE_AT_MINUS_DAYS lleva `days`. */
5
- export class SegmentParam {
6
- name: string;
7
- type: SegmentParamTypeEnum;
8
- source: SegmentParamSourceEnum;
9
- value?: string;
10
- days?: number;
11
- }
1
+ export * from '../../../../rules/dtos/population/SegmentParam';
@@ -1,11 +1 @@
1
- export class SegmentSchemaTableResponse {
2
- table: string;
3
- joinKey: string;
4
- columnCount: number;
5
- }
6
-
7
- /** `available: false` = ambiente sin datalake accesible: el constructor muestra "no disponible". */
8
- export class SegmentSchemaResponse {
9
- available: boolean;
10
- tables: SegmentSchemaTableResponse[];
11
- }
1
+ export * from '../../../../rules/dtos/population/SegmentSchemaResponse';
@@ -1,14 +1 @@
1
- import { SegmentOperatorEnum } from '../../../enums/SegmentOperatorEnum';
2
-
3
- export class SegmentColumnSchemaResponse {
4
- name: string;
5
- type: string;
6
- isDate: boolean;
7
- operators: SegmentOperatorEnum[];
8
- }
9
-
10
- export class SegmentTableSchemaResponse {
11
- table: string;
12
- joinKey: string;
13
- columns: SegmentColumnSchemaResponse[];
14
- }
1
+ export * from '../../../../rules/dtos/population/SegmentTableSchemaResponse';
@@ -1,5 +1 @@
1
- export class SegmentUsedColumn {
2
- table: string;
3
- column: string;
4
- type: string;
5
- }
1
+ export * from '../../../../rules/dtos/population/SegmentUsedColumn';
@@ -1,9 +1 @@
1
- import { Expose } from 'class-transformer';
2
- import { IsInt, Matches, Max, Min } from 'class-validator';
3
- import { SEGMENT_IDENTIFIER_PATTERN, SEGMENT_MAX_DAYS } from '../../../constants/SegmentLimits';
4
-
5
- /** Ventana relativa [referenceAt - days, referenceAt) sobre una columna de fecha (A§4.1). */
6
- export class SegmentWindow {
7
- @Expose() @Matches(SEGMENT_IDENTIFIER_PATTERN) dateColumn: string;
8
- @Expose() @IsInt() @Min(1) @Max(SEGMENT_MAX_DAYS) days: number;
9
- }
1
+ export * from '../../../../rules/dtos/population/SegmentWindow';
@@ -1,5 +1 @@
1
- export enum SegmentAggregateFnEnum {
2
- EXISTS = 'EXISTS',
3
- COUNT = 'COUNT',
4
- SUM = 'SUM',
5
- }
1
+ export * from '../../rules/enums/SegmentAggregateFnEnum';
@@ -1,4 +1 @@
1
- export enum SegmentConditionKindEnum {
2
- COLUMN = 'COLUMN',
3
- AGGREGATE = 'AGGREGATE',
4
- }
1
+ export * from '../../rules/enums/SegmentConditionKindEnum';
@@ -1,4 +1 @@
1
- export enum SegmentMatchEnum {
2
- ALL = 'ALL',
3
- ANY = 'ANY',
4
- }
1
+ export * from '../../rules/enums/SegmentMatchEnum';
@@ -1,16 +1 @@
1
- export enum SegmentOperatorEnum {
2
- EQUALS = 'EQUALS',
3
- NOT_EQUALS = 'NOT_EQUALS',
4
- IN = 'IN',
5
- NOT_IN = 'NOT_IN',
6
- IS_NULL = 'IS_NULL',
7
- IS_NOT_NULL = 'IS_NOT_NULL',
8
- GT = 'GT',
9
- GTE = 'GTE',
10
- LT = 'LT',
11
- LTE = 'LTE',
12
- CONTAINS = 'CONTAINS',
13
- ANY_IN = 'ANY_IN',
14
- WITHIN_LAST_DAYS = 'WITHIN_LAST_DAYS',
15
- NOT_WITHIN_LAST_DAYS = 'NOT_WITHIN_LAST_DAYS',
16
- }
1
+ export * from '../../rules/enums/SegmentOperatorEnum';
@@ -1,5 +1 @@
1
- export enum SegmentParamSourceEnum {
2
- LITERAL = 'LITERAL',
3
- REFERENCE_AT = 'REFERENCE_AT',
4
- REFERENCE_AT_MINUS_DAYS = 'REFERENCE_AT_MINUS_DAYS',
5
- }
1
+ export * from '../../rules/enums/SegmentParamSourceEnum';
@@ -1,7 +1 @@
1
- export enum SegmentParamTypeEnum {
2
- STRING = 'STRING',
3
- INTEGER = 'INTEGER',
4
- DECIMAL = 'DECIMAL',
5
- BOOLEAN = 'BOOLEAN',
6
- TIMESTAMP = 'TIMESTAMP',
7
- }
1
+ export * from '../../rules/enums/SegmentParamTypeEnum';
@@ -0,0 +1,5 @@
1
+ /** Identificador SQL permitido para tabla/columna (A§4.3 paso 1): minusculas, digitos y guion bajo; nunca texto libre. */
2
+ export const SEGMENT_IDENTIFIER_PATTERN = /^[a-z_][a-z0-9_]*$/;
3
+ export const SEGMENT_MAX_DAYS = 365;
4
+ export const SEGMENT_MAX_PARAMS = 40;
5
+ export const SEGMENT_MAX_AGGREGATES = 8;
@@ -0,0 +1,9 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import { IsDefined, IsOptional, IsString, ValidateNested } from 'class-validator';
3
+ import { PopulationSegmentDefinition } from './PopulationSegmentDefinition';
4
+
5
+ /** Compila una definicion a SQL parametrizado (POST /population/compile). `consumer` solo para logs/metricas. */
6
+ export class PopulationCompileRequest {
7
+ @Expose() @IsOptional() @IsString() consumer?: string;
8
+ @Expose() @IsDefined() @ValidateNested() @Type(() => PopulationSegmentDefinition) definition: PopulationSegmentDefinition;
9
+ }
@@ -0,0 +1,10 @@
1
+ import { SegmentParam } from './SegmentParam';
2
+ import { SegmentUsedColumn } from './SegmentUsedColumn';
3
+
4
+ export class PopulationCompileResponse {
5
+ sql: string;
6
+ params: SegmentParam[];
7
+ usedColumns: SegmentUsedColumn[];
8
+ humanSummary: string;
9
+ definitionHash: string;
10
+ }
@@ -0,0 +1,11 @@
1
+ import { PopulationErrorCodeEnum } from '../../enums/PopulationErrorCodeEnum';
2
+ import { PopulationExecutionStatusEnum } from '../../enums/PopulationExecutionStatusEnum';
3
+
4
+ /** Pagina de hasta 1000 ids. Sin `nextToken` = ultima pagina. */
5
+ export class PopulationExecutionPageResponse {
6
+ executionId: string;
7
+ status: PopulationExecutionStatusEnum;
8
+ ids: string[];
9
+ nextToken?: string;
10
+ reason?: PopulationErrorCodeEnum;
11
+ }
@@ -0,0 +1,13 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import { IsDefined, IsISO8601, IsNotEmpty, IsOptional, IsString, MaxLength, MinLength, ValidateNested } from 'class-validator';
3
+ import { PopulationSegmentDefinition } from './PopulationSegmentDefinition';
4
+
5
+ /** Inicia una ejecucion de poblacion (POST /population/executions). El central recompila; `expectedSql` activa G3 (SEGMENT_SCHEMA_DRIFT). */
6
+ export class PopulationExecutionRequest {
7
+ @Expose() @IsOptional() @IsString() consumer?: string;
8
+ @Expose() @IsDefined() @ValidateNested() @Type(() => PopulationSegmentDefinition) definition: PopulationSegmentDefinition;
9
+ @Expose() @IsISO8601({ strict: true }) referenceAt: string;
10
+ @Expose() @IsString() @MinLength(32) @MaxLength(128) idempotencyKey: string;
11
+ @Expose() @IsOptional() @IsString() @IsNotEmpty() expectedSql?: string;
12
+ @Expose() @IsOptional() @IsString() @MinLength(1) @MaxLength(256) afterDirectoryId?: string;
13
+ }
@@ -0,0 +1,6 @@
1
+ import { PopulationExecutionStatusEnum } from '../../enums/PopulationExecutionStatusEnum';
2
+
3
+ export class PopulationExecutionResponse {
4
+ executionId: string;
5
+ status: PopulationExecutionStatusEnum;
6
+ }
@@ -0,0 +1,12 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import { ArrayMaxSize, ArrayMinSize, IsArray, IsEnum, Matches, ValidateNested } from 'class-validator';
3
+ import { SEGMENT_IDENTIFIER_PATTERN } from '../../constants/SegmentLimits';
4
+ import { SegmentMatchEnum } from '../../enums/SegmentMatchEnum';
5
+ import { SegmentGroup } from './SegmentGroup';
6
+
7
+ /** El constructor tal cual (A§4.1): tabla ancla (una fila -> un directoryid), TODAS/ALGUNA global y grupos con su propio TODAS/ALGUNA. */
8
+ export class PopulationSegmentDefinition {
9
+ @Expose() @Matches(SEGMENT_IDENTIFIER_PATTERN) baseTable: string;
10
+ @Expose() @IsEnum(SegmentMatchEnum) match: SegmentMatchEnum;
11
+ @Expose() @IsArray() @ArrayMinSize(1) @ArrayMaxSize(10) @ValidateNested({ each: true }) @Type(() => SegmentGroup) groups: SegmentGroup[];
12
+ }
@@ -0,0 +1,10 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import { IsDefined, IsISO8601, IsOptional, IsString, ValidateNested } from 'class-validator';
3
+ import { PopulationSegmentDefinition } from './PopulationSegmentDefinition';
4
+
5
+ /** Prueba sin estado de una definicion (POST /population/tests). `referenceAt` ISO-8601 con zona; por defecto, ahora. */
6
+ export class PopulationTestRequest {
7
+ @Expose() @IsOptional() @IsString() consumer?: string;
8
+ @Expose() @IsDefined() @ValidateNested() @Type(() => PopulationSegmentDefinition) definition: PopulationSegmentDefinition;
9
+ @Expose() @IsOptional() @IsISO8601({ strict: true }) referenceAt?: string;
10
+ }
@@ -0,0 +1,29 @@
1
+ import { PopulationErrorCodeEnum } from '../../enums/PopulationErrorCodeEnum';
2
+ import { PopulationTestStatusEnum } from '../../enums/PopulationTestStatusEnum';
3
+ import { SegmentParam } from './SegmentParam';
4
+
5
+ export class PopulationTestResultResponse {
6
+ count: number;
7
+ sampleIds: string[];
8
+ bytesScanned: number;
9
+ durationMs: number;
10
+ }
11
+
12
+ export class PopulationTestErrorResponse {
13
+ code: PopulationErrorCodeEnum;
14
+ message: string;
15
+ }
16
+
17
+ /** `queryExecutionId` sale del count (lastTest de rewards). Estado RUNNING: el cliente reconsulta por `testId`. */
18
+ export class PopulationTestResponse {
19
+ testId: string;
20
+ status: PopulationTestStatusEnum;
21
+ referenceAt: string;
22
+ definitionHash: string;
23
+ humanSummary: string;
24
+ sql: string;
25
+ params: SegmentParam[];
26
+ queryExecutionId?: string;
27
+ result?: PopulationTestResultResponse;
28
+ errors?: PopulationTestErrorResponse[];
29
+ }