@fiado/type-kit 3.535.0 → 3.537.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 (62) hide show
  1. package/_test_/unit/loanCredit/creditLifecycleEnums.test.ts +2 -1
  2. package/_test_/unit/loanCredit/signLoanCreditRequest.test.ts +37 -0
  3. package/_test_/unit/messagesConnector/otpBinding.test.ts +43 -0
  4. package/_test_/unit/retailWizard/otherStoreSale.test.ts +54 -0
  5. package/_test_/unit/retailWizard/signatureSendOtpRequest.test.ts +25 -0
  6. package/bin/loanCredit/dtos/LoanContract.d.ts +5 -1
  7. package/bin/loanCredit/dtos/LoanContract.js +8 -1
  8. package/bin/loanCredit/dtos/LoanContractSignatureEvidence.d.ts +45 -0
  9. package/bin/loanCredit/dtos/LoanContractSignatureEvidence.js +2 -0
  10. package/bin/loanCredit/dtos/SignatureContext.d.ts +20 -0
  11. package/bin/loanCredit/dtos/SignatureContext.js +92 -0
  12. package/bin/loanCredit/dtos/requests/SignLoanCreditRequest.d.ts +6 -0
  13. package/bin/loanCredit/dtos/requests/SignLoanCreditRequest.js +8 -0
  14. package/bin/loanCredit/dtos/responses/LoanContractResponse.d.ts +3 -0
  15. package/bin/loanCredit/enums/ContractTypeEnum.d.ts +2 -0
  16. package/bin/loanCredit/enums/ContractTypeEnum.js +2 -0
  17. package/bin/loanCredit/index.d.ts +2 -0
  18. package/bin/loanCredit/index.js +2 -0
  19. package/bin/messagesConnector/constants/OtpBinding.d.ts +2 -0
  20. package/bin/messagesConnector/constants/OtpBinding.js +5 -0
  21. package/bin/messagesConnector/dtos/SendMessageRequest.d.ts +1 -0
  22. package/bin/messagesConnector/dtos/SendMessageRequest.js +7 -0
  23. package/bin/messagesConnector/dtos/VerifyOtpRequest.d.ts +2 -0
  24. package/bin/messagesConnector/dtos/VerifyOtpRequest.js +14 -0
  25. package/bin/messagesConnector/dtos/VerifyOtpResponse.d.ts +6 -0
  26. package/bin/messagesConnector/index.d.ts +1 -0
  27. package/bin/messagesConnector/index.js +1 -0
  28. package/bin/retailWizard/dtos/WizardSession.d.ts +5 -0
  29. package/bin/retailWizard/dtos/requests/CancelOtherStoreSaleRequest.d.ts +9 -0
  30. package/bin/retailWizard/dtos/requests/CancelOtherStoreSaleRequest.js +34 -0
  31. package/bin/retailWizard/dtos/requests/SignatureSendOtpRequest.d.ts +7 -0
  32. package/bin/retailWizard/dtos/requests/SignatureSendOtpRequest.js +26 -0
  33. package/bin/retailWizard/dtos/responses/ActiveSessionByPhoneResponse.d.ts +5 -0
  34. package/bin/retailWizard/dtos/responses/CancelOtherStoreSaleResponse.d.ts +7 -0
  35. package/bin/retailWizard/dtos/responses/CancelOtherStoreSaleResponse.js +2 -0
  36. package/bin/retailWizard/enums/MoneyAtStakeKindEnum.d.ts +9 -0
  37. package/bin/retailWizard/enums/MoneyAtStakeKindEnum.js +13 -0
  38. package/bin/retailWizard/enums/SystemCancelReasonEnum.d.ts +7 -2
  39. package/bin/retailWizard/enums/SystemCancelReasonEnum.js +6 -1
  40. package/bin/retailWizard/index.d.ts +4 -0
  41. package/bin/retailWizard/index.js +4 -0
  42. package/package.json +1 -1
  43. package/src/loanCredit/dtos/LoanContract.ts +10 -2
  44. package/src/loanCredit/dtos/LoanContractSignatureEvidence.ts +50 -0
  45. package/src/loanCredit/dtos/SignatureContext.ts +75 -0
  46. package/src/loanCredit/dtos/requests/SignLoanCreditRequest.ts +11 -0
  47. package/src/loanCredit/dtos/responses/LoanContractResponse.ts +3 -0
  48. package/src/loanCredit/enums/ContractTypeEnum.ts +2 -0
  49. package/src/loanCredit/index.ts +2 -0
  50. package/src/messagesConnector/constants/OtpBinding.ts +2 -0
  51. package/src/messagesConnector/dtos/SendMessageRequest.ts +5 -1
  52. package/src/messagesConnector/dtos/VerifyOtpRequest.ts +5 -1
  53. package/src/messagesConnector/dtos/VerifyOtpResponse.ts +6 -0
  54. package/src/messagesConnector/index.ts +1 -0
  55. package/src/retailWizard/dtos/WizardSession.ts +5 -0
  56. package/src/retailWizard/dtos/requests/CancelOtherStoreSaleRequest.ts +20 -0
  57. package/src/retailWizard/dtos/requests/SignatureSendOtpRequest.ts +12 -0
  58. package/src/retailWizard/dtos/responses/ActiveSessionByPhoneResponse.ts +5 -0
  59. package/src/retailWizard/dtos/responses/CancelOtherStoreSaleResponse.ts +7 -0
  60. package/src/retailWizard/enums/MoneyAtStakeKindEnum.ts +9 -0
  61. package/src/retailWizard/enums/SystemCancelReasonEnum.ts +6 -1
  62. package/src/retailWizard/index.ts +4 -0
@@ -16,12 +16,13 @@ import {
16
16
  const sortedValues = (enumObject: Record<string, string>) => Object.values(enumObject).sort();
17
17
 
18
18
  describe('ContractTypeEnum', () => {
19
- it('suma los documentos del ciclo de vida a los tres de la originación', () => {
19
+ it('suma la constancia de firma y los documentos del ciclo de vida a los tres de la originación', () => {
20
20
  expect(sortedValues(ContractTypeEnum)).toEqual(
21
21
  [
22
22
  'CREDIT',
23
23
  'PROMISSORY_NOTE',
24
24
  'SIC_AUTHORIZATION',
25
+ 'SIGNATURE_EVIDENCE',
25
26
  'RESTRUCTURE_ADDENDUM',
26
27
  'ADVANCE_AUTHORIZATION',
27
28
  'SETTLEMENT_CERTIFICATE',
@@ -86,3 +86,40 @@ describe('SignLoanCreditRequest', () => {
86
86
  expect(await errorsOf({ contractDetails: details })).toEqual(['contractDetails.provider.legalName']);
87
87
  });
88
88
  });
89
+
90
+ const CONTEXT = {
91
+ ip: '201.141.10.20',
92
+ userAgent: 'Mozilla/5.0',
93
+ termsAccepted: true,
94
+ sellerId: 'ru-1',
95
+ sellerActorId: 'sub-1',
96
+ sellerName: 'Ana López',
97
+ storeId: 'st-1',
98
+ storeName: 'Tienda Centro',
99
+ wizardSessionId: 'WZ-1',
100
+ };
101
+
102
+ describe('SignLoanCreditRequest.signatureContext', () => {
103
+ it('acepta el contexto completo', async () => {
104
+ expect(await errorsOf({ signatureContext: CONTEXT })).toEqual([]);
105
+ });
106
+
107
+ it('acepta el contexto sin nombres ni navegador', async () => {
108
+ const minimal = { ip: CONTEXT.ip, sellerId: 'ru-1', sellerActorId: 'sub-1', storeId: 'st-1', wizardSessionId: 'WZ-1' };
109
+ expect(await errorsOf({ signatureContext: minimal })).toEqual([]);
110
+ });
111
+
112
+ it('exige ip, vendedor, tienda y sesión', async () => {
113
+ expect(await errorsOf({ signatureContext: {} })).toEqual([
114
+ 'signatureContext.ip',
115
+ 'signatureContext.sellerActorId',
116
+ 'signatureContext.sellerId',
117
+ 'signatureContext.storeId',
118
+ 'signatureContext.wizardSessionId',
119
+ ]);
120
+ });
121
+
122
+ it('rechaza una aceptación que no es booleana', async () => {
123
+ expect(await errorsOf({ signatureContext: { ...CONTEXT, termsAccepted: 'si' } })).toEqual(['signatureContext.termsAccepted']);
124
+ });
125
+ });
@@ -0,0 +1,43 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import { SendMessageRequest, VerifyOtpRequest } from '../../../src/messagesConnector/index';
5
+ import { DeliveryChannelEnum } from '../../../src/messaging';
6
+
7
+ const HASH = 'a'.repeat(64);
8
+ const SEND = {
9
+ channelType: DeliveryChannelEnum.SMS,
10
+ messageType: 'CONTRACT_SIGNATURE_OTP',
11
+ directoryId: 'd1',
12
+ typeOfDirectory: 'USER',
13
+ language: 'es',
14
+ country: 'MX',
15
+ destination: '+525512345678',
16
+ transactionNumber: 'c-1',
17
+ };
18
+ const VERIFY = { directoryId: 'd1', typeOfDirectoryId: 'USER', message: '1234' };
19
+
20
+ const failing = async (cls: new () => object, body: Record<string, unknown>): Promise<string[]> =>
21
+ (await validate(plainToInstance(cls, body))).map((error) => error.property).sort();
22
+
23
+ describe('amarre del código de firma', () => {
24
+ it('SendMessageRequest acepta la huella sha256 del documento', async () => {
25
+ expect(await failing(SendMessageRequest, { ...SEND, documentHash: HASH })).toEqual([]);
26
+ });
27
+
28
+ it('SendMessageRequest rechaza una huella que no es sha256 en hexadecimal', async () => {
29
+ expect(await failing(SendMessageRequest, { ...SEND, documentHash: 'ABC' })).toEqual(['documentHash']);
30
+ });
31
+
32
+ it('VerifyOtpRequest acepta el crédito y la huella', async () => {
33
+ expect(await failing(VerifyOtpRequest, { ...VERIFY, transactionNumber: 'c-1', documentHash: HASH })).toEqual([]);
34
+ });
35
+
36
+ it('VerifyOtpRequest sigue aceptando la verificación sin amarre', async () => {
37
+ expect(await failing(VerifyOtpRequest, VERIFY)).toEqual([]);
38
+ });
39
+
40
+ it('VerifyOtpRequest rechaza una huella inválida', async () => {
41
+ expect(await failing(VerifyOtpRequest, { ...VERIFY, documentHash: 'x' })).toEqual(['documentHash']);
42
+ });
43
+ });
@@ -0,0 +1,54 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import {
5
+ CancelOtherStoreSaleRequest,
6
+ SystemCancelReasonEnum,
7
+ type ActiveSessionByPhoneResponse,
8
+ type CancelOtherStoreSaleResponse,
9
+ type WizardSession,
10
+ } from '../../../src/retailWizard';
11
+
12
+ async function errorsOf(body: Record<string, unknown>): Promise<string[]> {
13
+ const errors = await validate(plainToInstance(CancelOtherStoreSaleRequest, body));
14
+ return errors.map((e) => e.property);
15
+ }
16
+
17
+ describe('SystemCancelReasonEnum', () => {
18
+ it('names the cancel when another store takes the customer over', () => {
19
+ expect(SystemCancelReasonEnum.TAKEN_OVER_BY_OTHER_STORE).toBe('TAKEN_OVER_BY_OTHER_STORE');
20
+ });
21
+ });
22
+
23
+ describe('CancelOtherStoreSaleRequest', () => {
24
+ it('accepts a phone and a reason of at least 10 characters', async () => {
25
+ expect(await errorsOf({ phone: '5512345678', reason: 'El cliente compra aquí' })).toEqual([]);
26
+ });
27
+
28
+ it('the reason is mandatory and meaningful', async () => {
29
+ expect(await errorsOf({ phone: '5512345678' })).toContain('reason');
30
+ expect(await errorsOf({ phone: '5512345678', reason: 'corto' })).toContain('reason');
31
+ });
32
+
33
+ it('the phone is mandatory', async () => {
34
+ expect(await errorsOf({ reason: 'El cliente compra aquí' })).toContain('phone');
35
+ });
36
+ });
37
+
38
+ describe('cash-only sale', () => {
39
+ it('WizardSession and the sale by phone carry the cash-only mark', () => {
40
+ const session: Pick<WizardSession, 'cashOnly'> = { cashOnly: true };
41
+ const byPhone: Pick<ActiveSessionByPhoneResponse, 'cashOnly'> = { cashOnly: true };
42
+ const cancelled: CancelOtherStoreSaleResponse = { sessionId: 'S1', refundPendingCents: null };
43
+ expect([session.cashOnly, byPhone.cashOnly, cancelled.sessionId]).toEqual([true, true, 'S1']);
44
+ });
45
+ });
46
+
47
+ describe('MoneyAtStakeKindEnum', () => {
48
+ it('distinguishes a charged or closed sale from a quoted credit', async () => {
49
+ const { MoneyAtStakeKindEnum } = await import('../../../src/retailWizard');
50
+ expect(Object.values(MoneyAtStakeKindEnum)).toEqual(['SALE', 'CREDIT_QUOTED']);
51
+ const byPhone: Pick<ActiveSessionByPhoneResponse, 'moneyAtStakeKind'> = { moneyAtStakeKind: MoneyAtStakeKindEnum.CREDIT_QUOTED };
52
+ expect(byPhone.moneyAtStakeKind).toBe('CREDIT_QUOTED');
53
+ });
54
+ });
@@ -0,0 +1,25 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import { SignatureSendOtpRequest } from '../../../src/retailWizard/index';
5
+
6
+ const failing = async (body: Record<string, unknown>): Promise<string[]> =>
7
+ (await validate(plainToInstance(SignatureSendOtpRequest, body))).map((error) => error.property);
8
+
9
+ describe('SignatureSendOtpRequest', () => {
10
+ it('acepta la aceptación de los términos', async () => {
11
+ expect(await failing({ termsAccepted: true })).toEqual([]);
12
+ });
13
+
14
+ it('rechaza el envío sin aceptación', async () => {
15
+ expect(await failing({})).toEqual(['termsAccepted']);
16
+ });
17
+
18
+ it('rechaza termsAccepted en false', async () => {
19
+ expect(await failing({ termsAccepted: false })).toEqual(['termsAccepted']);
20
+ });
21
+
22
+ it('rechaza "true" como texto', async () => {
23
+ expect(await failing({ termsAccepted: 'true' })).toEqual(['termsAccepted']);
24
+ });
25
+ });
@@ -1,7 +1,9 @@
1
1
  import { ContractTypeEnum } from '../enums/ContractTypeEnum';
2
+ import type { LoanContractSignatureEvidence } from './LoanContractSignatureEvidence';
2
3
  /**
3
4
  * LoanContract — documento del contrato de crédito con firma FES (modelo-datos §5b ·
4
- * `<T>LoanContract_GT` · M2 §4.3-§4.4). Un registro por documento (3 por crédito — C4).
5
+ * `<T>LoanContract_GT` · M2 §4.3-§4.4). Un registro por documento: los 3 de la originación (C4), más la
6
+ * constancia de firma al firmar.
5
7
  *
6
8
  * Nace DRAFT en la originación (sin PDF); la firma FES genera el PDF, calcula su `sha256`,
7
9
  * verifica el OTP y sella con NOM-151. Conservación documental: 10 años (NOM-151).
@@ -22,6 +24,8 @@ export declare class LoanContract {
22
24
  /** Sello de tiempo NOM-151 (TSA). Ausente hasta firmar (AS del TSA connector). */
23
25
  nom151Timestamp?: string;
24
26
  signedAt?: string;
27
+ /** Evidencia de la firma con código (solo en documentos firmados). */
28
+ signatureEvidence?: LoanContractSignatureEvidence;
25
29
  createdBy: string;
26
30
  updatedBy: string;
27
31
  createdAt: string;
@@ -16,7 +16,8 @@ const regex_1 = require("../../helpers/constans/regex");
16
16
  const ContractTypeEnum_1 = require("../enums/ContractTypeEnum");
17
17
  /**
18
18
  * LoanContract — documento del contrato de crédito con firma FES (modelo-datos §5b ·
19
- * `<T>LoanContract_GT` · M2 §4.3-§4.4). Un registro por documento (3 por crédito — C4).
19
+ * `<T>LoanContract_GT` · M2 §4.3-§4.4). Un registro por documento: los 3 de la originación (C4), más la
20
+ * constancia de firma al firmar.
20
21
  *
21
22
  * Nace DRAFT en la originación (sin PDF); la firma FES genera el PDF, calcula su `sha256`,
22
23
  * verifica el OTP y sella con NOM-151. Conservación documental: 10 años (NOM-151).
@@ -75,6 +76,12 @@ __decorate([
75
76
  (0, class_validator_1.Matches)(regex_1.regexIso8601),
76
77
  __metadata("design:type", String)
77
78
  ], LoanContract.prototype, "signedAt", void 0);
79
+ __decorate([
80
+ (0, class_transformer_1.Expose)(),
81
+ (0, class_validator_1.IsOptional)(),
82
+ (0, class_validator_1.IsObject)(),
83
+ __metadata("design:type", Object)
84
+ ], LoanContract.prototype, "signatureEvidence", void 0);
78
85
  __decorate([
79
86
  (0, class_transformer_1.Expose)(),
80
87
  (0, class_validator_1.IsString)(),
@@ -0,0 +1,45 @@
1
+ /** El código de firma tal como lo validó messages-business. */
2
+ export interface SignatureEvidenceOtp {
3
+ /** Id del envío en messages-business (fila del log del código). */
4
+ messageLogId: string;
5
+ sentAt: string;
6
+ verifiedAt: string;
7
+ channel: 'SMS';
8
+ /** Teléfono destino enmascarado (`****1234`). */
9
+ destinationMasked?: string;
10
+ }
11
+ /** Envíos del código (con reenvíos) y validaciones fallidas antes de firmar. */
12
+ export interface SignatureEvidenceAttempts {
13
+ sends: number;
14
+ failedVerifications: number;
15
+ }
16
+ /** Aceptación de términos del tiempo 1, amarrada a la huella del contrato generado en esa llamada. */
17
+ export interface SignatureEvidenceAcceptance {
18
+ acceptedAt: string;
19
+ contractSha256: string;
20
+ ip: string;
21
+ userAgent?: string;
22
+ }
23
+ /** Desde dónde y quién envió el código al firmar (tiempo 2). */
24
+ export interface SignatureEvidenceSigning {
25
+ ip: string;
26
+ userAgent?: string;
27
+ sellerActorId: string;
28
+ }
29
+ /** Quién facilitó la firma en la tienda. */
30
+ export interface SignatureEvidenceFacilitator {
31
+ sellerId: string;
32
+ sellerActorId: string;
33
+ sellerName?: string;
34
+ storeId: string;
35
+ storeName?: string;
36
+ wizardSessionId: string;
37
+ }
38
+ /** Evidencia de la firma con código que queda en cada documento firmado. */
39
+ export interface LoanContractSignatureEvidence {
40
+ otp: SignatureEvidenceOtp;
41
+ attempts: SignatureEvidenceAttempts;
42
+ acceptance: SignatureEvidenceAcceptance;
43
+ signing: SignatureEvidenceSigning;
44
+ facilitator: SignatureEvidenceFacilitator;
45
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Contexto de la firma que aporta el wizard en cada tiempo de `POST /private/credits/:creditId/sign`:
3
+ * quién facilita la firma (vendedor, tienda, sesión) y desde qué navegador. Es evidencia de la
4
+ * ceremonia: la IP y el navegador son del equipo de la tienda. Nunca se loguean.
5
+ */
6
+ export declare class SignatureContext {
7
+ /** IP de origen de la llamada, como la ve el API Gateway del wizard. */
8
+ ip: string;
9
+ userAgent?: string;
10
+ /** Tiempo 1: el cliente marcó "Acepto los términos". El motor exige `true` para mandar el código. */
11
+ termsAccepted?: boolean;
12
+ /** Usuario retail del vendedor. */
13
+ sellerId: string;
14
+ /** Cognito sub del vendedor: queda como actor de la firma. */
15
+ sellerActorId: string;
16
+ sellerName?: string;
17
+ storeId: string;
18
+ storeName?: string;
19
+ wizardSessionId: string;
20
+ }
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SignatureContext = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ /** Largo máximo de un id operacional (vendedor, tienda, sesión). */
16
+ const ID_TEXT = 128;
17
+ /** Largo máximo de un nombre para mostrar. */
18
+ const NAME_TEXT = 300;
19
+ /** Una IPv6 mide 39 caracteres; se deja margen para el formato mapeado. */
20
+ const IP_TEXT = 64;
21
+ /** Los navegadores mandan User-Agent de 150 a 300 caracteres. */
22
+ const USER_AGENT_TEXT = 512;
23
+ /**
24
+ * Contexto de la firma que aporta el wizard en cada tiempo de `POST /private/credits/:creditId/sign`:
25
+ * quién facilita la firma (vendedor, tienda, sesión) y desde qué navegador. Es evidencia de la
26
+ * ceremonia: la IP y el navegador son del equipo de la tienda. Nunca se loguean.
27
+ */
28
+ class SignatureContext {
29
+ }
30
+ exports.SignatureContext = SignatureContext;
31
+ __decorate([
32
+ (0, class_transformer_1.Expose)(),
33
+ (0, class_validator_1.IsString)(),
34
+ (0, class_validator_1.IsNotEmpty)(),
35
+ (0, class_validator_1.MaxLength)(IP_TEXT),
36
+ __metadata("design:type", String)
37
+ ], SignatureContext.prototype, "ip", void 0);
38
+ __decorate([
39
+ (0, class_transformer_1.Expose)(),
40
+ (0, class_validator_1.IsOptional)(),
41
+ (0, class_validator_1.IsString)(),
42
+ (0, class_validator_1.MaxLength)(USER_AGENT_TEXT),
43
+ __metadata("design:type", String)
44
+ ], SignatureContext.prototype, "userAgent", void 0);
45
+ __decorate([
46
+ (0, class_transformer_1.Expose)(),
47
+ (0, class_validator_1.IsOptional)(),
48
+ (0, class_validator_1.IsBoolean)(),
49
+ __metadata("design:type", Boolean)
50
+ ], SignatureContext.prototype, "termsAccepted", void 0);
51
+ __decorate([
52
+ (0, class_transformer_1.Expose)(),
53
+ (0, class_validator_1.IsString)(),
54
+ (0, class_validator_1.IsNotEmpty)(),
55
+ (0, class_validator_1.MaxLength)(ID_TEXT),
56
+ __metadata("design:type", String)
57
+ ], SignatureContext.prototype, "sellerId", void 0);
58
+ __decorate([
59
+ (0, class_transformer_1.Expose)(),
60
+ (0, class_validator_1.IsString)(),
61
+ (0, class_validator_1.IsNotEmpty)(),
62
+ (0, class_validator_1.MaxLength)(ID_TEXT),
63
+ __metadata("design:type", String)
64
+ ], SignatureContext.prototype, "sellerActorId", void 0);
65
+ __decorate([
66
+ (0, class_transformer_1.Expose)(),
67
+ (0, class_validator_1.IsOptional)(),
68
+ (0, class_validator_1.IsString)(),
69
+ (0, class_validator_1.MaxLength)(NAME_TEXT),
70
+ __metadata("design:type", String)
71
+ ], SignatureContext.prototype, "sellerName", void 0);
72
+ __decorate([
73
+ (0, class_transformer_1.Expose)(),
74
+ (0, class_validator_1.IsString)(),
75
+ (0, class_validator_1.IsNotEmpty)(),
76
+ (0, class_validator_1.MaxLength)(ID_TEXT),
77
+ __metadata("design:type", String)
78
+ ], SignatureContext.prototype, "storeId", void 0);
79
+ __decorate([
80
+ (0, class_transformer_1.Expose)(),
81
+ (0, class_validator_1.IsOptional)(),
82
+ (0, class_validator_1.IsString)(),
83
+ (0, class_validator_1.MaxLength)(NAME_TEXT),
84
+ __metadata("design:type", String)
85
+ ], SignatureContext.prototype, "storeName", void 0);
86
+ __decorate([
87
+ (0, class_transformer_1.Expose)(),
88
+ (0, class_validator_1.IsString)(),
89
+ (0, class_validator_1.IsNotEmpty)(),
90
+ (0, class_validator_1.MaxLength)(ID_TEXT),
91
+ __metadata("design:type", String)
92
+ ], SignatureContext.prototype, "wizardSessionId", void 0);
@@ -1,4 +1,5 @@
1
1
  import { LoanContractDetails } from '../LoanContractDetails';
2
+ import { SignatureContext } from '../SignatureContext';
2
3
  /**
3
4
  * Body de `POST /private/credits/:creditId/sign` (loan-credit-business — wizard paso 08, firma FES
4
5
  * M2 §4.4). Endpoint de DOS tiempos sobre el mismo contrato:
@@ -40,4 +41,9 @@ export declare class SignLoanCreditRequest {
40
41
  * PII-zero — el teléfono vive en RetailCustomer).
41
42
  */
42
43
  otpDestination?: string;
44
+ /**
45
+ * Ambos tiempos: quién facilita la firma y desde qué navegador (evidencia de la ceremonia). En el
46
+ * tiempo 1 trae `termsAccepted: true`. El motor lo exige; la IP y el navegador nunca se loguean.
47
+ */
48
+ signatureContext?: SignatureContext;
43
49
  }
@@ -13,6 +13,7 @@ exports.SignLoanCreditRequest = void 0;
13
13
  const class_transformer_1 = require("class-transformer");
14
14
  const class_validator_1 = require("class-validator");
15
15
  const LoanContractDetails_1 = require("../LoanContractDetails");
16
+ const SignatureContext_1 = require("../SignatureContext");
16
17
  /**
17
18
  * Body de `POST /private/credits/:creditId/sign` (loan-credit-business — wizard paso 08, firma FES
18
19
  * M2 §4.4). Endpoint de DOS tiempos sobre el mismo contrato:
@@ -61,3 +62,10 @@ __decorate([
61
62
  (0, class_validator_1.IsString)(),
62
63
  __metadata("design:type", String)
63
64
  ], SignLoanCreditRequest.prototype, "otpDestination", void 0);
65
+ __decorate([
66
+ (0, class_transformer_1.Expose)(),
67
+ (0, class_validator_1.IsOptional)(),
68
+ (0, class_validator_1.ValidateNested)(),
69
+ (0, class_transformer_1.Type)(() => SignatureContext_1.SignatureContext),
70
+ __metadata("design:type", SignatureContext_1.SignatureContext)
71
+ ], SignLoanCreditRequest.prototype, "signatureContext", void 0);
@@ -1,4 +1,5 @@
1
1
  import { ContractTypeEnum } from '../../enums/ContractTypeEnum';
2
+ import type { LoanContractSignatureEvidence } from '../LoanContractSignatureEvidence';
2
3
  /**
3
4
  * Response de un documento del contrato (loan-credit-business). `signedAt` ausente = draft.
4
5
  */
@@ -12,6 +13,8 @@ export interface LoanContractResponse {
12
13
  otpVerified: boolean;
13
14
  nom151Timestamp?: string;
14
15
  signedAt?: string;
16
+ /** Evidencia de la firma con código (solo en documentos firmados). */
17
+ signatureEvidence?: LoanContractSignatureEvidence;
15
18
  createdAt: string;
16
19
  updatedAt: string;
17
20
  }
@@ -6,6 +6,8 @@ export declare enum ContractTypeEnum {
6
6
  CREDIT = "CREDIT",
7
7
  PROMISSORY_NOTE = "PROMISSORY_NOTE",
8
8
  SIC_AUTHORIZATION = "SIC_AUTHORIZATION",
9
+ /** Constancia de firma electrónica: la evidencia de la firma con código, en PDF. */
10
+ SIGNATURE_EVIDENCE = "SIGNATURE_EVIDENCE",
9
11
  RESTRUCTURE_ADDENDUM = "RESTRUCTURE_ADDENDUM",
10
12
  ADVANCE_AUTHORIZATION = "ADVANCE_AUTHORIZATION",
11
13
  SETTLEMENT_CERTIFICATE = "SETTLEMENT_CERTIFICATE",
@@ -10,6 +10,8 @@ var ContractTypeEnum;
10
10
  ContractTypeEnum["CREDIT"] = "CREDIT";
11
11
  ContractTypeEnum["PROMISSORY_NOTE"] = "PROMISSORY_NOTE";
12
12
  ContractTypeEnum["SIC_AUTHORIZATION"] = "SIC_AUTHORIZATION";
13
+ /** Constancia de firma electrónica: la evidencia de la firma con código, en PDF. */
14
+ ContractTypeEnum["SIGNATURE_EVIDENCE"] = "SIGNATURE_EVIDENCE";
13
15
  ContractTypeEnum["RESTRUCTURE_ADDENDUM"] = "RESTRUCTURE_ADDENDUM";
14
16
  ContractTypeEnum["ADVANCE_AUTHORIZATION"] = "ADVANCE_AUTHORIZATION";
15
17
  ContractTypeEnum["SETTLEMENT_CERTIFICATE"] = "SETTLEMENT_CERTIFICATE";
@@ -9,6 +9,8 @@ export * from './dtos/LoanInstallment';
9
9
  export * from './dtos/InstallmentPaidEvent';
10
10
  export * from './dtos/LoanContract';
11
11
  export * from './dtos/LoanContractDetails';
12
+ export * from './dtos/SignatureContext';
13
+ export * from './dtos/LoanContractSignatureEvidence';
12
14
  export * from './dtos/ActivationChecklist';
13
15
  export * from './dtos/AppliedPromotionSnapshot';
14
16
  export * from './dtos/AppliedStorePolicySnapshot';
@@ -30,6 +30,8 @@ __exportStar(require("./dtos/LoanInstallment"), exports);
30
30
  __exportStar(require("./dtos/InstallmentPaidEvent"), exports);
31
31
  __exportStar(require("./dtos/LoanContract"), exports);
32
32
  __exportStar(require("./dtos/LoanContractDetails"), exports);
33
+ __exportStar(require("./dtos/SignatureContext"), exports);
34
+ __exportStar(require("./dtos/LoanContractSignatureEvidence"), exports);
33
35
  __exportStar(require("./dtos/ActivationChecklist"), exports);
34
36
  __exportStar(require("./dtos/AppliedPromotionSnapshot"), exports);
35
37
  __exportStar(require("./dtos/AppliedStorePolicySnapshot"), exports);
@@ -0,0 +1,2 @@
1
+ /** Huella SHA-256 en hexadecimal, tal como la calcula pdf-render sobre el PDF. */
2
+ export declare const OTP_DOCUMENT_HASH_PATTERN: RegExp;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OTP_DOCUMENT_HASH_PATTERN = void 0;
4
+ /** Huella SHA-256 en hexadecimal, tal como la calcula pdf-render sobre el PDF. */
5
+ exports.OTP_DOCUMENT_HASH_PATTERN = /^[a-f0-9]{64}$/;
@@ -18,6 +18,7 @@ export declare class SendMessageRequest {
18
18
  options?: Record<string, unknown>;
19
19
  referenceMessageId?: string;
20
20
  transactionNumber?: string;
21
+ documentHash?: string;
21
22
  purpose?: OtpMessagePurposeEnum;
22
23
  tenantId?: string;
23
24
  }
@@ -13,6 +13,7 @@ exports.SendMessageRequest = void 0;
13
13
  const class_transformer_1 = require("class-transformer");
14
14
  const class_validator_1 = require("class-validator");
15
15
  const messaging_1 = require("../../messaging");
16
+ const OtpBinding_1 = require("../constants/OtpBinding");
16
17
  const OtpMessagePurposeEnum_1 = require("../enums/OtpMessagePurposeEnum");
17
18
  class SendMessageRequest {
18
19
  }
@@ -118,6 +119,12 @@ __decorate([
118
119
  (0, class_validator_1.IsString)(),
119
120
  __metadata("design:type", String)
120
121
  ], SendMessageRequest.prototype, "transactionNumber", void 0);
122
+ __decorate([
123
+ (0, class_transformer_1.Expose)(),
124
+ (0, class_validator_1.IsOptional)(),
125
+ (0, class_validator_1.Matches)(OtpBinding_1.OTP_DOCUMENT_HASH_PATTERN),
126
+ __metadata("design:type", String)
127
+ ], SendMessageRequest.prototype, "documentHash", void 0);
121
128
  __decorate([
122
129
  (0, class_transformer_1.Expose)(),
123
130
  (0, class_validator_1.IsOptional)(),
@@ -4,4 +4,6 @@ export declare class VerifyOtpRequest {
4
4
  typeOfDirectoryId: string;
5
5
  message: string;
6
6
  purpose?: OtpMessagePurposeEnum;
7
+ transactionNumber?: string;
8
+ documentHash?: string;
7
9
  }
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.VerifyOtpRequest = void 0;
13
13
  const class_transformer_1 = require("class-transformer");
14
14
  const class_validator_1 = require("class-validator");
15
+ const OtpBinding_1 = require("../constants/OtpBinding");
15
16
  const OtpMessagePurposeEnum_1 = require("../enums/OtpMessagePurposeEnum");
16
17
  class VerifyOtpRequest {
17
18
  }
@@ -40,3 +41,16 @@ __decorate([
40
41
  (0, class_validator_1.IsEnum)(OtpMessagePurposeEnum_1.OtpMessagePurposeEnum),
41
42
  __metadata("design:type", String)
42
43
  ], VerifyOtpRequest.prototype, "purpose", void 0);
44
+ __decorate([
45
+ (0, class_transformer_1.Expose)(),
46
+ (0, class_validator_1.IsOptional)(),
47
+ (0, class_validator_1.IsString)(),
48
+ (0, class_validator_1.IsNotEmpty)(),
49
+ __metadata("design:type", String)
50
+ ], VerifyOtpRequest.prototype, "transactionNumber", void 0);
51
+ __decorate([
52
+ (0, class_transformer_1.Expose)(),
53
+ (0, class_validator_1.IsOptional)(),
54
+ (0, class_validator_1.Matches)(OtpBinding_1.OTP_DOCUMENT_HASH_PATTERN),
55
+ __metadata("design:type", String)
56
+ ], VerifyOtpRequest.prototype, "documentHash", void 0);
@@ -2,4 +2,10 @@ export declare class VerifyOtpResponse {
2
2
  verified: boolean;
3
3
  directoryId: string;
4
4
  typeOfDirectoryId: string;
5
+ /** Id del envío (fila del log) que se validó. */
6
+ logId?: string;
7
+ /** Cuándo se mandó el código (ISO 8601). */
8
+ sentAt?: string;
9
+ /** Cuándo se validó (ISO 8601). */
10
+ verifiedAt?: string;
5
11
  }
@@ -2,6 +2,7 @@ export * from './enums/DeliveryChannelExtendedEnum';
2
2
  export * from './enums/NotificationOriginEnum';
3
3
  export * from './enums/MessagingSlotEnum';
4
4
  export * from './enums/OtpMessagePurposeEnum';
5
+ export * from './constants/OtpBinding';
5
6
  export * from './validators/IsStringValueRecord';
6
7
  export * from './dtos/NotificationQueueMessageRequestV2';
7
8
  export * from './dtos/SendMessageRequest';
@@ -18,6 +18,7 @@ __exportStar(require("./enums/DeliveryChannelExtendedEnum"), exports);
18
18
  __exportStar(require("./enums/NotificationOriginEnum"), exports);
19
19
  __exportStar(require("./enums/MessagingSlotEnum"), exports);
20
20
  __exportStar(require("./enums/OtpMessagePurposeEnum"), exports);
21
+ __exportStar(require("./constants/OtpBinding"), exports);
21
22
  __exportStar(require("./validators/IsStringValueRecord"), exports);
22
23
  __exportStar(require("./dtos/NotificationQueueMessageRequestV2"), exports);
23
24
  __exportStar(require("./dtos/SendMessageRequest"), exports);
@@ -151,6 +151,11 @@ export interface WizardSession {
151
151
  /** Prospecto vinculado (si la sesión se reanudó desde un prospecto): se cierra al cerrar la venta (D-prospecto). */
152
152
  prospectId: string | null;
153
153
  cancelReason: string | null;
154
+ /**
155
+ * Venta solo de contado: el cliente tiene una venta con dinero en juego en otra sucursal.
156
+ * Crédito y derivación se rechazan con `CREDIT_IN_PROGRESS_OTHER_STORE`. Ausente = venta completa.
157
+ */
158
+ cashOnly?: boolean;
154
159
  /** TTL DDB ~24h de inactividad (D14). */
155
160
  ttlEpoch: number;
156
161
  createdBy: string;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * POST /wizard/phone-holder/cancel y /backoffice/phone-holder/cancel — el encargado de tienda o el
3
+ * Admin VL cancela la venta viva de otra sucursal que retiene al cliente. SureKeep — pista Retail.
4
+ */
5
+ export declare class CancelOtherStoreSaleRequest {
6
+ /** Teléfono del cliente: la venta ajena no se expone, así que es la única llave. */
7
+ phone: string;
8
+ reason: string;
9
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CancelOtherStoreSaleRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ /**
16
+ * POST /wizard/phone-holder/cancel y /backoffice/phone-holder/cancel — el encargado de tienda o el
17
+ * Admin VL cancela la venta viva de otra sucursal que retiene al cliente. SureKeep — pista Retail.
18
+ */
19
+ class CancelOtherStoreSaleRequest {
20
+ }
21
+ exports.CancelOtherStoreSaleRequest = CancelOtherStoreSaleRequest;
22
+ __decorate([
23
+ (0, class_transformer_1.Expose)(),
24
+ (0, class_validator_1.IsString)(),
25
+ (0, class_validator_1.MaxLength)(20),
26
+ __metadata("design:type", String)
27
+ ], CancelOtherStoreSaleRequest.prototype, "phone", void 0);
28
+ __decorate([
29
+ (0, class_transformer_1.Expose)(),
30
+ (0, class_validator_1.IsString)(),
31
+ (0, class_validator_1.MinLength)(10),
32
+ (0, class_validator_1.MaxLength)(200),
33
+ __metadata("design:type", String)
34
+ ], CancelOtherStoreSaleRequest.prototype, "reason", void 0);