@fiado/type-kit 3.589.0 → 3.590.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,67 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validateSync } from 'class-validator';
4
+ import * as RetailWizard from '../../../src/retailWizard';
5
+ import * as RetailCatalog from '../../../src/retailCatalog';
6
+
7
+ const { BackofficeSessionSummariesRequest, BACKOFFICE_SESSION_SUMMARIES_MAX_IDS } = RetailWizard;
8
+
9
+ function errorsOf(payload: Record<string, unknown>): string[] {
10
+ const dto = plainToInstance(BackofficeSessionSummariesRequest, payload, { excludeExtraneousValues: true });
11
+ return validateSync(dto).map((e) => e.property);
12
+ }
13
+
14
+ describe('BackofficeSessionSummariesRequest', () => {
15
+ it('acepta una lista de ids válidos', () => {
16
+ expect(errorsOf({ sessionIds: ['01HXYZ', 'abc_def-1'] })).toEqual([]);
17
+ });
18
+
19
+ it('rechaza lista vacía, ausente o no-lista', () => {
20
+ expect(errorsOf({ sessionIds: [] })).toEqual(['sessionIds']);
21
+ expect(errorsOf({})).toEqual(['sessionIds']);
22
+ expect(errorsOf({ sessionIds: 'abc' })).toEqual(['sessionIds']);
23
+ });
24
+
25
+ it('rechaza más ids que el techo', () => {
26
+ const ids = Array.from({ length: BACKOFFICE_SESSION_SUMMARIES_MAX_IDS + 1 }, (_, i) => `s${i}`);
27
+ expect(errorsOf({ sessionIds: ids })).toEqual(['sessionIds']);
28
+ });
29
+
30
+ it('rechaza ids con forma inválida o que no son texto', () => {
31
+ expect(errorsOf({ sessionIds: ['ok', 'con espacio'] })).toEqual(['sessionIds']);
32
+ expect(errorsOf({ sessionIds: [123] })).toEqual(['sessionIds']);
33
+ });
34
+
35
+ it('el response tipa el resumen de sesión', () => {
36
+ const result: RetailWizard.BackofficeSessionSummariesResult = {
37
+ sessions: [
38
+ {
39
+ sessionId: 's1',
40
+ state: RetailWizard.WizardStateEnum.ACTIVE,
41
+ sellerName: null,
42
+ sellerRetailUserId: null,
43
+ storeId: 'st1',
44
+ paid: false,
45
+ saleId: null,
46
+ currentStep: null,
47
+ },
48
+ ],
49
+ };
50
+ expect(result.sessions).toHaveLength(1);
51
+ });
52
+ });
53
+
54
+ describe('retailCatalog — saldo por tienda y reservas vivas', () => {
55
+ it('InventoryStorePieces acepta el saldo opcional y GetInventorySkuResponse las reservas vivas', () => {
56
+ const store: RetailCatalog.InventoryStorePieces = { storeId: 'st1', pieces: [], available: 3, reserved: 1, availableToSell: 2 };
57
+ const reservation: RetailCatalog.InventoryLiveReservation = {
58
+ storeId: 'st1', sessionId: 's1', lineId: 'l1', reservationId: 'r1', quantity: 1,
59
+ expiresAt: '2026-10-26T00:00:00.000Z', reservedAt: null,
60
+ };
61
+ const detail: Pick<RetailCatalog.GetInventorySkuResponse, 'piecesByStore' | 'liveReservations'> = {
62
+ piecesByStore: [store],
63
+ liveReservations: [reservation],
64
+ };
65
+ expect(detail.liveReservations?.[0].reservationId).toBe('r1');
66
+ });
67
+ });
@@ -37,6 +37,24 @@ export interface InventoryPieceEntry {
37
37
  export interface InventoryStorePieces {
38
38
  storeId: string;
39
39
  pieces: InventoryPieceEntry[];
40
+ /** BALANCE#.available de la tienda; 0 sin BALANCE#. */
41
+ available?: number;
42
+ /** BALANCE#.reserved: apartadas por cantidad o con pieza HELD. */
43
+ reserved?: number;
44
+ /** Unidades que de verdad se pueden vender: min(available, piezas AVAILABLE). */
45
+ availableToSell?: number;
46
+ }
47
+ /** Reserva RES# viva de un SKU en una tienda, para la tarjeta "Apartados ahora" de la ficha. */
48
+ export interface InventoryLiveReservation {
49
+ storeId: string;
50
+ sessionId: string;
51
+ lineId: string;
52
+ reservationId: string;
53
+ quantity: number;
54
+ /** ISO en que vence la reserva. */
55
+ expiresAt: string;
56
+ /** ISO en que se apartó; null si la fila no trae createdAt. */
57
+ reservedAt: string | null;
40
58
  }
41
59
  /** Response de backofficeGetInventorySku: solo lo que la fila de filter=list no trae. */
42
60
  export interface GetInventorySkuResponse {
@@ -51,6 +69,8 @@ export interface GetInventorySkuResponse {
51
69
  /** Promos de venta vigentes del SKU; `null` si retail-promotions no respondió. */
52
70
  promotions?: ActiveSalePromotionSummary[] | null;
53
71
  sources?: InventorySkuSources;
72
+ /** Reservas RES# vivas del SKU en todas las tiendas. */
73
+ liveReservations?: InventoryLiveReservation[];
54
74
  }
55
75
  /** Estado de las fuentes externas de la ficha. */
56
76
  export interface InventorySkuSources {
@@ -0,0 +1,4 @@
1
+ /** Techo de ids por request de `POST /backoffice/wizard/sessions/summaries`. */
2
+ export declare const BACKOFFICE_SESSION_SUMMARIES_MAX_IDS = 50;
3
+ /** Forma aceptada de un `sessionId`; la misma que el lote privado de sesiones. */
4
+ export declare const BACKOFFICE_SESSION_ID_PATTERN: RegExp;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BACKOFFICE_SESSION_ID_PATTERN = exports.BACKOFFICE_SESSION_SUMMARIES_MAX_IDS = void 0;
4
+ /** Techo de ids por request de `POST /backoffice/wizard/sessions/summaries`. */
5
+ exports.BACKOFFICE_SESSION_SUMMARIES_MAX_IDS = 50;
6
+ /** Forma aceptada de un `sessionId`; la misma que el lote privado de sesiones. */
7
+ exports.BACKOFFICE_SESSION_ID_PATTERN = /^[0-9A-Za-z_-]{1,64}$/;
@@ -0,0 +1,4 @@
1
+ /** Body de `POST /backoffice/wizard/sessions/summaries`. */
2
+ export declare class BackofficeSessionSummariesRequest {
3
+ sessionIds: string[];
4
+ }
@@ -0,0 +1,30 @@
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.BackofficeSessionSummariesRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const backofficeSessionSummaries_1 = require("../../catalog/backofficeSessionSummaries");
16
+ /** Body de `POST /backoffice/wizard/sessions/summaries`. */
17
+ class BackofficeSessionSummariesRequest {
18
+ }
19
+ exports.BackofficeSessionSummariesRequest = BackofficeSessionSummariesRequest;
20
+ __decorate([
21
+ (0, class_transformer_1.Expose)(),
22
+ (0, class_validator_1.IsArray)({ message: 'sessionIds debe ser una lista' }),
23
+ (0, class_validator_1.ArrayMinSize)(1, { message: 'sessionIds debe traer al menos un id' }),
24
+ (0, class_validator_1.ArrayMaxSize)(backofficeSessionSummaries_1.BACKOFFICE_SESSION_SUMMARIES_MAX_IDS, {
25
+ message: `sessionIds no puede pasar de ${backofficeSessionSummaries_1.BACKOFFICE_SESSION_SUMMARIES_MAX_IDS} ids`,
26
+ }),
27
+ (0, class_validator_1.IsString)({ each: true, message: 'cada sessionId debe ser texto' }),
28
+ (0, class_validator_1.Matches)(backofficeSessionSummaries_1.BACKOFFICE_SESSION_ID_PATTERN, { each: true, message: 'cada sessionId debe tener forma de id' }),
29
+ __metadata("design:type", Array)
30
+ ], BackofficeSessionSummariesRequest.prototype, "sessionIds", void 0);
@@ -0,0 +1,18 @@
1
+ import type { WizardStateEnum } from '../../enums/WizardStateEnum';
2
+ import type { WizardStepEnum } from '../../enums/WizardStepEnum';
3
+ /** Resumen de una sesión para el cajón de inventario del backoffice. */
4
+ export interface BackofficeSessionSummary {
5
+ sessionId: string;
6
+ state: WizardStateEnum;
7
+ sellerName: string | null;
8
+ sellerRetailUserId: string | null;
9
+ storeId: string;
10
+ /** `true` si la sesión ya tiene cobro registrado. */
11
+ paid: boolean;
12
+ saleId: string | null;
13
+ currentStep: WizardStepEnum | null;
14
+ }
15
+ /** Respuesta de `POST /backoffice/wizard/sessions/summaries`; los ids desconocidos no aparecen. */
16
+ export interface BackofficeSessionSummariesResult {
17
+ sessions: BackofficeSessionSummary[];
18
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -188,3 +188,6 @@ export * from './dtos/WizardSessionLookupEntry';
188
188
  export * from './dtos/responses/WizardSessionLookupResponse';
189
189
  export * from './dtos/responses/PrivateWizardSessionResponse';
190
190
  export * from './dtos/responses/SetAnchorGiftsResponse';
191
+ export * from './catalog/backofficeSessionSummaries';
192
+ export * from './dtos/requests/BackofficeSessionSummariesRequest';
193
+ export * from './dtos/responses/BackofficeSessionSummariesResponse';
@@ -224,3 +224,7 @@ __exportStar(require("./dtos/responses/WizardSessionLookupResponse"), exports);
224
224
  // M2M de Promociones (lectura privada de la sesión y regalo)
225
225
  __exportStar(require("./dtos/responses/PrivateWizardSessionResponse"), exports);
226
226
  __exportStar(require("./dtos/responses/SetAnchorGiftsResponse"), exports);
227
+ // Resúmenes de sesión para el cajón de inventario (POST /backoffice/wizard/sessions/summaries)
228
+ __exportStar(require("./catalog/backofficeSessionSummaries"), exports);
229
+ __exportStar(require("./dtos/requests/BackofficeSessionSummariesRequest"), exports);
230
+ __exportStar(require("./dtos/responses/BackofficeSessionSummariesResponse"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.589.0",
3
+ "version": "3.590.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -41,6 +41,25 @@ export interface InventoryPieceEntry {
41
41
  export interface InventoryStorePieces {
42
42
  storeId: string;
43
43
  pieces: InventoryPieceEntry[];
44
+ /** BALANCE#.available de la tienda; 0 sin BALANCE#. */
45
+ available?: number;
46
+ /** BALANCE#.reserved: apartadas por cantidad o con pieza HELD. */
47
+ reserved?: number;
48
+ /** Unidades que de verdad se pueden vender: min(available, piezas AVAILABLE). */
49
+ availableToSell?: number;
50
+ }
51
+
52
+ /** Reserva RES# viva de un SKU en una tienda, para la tarjeta "Apartados ahora" de la ficha. */
53
+ export interface InventoryLiveReservation {
54
+ storeId: string;
55
+ sessionId: string;
56
+ lineId: string;
57
+ reservationId: string;
58
+ quantity: number;
59
+ /** ISO en que vence la reserva. */
60
+ expiresAt: string;
61
+ /** ISO en que se apartó; null si la fila no trae createdAt. */
62
+ reservedAt: string | null;
44
63
  }
45
64
 
46
65
  /** Response de backofficeGetInventorySku: solo lo que la fila de filter=list no trae. */
@@ -56,6 +75,8 @@ export interface GetInventorySkuResponse {
56
75
  /** Promos de venta vigentes del SKU; `null` si retail-promotions no respondió. */
57
76
  promotions?: ActiveSalePromotionSummary[] | null;
58
77
  sources?: InventorySkuSources;
78
+ /** Reservas RES# vivas del SKU en todas las tiendas. */
79
+ liveReservations?: InventoryLiveReservation[];
59
80
  }
60
81
 
61
82
  /** Estado de las fuentes externas de la ficha. */
@@ -0,0 +1,5 @@
1
+ /** Techo de ids por request de `POST /backoffice/wizard/sessions/summaries`. */
2
+ export const BACKOFFICE_SESSION_SUMMARIES_MAX_IDS = 50;
3
+
4
+ /** Forma aceptada de un `sessionId`; la misma que el lote privado de sesiones. */
5
+ export const BACKOFFICE_SESSION_ID_PATTERN = /^[0-9A-Za-z_-]{1,64}$/;
@@ -0,0 +1,19 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { ArrayMaxSize, ArrayMinSize, IsArray, IsString, Matches } from 'class-validator';
3
+ import {
4
+ BACKOFFICE_SESSION_ID_PATTERN,
5
+ BACKOFFICE_SESSION_SUMMARIES_MAX_IDS,
6
+ } from '../../catalog/backofficeSessionSummaries';
7
+
8
+ /** Body de `POST /backoffice/wizard/sessions/summaries`. */
9
+ export class BackofficeSessionSummariesRequest {
10
+ @Expose()
11
+ @IsArray({ message: 'sessionIds debe ser una lista' })
12
+ @ArrayMinSize(1, { message: 'sessionIds debe traer al menos un id' })
13
+ @ArrayMaxSize(BACKOFFICE_SESSION_SUMMARIES_MAX_IDS, {
14
+ message: `sessionIds no puede pasar de ${BACKOFFICE_SESSION_SUMMARIES_MAX_IDS} ids`,
15
+ })
16
+ @IsString({ each: true, message: 'cada sessionId debe ser texto' })
17
+ @Matches(BACKOFFICE_SESSION_ID_PATTERN, { each: true, message: 'cada sessionId debe tener forma de id' })
18
+ sessionIds!: string[];
19
+ }
@@ -0,0 +1,20 @@
1
+ import type { WizardStateEnum } from '../../enums/WizardStateEnum';
2
+ import type { WizardStepEnum } from '../../enums/WizardStepEnum';
3
+
4
+ /** Resumen de una sesión para el cajón de inventario del backoffice. */
5
+ export interface BackofficeSessionSummary {
6
+ sessionId: string;
7
+ state: WizardStateEnum;
8
+ sellerName: string | null;
9
+ sellerRetailUserId: string | null;
10
+ storeId: string;
11
+ /** `true` si la sesión ya tiene cobro registrado. */
12
+ paid: boolean;
13
+ saleId: string | null;
14
+ currentStep: WizardStepEnum | null;
15
+ }
16
+
17
+ /** Respuesta de `POST /backoffice/wizard/sessions/summaries`; los ids desconocidos no aparecen. */
18
+ export interface BackofficeSessionSummariesResult {
19
+ sessions: BackofficeSessionSummary[];
20
+ }
@@ -219,3 +219,8 @@ export * from './dtos/responses/WizardSessionLookupResponse';
219
219
  // M2M de Promociones (lectura privada de la sesión y regalo)
220
220
  export * from './dtos/responses/PrivateWizardSessionResponse';
221
221
  export * from './dtos/responses/SetAnchorGiftsResponse';
222
+
223
+ // Resúmenes de sesión para el cajón de inventario (POST /backoffice/wizard/sessions/summaries)
224
+ export * from './catalog/backofficeSessionSummaries';
225
+ export * from './dtos/requests/BackofficeSessionSummariesRequest';
226
+ export * from './dtos/responses/BackofficeSessionSummariesResponse';