@fiado/type-kit 3.273.0 → 3.275.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.
@@ -37,6 +37,32 @@ export interface MetricSpecDto {
37
37
  /** Con `COUNT` se acepta `{ column: '*' }`. */
38
38
  column: ColumnRefDto;
39
39
  fn: MetricFnEnum;
40
+ /**
41
+ * Columnas de respaldo, en orden: el backend emite `FN(COALESCE(col, r1, r2…))`.
42
+ *
43
+ * ## Cuándo lo necesitas
44
+ *
45
+ * Cuando el valor que quieres sumar vive en más de una columna según la fila. En
46
+ * `retail_sale`, por ejemplo, el monto está en `amountcents` o en `equipmentpricecents` — no
47
+ * hay una columna `soldcents`.
48
+ *
49
+ * **No se puede resolver del lado del caller.** `SUM(COALESCE(a,b))` NO se reconstruye desde
50
+ * `SUM(a)` y `SUM(b)`: el COALESCE es por fila, así que si unas traen `a` y otras solo `b`,
51
+ * cualquier combinación da un número distinto. O lo hace el motor, o el dato sale mal.
52
+ *
53
+ * ## Por qué es un campo del request y no una columna del lake
54
+ *
55
+ * Una columna calculada en la tabla Iceberg **congelaría la regla de negocio dentro del
56
+ * pipeline de datos**, que es de otro equipo: cambiarla obligaría a redesplegar el pipeline y a
57
+ * rellenar el histórico, y la definición quedaría lejos de la decisión que la gobierna.
58
+ *
59
+ * Así el mecanismo es genérico y **qué columnas encadenar lo decide el dominio dueño de la
60
+ * regla**, en su propio código.
61
+ *
62
+ * ⚠️ Cada respaldo se valida contra el schema vivo de Glue igual que cualquier otra columna.
63
+ * No admite `COUNT(*)`.
64
+ */
65
+ coalesceWith?: ColumnRefDto[];
40
66
  /** Alias de salida. Si no viene, se deriva de la función y la columna. */
41
67
  alias?: string;
42
68
  }
@@ -32,6 +32,8 @@ export interface SaleException {
32
32
  requestedAt: string;
33
33
  /** OBLIGATORIA. Es lo que hace auditable la excepción. */
34
34
  justification: string;
35
+ /** Qué pidió el solicitante, en sus palabras. `null` si no lo detalló. */
36
+ requestedAction: string | null;
35
37
  /**
36
38
  * Impacto económico en centavos, con signo: positivo si la excepción suma (devolución al cliente,
37
39
  * reemplazo), negativo si resta (descuento autorizado). `null` cuando no aplica.
@@ -22,6 +22,25 @@ export declare class CreateSaleExceptionRequest {
22
22
  /** Obligatorio cuando NO hay `saleId`; si hay venta, se toma el de la venta. */
23
23
  storeId?: string;
24
24
  justification: string;
25
+ /**
26
+ * Quién PIDIÓ la excepción, cuando no es quien la registra.
27
+ *
28
+ * El botón «Levantar excepción» vive en la pantalla del Admin VL, pero el mockup muestra
29
+ * `solicitante: V-05` con «Vendedor solicita corrección»: el vendedor avisa por fuera y el Admin
30
+ * la anota. Sin este campo, la columna «Solicitante» diría SIEMPRE «Admin VL» y se perdería el
31
+ * dato de quién originó el caso — que es justo lo que la bandeja viene a auditar.
32
+ *
33
+ * Ausente → se usa el actor del token (el Admin la levantó por su cuenta).
34
+ */
35
+ requestedBy?: string;
36
+ /**
37
+ * Qué hay que hacer, en palabras del humano. Ej.: «cambiar SKU de P-002 a P-005».
38
+ *
39
+ * Convive con `payload` y NO lo reemplaza: el texto libre es para que la persona explique, el
40
+ * `payload` tipado es para que algún día el sistema pueda aplicar el cambio solo. Hoy quien
41
+ * aplica es un humano leyendo esto.
42
+ */
43
+ requestedAction?: string;
25
44
  /** Impacto económico con signo, en centavos. Negativo si la excepción resta (descuento). */
26
45
  impactCents?: number;
27
46
  payload?: SaleExceptionPayloadInput;
@@ -81,6 +81,20 @@ __decorate([
81
81
  (0, class_validator_1.MaxLength)(1000),
82
82
  __metadata("design:type", String)
83
83
  ], CreateSaleExceptionRequest.prototype, "justification", void 0);
84
+ __decorate([
85
+ (0, class_transformer_1.Expose)(),
86
+ (0, class_validator_1.IsOptional)(),
87
+ (0, class_validator_1.IsString)(),
88
+ (0, class_validator_1.MaxLength)(64),
89
+ __metadata("design:type", String)
90
+ ], CreateSaleExceptionRequest.prototype, "requestedBy", void 0);
91
+ __decorate([
92
+ (0, class_transformer_1.Expose)(),
93
+ (0, class_validator_1.IsOptional)(),
94
+ (0, class_validator_1.IsString)(),
95
+ (0, class_validator_1.MaxLength)(500),
96
+ __metadata("design:type", String)
97
+ ], CreateSaleExceptionRequest.prototype, "requestedAction", void 0);
84
98
  __decorate([
85
99
  (0, class_transformer_1.Expose)(),
86
100
  (0, class_validator_1.IsOptional)(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.273.0",
3
+ "version": "3.275.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -41,6 +41,32 @@ export interface MetricSpecDto {
41
41
  /** Con `COUNT` se acepta `{ column: '*' }`. */
42
42
  column: ColumnRefDto;
43
43
  fn: MetricFnEnum;
44
+ /**
45
+ * Columnas de respaldo, en orden: el backend emite `FN(COALESCE(col, r1, r2…))`.
46
+ *
47
+ * ## Cuándo lo necesitas
48
+ *
49
+ * Cuando el valor que quieres sumar vive en más de una columna según la fila. En
50
+ * `retail_sale`, por ejemplo, el monto está en `amountcents` o en `equipmentpricecents` — no
51
+ * hay una columna `soldcents`.
52
+ *
53
+ * **No se puede resolver del lado del caller.** `SUM(COALESCE(a,b))` NO se reconstruye desde
54
+ * `SUM(a)` y `SUM(b)`: el COALESCE es por fila, así que si unas traen `a` y otras solo `b`,
55
+ * cualquier combinación da un número distinto. O lo hace el motor, o el dato sale mal.
56
+ *
57
+ * ## Por qué es un campo del request y no una columna del lake
58
+ *
59
+ * Una columna calculada en la tabla Iceberg **congelaría la regla de negocio dentro del
60
+ * pipeline de datos**, que es de otro equipo: cambiarla obligaría a redesplegar el pipeline y a
61
+ * rellenar el histórico, y la definición quedaría lejos de la decisión que la gobierna.
62
+ *
63
+ * Así el mecanismo es genérico y **qué columnas encadenar lo decide el dominio dueño de la
64
+ * regla**, en su propio código.
65
+ *
66
+ * ⚠️ Cada respaldo se valida contra el schema vivo de Glue igual que cualquier otra columna.
67
+ * No admite `COUNT(*)`.
68
+ */
69
+ coalesceWith?: ColumnRefDto[];
44
70
  /** Alias de salida. Si no viene, se deriva de la función y la columna. */
45
71
  alias?: string;
46
72
  }
@@ -33,6 +33,8 @@ export interface SaleException {
33
33
  requestedAt: string;
34
34
  /** OBLIGATORIA. Es lo que hace auditable la excepción. */
35
35
  justification: string;
36
+ /** Qué pidió el solicitante, en sus palabras. `null` si no lo detalló. */
37
+ requestedAction: string | null;
36
38
  /**
37
39
  * Impacto económico en centavos, con signo: positivo si la excepción suma (devolución al cliente,
38
40
  * reemplazo), negativo si resta (descuento autorizado). `null` cuando no aplica.
@@ -70,6 +70,35 @@ export class CreateSaleExceptionRequest {
70
70
  @MaxLength(1000)
71
71
  justification!: string;
72
72
 
73
+ /**
74
+ * Quién PIDIÓ la excepción, cuando no es quien la registra.
75
+ *
76
+ * El botón «Levantar excepción» vive en la pantalla del Admin VL, pero el mockup muestra
77
+ * `solicitante: V-05` con «Vendedor solicita corrección»: el vendedor avisa por fuera y el Admin
78
+ * la anota. Sin este campo, la columna «Solicitante» diría SIEMPRE «Admin VL» y se perdería el
79
+ * dato de quién originó el caso — que es justo lo que la bandeja viene a auditar.
80
+ *
81
+ * Ausente → se usa el actor del token (el Admin la levantó por su cuenta).
82
+ */
83
+ @Expose()
84
+ @IsOptional()
85
+ @IsString()
86
+ @MaxLength(64)
87
+ requestedBy?: string;
88
+
89
+ /**
90
+ * Qué hay que hacer, en palabras del humano. Ej.: «cambiar SKU de P-002 a P-005».
91
+ *
92
+ * Convive con `payload` y NO lo reemplaza: el texto libre es para que la persona explique, el
93
+ * `payload` tipado es para que algún día el sistema pueda aplicar el cambio solo. Hoy quien
94
+ * aplica es un humano leyendo esto.
95
+ */
96
+ @Expose()
97
+ @IsOptional()
98
+ @IsString()
99
+ @MaxLength(500)
100
+ requestedAction?: string;
101
+
73
102
  /** Impacto económico con signo, en centavos. Negativo si la excepción resta (descuento). */
74
103
  @Expose()
75
104
  @IsOptional()