@fiado/type-kit 3.407.0 → 3.409.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 (36) hide show
  1. package/_test_/unit/loanCredit/dtos/loanDeviceContract.test.ts +15 -4
  2. package/_test_/unit/mdm/dtos/mdmDeviceContract.test.ts +32 -0
  3. package/bin/loanCredit/constants/creditPaymentHook.d.ts +2 -0
  4. package/bin/loanCredit/constants/creditPaymentHook.js +5 -0
  5. package/bin/loanCredit/dtos/LoanDeviceNotifyItem.d.ts +8 -10
  6. package/bin/loanCredit/dtos/LoanDeviceNotifyItem.js +4 -2
  7. package/bin/loanCredit/dtos/requests/CreditPaymentAppliedRequest.d.ts +10 -0
  8. package/bin/loanCredit/dtos/requests/CreditPaymentAppliedRequest.js +38 -0
  9. package/bin/loanCredit/dtos/requests/CreditSettledRequest.d.ts +10 -0
  10. package/bin/loanCredit/dtos/requests/CreditSettledRequest.js +38 -0
  11. package/bin/loanCredit/dtos/responses/CreditPaymentAppliedResponse.d.ts +8 -0
  12. package/bin/loanCredit/dtos/responses/CreditPaymentAppliedResponse.js +2 -0
  13. package/bin/loanCredit/dtos/responses/CreditSettledResponse.d.ts +8 -0
  14. package/bin/loanCredit/dtos/responses/CreditSettledResponse.js +2 -0
  15. package/bin/loanCredit/enums/CreditPaymentUnlockDecisionEnum.d.ts +20 -0
  16. package/bin/loanCredit/enums/CreditPaymentUnlockDecisionEnum.js +24 -0
  17. package/bin/loanCredit/enums/CreditSettlementDecisionEnum.d.ts +21 -0
  18. package/bin/loanCredit/enums/CreditSettlementDecisionEnum.js +25 -0
  19. package/bin/loanCredit/enums/CreditSettlementReleaseDecisionEnum.d.ts +17 -0
  20. package/bin/loanCredit/enums/CreditSettlementReleaseDecisionEnum.js +21 -0
  21. package/bin/loanCredit/index.d.ts +8 -0
  22. package/bin/loanCredit/index.js +8 -0
  23. package/bin/mdm/dtos/DeviceNotifyRequest.d.ts +7 -8
  24. package/bin/mdm/dtos/DeviceNotifyRequest.js +3 -0
  25. package/package.json +1 -1
  26. package/src/loanCredit/constants/creditPaymentHook.ts +2 -0
  27. package/src/loanCredit/dtos/LoanDeviceNotifyItem.ts +11 -10
  28. package/src/loanCredit/dtos/requests/CreditPaymentAppliedRequest.ts +25 -0
  29. package/src/loanCredit/dtos/requests/CreditSettledRequest.ts +25 -0
  30. package/src/loanCredit/dtos/responses/CreditPaymentAppliedResponse.ts +9 -0
  31. package/src/loanCredit/dtos/responses/CreditSettledResponse.ts +9 -0
  32. package/src/loanCredit/enums/CreditPaymentUnlockDecisionEnum.ts +20 -0
  33. package/src/loanCredit/enums/CreditSettlementDecisionEnum.ts +21 -0
  34. package/src/loanCredit/enums/CreditSettlementReleaseDecisionEnum.ts +17 -0
  35. package/src/loanCredit/index.ts +8 -0
  36. package/src/mdm/dtos/DeviceNotifyRequest.ts +10 -8
@@ -369,13 +369,24 @@ describe('LoanDeviceNotifyRequest', () => {
369
369
  expect(JSON.stringify(itemsError)).toContain(field);
370
370
  });
371
371
 
372
- it.each(['notificationCode', 'title', 'content'] as const)('falla si %s no viene', async field => {
372
+ it.each(['notificationCode', 'title', 'content'] as const)('valida sin %s', async field => {
373
373
  const { [field]: _omitted, ...rest } = validNotifyItem;
374
374
  const dto = plainToInstance(LoanDeviceNotifyRequest, notifyWithItems([rest]));
375
375
  const errors = await validate(dto);
376
- const itemsError = errors.find(e => e.property === 'items');
377
- expect(itemsError).toBeDefined();
378
- expect(JSON.stringify(itemsError)).toContain(field);
376
+ expect(errors).toEqual([]);
377
+ });
378
+
379
+ it('valida el ítem que manda el motor: noticeType y nada de texto', async () => {
380
+ const items = [
381
+ {
382
+ creditId: CREDIT_ID,
383
+ intensity: DeviceNotifyIntensityEnum.FULLSCREEN,
384
+ noticeType: MdmNoticeTypeEnum.OVERDUE_1_DAY,
385
+ },
386
+ ];
387
+ const dto = plainToInstance(LoanDeviceNotifyRequest, notifyWithItems(items));
388
+ const errors = await validate(dto);
389
+ expect(errors).toEqual([]);
379
390
  });
380
391
 
381
392
  it.each(['notificationCode', 'title', 'content'] as const)('falla si %s no es string', async field => {
@@ -116,6 +116,38 @@ describe('DeviceNotifyRequest.noticeType', () => {
116
116
  });
117
117
  });
118
118
 
119
+ describe('DeviceNotifyRequest — los tres textos son opcionales', () => {
120
+ /** Aviso como lo manda el motor: solo el id agnóstico, sin relleno de texto. */
121
+ const noticeOnly = {
122
+ imei: validNotify.imei,
123
+ intensity: validNotify.intensity,
124
+ noticeType: MdmNoticeTypeEnum.OVERDUE_1_DAY,
125
+ operationReference: validNotify.operationReference,
126
+ };
127
+
128
+ it('valida con noticeType y sin ninguno de los tres textos', async () => {
129
+ const dto = plainToInstance(DeviceNotifyRequest, noticeOnly);
130
+ const errors = await validate(dto);
131
+ expect(errors).toEqual([]);
132
+ expect(dto.notificationCode).toBeUndefined();
133
+ expect(dto.title).toBeUndefined();
134
+ expect(dto.content).toBeUndefined();
135
+ });
136
+
137
+ it.each(['notificationCode', 'title', 'content'] as const)('valida sin %s', async field => {
138
+ const { [field]: _omitted, ...rest } = validNotify;
139
+ const dto = plainToInstance(DeviceNotifyRequest, rest);
140
+ const errors = await validate(dto);
141
+ expect(errors).toEqual([]);
142
+ });
143
+
144
+ it.each(['notificationCode', 'title', 'content'] as const)('falla si %s viene vacío', async field => {
145
+ const dto = plainToInstance(DeviceNotifyRequest, { ...validNotify, [field]: '' });
146
+ const errors = await validate(dto);
147
+ expect(hasConstraint(errors, field, 'isNotEmpty')).toBe(true);
148
+ });
149
+ });
150
+
119
151
  describe('MdmNoticeTypeEnum', () => {
120
152
  it('expone los diez avisos del catálogo de cobranza', () => {
121
153
  expect(Object.values(MdmNoticeTypeEnum)).toEqual([
@@ -0,0 +1,2 @@
1
+ /** Largo máximo del actor y de la referencia de pago de los dos hooks de cobranza del crédito. */
2
+ export declare const CREDIT_PAYMENT_HOOK_TEXT_MAX_LENGTH = 120;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CREDIT_PAYMENT_HOOK_TEXT_MAX_LENGTH = void 0;
4
+ /** Largo máximo del actor y de la referencia de pago de los dos hooks de cobranza del crédito. */
5
+ exports.CREDIT_PAYMENT_HOOK_TEXT_MAX_LENGTH = 120;
@@ -2,22 +2,20 @@ import { DeviceNotifyIntensityEnum } from '../../mdm/enums/DeviceNotifyIntensity
2
2
  import { MdmNoticeTypeEnum } from '../../mdm/enums/MdmNoticeTypeEnum';
3
3
  /**
4
4
  * Ítem de notificación: a qué crédito se le avisa y con qué aviso.
5
- * El aviso viaja como `noticeType`; los tres campos de texto siguen siendo obligatorios porque
6
- * Datacultr usa el código del catálogo y Trustonic el texto crudo.
5
+ * El aviso viaja como `noticeType`; los tres campos de texto son el camino legacy.
7
6
  */
8
7
  export declare class LoanDeviceNotifyItem {
9
8
  creditId: string;
10
9
  intensity: DeviceNotifyIntensityEnum;
11
10
  /**
12
11
  * Id agnóstico del aviso; cada connector lo traduce a lo que su proveedor entiende.
13
- * Los connectors lo van a preferir sobre `notificationCode`/`title`/`content`;
14
- * hasta entonces esos tres siguen siendo la fuente.
12
+ * Cuando viaja, manda: los connectors ignoran `notificationCode`, `title` y `content`.
15
13
  */
16
14
  noticeType?: MdmNoticeTypeEnum;
17
- /** Código de notificación del catálogo de Datacultr. Queda por compatibilidad durante la migración a `noticeType`. */
18
- notificationCode: string;
19
- /** Título crudo que exige Trustonic. Queda por compatibilidad durante la migración a `noticeType`. */
20
- title: string;
21
- /** Cuerpo crudo que exige Trustonic. Queda por compatibilidad durante la migración a `noticeType`. */
22
- content: string;
15
+ /** Código del catálogo de Datacultr. Camino legacy: solo se lee si no viaja `noticeType`. */
16
+ notificationCode?: string;
17
+ /** Título crudo para Trustonic. Camino legacy: solo se lee si no viaja `noticeType`. */
18
+ title?: string;
19
+ /** Cuerpo crudo para Trustonic. Camino legacy: solo se lee si no viaja `noticeType`. */
20
+ content?: string;
23
21
  }
@@ -17,8 +17,7 @@ const MdmNoticeTypeEnum_1 = require("../../mdm/enums/MdmNoticeTypeEnum");
17
17
  const CreditIdPattern_1 = require("../constants/CreditIdPattern");
18
18
  /**
19
19
  * Ítem de notificación: a qué crédito se le avisa y con qué aviso.
20
- * El aviso viaja como `noticeType`; los tres campos de texto siguen siendo obligatorios porque
21
- * Datacultr usa el código del catálogo y Trustonic el texto crudo.
20
+ * El aviso viaja como `noticeType`; los tres campos de texto son el camino legacy.
22
21
  */
23
22
  class LoanDeviceNotifyItem {
24
23
  }
@@ -41,6 +40,7 @@ __decorate([
41
40
  ], LoanDeviceNotifyItem.prototype, "noticeType", void 0);
42
41
  __decorate([
43
42
  (0, class_transformer_1.Expose)(),
43
+ (0, class_validator_1.IsOptional)(),
44
44
  (0, class_validator_1.IsString)(),
45
45
  (0, class_validator_1.IsNotEmpty)(),
46
46
  (0, class_validator_1.MaxLength)(64),
@@ -48,6 +48,7 @@ __decorate([
48
48
  ], LoanDeviceNotifyItem.prototype, "notificationCode", void 0);
49
49
  __decorate([
50
50
  (0, class_transformer_1.Expose)(),
51
+ (0, class_validator_1.IsOptional)(),
51
52
  (0, class_validator_1.IsString)(),
52
53
  (0, class_validator_1.IsNotEmpty)(),
53
54
  (0, class_validator_1.MaxLength)(128),
@@ -55,6 +56,7 @@ __decorate([
55
56
  ], LoanDeviceNotifyItem.prototype, "title", void 0);
56
57
  __decorate([
57
58
  (0, class_transformer_1.Expose)(),
59
+ (0, class_validator_1.IsOptional)(),
58
60
  (0, class_validator_1.IsString)(),
59
61
  (0, class_validator_1.IsNotEmpty)(),
60
62
  (0, class_validator_1.MaxLength)(1024),
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Body de `POST /private/credits/:creditId/payment-applied` (loan-credit-business). Es OPCIONAL:
3
+ * sin él el pago se atribuye al sistema. `paymentReference` es sólo trazabilidad — no decide nada.
4
+ */
5
+ export declare class CreditPaymentAppliedRequest {
6
+ /** Quién aplicó el pago; queda en la bitácora del expediente. */
7
+ actor?: string;
8
+ /** Referencia del pago en el sistema que lo aplicó. Sólo trazabilidad. */
9
+ paymentReference?: string;
10
+ }
@@ -0,0 +1,38 @@
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.CreditPaymentAppliedRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const creditPaymentHook_1 = require("../../constants/creditPaymentHook");
16
+ /**
17
+ * Body de `POST /private/credits/:creditId/payment-applied` (loan-credit-business). Es OPCIONAL:
18
+ * sin él el pago se atribuye al sistema. `paymentReference` es sólo trazabilidad — no decide nada.
19
+ */
20
+ class CreditPaymentAppliedRequest {
21
+ }
22
+ exports.CreditPaymentAppliedRequest = CreditPaymentAppliedRequest;
23
+ __decorate([
24
+ (0, class_transformer_1.Expose)(),
25
+ (0, class_validator_1.IsOptional)(),
26
+ (0, class_validator_1.IsString)(),
27
+ (0, class_validator_1.IsNotEmpty)(),
28
+ (0, class_validator_1.MaxLength)(creditPaymentHook_1.CREDIT_PAYMENT_HOOK_TEXT_MAX_LENGTH),
29
+ __metadata("design:type", String)
30
+ ], CreditPaymentAppliedRequest.prototype, "actor", void 0);
31
+ __decorate([
32
+ (0, class_transformer_1.Expose)(),
33
+ (0, class_validator_1.IsOptional)(),
34
+ (0, class_validator_1.IsString)(),
35
+ (0, class_validator_1.IsNotEmpty)(),
36
+ (0, class_validator_1.MaxLength)(creditPaymentHook_1.CREDIT_PAYMENT_HOOK_TEXT_MAX_LENGTH),
37
+ __metadata("design:type", String)
38
+ ], CreditPaymentAppliedRequest.prototype, "paymentReference", void 0);
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Body de `POST /private/credits/:creditId/settled` (loan-credit-business). También opcional.
3
+ * La ruta VERIFICA que el crédito no deba nada: no le cree al caller.
4
+ */
5
+ export declare class CreditSettledRequest {
6
+ /** Quién declaró la liquidación; queda en la bitácora del expediente. */
7
+ actor?: string;
8
+ /** Referencia del pago que liquidó. Sólo trazabilidad. */
9
+ paymentReference?: string;
10
+ }
@@ -0,0 +1,38 @@
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.CreditSettledRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const creditPaymentHook_1 = require("../../constants/creditPaymentHook");
16
+ /**
17
+ * Body de `POST /private/credits/:creditId/settled` (loan-credit-business). También opcional.
18
+ * La ruta VERIFICA que el crédito no deba nada: no le cree al caller.
19
+ */
20
+ class CreditSettledRequest {
21
+ }
22
+ exports.CreditSettledRequest = CreditSettledRequest;
23
+ __decorate([
24
+ (0, class_transformer_1.Expose)(),
25
+ (0, class_validator_1.IsOptional)(),
26
+ (0, class_validator_1.IsString)(),
27
+ (0, class_validator_1.IsNotEmpty)(),
28
+ (0, class_validator_1.MaxLength)(creditPaymentHook_1.CREDIT_PAYMENT_HOOK_TEXT_MAX_LENGTH),
29
+ __metadata("design:type", String)
30
+ ], CreditSettledRequest.prototype, "actor", void 0);
31
+ __decorate([
32
+ (0, class_transformer_1.Expose)(),
33
+ (0, class_validator_1.IsOptional)(),
34
+ (0, class_validator_1.IsString)(),
35
+ (0, class_validator_1.IsNotEmpty)(),
36
+ (0, class_validator_1.MaxLength)(creditPaymentHook_1.CREDIT_PAYMENT_HOOK_TEXT_MAX_LENGTH),
37
+ __metadata("design:type", String)
38
+ ], CreditSettledRequest.prototype, "paymentReference", void 0);
@@ -0,0 +1,8 @@
1
+ import { CreditPaymentUnlockDecisionEnum } from '../../enums/CreditPaymentUnlockDecisionEnum';
2
+ /** Resultado de aplicar un pago: el crédito sale de mora y el equipo se suelta si corresponde. */
3
+ export interface CreditPaymentAppliedResponse {
4
+ creditId: string;
5
+ /** El crédito salió de mora. Pasa aunque no haya equipo, esté sin candado, o sea SCHEDULED. */
6
+ creditReactivated: boolean;
7
+ unlockDecision: CreditPaymentUnlockDecisionEnum;
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,8 @@
1
+ import { CreditSettlementDecisionEnum } from '../../enums/CreditSettlementDecisionEnum';
2
+ import { CreditSettlementReleaseDecisionEnum } from '../../enums/CreditSettlementReleaseDecisionEnum';
3
+ /** Resultado de liquidar el crédito; `releaseDecision` es null si el equipo no salió al proveedor. */
4
+ export interface CreditSettledResponse {
5
+ creditId: string;
6
+ settlementDecision: CreditSettlementDecisionEnum;
7
+ releaseDecision: CreditSettlementReleaseDecisionEnum | null;
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Qué pasó con el equipo cuando se aplicó un pago al crédito.
3
+ * @enum {string}
4
+ */
5
+ export declare enum CreditPaymentUnlockDecisionEnum {
6
+ CREDIT_NOT_FOUND = "CREDIT_NOT_FOUND",
7
+ /** El crédito no está en un estado al que el pago le suelte el equipo. */
8
+ CREDIT_NOT_UNLOCKABLE = "CREDIT_NOT_UNLOCKABLE",
9
+ NOT_ENROLLED = "NOT_ENROLLED",
10
+ /** El equipo no estaba bloqueado: no hay nada que soltar. */
11
+ NOT_LOCKED = "NOT_LOCKED",
12
+ /** El candado no es el de la mora (fraude, manual, o sin motivo): un pago no lo suelta. */
13
+ LOCKED_FOR_OTHER_REASON = "LOCKED_FOR_OTHER_REASON",
14
+ /** El pago no alcanzó el umbral escalonado: sigue bloqueado y no se reprograma nada. */
15
+ THRESHOLD_NOT_MET = "THRESHOLD_NOT_MET",
16
+ UNLOCKED = "UNLOCKED",
17
+ /** El proveedor aceptó la orden y todavía no la dio por hecha. */
18
+ UNLOCK_PENDING = "UNLOCK_PENDING",
19
+ UNLOCK_FAILED = "UNLOCK_FAILED"
20
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CreditPaymentUnlockDecisionEnum = void 0;
4
+ /**
5
+ * Qué pasó con el equipo cuando se aplicó un pago al crédito.
6
+ * @enum {string}
7
+ */
8
+ var CreditPaymentUnlockDecisionEnum;
9
+ (function (CreditPaymentUnlockDecisionEnum) {
10
+ CreditPaymentUnlockDecisionEnum["CREDIT_NOT_FOUND"] = "CREDIT_NOT_FOUND";
11
+ /** El crédito no está en un estado al que el pago le suelte el equipo. */
12
+ CreditPaymentUnlockDecisionEnum["CREDIT_NOT_UNLOCKABLE"] = "CREDIT_NOT_UNLOCKABLE";
13
+ CreditPaymentUnlockDecisionEnum["NOT_ENROLLED"] = "NOT_ENROLLED";
14
+ /** El equipo no estaba bloqueado: no hay nada que soltar. */
15
+ CreditPaymentUnlockDecisionEnum["NOT_LOCKED"] = "NOT_LOCKED";
16
+ /** El candado no es el de la mora (fraude, manual, o sin motivo): un pago no lo suelta. */
17
+ CreditPaymentUnlockDecisionEnum["LOCKED_FOR_OTHER_REASON"] = "LOCKED_FOR_OTHER_REASON";
18
+ /** El pago no alcanzó el umbral escalonado: sigue bloqueado y no se reprograma nada. */
19
+ CreditPaymentUnlockDecisionEnum["THRESHOLD_NOT_MET"] = "THRESHOLD_NOT_MET";
20
+ CreditPaymentUnlockDecisionEnum["UNLOCKED"] = "UNLOCKED";
21
+ /** El proveedor aceptó la orden y todavía no la dio por hecha. */
22
+ CreditPaymentUnlockDecisionEnum["UNLOCK_PENDING"] = "UNLOCK_PENDING";
23
+ CreditPaymentUnlockDecisionEnum["UNLOCK_FAILED"] = "UNLOCK_FAILED";
24
+ })(CreditPaymentUnlockDecisionEnum || (exports.CreditPaymentUnlockDecisionEnum = CreditPaymentUnlockDecisionEnum = {}));
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Qué pasó al intentar dejar el crédito liquidado. La ruta VERIFICA el saldo, no cree al caller.
3
+ * @enum {string}
4
+ */
5
+ export declare enum CreditSettlementDecisionEnum {
6
+ CREDIT_NOT_FOUND = "CREDIT_NOT_FOUND",
7
+ /** Ya estaba liquidado: la ruta es idempotente y la liberación corre igual. */
8
+ ALREADY_SETTLED = "ALREADY_SETTLED",
9
+ /** El estado del crédito no admite liquidación (sólo ACTIVE e IN_ARREARS la admiten). */
10
+ CREDIT_NOT_SETTLEABLE = "CREDIT_NOT_SETTLEABLE",
11
+ /** Sin plan de cuotas no hay evidencia de que deba cero; fail-closed. */
12
+ NO_INSTALLMENTS = "NO_INSTALLMENTS",
13
+ /** Al plan le falta alguna cuota del plazo: la deuda que no se persistió no se puede saldar. */
14
+ INCOMPLETE_PLAN = "INCOMPLETE_PLAN",
15
+ /** Alguna cuota sigue debiendo: liquidar acá liberaría un equipo con deuda viva. */
16
+ BALANCE_OUTSTANDING = "BALANCE_OUTSTANDING",
17
+ SETTLED = "SETTLED",
18
+ /** Otro movió el estado entre la lectura y la escritura; el caller relee y reintenta. */
19
+ SETTLE_CONFLICT = "SETTLE_CONFLICT",
20
+ SETTLE_FAILED = "SETTLE_FAILED"
21
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CreditSettlementDecisionEnum = void 0;
4
+ /**
5
+ * Qué pasó al intentar dejar el crédito liquidado. La ruta VERIFICA el saldo, no cree al caller.
6
+ * @enum {string}
7
+ */
8
+ var CreditSettlementDecisionEnum;
9
+ (function (CreditSettlementDecisionEnum) {
10
+ CreditSettlementDecisionEnum["CREDIT_NOT_FOUND"] = "CREDIT_NOT_FOUND";
11
+ /** Ya estaba liquidado: la ruta es idempotente y la liberación corre igual. */
12
+ CreditSettlementDecisionEnum["ALREADY_SETTLED"] = "ALREADY_SETTLED";
13
+ /** El estado del crédito no admite liquidación (sólo ACTIVE e IN_ARREARS la admiten). */
14
+ CreditSettlementDecisionEnum["CREDIT_NOT_SETTLEABLE"] = "CREDIT_NOT_SETTLEABLE";
15
+ /** Sin plan de cuotas no hay evidencia de que deba cero; fail-closed. */
16
+ CreditSettlementDecisionEnum["NO_INSTALLMENTS"] = "NO_INSTALLMENTS";
17
+ /** Al plan le falta alguna cuota del plazo: la deuda que no se persistió no se puede saldar. */
18
+ CreditSettlementDecisionEnum["INCOMPLETE_PLAN"] = "INCOMPLETE_PLAN";
19
+ /** Alguna cuota sigue debiendo: liquidar acá liberaría un equipo con deuda viva. */
20
+ CreditSettlementDecisionEnum["BALANCE_OUTSTANDING"] = "BALANCE_OUTSTANDING";
21
+ CreditSettlementDecisionEnum["SETTLED"] = "SETTLED";
22
+ /** Otro movió el estado entre la lectura y la escritura; el caller relee y reintenta. */
23
+ CreditSettlementDecisionEnum["SETTLE_CONFLICT"] = "SETTLE_CONFLICT";
24
+ CreditSettlementDecisionEnum["SETTLE_FAILED"] = "SETTLE_FAILED";
25
+ })(CreditSettlementDecisionEnum || (exports.CreditSettlementDecisionEnum = CreditSettlementDecisionEnum = {}));
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Qué pasó con el equipo al liquidarse el crédito. El verbo es Release, terminal: el equipo SALE
3
+ * del enrolamiento, no se queda desbloqueado.
4
+ * @enum {string}
5
+ */
6
+ export declare enum CreditSettlementReleaseDecisionEnum {
7
+ CREDIT_NOT_FOUND = "CREDIT_NOT_FOUND",
8
+ /** El crédito no está liquidado: liberar el equipo sería irreversible y prematuro. */
9
+ CREDIT_NOT_SETTLED = "CREDIT_NOT_SETTLED",
10
+ NOT_ENROLLED = "NOT_ENROLLED",
11
+ /** El expediente ya salió del MDM; la liberación es idempotente y no vuelve a salir. */
12
+ ALREADY_RELEASED = "ALREADY_RELEASED",
13
+ RELEASED = "RELEASED",
14
+ /** El proveedor aceptó la liberación y todavía no la dio por hecha. */
15
+ RELEASE_PENDING = "RELEASE_PENDING",
16
+ RELEASE_FAILED = "RELEASE_FAILED"
17
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CreditSettlementReleaseDecisionEnum = void 0;
4
+ /**
5
+ * Qué pasó con el equipo al liquidarse el crédito. El verbo es Release, terminal: el equipo SALE
6
+ * del enrolamiento, no se queda desbloqueado.
7
+ * @enum {string}
8
+ */
9
+ var CreditSettlementReleaseDecisionEnum;
10
+ (function (CreditSettlementReleaseDecisionEnum) {
11
+ CreditSettlementReleaseDecisionEnum["CREDIT_NOT_FOUND"] = "CREDIT_NOT_FOUND";
12
+ /** El crédito no está liquidado: liberar el equipo sería irreversible y prematuro. */
13
+ CreditSettlementReleaseDecisionEnum["CREDIT_NOT_SETTLED"] = "CREDIT_NOT_SETTLED";
14
+ CreditSettlementReleaseDecisionEnum["NOT_ENROLLED"] = "NOT_ENROLLED";
15
+ /** El expediente ya salió del MDM; la liberación es idempotente y no vuelve a salir. */
16
+ CreditSettlementReleaseDecisionEnum["ALREADY_RELEASED"] = "ALREADY_RELEASED";
17
+ CreditSettlementReleaseDecisionEnum["RELEASED"] = "RELEASED";
18
+ /** El proveedor aceptó la liberación y todavía no la dio por hecha. */
19
+ CreditSettlementReleaseDecisionEnum["RELEASE_PENDING"] = "RELEASE_PENDING";
20
+ CreditSettlementReleaseDecisionEnum["RELEASE_FAILED"] = "RELEASE_FAILED";
21
+ })(CreditSettlementReleaseDecisionEnum || (exports.CreditSettlementReleaseDecisionEnum = CreditSettlementReleaseDecisionEnum = {}));
@@ -17,6 +17,14 @@ export * from './dtos/requests/OriginateLoanCreditRequest';
17
17
  export * from './dtos/requests/QuoteLoanCreditRequest';
18
18
  export * from './dtos/requests/SignLoanCreditRequest';
19
19
  export * from './dtos/requests/ActivationCheckRequest';
20
+ export * from './dtos/requests/CreditPaymentAppliedRequest';
21
+ export * from './dtos/requests/CreditSettledRequest';
22
+ export * from './dtos/responses/CreditPaymentAppliedResponse';
23
+ export * from './dtos/responses/CreditSettledResponse';
24
+ export * from './enums/CreditPaymentUnlockDecisionEnum';
25
+ export * from './enums/CreditSettlementDecisionEnum';
26
+ export * from './enums/CreditSettlementReleaseDecisionEnum';
27
+ export * from './constants/creditPaymentHook';
20
28
  export * from './dtos/requests/ChangeLoanCreditStatusRequest';
21
29
  export * from './dtos/responses/LoanBorrowerResponse';
22
30
  export * from './dtos/responses/LoanCreditResponse';
@@ -39,6 +39,14 @@ __exportStar(require("./dtos/requests/OriginateLoanCreditRequest"), exports);
39
39
  __exportStar(require("./dtos/requests/QuoteLoanCreditRequest"), exports);
40
40
  __exportStar(require("./dtos/requests/SignLoanCreditRequest"), exports);
41
41
  __exportStar(require("./dtos/requests/ActivationCheckRequest"), exports);
42
+ __exportStar(require("./dtos/requests/CreditPaymentAppliedRequest"), exports);
43
+ __exportStar(require("./dtos/requests/CreditSettledRequest"), exports);
44
+ __exportStar(require("./dtos/responses/CreditPaymentAppliedResponse"), exports);
45
+ __exportStar(require("./dtos/responses/CreditSettledResponse"), exports);
46
+ __exportStar(require("./enums/CreditPaymentUnlockDecisionEnum"), exports);
47
+ __exportStar(require("./enums/CreditSettlementDecisionEnum"), exports);
48
+ __exportStar(require("./enums/CreditSettlementReleaseDecisionEnum"), exports);
49
+ __exportStar(require("./constants/creditPaymentHook"), exports);
42
50
  __exportStar(require("./dtos/requests/ChangeLoanCreditStatusRequest"), exports);
43
51
  // Response DTOs
44
52
  __exportStar(require("./dtos/responses/LoanBorrowerResponse"), exports);
@@ -5,15 +5,14 @@ export declare class DeviceNotifyRequest {
5
5
  intensity: DeviceNotifyIntensityEnum;
6
6
  /**
7
7
  * Id agnóstico del aviso; cada connector lo traduce a lo que su proveedor entiende.
8
- * Los connectors lo van a preferir sobre `notificationCode`/`title`/`content`;
9
- * hasta entonces esos tres siguen siendo la fuente.
8
+ * Cuando viaja, manda: los connectors ignoran `notificationCode`, `title` y `content`.
10
9
  */
11
10
  noticeType?: MdmNoticeTypeEnum;
12
- /** Código de notificación del catálogo de Datacultr. Queda por compatibilidad durante la migración a `noticeType`. */
13
- notificationCode: string;
14
- /** Título crudo que exige Trustonic. Queda por compatibilidad durante la migración a `noticeType`. */
15
- title: string;
16
- /** Cuerpo crudo que exige Trustonic. Queda por compatibilidad durante la migración a `noticeType`. */
17
- content: string;
11
+ /** Código del catálogo de Datacultr. Camino legacy: solo se lee si no viaja `noticeType`. */
12
+ notificationCode?: string;
13
+ /** Título crudo para Trustonic. Camino legacy: solo se lee si no viaja `noticeType`. */
14
+ title?: string;
15
+ /** Cuerpo crudo para Trustonic. Camino legacy: solo se lee si no viaja `noticeType`. */
16
+ content?: string;
18
17
  operationReference: string;
19
18
  }
@@ -36,18 +36,21 @@ __decorate([
36
36
  ], DeviceNotifyRequest.prototype, "noticeType", void 0);
37
37
  __decorate([
38
38
  (0, class_transformer_1.Expose)(),
39
+ (0, class_validator_1.IsOptional)(),
39
40
  (0, class_validator_1.IsString)(),
40
41
  (0, class_validator_1.IsNotEmpty)(),
41
42
  __metadata("design:type", String)
42
43
  ], DeviceNotifyRequest.prototype, "notificationCode", void 0);
43
44
  __decorate([
44
45
  (0, class_transformer_1.Expose)(),
46
+ (0, class_validator_1.IsOptional)(),
45
47
  (0, class_validator_1.IsString)(),
46
48
  (0, class_validator_1.IsNotEmpty)(),
47
49
  __metadata("design:type", String)
48
50
  ], DeviceNotifyRequest.prototype, "title", void 0);
49
51
  __decorate([
50
52
  (0, class_transformer_1.Expose)(),
53
+ (0, class_validator_1.IsOptional)(),
51
54
  (0, class_validator_1.IsString)(),
52
55
  (0, class_validator_1.IsNotEmpty)(),
53
56
  __metadata("design:type", String)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.407.0",
3
+ "version": "3.409.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -0,0 +1,2 @@
1
+ /** Largo máximo del actor y de la referencia de pago de los dos hooks de cobranza del crédito. */
2
+ export const CREDIT_PAYMENT_HOOK_TEXT_MAX_LENGTH = 120;
@@ -6,8 +6,7 @@ import { CREDIT_ID_MESSAGE, CREDIT_ID_PATTERN } from '../constants/CreditIdPatte
6
6
 
7
7
  /**
8
8
  * Ítem de notificación: a qué crédito se le avisa y con qué aviso.
9
- * El aviso viaja como `noticeType`; los tres campos de texto siguen siendo obligatorios porque
10
- * Datacultr usa el código del catálogo y Trustonic el texto crudo.
9
+ * El aviso viaja como `noticeType`; los tres campos de texto son el camino legacy.
11
10
  */
12
11
  export class LoanDeviceNotifyItem {
13
12
  @Expose()
@@ -20,32 +19,34 @@ export class LoanDeviceNotifyItem {
20
19
 
21
20
  /**
22
21
  * Id agnóstico del aviso; cada connector lo traduce a lo que su proveedor entiende.
23
- * Los connectors lo van a preferir sobre `notificationCode`/`title`/`content`;
24
- * hasta entonces esos tres siguen siendo la fuente.
22
+ * Cuando viaja, manda: los connectors ignoran `notificationCode`, `title` y `content`.
25
23
  */
26
24
  @Expose()
27
25
  @IsOptional()
28
26
  @IsEnum(MdmNoticeTypeEnum)
29
27
  noticeType?: MdmNoticeTypeEnum;
30
28
 
31
- /** Código de notificación del catálogo de Datacultr. Queda por compatibilidad durante la migración a `noticeType`. */
29
+ /** Código del catálogo de Datacultr. Camino legacy: solo se lee si no viaja `noticeType`. */
32
30
  @Expose()
31
+ @IsOptional()
33
32
  @IsString()
34
33
  @IsNotEmpty()
35
34
  @MaxLength(64)
36
- notificationCode: string;
35
+ notificationCode?: string;
37
36
 
38
- /** Título crudo que exige Trustonic. Queda por compatibilidad durante la migración a `noticeType`. */
37
+ /** Título crudo para Trustonic. Camino legacy: solo se lee si no viaja `noticeType`. */
39
38
  @Expose()
39
+ @IsOptional()
40
40
  @IsString()
41
41
  @IsNotEmpty()
42
42
  @MaxLength(128)
43
- title: string;
43
+ title?: string;
44
44
 
45
- /** Cuerpo crudo que exige Trustonic. Queda por compatibilidad durante la migración a `noticeType`. */
45
+ /** Cuerpo crudo para Trustonic. Camino legacy: solo se lee si no viaja `noticeType`. */
46
46
  @Expose()
47
+ @IsOptional()
47
48
  @IsString()
48
49
  @IsNotEmpty()
49
50
  @MaxLength(1024)
50
- content: string;
51
+ content?: string;
51
52
  }
@@ -0,0 +1,25 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-validator';
3
+ import { CREDIT_PAYMENT_HOOK_TEXT_MAX_LENGTH } from '../../constants/creditPaymentHook';
4
+
5
+ /**
6
+ * Body de `POST /private/credits/:creditId/payment-applied` (loan-credit-business). Es OPCIONAL:
7
+ * sin él el pago se atribuye al sistema. `paymentReference` es sólo trazabilidad — no decide nada.
8
+ */
9
+ export class CreditPaymentAppliedRequest {
10
+ /** Quién aplicó el pago; queda en la bitácora del expediente. */
11
+ @Expose()
12
+ @IsOptional()
13
+ @IsString()
14
+ @IsNotEmpty()
15
+ @MaxLength(CREDIT_PAYMENT_HOOK_TEXT_MAX_LENGTH)
16
+ actor?: string;
17
+
18
+ /** Referencia del pago en el sistema que lo aplicó. Sólo trazabilidad. */
19
+ @Expose()
20
+ @IsOptional()
21
+ @IsString()
22
+ @IsNotEmpty()
23
+ @MaxLength(CREDIT_PAYMENT_HOOK_TEXT_MAX_LENGTH)
24
+ paymentReference?: string;
25
+ }
@@ -0,0 +1,25 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-validator';
3
+ import { CREDIT_PAYMENT_HOOK_TEXT_MAX_LENGTH } from '../../constants/creditPaymentHook';
4
+
5
+ /**
6
+ * Body de `POST /private/credits/:creditId/settled` (loan-credit-business). También opcional.
7
+ * La ruta VERIFICA que el crédito no deba nada: no le cree al caller.
8
+ */
9
+ export class CreditSettledRequest {
10
+ /** Quién declaró la liquidación; queda en la bitácora del expediente. */
11
+ @Expose()
12
+ @IsOptional()
13
+ @IsString()
14
+ @IsNotEmpty()
15
+ @MaxLength(CREDIT_PAYMENT_HOOK_TEXT_MAX_LENGTH)
16
+ actor?: string;
17
+
18
+ /** Referencia del pago que liquidó. Sólo trazabilidad. */
19
+ @Expose()
20
+ @IsOptional()
21
+ @IsString()
22
+ @IsNotEmpty()
23
+ @MaxLength(CREDIT_PAYMENT_HOOK_TEXT_MAX_LENGTH)
24
+ paymentReference?: string;
25
+ }
@@ -0,0 +1,9 @@
1
+ import { CreditPaymentUnlockDecisionEnum } from '../../enums/CreditPaymentUnlockDecisionEnum';
2
+
3
+ /** Resultado de aplicar un pago: el crédito sale de mora y el equipo se suelta si corresponde. */
4
+ export interface CreditPaymentAppliedResponse {
5
+ creditId: string;
6
+ /** El crédito salió de mora. Pasa aunque no haya equipo, esté sin candado, o sea SCHEDULED. */
7
+ creditReactivated: boolean;
8
+ unlockDecision: CreditPaymentUnlockDecisionEnum;
9
+ }
@@ -0,0 +1,9 @@
1
+ import { CreditSettlementDecisionEnum } from '../../enums/CreditSettlementDecisionEnum';
2
+ import { CreditSettlementReleaseDecisionEnum } from '../../enums/CreditSettlementReleaseDecisionEnum';
3
+
4
+ /** Resultado de liquidar el crédito; `releaseDecision` es null si el equipo no salió al proveedor. */
5
+ export interface CreditSettledResponse {
6
+ creditId: string;
7
+ settlementDecision: CreditSettlementDecisionEnum;
8
+ releaseDecision: CreditSettlementReleaseDecisionEnum | null;
9
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Qué pasó con el equipo cuando se aplicó un pago al crédito.
3
+ * @enum {string}
4
+ */
5
+ export enum CreditPaymentUnlockDecisionEnum {
6
+ CREDIT_NOT_FOUND = 'CREDIT_NOT_FOUND',
7
+ /** El crédito no está en un estado al que el pago le suelte el equipo. */
8
+ CREDIT_NOT_UNLOCKABLE = 'CREDIT_NOT_UNLOCKABLE',
9
+ NOT_ENROLLED = 'NOT_ENROLLED',
10
+ /** El equipo no estaba bloqueado: no hay nada que soltar. */
11
+ NOT_LOCKED = 'NOT_LOCKED',
12
+ /** El candado no es el de la mora (fraude, manual, o sin motivo): un pago no lo suelta. */
13
+ LOCKED_FOR_OTHER_REASON = 'LOCKED_FOR_OTHER_REASON',
14
+ /** El pago no alcanzó el umbral escalonado: sigue bloqueado y no se reprograma nada. */
15
+ THRESHOLD_NOT_MET = 'THRESHOLD_NOT_MET',
16
+ UNLOCKED = 'UNLOCKED',
17
+ /** El proveedor aceptó la orden y todavía no la dio por hecha. */
18
+ UNLOCK_PENDING = 'UNLOCK_PENDING',
19
+ UNLOCK_FAILED = 'UNLOCK_FAILED',
20
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Qué pasó al intentar dejar el crédito liquidado. La ruta VERIFICA el saldo, no cree al caller.
3
+ * @enum {string}
4
+ */
5
+ export enum CreditSettlementDecisionEnum {
6
+ CREDIT_NOT_FOUND = 'CREDIT_NOT_FOUND',
7
+ /** Ya estaba liquidado: la ruta es idempotente y la liberación corre igual. */
8
+ ALREADY_SETTLED = 'ALREADY_SETTLED',
9
+ /** El estado del crédito no admite liquidación (sólo ACTIVE e IN_ARREARS la admiten). */
10
+ CREDIT_NOT_SETTLEABLE = 'CREDIT_NOT_SETTLEABLE',
11
+ /** Sin plan de cuotas no hay evidencia de que deba cero; fail-closed. */
12
+ NO_INSTALLMENTS = 'NO_INSTALLMENTS',
13
+ /** Al plan le falta alguna cuota del plazo: la deuda que no se persistió no se puede saldar. */
14
+ INCOMPLETE_PLAN = 'INCOMPLETE_PLAN',
15
+ /** Alguna cuota sigue debiendo: liquidar acá liberaría un equipo con deuda viva. */
16
+ BALANCE_OUTSTANDING = 'BALANCE_OUTSTANDING',
17
+ SETTLED = 'SETTLED',
18
+ /** Otro movió el estado entre la lectura y la escritura; el caller relee y reintenta. */
19
+ SETTLE_CONFLICT = 'SETTLE_CONFLICT',
20
+ SETTLE_FAILED = 'SETTLE_FAILED',
21
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Qué pasó con el equipo al liquidarse el crédito. El verbo es Release, terminal: el equipo SALE
3
+ * del enrolamiento, no se queda desbloqueado.
4
+ * @enum {string}
5
+ */
6
+ export enum CreditSettlementReleaseDecisionEnum {
7
+ CREDIT_NOT_FOUND = 'CREDIT_NOT_FOUND',
8
+ /** El crédito no está liquidado: liberar el equipo sería irreversible y prematuro. */
9
+ CREDIT_NOT_SETTLED = 'CREDIT_NOT_SETTLED',
10
+ NOT_ENROLLED = 'NOT_ENROLLED',
11
+ /** El expediente ya salió del MDM; la liberación es idempotente y no vuelve a salir. */
12
+ ALREADY_RELEASED = 'ALREADY_RELEASED',
13
+ RELEASED = 'RELEASED',
14
+ /** El proveedor aceptó la liberación y todavía no la dio por hecha. */
15
+ RELEASE_PENDING = 'RELEASE_PENDING',
16
+ RELEASE_FAILED = 'RELEASE_FAILED',
17
+ }
@@ -23,6 +23,14 @@ export * from './dtos/requests/OriginateLoanCreditRequest';
23
23
  export * from './dtos/requests/QuoteLoanCreditRequest';
24
24
  export * from './dtos/requests/SignLoanCreditRequest';
25
25
  export * from './dtos/requests/ActivationCheckRequest';
26
+ export * from './dtos/requests/CreditPaymentAppliedRequest';
27
+ export * from './dtos/requests/CreditSettledRequest';
28
+ export * from './dtos/responses/CreditPaymentAppliedResponse';
29
+ export * from './dtos/responses/CreditSettledResponse';
30
+ export * from './enums/CreditPaymentUnlockDecisionEnum';
31
+ export * from './enums/CreditSettlementDecisionEnum';
32
+ export * from './enums/CreditSettlementReleaseDecisionEnum';
33
+ export * from './constants/creditPaymentHook';
26
34
  export * from './dtos/requests/ChangeLoanCreditStatusRequest';
27
35
 
28
36
  // Response DTOs
@@ -15,31 +15,33 @@ export class DeviceNotifyRequest {
15
15
 
16
16
  /**
17
17
  * Id agnóstico del aviso; cada connector lo traduce a lo que su proveedor entiende.
18
- * Los connectors lo van a preferir sobre `notificationCode`/`title`/`content`;
19
- * hasta entonces esos tres siguen siendo la fuente.
18
+ * Cuando viaja, manda: los connectors ignoran `notificationCode`, `title` y `content`.
20
19
  */
21
20
  @Expose()
22
21
  @IsOptional()
23
22
  @IsEnum(MdmNoticeTypeEnum)
24
23
  noticeType?: MdmNoticeTypeEnum;
25
24
 
26
- /** Código de notificación del catálogo de Datacultr. Queda por compatibilidad durante la migración a `noticeType`. */
25
+ /** Código del catálogo de Datacultr. Camino legacy: solo se lee si no viaja `noticeType`. */
27
26
  @Expose()
27
+ @IsOptional()
28
28
  @IsString()
29
29
  @IsNotEmpty()
30
- notificationCode: string;
30
+ notificationCode?: string;
31
31
 
32
- /** Título crudo que exige Trustonic. Queda por compatibilidad durante la migración a `noticeType`. */
32
+ /** Título crudo para Trustonic. Camino legacy: solo se lee si no viaja `noticeType`. */
33
33
  @Expose()
34
+ @IsOptional()
34
35
  @IsString()
35
36
  @IsNotEmpty()
36
- title: string;
37
+ title?: string;
37
38
 
38
- /** Cuerpo crudo que exige Trustonic. Queda por compatibilidad durante la migración a `noticeType`. */
39
+ /** Cuerpo crudo para Trustonic. Camino legacy: solo se lee si no viaja `noticeType`. */
39
40
  @Expose()
41
+ @IsOptional()
40
42
  @IsString()
41
43
  @IsNotEmpty()
42
- content: string;
44
+ content?: string;
43
45
 
44
46
  @Expose()
45
47
  @IsString()