103 lines
2.6 KiB
TypeScript
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[];
|
|
}
|