From b0a00d8c23a3f3be55f33398ebd7179d611ea8a5 Mon Sep 17 00:00:00 2001 From: NYD Date: Mon, 12 Jan 2026 11:15:26 +0900 Subject: [PATCH] fix_cow_list_search --- backend/src/cow/cow.service.ts | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/backend/src/cow/cow.service.ts b/backend/src/cow/cow.service.ts index 0b01e6e..7791b92 100644 --- a/backend/src/cow/cow.service.ts +++ b/backend/src/cow/cow.service.ts @@ -169,18 +169,22 @@ export class CowService { private async getFilteredCows(filterOptions?: any): Promise<{ cows: CowModel[], mptCowIdMap: Map }> { // Step 1: 4가지 데이터 소스에서 cowId 수집 (병렬 처리) const [genomeRequestCowIds, genomeCowIds, geneCowIds, mptCowIds] = await Promise.all([ - // 유전체 분석 의뢰가 있는 개체의 cowId (cow 테이블 조인) + // 유전체 분석 의뢰가 있고, 유효한 형질 데이터가 있는 개체의 cowId만 조회 + // (genomeScore가 null이지만 anlysDt가 있는 경우 제외) this.genomeRequestRepository .createQueryBuilder('request') .innerJoin('request.cow', 'cow') + .innerJoin('request.traitDetails', 'trait', 'trait.delDt IS NULL AND trait.traitEbv IS NOT NULL') .select('DISTINCT cow.cowId', 'cowId') .where('request.delDt IS NULL') + .andWhere('request.requestDt IS NOT NULL') .getRawMany(), - // 유전체 형질 데이터가 있는 cowId + // 유전체 형질 데이터가 있는 cowId (유효한 EBV 값이 있는 경우만) this.genomeTraitDetailRepository .createQueryBuilder('trait') .select('DISTINCT trait.cowId', 'cowId') .where('trait.delDt IS NULL') + .andWhere('trait.traitEbv IS NOT NULL') .getRawMany(), // 유전자 데이터가 있는 cowId this.geneDetailRepository @@ -465,8 +469,27 @@ export class CowService { // "criteriaType": "GENOME" // } - // Step 8: 점수 기준 내림차순 정렬 - const sorted = cowsWithScore.sort((a, b) => { + // Step 8: genomeScore(sortValue)가 null/undefined이고 anlysDt가 있는 데이터 제외 + // 단, 부모불일치인 개체는 조회되어야 하므로 제외하지 않음 + const filteredCows = cowsWithScore.filter((item) => { + const sortValue = item.sortValue; + const anlysDt = (item.entity as any).anlysDt; + const unavailableReason = (item.entity as any).unavailableReason; + + // 부모불일치 관련 사유인 경우는 조회 유지 + const isParentMismatch = unavailableReason === '부 불일치' || + unavailableReason === '모 불일치' || + unavailableReason === '모 이력제부재'; + + // sortValue가 null/undefined이고 anlysDt가 있지만, 부모불일치가 아닌 경우만 제외 + if ((sortValue === null || sortValue === undefined) && anlysDt && !isParentMismatch) { + return false; + } + return true; + }); + + // Step 9: 점수 기준 내림차순 정렬 + const sorted = filteredCows.sort((a, b) => { // null 값은 맨 뒤로 if (a.sortValue === null && b.sortValue === null) return 0; if (a.sortValue === null) return 1; @@ -475,7 +498,7 @@ export class CowService { return b.sortValue - a.sortValue; }); - // Step 9: 순위 부여 후 반환 + // Step 10: 순위 부여 후 반환 return { items: sorted.map((item, index) => ({ ...item,