- Bottling quality: water content above the legal limit (strict >) answers 409 CONFIRMATION_REQUIRED bound to the measured value; prefill for jar size, best-before (shelfLifeMonths, month-end clamping) and water content; impossible dates give 400; water-content checks in src/common/quality. - Frontend phenology: "Entwicklung melden" sheet, IndexedDB v4 queue, season header on the apiary page, confirmed revoke for all apiaries. - Frontend honey chain: "Vorschlag aus …" hints with explicit take-over, prefill status note, movement ledger with withdraw/correct dialogs. - Telegram: link tokens (hashed, single use), private-chat receiver with lease and offset CAS, bounded poison-update skip, Retry-After, pending deliveries skipped on disconnect; system API for deliveries and retry; worker-only secret wiring and manifest policy tests. - ARCHITECTURE.md §7, §9, §10, §11.11–11.13, Annahmen 51–55. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
90 lines
2.0 KiB
TypeScript
90 lines
2.0 KiB
TypeScript
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
import {
|
|
Max,
|
|
Min,
|
|
ArrayMaxSize,
|
|
ArrayUnique,
|
|
IsArray,
|
|
IsDateString,
|
|
IsIn,
|
|
IsInt,
|
|
IsNumber,
|
|
IsOptional,
|
|
IsPositive,
|
|
IsString,
|
|
} from 'class-validator';
|
|
|
|
export const BOTTLING_ACKNOWLEDGEABLE_WARNINGS = [
|
|
'WATER_CONTENT_ABOVE_LEGAL',
|
|
] as const;
|
|
export type AcknowledgeableWarning =
|
|
(typeof BOTTLING_ACKNOWLEDGEABLE_WARNINGS)[number];
|
|
|
|
export class CreateBottlingBatchDto {
|
|
@ApiProperty()
|
|
@IsString()
|
|
honeyBatchId!: string;
|
|
|
|
@ApiPropertyOptional()
|
|
@IsOptional()
|
|
@IsString()
|
|
productId?: string;
|
|
|
|
@ApiProperty()
|
|
@IsDateString({ strict: true })
|
|
date!: string;
|
|
|
|
@ApiPropertyOptional({
|
|
description:
|
|
'Glasgröße in Gramm. Fehlt sie, gilt die Packungsgröße des Artikels.',
|
|
})
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@IsPositive()
|
|
jarSize?: number;
|
|
|
|
@ApiProperty()
|
|
@IsInt()
|
|
@IsPositive()
|
|
jarCount!: number;
|
|
|
|
@ApiPropertyOptional({
|
|
description:
|
|
'MHD. Fehlt es, gilt Abfülldatum plus Haltbarkeit des Artikels (Monatsende abgeschnitten).',
|
|
})
|
|
@IsOptional()
|
|
@IsDateString({ strict: true })
|
|
bestBeforeDate?: string;
|
|
|
|
@ApiPropertyOptional({
|
|
description:
|
|
'Wird automatisch generiert, falls die Automatisierung "Los-/Chargennummer-Format" aktiv ist',
|
|
})
|
|
@IsOptional()
|
|
@IsString()
|
|
lotNumber?: string;
|
|
|
|
@ApiPropertyOptional({
|
|
enum: BOTTLING_ACKNOWLEDGEABLE_WARNINGS,
|
|
isArray: true,
|
|
description:
|
|
'Bestätigte Warnungen. Über der gesetzlichen Wassergehaltsgrenze nötig, sonst 409 CONFIRMATION_REQUIRED.',
|
|
})
|
|
@IsOptional()
|
|
@IsArray()
|
|
@ArrayMaxSize(1)
|
|
@ArrayUnique()
|
|
@IsIn(BOTTLING_ACKNOWLEDGEABLE_WARNINGS, { each: true })
|
|
acknowledgedWarnings?: AcknowledgeableWarning[];
|
|
|
|
@ApiPropertyOptional({
|
|
description:
|
|
'Der Wassergehalt (%), den die Bestätigung meint: der Wert aus der 409-Antwort. Weicht der geprüfte Wert ab, folgt eine neue 409.',
|
|
})
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
@Max(100)
|
|
acknowledgedWaterContent?: number;
|
|
}
|