fix: reject negative weights/quantities and out-of-range percentages
None of these numeric business fields had a lower bound, so a negative honey weight, jar count, feeding amount, mite count, or stock quantity was silently accepted - each would corrupt whatever total or statistic it later feeds into. Added @Min(0): - Harvest: honeySuperCount, grossWeight, netWeight - HoneyBatch: amount (+ @Max(100) on waterContent, a percentage) - HoneyMeasurement: waterContent (+ @Max(100)) - Feeding: amount - Extraction: amount (+ @Max(100) on waterContent) - StockItem: quantity, minThreshold - VarroaMeasurement: durationMinutes, miteCount, calculatedValue Left temperature fields alone (extraction, inspection) - genuinely can be negative (winter inspections, outdoor storage) and no confident domain bound exists to apply instead. Update DTOs for these entities all extend PartialType(PickType(Create...Dto, [...])) from @nestjs/swagger, which preserves validation decorators, so no separate change was needed there. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
1 parent
93d0f2b208
commit
b208f52fd1
7 files changed
+32
-3
No files matched your search
@@ -6,6 +6,8 @@ import {
|
|||||||
IsNumber,
|
IsNumber,
|
||||||
IsOptional,
|
IsOptional,
|
||||||
IsString,
|
IsString,
|
||||||
|
Max,
|
||||||
|
Min,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
|
|
||||||
export class CreateExtractionDto {
|
export class CreateExtractionDto {
|
||||||
@@ -22,6 +24,7 @@ export class CreateExtractionDto {
|
|||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
amount?: number;
|
amount?: number;
|
||||||
|
|
||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
@@ -32,6 +35,8 @@ export class CreateExtractionDto {
|
|||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
|
@Max(100)
|
||||||
waterContent?: number;
|
waterContent?: number;
|
||||||
|
|
||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
IsNumber,
|
IsNumber,
|
||||||
IsOptional,
|
IsOptional,
|
||||||
IsString,
|
IsString,
|
||||||
|
Min,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { FeedType } from '../../../generated/prisma';
|
import { FeedType } from '../../../generated/prisma';
|
||||||
|
|
||||||
@@ -28,6 +29,7 @@ export class CreateFeedingDto {
|
|||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
amount!: number;
|
amount!: number;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
IsNumber,
|
IsNumber,
|
||||||
IsOptional,
|
IsOptional,
|
||||||
IsString,
|
IsString,
|
||||||
|
Min,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
|
|
||||||
export class CreateHarvestDto {
|
export class CreateHarvestDto {
|
||||||
@@ -32,16 +33,19 @@ export class CreateHarvestDto {
|
|||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@Min(0)
|
||||||
honeySuperCount?: number;
|
honeySuperCount?: number;
|
||||||
|
|
||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
grossWeight?: number;
|
grossWeight?: number;
|
||||||
|
|
||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
netWeight?: number;
|
netWeight?: number;
|
||||||
|
|
||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
import { IsNumber, IsOptional, IsString } from 'class-validator';
|
import { IsNumber, IsOptional, IsString, Max, Min } from 'class-validator';
|
||||||
|
|
||||||
export class CreateHoneyBatchDto {
|
export class CreateHoneyBatchDto {
|
||||||
@ApiPropertyOptional({
|
@ApiPropertyOptional({
|
||||||
@@ -22,11 +22,14 @@ export class CreateHoneyBatchDto {
|
|||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
amount?: number;
|
amount?: number;
|
||||||
|
|
||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
|
@Max(100)
|
||||||
waterContent?: number;
|
waterContent?: number;
|
||||||
|
|
||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
import { IsDateString, IsNumber, IsOptional, IsString } from 'class-validator';
|
import {
|
||||||
|
IsDateString,
|
||||||
|
IsNumber,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
|
Max,
|
||||||
|
Min,
|
||||||
|
} from 'class-validator';
|
||||||
|
|
||||||
export class CreateHoneyMeasurementDto {
|
export class CreateHoneyMeasurementDto {
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
|
@Max(100)
|
||||||
waterContent!: number;
|
waterContent!: number;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
import { IsEnum, IsNumber, IsOptional, IsString } from 'class-validator';
|
import { IsEnum, IsNumber, IsOptional, IsString, Min } from 'class-validator';
|
||||||
import { StockCategory } from '../../../generated/prisma';
|
import { StockCategory } from '../../../generated/prisma';
|
||||||
|
|
||||||
export class CreateStockItemDto {
|
export class CreateStockItemDto {
|
||||||
@@ -18,11 +18,13 @@ export class CreateStockItemDto {
|
|||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
quantity?: number;
|
quantity?: number;
|
||||||
|
|
||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
minThreshold?: number;
|
minThreshold?: number;
|
||||||
|
|
||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
IsNumber,
|
IsNumber,
|
||||||
IsOptional,
|
IsOptional,
|
||||||
IsString,
|
IsString,
|
||||||
|
Min,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { VarroaMethod } from '../../../generated/prisma';
|
import { VarroaMethod } from '../../../generated/prisma';
|
||||||
|
|
||||||
@@ -25,16 +26,19 @@ export class CreateVarroaMeasurementDto {
|
|||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@Min(0)
|
||||||
durationMinutes?: number;
|
durationMinutes?: number;
|
||||||
|
|
||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@Min(0)
|
||||||
miteCount?: number;
|
miteCount?: number;
|
||||||
|
|
||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
calculatedValue?: number;
|
calculatedValue?: number;
|
||||||
|
|
||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
|
|||||||
Reference in new issue
Block a user