@fiado/type-kit 3.215.0 → 3.217.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.
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Ficha COMERCIAL del equipo reservado, congelada en la sesión al momento de reservarlo (S03).
3
+ *
4
+ * **Por qué un snapshot y no una lectura del catálogo en cada `GET`:**
5
+ * 1. Una venta se cotiza al instante en que se reserva. Si el catálogo cambia el precio o retira el
6
+ * modelo mientras el vendedor sigue en el wizard, la venta en curso NO debe cambiar debajo de él
7
+ * — el precio ancla el cobro (`amountCents == cashPrice`) y el contrato ya se le mostró al cliente.
8
+ * 2. El front pollea la sesión cada 3–5 s durante el KYC (D20). Resolver el catálogo en cada lectura
9
+ * convertiría ese poll en un llamado cross-lambda por tick.
10
+ *
11
+ * Lo llena `addProduct`, que YA consulta el catálogo para elegir la unidad física y su precio: los
12
+ * datos salen de la MISMA lectura, sin viajes extra.
13
+ *
14
+ * ⚠️ NO lleva `stock`: es volátil por definición y no describe la unidad ya reservada (que por
15
+ * definición dejó de estar disponible). El stock vive en el catálogo y solo importa en el paso 03.
16
+ *
17
+ * SureKeep Fase 2 — pista Retail.
18
+ */
19
+ export interface WizardProduct {
20
+ /** SKU del modelo comercial. Espeja `WizardSession.reservedSku`. */
21
+ sku: string;
22
+ /** Unidad física reservada. Espeja `WizardSession.reservedImei`. */
23
+ imei: string;
24
+ /**
25
+ * Precio de contado en centavos, TAL COMO estaba en el catálogo al reservar. Es el ancla del
26
+ * cobro: `registerPayment` exige `amountCents == cashPriceCents`.
27
+ */
28
+ cashPriceCents: number;
29
+ brand: string;
30
+ model: string;
31
+ capacity: string;
32
+ color: string;
33
+ imageUrl: string | null;
34
+ /** Gama del equipo (`PREMIUM` / `HIGH` / `MID` …). La define el catálogo, no el wizard. */
35
+ tier: string;
36
+ /**
37
+ * Financieras alternativas elegibles para este producto (derivación externa, paso 04).
38
+ * Mismo nombre que en `retail-catalog`: es su dato, no se renombra al cruzar la frontera.
39
+ */
40
+ eligibleFinanciers: string[];
41
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -7,6 +7,7 @@ import type { OccupationEnum } from '../enums/OccupationEnum';
7
7
  import type { WizardConsents } from './WizardConsents';
8
8
  import type { WizardLoan } from './WizardLoan';
9
9
  import type { WizardPayment } from './WizardPayment';
10
+ import type { WizardProduct } from './WizardProduct';
10
11
  import type { WizardWelcome } from './WizardWelcome';
11
12
  /** Modalidad de captura del KYC (M1 §213-329). */
12
13
  export type KycModality = 'CUSTOMER_LINK' | 'STORE_DEVICE' | 'MANUAL';
@@ -46,6 +47,12 @@ export interface WizardSession {
46
47
  accountStatus: AccountStatus | null;
47
48
  reservedSku: string | null;
48
49
  reservedImei: string | null;
50
+ /**
51
+ * Ficha comercial del equipo reservado (marca, modelo, precio, financieras), congelada al
52
+ * reservar. `reservedSku`/`reservedImei` siguen siendo la fuente de verdad de QUÉ unidad está
53
+ * tomada; esto es lo que hace falta para PINTARLA sin volver al catálogo. Null antes del S03.
54
+ */
55
+ product: WizardProduct | null;
49
56
  reservationExpiresAt: string | null;
50
57
  paymentMethod: PaymentMethodEnum | null;
51
58
  externalProvider: ExternalProviderEnum | null;
@@ -1,10 +1,15 @@
1
1
  /**
2
2
  * POST /wizard/sessions/:id/product — reserva un equipo del catálogo (paso 03). Reserva 30 min en
3
- * RetailInventory F1 (condición atómica H2). El `cashPriceCents` de la reserva ancla el cobro
4
- * (regla dura: `amountCents == cashPrice`). SureKeep Fase 2 — pista Retail.
3
+ * RetailInventory F1 (condición atómica H2).
4
+ *
5
+ * `imei` y `cashPriceCents` son OPCIONALES a propósito: la unidad física y el precio son AUTORIDAD DEL
6
+ * SERVIDOR. Con solo el `sku`, el wizard elige una unidad disponible del catálogo y toma su precio (el
7
+ * cliente NUNCA dicta el monto a cobrar — `cashPriceCents` ancla el cobro con `amountCents == cashPrice`).
8
+ * Si el caller manda `imei`, el server puede honrar esa unidad, pero el precio SIEMPRE sale del catálogo.
9
+ * SureKeep Fase 2 — pista Retail.
5
10
  */
6
11
  export declare class AddProductRequest {
7
12
  sku: string;
8
- imei: string;
9
- cashPriceCents: number;
13
+ imei?: string;
14
+ cashPriceCents?: number;
10
15
  }
@@ -14,8 +14,13 @@ const class_transformer_1 = require("class-transformer");
14
14
  const class_validator_1 = require("class-validator");
15
15
  /**
16
16
  * POST /wizard/sessions/:id/product — reserva un equipo del catálogo (paso 03). Reserva 30 min en
17
- * RetailInventory F1 (condición atómica H2). El `cashPriceCents` de la reserva ancla el cobro
18
- * (regla dura: `amountCents == cashPrice`). SureKeep Fase 2 — pista Retail.
17
+ * RetailInventory F1 (condición atómica H2).
18
+ *
19
+ * `imei` y `cashPriceCents` son OPCIONALES a propósito: la unidad física y el precio son AUTORIDAD DEL
20
+ * SERVIDOR. Con solo el `sku`, el wizard elige una unidad disponible del catálogo y toma su precio (el
21
+ * cliente NUNCA dicta el monto a cobrar — `cashPriceCents` ancla el cobro con `amountCents == cashPrice`).
22
+ * Si el caller manda `imei`, el server puede honrar esa unidad, pero el precio SIEMPRE sale del catálogo.
23
+ * SureKeep Fase 2 — pista Retail.
19
24
  */
20
25
  class AddProductRequest {
21
26
  }
@@ -27,11 +32,13 @@ __decorate([
27
32
  ], AddProductRequest.prototype, "sku", void 0);
28
33
  __decorate([
29
34
  (0, class_transformer_1.Expose)(),
35
+ (0, class_validator_1.IsOptional)(),
30
36
  (0, class_validator_1.IsString)(),
31
37
  __metadata("design:type", String)
32
38
  ], AddProductRequest.prototype, "imei", void 0);
33
39
  __decorate([
34
40
  (0, class_transformer_1.Expose)(),
41
+ (0, class_validator_1.IsOptional)(),
35
42
  (0, class_validator_1.IsInt)(),
36
43
  (0, class_validator_1.Min)(0),
37
44
  __metadata("design:type", Number)
@@ -14,6 +14,7 @@ export * from './enums/OccupationEnum';
14
14
  export * from './enums/BeneficiaryRelationEnum';
15
15
  export * from './dtos/WizardConsents';
16
16
  export * from './dtos/WizardPayment';
17
+ export * from './dtos/WizardProduct';
17
18
  export * from './dtos/WizardWelcome';
18
19
  export * from './dtos/SalePaymentDetail';
19
20
  export * from './dtos/ProspectNewCustomer';
@@ -32,6 +32,7 @@ __exportStar(require("./enums/BeneficiaryRelationEnum"), exports);
32
32
  // DTOs anidados
33
33
  __exportStar(require("./dtos/WizardConsents"), exports);
34
34
  __exportStar(require("./dtos/WizardPayment"), exports);
35
+ __exportStar(require("./dtos/WizardProduct"), exports);
35
36
  __exportStar(require("./dtos/WizardWelcome"), exports);
36
37
  __exportStar(require("./dtos/SalePaymentDetail"), exports);
37
38
  __exportStar(require("./dtos/ProspectNewCustomer"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.215.0",
3
+ "version": "3.217.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Ficha COMERCIAL del equipo reservado, congelada en la sesión al momento de reservarlo (S03).
3
+ *
4
+ * **Por qué un snapshot y no una lectura del catálogo en cada `GET`:**
5
+ * 1. Una venta se cotiza al instante en que se reserva. Si el catálogo cambia el precio o retira el
6
+ * modelo mientras el vendedor sigue en el wizard, la venta en curso NO debe cambiar debajo de él
7
+ * — el precio ancla el cobro (`amountCents == cashPrice`) y el contrato ya se le mostró al cliente.
8
+ * 2. El front pollea la sesión cada 3–5 s durante el KYC (D20). Resolver el catálogo en cada lectura
9
+ * convertiría ese poll en un llamado cross-lambda por tick.
10
+ *
11
+ * Lo llena `addProduct`, que YA consulta el catálogo para elegir la unidad física y su precio: los
12
+ * datos salen de la MISMA lectura, sin viajes extra.
13
+ *
14
+ * ⚠️ NO lleva `stock`: es volátil por definición y no describe la unidad ya reservada (que por
15
+ * definición dejó de estar disponible). El stock vive en el catálogo y solo importa en el paso 03.
16
+ *
17
+ * SureKeep Fase 2 — pista Retail.
18
+ */
19
+ export interface WizardProduct {
20
+ /** SKU del modelo comercial. Espeja `WizardSession.reservedSku`. */
21
+ sku: string;
22
+ /** Unidad física reservada. Espeja `WizardSession.reservedImei`. */
23
+ imei: string;
24
+ /**
25
+ * Precio de contado en centavos, TAL COMO estaba en el catálogo al reservar. Es el ancla del
26
+ * cobro: `registerPayment` exige `amountCents == cashPriceCents`.
27
+ */
28
+ cashPriceCents: number;
29
+ brand: string;
30
+ model: string;
31
+ capacity: string;
32
+ color: string;
33
+ imageUrl: string | null;
34
+ /** Gama del equipo (`PREMIUM` / `HIGH` / `MID` …). La define el catálogo, no el wizard. */
35
+ tier: string;
36
+ /**
37
+ * Financieras alternativas elegibles para este producto (derivación externa, paso 04).
38
+ * Mismo nombre que en `retail-catalog`: es su dato, no se renombra al cruzar la frontera.
39
+ */
40
+ eligibleFinanciers: string[];
41
+ }
@@ -7,6 +7,7 @@ import type { OccupationEnum } from '../enums/OccupationEnum';
7
7
  import type { WizardConsents } from './WizardConsents';
8
8
  import type { WizardLoan } from './WizardLoan';
9
9
  import type { WizardPayment } from './WizardPayment';
10
+ import type { WizardProduct } from './WizardProduct';
10
11
  import type { WizardWelcome } from './WizardWelcome';
11
12
 
12
13
  /** Modalidad de captura del KYC (M1 §213-329). */
@@ -49,6 +50,12 @@ export interface WizardSession {
49
50
  accountStatus: AccountStatus | null;
50
51
  reservedSku: string | null;
51
52
  reservedImei: string | null;
53
+ /**
54
+ * Ficha comercial del equipo reservado (marca, modelo, precio, financieras), congelada al
55
+ * reservar. `reservedSku`/`reservedImei` siguen siendo la fuente de verdad de QUÉ unidad está
56
+ * tomada; esto es lo que hace falta para PINTARLA sin volver al catálogo. Null antes del S03.
57
+ */
58
+ product: WizardProduct | null;
52
59
  reservationExpiresAt: string | null;
53
60
  paymentMethod: PaymentMethodEnum | null;
54
61
  externalProvider: ExternalProviderEnum | null;
@@ -1,10 +1,15 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsInt, IsString, Min } from 'class-validator';
2
+ import { IsInt, IsOptional, IsString, Min } from 'class-validator';
3
3
 
4
4
  /**
5
5
  * POST /wizard/sessions/:id/product — reserva un equipo del catálogo (paso 03). Reserva 30 min en
6
- * RetailInventory F1 (condición atómica H2). El `cashPriceCents` de la reserva ancla el cobro
7
- * (regla dura: `amountCents == cashPrice`). SureKeep Fase 2 — pista Retail.
6
+ * RetailInventory F1 (condición atómica H2).
7
+ *
8
+ * `imei` y `cashPriceCents` son OPCIONALES a propósito: la unidad física y el precio son AUTORIDAD DEL
9
+ * SERVIDOR. Con solo el `sku`, el wizard elige una unidad disponible del catálogo y toma su precio (el
10
+ * cliente NUNCA dicta el monto a cobrar — `cashPriceCents` ancla el cobro con `amountCents == cashPrice`).
11
+ * Si el caller manda `imei`, el server puede honrar esa unidad, pero el precio SIEMPRE sale del catálogo.
12
+ * SureKeep Fase 2 — pista Retail.
8
13
  */
9
14
  export class AddProductRequest {
10
15
  @Expose()
@@ -12,11 +17,13 @@ export class AddProductRequest {
12
17
  sku!: string;
13
18
 
14
19
  @Expose()
20
+ @IsOptional()
15
21
  @IsString()
16
- imei!: string;
22
+ imei?: string;
17
23
 
18
24
  @Expose()
25
+ @IsOptional()
19
26
  @IsInt()
20
27
  @Min(0)
21
- cashPriceCents!: number;
28
+ cashPriceCents?: number;
22
29
  }
@@ -17,6 +17,7 @@ export * from './enums/BeneficiaryRelationEnum';
17
17
  // DTOs anidados
18
18
  export * from './dtos/WizardConsents';
19
19
  export * from './dtos/WizardPayment';
20
+ export * from './dtos/WizardProduct';
20
21
  export * from './dtos/WizardWelcome';
21
22
  export * from './dtos/SalePaymentDetail';
22
23
  export * from './dtos/ProspectNewCustomer';