@fiado/type-kit 3.288.0 → 3.290.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 (30) hide show
  1. package/bin/loanConfig/enums/ModifiableByRoleEnum.d.ts +11 -0
  2. package/bin/loanConfig/enums/ModifiableByRoleEnum.js +15 -0
  3. package/bin/phoneSales/DeviceCatalogModelDto.d.ts +19 -0
  4. package/bin/phoneSales/DeviceCatalogModelDto.js +12 -0
  5. package/bin/phoneSales/index.d.ts +1 -0
  6. package/bin/phoneSales/index.js +1 -0
  7. package/bin/platformRbac/dtos/ResendOtpRequest.d.ts +22 -0
  8. package/bin/platformRbac/dtos/{CompleteMyProfileRequest.js → ResendOtpRequest.js} +14 -12
  9. package/bin/platformRbac/dtos/ResendSelfRegisterOtpRequest.d.ts +11 -0
  10. package/bin/platformRbac/dtos/ResendSelfRegisterOtpRequest.js +36 -0
  11. package/bin/retailWizard/dtos/SaleLogEntry.d.ts +13 -0
  12. package/bin/retailWizard/dtos/responses/BackofficeSalesStatsResponse.d.ts +20 -4
  13. package/bin/retailWizard/dtos/responses/BackofficeSellerKpisResponse.d.ts +7 -0
  14. package/bin/retailWizard/dtos/responses/BackofficeStoreKpisResponse.d.ts +27 -0
  15. package/package.json +1 -1
  16. package/src/phoneSales/DeviceCatalogModelDto.ts +24 -0
  17. package/src/phoneSales/index.ts +1 -0
  18. package/src/retailWizard/dtos/SaleLogEntry.ts +13 -0
  19. package/src/retailWizard/dtos/responses/BackofficeSalesStatsResponse.ts +20 -4
  20. package/src/retailWizard/dtos/responses/BackofficeSellerKpisResponse.ts +7 -0
  21. package/src/retailWizard/dtos/responses/BackofficeStoreKpisResponse.ts +27 -0
  22. package/bin/platformRbac/dtos/CompleteMyProfileRequest.d.ts +0 -9
  23. package/bin/walletFunding/dtos/CancelFundingReferenceRequest.d.ts +0 -14
  24. package/bin/walletFunding/dtos/CancelFundingReferenceRequest.js +0 -41
  25. package/bin/walletFunding/dtos/CancelFundingReferenceResponse.d.ts +0 -15
  26. package/bin/walletFunding/dtos/CancelFundingReferenceResponse.js +0 -13
  27. package/bin/walletFunding/dtos/CancelWalletFundingRequest.d.ts +0 -3
  28. package/bin/walletFunding/dtos/CancelWalletFundingRequest.js +0 -21
  29. package/bin/walletFunding/dtos/CancelWalletFundingResponse.d.ts +0 -7
  30. package/bin/walletFunding/dtos/CancelWalletFundingResponse.js +0 -6
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Rol RBAC mínimo que puede modificar un parámetro (RBAC a nivel de parámetro, modelo-datos §8).
3
+ * `retailer_admin` = "Admin VentasLuga" de M6 §8. Valores = identificadores de rol de RBAC F0.
4
+ * TD-004: confirmar mapeo super_admin ↔ platform_super_admin con el naming real de F0.
5
+ * @enum {string}
6
+ */
7
+ export declare enum ModifiableByRoleEnum {
8
+ SUPER_ADMIN = "super_admin",
9
+ SOFOM_ADMIN = "sofom_admin",
10
+ RETAILER_ADMIN = "retailer_admin"
11
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ModifiableByRoleEnum = void 0;
4
+ /**
5
+ * Rol RBAC mínimo que puede modificar un parámetro (RBAC a nivel de parámetro, modelo-datos §8).
6
+ * `retailer_admin` = "Admin VentasLuga" de M6 §8. Valores = identificadores de rol de RBAC F0.
7
+ * TD-004: confirmar mapeo super_admin ↔ platform_super_admin con el naming real de F0.
8
+ * @enum {string}
9
+ */
10
+ var ModifiableByRoleEnum;
11
+ (function (ModifiableByRoleEnum) {
12
+ ModifiableByRoleEnum["SUPER_ADMIN"] = "super_admin";
13
+ ModifiableByRoleEnum["SOFOM_ADMIN"] = "sofom_admin";
14
+ ModifiableByRoleEnum["RETAILER_ADMIN"] = "retailer_admin";
15
+ })(ModifiableByRoleEnum || (exports.ModifiableByRoleEnum = ModifiableByRoleEnum = {}));
@@ -0,0 +1,19 @@
1
+ import { CurrencyId } from '../currency';
2
+ import { DeviceVariantResponseDto } from './DeviceVariantResponseDto';
3
+ /**
4
+ * Catálogo público agrupado por modelo (GET /device-variants, PublicController). Cada item agrupa
5
+ * las variantes visibles de un mismo `model` (ya filtradas por ListPublicDeviceVariantsManager:
6
+ * stock > 0, status distinto de HIDDEN, con precio cargado en la moneda del comprador) para que el
7
+ * front no tenga que agrupar/derivar esto del array plano de variantes.
8
+ */
9
+ export declare class DeviceCatalogModelDto {
10
+ model: string;
11
+ /** Imagen representativa del modelo: la de la variante con `minPrice` dentro del grupo. */
12
+ imageUrl: string;
13
+ /** Precio mínimo (`price`) entre las variantes visibles del modelo, en `currencyId`. */
14
+ minPrice: number;
15
+ /** Misma moneda resuelta server-side que ya trae cada item de `variants` (DEC-011). */
16
+ currencyId: CurrencyId;
17
+ /** Variantes visibles del modelo, cada una con `price`/`currencyId` ya resueltos. */
18
+ variants: DeviceVariantResponseDto[];
19
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeviceCatalogModelDto = void 0;
4
+ /**
5
+ * Catálogo público agrupado por modelo (GET /device-variants, PublicController). Cada item agrupa
6
+ * las variantes visibles de un mismo `model` (ya filtradas por ListPublicDeviceVariantsManager:
7
+ * stock > 0, status distinto de HIDDEN, con precio cargado en la moneda del comprador) para que el
8
+ * front no tenga que agrupar/derivar esto del array plano de variantes.
9
+ */
10
+ class DeviceCatalogModelDto {
11
+ }
12
+ exports.DeviceCatalogModelDto = DeviceCatalogModelDto;
@@ -1,4 +1,5 @@
1
1
  export * from './DeviceVariantResponseDto';
2
+ export * from './DeviceCatalogModelDto';
2
3
  export * from './CreateDeviceVariantRequestDto';
3
4
  export * from './UpdateDeviceVariantRequestDto';
4
5
  export * from './CreateSaleRequestDto';
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./DeviceVariantResponseDto"), exports);
18
+ __exportStar(require("./DeviceCatalogModelDto"), exports);
18
19
  __exportStar(require("./CreateDeviceVariantRequestDto"), exports);
19
20
  __exportStar(require("./UpdateDeviceVariantRequestDto"), exports);
20
21
  __exportStar(require("./CreateSaleRequestDto"), exports);
@@ -0,0 +1,22 @@
1
+ import { MfaMethodEnum } from '../enums/MfaMethodEnum';
2
+ /**
3
+ * Body del POST /auth/resend-otp (público, anónimo). DEC-RBAC-054.
4
+ * Reenvía el OTP del login re-disparando el challenge real CUSTOM_AUTH (EMAIL_OTP) para la
5
+ * identidad SIN password. `tenantId` obligatorio (DEC-064 — el picker ya lo resolvió, NO "solo email").
6
+ * El email se normaliza lowercase server-side. Postura anti-enumeración: respuesta 200 genérica
7
+ * siempre, sin filtrar existencia (ver AuthLoginManager.resendChallengeOtp).
8
+ */
9
+ export declare class ResendOtpRequest {
10
+ email: string;
11
+ tenantId: string;
12
+ }
13
+ /**
14
+ * Respuesta del resend-otp. `session`/`mfaMethod` frescos del nuevo challenge CUSTOM_AUTH.
15
+ * Plain sin validators (no validamos lo que mandamos al cliente — fiado-validation-and-dtos § 7).
16
+ * Ambos opcionales: en los caminos de rechazo silencioso (anti-enumeración) o ramas sin CUSTOM_AUTH
17
+ * el server responde 200 genérico sin session ni método.
18
+ */
19
+ export interface ResendOtpResponse {
20
+ session?: string;
21
+ mfaMethod?: MfaMethodEnum;
22
+ }
@@ -9,26 +9,28 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.CompleteMyProfileRequest = void 0;
12
+ exports.ResendOtpRequest = void 0;
13
13
  const class_transformer_1 = require("class-transformer");
14
14
  const class_validator_1 = require("class-validator");
15
15
  /**
16
- * Body del PUT /me/profile/complete (autenticado, gate post-MFA del autoregistro). DEC-RBAC-034.
17
- * Opera sobre el propio usuario (cognitoSub del token). Valida nombre + los `userFieldDefs` requeridos
18
- * del tenant (422 MISSING_REQUIRED_FIELDS si faltan) y flipea `profileComplete=true`.
16
+ * Body del POST /auth/resend-otp (público, anónimo). DEC-RBAC-054.
17
+ * Reenvía el OTP del login re-disparando el challenge real CUSTOM_AUTH (EMAIL_OTP) para la
18
+ * identidad SIN password. `tenantId` obligatorio (DEC-064 el picker ya lo resolvió, NO "solo email").
19
+ * El email se normaliza lowercase server-side. Postura anti-enumeración: respuesta 200 genérica
20
+ * siempre, sin filtrar existencia (ver AuthLoginManager.resendChallengeOtp).
19
21
  */
20
- class CompleteMyProfileRequest {
22
+ class ResendOtpRequest {
21
23
  }
22
- exports.CompleteMyProfileRequest = CompleteMyProfileRequest;
24
+ exports.ResendOtpRequest = ResendOtpRequest;
23
25
  __decorate([
24
26
  (0, class_transformer_1.Expose)(),
25
- (0, class_validator_1.IsString)(),
27
+ (0, class_validator_1.IsEmail)(),
26
28
  (0, class_validator_1.IsNotEmpty)(),
27
29
  __metadata("design:type", String)
28
- ], CompleteMyProfileRequest.prototype, "displayName", void 0);
30
+ ], ResendOtpRequest.prototype, "email", void 0);
29
31
  __decorate([
30
32
  (0, class_transformer_1.Expose)(),
31
- (0, class_validator_1.IsOptional)(),
32
- (0, class_validator_1.IsObject)(),
33
- __metadata("design:type", Object)
34
- ], CompleteMyProfileRequest.prototype, "customFields", void 0);
33
+ (0, class_validator_1.IsString)(),
34
+ (0, class_validator_1.IsNotEmpty)(),
35
+ __metadata("design:type", String)
36
+ ], ResendOtpRequest.prototype, "tenantId", void 0);
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Body del POST /self-register/resend-otp (público, anónimo). DEC-RBAC-054.
3
+ * Re-envía el OTP del autoregistro (mecanismo messages-business, NO Cognito) tras validar un
4
+ * `pending` existente. Misma postura anti-enumeración del start. El email se normaliza lowercase
5
+ * server-side. DTO propio por endpoint (NO reusa SelfRegisterStartRequest, que exige roleId/scope/
6
+ * scopeRef, ni SelfRegisterVerifyOtpRequest, que exige otp).
7
+ */
8
+ export declare class ResendSelfRegisterOtpRequest {
9
+ tenantId: string;
10
+ email: string;
11
+ }
@@ -0,0 +1,36 @@
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.ResendSelfRegisterOtpRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ /**
16
+ * Body del POST /self-register/resend-otp (público, anónimo). DEC-RBAC-054.
17
+ * Re-envía el OTP del autoregistro (mecanismo messages-business, NO Cognito) tras validar un
18
+ * `pending` existente. Misma postura anti-enumeración del start. El email se normaliza lowercase
19
+ * server-side. DTO propio por endpoint (NO reusa SelfRegisterStartRequest, que exige roleId/scope/
20
+ * scopeRef, ni SelfRegisterVerifyOtpRequest, que exige otp).
21
+ */
22
+ class ResendSelfRegisterOtpRequest {
23
+ }
24
+ exports.ResendSelfRegisterOtpRequest = ResendSelfRegisterOtpRequest;
25
+ __decorate([
26
+ (0, class_transformer_1.Expose)(),
27
+ (0, class_validator_1.IsString)(),
28
+ (0, class_validator_1.IsNotEmpty)(),
29
+ __metadata("design:type", String)
30
+ ], ResendSelfRegisterOtpRequest.prototype, "tenantId", void 0);
31
+ __decorate([
32
+ (0, class_transformer_1.Expose)(),
33
+ (0, class_validator_1.IsEmail)(),
34
+ (0, class_validator_1.IsNotEmpty)(),
35
+ __metadata("design:type", String)
36
+ ], ResendSelfRegisterOtpRequest.prototype, "email", void 0);
@@ -26,4 +26,17 @@ export interface SaleLogEntry {
26
26
  /** Motivo, cuando la acción lo exige (cancelación, excepción aplicada). */
27
27
  reason: string | null;
28
28
  changes: SaleLogChange[];
29
+ /**
30
+ * Datos de la venta que la acción NO cambió y que se guardan para poder leer la entrada sin abrir
31
+ * otra pantalla (en un `SALE_CANCEL`: el tipo de venta, el monto, el enganche, el crédito).
32
+ *
33
+ * Va aparte de `changes` a propósito. Antes viajaba dentro de `new` y `changes` lo pintaba como un
34
+ * alta: la bitácora afirmaba que en la cancelación el tipo de venta había pasado «de nada a CASH».
35
+ * En una auditoría un cambio inventado es peor que un dato faltante.
36
+ *
37
+ * **El front lo pinta como contexto, NUNCA como «antes → después».** `null` cuando la acción no
38
+ * mandó contexto. Valores serializados a string igual que `changes`; y como `changes`, NUNCA
39
+ * lleva PII.
40
+ */
41
+ context: Record<string, string | null> | null;
29
42
  }
@@ -7,20 +7,36 @@
7
7
  * contra el que el front ya mockeó la pantalla. Cambiarlas a inglés por consistencia rompería una
8
8
  * pantalla ya construida sin ganar nada. Decisión de Andrés, 2026-08-03.
9
9
  *
10
- * `contado` + `credito` == `total`. `surekeep` + `externas` == `credito`: las dos particiones son
11
- * completas y NO se solapan (ver `helpers/saleFinancier`).
10
+ * **Las identidades del contrato** (las tres se cumplen siempre y están cubiertas por tests):
11
+ *
12
+ * - `contado` + `credito` + `sinProveedor` == `total`
13
+ * - `surekeep` + `externas` == `credito`
14
+ *
15
+ * `contado`, `credito` y `sinProveedor` particionan `total`; `surekeep` y `externas` particionan
16
+ * `credito`. Ninguna de las dos particiones se solapa (ver `helpers/saleFinancier`).
12
17
  */
13
18
  export interface BackofficeSalesStatsResponse {
14
19
  /** Ventas del retailer en la ventana consultada. */
15
20
  total: number;
16
21
  /** Subconjunto de `total` con `soldAt` en el día de hoy. */
17
22
  hoy: number;
18
- /** `type: CASH`. */
23
+ /** `type: CASH`. Efectivo de verdad — ver `sinProveedor`. */
19
24
  contado: number;
20
- /** `type: CREDIT` o `EXTERNAL_REFERRAL` todo lo que no es contado. */
25
+ /** Derivadas con financiera CONOCIDA: `type: CREDIT`, o `EXTERNAL_REFERRAL` con proveedor. */
21
26
  credito: number;
22
27
  /** Financiadas por la SOFOM (`type: CREDIT`). */
23
28
  surekeep: number;
24
29
  /** Financiadas por un tercero (`EXTERNAL_REFERRAL` con proveedor). */
25
30
  externas: number;
31
+ /**
32
+ * `type: EXTERNAL_REFERRAL` **sin** `externalProvider` — derivadas cuya financiera no quedó
33
+ * registrada. Es un DATO ROTO, no una forma de pago.
34
+ *
35
+ * Vive en su propia llave y NO en `contado` porque antes caía ahí y la pantalla las leía como
36
+ * EFECTIVO, que es la lectura más cara de equivocar. Tampoco entra en `credito`: `surekeep` +
37
+ * `externas` == `credito` y una venta sin financiera no pertenece a ninguna de las dos.
38
+ * Análisis ya las descartaba de su mix, y por eso Ventas y Análisis contaban distinto el mismo
39
+ * período. Un valor > 0 es una invitación a ir a corregir esas filas.
40
+ */
41
+ sinProveedor: number;
26
42
  }
@@ -22,6 +22,13 @@ export interface SellerKpiRow {
22
22
  *
23
23
  * Mismo criterio que A3: el eje es la venta, así que solo aparecen los vendedores que vendieron en
24
24
  * la ventana. El roster completo vive en `retail-org-business`.
25
+ *
26
+ * ⚠️ **Sin la ★ de encargado de tienda** que pinta el mockup (`es_admin_tienda`). Ese flag es del
27
+ * padrón (`RetailUser_GT`, de `retail-org-business`), no del snapshot de la venta: la pantalla lo
28
+ * trae de ahí y lo une por `sellerRetailUserId`.
29
+ *
30
+ * ⚠️ Tampoco lleva variación contra la semana pasada — el mockup de Vendedores no la pinta, solo el
31
+ * de Tiendas (ver `StoreKpiRow.weekOverWeekChangePct`).
25
32
  */
26
33
  export interface BackofficeSellerKpisResponse {
27
34
  items: SellerKpiRow[];
@@ -15,6 +15,21 @@ export interface StoreKpiRow {
15
15
  averageTicketCents: number | null;
16
16
  /** ISO-8601 de la venta más reciente de la tienda en la ventana. `null` si no vendió. */
17
17
  lastSaleAt: string | null;
18
+ /**
19
+ * Variación porcentual del volumen colocado contra la MISMA ventana corrida 7 días atrás, con un
20
+ * decimal. Es el chip `+12%` / `-8%` de la pantalla Tiendas.
21
+ *
22
+ * `null` en tres casos, todos «no sé» y ninguno «no cambió»:
23
+ * - la ventana pedida abarca **más de 7 días**, así que el baseline se solaparía con ella y el
24
+ * delta compararía un período contra sí mismo (con el default de 90 días, siempre);
25
+ * - la tienda no vendió nada esa semana — no se divide por cero;
26
+ * - los números vienen del data lake y no hay fila para esta tienda en el baseline.
27
+ */
28
+ weekOverWeekChangePct: number | null;
29
+ /** Volumen colocado de la ventana de hace 7 días — el denominador del chip, explícito. */
30
+ baselineSameWeekdayCents: number | null;
31
+ /** Piezas de esa misma ventana. La pantalla las pinta debajo del chip («N piezas semana pasada»). */
32
+ baselineSameWeekdayUnits: number | null;
18
33
  }
19
34
  /**
20
35
  * GET /backoffice/stores/kpis — la pantalla Tiendas del Admin VL (A3).
@@ -22,6 +37,18 @@ export interface StoreKpiRow {
22
37
  *
23
38
  * El eje es la VENTA: solo aparecen las tiendas que vendieron en la ventana. El roster completo
24
39
  * (incluidas las que no vendieron) lo tiene `retail-org-business`; la pantalla los cruza.
40
+ *
41
+ * ⚠️ **Tres columnas del mockup NO salen de acá y no van a salir**, porque no están en el snapshot
42
+ * congelado de la venta sino en el padrón:
43
+ *
44
+ * | Columna | Dónde vive |
45
+ * |---|---|
46
+ * | código de tienda | `Store` — `retail-org-business` |
47
+ * | tipo propia / subdistribuidor | NO es un campo de `Store`: un subdistribuidor es un *retailer hijo*, así que sale de `GET /retailers/{retailerId}/hierarchy` |
48
+ * | vendedores activos | `RetailUser_GT` — `retail-org-business` |
49
+ *
50
+ * La pantalla las trae de ahí y las une por `storeId`. Devolverlas desde este endpoint obligaría al
51
+ * silo de ventas a consultar el padrón en cada lectura de tablero.
25
52
  */
26
53
  export interface BackofficeStoreKpisResponse {
27
54
  items: StoreKpiRow[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.288.0",
3
+ "version": "3.290.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -0,0 +1,24 @@
1
+ import { CurrencyId } from '../currency';
2
+ import { DeviceVariantResponseDto } from './DeviceVariantResponseDto';
3
+
4
+ /**
5
+ * Catálogo público agrupado por modelo (GET /device-variants, PublicController). Cada item agrupa
6
+ * las variantes visibles de un mismo `model` (ya filtradas por ListPublicDeviceVariantsManager:
7
+ * stock > 0, status distinto de HIDDEN, con precio cargado en la moneda del comprador) para que el
8
+ * front no tenga que agrupar/derivar esto del array plano de variantes.
9
+ */
10
+ export class DeviceCatalogModelDto {
11
+ model!: string;
12
+
13
+ /** Imagen representativa del modelo: la de la variante con `minPrice` dentro del grupo. */
14
+ imageUrl!: string;
15
+
16
+ /** Precio mínimo (`price`) entre las variantes visibles del modelo, en `currencyId`. */
17
+ minPrice!: number;
18
+
19
+ /** Misma moneda resuelta server-side que ya trae cada item de `variants` (DEC-011). */
20
+ currencyId!: CurrencyId;
21
+
22
+ /** Variantes visibles del modelo, cada una con `price`/`currencyId` ya resueltos. */
23
+ variants!: DeviceVariantResponseDto[];
24
+ }
@@ -1,4 +1,5 @@
1
1
  export * from './DeviceVariantResponseDto';
2
+ export * from './DeviceCatalogModelDto';
2
3
  export * from './CreateDeviceVariantRequestDto';
3
4
  export * from './UpdateDeviceVariantRequestDto';
4
5
  export * from './CreateSaleRequestDto';
@@ -27,4 +27,17 @@ export interface SaleLogEntry {
27
27
  /** Motivo, cuando la acción lo exige (cancelación, excepción aplicada). */
28
28
  reason: string | null;
29
29
  changes: SaleLogChange[];
30
+ /**
31
+ * Datos de la venta que la acción NO cambió y que se guardan para poder leer la entrada sin abrir
32
+ * otra pantalla (en un `SALE_CANCEL`: el tipo de venta, el monto, el enganche, el crédito).
33
+ *
34
+ * Va aparte de `changes` a propósito. Antes viajaba dentro de `new` y `changes` lo pintaba como un
35
+ * alta: la bitácora afirmaba que en la cancelación el tipo de venta había pasado «de nada a CASH».
36
+ * En una auditoría un cambio inventado es peor que un dato faltante.
37
+ *
38
+ * **El front lo pinta como contexto, NUNCA como «antes → después».** `null` cuando la acción no
39
+ * mandó contexto. Valores serializados a string igual que `changes`; y como `changes`, NUNCA
40
+ * lleva PII.
41
+ */
42
+ context: Record<string, string | null> | null;
30
43
  }
@@ -7,20 +7,36 @@
7
7
  * contra el que el front ya mockeó la pantalla. Cambiarlas a inglés por consistencia rompería una
8
8
  * pantalla ya construida sin ganar nada. Decisión de Andrés, 2026-08-03.
9
9
  *
10
- * `contado` + `credito` == `total`. `surekeep` + `externas` == `credito`: las dos particiones son
11
- * completas y NO se solapan (ver `helpers/saleFinancier`).
10
+ * **Las identidades del contrato** (las tres se cumplen siempre y están cubiertas por tests):
11
+ *
12
+ * - `contado` + `credito` + `sinProveedor` == `total`
13
+ * - `surekeep` + `externas` == `credito`
14
+ *
15
+ * `contado`, `credito` y `sinProveedor` particionan `total`; `surekeep` y `externas` particionan
16
+ * `credito`. Ninguna de las dos particiones se solapa (ver `helpers/saleFinancier`).
12
17
  */
13
18
  export interface BackofficeSalesStatsResponse {
14
19
  /** Ventas del retailer en la ventana consultada. */
15
20
  total: number;
16
21
  /** Subconjunto de `total` con `soldAt` en el día de hoy. */
17
22
  hoy: number;
18
- /** `type: CASH`. */
23
+ /** `type: CASH`. Efectivo de verdad — ver `sinProveedor`. */
19
24
  contado: number;
20
- /** `type: CREDIT` o `EXTERNAL_REFERRAL` todo lo que no es contado. */
25
+ /** Derivadas con financiera CONOCIDA: `type: CREDIT`, o `EXTERNAL_REFERRAL` con proveedor. */
21
26
  credito: number;
22
27
  /** Financiadas por la SOFOM (`type: CREDIT`). */
23
28
  surekeep: number;
24
29
  /** Financiadas por un tercero (`EXTERNAL_REFERRAL` con proveedor). */
25
30
  externas: number;
31
+ /**
32
+ * `type: EXTERNAL_REFERRAL` **sin** `externalProvider` — derivadas cuya financiera no quedó
33
+ * registrada. Es un DATO ROTO, no una forma de pago.
34
+ *
35
+ * Vive en su propia llave y NO en `contado` porque antes caía ahí y la pantalla las leía como
36
+ * EFECTIVO, que es la lectura más cara de equivocar. Tampoco entra en `credito`: `surekeep` +
37
+ * `externas` == `credito` y una venta sin financiera no pertenece a ninguna de las dos.
38
+ * Análisis ya las descartaba de su mix, y por eso Ventas y Análisis contaban distinto el mismo
39
+ * período. Un valor > 0 es una invitación a ir a corregir esas filas.
40
+ */
41
+ sinProveedor: number;
26
42
  }
@@ -23,6 +23,13 @@ export interface SellerKpiRow {
23
23
  *
24
24
  * Mismo criterio que A3: el eje es la venta, así que solo aparecen los vendedores que vendieron en
25
25
  * la ventana. El roster completo vive en `retail-org-business`.
26
+ *
27
+ * ⚠️ **Sin la ★ de encargado de tienda** que pinta el mockup (`es_admin_tienda`). Ese flag es del
28
+ * padrón (`RetailUser_GT`, de `retail-org-business`), no del snapshot de la venta: la pantalla lo
29
+ * trae de ahí y lo une por `sellerRetailUserId`.
30
+ *
31
+ * ⚠️ Tampoco lleva variación contra la semana pasada — el mockup de Vendedores no la pinta, solo el
32
+ * de Tiendas (ver `StoreKpiRow.weekOverWeekChangePct`).
26
33
  */
27
34
  export interface BackofficeSellerKpisResponse {
28
35
  items: SellerKpiRow[];
@@ -15,6 +15,21 @@ export interface StoreKpiRow {
15
15
  averageTicketCents: number | null;
16
16
  /** ISO-8601 de la venta más reciente de la tienda en la ventana. `null` si no vendió. */
17
17
  lastSaleAt: string | null;
18
+ /**
19
+ * Variación porcentual del volumen colocado contra la MISMA ventana corrida 7 días atrás, con un
20
+ * decimal. Es el chip `+12%` / `-8%` de la pantalla Tiendas.
21
+ *
22
+ * `null` en tres casos, todos «no sé» y ninguno «no cambió»:
23
+ * - la ventana pedida abarca **más de 7 días**, así que el baseline se solaparía con ella y el
24
+ * delta compararía un período contra sí mismo (con el default de 90 días, siempre);
25
+ * - la tienda no vendió nada esa semana — no se divide por cero;
26
+ * - los números vienen del data lake y no hay fila para esta tienda en el baseline.
27
+ */
28
+ weekOverWeekChangePct: number | null;
29
+ /** Volumen colocado de la ventana de hace 7 días — el denominador del chip, explícito. */
30
+ baselineSameWeekdayCents: number | null;
31
+ /** Piezas de esa misma ventana. La pantalla las pinta debajo del chip («N piezas semana pasada»). */
32
+ baselineSameWeekdayUnits: number | null;
18
33
  }
19
34
 
20
35
  /**
@@ -23,6 +38,18 @@ export interface StoreKpiRow {
23
38
  *
24
39
  * El eje es la VENTA: solo aparecen las tiendas que vendieron en la ventana. El roster completo
25
40
  * (incluidas las que no vendieron) lo tiene `retail-org-business`; la pantalla los cruza.
41
+ *
42
+ * ⚠️ **Tres columnas del mockup NO salen de acá y no van a salir**, porque no están en el snapshot
43
+ * congelado de la venta sino en el padrón:
44
+ *
45
+ * | Columna | Dónde vive |
46
+ * |---|---|
47
+ * | código de tienda | `Store` — `retail-org-business` |
48
+ * | tipo propia / subdistribuidor | NO es un campo de `Store`: un subdistribuidor es un *retailer hijo*, así que sale de `GET /retailers/{retailerId}/hierarchy` |
49
+ * | vendedores activos | `RetailUser_GT` — `retail-org-business` |
50
+ *
51
+ * La pantalla las trae de ahí y las une por `storeId`. Devolverlas desde este endpoint obligaría al
52
+ * silo de ventas a consultar el padrón en cada lectura de tablero.
26
53
  */
27
54
  export interface BackofficeStoreKpisResponse {
28
55
  items: StoreKpiRow[];
@@ -1,9 +0,0 @@
1
- /**
2
- * Body del PUT /me/profile/complete (autenticado, gate post-MFA del autoregistro). DEC-RBAC-034.
3
- * Opera sobre el propio usuario (cognitoSub del token). Valida nombre + los `userFieldDefs` requeridos
4
- * del tenant (422 MISSING_REQUIRED_FIELDS si faltan) y flipea `profileComplete=true`.
5
- */
6
- export declare class CompleteMyProfileRequest {
7
- displayName: string;
8
- customFields?: Record<string, string>;
9
- }
@@ -1,14 +0,0 @@
1
- /**
2
- * Body para cancelar una referencia de funding ya creada. La referencia/fundingId
3
- * viaja en la URL (`/funding/{moduleName}/{fundingId}/cancel`); este body aporta
4
- * el contexto del solicitante + idempotencia.
5
- *
6
- * NOTA: shape inferido desde el uso en `@fiado/api-invoker`
7
- * (benefits-marketplace / equality-connector) — confirmar con el dueño del
8
- * módulo walletFunding / el lambda equality-connector que implementa el cancel.
9
- */
10
- export declare class CancelFundingReferenceRequest {
11
- directoryId: string;
12
- reason?: string;
13
- idempotencyKey: string;
14
- }
@@ -1,41 +0,0 @@
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.CancelFundingReferenceRequest = void 0;
13
- const class_validator_1 = require("class-validator");
14
- /**
15
- * Body para cancelar una referencia de funding ya creada. La referencia/fundingId
16
- * viaja en la URL (`/funding/{moduleName}/{fundingId}/cancel`); este body aporta
17
- * el contexto del solicitante + idempotencia.
18
- *
19
- * NOTA: shape inferido desde el uso en `@fiado/api-invoker`
20
- * (benefits-marketplace / equality-connector) — confirmar con el dueño del
21
- * módulo walletFunding / el lambda equality-connector que implementa el cancel.
22
- */
23
- class CancelFundingReferenceRequest {
24
- }
25
- exports.CancelFundingReferenceRequest = CancelFundingReferenceRequest;
26
- __decorate([
27
- (0, class_validator_1.IsString)(),
28
- (0, class_validator_1.MaxLength)(64),
29
- __metadata("design:type", String)
30
- ], CancelFundingReferenceRequest.prototype, "directoryId", void 0);
31
- __decorate([
32
- (0, class_validator_1.IsOptional)(),
33
- (0, class_validator_1.IsString)(),
34
- (0, class_validator_1.MaxLength)(256),
35
- __metadata("design:type", String)
36
- ], CancelFundingReferenceRequest.prototype, "reason", void 0);
37
- __decorate([
38
- (0, class_validator_1.IsString)(),
39
- (0, class_validator_1.MaxLength)(64),
40
- __metadata("design:type", String)
41
- ], CancelFundingReferenceRequest.prototype, "idempotencyKey", void 0);
@@ -1,15 +0,0 @@
1
- import { BenefitPaymentStatusEnum } from "../../benefitCenter/enums/BenefitPaymentStatusEnum";
2
- import { WalletFundingErrorCodeEnum } from "../enums/WalletFundingErrorCodeEnum";
3
- /**
4
- * Respuesta de la cancelación de una referencia de funding. Mismo estilo que
5
- * CreateFundingReferenceResponse.
6
- *
7
- * NOTA: shape inferido desde el uso en `@fiado/api-invoker` — confirmar con el
8
- * dueño del módulo walletFunding / el lambda equality-connector.
9
- */
10
- export declare class CancelFundingReferenceResponse {
11
- /** Referencia cancelada (misma PK que se creó). */
12
- reference: string;
13
- status: BenefitPaymentStatusEnum;
14
- errorCode?: WalletFundingErrorCodeEnum;
15
- }
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CancelFundingReferenceResponse = void 0;
4
- /**
5
- * Respuesta de la cancelación de una referencia de funding. Mismo estilo que
6
- * CreateFundingReferenceResponse.
7
- *
8
- * NOTA: shape inferido desde el uso en `@fiado/api-invoker` — confirmar con el
9
- * dueño del módulo walletFunding / el lambda equality-connector.
10
- */
11
- class CancelFundingReferenceResponse {
12
- }
13
- exports.CancelFundingReferenceResponse = CancelFundingReferenceResponse;
@@ -1,3 +0,0 @@
1
- export declare class CancelWalletFundingRequest {
2
- idempotencyKey: string;
3
- }
@@ -1,21 +0,0 @@
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.CancelWalletFundingRequest = void 0;
13
- const class_validator_1 = require("class-validator");
14
- class CancelWalletFundingRequest {
15
- }
16
- exports.CancelWalletFundingRequest = CancelWalletFundingRequest;
17
- __decorate([
18
- (0, class_validator_1.IsString)(),
19
- (0, class_validator_1.MaxLength)(64),
20
- __metadata("design:type", String)
21
- ], CancelWalletFundingRequest.prototype, "idempotencyKey", void 0);
@@ -1,7 +0,0 @@
1
- import { BenefitPaymentStatusEnum } from "../../benefitCenter/enums/BenefitPaymentStatusEnum";
2
- import { WalletFundingErrorCodeEnum } from "../enums/WalletFundingErrorCodeEnum";
3
- export declare class CancelWalletFundingResponse {
4
- status: BenefitPaymentStatusEnum;
5
- errorCode?: WalletFundingErrorCodeEnum;
6
- fundingId?: string;
7
- }
@@ -1,6 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CancelWalletFundingResponse = void 0;
4
- class CancelWalletFundingResponse {
5
- }
6
- exports.CancelWalletFundingResponse = CancelWalletFundingResponse;