Files
genome2025/backend/src/cow/dto/ranking-request.dto.ts
2025-12-24 08:25:44 +09:00

138 lines
3.2 KiB
TypeScript

/**
* ============================================================
* 랭킹 요청 DTO
* ============================================================
*
* 사용 페이지: 개체 목록 페이지 (/cow)
*
* 프론트에서 POST /cow/ranking 호출 시 사용
*
* 지원하는 랭킹 기준:
* 1. GENOME - 35개 유전체 형질 EBV 가중치 기반
* ============================================================
*/
import {
IsEnum,
IsOptional,
IsArray,
IsString,
IsNumber,
Min,
Max,
ValidateNested,
} from 'class-validator';
import { Type } from 'class-transformer';
import {
FilterCondition,
SortOption,
PaginationOption,
FilterEngineOptions,
} from '../../shared/filter/interfaces/filter.interface';
import { RankingCriteriaType } from '../../common/const/RankingCriteriaType';
// Re-export for convenience
export { RankingCriteriaType };
// ============================================================
// 랭킹 조건 DTO
// ============================================================
/**
* 유전체 형질 랭킹 조건
* - 35개 형질 중 사용자가 선택한 형질만 대상
* - weight: 1~10 가중치 (10이 100%)
*
* 예: { traitNm: '도체중', weight: 8 }
*/
export class TraitRankingConditionDto {
@IsString()
traitNm: string; // 형질명 (예: '도체중', '근내지방도')
@IsOptional()
@IsNumber()
@Min(1)
@Max(10)
weight?: number; // 가중치 1~10 (기본값: 1)
}
/**
* 랭킹 옵션 DTO
*/
export class RankingOptionsDto {
@IsEnum(RankingCriteriaType)
criteriaType: RankingCriteriaType; // 랭킹 기준 타입
@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => TraitRankingConditionDto)
traitConditions?: TraitRankingConditionDto[]; // GENOME용: 형질별 가중치
@IsOptional()
@IsNumber()
@Min(1)
limit?: number;
@IsOptional()
@IsNumber()
@Min(0)
offset?: number;
}
// ============================================================
// 필터 옵션 DTO (FilterEngine용)
// ============================================================
/**
* 필터 엔진 옵션 DTO
* - 개체 목록 필터링에 사용
*/
export class FilterEngineOptionsDto implements FilterEngineOptions {
@IsOptional()
@IsArray()
filters?: FilterCondition[];
@IsOptional()
@IsArray()
sorts?: SortOption[];
@IsOptional()
pagination?: PaginationOption;
}
// ============================================================
// 메인 요청 DTO
// ============================================================
/**
* 랭킹 요청 DTO
*
* 프론트에서 POST /cow/ranking 호출 시 Body로 전송
*
* @example
* {
* filterOptions: {
* filters: [{ field: 'cowSex', operator: 'eq', value: 'F' }],
* pagination: { page: 1, limit: 20 }
* },
* rankingOptions: {
* criteriaType: 'GENOME',
* traitConditions: [
* { traitNm: '도체중', weight: 8 },
* { traitNm: '근내지방도', weight: 10 }
* ]
* }
* }
*/
export class RankingRequestDto {
@IsOptional()
@ValidateNested()
@Type(() => FilterEngineOptionsDto)
filterOptions?: FilterEngineOptionsDto; // 필터/정렬/페이지네이션
@ValidateNested()
@Type(() => RankingOptionsDto)
rankingOptions: RankingOptionsDto; // 랭킹 조건
}