@fiado/api-invoker 4.66.0 → 4.68.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
@@ -79,6 +79,7 @@ export * from "./platformRbac/index.js";
79
79
  export * from "./retailOrg/index.js";
80
80
  export * from "./loanConfig/index.js";
81
81
  export * from "./loanOfferings/index.js";
82
+ export * from "./loanCollectorAssignment/index.js";
82
83
  export * from "./messages-business/index.js";
83
84
  export * from "./totp-security/index.js";
84
85
  export * from "./equality-connector/index.js";
package/bin/index.js CHANGED
@@ -79,6 +79,7 @@ export * from "./platformRbac/index.js";
79
79
  export * from "./retailOrg/index.js";
80
80
  export * from "./loanConfig/index.js";
81
81
  export * from "./loanOfferings/index.js";
82
+ export * from "./loanCollectorAssignment/index.js";
82
83
  export * from "./messages-business/index.js";
83
84
  export * from "./totp-security/index.js";
84
85
  export * from "./equality-connector/index.js";
@@ -0,0 +1,24 @@
1
+ import type { IHttpRequest } from "@fiado/http-client";
2
+ import { StandardResponse } from "@fiado/gateway-adapter";
3
+ import { AutoAssignRequest, CollectorAssignmentResponse } from "@fiado/type-kit/bin/loanCollectorAssignment/index.js";
4
+ import { ILoanCollectorAssignmentBusinessApi } from "./interfaces/ILoanCollectorAssignmentBusinessApi.js";
5
+ /**
6
+ * Publisher HTTP del lambda `loan-collector-assignment-business` (componente 08 SureKeep Fase 1) para
7
+ * sus 3 endpoints privados de asignación de cartera. Contrato y semántica completos →
8
+ * `ILoanCollectorAssignmentBusinessApi` (tenantId obligatorio, `StandardResponse` → leer `result.data`).
9
+ *
10
+ * Env var requerida en el consumer: `LOAN_COLLECTOR_ASSIGNMENT_BUSINESS_URL`.
11
+ * El template.yml del consumer la setea con:
12
+ *
13
+ * LOAN_COLLECTOR_ASSIGNMENT_BUSINESS_URL: '{{resolve:ssm:loan-collector-assignment-business}}'
14
+ *
15
+ * Convención CLAUDE.md global: SSM key = nombre del lambda owner de la URL.
16
+ */
17
+ export default class LoanCollectorAssignmentBusinessApi implements ILoanCollectorAssignmentBusinessApi {
18
+ private httpRequest;
19
+ private readonly baseUrl;
20
+ constructor(httpRequest: IHttpRequest);
21
+ autoAssign(input: AutoAssignRequest, tenantId: string): Promise<StandardResponse<CollectorAssignmentResponse>>;
22
+ release(creditId: string, tenantId: string): Promise<StandardResponse<CollectorAssignmentResponse>>;
23
+ getAssignmentByCredit(creditId: string, tenantId: string): Promise<StandardResponse<CollectorAssignmentResponse>>;
24
+ }
@@ -0,0 +1,51 @@
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-collector-assignment-business` (componente 08 SureKeep Fase 1) para
16
+ * sus 3 endpoints privados de asignación de cartera. Contrato y semántica completos →
17
+ * `ILoanCollectorAssignmentBusinessApi` (tenantId obligatorio, `StandardResponse` → leer `result.data`).
18
+ *
19
+ * Env var requerida en el consumer: `LOAN_COLLECTOR_ASSIGNMENT_BUSINESS_URL`.
20
+ * El template.yml del consumer la setea con:
21
+ *
22
+ * LOAN_COLLECTOR_ASSIGNMENT_BUSINESS_URL: '{{resolve:ssm:loan-collector-assignment-business}}'
23
+ *
24
+ * Convención CLAUDE.md global: SSM key = nombre del lambda owner de la URL.
25
+ */
26
+ let LoanCollectorAssignmentBusinessApi = class LoanCollectorAssignmentBusinessApi {
27
+ httpRequest;
28
+ // El buildspec publica la URL en SSM con "/" final — se normaliza para no armar "//private".
29
+ baseUrl = (process.env.LOAN_COLLECTOR_ASSIGNMENT_BUSINESS_URL || "").replace(/\/+$/, "");
30
+ constructor(httpRequest) {
31
+ this.httpRequest = httpRequest;
32
+ }
33
+ async autoAssign(input, tenantId) {
34
+ const url = `${this.baseUrl}/private/collector-assignments/auto-assign?tenantId=${encodeURIComponent(tenantId)}`;
35
+ return await this.httpRequest.post(url, input);
36
+ }
37
+ async release(creditId, tenantId) {
38
+ const url = `${this.baseUrl}/private/collector-assignments/${encodeURIComponent(creditId)}/release?tenantId=${encodeURIComponent(tenantId)}`;
39
+ return await this.httpRequest.put(url);
40
+ }
41
+ async getAssignmentByCredit(creditId, tenantId) {
42
+ const url = `${this.baseUrl}/private/collector-assignments/by-credit/${encodeURIComponent(creditId)}?tenantId=${encodeURIComponent(tenantId)}`;
43
+ return await this.httpRequest.get(url);
44
+ }
45
+ };
46
+ LoanCollectorAssignmentBusinessApi = __decorate([
47
+ injectable(),
48
+ __param(0, inject("IHttpRequest")),
49
+ __metadata("design:paramtypes", [Object])
50
+ ], LoanCollectorAssignmentBusinessApi);
51
+ export default LoanCollectorAssignmentBusinessApi;
@@ -0,0 +1,63 @@
1
+ import { StandardResponse } from "@fiado/gateway-adapter";
2
+ import { AutoAssignRequest, CollectorAssignmentResponse } from "@fiado/type-kit/bin/loanCollectorAssignment/index.js";
3
+ /**
4
+ * Contrato del publisher HTTP del lambda `loan-collector-assignment-business` (componente 08 SureKeep
5
+ * Fase 1) para sus 3 endpoints privados de asignación de cartera de cobranza (service-to-service,
6
+ * VPC-only). Este lambda decide qué cobrador gestiona qué crédito.
7
+ *
8
+ * Consumidor previsto:
9
+ * - motor de crédito (F3) → auto-asigna cobrador al crearse el crédito · libera al liquidarlo ·
10
+ * consulta quién gestiona un crédito.
11
+ *
12
+ * ─────────────────────────────────────────────────────────────────────────────
13
+ * `tenantId` es OBLIGATORIO en los 3 métodos — no es un detalle de firma.
14
+ * ─────────────────────────────────────────────────────────────────────────────
15
+ * Los privados NO llevan token de usuario (`Feature.ANONIMUS`; la protección es la red VPC), así que
16
+ * el lambda destino no tiene `AuthContext.issuer` y NO puede inferir el silo. El caller declara el
17
+ * tenant explícito por query y `@fiado/tenant-context` asume el rol de ESE silo. Sin `tenantId` →
18
+ * `400 UNKNOWN_TENANT` (fail-closed). Nunca hay default: caer a un tenant por default sería fail-OPEN
19
+ * y podría tocar el silo de otra SOFOM (auto-assign y release ESCRIBEN).
20
+ *
21
+ * ─────────────────────────────────────────────────────────────────────────────
22
+ * ⚠️ Patrón de retorno: `StandardResponse<T>` — el consumer accede `result.data`, NO `result.body`.
23
+ * ─────────────────────────────────────────────────────────────────────────────
24
+ *
25
+ * Errores: el lambda destino lanza `DomainError` tipado → el publisher RECHAZA (no devuelve null).
26
+ * Cada consumer mapea a su propio error de dominio (ver `fiado-api-invoker § 6`):
27
+ * `412 NO_ACTIVE_RULE` (el retailer no tiene regla de asignación activa)
28
+ * `503 NO_COLLECTORS_AVAILABLE` (no hay cobradores elegibles para asignar)
29
+ * `404 ASSIGNMENT_NOT_FOUND` (el crédito no tiene asignación — release / consulta)
30
+ * `400 UNKNOWN_TENANT` (tenantId ausente o desconocido)
31
+ *
32
+ * Env var requerida en el consumer: `LOAN_COLLECTOR_ASSIGNMENT_BUSINESS_URL`.
33
+ * El template.yml del consumer la setea con:
34
+ *
35
+ * LOAN_COLLECTOR_ASSIGNMENT_BUSINESS_URL: '{{resolve:ssm:loan-collector-assignment-business}}'
36
+ *
37
+ * Convención CLAUDE.md global: SSM key = nombre del lambda owner de la URL.
38
+ */
39
+ export interface ILoanCollectorAssignmentBusinessApi {
40
+ /**
41
+ * POST /private/collector-assignments/auto-assign — asigna un cobrador al crédito recién creado
42
+ * (regla activa → cobradores elegibles → ranking) y devuelve la asignación ACTIVE. Idempotente:
43
+ * si el crédito ya tiene cobrador activo devuelve el existente.
44
+ *
45
+ * @throws `412 NO_ACTIVE_RULE` si el retailer no tiene regla activa; `503 NO_COLLECTORS_AVAILABLE`
46
+ * si no hay cobradores elegibles.
47
+ */
48
+ autoAssign(input: AutoAssignRequest, tenantId: string): Promise<StandardResponse<CollectorAssignmentResponse>>;
49
+ /**
50
+ * PUT /private/collector-assignments/{creditId}/release — libera la asignación al liquidarse el
51
+ * crédito (la marca INACTIVE). Idempotente: sobre una asignación ya liberada devuelve sin re-emitir.
52
+ *
53
+ * @throws `404 ASSIGNMENT_NOT_FOUND` si el crédito no tiene asignación.
54
+ */
55
+ release(creditId: string, tenantId: string): Promise<StandardResponse<CollectorAssignmentResponse>>;
56
+ /**
57
+ * GET /private/collector-assignments/by-credit/{creditId} — devuelve la asignación (cobrador
58
+ * actual + estado) de un crédito.
59
+ *
60
+ * @throws `404 ASSIGNMENT_NOT_FOUND` si el crédito no tiene asignación.
61
+ */
62
+ getAssignmentByCredit(creditId: string, tenantId: string): Promise<StandardResponse<CollectorAssignmentResponse>>;
63
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./api/interfaces/ILoanCollectorAssignmentBusinessApi.js";
2
+ export { default as LoanCollectorAssignmentBusinessApi } from "./api/LoanCollectorAssignmentBusinessApi.js";
@@ -0,0 +1,2 @@
1
+ export * from "./api/interfaces/ILoanCollectorAssignmentBusinessApi.js";
2
+ export { default as LoanCollectorAssignmentBusinessApi } from "./api/LoanCollectorAssignmentBusinessApi.js";
@@ -1,6 +1,6 @@
1
1
  import type { IHttpRequest } from "@fiado/http-client";
2
2
  import { ApiGatewayResponse, ResolvedPermissions, ResolveInput } from "@fiado/gateway-adapter";
3
- import { DefineNextChallengeRequest, DefineNextChallengeResponse, PrepareChallengeRequest, PrepareChallengeResponse, VerifyChallengeRequest, VerifyChallengeResponse, AuthorizeRequest, AuthorizeResponse, EffectivePermissionsResponse, InjectableUserAttributesResponse } from "@fiado/type-kit/bin/platformRbac/index.js";
3
+ import { DefineNextChallengeRequest, DefineNextChallengeResponse, PrepareChallengeRequest, PrepareChallengeResponse, VerifyChallengeRequest, VerifyChallengeResponse, AuthorizeRequest, AuthorizeResponse, EffectivePermissionsResponse, InjectableUserAttributesResponse, PermissionScope, CreateLevelEntityRequest, CreateLevelEntityResponse, CreateTenantUserRequest, CreateTenantUserResponse } from "@fiado/type-kit/bin/platformRbac/index.js";
4
4
  import { IPlatformRbacBusinessApi } from "./interfaces/IPlatformRbacBusinessApi.js";
5
5
  /**
6
6
  * Publisher HTTP del lambda `platform-rbac-business` (componente 06 SureKeep Fase 0)
@@ -26,4 +26,6 @@ export default class PlatformRbacBusinessApi implements IPlatformRbacBusinessApi
26
26
  effectivePermissions(cognitoSub: string, tenantId?: string): Promise<ApiGatewayResponse<EffectivePermissionsResponse>>;
27
27
  getInjectableUserAttributes(cognitoSub: string, tenantId: string): Promise<ApiGatewayResponse<InjectableUserAttributesResponse>>;
28
28
  resolvePermissions(input: ResolveInput): Promise<ApiGatewayResponse<ResolvedPermissions>>;
29
+ createLevelEntity(tenantId: string, level: PermissionScope, input: CreateLevelEntityRequest): Promise<ApiGatewayResponse<CreateLevelEntityResponse>>;
30
+ createTenantUser(tenantId: string, input: CreateTenantUserRequest): Promise<ApiGatewayResponse<CreateTenantUserResponse>>;
29
31
  }
@@ -68,6 +68,14 @@ let PlatformRbacBusinessApi = class PlatformRbacBusinessApi {
68
68
  const url = `${this.baseUrl}/internal/permissions/resolve`;
69
69
  return await this.httpRequest.post(url, input);
70
70
  }
71
+ async createLevelEntity(tenantId, level, input) {
72
+ const url = `${this.baseUrl}/internal/tenants/${encodeURIComponent(tenantId)}/levels/${encodeURIComponent(level)}/entities`;
73
+ return await this.httpRequest.post(url, input);
74
+ }
75
+ async createTenantUser(tenantId, input) {
76
+ const url = `${this.baseUrl}/internal/tenants/${encodeURIComponent(tenantId)}/users`;
77
+ return await this.httpRequest.post(url, input);
78
+ }
71
79
  };
72
80
  PlatformRbacBusinessApi = __decorate([
73
81
  injectable(),
@@ -1,5 +1,5 @@
1
1
  import { ApiGatewayResponse, ResolvedPermissions, ResolveInput } from "@fiado/gateway-adapter";
2
- import { DefineNextChallengeRequest, DefineNextChallengeResponse, PrepareChallengeRequest, PrepareChallengeResponse, VerifyChallengeRequest, VerifyChallengeResponse, AuthorizeRequest, AuthorizeResponse, EffectivePermissionsResponse, InjectableUserAttributesResponse } from "@fiado/type-kit/bin/platformRbac/index.js";
2
+ import { DefineNextChallengeRequest, DefineNextChallengeResponse, PrepareChallengeRequest, PrepareChallengeResponse, VerifyChallengeRequest, VerifyChallengeResponse, AuthorizeRequest, AuthorizeResponse, EffectivePermissionsResponse, InjectableUserAttributesResponse, PermissionScope, CreateLevelEntityRequest, CreateLevelEntityResponse, CreateTenantUserRequest, CreateTenantUserResponse } from "@fiado/type-kit/bin/platformRbac/index.js";
3
3
  /**
4
4
  * Contrato del publisher HTTP del lambda `platform-rbac-business` (componente 06 SureKeep Fase 0)
5
5
  * para los 3 endpoints internos del Custom Auth Challenge flow (MFA).
@@ -63,4 +63,16 @@ export interface IPlatformRbacBusinessApi {
63
63
  getInjectableUserAttributes(cognitoSub: string, tenantId: string): Promise<ApiGatewayResponse<InjectableUserAttributesResponse>>;
64
64
  /** POST /internal/permissions/resolve — resuelve permisos scope-bound (set completo, paginación interna) para el RBAC enforcement del gateway-adapter. DEC-RBAC-064. */
65
65
  resolvePermissions(input: ResolveInput): Promise<ApiGatewayResponse<ResolvedPermissions>>;
66
+ /**
67
+ * POST /internal/tenants/{tenantId}/levels/{level}/entities — crea una scope-entity genérica
68
+ * L1/L2/L3 en RBAC (endpoint privado, VPC/ANONIMUS). Espejo de jerarquía de SureKeep F1
69
+ * (retailer→L1, zona→L2, tienda→L3). BYOID + idempotente. `level` (LEVEL_1|2|3) va en el path.
70
+ */
71
+ createLevelEntity(tenantId: string, level: PermissionScope, input: CreateLevelEntityRequest): Promise<ApiGatewayResponse<CreateLevelEntityResponse>>;
72
+ /**
73
+ * POST /internal/tenants/{tenantId}/users — provisiona un usuario del tenant (Cognito + SharedUser +
74
+ * RoleAssignment) en RBAC (endpoint privado, VPC/ANONIMUS). Alta orquestada de SureKeep F1: el usuario
75
+ * queda INVITED (mitiga orphan) y retail-org guarda el `cognitoSub` retornado. Idempotente por identidad Cognito.
76
+ */
77
+ createTenantUser(tenantId: string, input: CreateTenantUserRequest): Promise<ApiGatewayResponse<CreateTenantUserResponse>>;
66
78
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/api-invoker",
3
- "version": "4.66.0",
3
+ "version": "4.68.0",
4
4
  "description": "Sirve como un puente entre diferentes funciones lambda, facilitando la comunicación entre ellas a través de invocaciones http",
5
5
  "type": "module",
6
6
  "main": "bin/index.js",
@@ -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.191.0",
37
+ "@fiado/type-kit": "^3.193.0",
38
38
  "dotenv": "^16.4.7"
39
39
  },
40
40
  "peerDependencies": {
package/src/index.ts CHANGED
@@ -79,6 +79,7 @@ export * from "./platformRbac/index.js";
79
79
  export * from "./retailOrg/index.js";
80
80
  export * from "./loanConfig/index.js";
81
81
  export * from "./loanOfferings/index.js";
82
+ export * from "./loanCollectorAssignment/index.js";
82
83
  export * from "./messages-business/index.js";
83
84
  export * from "./totp-security/index.js";
84
85
  export * from "./equality-connector/index.js";
@@ -0,0 +1,52 @@
1
+ import { inject, injectable } from "inversify";
2
+ import type { IHttpRequest } from "@fiado/http-client";
3
+ import { StandardResponse } from "@fiado/gateway-adapter";
4
+ import {
5
+ AutoAssignRequest,
6
+ CollectorAssignmentResponse,
7
+ } from "@fiado/type-kit/bin/loanCollectorAssignment/index.js";
8
+ import { ILoanCollectorAssignmentBusinessApi } from "./interfaces/ILoanCollectorAssignmentBusinessApi.js";
9
+
10
+ /**
11
+ * Publisher HTTP del lambda `loan-collector-assignment-business` (componente 08 SureKeep Fase 1) para
12
+ * sus 3 endpoints privados de asignación de cartera. Contrato y semántica completos →
13
+ * `ILoanCollectorAssignmentBusinessApi` (tenantId obligatorio, `StandardResponse` → leer `result.data`).
14
+ *
15
+ * Env var requerida en el consumer: `LOAN_COLLECTOR_ASSIGNMENT_BUSINESS_URL`.
16
+ * El template.yml del consumer la setea con:
17
+ *
18
+ * LOAN_COLLECTOR_ASSIGNMENT_BUSINESS_URL: '{{resolve:ssm:loan-collector-assignment-business}}'
19
+ *
20
+ * Convención CLAUDE.md global: SSM key = nombre del lambda owner de la URL.
21
+ */
22
+ @injectable()
23
+ export default class LoanCollectorAssignmentBusinessApi implements ILoanCollectorAssignmentBusinessApi {
24
+ // El buildspec publica la URL en SSM con "/" final — se normaliza para no armar "//private".
25
+ private readonly baseUrl = (process.env.LOAN_COLLECTOR_ASSIGNMENT_BUSINESS_URL || "").replace(/\/+$/, "");
26
+
27
+ constructor(@inject("IHttpRequest") private httpRequest: IHttpRequest) {}
28
+
29
+ async autoAssign(
30
+ input: AutoAssignRequest,
31
+ tenantId: string,
32
+ ): Promise<StandardResponse<CollectorAssignmentResponse>> {
33
+ const url = `${this.baseUrl}/private/collector-assignments/auto-assign?tenantId=${encodeURIComponent(tenantId)}`;
34
+ return await this.httpRequest.post(url, input);
35
+ }
36
+
37
+ async release(
38
+ creditId: string,
39
+ tenantId: string,
40
+ ): Promise<StandardResponse<CollectorAssignmentResponse>> {
41
+ const url = `${this.baseUrl}/private/collector-assignments/${encodeURIComponent(creditId)}/release?tenantId=${encodeURIComponent(tenantId)}`;
42
+ return await this.httpRequest.put(url);
43
+ }
44
+
45
+ async getAssignmentByCredit(
46
+ creditId: string,
47
+ tenantId: string,
48
+ ): Promise<StandardResponse<CollectorAssignmentResponse>> {
49
+ const url = `${this.baseUrl}/private/collector-assignments/by-credit/${encodeURIComponent(creditId)}?tenantId=${encodeURIComponent(tenantId)}`;
50
+ return await this.httpRequest.get(url);
51
+ }
52
+ }
@@ -0,0 +1,78 @@
1
+ import { StandardResponse } from "@fiado/gateway-adapter";
2
+ import {
3
+ AutoAssignRequest,
4
+ CollectorAssignmentResponse,
5
+ } from "@fiado/type-kit/bin/loanCollectorAssignment/index.js";
6
+
7
+ /**
8
+ * Contrato del publisher HTTP del lambda `loan-collector-assignment-business` (componente 08 SureKeep
9
+ * Fase 1) para sus 3 endpoints privados de asignación de cartera de cobranza (service-to-service,
10
+ * VPC-only). Este lambda decide qué cobrador gestiona qué crédito.
11
+ *
12
+ * Consumidor previsto:
13
+ * - motor de crédito (F3) → auto-asigna cobrador al crearse el crédito · libera al liquidarlo ·
14
+ * consulta quién gestiona un crédito.
15
+ *
16
+ * ─────────────────────────────────────────────────────────────────────────────
17
+ * `tenantId` es OBLIGATORIO en los 3 métodos — no es un detalle de firma.
18
+ * ─────────────────────────────────────────────────────────────────────────────
19
+ * Los privados NO llevan token de usuario (`Feature.ANONIMUS`; la protección es la red VPC), así que
20
+ * el lambda destino no tiene `AuthContext.issuer` y NO puede inferir el silo. El caller declara el
21
+ * tenant explícito por query y `@fiado/tenant-context` asume el rol de ESE silo. Sin `tenantId` →
22
+ * `400 UNKNOWN_TENANT` (fail-closed). Nunca hay default: caer a un tenant por default sería fail-OPEN
23
+ * y podría tocar el silo de otra SOFOM (auto-assign y release ESCRIBEN).
24
+ *
25
+ * ─────────────────────────────────────────────────────────────────────────────
26
+ * ⚠️ Patrón de retorno: `StandardResponse<T>` — el consumer accede `result.data`, NO `result.body`.
27
+ * ─────────────────────────────────────────────────────────────────────────────
28
+ *
29
+ * Errores: el lambda destino lanza `DomainError` tipado → el publisher RECHAZA (no devuelve null).
30
+ * Cada consumer mapea a su propio error de dominio (ver `fiado-api-invoker § 6`):
31
+ * `412 NO_ACTIVE_RULE` (el retailer no tiene regla de asignación activa)
32
+ * `503 NO_COLLECTORS_AVAILABLE` (no hay cobradores elegibles para asignar)
33
+ * `404 ASSIGNMENT_NOT_FOUND` (el crédito no tiene asignación — release / consulta)
34
+ * `400 UNKNOWN_TENANT` (tenantId ausente o desconocido)
35
+ *
36
+ * Env var requerida en el consumer: `LOAN_COLLECTOR_ASSIGNMENT_BUSINESS_URL`.
37
+ * El template.yml del consumer la setea con:
38
+ *
39
+ * LOAN_COLLECTOR_ASSIGNMENT_BUSINESS_URL: '{{resolve:ssm:loan-collector-assignment-business}}'
40
+ *
41
+ * Convención CLAUDE.md global: SSM key = nombre del lambda owner de la URL.
42
+ */
43
+ export interface ILoanCollectorAssignmentBusinessApi {
44
+ /**
45
+ * POST /private/collector-assignments/auto-assign — asigna un cobrador al crédito recién creado
46
+ * (regla activa → cobradores elegibles → ranking) y devuelve la asignación ACTIVE. Idempotente:
47
+ * si el crédito ya tiene cobrador activo devuelve el existente.
48
+ *
49
+ * @throws `412 NO_ACTIVE_RULE` si el retailer no tiene regla activa; `503 NO_COLLECTORS_AVAILABLE`
50
+ * si no hay cobradores elegibles.
51
+ */
52
+ autoAssign(
53
+ input: AutoAssignRequest,
54
+ tenantId: string,
55
+ ): Promise<StandardResponse<CollectorAssignmentResponse>>;
56
+
57
+ /**
58
+ * PUT /private/collector-assignments/{creditId}/release — libera la asignación al liquidarse el
59
+ * crédito (la marca INACTIVE). Idempotente: sobre una asignación ya liberada devuelve sin re-emitir.
60
+ *
61
+ * @throws `404 ASSIGNMENT_NOT_FOUND` si el crédito no tiene asignación.
62
+ */
63
+ release(
64
+ creditId: string,
65
+ tenantId: string,
66
+ ): Promise<StandardResponse<CollectorAssignmentResponse>>;
67
+
68
+ /**
69
+ * GET /private/collector-assignments/by-credit/{creditId} — devuelve la asignación (cobrador
70
+ * actual + estado) de un crédito.
71
+ *
72
+ * @throws `404 ASSIGNMENT_NOT_FOUND` si el crédito no tiene asignación.
73
+ */
74
+ getAssignmentByCredit(
75
+ creditId: string,
76
+ tenantId: string,
77
+ ): Promise<StandardResponse<CollectorAssignmentResponse>>;
78
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./api/interfaces/ILoanCollectorAssignmentBusinessApi.js";
2
+ export { default as LoanCollectorAssignmentBusinessApi } from "./api/LoanCollectorAssignmentBusinessApi.js";
@@ -13,6 +13,11 @@ import {
13
13
  AuthorizeResponse,
14
14
  EffectivePermissionsResponse,
15
15
  InjectableUserAttributesResponse,
16
+ PermissionScope,
17
+ CreateLevelEntityRequest,
18
+ CreateLevelEntityResponse,
19
+ CreateTenantUserRequest,
20
+ CreateTenantUserResponse,
16
21
  } from "@fiado/type-kit/bin/platformRbac/index.js";
17
22
  import { IPlatformRbacBusinessApi } from "./interfaces/IPlatformRbacBusinessApi.js";
18
23
 
@@ -95,4 +100,21 @@ export default class PlatformRbacBusinessApi implements IPlatformRbacBusinessApi
95
100
  const url = `${this.baseUrl}/internal/permissions/resolve`;
96
101
  return await this.httpRequest.post(url, input);
97
102
  }
103
+
104
+ async createLevelEntity(
105
+ tenantId: string,
106
+ level: PermissionScope,
107
+ input: CreateLevelEntityRequest,
108
+ ): Promise<ApiGatewayResponse<CreateLevelEntityResponse>> {
109
+ const url = `${this.baseUrl}/internal/tenants/${encodeURIComponent(tenantId)}/levels/${encodeURIComponent(level)}/entities`;
110
+ return await this.httpRequest.post(url, input);
111
+ }
112
+
113
+ async createTenantUser(
114
+ tenantId: string,
115
+ input: CreateTenantUserRequest,
116
+ ): Promise<ApiGatewayResponse<CreateTenantUserResponse>> {
117
+ const url = `${this.baseUrl}/internal/tenants/${encodeURIComponent(tenantId)}/users`;
118
+ return await this.httpRequest.post(url, input);
119
+ }
98
120
  }
@@ -10,6 +10,11 @@ import {
10
10
  AuthorizeResponse,
11
11
  EffectivePermissionsResponse,
12
12
  InjectableUserAttributesResponse,
13
+ PermissionScope,
14
+ CreateLevelEntityRequest,
15
+ CreateLevelEntityResponse,
16
+ CreateTenantUserRequest,
17
+ CreateTenantUserResponse,
13
18
  } from "@fiado/type-kit/bin/platformRbac/index.js";
14
19
 
15
20
  /**
@@ -95,4 +100,25 @@ export interface IPlatformRbacBusinessApi {
95
100
 
96
101
  /** POST /internal/permissions/resolve — resuelve permisos scope-bound (set completo, paginación interna) para el RBAC enforcement del gateway-adapter. DEC-RBAC-064. */
97
102
  resolvePermissions(input: ResolveInput): Promise<ApiGatewayResponse<ResolvedPermissions>>;
103
+
104
+ /**
105
+ * POST /internal/tenants/{tenantId}/levels/{level}/entities — crea una scope-entity genérica
106
+ * L1/L2/L3 en RBAC (endpoint privado, VPC/ANONIMUS). Espejo de jerarquía de SureKeep F1
107
+ * (retailer→L1, zona→L2, tienda→L3). BYOID + idempotente. `level` (LEVEL_1|2|3) va en el path.
108
+ */
109
+ createLevelEntity(
110
+ tenantId: string,
111
+ level: PermissionScope,
112
+ input: CreateLevelEntityRequest,
113
+ ): Promise<ApiGatewayResponse<CreateLevelEntityResponse>>;
114
+
115
+ /**
116
+ * POST /internal/tenants/{tenantId}/users — provisiona un usuario del tenant (Cognito + SharedUser +
117
+ * RoleAssignment) en RBAC (endpoint privado, VPC/ANONIMUS). Alta orquestada de SureKeep F1: el usuario
118
+ * queda INVITED (mitiga orphan) y retail-org guarda el `cognitoSub` retornado. Idempotente por identidad Cognito.
119
+ */
120
+ createTenantUser(
121
+ tenantId: string,
122
+ input: CreateTenantUserRequest,
123
+ ): Promise<ApiGatewayResponse<CreateTenantUserResponse>>;
98
124
  }