diff --git a/apps/sn/app/(map-layout)/map/components/sinkhole/SinkholeDetailPanel.tsx b/apps/sn/app/(map-layout)/map/components/sinkhole/SinkholeDetailPanel.tsx index 9374c2a22..eca905925 100644 --- a/apps/sn/app/(map-layout)/map/components/sinkhole/SinkholeDetailPanel.tsx +++ b/apps/sn/app/(map-layout)/map/components/sinkhole/SinkholeDetailPanel.tsx @@ -25,6 +25,14 @@ const displayNumber = (value: unknown, suffix = "") => { return `${normalized.toLocaleString()}${suffix}`; }; +const parseElapsedYears = (value: unknown) => { + if (value === null || value === undefined || value === "") return null; + const normalized = Number(value); + return Number.isFinite(normalized) ? normalized : null; +}; + +const displayElapsedYears = (value: unknown) => displayNumber(value, "년"); + export default function SinkholeDetailPanel({ detail, nearbyPipes, @@ -33,6 +41,21 @@ export default function SinkholeDetailPanel({ onSelectPipe, }: Props) { const canShowNearby = String(detail.coordStatus ?? "").trim() === "SUCCESS"; + const nearbyPipeElapsedSummary = useMemo(() => { + const elapsedYears = nearbyPipes + .map((pipe) => parseElapsedYears(pipe.elapsedYears)) + .filter((value): value is number => value !== null); + + if (elapsedYears.length === 0) { + return { average: null, oldest: null }; + } + + const total = elapsedYears.reduce((sum, value) => sum + value, 0); + const average = Math.round((total / elapsedYears.length) * 10) / 10; + const oldest = Math.max(...elapsedYears); + + return { average, oldest }; + }, [nearbyPipes]); const summaryTableData = useMemo( () => [ { @@ -121,37 +144,58 @@ export default function SinkholeDetailPanel({
- - - + + + + - - - + + + + + {nearbyPipes.map((pipe, index) => ( onSelectPipe(pipe)} > - - - + diff --git a/apps/sn/app/(map-layout)/map/components/sinkhole/sinkholeTypes.ts b/apps/sn/app/(map-layout)/map/components/sinkhole/sinkholeTypes.ts index 34dec4588..8a344d4cd 100644 --- a/apps/sn/app/(map-layout)/map/components/sinkhole/sinkholeTypes.ts +++ b/apps/sn/app/(map-layout)/map/components/sinkhole/sinkholeTypes.ts @@ -66,6 +66,7 @@ export type SinkholeNearbyPipe = { pipeTypeName?: string; diameter?: number | string | null; length?: number | string | null; + elapsedYears?: number | string | null; distanceMeters?: number | string | null; }; diff --git a/apps/sn/docs/작업검증/SFR-010-010-지반침하정보/002-qa-SFR-010-010-지반침하정보-통합검증결과.md b/apps/sn/docs/작업검증/SFR-010-010-지반침하정보/002-qa-SFR-010-010-지반침하정보-통합검증결과.md index 45090a3ad..9d6525732 100644 --- a/apps/sn/docs/작업검증/SFR-010-010-지반침하정보/002-qa-SFR-010-010-지반침하정보-통합검증결과.md +++ b/apps/sn/docs/작업검증/SFR-010-010-지반침하정보/002-qa-SFR-010-010-지반침하정보-통합검증결과.md @@ -102,6 +102,27 @@ - 사용자 확인 완료 - 추가 브라우저 재현 캡처와 빌드 재실행은 이번 라운드에서 수행하지 않음 +### 2.14 2026-06-25 반경 내 관로정보 경과년도 컬럼 및 집계행 코드 검증 + +- 검증 대상 + - `FE_APP_ROOT/app/(map-layout)/map/components/sinkhole/SinkholeDetailPanel.tsx` + - `FE_APP_ROOT/app/(map-layout)/map/components/sinkhole/sinkholeTypes.ts` + - `BE_REPO_ROOT/src/main/java/iipbs/ms/domain/SinkholeNearbyPipeRepository.java` + - `BE_REPO_ROOT/src/main/java/iipbs/sewerage/api/sinkhole/dto/SinkholeNearbyPipeRowDto.java` +- 확인 내용 + - 백엔드 `nearbyPipes` row DTO에 `elapsedYears`가 추가되고 native query 결과 매핑 인덱스가 함께 조정됐는지 확인했다. + - 프론트 반경 내 관로정보 표에서 `용도` 컬럼을 제외하고 `경과년도` 컬럼과 최상단 집계행(`평균경과`, `최대경과`)이 추가되는지 코드 경로를 확인했다. + - `git diff --check`를 FE/BE 변경 파일 기준으로 실행해 공백 오류가 없음을 확인했다. + - 백엔드 `./gradlew.bat compileJava` 통과를 확인했다. +- 미확인 내용 + - FE `tsc --noEmit`은 로컬 `tsc` 명령 부재로 실행하지 못했다. + - 실제 브라우저에서 4개 컬럼과 집계행이 잘리지 않는지, API 응답 `elapsedYears` 값으로 평균/최대경과가 계산되는지는 개발서버 수동 검증이 필요하다. + +### 2.15 2026-06-25 반경 조회 회귀 방지 확인 +- `map/page.tsx`에 추가했던 반경 조회 fallback 변경을 제거하고, 기존 조회 흐름으로 원복했음을 확인했다. +- FE 컬럼 추가와 타입 추가, BE 응답 필드 추가만 남긴 상태에서 `git diff --check`를 다시 수행한다. +- 실제 브라우저에서 사고번호 `20260026`처럼 기존에 24건이 나오던 케이스가 그대로 유지되는지 재확인이 필요하다. + ## 3. 미실행 항목 - FE 브라우저 검증 diff --git a/apps/sn/docs/작업내용/SFR-010-010-지반침하정보/001-fe-SFR-010-010-지반침하정보-통합구현기록.md b/apps/sn/docs/작업내용/SFR-010-010-지반침하정보/001-fe-SFR-010-010-지반침하정보-통합구현기록.md index ab0b1098b..932fcb5d2 100644 --- a/apps/sn/docs/작업내용/SFR-010-010-지반침하정보/001-fe-SFR-010-010-지반침하정보-통합구현기록.md +++ b/apps/sn/docs/작업내용/SFR-010-010-지반침하정보/001-fe-SFR-010-010-지반침하정보-통합구현기록.md @@ -246,6 +246,18 @@ - 문제 PNG는 `sRGB`, `gAMA`, `pHYs` 부가 청크를 포함하고 있었고, 정상 로드되는 단순 RGBA PNG 중 `WTL_RSRV_PS_ORANGE.png`는 `IHDR`, `IDAT`, `IEND`만 가지고 있었다. - 이에 `SN_SINKHOLE_SPOT_ORANGE.png`, `SN_SINKHOLE_SPOT_BLUE.png`의 파일명과 픽셀은 유지하고, PNG 컨테이너만 `IHDR + IDAT + IEND` 구조로 재인코딩해 개발서버 정적 파일 처리 차이를 줄였다. +### 4.31 2026-06-25 반경 내 관로정보 경과년도 컬럼 및 집계행 추가 + +- 요구사항 변경으로 관로 `용도` 컬럼은 이번 범위에서 제외하고, 지반침하 상세 패널의 `침하발생 반경내 관로정보` 표에 `경과년도` 컬럼만 추가했다. +- 표는 `NO / 관로 ID / 경과년도 / 거리(m)` 4개 컬럼으로 구성하고, 본문 최상단에 집계 1행을 추가해 `평균경과`와 `최대경과`를 함께 표시한다. +- 집계값은 `nearbyPipes` 응답의 `elapsedYears` 중 숫자로 해석 가능한 값만 대상으로 계산하며, 계산 대상이 없으면 기존 표시 정책대로 `-`를 보여준다. +- 개별 행의 `경과년도`는 백엔드 `nearbyPipes` 응답에 추가한 `elapsedYears`를 사용한다. + +### 4.32 2026-06-25 반경 조회 흐름 원복 확인 + +- 기존 반경 내 관로 조회 기능은 정상 동작하던 기능이므로, `map/page.tsx`에 추가했던 좌표/사고번호 재조회 fallback 변경은 제거했다. +- FE 변경 범위는 `SinkholeDetailPanel.tsx`의 표 컬럼 추가와 `sinkholeTypes.ts`의 `elapsedYears` 타입 추가로 제한한다. + ## 5. 승인 전 보류 사항 - 목록 팝업을 `window popup`으로 열지 `/map` 내부 중앙 모달로 열지 확정 필요
+ NO + 관로 ID + + 경과년도 + 거리(m)
+ 평균경과 + + {displayElapsedYears(nearbyPipeElapsedSummary.average)} + + + 최대경과 + + {displayElapsedYears(nearbyPipeElapsedSummary.oldest)} + +
+ {index + 1} + {display(pipe.pipeId)} + + {displayElapsedYears(pipe.elapsedYears)} + {displayNumber(pipe.distanceMeters)}