@fiado/type-kit 3.572.0 → 3.574.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.
@@ -56,3 +56,25 @@ describe('population DTOs', () => {
56
56
  expect(Object.keys(Rules.PopulationExecutionStatusEnum)).toEqual(['RUNNING', 'SUCCEEDED', 'FAILED', 'CANCELLED']);
57
57
  });
58
58
  });
59
+
60
+ describe('rutas de columna (SEGMENT_COLUMN_PATH_PATTERN)', () => {
61
+ const colCond = (column: string) => ({ kind: 'COLUMN', table: 'riskprofile', column, op: 'GT', value: 1 });
62
+ it.each(['score', 'riskfactors.income.value', 'a.b.c.d.e.f.g.h'])('column "%s" válida -> 0 errores', async (column) => {
63
+ expect(await errorsOf(Rules.SegmentColumnCondition, colCond(column))).toBe(0);
64
+ });
65
+ it.each(['a.b.c.d.e.f.g.h.i', 'Riskfactors.income', 'a..b', 'a.', '.a', 'a.1b', 'a-b.c'])('column "%s" inválida -> error', async (column) => {
66
+ expect(await errorsOf(Rules.SegmentColumnCondition, colCond(column))).toBeGreaterThan(0);
67
+ });
68
+ it('table con punto sigue inválida', async () => {
69
+ expect(await errorsOf(Rules.SegmentColumnCondition, { ...colCond('score'), table: 'a.b' })).toBeGreaterThan(0);
70
+ });
71
+ it('dateColumn anidada válida y SEGMENT_MAX_PATH_DEPTH = 8', async () => {
72
+ expect(await errorsOf(Rules.SegmentWindow, { dateColumn: 'riskfactors.income.evaluationat', days: 30 })).toBe(0);
73
+ expect(Rules.SEGMENT_MAX_PATH_DEPTH).toBe(8);
74
+ });
75
+ it('aggregate column anidada válida', async () => {
76
+ const agg = { kind: 'AGGREGATE', table: 'tx', fn: 'SUM', column: 'a.b.c', op: 'GT', value: 1 };
77
+ const errs = await validate(plainToInstance(Rules.SegmentAggregateCondition, agg, { excludeExtraneousValues: true }));
78
+ expect(errs.filter((e) => e.property === 'column')).toHaveLength(0);
79
+ });
80
+ });
@@ -395,6 +395,26 @@ export interface MyCommissionsTotals {
395
395
  unitsCount: number;
396
396
  netCents: number;
397
397
  }
398
+ /**
399
+ * Lo que un cierre todavía abierto va a mover en el saldo del vendedor, calculado al momento con la
400
+ * misma cuenta del cierre: cada venta con el «Cuándo se paga» de su plan, menos lo ya acreditado al
401
+ * momento, más los ajustes del corte.
402
+ */
403
+ export interface MyCommissionsUpcomingCut {
404
+ periodId: string;
405
+ periodStart: string;
406
+ periodEnd: string;
407
+ /** Día del cierre en México (`yyyy-mm-dd`): el lunes siguiente al domingo del corte. */
408
+ cutDate: string;
409
+ /** Lo que el cierre deja por depositar; negativo si descuenta. */
410
+ payableCents: number;
411
+ /** De `payableCents`, lo que viene de ajustes del corte. */
412
+ adjustmentsCents: number;
413
+ /** Lo que el cierre retiene hasta el día 1. */
414
+ retainedCents: number;
415
+ /** Día en que se libera lo retenido (`yyyy-mm-dd`); `null` si no retiene. */
416
+ releaseDate: string | null;
417
+ }
398
418
  /**
399
419
  * `GET /commissions/me?weeks=` — las comisiones del vendedor que llama. El vendedor sale del token;
400
420
  * no se puede pedir el de otro.
@@ -412,6 +432,11 @@ export interface GetMyCommissionsResponse {
412
432
  };
413
433
  /** El corte en curso; `null` si todavía no tiene ventas, renta ni ajustes. */
414
434
  week: CommissionSellerBreakdown | null;
435
+ /**
436
+ * Los cierres pendientes con algo que mover: el del corte anterior si todavía no cierra y el del
437
+ * corte en curso, del más próximo al más lejano. Ausente en motores anteriores.
438
+ */
439
+ upcomingCuts?: MyCommissionsUpcomingCut[];
415
440
  /** Cortes cuya semana empieza en el mes de hoy: cerrados, el anterior aún sin cerrar y el en curso. */
416
441
  month: MyCommissionsTotals;
417
442
  /** Cortes cuya semana empieza en el año de hoy: cerrados, el anterior aún sin cerrar y el en curso. */
@@ -1,5 +1,8 @@
1
1
  /** Identificador SQL permitido para tabla/columna (A§4.3 paso 1): minusculas, digitos y guion bajo; nunca texto libre. */
2
2
  export declare const SEGMENT_IDENTIFIER_PATTERN: RegExp;
3
+ /** Ruta a una hoja de columna struct de Glue (`riskfactors.income.value`): segmentos separados por punto, maximo SEGMENT_MAX_PATH_DEPTH. Una columna plana es una ruta de 1 segmento. */
4
+ export declare const SEGMENT_COLUMN_PATH_PATTERN: RegExp;
5
+ export declare const SEGMENT_MAX_PATH_DEPTH = 8;
3
6
  export declare const SEGMENT_MAX_DAYS = 365;
4
7
  export declare const SEGMENT_MAX_PARAMS = 40;
5
8
  export declare const SEGMENT_MAX_AGGREGATES = 8;
@@ -1,8 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SEGMENT_MAX_AGGREGATES = exports.SEGMENT_MAX_PARAMS = exports.SEGMENT_MAX_DAYS = exports.SEGMENT_IDENTIFIER_PATTERN = void 0;
3
+ exports.SEGMENT_MAX_AGGREGATES = exports.SEGMENT_MAX_PARAMS = exports.SEGMENT_MAX_DAYS = exports.SEGMENT_MAX_PATH_DEPTH = exports.SEGMENT_COLUMN_PATH_PATTERN = exports.SEGMENT_IDENTIFIER_PATTERN = void 0;
4
4
  /** Identificador SQL permitido para tabla/columna (A§4.3 paso 1): minusculas, digitos y guion bajo; nunca texto libre. */
5
5
  exports.SEGMENT_IDENTIFIER_PATTERN = /^[a-z_][a-z0-9_]*$/;
6
+ /** Ruta a una hoja de columna struct de Glue (`riskfactors.income.value`): segmentos separados por punto, maximo SEGMENT_MAX_PATH_DEPTH. Una columna plana es una ruta de 1 segmento. */
7
+ exports.SEGMENT_COLUMN_PATH_PATTERN = /^[a-z_][a-z0-9_]*(\.[a-z_][a-z0-9_]*){0,7}$/;
8
+ exports.SEGMENT_MAX_PATH_DEPTH = 8;
6
9
  exports.SEGMENT_MAX_DAYS = 365;
7
10
  exports.SEGMENT_MAX_PARAMS = 40;
8
11
  exports.SEGMENT_MAX_AGGREGATES = 8;
@@ -40,7 +40,7 @@ __decorate([
40
40
  __decorate([
41
41
  (0, class_transformer_1.Expose)(),
42
42
  (0, class_validator_1.IsOptional)(),
43
- (0, class_validator_1.Matches)(SegmentLimits_1.SEGMENT_IDENTIFIER_PATTERN),
43
+ (0, class_validator_1.Matches)(SegmentLimits_1.SEGMENT_COLUMN_PATH_PATTERN),
44
44
  __metadata("design:type", String)
45
45
  ], SegmentAggregateCondition.prototype, "column", void 0);
46
46
  __decorate([
@@ -31,7 +31,7 @@ __decorate([
31
31
  ], SegmentColumnCondition.prototype, "table", void 0);
32
32
  __decorate([
33
33
  (0, class_transformer_1.Expose)(),
34
- (0, class_validator_1.Matches)(SegmentLimits_1.SEGMENT_IDENTIFIER_PATTERN),
34
+ (0, class_validator_1.Matches)(SegmentLimits_1.SEGMENT_COLUMN_PATH_PATTERN),
35
35
  __metadata("design:type", String)
36
36
  ], SegmentColumnCondition.prototype, "column", void 0);
37
37
  __decorate([
@@ -1,6 +1,8 @@
1
1
  import { SegmentOperatorEnum } from '../../enums/SegmentOperatorEnum';
2
2
  export declare class SegmentColumnSchemaResponse {
3
3
  name: string;
4
+ /** Columna raiz de Glue cuando `name` es una ruta a una hoja de struct (agrupa en la UI). */
5
+ root?: string;
4
6
  type: string;
5
7
  isDate: boolean;
6
8
  operators: SegmentOperatorEnum[];
@@ -19,7 +19,7 @@ class SegmentWindow {
19
19
  exports.SegmentWindow = SegmentWindow;
20
20
  __decorate([
21
21
  (0, class_transformer_1.Expose)(),
22
- (0, class_validator_1.Matches)(SegmentLimits_1.SEGMENT_IDENTIFIER_PATTERN),
22
+ (0, class_validator_1.Matches)(SegmentLimits_1.SEGMENT_COLUMN_PATH_PATTERN),
23
23
  __metadata("design:type", String)
24
24
  ], SegmentWindow.prototype, "dateColumn", void 0);
25
25
  __decorate([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.572.0",
3
+ "version": "3.574.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -476,6 +476,27 @@ export interface MyCommissionsTotals {
476
476
  netCents: number;
477
477
  }
478
478
 
479
+ /**
480
+ * Lo que un cierre todavía abierto va a mover en el saldo del vendedor, calculado al momento con la
481
+ * misma cuenta del cierre: cada venta con el «Cuándo se paga» de su plan, menos lo ya acreditado al
482
+ * momento, más los ajustes del corte.
483
+ */
484
+ export interface MyCommissionsUpcomingCut {
485
+ periodId: string;
486
+ periodStart: string;
487
+ periodEnd: string;
488
+ /** Día del cierre en México (`yyyy-mm-dd`): el lunes siguiente al domingo del corte. */
489
+ cutDate: string;
490
+ /** Lo que el cierre deja por depositar; negativo si descuenta. */
491
+ payableCents: number;
492
+ /** De `payableCents`, lo que viene de ajustes del corte. */
493
+ adjustmentsCents: number;
494
+ /** Lo que el cierre retiene hasta el día 1. */
495
+ retainedCents: number;
496
+ /** Día en que se libera lo retenido (`yyyy-mm-dd`); `null` si no retiene. */
497
+ releaseDate: string | null;
498
+ }
499
+
479
500
  /**
480
501
  * `GET /commissions/me?weeks=` — las comisiones del vendedor que llama. El vendedor sale del token;
481
502
  * no se puede pedir el de otro.
@@ -485,6 +506,11 @@ export interface GetMyCommissionsResponse {
485
506
  period: { periodId: string; periodStart: string; periodEnd: string };
486
507
  /** El corte en curso; `null` si todavía no tiene ventas, renta ni ajustes. */
487
508
  week: CommissionSellerBreakdown | null;
509
+ /**
510
+ * Los cierres pendientes con algo que mover: el del corte anterior si todavía no cierra y el del
511
+ * corte en curso, del más próximo al más lejano. Ausente en motores anteriores.
512
+ */
513
+ upcomingCuts?: MyCommissionsUpcomingCut[];
488
514
  /** Cortes cuya semana empieza en el mes de hoy: cerrados, el anterior aún sin cerrar y el en curso. */
489
515
  month: MyCommissionsTotals;
490
516
  /** Cortes cuya semana empieza en el año de hoy: cerrados, el anterior aún sin cerrar y el en curso. */
@@ -1,5 +1,8 @@
1
1
  /** Identificador SQL permitido para tabla/columna (A§4.3 paso 1): minusculas, digitos y guion bajo; nunca texto libre. */
2
2
  export const SEGMENT_IDENTIFIER_PATTERN = /^[a-z_][a-z0-9_]*$/;
3
+ /** Ruta a una hoja de columna struct de Glue (`riskfactors.income.value`): segmentos separados por punto, maximo SEGMENT_MAX_PATH_DEPTH. Una columna plana es una ruta de 1 segmento. */
4
+ export const SEGMENT_COLUMN_PATH_PATTERN = /^[a-z_][a-z0-9_]*(\.[a-z_][a-z0-9_]*){0,7}$/;
5
+ export const SEGMENT_MAX_PATH_DEPTH = 8;
3
6
  export const SEGMENT_MAX_DAYS = 365;
4
7
  export const SEGMENT_MAX_PARAMS = 40;
5
8
  export const SEGMENT_MAX_AGGREGATES = 8;
@@ -1,6 +1,6 @@
1
1
  import { Expose, Type } from 'class-transformer';
2
2
  import { ArrayMaxSize, Equals, IsArray, IsEnum, IsNumber, IsOptional, Matches, ValidateNested } from 'class-validator';
3
- import { SEGMENT_IDENTIFIER_PATTERN } from '../../constants/SegmentLimits';
3
+ import { SEGMENT_COLUMN_PATH_PATTERN, SEGMENT_IDENTIFIER_PATTERN } from '../../constants/SegmentLimits';
4
4
  import { SegmentAggregateFnEnum } from '../../enums/SegmentAggregateFnEnum';
5
5
  import { SegmentConditionKindEnum } from '../../enums/SegmentConditionKindEnum';
6
6
  import { SegmentOperatorEnum } from '../../enums/SegmentOperatorEnum';
@@ -13,7 +13,7 @@ export class SegmentAggregateCondition {
13
13
  @Expose() @Matches(SEGMENT_IDENTIFIER_PATTERN) table: string;
14
14
  @Expose() @IsEnum(SegmentAggregateFnEnum) fn: SegmentAggregateFnEnum;
15
15
  /** Solo SUM. */
16
- @Expose() @IsOptional() @Matches(SEGMENT_IDENTIFIER_PATTERN) column?: string;
16
+ @Expose() @IsOptional() @Matches(SEGMENT_COLUMN_PATH_PATTERN) column?: string;
17
17
  /** COUNT y SUM; EXISTS no lleva. */
18
18
  @Expose() @IsOptional() @IsEnum(SegmentOperatorEnum) op?: SegmentOperatorEnum;
19
19
  @Expose() @IsOptional() @IsNumber() value?: number;
@@ -1,7 +1,7 @@
1
1
  import { Expose } from 'class-transformer';
2
2
  import { Equals, IsEnum, IsOptional, Matches } from 'class-validator';
3
3
  import { JsonValue } from '../../../common';
4
- import { SEGMENT_IDENTIFIER_PATTERN } from '../../constants/SegmentLimits';
4
+ import { SEGMENT_COLUMN_PATH_PATTERN, SEGMENT_IDENTIFIER_PATTERN } from '../../constants/SegmentLimits';
5
5
  import { SegmentConditionKindEnum } from '../../enums/SegmentConditionKindEnum';
6
6
  import { SegmentOperatorEnum } from '../../enums/SegmentOperatorEnum';
7
7
 
@@ -9,7 +9,7 @@ import { SegmentOperatorEnum } from '../../enums/SegmentOperatorEnum';
9
9
  export class SegmentColumnCondition {
10
10
  @Expose() @Equals(SegmentConditionKindEnum.COLUMN) kind: SegmentConditionKindEnum.COLUMN;
11
11
  @Expose() @Matches(SEGMENT_IDENTIFIER_PATTERN) table: string;
12
- @Expose() @Matches(SEGMENT_IDENTIFIER_PATTERN) column: string;
12
+ @Expose() @Matches(SEGMENT_COLUMN_PATH_PATTERN) column: string;
13
13
  @Expose() @IsEnum(SegmentOperatorEnum) op: SegmentOperatorEnum;
14
14
  @Expose() @IsOptional() value?: JsonValue;
15
15
  }
@@ -2,6 +2,8 @@ import { SegmentOperatorEnum } from '../../enums/SegmentOperatorEnum';
2
2
 
3
3
  export class SegmentColumnSchemaResponse {
4
4
  name: string;
5
+ /** Columna raiz de Glue cuando `name` es una ruta a una hoja de struct (agrupa en la UI). */
6
+ root?: string;
5
7
  type: string;
6
8
  isDate: boolean;
7
9
  operators: SegmentOperatorEnum[];
@@ -1,9 +1,9 @@
1
1
  import { Expose } from 'class-transformer';
2
2
  import { IsInt, Matches, Max, Min } from 'class-validator';
3
- import { SEGMENT_IDENTIFIER_PATTERN, SEGMENT_MAX_DAYS } from '../../constants/SegmentLimits';
3
+ import { SEGMENT_COLUMN_PATH_PATTERN, SEGMENT_MAX_DAYS } from '../../constants/SegmentLimits';
4
4
 
5
5
  /** Ventana relativa [referenceAt - days, referenceAt) sobre una columna de fecha (A§4.1). */
6
6
  export class SegmentWindow {
7
- @Expose() @Matches(SEGMENT_IDENTIFIER_PATTERN) dateColumn: string;
7
+ @Expose() @Matches(SEGMENT_COLUMN_PATH_PATTERN) dateColumn: string;
8
8
  @Expose() @IsInt() @Min(1) @Max(SEGMENT_MAX_DAYS) days: number;
9
9
  }