@fiado/type-kit 3.449.0 → 3.451.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 (28) hide show
  1. package/_test_/unit/productCatalog/dtos/CreateProductCatalogRequest.test.ts +37 -0
  2. package/_test_/unit/productCatalog/dtos/GetProductCatalogResponse.test.ts +39 -0
  3. package/_test_/unit/productCatalog/enums/ProductTaxFeeTypeEnum.test.ts +13 -0
  4. package/bin/productCatalog/dtos/CreateProductCatalogRequest.d.ts +1 -0
  5. package/bin/productCatalog/dtos/CreateProductCatalogRequest.js +15 -0
  6. package/bin/productCatalog/dtos/GetProductCatalogResponse.d.ts +1 -0
  7. package/bin/productCatalog/dtos/GetProductCatalogResponse.js +5 -0
  8. package/bin/productCatalog/enums/ProductTaxFeeTypeEnum.d.ts +2 -1
  9. package/bin/productCatalog/enums/ProductTaxFeeTypeEnum.js +1 -0
  10. package/bin/remittance/dtos/RemittanceBackofficeTransaction.d.ts +27 -0
  11. package/bin/remittance/dtos/RemittanceBackofficeTransaction.js +6 -0
  12. package/bin/remittance/dtos/RemittanceReconciliation.d.ts +61 -0
  13. package/bin/remittance/dtos/RemittanceReconciliation.js +2 -0
  14. package/bin/remittance/dtos/index.d.ts +1 -0
  15. package/bin/remittance/dtos/index.js +1 -0
  16. package/bin/remittance/enums/RemittanceReconStatus.d.ts +15 -0
  17. package/bin/remittance/enums/RemittanceReconStatus.js +19 -0
  18. package/bin/remittance/enums/index.d.ts +1 -0
  19. package/bin/remittance/enums/index.js +1 -0
  20. package/package.json +1 -1
  21. package/src/productCatalog/dtos/CreateProductCatalogRequest.ts +5 -0
  22. package/src/productCatalog/dtos/GetProductCatalogResponse.ts +5 -1
  23. package/src/productCatalog/enums/ProductTaxFeeTypeEnum.ts +2 -1
  24. package/src/remittance/dtos/RemittanceBackofficeTransaction.ts +33 -0
  25. package/src/remittance/dtos/RemittanceReconciliation.ts +71 -0
  26. package/src/remittance/dtos/index.ts +1 -0
  27. package/src/remittance/enums/RemittanceReconStatus.ts +15 -0
  28. package/src/remittance/enums/index.ts +1 -0
@@ -0,0 +1,37 @@
1
+ import 'reflect-metadata';
2
+ import { validate } from "class-validator";
3
+ import { plainToInstance } from "class-transformer";
4
+ import { CreateProductCatalogRequest } from "../../../../src/productCatalog/dtos/CreateProductCatalogRequest";
5
+
6
+ describe("CreateProductCatalogRequest — campo minFee", () => {
7
+ const base = {
8
+ id: "SP_CASH_IN",
9
+ description: "Comisión fondeo en efectivo",
10
+ displayName: "Comisión fondeo en efectivo",
11
+ type: "SP_CASH_IN",
12
+ currencyId: "484",
13
+ feeType: "PERCENT_WITH_MIN",
14
+ fee: 3.5,
15
+ taxType: "PERCENT",
16
+ tax: 16,
17
+ };
18
+
19
+ it("acepta minFee numérico >= 0", async () => {
20
+ const dto = plainToInstance(CreateProductCatalogRequest, { ...base, minFee: 10 });
21
+ const errors = await validate(dto);
22
+ expect(errors).toEqual([]);
23
+ });
24
+
25
+ it("acepta minFee ausente (opcional, retro-compat)", async () => {
26
+ const dto = plainToInstance(CreateProductCatalogRequest, base);
27
+ const errors = await validate(dto);
28
+ expect(errors).toEqual([]);
29
+ });
30
+
31
+ it("rechaza minFee no numérico", async () => {
32
+ const dto = plainToInstance(CreateProductCatalogRequest, { ...base, minFee: "diez" });
33
+ const errors = await validate(dto);
34
+ expect(errors.length).toBeGreaterThan(0);
35
+ expect(errors[0].property).toBe("minFee");
36
+ });
37
+ });
@@ -0,0 +1,39 @@
1
+ import 'reflect-metadata';
2
+ import { validate } from "class-validator";
3
+ import { plainToInstance } from "class-transformer";
4
+ import GetProductCatalogResponse from "../../../../src/productCatalog/dtos/GetProductCatalogResponse";
5
+
6
+ describe("GetProductCatalogResponse — campo minFee", () => {
7
+ const base = {
8
+ id: "SP_CASH_IN",
9
+ description: "Comisión fondeo en efectivo",
10
+ displayName: "Comisión fondeo en efectivo",
11
+ type: "SP_CASH_IN",
12
+ currencyId: "484",
13
+ feeType: "PERCENT_WITH_MIN",
14
+ fee: 3.5,
15
+ taxType: "PERCENT",
16
+ tax: 16,
17
+ createdAt: "2026-01-01T00:00:00Z",
18
+ updatedAt: "2026-09-19T00:00:00Z",
19
+ };
20
+
21
+ it("acepta minFee numérico >= 0", async () => {
22
+ const dto = plainToInstance(GetProductCatalogResponse, { ...base, minFee: 10 });
23
+ const errors = await validate(dto);
24
+ expect(errors).toEqual([]);
25
+ });
26
+
27
+ it("acepta minFee ausente (opcional, retro-compat)", async () => {
28
+ const dto = plainToInstance(GetProductCatalogResponse, base);
29
+ const errors = await validate(dto);
30
+ expect(errors).toEqual([]);
31
+ });
32
+
33
+ it("rechaza minFee no numérico", async () => {
34
+ const dto = plainToInstance(GetProductCatalogResponse, { ...base, minFee: "diez" });
35
+ const errors = await validate(dto);
36
+ expect(errors.length).toBeGreaterThan(0);
37
+ expect(errors[0].property).toBe("minFee");
38
+ });
39
+ });
@@ -0,0 +1,13 @@
1
+ import 'reflect-metadata';
2
+ import { ProductTaxFeeTypeEnum } from "../../../../src/productCatalog/enums/ProductTaxFeeTypeEnum";
3
+
4
+ describe("ProductTaxFeeTypeEnum", () => {
5
+ it("incluye PERCENT_WITH_MIN para tarifas con piso", () => {
6
+ expect(ProductTaxFeeTypeEnum.PERCENT_WITH_MIN).toBe("PERCENT_WITH_MIN");
7
+ });
8
+
9
+ it("preserva valores existentes PERCENT y FIXED", () => {
10
+ expect(ProductTaxFeeTypeEnum.PERCENT).toBe("PERCENT");
11
+ expect(ProductTaxFeeTypeEnum.FIXED).toBe("FIXED");
12
+ });
13
+ });
@@ -11,4 +11,5 @@ export declare class CreateProductCatalogRequest {
11
11
  fee: number;
12
12
  taxType: ProductTaxFeeTypeEnum;
13
13
  tax: number;
14
+ minFee?: number;
14
15
  }
@@ -1,6 +1,21 @@
1
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
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.CreateProductCatalogRequest = void 0;
13
+ const class_validator_1 = require("class-validator");
4
14
  class CreateProductCatalogRequest {
5
15
  }
6
16
  exports.CreateProductCatalogRequest = CreateProductCatalogRequest;
17
+ __decorate([
18
+ (0, class_validator_1.IsOptional)(),
19
+ (0, class_validator_1.IsNumber)(),
20
+ __metadata("design:type", Number)
21
+ ], CreateProductCatalogRequest.prototype, "minFee", void 0);
@@ -11,6 +11,7 @@ export default class GetProductCatalogResponse {
11
11
  fee: number;
12
12
  taxType: ProductTaxFeeTypeEnum;
13
13
  tax: number;
14
+ minFee?: number;
14
15
  createdAt: string;
15
16
  updatedAt: string;
16
17
  }
@@ -52,6 +52,11 @@ __decorate([
52
52
  (0, class_validator_1.IsNumber)(),
53
53
  __metadata("design:type", Number)
54
54
  ], GetProductCatalogResponse.prototype, "tax", void 0);
55
+ __decorate([
56
+ (0, class_validator_1.IsOptional)(),
57
+ (0, class_validator_1.IsNumber)(),
58
+ __metadata("design:type", Number)
59
+ ], GetProductCatalogResponse.prototype, "minFee", void 0);
55
60
  __decorate([
56
61
  (0, class_validator_1.IsString)(),
57
62
  __metadata("design:type", String)
@@ -1,4 +1,5 @@
1
1
  export declare enum ProductTaxFeeTypeEnum {
2
2
  PERCENT = "PERCENT",
3
- FIXED = "FIXED"
3
+ FIXED = "FIXED",
4
+ PERCENT_WITH_MIN = "PERCENT_WITH_MIN"
4
5
  }
@@ -5,4 +5,5 @@ var ProductTaxFeeTypeEnum;
5
5
  (function (ProductTaxFeeTypeEnum) {
6
6
  ProductTaxFeeTypeEnum["PERCENT"] = "PERCENT";
7
7
  ProductTaxFeeTypeEnum["FIXED"] = "FIXED";
8
+ ProductTaxFeeTypeEnum["PERCENT_WITH_MIN"] = "PERCENT_WITH_MIN";
8
9
  })(ProductTaxFeeTypeEnum || (exports.ProductTaxFeeTypeEnum = ProductTaxFeeTypeEnum = {}));
@@ -1,10 +1,17 @@
1
1
  import { RemittanceTxStatus } from "../enums/RemittanceTxStatus";
2
2
  import { RemittanceCancelStageEnum } from "../enums/RemittanceCancelStageEnum";
3
3
  import { RemittanceCancelOutcomeEnum } from "../enums/RemittanceCancelOutcomeEnum";
4
+ import { RemittanceReconStatus } from "../enums/RemittanceReconStatus";
4
5
  /**
5
6
  * Vista operativa COMPLETA de una tx para el backoffice (F9): incluye campos
6
7
  * de trazabilidad (previewRef, idempotencyKey, marketplaceTransactionNumber
7
8
  * para correlación con el procesador) que el DTO de usuario no expone.
9
+ *
10
+ * A partir de Fase B de Uniteller también incluye los campos de enrichment
11
+ * poblados por el pipeline SUTWEB38 (unitellerCostTicket, netMarginUsd,
12
+ * reconStatus, etc.) — todos opcionales, filas creadas antes de la
13
+ * implementación no los tienen. Ver `RemittanceReconciliationFields` para
14
+ * el shape canónico.
8
15
  */
9
16
  export declare class RemittanceBackofficeTransaction {
10
17
  directoryId: string;
@@ -68,4 +75,24 @@ export declare class RemittanceBackofficeTransaction {
68
75
  updatedAt: string;
69
76
  createdBy?: string;
70
77
  updatedBy?: string;
78
+ /** Processing Fee (costo per-tx) reportado por Uniteller en TxDetails. */
79
+ unitellerCostTicket?: number;
80
+ /** Fx Gain reportado por Uniteller (para reconciliar contra cálculo local). */
81
+ unitellerFxGainReported?: number;
82
+ /** Liquidation Rate real que Uniteller aplicó (wholesale efectivo). */
83
+ liquidationRateReported?: number;
84
+ /** Retail Rate que Uniteller cobró al cliente. */
85
+ retailRateReported?: number;
86
+ /** serviceFee + fxGainUsdLocal − unitellerCostTicket. Redondeo 2 decimales. */
87
+ netMarginUsd?: number;
88
+ /** YYYY-MM-DD del reporte SUTWEB38 que pobló los campos anteriores. */
89
+ providerStatementDate?: string;
90
+ /** S3 key del CSV que pobló los campos (trazabilidad + idempotencia). */
91
+ providerStatementSourceKey?: string;
92
+ /** ISO UTC del enrichment. */
93
+ providerStatementAppliedAt?: string;
94
+ /** Estado de reconciliación calculado por AssertionEngine. */
95
+ reconStatus?: RemittanceReconStatus;
96
+ /** Detalle textual de los diffs cuando reconStatus !== OK. */
97
+ reconDiffDetail?: string;
71
98
  }
@@ -5,6 +5,12 @@ exports.RemittanceBackofficeTransaction = void 0;
5
5
  * Vista operativa COMPLETA de una tx para el backoffice (F9): incluye campos
6
6
  * de trazabilidad (previewRef, idempotencyKey, marketplaceTransactionNumber
7
7
  * para correlación con el procesador) que el DTO de usuario no expone.
8
+ *
9
+ * A partir de Fase B de Uniteller también incluye los campos de enrichment
10
+ * poblados por el pipeline SUTWEB38 (unitellerCostTicket, netMarginUsd,
11
+ * reconStatus, etc.) — todos opcionales, filas creadas antes de la
12
+ * implementación no los tienen. Ver `RemittanceReconciliationFields` para
13
+ * el shape canónico.
8
14
  */
9
15
  class RemittanceBackofficeTransaction {
10
16
  }
@@ -0,0 +1,61 @@
1
+ import { RemittanceReconStatus } from "../enums/RemittanceReconStatus";
2
+ /**
3
+ * Campos de enrichment poblados en una tx local por el pipeline de ingesta
4
+ * SUTWEB38 del uniteller-connector, cuando aterriza el archivo TxDetails del
5
+ * día y matchea la tx por `txIdentifier === txNumber`. Todos son opcionales
6
+ * — filas de tx creadas antes de la implementación de Fase B no los tienen.
7
+ *
8
+ * Se comparte como interface (no class) para que otros DTOs (por ejemplo
9
+ * `RemittanceBackofficeTransaction`) la extiendan o intersecten sin duplicar
10
+ * definiciones.
11
+ *
12
+ * Ver spec Cap 4.2.
13
+ */
14
+ export interface RemittanceReconciliationFields {
15
+ /**
16
+ * Processing Fee reportado por Uniteller en la fila TxDetails del SUTWEB38.
17
+ * Es el costo per-tx que Uniteller cobra a Fiado (consolida "UNITELLER
18
+ * processing Cost" + "Payer Cost" del Exhibit A del contrato firmado).
19
+ */
20
+ unitellerCostTicket?: number;
21
+ /**
22
+ * Fx Gain reportado por Uniteller en la fila TxDetails. Se usa para
23
+ * reconciliar contra el cálculo local `amountUSD × markupBps / 10000`.
24
+ * Diff sistemática apunta a redondeo o a que Uniteller aplicó un rate
25
+ * distinto al instruido.
26
+ */
27
+ unitellerFxGainReported?: number;
28
+ /**
29
+ * Liquidation Rate reportado por Uniteller (rate wholesale efectivamente
30
+ * aplicado). Se compara contra el `wholesaleRate` snapshot local para
31
+ * detectar drift silencioso de FX.
32
+ */
33
+ liquidationRateReported?: number;
34
+ /** Retail Rate reportado por Uniteller (rate que cobró al cliente). */
35
+ retailRateReported?: number;
36
+ /**
37
+ * Margen neto USD por transacción calculado como:
38
+ * serviceFee + (amountUSD × markupBps / 10000) − unitellerCostTicket
39
+ * Redondeado a 2 decimales.
40
+ */
41
+ netMarginUsd?: number;
42
+ /**
43
+ * Fecha del reporte SUTWEB38 (YYYY-MM-DD) que pobló los campos anteriores.
44
+ * Derivada del filename `SUTWEBXX_TxDetails_MMDDYYYY_MMDDYYYY.csv`.
45
+ */
46
+ providerStatementDate?: string;
47
+ /**
48
+ * S3 key del archivo CSV que pobló los campos (para trazabilidad
49
+ * regulatoria y para la idempotencia por conditional write DDB).
50
+ */
51
+ providerStatementSourceKey?: string;
52
+ /** ISO UTC del momento en que se aplicó el enrichment. */
53
+ providerStatementAppliedAt?: string;
54
+ /** Estado de reconciliación calculado por AssertionEngine. */
55
+ reconStatus?: RemittanceReconStatus;
56
+ /**
57
+ * Descripción textual concatenada de los diffs encontrados (ej.
58
+ * "amountUSD 150 vs stmt 151; fx local 0.585 vs stmt 2.0").
59
+ */
60
+ reconDiffDetail?: string;
61
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -31,6 +31,7 @@ export * from "./RemittanceSmsRequest";
31
31
  export * from "./RemittanceBackofficeUserView";
32
32
  export * from "./RemittanceBackofficeDashboardSummary";
33
33
  export * from "./RemittanceBackofficeTransaction";
34
+ export * from "./RemittanceReconciliation";
34
35
  export * from "./RemittanceBackofficeUserDetail";
35
36
  export * from "./RemittanceBackofficeUserListResponse";
36
37
  export * from "./RemittanceBackofficeTxListResponse";
@@ -47,6 +47,7 @@ __exportStar(require("./RemittanceSmsRequest"), exports);
47
47
  __exportStar(require("./RemittanceBackofficeUserView"), exports);
48
48
  __exportStar(require("./RemittanceBackofficeDashboardSummary"), exports);
49
49
  __exportStar(require("./RemittanceBackofficeTransaction"), exports);
50
+ __exportStar(require("./RemittanceReconciliation"), exports);
50
51
  __exportStar(require("./RemittanceBackofficeUserDetail"), exports);
51
52
  __exportStar(require("./RemittanceBackofficeUserListResponse"), exports);
52
53
  __exportStar(require("./RemittanceBackofficeTxListResponse"), exports);
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Estado de reconciliación de una tx local contra el reporte SUTWEB38 diario
3
+ * de Uniteller. Poblado por AssertionEngine del uniteller-connector al ingerir
4
+ * el archivo TxDetails. Ver spec de reconciliación Cap 6 (motor de aserciones).
5
+ *
6
+ * Prioridad si múltiples diffs: DIFF_COST > DIFF_FX > DIFF_RATE > DIFF_AMOUNT > OK.
7
+ */
8
+ export declare enum RemittanceReconStatus {
9
+ OK = "OK",
10
+ DIFF_FX = "DIFF_FX",
11
+ DIFF_COST = "DIFF_COST",
12
+ DIFF_RATE = "DIFF_RATE",
13
+ DIFF_AMOUNT = "DIFF_AMOUNT",
14
+ MISSING_IN_PROVIDER = "MISSING_IN_PROVIDER"
15
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RemittanceReconStatus = void 0;
4
+ /**
5
+ * Estado de reconciliación de una tx local contra el reporte SUTWEB38 diario
6
+ * de Uniteller. Poblado por AssertionEngine del uniteller-connector al ingerir
7
+ * el archivo TxDetails. Ver spec de reconciliación Cap 6 (motor de aserciones).
8
+ *
9
+ * Prioridad si múltiples diffs: DIFF_COST > DIFF_FX > DIFF_RATE > DIFF_AMOUNT > OK.
10
+ */
11
+ var RemittanceReconStatus;
12
+ (function (RemittanceReconStatus) {
13
+ RemittanceReconStatus["OK"] = "OK";
14
+ RemittanceReconStatus["DIFF_FX"] = "DIFF_FX";
15
+ RemittanceReconStatus["DIFF_COST"] = "DIFF_COST";
16
+ RemittanceReconStatus["DIFF_RATE"] = "DIFF_RATE";
17
+ RemittanceReconStatus["DIFF_AMOUNT"] = "DIFF_AMOUNT";
18
+ RemittanceReconStatus["MISSING_IN_PROVIDER"] = "MISSING_IN_PROVIDER";
19
+ })(RemittanceReconStatus || (exports.RemittanceReconStatus = RemittanceReconStatus = {}));
@@ -25,3 +25,4 @@ export * from "./RuleActionType";
25
25
  export * from "./AuditResult";
26
26
  export * from "./RemittanceExceptionCode";
27
27
  export * from "./RemittanceFieldBelongsTo";
28
+ export * from "./RemittanceReconStatus";
@@ -41,3 +41,4 @@ __exportStar(require("./RuleActionType"), exports);
41
41
  __exportStar(require("./AuditResult"), exports);
42
42
  __exportStar(require("./RemittanceExceptionCode"), exports);
43
43
  __exportStar(require("./RemittanceFieldBelongsTo"), exports);
44
+ __exportStar(require("./RemittanceReconStatus"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.449.0",
3
+ "version": "3.451.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -1,6 +1,7 @@
1
1
  import {CountryId} from "../../country";
2
2
  import {ProductTaxFeeTypeEnum} from "../enums/ProductTaxFeeTypeEnum";
3
3
  import {ProductTypeEnum} from "../enums/ProductTypeEnum";
4
+ import {IsNumber, IsOptional} from "class-validator";
4
5
 
5
6
  export class CreateProductCatalogRequest {
6
7
  id: string;
@@ -12,4 +13,8 @@ export class CreateProductCatalogRequest {
12
13
  fee: number;
13
14
  taxType: ProductTaxFeeTypeEnum;
14
15
  tax: number;
16
+
17
+ @IsOptional()
18
+ @IsNumber()
19
+ minFee?: number;
15
20
  }
@@ -1,6 +1,6 @@
1
1
  import {CountryId} from "../../country";
2
2
  import {ProductTaxFeeTypeEnum} from "../enums/ProductTaxFeeTypeEnum";
3
- import {IsEnum, IsNumber, IsString} from "class-validator";
3
+ import {IsEnum, IsNumber, IsOptional, IsString} from "class-validator";
4
4
  import {ProductTypeEnum} from "../enums/ProductTypeEnum";
5
5
 
6
6
  export default class GetProductCatalogResponse {
@@ -31,6 +31,10 @@ export default class GetProductCatalogResponse {
31
31
  @IsNumber()
32
32
  tax: number;
33
33
 
34
+ @IsOptional()
35
+ @IsNumber()
36
+ minFee?: number;
37
+
34
38
  @IsString()
35
39
  createdAt: string;
36
40
 
@@ -1,4 +1,5 @@
1
1
  export enum ProductTaxFeeTypeEnum {
2
2
  PERCENT = "PERCENT",
3
- FIXED = "FIXED"
3
+ FIXED = "FIXED",
4
+ PERCENT_WITH_MIN = "PERCENT_WITH_MIN",
4
5
  }
@@ -1,11 +1,18 @@
1
1
  import { RemittanceTxStatus } from "../enums/RemittanceTxStatus";
2
2
  import { RemittanceCancelStageEnum } from "../enums/RemittanceCancelStageEnum";
3
3
  import { RemittanceCancelOutcomeEnum } from "../enums/RemittanceCancelOutcomeEnum";
4
+ import { RemittanceReconStatus } from "../enums/RemittanceReconStatus";
4
5
 
5
6
  /**
6
7
  * Vista operativa COMPLETA de una tx para el backoffice (F9): incluye campos
7
8
  * de trazabilidad (previewRef, idempotencyKey, marketplaceTransactionNumber
8
9
  * para correlación con el procesador) que el DTO de usuario no expone.
10
+ *
11
+ * A partir de Fase B de Uniteller también incluye los campos de enrichment
12
+ * poblados por el pipeline SUTWEB38 (unitellerCostTicket, netMarginUsd,
13
+ * reconStatus, etc.) — todos opcionales, filas creadas antes de la
14
+ * implementación no los tienen. Ver `RemittanceReconciliationFields` para
15
+ * el shape canónico.
9
16
  */
10
17
  export class RemittanceBackofficeTransaction {
11
18
  directoryId!: string;
@@ -69,4 +76,30 @@ export class RemittanceBackofficeTransaction {
69
76
  updatedAt!: string;
70
77
  createdBy?: string;
71
78
  updatedBy?: string;
79
+
80
+ // ─── Enrichment SUTWEB38 (Fase B Uniteller) ─────────────────────────
81
+ // Poblados por Sutweb38FilePipeline en uniteller-connector al aterrizar
82
+ // el archivo TxDetails del día que matchea txNumber. Ver
83
+ // RemittanceReconciliationFields para docs por campo.
84
+
85
+ /** Processing Fee (costo per-tx) reportado por Uniteller en TxDetails. */
86
+ unitellerCostTicket?: number;
87
+ /** Fx Gain reportado por Uniteller (para reconciliar contra cálculo local). */
88
+ unitellerFxGainReported?: number;
89
+ /** Liquidation Rate real que Uniteller aplicó (wholesale efectivo). */
90
+ liquidationRateReported?: number;
91
+ /** Retail Rate que Uniteller cobró al cliente. */
92
+ retailRateReported?: number;
93
+ /** serviceFee + fxGainUsdLocal − unitellerCostTicket. Redondeo 2 decimales. */
94
+ netMarginUsd?: number;
95
+ /** YYYY-MM-DD del reporte SUTWEB38 que pobló los campos anteriores. */
96
+ providerStatementDate?: string;
97
+ /** S3 key del CSV que pobló los campos (trazabilidad + idempotencia). */
98
+ providerStatementSourceKey?: string;
99
+ /** ISO UTC del enrichment. */
100
+ providerStatementAppliedAt?: string;
101
+ /** Estado de reconciliación calculado por AssertionEngine. */
102
+ reconStatus?: RemittanceReconStatus;
103
+ /** Detalle textual de los diffs cuando reconStatus !== OK. */
104
+ reconDiffDetail?: string;
72
105
  }
@@ -0,0 +1,71 @@
1
+ import { RemittanceReconStatus } from "../enums/RemittanceReconStatus";
2
+
3
+ /**
4
+ * Campos de enrichment poblados en una tx local por el pipeline de ingesta
5
+ * SUTWEB38 del uniteller-connector, cuando aterriza el archivo TxDetails del
6
+ * día y matchea la tx por `txIdentifier === txNumber`. Todos son opcionales
7
+ * — filas de tx creadas antes de la implementación de Fase B no los tienen.
8
+ *
9
+ * Se comparte como interface (no class) para que otros DTOs (por ejemplo
10
+ * `RemittanceBackofficeTransaction`) la extiendan o intersecten sin duplicar
11
+ * definiciones.
12
+ *
13
+ * Ver spec Cap 4.2.
14
+ */
15
+ export interface RemittanceReconciliationFields {
16
+ /**
17
+ * Processing Fee reportado por Uniteller en la fila TxDetails del SUTWEB38.
18
+ * Es el costo per-tx que Uniteller cobra a Fiado (consolida "UNITELLER
19
+ * processing Cost" + "Payer Cost" del Exhibit A del contrato firmado).
20
+ */
21
+ unitellerCostTicket?: number;
22
+
23
+ /**
24
+ * Fx Gain reportado por Uniteller en la fila TxDetails. Se usa para
25
+ * reconciliar contra el cálculo local `amountUSD × markupBps / 10000`.
26
+ * Diff sistemática apunta a redondeo o a que Uniteller aplicó un rate
27
+ * distinto al instruido.
28
+ */
29
+ unitellerFxGainReported?: number;
30
+
31
+ /**
32
+ * Liquidation Rate reportado por Uniteller (rate wholesale efectivamente
33
+ * aplicado). Se compara contra el `wholesaleRate` snapshot local para
34
+ * detectar drift silencioso de FX.
35
+ */
36
+ liquidationRateReported?: number;
37
+
38
+ /** Retail Rate reportado por Uniteller (rate que cobró al cliente). */
39
+ retailRateReported?: number;
40
+
41
+ /**
42
+ * Margen neto USD por transacción calculado como:
43
+ * serviceFee + (amountUSD × markupBps / 10000) − unitellerCostTicket
44
+ * Redondeado a 2 decimales.
45
+ */
46
+ netMarginUsd?: number;
47
+
48
+ /**
49
+ * Fecha del reporte SUTWEB38 (YYYY-MM-DD) que pobló los campos anteriores.
50
+ * Derivada del filename `SUTWEBXX_TxDetails_MMDDYYYY_MMDDYYYY.csv`.
51
+ */
52
+ providerStatementDate?: string;
53
+
54
+ /**
55
+ * S3 key del archivo CSV que pobló los campos (para trazabilidad
56
+ * regulatoria y para la idempotencia por conditional write DDB).
57
+ */
58
+ providerStatementSourceKey?: string;
59
+
60
+ /** ISO UTC del momento en que se aplicó el enrichment. */
61
+ providerStatementAppliedAt?: string;
62
+
63
+ /** Estado de reconciliación calculado por AssertionEngine. */
64
+ reconStatus?: RemittanceReconStatus;
65
+
66
+ /**
67
+ * Descripción textual concatenada de los diffs encontrados (ej.
68
+ * "amountUSD 150 vs stmt 151; fx local 0.585 vs stmt 2.0").
69
+ */
70
+ reconDiffDetail?: string;
71
+ }
@@ -31,6 +31,7 @@ export * from "./RemittanceSmsRequest";
31
31
  export * from "./RemittanceBackofficeUserView";
32
32
  export * from "./RemittanceBackofficeDashboardSummary";
33
33
  export * from "./RemittanceBackofficeTransaction";
34
+ export * from "./RemittanceReconciliation";
34
35
  export * from "./RemittanceBackofficeUserDetail";
35
36
  export * from "./RemittanceBackofficeUserListResponse";
36
37
  export * from "./RemittanceBackofficeTxListResponse";
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Estado de reconciliación de una tx local contra el reporte SUTWEB38 diario
3
+ * de Uniteller. Poblado por AssertionEngine del uniteller-connector al ingerir
4
+ * el archivo TxDetails. Ver spec de reconciliación Cap 6 (motor de aserciones).
5
+ *
6
+ * Prioridad si múltiples diffs: DIFF_COST > DIFF_FX > DIFF_RATE > DIFF_AMOUNT > OK.
7
+ */
8
+ export enum RemittanceReconStatus {
9
+ OK = "OK",
10
+ DIFF_FX = "DIFF_FX",
11
+ DIFF_COST = "DIFF_COST",
12
+ DIFF_RATE = "DIFF_RATE",
13
+ DIFF_AMOUNT = "DIFF_AMOUNT",
14
+ MISSING_IN_PROVIDER = "MISSING_IN_PROVIDER",
15
+ }
@@ -25,3 +25,4 @@ export * from "./RuleActionType";
25
25
  export * from "./AuditResult";
26
26
  export * from "./RemittanceExceptionCode";
27
27
  export * from "./RemittanceFieldBelongsTo";
28
+ export * from "./RemittanceReconStatus";