Files
kooltab-backoffice/apps/api/src/devices/dto/sync.dto.ts
T
brammie15 0ca9f4d16a
CI / build-and-test (push) Canceled after 0s
feat: make server own tabs
2026-10-20 16:18:36 +02:00

103 lines
2.6 KiB
TypeScript

import { IsString, IsOptional, IsArray, IsInt, Min, IsUUID, ValidateNested, ArrayMaxSize, IsNotEmpty, MaxLength } from 'class-validator';
import { Type } from 'class-transformer';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
export class OpenTabItemDto {
@ApiProperty({ example: 'Cola' })
@IsString()
@IsNotEmpty()
@MaxLength(200)
productName: string;
@ApiProperty({ example: 10 })
@IsInt()
@Min(0)
quantity: number;
@ApiProperty({ example: 250 })
@IsInt()
@Min(0)
unitPriceInCents: number;
}
export class OpenTabDto {
@ApiProperty({ example: 'local-tab-uuid' })
@IsString()
@IsNotEmpty()
id: string;
@ApiProperty({ example: 'Jan' })
@IsString()
customerName: string;
@ApiProperty({ example: 5 })
@IsInt()
@Min(0)
version: number;
@ApiProperty({ example: 2450 })
@IsInt()
@Min(0)
totalInCents: number;
@ApiProperty({ example: 3 })
@IsInt()
@Min(0)
itemCount: number;
@ApiPropertyOptional({ type: [OpenTabItemDto], description: 'Lines on the tab; omitted by older app versions' })
@IsOptional()
@IsArray()
@ArrayMaxSize(500)
@ValidateNested({ each: true })
@Type(() => OpenTabItemDto)
items?: OpenTabItemDto[];
}
export class SyncDto {
@ApiProperty({ example: 'uuid' })
@IsUUID()
deviceId: string;
@ApiPropertyOptional({ example: 'cursor-value' })
@IsOptional()
@IsString()
cursor?: string;
@ApiPropertyOptional({ description: 'Where the settlements feed left off; absent on the first sync after pairing' })
@IsOptional()
@IsString()
@MaxLength(100)
settlementsCursor?: string;
// The server holds the tabs: only used once, to take over the terminal's tabs on its first sync
@ApiProperty({ type: [OpenTabDto] })
@IsArray()
@ArrayMaxSize(1000)
@ValidateNested({ each: true })
@Type(() => OpenTabDto)
openTabs: OpenTabDto[];
// Validated one by one in the service: a bad event is rejected on its own instead of failing the sync
@ApiPropertyOptional({ description: 'TabEventDto[]: what happened on tabs since the last acknowledged sync' })
@IsOptional()
@IsArray()
@ArrayMaxSize(1000)
events?: unknown[];
// Validated one by one in the service, like events
@ApiPropertyOptional({
description: "ReportedProductDto[]: the terminal's complete product catalog with stock. Omitted by app versions without stock",
})
@IsOptional()
@IsArray()
@ArrayMaxSize(2000)
products?: unknown[];
@ApiPropertyOptional({ description: 'StockAdjustmentResultDto[]: outcomes of stock adjustments the terminal received' })
@IsOptional()
@IsArray()
@ArrayMaxSize(1000)
stockAdjustmentResults?: unknown[];
}