@fiado/type-kit 3.329.0 → 3.331.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.
@@ -0,0 +1,30 @@
1
+ name: "Publish to npm"
2
+
3
+ on:
4
+ push:
5
+ branches: [ develop ]
6
+ paths-ignore:
7
+ - '**.md'
8
+ - 'docs/**'
9
+ - '.gitignore'
10
+ - '.npmignore'
11
+ workflow_dispatch:
12
+ inputs:
13
+ dry-run:
14
+ description: 'Corre build, test y npm publish --dry-run sin publicar de verdad'
15
+ required: false
16
+ default: false
17
+ type: boolean
18
+
19
+ concurrency:
20
+ group: npm-publish-${{ github.ref }}
21
+ cancel-in-progress: false
22
+
23
+ jobs:
24
+ publish:
25
+ uses: Fiado-Today/github-workflows/.github/workflows/npm-publish.yml@develop
26
+ permissions:
27
+ contents: write
28
+ with:
29
+ dry-run: ${{ inputs.dry-run == true }}
30
+ secrets: inherit
@@ -0,0 +1,70 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import { GetNearbyPlacesRequest, PlaceTypeEnum } from '../../../src/places/index';
5
+
6
+ /** El request mínimo válido: punto + al menos un tipo. */
7
+ const base = {
8
+ latitude: 19.4326,
9
+ longitude: -99.1332,
10
+ types: [PlaceTypeEnum.CashInMx],
11
+ };
12
+
13
+ const instancia = (raw: Record<string, unknown>): GetNearbyPlacesRequest =>
14
+ plainToInstance(GetNearbyPlacesRequest, raw);
15
+
16
+ /**
17
+ * Mismo modo en que valida el consumidor real (`places-business`): `whitelist: true`.
18
+ * Importa que sea idéntico, ver el test del radio más abajo.
19
+ */
20
+ const propiedadesConError = async (raw: Record<string, unknown>): Promise<string[]> =>
21
+ (await validate(instancia(raw) as object, { whitelist: true })).map((e) => e.property);
22
+
23
+ describe('GetNearbyPlacesRequest', () => {
24
+ it('valida sin radius: el radio es opcional', async () => {
25
+ const dto = instancia(base);
26
+
27
+ expect(await validate(dto as object, { whitelist: true })).toHaveLength(0);
28
+ expect(dto.radius).toBeUndefined();
29
+ });
30
+
31
+ it('valida con radius', async () => {
32
+ const dto = instancia({ ...base, radius: 5 });
33
+
34
+ expect(await validate(dto as object, { whitelist: true })).toHaveLength(0);
35
+ expect(dto.radius).toBe(5);
36
+ });
37
+
38
+ /**
39
+ * El guard que de verdad importa. El consumidor valida con `whitelist: true`, que
40
+ * DESCARTA toda propiedad sin decorador. Si alguien le quita los decoradores a
41
+ * `radius`, este contrato sigue compilando y el lambda pierde el radio en silencio:
42
+ * el mapa se quedaría pidiendo siempre el default. Que falle acá, no en producción.
43
+ */
44
+ it('radius sobrevive al whitelist del validador', async () => {
45
+ const instancia = plainToInstance(GetNearbyPlacesRequest, { ...base, radius: 12 });
46
+
47
+ await validate(instancia as object, { whitelist: true });
48
+
49
+ expect(instancia.radius).toBe(12);
50
+ });
51
+
52
+ it('rechaza un radius que no es positivo', async () => {
53
+ expect(await propiedadesConError({ ...base, radius: 0 })).toContain('radius');
54
+ expect(await propiedadesConError({ ...base, radius: -3 })).toContain('radius');
55
+ });
56
+
57
+ it('rechaza un radius que no es número', async () => {
58
+ expect(await propiedadesConError({ ...base, radius: 'cinco' })).toContain('radius');
59
+ });
60
+
61
+ /** Los campos que ya existían siguen siendo obligatorios: el cambio es aditivo. */
62
+ it('sigue exigiendo punto y tipos', async () => {
63
+ expect(await propiedadesConError({ types: [PlaceTypeEnum.CashInMx] })).toEqual(
64
+ expect.arrayContaining(['latitude', 'longitude']),
65
+ );
66
+ expect(await propiedadesConError({ latitude: 19.4326, longitude: -99.1332, types: [] })).toContain(
67
+ 'types',
68
+ );
69
+ });
70
+ });
@@ -12,11 +12,12 @@ describe('BlockedReasonEnum', () => {
12
12
  });
13
13
 
14
14
  describe('BlockedCategoryEnum', () => {
15
- it('tiene las tres categorias que dicen quien resuelve', () => {
15
+ it('tiene las cuatro categorias que dicen quien resuelve', () => {
16
16
  expect(BlockedCategoryEnum.CUSTOMER_RECORD).toBe('CUSTOMER_RECORD');
17
17
  expect(BlockedCategoryEnum.UNDER_REVIEW).toBe('UNDER_REVIEW');
18
18
  expect(BlockedCategoryEnum.TEMPORARY).toBe('TEMPORARY');
19
- expect(Object.keys(BlockedCategoryEnum)).toHaveLength(3);
19
+ expect(BlockedCategoryEnum.REJECTED).toBe('REJECTED');
20
+ expect(Object.keys(BlockedCategoryEnum)).toHaveLength(4);
20
21
  });
21
22
 
22
23
  it('ningun valor nombra listas de cumplimiento ni PLD', () => {
@@ -12,4 +12,13 @@ export interface ManualApproval {
12
12
  at: string;
13
13
  /** justificación obligatoria del override */
14
14
  reason: string;
15
+ /**
16
+ * Conclusión del oficial. Ausente en los sellos escritos antes de este campo, que solo se
17
+ * estampaban al aprobar: leerlos sin `verdict` equivale a `APPROVED`.
18
+ */
19
+ verdict?: ManualApprovalVerdict;
20
+ /** Alerta de PLD que se dictaminó, para rastrear el sello hasta su expediente. */
21
+ alertId?: string;
15
22
  }
23
+ /** Conclusión del oficial de cumplimiento sobre la lista que revisó. */
24
+ export type ManualApprovalVerdict = 'APPROVED' | 'REJECTED';
@@ -131,6 +131,10 @@ export declare class PeopleResponse {
131
131
  /** Geolocalización aprobada. `null` = no evaluada; solo `false` bloquea. */
132
132
  geoApproved?: boolean | null;
133
133
  cnbvManualApproval?: ManualApproval | null;
134
+ /** Sello del oficial sobre las listas internacionales y PEP (`blackListApproved`). */
135
+ blackListManualApproval?: ManualApproval | null;
136
+ /** Sello del oficial sobre la lista negra interna de Fiado (`fiadoListApproved`). */
137
+ fiadoListManualApproval?: ManualApproval | null;
134
138
  minorManualApproval?: ManualApproval | null;
135
139
  };
136
140
  SIN: string | null;
@@ -55,6 +55,8 @@ export declare class PeopleUpdateRequest {
55
55
  ofacListApproved?: boolean | null;
56
56
  cnbvListApproved?: boolean | null;
57
57
  cnbvManualApproval?: ManualApproval | null;
58
+ blackListManualApproval?: ManualApproval | null;
59
+ fiadoListManualApproval?: ManualApproval | null;
58
60
  minorManualApproval?: ManualApproval | null;
59
61
  blackListApproved?: boolean | null;
60
62
  whiteList?: boolean | null;
@@ -7,4 +7,17 @@ export declare class GetNearbyPlacesRequest {
7
7
  latitude: number;
8
8
  longitude: number;
9
9
  types: PlaceTypeEnum[];
10
+ /**
11
+ * Radio de búsqueda en km.
12
+ *
13
+ * Sólo aplica a los tipos que consultan un directorio EN VIVO del proveedor; los que
14
+ * se sirven de la cache geoespacial lo ignoran, porque su área la fija la resolución
15
+ * de las celdas y no un radio del request.
16
+ *
17
+ * Omitido = el default de quien atiende la búsqueda. No lleva `@Max` acá a propósito:
18
+ * el tope sano depende del proveedor (un directorio que no pagina devuelve miles de
19
+ * tiendas en una sola respuesta), así que lo aplica el lambda que lo consume y no este
20
+ * contrato, que es compartido.
21
+ */
22
+ radius?: number;
10
23
  }
@@ -37,3 +37,9 @@ __decorate([
37
37
  (0, class_validator_1.IsEnum)(PlaceTypeEnum_1.PlaceTypeEnum, { each: true }),
38
38
  __metadata("design:type", Array)
39
39
  ], GetNearbyPlacesRequest.prototype, "types", void 0);
40
+ __decorate([
41
+ (0, class_validator_1.IsOptional)(),
42
+ (0, class_validator_1.IsNumber)(),
43
+ (0, class_validator_1.IsPositive)(),
44
+ __metadata("design:type", Number)
45
+ ], GetNearbyPlacesRequest.prototype, "radius", void 0);
@@ -1,11 +1,25 @@
1
1
  import { EstablishmentDto } from './EstablishmentDto';
2
2
  import { OfficeDto } from '../../offices/dtos/OfficeDto';
3
+ import { FundingStoreItem } from '../../walletFunding/dtos/FundingStoreItem';
3
4
  /**
4
5
  * Respuesta de la búsqueda unificada. Solo se incluyen los tipos pedidos en `types`.
5
6
  */
6
7
  export declare class GetNearbyPlacesResponse {
7
8
  cashInUs?: EstablishmentDto[];
8
9
  cashInMx?: EstablishmentDto[];
10
+ /**
11
+ * Cash-in MX servido por el directorio EN VIVO del proveedor de fondeo, en vez de
12
+ * por la cache geoespacial que alimenta `cashInMx`.
13
+ *
14
+ * Campo aparte a propósito, por dos razones. `FundingStoreItem` trae lo que
15
+ * `EstablishmentDto` no tiene y la app necesita pintar en el pin —comisión de caja,
16
+ * tope por operación, horario, logo—; y es el MISMO tipo que ya comparten el connector
17
+ * y el wallet-app, así que reusarlo evita una tercera declaración del mismo concepto.
18
+ *
19
+ * Cuál de los dos campos se llena lo decide la configuración de ruteo del lambda:
20
+ * viene uno u otro, nunca los dos.
21
+ */
22
+ cashInMxStores?: FundingStoreItem[];
9
23
  officeFiado?: OfficeDto[];
10
24
  storeFiado?: OfficeDto[];
11
25
  }
@@ -11,5 +11,10 @@ export declare enum BlockedCategoryEnum {
11
11
  */
12
12
  UNDER_REVIEW = "UNDER_REVIEW",
13
13
  /** Falla pasajera del proveedor o de la lectura; cede sola cuando el servicio vuelve. */
14
- TEMPORARY = "TEMPORARY"
14
+ TEMPORARY = "TEMPORARY",
15
+ /**
16
+ * Quien revisaba el caso ya resolvió que la cuenta no se abre. Es terminal: nadie la va a
17
+ * destrabar y la venta no continúa. Tampoco dice por qué.
18
+ */
19
+ REJECTED = "REJECTED"
15
20
  }
@@ -16,4 +16,9 @@ var BlockedCategoryEnum;
16
16
  BlockedCategoryEnum["UNDER_REVIEW"] = "UNDER_REVIEW";
17
17
  /** Falla pasajera del proveedor o de la lectura; cede sola cuando el servicio vuelve. */
18
18
  BlockedCategoryEnum["TEMPORARY"] = "TEMPORARY";
19
+ /**
20
+ * Quien revisaba el caso ya resolvió que la cuenta no se abre. Es terminal: nadie la va a
21
+ * destrabar y la venta no continúa. Tampoco dice por qué.
22
+ */
23
+ BlockedCategoryEnum["REJECTED"] = "REJECTED";
19
24
  })(BlockedCategoryEnum || (exports.BlockedCategoryEnum = BlockedCategoryEnum = {}));
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Motivo por el que un cliente quedó como prospecto, filtrados por paso.
3
3
  *
4
- * Los primeros quince son objeciones del CLIENTE y los elige el vendedor. Los dos últimos los pone
4
+ * Los primeros quince son objeciones del CLIENTE y los elige el vendedor. Los tres últimos los pone
5
5
  * el sistema cuando la venta se traba por la cuenta: no se ofrecen en el desplegable ni se editan.
6
6
  * SureKeep Fase 2 — pista Retail.
7
7
  */
@@ -27,7 +27,9 @@ export declare enum PendingReasonEnum {
27
27
  */
28
28
  ACCOUNT_UNDER_REVIEW = "ACCOUNT_UNDER_REVIEW",
29
29
  /** La cuenta no abrió por un dato del expediente o una falla del proveedor. */
30
- ACCOUNT_OPEN_FAILED = "ACCOUNT_OPEN_FAILED"
30
+ ACCOUNT_OPEN_FAILED = "ACCOUNT_OPEN_FAILED",
31
+ /** La revisión terminó y la cuenta no se abre. La venta no continúa. */
32
+ ACCOUNT_REJECTED = "ACCOUNT_REJECTED"
31
33
  }
32
34
  /** Los que pone el sistema al trabarse la venta: no se ofrecen al vendedor ni se pueden editar. */
33
35
  export declare const SYSTEM_PENDING_REASONS: readonly PendingReasonEnum[];
@@ -4,7 +4,7 @@ exports.SYSTEM_PENDING_REASONS = exports.PendingReasonEnum = void 0;
4
4
  /**
5
5
  * Motivo por el que un cliente quedó como prospecto, filtrados por paso.
6
6
  *
7
- * Los primeros quince son objeciones del CLIENTE y los elige el vendedor. Los dos últimos los pone
7
+ * Los primeros quince son objeciones del CLIENTE y los elige el vendedor. Los tres últimos los pone
8
8
  * el sistema cuando la venta se traba por la cuenta: no se ofrecen en el desplegable ni se editan.
9
9
  * SureKeep Fase 2 — pista Retail.
10
10
  */
@@ -32,9 +32,12 @@ var PendingReasonEnum;
32
32
  PendingReasonEnum["ACCOUNT_UNDER_REVIEW"] = "ACCOUNT_UNDER_REVIEW";
33
33
  /** La cuenta no abrió por un dato del expediente o una falla del proveedor. */
34
34
  PendingReasonEnum["ACCOUNT_OPEN_FAILED"] = "ACCOUNT_OPEN_FAILED";
35
+ /** La revisión terminó y la cuenta no se abre. La venta no continúa. */
36
+ PendingReasonEnum["ACCOUNT_REJECTED"] = "ACCOUNT_REJECTED";
35
37
  })(PendingReasonEnum || (exports.PendingReasonEnum = PendingReasonEnum = {}));
36
38
  /** Los que pone el sistema al trabarse la venta: no se ofrecen al vendedor ni se pueden editar. */
37
39
  exports.SYSTEM_PENDING_REASONS = [
38
40
  PendingReasonEnum.ACCOUNT_UNDER_REVIEW,
39
41
  PendingReasonEnum.ACCOUNT_OPEN_FAILED,
42
+ PendingReasonEnum.ACCOUNT_REJECTED,
40
43
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.329.0",
3
+ "version": "3.331.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -28,4 +28,4 @@
28
28
  "class-validator": "^0.14.2",
29
29
  "reflect-metadata": "^0.2.2"
30
30
  }
31
- }
31
+ }
@@ -13,4 +13,14 @@ export interface ManualApproval {
13
13
  at: string;
14
14
  /** justificación obligatoria del override */
15
15
  reason: string;
16
+ /**
17
+ * Conclusión del oficial. Ausente en los sellos escritos antes de este campo, que solo se
18
+ * estampaban al aprobar: leerlos sin `verdict` equivale a `APPROVED`.
19
+ */
20
+ verdict?: ManualApprovalVerdict;
21
+ /** Alerta de PLD que se dictaminó, para rastrear el sello hasta su expediente. */
22
+ alertId?: string;
16
23
  }
24
+
25
+ /** Conclusión del oficial de cumplimiento sobre la lista que revisó. */
26
+ export type ManualApprovalVerdict = 'APPROVED' | 'REJECTED';
@@ -137,6 +137,10 @@ export class PeopleResponse {
137
137
  /** Geolocalización aprobada. `null` = no evaluada; solo `false` bloquea. */
138
138
  geoApproved?:boolean | null;
139
139
  cnbvManualApproval?: ManualApproval | null;
140
+ /** Sello del oficial sobre las listas internacionales y PEP (`blackListApproved`). */
141
+ blackListManualApproval?: ManualApproval | null;
142
+ /** Sello del oficial sobre la lista negra interna de Fiado (`fiadoListApproved`). */
143
+ fiadoListManualApproval?: ManualApproval | null;
140
144
  minorManualApproval?: ManualApproval | null;
141
145
 
142
146
  }
@@ -60,6 +60,8 @@ export class PeopleUpdateRequest {
60
60
  ofacListApproved?: boolean | null;
61
61
  cnbvListApproved?: boolean | null;
62
62
  cnbvManualApproval?: ManualApproval | null;
63
+ blackListManualApproval?: ManualApproval | null;
64
+ fiadoListManualApproval?: ManualApproval | null;
63
65
  minorManualApproval?: ManualApproval | null;
64
66
  blackListApproved?: boolean | null;
65
67
  whiteList?: boolean | null;
@@ -1,4 +1,4 @@
1
- import { ArrayNotEmpty, IsArray, IsEnum, IsNumber, Max, Min } from 'class-validator';
1
+ import { ArrayNotEmpty, IsArray, IsEnum, IsNumber, IsOptional, IsPositive, Max, Min } from 'class-validator';
2
2
  import { PlaceTypeEnum } from '../enums/PlaceTypeEnum';
3
3
 
4
4
  /**
@@ -20,4 +20,21 @@ export class GetNearbyPlacesRequest {
20
20
  @ArrayNotEmpty()
21
21
  @IsEnum(PlaceTypeEnum, { each: true })
22
22
  types: PlaceTypeEnum[];
23
+
24
+ /**
25
+ * Radio de búsqueda en km.
26
+ *
27
+ * Sólo aplica a los tipos que consultan un directorio EN VIVO del proveedor; los que
28
+ * se sirven de la cache geoespacial lo ignoran, porque su área la fija la resolución
29
+ * de las celdas y no un radio del request.
30
+ *
31
+ * Omitido = el default de quien atiende la búsqueda. No lleva `@Max` acá a propósito:
32
+ * el tope sano depende del proveedor (un directorio que no pagina devuelve miles de
33
+ * tiendas en una sola respuesta), así que lo aplica el lambda que lo consume y no este
34
+ * contrato, que es compartido.
35
+ */
36
+ @IsOptional()
37
+ @IsNumber()
38
+ @IsPositive()
39
+ radius?: number;
23
40
  }
@@ -1,5 +1,6 @@
1
1
  import { EstablishmentDto } from './EstablishmentDto';
2
2
  import { OfficeDto } from '../../offices/dtos/OfficeDto';
3
+ import { FundingStoreItem } from '../../walletFunding/dtos/FundingStoreItem';
3
4
 
4
5
  /**
5
6
  * Respuesta de la búsqueda unificada. Solo se incluyen los tipos pedidos en `types`.
@@ -7,6 +8,19 @@ import { OfficeDto } from '../../offices/dtos/OfficeDto';
7
8
  export class GetNearbyPlacesResponse {
8
9
  cashInUs?: EstablishmentDto[];
9
10
  cashInMx?: EstablishmentDto[];
11
+ /**
12
+ * Cash-in MX servido por el directorio EN VIVO del proveedor de fondeo, en vez de
13
+ * por la cache geoespacial que alimenta `cashInMx`.
14
+ *
15
+ * Campo aparte a propósito, por dos razones. `FundingStoreItem` trae lo que
16
+ * `EstablishmentDto` no tiene y la app necesita pintar en el pin —comisión de caja,
17
+ * tope por operación, horario, logo—; y es el MISMO tipo que ya comparten el connector
18
+ * y el wallet-app, así que reusarlo evita una tercera declaración del mismo concepto.
19
+ *
20
+ * Cuál de los dos campos se llena lo decide la configuración de ruteo del lambda:
21
+ * viene uno u otro, nunca los dos.
22
+ */
23
+ cashInMxStores?: FundingStoreItem[];
10
24
  officeFiado?: OfficeDto[];
11
25
  storeFiado?: OfficeDto[];
12
26
  }
@@ -12,4 +12,9 @@ export enum BlockedCategoryEnum {
12
12
  UNDER_REVIEW = 'UNDER_REVIEW',
13
13
  /** Falla pasajera del proveedor o de la lectura; cede sola cuando el servicio vuelve. */
14
14
  TEMPORARY = 'TEMPORARY',
15
+ /**
16
+ * Quien revisaba el caso ya resolvió que la cuenta no se abre. Es terminal: nadie la va a
17
+ * destrabar y la venta no continúa. Tampoco dice por qué.
18
+ */
19
+ REJECTED = 'REJECTED',
15
20
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Motivo por el que un cliente quedó como prospecto, filtrados por paso.
3
3
  *
4
- * Los primeros quince son objeciones del CLIENTE y los elige el vendedor. Los dos últimos los pone
4
+ * Los primeros quince son objeciones del CLIENTE y los elige el vendedor. Los tres últimos los pone
5
5
  * el sistema cuando la venta se traba por la cuenta: no se ofrecen en el desplegable ni se editan.
6
6
  * SureKeep Fase 2 — pista Retail.
7
7
  */
@@ -28,10 +28,13 @@ export enum PendingReasonEnum {
28
28
  ACCOUNT_UNDER_REVIEW = 'ACCOUNT_UNDER_REVIEW',
29
29
  /** La cuenta no abrió por un dato del expediente o una falla del proveedor. */
30
30
  ACCOUNT_OPEN_FAILED = 'ACCOUNT_OPEN_FAILED',
31
+ /** La revisión terminó y la cuenta no se abre. La venta no continúa. */
32
+ ACCOUNT_REJECTED = 'ACCOUNT_REJECTED',
31
33
  }
32
34
 
33
35
  /** Los que pone el sistema al trabarse la venta: no se ofrecen al vendedor ni se pueden editar. */
34
36
  export const SYSTEM_PENDING_REASONS: readonly PendingReasonEnum[] = [
35
37
  PendingReasonEnum.ACCOUNT_UNDER_REVIEW,
36
38
  PendingReasonEnum.ACCOUNT_OPEN_FAILED,
39
+ PendingReasonEnum.ACCOUNT_REJECTED,
37
40
  ] as const;