@fiado/type-kit 3.654.0 → 3.656.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.
- package/_test_/unit/phoneSales/PhoneSalesCodeRedeemedEventDetail.test.ts +33 -0
- package/_test_/unit/phoneSales/RedeemSaleCodeRequestDto.test.ts +34 -0
- package/bin/loanCredit/dtos/responses/LoanCustomerDocument.d.ts +5 -0
- package/bin/loanCredit/dtos/responses/LoanCustomerDocument.js +2 -0
- package/bin/loanCredit/index.d.ts +1 -0
- package/bin/loanCredit/index.js +1 -0
- package/bin/phoneSales/RedeemSaleCodeRequestDto.d.ts +4 -1
- package/bin/phoneSales/RedeemSaleCodeRequestDto.js +5 -1
- package/bin/phoneSales/SaleResponseDto.d.ts +3 -0
- package/bin/phoneSales/events/PhoneSalesCodeRedeemedEventDetail.d.ts +40 -0
- package/bin/phoneSales/events/PhoneSalesCodeRedeemedEventDetail.js +23 -0
- package/bin/phoneSales/index.d.ts +1 -0
- package/bin/phoneSales/index.js +1 -0
- package/package.json +1 -1
- package/src/loanCredit/dtos/responses/LoanCustomerDocument.ts +6 -0
- package/src/loanCredit/index.ts +1 -0
- package/src/phoneSales/RedeemSaleCodeRequestDto.ts +7 -2
- package/src/phoneSales/SaleResponseDto.ts +3 -0
- package/src/phoneSales/events/PhoneSalesCodeRedeemedEventDetail.ts +47 -0
- package/src/phoneSales/index.ts +1 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { PHONE_SALES_EVENTS_SOURCE, PhoneSalesEventDetailTypeEnum, PhoneSalesCodeRedeemedEventDetail } from '../../../src/phoneSales';
|
|
3
|
+
import { PhoneSales } from '../../../src';
|
|
4
|
+
|
|
5
|
+
it('constantes del evento', () => {
|
|
6
|
+
expect(PHONE_SALES_EVENTS_SOURCE).toBe('fiado.phone-sales');
|
|
7
|
+
expect(PhoneSalesEventDetailTypeEnum.CODE_REDEEMED).toBe('PhoneSalesCodeRedeemed');
|
|
8
|
+
expect(PhoneSales.PHONE_SALES_EVENTS_SOURCE).toBe('fiado.phone-sales');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('detail tiene la forma exacta del contrato', () => {
|
|
12
|
+
const detail = {
|
|
13
|
+
eventId: 'e1', occurredAt: '2026-11-05T12:00:00.000Z', saleId: 's1',
|
|
14
|
+
redeemer: { directoryId: 'd-redeemer' }, buyer: { directoryId: 'd-buyer' },
|
|
15
|
+
line: { phone: '5512345678', operatorId: 'at-t' },
|
|
16
|
+
sale: { variantId: 'v1', model: 'A15', storage: '128GB', color: 'Negro', currency: 'MXN', deliveryType: 'HOME', purchasedAt: '2026-11-05T11:00:00.000Z', amount: 4999 },
|
|
17
|
+
} satisfies PhoneSalesCodeRedeemedEventDetail;
|
|
18
|
+
expect(Object.keys(detail).sort()).toEqual(['buyer', 'eventId', 'line', 'occurredAt', 'redeemer', 'sale', 'saleId']);
|
|
19
|
+
expect(Object.keys(detail.sale).sort()).toEqual(['amount', 'color', 'currency', 'deliveryType', 'model', 'purchasedAt', 'storage', 'variantId']);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('amount y currency son opcionales (ventas previas a DEC-011)', () => {
|
|
23
|
+
const sale = {
|
|
24
|
+
variantId: 'v1', model: 'A15', storage: '128GB', color: 'Negro', deliveryType: 'HOME', purchasedAt: '2026-11-05T11:00:00.000Z',
|
|
25
|
+
} satisfies PhoneSalesCodeRedeemedEventDetail['sale'];
|
|
26
|
+
expect(Object.keys(sale)).not.toContain('amount');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('rechaza campos faltantes', () => {
|
|
30
|
+
// @ts-expect-error falta redeemer
|
|
31
|
+
const missing: PhoneSalesCodeRedeemedEventDetail = { eventId: 'e', occurredAt: 'x', saleId: 's', buyer: { directoryId: 'b' }, line: { phone: '1', operatorId: 'bait' }, sale: {} };
|
|
32
|
+
void missing;
|
|
33
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance } from 'class-transformer';
|
|
3
|
+
import { validate } from 'class-validator';
|
|
4
|
+
import { RedeemSaleCodeRequestDto, SaleResponseDto } from '../../../src/phoneSales';
|
|
5
|
+
|
|
6
|
+
const ok = { referenceCode: 'ABC123', linePhone: '55 1234 5678', lineOperatorId: 'at-t' };
|
|
7
|
+
const props = async (plain: object) =>
|
|
8
|
+
(await validate(plainToInstance(RedeemSaleCodeRequestDto, plain))).map((e) => e.property);
|
|
9
|
+
|
|
10
|
+
describe('RedeemSaleCodeRequestDto', () => {
|
|
11
|
+
it('válido: operador slug y teléfono string sin normalizar', async () => {
|
|
12
|
+
expect(await props(ok)).toEqual([]);
|
|
13
|
+
});
|
|
14
|
+
it.each(['Bait', 'a', 'x'.repeat(41), 'at_t', ''])('lineOperatorId %p inválido', async (lineOperatorId) => {
|
|
15
|
+
expect(await props({ ...ok, lineOperatorId })).toEqual(['lineOperatorId']);
|
|
16
|
+
});
|
|
17
|
+
it('linePhone no string inválido; ausente inválido', async () => {
|
|
18
|
+
expect(await props({ ...ok, linePhone: 5512345678 })).toEqual(['linePhone']);
|
|
19
|
+
expect(await props({ referenceCode: 'A', lineOperatorId: 'bait' })).toEqual(['linePhone']);
|
|
20
|
+
});
|
|
21
|
+
it('ya no exige newAccountDirectorId y la clase no lo declara', async () => {
|
|
22
|
+
expect(await props(ok)).toEqual([]);
|
|
23
|
+
expect('newAccountDirectorId' in new RedeemSaleCodeRequestDto()).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('SaleResponseDto.line', () => {
|
|
28
|
+
it('es opcional y acepta PhoneSalesLineDetail', () => {
|
|
29
|
+
const withLine: SaleResponseDto['line'] = { phone: '5512345678', operatorId: 'bait' };
|
|
30
|
+
const without: SaleResponseDto['line'] = undefined;
|
|
31
|
+
expect(withLine?.operatorId).toBe('bait');
|
|
32
|
+
expect(without).toBeUndefined();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { LoanCustomerCreditDocument } from './LoanCustomerCreditDocument';
|
|
2
|
+
/** Documento del ciclo de vida de cualquiera de los créditos del acreditado, con el crédito en el que está guardado. */
|
|
3
|
+
export interface LoanCustomerDocument extends LoanCustomerCreditDocument {
|
|
4
|
+
creditId: string;
|
|
5
|
+
}
|
|
@@ -43,6 +43,7 @@ export * from './dtos/responses/LoanContractDownloadUrl';
|
|
|
43
43
|
export * from './dtos/responses/LoanContractPreview';
|
|
44
44
|
export * from './dtos/responses/LoanContractResponse';
|
|
45
45
|
export * from './dtos/responses/LoanCustomerCreditDocument';
|
|
46
|
+
export * from './dtos/responses/LoanCustomerDocument';
|
|
46
47
|
export * from './dtos/responses/LoanCustomerCreditDocumentUrl';
|
|
47
48
|
export * from './dtos/responses/OriginateLoanCreditResponse';
|
|
48
49
|
export * from './dtos/responses/QuoteLoanCreditResponse';
|
package/bin/loanCredit/index.js
CHANGED
|
@@ -67,6 +67,7 @@ __exportStar(require("./dtos/responses/LoanContractDownloadUrl"), exports);
|
|
|
67
67
|
__exportStar(require("./dtos/responses/LoanContractPreview"), exports);
|
|
68
68
|
__exportStar(require("./dtos/responses/LoanContractResponse"), exports);
|
|
69
69
|
__exportStar(require("./dtos/responses/LoanCustomerCreditDocument"), exports);
|
|
70
|
+
__exportStar(require("./dtos/responses/LoanCustomerDocument"), exports);
|
|
70
71
|
__exportStar(require("./dtos/responses/LoanCustomerCreditDocumentUrl"), exports);
|
|
71
72
|
__exportStar(require("./dtos/responses/OriginateLoanCreditResponse"), exports);
|
|
72
73
|
__exportStar(require("./dtos/responses/QuoteLoanCreditResponse"), exports);
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export declare class RedeemSaleCodeRequestDto {
|
|
2
2
|
referenceCode: string;
|
|
3
|
-
|
|
3
|
+
/** Teléfono de la línea tal como lo escribe el usuario; la normalización a 10 dígitos la hace el backend. */
|
|
4
|
+
linePhone: string;
|
|
5
|
+
/** Slug del operador tal como lo da benefits (`bait`, `telcel`, `at-t`). */
|
|
6
|
+
lineOperatorId: string;
|
|
4
7
|
}
|
|
@@ -21,4 +21,8 @@ __decorate([
|
|
|
21
21
|
__decorate([
|
|
22
22
|
(0, class_validator_1.IsString)(),
|
|
23
23
|
__metadata("design:type", String)
|
|
24
|
-
], RedeemSaleCodeRequestDto.prototype, "
|
|
24
|
+
], RedeemSaleCodeRequestDto.prototype, "linePhone", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, class_validator_1.Matches)(/^[a-z0-9-]{2,40}$/),
|
|
27
|
+
__metadata("design:type", String)
|
|
28
|
+
], RedeemSaleCodeRequestDto.prototype, "lineOperatorId", void 0);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PhoneSalesLineDetail } from './events/PhoneSalesCodeRedeemedEventDetail';
|
|
1
2
|
import { CurrencyId } from '../currency';
|
|
2
3
|
import { PickupDeliveryData, HomeDeliveryData } from './SaleDeliveryData';
|
|
3
4
|
export declare class SaleResponseDto {
|
|
@@ -57,4 +58,6 @@ export declare class SaleResponseDto {
|
|
|
57
58
|
chargedAmount: number | null;
|
|
58
59
|
/** Moneda en la que se cobró `chargedAmount` — mismo motivo de nullability. */
|
|
59
60
|
chargedCurrencyId: CurrencyId | null;
|
|
61
|
+
/** Línea declarada al canjear; ausente en ventas anteriores o sin canjear. */
|
|
62
|
+
line?: PhoneSalesLineDetail;
|
|
60
63
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export declare const PHONE_SALES_EVENTS_SOURCE = "fiado.phone-sales";
|
|
2
|
+
export declare enum PhoneSalesEventDetailTypeEnum {
|
|
3
|
+
/** Un código de venta se canjeó con éxito. Solo lo publica quien ganó la escritura condicional del canje. */
|
|
4
|
+
CODE_REDEEMED = "PhoneSalesCodeRedeemed"
|
|
5
|
+
}
|
|
6
|
+
export declare class PhoneSalesEventParty {
|
|
7
|
+
directoryId: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class PhoneSalesLineDetail {
|
|
10
|
+
/** 10 dígitos MX normalizados (sin +52, espacios ni guiones). */
|
|
11
|
+
phone: string;
|
|
12
|
+
/** Slug del operador tal como lo da benefits (`bait`, `telcel`, `at-t`). */
|
|
13
|
+
operatorId: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class PhoneSalesSaleDetail {
|
|
16
|
+
variantId: string;
|
|
17
|
+
model: string;
|
|
18
|
+
storage: string;
|
|
19
|
+
color: string;
|
|
20
|
+
deliveryType: string;
|
|
21
|
+
/** ISO-8601 UTC de la compra. */
|
|
22
|
+
purchasedAt: string;
|
|
23
|
+
/** Se omite si la venta no lo tiene (ventas previas a DEC-011); nunca 0. */
|
|
24
|
+
amount?: number;
|
|
25
|
+
/** `USD` / `MXN`. Se omite si la venta no lo tiene; nunca vacío. */
|
|
26
|
+
currency?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare class PhoneSalesCodeRedeemedEventDetail {
|
|
29
|
+
/** uuid generado al publicar. */
|
|
30
|
+
eventId: string;
|
|
31
|
+
/** ISO-8601 UTC del momento del canje. */
|
|
32
|
+
occurredAt: string;
|
|
33
|
+
saleId: string;
|
|
34
|
+
/** Quien canjea (sale del token). */
|
|
35
|
+
redeemer: PhoneSalesEventParty;
|
|
36
|
+
/** Quien compró (`buyerDirectorId`). */
|
|
37
|
+
buyer: PhoneSalesEventParty;
|
|
38
|
+
line: PhoneSalesLineDetail;
|
|
39
|
+
sale: PhoneSalesSaleDetail;
|
|
40
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PhoneSalesCodeRedeemedEventDetail = exports.PhoneSalesSaleDetail = exports.PhoneSalesLineDetail = exports.PhoneSalesEventParty = exports.PhoneSalesEventDetailTypeEnum = exports.PHONE_SALES_EVENTS_SOURCE = void 0;
|
|
4
|
+
// Origen de los eventos de EventBridge que publica phone-sales (bus fiado-directory-events).
|
|
5
|
+
exports.PHONE_SALES_EVENTS_SOURCE = 'fiado.phone-sales';
|
|
6
|
+
var PhoneSalesEventDetailTypeEnum;
|
|
7
|
+
(function (PhoneSalesEventDetailTypeEnum) {
|
|
8
|
+
/** Un código de venta se canjeó con éxito. Solo lo publica quien ganó la escritura condicional del canje. */
|
|
9
|
+
PhoneSalesEventDetailTypeEnum["CODE_REDEEMED"] = "PhoneSalesCodeRedeemed";
|
|
10
|
+
})(PhoneSalesEventDetailTypeEnum || (exports.PhoneSalesEventDetailTypeEnum = PhoneSalesEventDetailTypeEnum = {}));
|
|
11
|
+
class PhoneSalesEventParty {
|
|
12
|
+
}
|
|
13
|
+
exports.PhoneSalesEventParty = PhoneSalesEventParty;
|
|
14
|
+
class PhoneSalesLineDetail {
|
|
15
|
+
}
|
|
16
|
+
exports.PhoneSalesLineDetail = PhoneSalesLineDetail;
|
|
17
|
+
class PhoneSalesSaleDetail {
|
|
18
|
+
}
|
|
19
|
+
exports.PhoneSalesSaleDetail = PhoneSalesSaleDetail;
|
|
20
|
+
// `detail` del evento PhoneSalesCodeRedeemed. El código canjeado NO viaja (funciona como secreto).
|
|
21
|
+
class PhoneSalesCodeRedeemedEventDetail {
|
|
22
|
+
}
|
|
23
|
+
exports.PhoneSalesCodeRedeemedEventDetail = PhoneSalesCodeRedeemedEventDetail;
|
|
@@ -13,3 +13,4 @@ export * from './DeviceVariantPriceRequestDto';
|
|
|
13
13
|
export * from './SetDeviceVariantPricesRequestDto';
|
|
14
14
|
export * from './enums/DeviceImageContentTypeEnum';
|
|
15
15
|
export * from './enums/DeviceVariantStatusEnum';
|
|
16
|
+
export * from './events/PhoneSalesCodeRedeemedEventDetail';
|
package/bin/phoneSales/index.js
CHANGED
|
@@ -29,3 +29,4 @@ __exportStar(require("./DeviceVariantPriceRequestDto"), exports);
|
|
|
29
29
|
__exportStar(require("./SetDeviceVariantPricesRequestDto"), exports);
|
|
30
30
|
__exportStar(require("./enums/DeviceImageContentTypeEnum"), exports);
|
|
31
31
|
__exportStar(require("./enums/DeviceVariantStatusEnum"), exports);
|
|
32
|
+
__exportStar(require("./events/PhoneSalesCodeRedeemedEventDetail"), exports);
|
package/package.json
CHANGED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { LoanCustomerCreditDocument } from './LoanCustomerCreditDocument';
|
|
2
|
+
|
|
3
|
+
/** Documento del ciclo de vida de cualquiera de los créditos del acreditado, con el crédito en el que está guardado. */
|
|
4
|
+
export interface LoanCustomerDocument extends LoanCustomerCreditDocument {
|
|
5
|
+
creditId: string;
|
|
6
|
+
}
|
package/src/loanCredit/index.ts
CHANGED
|
@@ -52,6 +52,7 @@ export * from './dtos/responses/LoanContractDownloadUrl';
|
|
|
52
52
|
export * from './dtos/responses/LoanContractPreview';
|
|
53
53
|
export * from './dtos/responses/LoanContractResponse';
|
|
54
54
|
export * from './dtos/responses/LoanCustomerCreditDocument';
|
|
55
|
+
export * from './dtos/responses/LoanCustomerDocument';
|
|
55
56
|
export * from './dtos/responses/LoanCustomerCreditDocumentUrl';
|
|
56
57
|
export * from './dtos/responses/OriginateLoanCreditResponse';
|
|
57
58
|
export * from './dtos/responses/QuoteLoanCreditResponse';
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import { IsString } from 'class-validator';
|
|
1
|
+
import { IsString, Matches } from 'class-validator';
|
|
2
2
|
|
|
3
3
|
export class RedeemSaleCodeRequestDto {
|
|
4
4
|
@IsString()
|
|
5
5
|
referenceCode!: string;
|
|
6
6
|
|
|
7
|
+
/** Teléfono de la línea tal como lo escribe el usuario; la normalización a 10 dígitos la hace el backend. */
|
|
7
8
|
@IsString()
|
|
8
|
-
|
|
9
|
+
linePhone!: string;
|
|
10
|
+
|
|
11
|
+
/** Slug del operador tal como lo da benefits (`bait`, `telcel`, `at-t`). */
|
|
12
|
+
@Matches(/^[a-z0-9-]{2,40}$/)
|
|
13
|
+
lineOperatorId!: string;
|
|
9
14
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PhoneSalesLineDetail } from './events/PhoneSalesCodeRedeemedEventDetail';
|
|
1
2
|
import { CurrencyId } from '../currency';
|
|
2
3
|
import { PickupDeliveryData, HomeDeliveryData } from './SaleDeliveryData';
|
|
3
4
|
|
|
@@ -58,6 +59,8 @@ export class SaleResponseDto {
|
|
|
58
59
|
chargedAmount!: number | null;
|
|
59
60
|
/** Moneda en la que se cobró `chargedAmount` — mismo motivo de nullability. */
|
|
60
61
|
chargedCurrencyId!: CurrencyId | null;
|
|
62
|
+
/** Línea declarada al canjear; ausente en ventas anteriores o sin canjear. */
|
|
63
|
+
line?: PhoneSalesLineDetail;
|
|
61
64
|
// Nota (v1, 2026-08-03): `buyerDirectorId` (arriba) sigue siendo el ID crudo del comprador a
|
|
62
65
|
// propósito. Se evaluó agregar `buyerName` resuelto server-side (vía servicio de directorios,
|
|
63
66
|
// @fiado/api-invoker IDirectoriesApi) pero requería wiring de infra pendiente
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Origen de los eventos de EventBridge que publica phone-sales (bus fiado-directory-events).
|
|
2
|
+
export const PHONE_SALES_EVENTS_SOURCE = 'fiado.phone-sales';
|
|
3
|
+
|
|
4
|
+
export enum PhoneSalesEventDetailTypeEnum {
|
|
5
|
+
/** Un código de venta se canjeó con éxito. Solo lo publica quien ganó la escritura condicional del canje. */
|
|
6
|
+
CODE_REDEEMED = 'PhoneSalesCodeRedeemed',
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class PhoneSalesEventParty {
|
|
10
|
+
directoryId!: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class PhoneSalesLineDetail {
|
|
14
|
+
/** 10 dígitos MX normalizados (sin +52, espacios ni guiones). */
|
|
15
|
+
phone!: string;
|
|
16
|
+
/** Slug del operador tal como lo da benefits (`bait`, `telcel`, `at-t`). */
|
|
17
|
+
operatorId!: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class PhoneSalesSaleDetail {
|
|
21
|
+
variantId!: string;
|
|
22
|
+
model!: string;
|
|
23
|
+
storage!: string;
|
|
24
|
+
color!: string;
|
|
25
|
+
deliveryType!: string;
|
|
26
|
+
/** ISO-8601 UTC de la compra. */
|
|
27
|
+
purchasedAt!: string;
|
|
28
|
+
/** Se omite si la venta no lo tiene (ventas previas a DEC-011); nunca 0. */
|
|
29
|
+
amount?: number;
|
|
30
|
+
/** `USD` / `MXN`. Se omite si la venta no lo tiene; nunca vacío. */
|
|
31
|
+
currency?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// `detail` del evento PhoneSalesCodeRedeemed. El código canjeado NO viaja (funciona como secreto).
|
|
35
|
+
export class PhoneSalesCodeRedeemedEventDetail {
|
|
36
|
+
/** uuid generado al publicar. */
|
|
37
|
+
eventId!: string;
|
|
38
|
+
/** ISO-8601 UTC del momento del canje. */
|
|
39
|
+
occurredAt!: string;
|
|
40
|
+
saleId!: string;
|
|
41
|
+
/** Quien canjea (sale del token). */
|
|
42
|
+
redeemer!: PhoneSalesEventParty;
|
|
43
|
+
/** Quien compró (`buyerDirectorId`). */
|
|
44
|
+
buyer!: PhoneSalesEventParty;
|
|
45
|
+
line!: PhoneSalesLineDetail;
|
|
46
|
+
sale!: PhoneSalesSaleDetail;
|
|
47
|
+
}
|
package/src/phoneSales/index.ts
CHANGED
|
@@ -13,3 +13,4 @@ export * from './DeviceVariantPriceRequestDto';
|
|
|
13
13
|
export * from './SetDeviceVariantPricesRequestDto';
|
|
14
14
|
export * from './enums/DeviceImageContentTypeEnum';
|
|
15
15
|
export * from './enums/DeviceVariantStatusEnum';
|
|
16
|
+
export * from './events/PhoneSalesCodeRedeemedEventDetail';
|