@fiado/api-invoker 4.72.0 → 4.74.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/bin/index.d.ts CHANGED
@@ -84,6 +84,7 @@ export * from "./retailCards/index.js";
84
84
  export * from "./loanConfig/index.js";
85
85
  export * from "./loanOfferings/index.js";
86
86
  export * from "./loanCollectorAssignment/index.js";
87
+ export * from "./loanCredit/index.js";
87
88
  export * from "./messages-business/index.js";
88
89
  export * from "./totp-security/index.js";
89
90
  export * from "./equality-connector/index.js";
package/bin/index.js CHANGED
@@ -84,6 +84,7 @@ export * from "./retailCards/index.js";
84
84
  export * from "./loanConfig/index.js";
85
85
  export * from "./loanOfferings/index.js";
86
86
  export * from "./loanCollectorAssignment/index.js";
87
+ export * from "./loanCredit/index.js";
87
88
  export * from "./messages-business/index.js";
88
89
  export * from "./totp-security/index.js";
89
90
  export * from "./equality-connector/index.js";
@@ -0,0 +1,28 @@
1
+ import type { IHttpRequest } from "@fiado/http-client";
2
+ import { StandardResponse } from "@fiado/gateway-adapter";
3
+ import { ActivationCheckRequest, ActivationCheckResponse, LoanBorrowerResponse, LoanCreditResponse, OriginateLoanCreditRequest, OriginateLoanCreditResponse, QuoteLoanCreditRequest, QuoteLoanCreditResponse, SignLoanCreditRequest, SignLoanCreditResponse, UpsertLoanBorrowerRequest } from "@fiado/type-kit/bin/loanCredit/index.js";
4
+ import { ILoanCreditBusinessApi } from "./interfaces/ILoanCreditBusinessApi.js";
5
+ /**
6
+ * Publisher HTTP del lambda `loan-credit-business` (componente 09 SureKeep F2 — motor de crédito).
7
+ * Contrato y semántica completos → `ILoanCreditBusinessApi` (tenantId obligatorio,
8
+ * `StandardResponse` → leer `result.data`).
9
+ *
10
+ * Env var requerida en el consumer: `LOAN_CREDIT_BUSINESS_URL`.
11
+ * El template.yml del consumer la setea con:
12
+ *
13
+ * LOAN_CREDIT_BUSINESS_URL: '{{resolve:ssm:loan-credit-business}}'
14
+ *
15
+ * Convención CLAUDE.md global: SSM key = nombre del lambda owner de la URL.
16
+ */
17
+ export default class LoanCreditBusinessApi implements ILoanCreditBusinessApi {
18
+ private httpRequest;
19
+ private readonly baseUrl;
20
+ constructor(httpRequest: IHttpRequest);
21
+ originate(input: OriginateLoanCreditRequest, tenantId: string): Promise<StandardResponse<OriginateLoanCreditResponse>>;
22
+ quote(creditId: string, input: QuoteLoanCreditRequest, tenantId: string): Promise<StandardResponse<QuoteLoanCreditResponse>>;
23
+ sign(creditId: string, input: SignLoanCreditRequest, tenantId: string): Promise<StandardResponse<SignLoanCreditResponse>>;
24
+ activateCheck(creditId: string, input: ActivationCheckRequest, tenantId: string): Promise<StandardResponse<ActivationCheckResponse>>;
25
+ getCredit(creditId: string, tenantId: string): Promise<StandardResponse<LoanCreditResponse>>;
26
+ getBorrowerByRetailCustomer(retailCustomerId: string, tenantId: string): Promise<StandardResponse<LoanBorrowerResponse>>;
27
+ upsertBorrower(input: UpsertLoanBorrowerRequest, tenantId: string): Promise<StandardResponse<LoanBorrowerResponse>>;
28
+ }
@@ -0,0 +1,67 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { inject, injectable } from "inversify";
14
+ /**
15
+ * Publisher HTTP del lambda `loan-credit-business` (componente 09 SureKeep F2 — motor de crédito).
16
+ * Contrato y semántica completos → `ILoanCreditBusinessApi` (tenantId obligatorio,
17
+ * `StandardResponse` → leer `result.data`).
18
+ *
19
+ * Env var requerida en el consumer: `LOAN_CREDIT_BUSINESS_URL`.
20
+ * El template.yml del consumer la setea con:
21
+ *
22
+ * LOAN_CREDIT_BUSINESS_URL: '{{resolve:ssm:loan-credit-business}}'
23
+ *
24
+ * Convención CLAUDE.md global: SSM key = nombre del lambda owner de la URL.
25
+ */
26
+ let LoanCreditBusinessApi = class LoanCreditBusinessApi {
27
+ httpRequest;
28
+ // El buildspec publica la URL en SSM con "/" final — se normaliza para no armar "//private".
29
+ baseUrl = (process.env.LOAN_CREDIT_BUSINESS_URL || "").replace(/\/+$/, "");
30
+ constructor(httpRequest) {
31
+ this.httpRequest = httpRequest;
32
+ }
33
+ async originate(input, tenantId) {
34
+ const url = `${this.baseUrl}/private/credits/originate?tenantId=${encodeURIComponent(tenantId)}`;
35
+ return await this.httpRequest.post(url, input);
36
+ }
37
+ async quote(creditId, input, tenantId) {
38
+ const url = `${this.baseUrl}/private/credits/${encodeURIComponent(creditId)}/quote?tenantId=${encodeURIComponent(tenantId)}`;
39
+ return await this.httpRequest.post(url, input);
40
+ }
41
+ async sign(creditId, input, tenantId) {
42
+ const url = `${this.baseUrl}/private/credits/${encodeURIComponent(creditId)}/sign?tenantId=${encodeURIComponent(tenantId)}`;
43
+ return await this.httpRequest.post(url, input);
44
+ }
45
+ async activateCheck(creditId, input, tenantId) {
46
+ const url = `${this.baseUrl}/private/credits/${encodeURIComponent(creditId)}/activate-check?tenantId=${encodeURIComponent(tenantId)}`;
47
+ return await this.httpRequest.post(url, input);
48
+ }
49
+ async getCredit(creditId, tenantId) {
50
+ const url = `${this.baseUrl}/private/credits/${encodeURIComponent(creditId)}?tenantId=${encodeURIComponent(tenantId)}`;
51
+ return await this.httpRequest.get(url);
52
+ }
53
+ async getBorrowerByRetailCustomer(retailCustomerId, tenantId) {
54
+ const url = `${this.baseUrl}/private/borrowers/by-retail-customer/${encodeURIComponent(retailCustomerId)}?tenantId=${encodeURIComponent(tenantId)}`;
55
+ return await this.httpRequest.get(url);
56
+ }
57
+ async upsertBorrower(input, tenantId) {
58
+ const url = `${this.baseUrl}/private/borrowers?tenantId=${encodeURIComponent(tenantId)}`;
59
+ return await this.httpRequest.post(url, input);
60
+ }
61
+ };
62
+ LoanCreditBusinessApi = __decorate([
63
+ injectable(),
64
+ __param(0, inject("IHttpRequest")),
65
+ __metadata("design:paramtypes", [Object])
66
+ ], LoanCreditBusinessApi);
67
+ export default LoanCreditBusinessApi;
@@ -0,0 +1,57 @@
1
+ import { StandardResponse } from "@fiado/gateway-adapter";
2
+ import { ActivationCheckRequest, ActivationCheckResponse, LoanBorrowerResponse, LoanCreditResponse, OriginateLoanCreditRequest, OriginateLoanCreditResponse, QuoteLoanCreditRequest, QuoteLoanCreditResponse, SignLoanCreditRequest, SignLoanCreditResponse, UpsertLoanBorrowerRequest } from "@fiado/type-kit/bin/loanCredit/index.js";
3
+ /**
4
+ * Contrato del publisher de `loan-credit-business` (componente 09 SureKeep F2 — motor de crédito
5
+ * SOFOM, pista Loan). Endpoints PRIVADOS (VPC) consumidos por `retail-wizard-business` (pasos
6
+ * 05/06/08/09 del wizard) y el BO.
7
+ *
8
+ * Convenciones (idénticas a `ILoanOfferingsBusinessApi`):
9
+ * - `tenantId` OBLIGATORIO en todos los métodos — viaja por query `?tenantId=` (convención de los
10
+ * privados Fiado). Sin él el lambda responde `400 UNKNOWN_TENANT` (fail-closed, nunca default).
11
+ * - Retorna `StandardResponse<T>` → leer `result.data` (NO `result.body`).
12
+ * - Errores: el publisher RECHAZA con `DomainError` tipado del motor — `404 CREDIT_NOT_FOUND` /
13
+ * `404 BORROWER_NOT_FOUND` / `409 ACTIVE_CREDIT_EXISTS` / `409 IMEI_IN_USE` /
14
+ * `422 PLAN_INACTIVE` / `400 CHECKLIST_INCOMPLETE` / `400 OTP_INVALID` / `OTP_EXPIRED` /
15
+ * `OTP_MAX_ATTEMPTS` / `400 CREDIT_NOT_PENDING` / `400 INVALID_TRANSITION`. Nunca fallback.
16
+ *
17
+ * Env var requerida en el consumer:
18
+ *
19
+ * LOAN_CREDIT_BUSINESS_URL: '{{resolve:ssm:loan-credit-business}}'
20
+ */
21
+ export interface ILoanCreditBusinessApi {
22
+ /**
23
+ * Origina el crédito (M2 §4): valida (sin otro crédito vivo, plan activo, IMEI libre), cotiza
24
+ * contra el simulador de loan-offerings y persiste crédito `PENDING_ACTIVATION` + cuotas +
25
+ * contratos draft. IDEMPOTENTE por `input.wizardSessionId` (reintenta seguro).
26
+ */
27
+ originate(input: OriginateLoanCreditRequest, tenantId: string): Promise<StandardResponse<OriginateLoanCreditResponse>>;
28
+ /**
29
+ * Paso 06 — re-cotiza el crédito `PENDING_ACTIVATION` (nuevo plazo/enganche) y regenera su
30
+ * plan de cuotas. Rechaza si el contrato ya se firmó (términos congelados).
31
+ */
32
+ quote(creditId: string, input: QuoteLoanCreditRequest, tenantId: string): Promise<StandardResponse<QuoteLoanCreditResponse>>;
33
+ /**
34
+ * Paso 08 — firma FES en 2 tiempos (M2 §4.4): sin `otpCode` inicia (genera PDFs + envía OTP
35
+ * dedicado vía messages-business); con `otpCode` verifica y firma (sha256 + NOM-151 +
36
+ * `activationChecklist.contractSigned = true`).
37
+ */
38
+ sign(creditId: string, input: SignLoanCreditRequest, tenantId: string): Promise<StandardResponse<SignLoanCreditResponse>>;
39
+ /**
40
+ * Marca condiciones del checklist de activación (M2 §5): `downPayment` (paso 07),
41
+ * `imeiEnrolled`/`lockVerified` (paso 09, dispara el MDM vía abstracción). Con las 4 en `true`
42
+ * el crédito pasa a `ACTIVE` (vencimientos +7d, ventana de cancelación 7d).
43
+ */
44
+ activateCheck(creditId: string, input: ActivationCheckRequest, tenantId: string): Promise<StandardResponse<ActivationCheckResponse>>;
45
+ /** Estado completo del crédito (checklist, status, términos). */
46
+ getCredit(creditId: string, tenantId: string): Promise<StandardResponse<LoanCreditResponse>>;
47
+ /**
48
+ * Busca el acreditado por su FK al cliente retail (lookup del wizard/scoring).
49
+ * `404 BORROWER_NOT_FOUND` si el evento KYC aún no lo hidrató.
50
+ */
51
+ getBorrowerByRetailCustomer(retailCustomerId: string, tenantId: string): Promise<StandardResponse<LoanBorrowerResponse>>;
52
+ /**
53
+ * Upsert idempotente del acreditado por `retailCustomerId` (mismo contrato que el consumidor
54
+ * del evento `CustomerKycVerifiedV1` — fallback operativo mientras la cola no exista).
55
+ */
56
+ upsertBorrower(input: UpsertLoanBorrowerRequest, tenantId: string): Promise<StandardResponse<LoanBorrowerResponse>>;
57
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./api/interfaces/ILoanCreditBusinessApi.js";
2
+ export { default as LoanCreditBusinessApi } from "./api/LoanCreditBusinessApi.js";
@@ -0,0 +1,2 @@
1
+ export * from "./api/interfaces/ILoanCreditBusinessApi.js";
2
+ export { default as LoanCreditBusinessApi } from "./api/LoanCreditBusinessApi.js";
@@ -31,6 +31,20 @@ export interface StoreCatalogItem {
31
31
  imei: string;
32
32
  cashPriceCents: number;
33
33
  available: boolean;
34
+ /** Marca comercial (p. ej. "Apple"). */
35
+ brand: string;
36
+ /** Modelo (p. ej. "iPhone 15 Pro"). */
37
+ model: string;
38
+ /** Capacidad de almacenamiento (p. ej. "128GB"). */
39
+ capacity: string;
40
+ /** Color comercial (p. ej. "Black"). */
41
+ color: string;
42
+ /** Imagen del producto; `null` si no tiene una cargada. */
43
+ imageUrl: string | null;
44
+ /** Gama del producto (PREMIUM/HIGH/…); el consumidor decide si la usa para ordenar. */
45
+ tier: string;
46
+ /** Financieras alternativas habilitadas (derivación externa, paso 04 del wizard). */
47
+ eligibleFinanciers: string[];
34
48
  }
35
49
  /** Resultado de la reserva (espeja `ReserveInventoryResponse` del destino). */
36
50
  export interface ReserveInventoryResult {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fiado/api-invoker",
3
- "version": "4.72.0",
4
- "description": "Sirve como un puente entre diferentes funciones lambda, facilitando la comunicación entre ellas a través de invocaciones http",
3
+ "version": "4.74.0",
4
+ "description": "Sirve como un puente entre diferentes funciones lambda, facilitando la comunicaci\u00f3n entre ellas a trav\u00e9s de invocaciones http",
5
5
  "type": "module",
6
6
  "main": "bin/index.js",
7
7
  "types": "bin/index.d.ts",
@@ -34,7 +34,7 @@
34
34
  "@fiado/gateway-adapter": "^3.9.0",
35
35
  "@fiado/http-client": "^2.0.1",
36
36
  "@fiado/logger": "^1.1.3",
37
- "@fiado/type-kit": "^3.196.0",
37
+ "@fiado/type-kit": "^3.199.0",
38
38
  "dotenv": "^16.4.7"
39
39
  },
40
40
  "peerDependencies": {
package/src/index.ts CHANGED
@@ -84,6 +84,7 @@ export * from "./retailCards/index.js";
84
84
  export * from "./loanConfig/index.js";
85
85
  export * from "./loanOfferings/index.js";
86
86
  export * from "./loanCollectorAssignment/index.js";
87
+ export * from "./loanCredit/index.js";
87
88
  export * from "./messages-business/index.js";
88
89
  export * from "./totp-security/index.js";
89
90
  export * from "./equality-connector/index.js";
@@ -0,0 +1,96 @@
1
+ import { inject, injectable } from "inversify";
2
+ import type { IHttpRequest } from "@fiado/http-client";
3
+ import { StandardResponse } from "@fiado/gateway-adapter";
4
+ import {
5
+ ActivationCheckRequest,
6
+ ActivationCheckResponse,
7
+ LoanBorrowerResponse,
8
+ LoanCreditResponse,
9
+ OriginateLoanCreditRequest,
10
+ OriginateLoanCreditResponse,
11
+ QuoteLoanCreditRequest,
12
+ QuoteLoanCreditResponse,
13
+ SignLoanCreditRequest,
14
+ SignLoanCreditResponse,
15
+ UpsertLoanBorrowerRequest,
16
+ } from "@fiado/type-kit/bin/loanCredit/index.js";
17
+ import { ILoanCreditBusinessApi } from "./interfaces/ILoanCreditBusinessApi.js";
18
+
19
+ /**
20
+ * Publisher HTTP del lambda `loan-credit-business` (componente 09 SureKeep F2 — motor de crédito).
21
+ * Contrato y semántica completos → `ILoanCreditBusinessApi` (tenantId obligatorio,
22
+ * `StandardResponse` → leer `result.data`).
23
+ *
24
+ * Env var requerida en el consumer: `LOAN_CREDIT_BUSINESS_URL`.
25
+ * El template.yml del consumer la setea con:
26
+ *
27
+ * LOAN_CREDIT_BUSINESS_URL: '{{resolve:ssm:loan-credit-business}}'
28
+ *
29
+ * Convención CLAUDE.md global: SSM key = nombre del lambda owner de la URL.
30
+ */
31
+ @injectable()
32
+ export default class LoanCreditBusinessApi implements ILoanCreditBusinessApi {
33
+ // El buildspec publica la URL en SSM con "/" final — se normaliza para no armar "//private".
34
+ private readonly baseUrl = (process.env.LOAN_CREDIT_BUSINESS_URL || "").replace(/\/+$/, "");
35
+
36
+ constructor(@inject("IHttpRequest") private httpRequest: IHttpRequest) {}
37
+
38
+ async originate(
39
+ input: OriginateLoanCreditRequest,
40
+ tenantId: string,
41
+ ): Promise<StandardResponse<OriginateLoanCreditResponse>> {
42
+ const url = `${this.baseUrl}/private/credits/originate?tenantId=${encodeURIComponent(tenantId)}`;
43
+ return await this.httpRequest.post(url, input);
44
+ }
45
+
46
+ async quote(
47
+ creditId: string,
48
+ input: QuoteLoanCreditRequest,
49
+ tenantId: string,
50
+ ): Promise<StandardResponse<QuoteLoanCreditResponse>> {
51
+ const url = `${this.baseUrl}/private/credits/${encodeURIComponent(creditId)}/quote?tenantId=${encodeURIComponent(tenantId)}`;
52
+ return await this.httpRequest.post(url, input);
53
+ }
54
+
55
+ async sign(
56
+ creditId: string,
57
+ input: SignLoanCreditRequest,
58
+ tenantId: string,
59
+ ): Promise<StandardResponse<SignLoanCreditResponse>> {
60
+ const url = `${this.baseUrl}/private/credits/${encodeURIComponent(creditId)}/sign?tenantId=${encodeURIComponent(tenantId)}`;
61
+ return await this.httpRequest.post(url, input);
62
+ }
63
+
64
+ async activateCheck(
65
+ creditId: string,
66
+ input: ActivationCheckRequest,
67
+ tenantId: string,
68
+ ): Promise<StandardResponse<ActivationCheckResponse>> {
69
+ const url = `${this.baseUrl}/private/credits/${encodeURIComponent(creditId)}/activate-check?tenantId=${encodeURIComponent(tenantId)}`;
70
+ return await this.httpRequest.post(url, input);
71
+ }
72
+
73
+ async getCredit(
74
+ creditId: string,
75
+ tenantId: string,
76
+ ): Promise<StandardResponse<LoanCreditResponse>> {
77
+ const url = `${this.baseUrl}/private/credits/${encodeURIComponent(creditId)}?tenantId=${encodeURIComponent(tenantId)}`;
78
+ return await this.httpRequest.get(url);
79
+ }
80
+
81
+ async getBorrowerByRetailCustomer(
82
+ retailCustomerId: string,
83
+ tenantId: string,
84
+ ): Promise<StandardResponse<LoanBorrowerResponse>> {
85
+ const url = `${this.baseUrl}/private/borrowers/by-retail-customer/${encodeURIComponent(retailCustomerId)}?tenantId=${encodeURIComponent(tenantId)}`;
86
+ return await this.httpRequest.get(url);
87
+ }
88
+
89
+ async upsertBorrower(
90
+ input: UpsertLoanBorrowerRequest,
91
+ tenantId: string,
92
+ ): Promise<StandardResponse<LoanBorrowerResponse>> {
93
+ const url = `${this.baseUrl}/private/borrowers?tenantId=${encodeURIComponent(tenantId)}`;
94
+ return await this.httpRequest.post(url, input);
95
+ }
96
+ }
@@ -0,0 +1,100 @@
1
+ import { StandardResponse } from "@fiado/gateway-adapter";
2
+ import {
3
+ ActivationCheckRequest,
4
+ ActivationCheckResponse,
5
+ LoanBorrowerResponse,
6
+ LoanCreditResponse,
7
+ OriginateLoanCreditRequest,
8
+ OriginateLoanCreditResponse,
9
+ QuoteLoanCreditRequest,
10
+ QuoteLoanCreditResponse,
11
+ SignLoanCreditRequest,
12
+ SignLoanCreditResponse,
13
+ UpsertLoanBorrowerRequest,
14
+ } from "@fiado/type-kit/bin/loanCredit/index.js";
15
+
16
+ /**
17
+ * Contrato del publisher de `loan-credit-business` (componente 09 SureKeep F2 — motor de crédito
18
+ * SOFOM, pista Loan). Endpoints PRIVADOS (VPC) consumidos por `retail-wizard-business` (pasos
19
+ * 05/06/08/09 del wizard) y el BO.
20
+ *
21
+ * Convenciones (idénticas a `ILoanOfferingsBusinessApi`):
22
+ * - `tenantId` OBLIGATORIO en todos los métodos — viaja por query `?tenantId=` (convención de los
23
+ * privados Fiado). Sin él el lambda responde `400 UNKNOWN_TENANT` (fail-closed, nunca default).
24
+ * - Retorna `StandardResponse<T>` → leer `result.data` (NO `result.body`).
25
+ * - Errores: el publisher RECHAZA con `DomainError` tipado del motor — `404 CREDIT_NOT_FOUND` /
26
+ * `404 BORROWER_NOT_FOUND` / `409 ACTIVE_CREDIT_EXISTS` / `409 IMEI_IN_USE` /
27
+ * `422 PLAN_INACTIVE` / `400 CHECKLIST_INCOMPLETE` / `400 OTP_INVALID` / `OTP_EXPIRED` /
28
+ * `OTP_MAX_ATTEMPTS` / `400 CREDIT_NOT_PENDING` / `400 INVALID_TRANSITION`. Nunca fallback.
29
+ *
30
+ * Env var requerida en el consumer:
31
+ *
32
+ * LOAN_CREDIT_BUSINESS_URL: '{{resolve:ssm:loan-credit-business}}'
33
+ */
34
+ export interface ILoanCreditBusinessApi {
35
+ /**
36
+ * Origina el crédito (M2 §4): valida (sin otro crédito vivo, plan activo, IMEI libre), cotiza
37
+ * contra el simulador de loan-offerings y persiste crédito `PENDING_ACTIVATION` + cuotas +
38
+ * contratos draft. IDEMPOTENTE por `input.wizardSessionId` (reintenta seguro).
39
+ */
40
+ originate(
41
+ input: OriginateLoanCreditRequest,
42
+ tenantId: string,
43
+ ): Promise<StandardResponse<OriginateLoanCreditResponse>>;
44
+
45
+ /**
46
+ * Paso 06 — re-cotiza el crédito `PENDING_ACTIVATION` (nuevo plazo/enganche) y regenera su
47
+ * plan de cuotas. Rechaza si el contrato ya se firmó (términos congelados).
48
+ */
49
+ quote(
50
+ creditId: string,
51
+ input: QuoteLoanCreditRequest,
52
+ tenantId: string,
53
+ ): Promise<StandardResponse<QuoteLoanCreditResponse>>;
54
+
55
+ /**
56
+ * Paso 08 — firma FES en 2 tiempos (M2 §4.4): sin `otpCode` inicia (genera PDFs + envía OTP
57
+ * dedicado vía messages-business); con `otpCode` verifica y firma (sha256 + NOM-151 +
58
+ * `activationChecklist.contractSigned = true`).
59
+ */
60
+ sign(
61
+ creditId: string,
62
+ input: SignLoanCreditRequest,
63
+ tenantId: string,
64
+ ): Promise<StandardResponse<SignLoanCreditResponse>>;
65
+
66
+ /**
67
+ * Marca condiciones del checklist de activación (M2 §5): `downPayment` (paso 07),
68
+ * `imeiEnrolled`/`lockVerified` (paso 09, dispara el MDM vía abstracción). Con las 4 en `true`
69
+ * el crédito pasa a `ACTIVE` (vencimientos +7d, ventana de cancelación 7d).
70
+ */
71
+ activateCheck(
72
+ creditId: string,
73
+ input: ActivationCheckRequest,
74
+ tenantId: string,
75
+ ): Promise<StandardResponse<ActivationCheckResponse>>;
76
+
77
+ /** Estado completo del crédito (checklist, status, términos). */
78
+ getCredit(
79
+ creditId: string,
80
+ tenantId: string,
81
+ ): Promise<StandardResponse<LoanCreditResponse>>;
82
+
83
+ /**
84
+ * Busca el acreditado por su FK al cliente retail (lookup del wizard/scoring).
85
+ * `404 BORROWER_NOT_FOUND` si el evento KYC aún no lo hidrató.
86
+ */
87
+ getBorrowerByRetailCustomer(
88
+ retailCustomerId: string,
89
+ tenantId: string,
90
+ ): Promise<StandardResponse<LoanBorrowerResponse>>;
91
+
92
+ /**
93
+ * Upsert idempotente del acreditado por `retailCustomerId` (mismo contrato que el consumidor
94
+ * del evento `CustomerKycVerifiedV1` — fallback operativo mientras la cola no exista).
95
+ */
96
+ upsertBorrower(
97
+ input: UpsertLoanBorrowerRequest,
98
+ tenantId: string,
99
+ ): Promise<StandardResponse<LoanBorrowerResponse>>;
100
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./api/interfaces/ILoanCreditBusinessApi.js";
2
+ export { default as LoanCreditBusinessApi } from "./api/LoanCreditBusinessApi.js";
@@ -33,6 +33,23 @@ export interface StoreCatalogItem {
33
33
  imei: string;
34
34
  cashPriceCents: number;
35
35
  available: boolean;
36
+ // Atributos del producto (2026-07-21, MINOR aditivo). El consumidor real —el paso 03 del wizard—
37
+ // pinta TARJETAS DE PRODUCTO: sin marca/modelo/capacidad el catálogo es inusable en la UI. El
38
+ // destino ya cargaba el producto completo para su join anti-N+1, así que no cuesta I/O extra.
39
+ /** Marca comercial (p. ej. "Apple"). */
40
+ brand: string;
41
+ /** Modelo (p. ej. "iPhone 15 Pro"). */
42
+ model: string;
43
+ /** Capacidad de almacenamiento (p. ej. "128GB"). */
44
+ capacity: string;
45
+ /** Color comercial (p. ej. "Black"). */
46
+ color: string;
47
+ /** Imagen del producto; `null` si no tiene una cargada. */
48
+ imageUrl: string | null;
49
+ /** Gama del producto (PREMIUM/HIGH/…); el consumidor decide si la usa para ordenar. */
50
+ tier: string;
51
+ /** Financieras alternativas habilitadas (derivación externa, paso 04 del wizard). */
52
+ eligibleFinanciers: string[];
36
53
  }
37
54
 
38
55
  /** Resultado de la reserva (espeja `ReserveInventoryResponse` del destino). */