POST /enfants pour gestionnaire/admin avec parent_user_id, liens foyer, multipart photo optionnel ; UI modale création + sélection famille. Co-authored-by: Cursor <cursoragent@cursor.com>
95 lines
2.6 KiB
TypeScript
95 lines
2.6 KiB
TypeScript
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
import { Transform } from 'class-transformer';
|
|
import {
|
|
IsBoolean,
|
|
IsDateString,
|
|
IsEnum,
|
|
IsNotEmpty,
|
|
IsOptional,
|
|
IsString,
|
|
IsUUID,
|
|
MaxLength,
|
|
ValidateIf,
|
|
} from 'class-validator';
|
|
import { GenreType, StatutEnfantType } from 'src/entities/children.entity';
|
|
|
|
/** Multipart envoie des strings ("true"/"false") — JSON envoie déjà des booleans. */
|
|
function toBoolean({ value }: { value: unknown }): boolean | unknown {
|
|
if (typeof value === 'boolean') return value;
|
|
if (typeof value === 'string') {
|
|
const v = value.trim().toLowerCase();
|
|
if (v === 'true' || v === '1') return true;
|
|
if (v === 'false' || v === '0' || v === '') return false;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
export class CreateEnfantsDto {
|
|
@ApiProperty({ enum: StatutEnfantType, example: StatutEnfantType.SANS_GARDE })
|
|
@IsEnum(StatutEnfantType)
|
|
@IsNotEmpty()
|
|
status: StatutEnfantType;
|
|
|
|
@ApiProperty({ example: 'Georges', required: false })
|
|
@IsOptional()
|
|
@IsString()
|
|
@MaxLength(100)
|
|
first_name?: string;
|
|
|
|
@ApiProperty({ example: 'Dupont', required: false })
|
|
@IsOptional()
|
|
@IsString()
|
|
@MaxLength(100)
|
|
last_name?: string;
|
|
|
|
@ApiProperty({ enum: GenreType })
|
|
@IsEnum(GenreType)
|
|
@IsNotEmpty()
|
|
gender: GenreType;
|
|
|
|
@ApiProperty({ example: '2018-06-24', required: false })
|
|
@ValidateIf(o => o.status !== StatutEnfantType.A_NAITRE)
|
|
@IsOptional()
|
|
@IsDateString()
|
|
birth_date?: string;
|
|
|
|
@ApiProperty({ example: '2025-12-15', required: false })
|
|
@ValidateIf(o => o.status === StatutEnfantType.A_NAITRE)
|
|
@IsOptional()
|
|
@IsDateString()
|
|
due_date?: string;
|
|
|
|
@ApiProperty({ example: 'https://monimage.com/photo.jpg', required: false })
|
|
@IsOptional()
|
|
@IsString()
|
|
photo_url?: string;
|
|
|
|
@ApiProperty({ default: false })
|
|
@Transform(toBoolean)
|
|
@IsBoolean()
|
|
consent_photo: boolean;
|
|
|
|
@ApiProperty({ required: false })
|
|
@IsOptional()
|
|
@IsDateString()
|
|
consent_photo_at?: string;
|
|
|
|
@ApiProperty({ default: false })
|
|
@Transform(toBoolean)
|
|
@IsBoolean()
|
|
is_multiple: boolean;
|
|
|
|
/**
|
|
* Parent pivot du foyer — obligatoire pour staff (gestionnaire/admin).
|
|
* Ignoré / interdit en externe pour un PARENT (ticket #132).
|
|
*/
|
|
@ApiPropertyOptional({
|
|
description:
|
|
'UUID du parent pivot (staff only). Obligatoire pour GESTIONNAIRE / ADMIN / SUPER_ADMIN.',
|
|
format: 'uuid',
|
|
})
|
|
@IsOptional()
|
|
@IsUUID('4')
|
|
parent_user_id?: string;
|
|
}
|