관망도 업로드 수정

This commit is contained in:
2026-08-28 15:45:43 +09:00
parent 884dd71ca7
commit 201dbf577f
14 changed files with 274 additions and 60 deletions
@@ -600,3 +600,18 @@
| 선형 시설 회귀 | 정적 통과 | 기존 스타일 뒤에 선형 선택 강조를 추가하는 순서 유지 |
| 변경 공백·구문 검사 | 통과 | `git diff --check`, `node --check` 수행 |
| 브라우저 수동 검증 | 대기 | 맨홀 클릭 후 보라색 맨홀 심볼과 선택 원이 함께 유지되는지 확인 필요 |
## 38. 2026-08-28 조사 입력양식 다운로드 검증
| 검증 항목 | 결과 | 근거 |
| --- | --- | --- |
| 저장 전 클릭 안내 | 통과 | `사업정보를 먼저 저장해주세요.` 안내 표출 확인 |
| 등록 화면 사업별 양식 버튼 | 통과 | `양식다운로드` 버튼 0개 |
| 등록 화면 공통 보고서 양식 | 통과 | `조사보고서 양식다운로드` 버튼 1개 유지 |
| 수정 화면 사업별 양식 버튼 | 통과 | 저장 사업 `신사업`에서 `양식다운로드` 버튼 1개 |
| 수정 화면 공통 보고서 양식 | 통과 | `조사보고서 양식다운로드` 버튼 1개 유지 |
| 실제 파일 생성 | 통과 | `신사업_조사입력양식 (2).xlsx`, 188,261바이트 생성 |
| 정적 검사 | 통과 | 전체 TypeScript, 대상 Prettier, `git diff --check` 통과 |
| Next build | 미수행 | 사용자 실행 중인 3002 개발서버 보호 기준에 따라 생략 |
- API·DB 변경 없음. 판정: PASS.
@@ -338,3 +338,36 @@ Chrome 확장의 파일 URL 접근 권한이 꺼져 있어 이번 회귀에서 E
| 공통 선택 스타일 | 통과 | 별도 준설 CSS 없이 기존 `bg-accent !text-primary` 규칙 적용 |
| 브라우저 콘솔 | 통과 | 새 검증 탭 경고·오류 0건 |
| Next build | 미수행 | 사용자가 실행한 3002 개발 서버 보호 기준에 따라 생략 |
## 14. 2026-08-28 일반 HTTP 준설 등록 팝업 회귀검증
| 검증 항목 | 결과 | 근거 |
| --- | --- | --- |
| 원격 오류 재현 | 통과 | `con.mind-one.co.kr:11302`에서 client-side exception과 `crypto.randomUUID is not a function` 확인 |
| 비보안 컨텍스트 조건 | 통과 | LAN HTTP 개발주소에서 `isSecureContext=false`, `crypto` 미제공 확인 |
| UUID fallback | 통과 | Web Crypto `getRandomValues`만 있는 경우와 `crypto`가 없는 경우 모두 UUID v4 정규식 통과 |
| 로컬 HMR 팝업 | 통과 | 등록 건 1, 사진 업로드, 위치 지정, 지도 영역이 정상 렌더링되고 오류·경고 0건 |
| 준설 직접 호출 제거 | 통과 | 기능 파일의 직접 호출을 제거하고 `lib/uuid.ts` 공통 함수 한 곳으로 집중 |
| TypeScript | 통과 | SN 전체 `tsc --noEmit --ignoreDeprecations 5.0` 종료코드 0 |
| Prettier·공백 검사 | 통과 | 변경 5개 파일 Prettier 및 `git diff --check` 통과 |
| Next build | 미수행 | 사용자 실행 중인 3002 개발서버 보호 기준에 따라 생략 |
- 수정 전 원격 증빙: `COMMON_DOCS_ROOT/작업내용/SFR-010-012-준설관리/검증/20260828/01-원격HTTP-randomUUID-오류.png`.
- 수정 후 로컬 증빙: `COMMON_DOCS_ROOT/작업내용/SFR-010-012-준설관리/검증/20260828/02-로컬-수정후-준설등록-정상.png`.
- 원격 11302 서버는 아직 수정 코드가 배포되지 않았으므로 배포 후 같은 URL의 최종 회귀검증이 필요하다.
## 15. 2026-08-28 등록·수정 촬영일시 날짜 표출 검증
| 검증 항목 | 결과 | 근거 |
| --- | --- | --- |
| ISO 일시 | 통과 | `2026-06-20T15:47:45 → 2026-06-20` |
| 공백 구분 일시 | 통과 | `2026-07-18 16:12:57 → 2026-07-18` |
| 날짜 단독 | 통과 | `2026-02-14 → 2026-02-14` |
| 잘못된 날짜·빈 값 | 통과 | `2026-02-30`, null, 빈 문자열은 fallback 처리 |
| 등록 화면 | 통과 | 사진 표의 촬영일시 cell과 title에 공통 날짜 포맷 함수 적용 |
| 수정 화면 | 통과 | 기존 사진 3건이 `2026-06-20`, `2026-07-18`로 표출되고 시간 미표시 확인 |
| 저장 계약 | 통과 | `clientCapturedAt`에는 기존 원본 일시를 그대로 전달 |
| 정적 검사 | 통과 | 전체 TypeScript, 대상 Prettier, `git diff --check` 통과 |
- 검증 화면: `COMMON_DOCS_ROOT/작업내용/SFR-010-012-준설관리/검증/20260828/03-수정화면-촬영일자-날짜만.png`.
- 사용자 실행 중인 3002 개발서버를 보호하기 위해 Next build는 수행하지 않았다.
@@ -293,3 +293,23 @@
- 10초는 로컬 warm 11.2MB·16,670건 조건의 통과 결과이며 운영 SLA 보증이 아니다.
- 증빙: `COMMON_DOCS_ROOT/작업내용/SFR-012-002-하수관망도 업로드/검증/20260807/10s/23-performance-summary.json`
- 최종 데이터 대조: 같은 폴더의 `22-final-feature-comparison.json`
## 9. 2026-08-28 관리기관 콤보박스 목록 검증
- 개발서버 API 확인:
- `GET /api/v1/map/gisUploadFacilityTypes?screenId=SN_MN010302`: 하수관로 시설유형 1건, HTTP 200.
- `GET /api/v1/fcltppl/mngInsts`: 관리기관 160건, 빈 관리기관코드 0건, HTTP 200.
- 수정 후 실제 Chrome 개발서버 팝업에서 관리기관 콤보박스 161개 옵션(`선택` 1개 + 관리기관 160개)을 확인했다.
- `가평군(4160000)`을 선택한 뒤 GIS 업로드 이력 목록과 다운로드·조회 버튼 활성화를 확인했다.
- Prettier, SN 전체 TypeScript, `git diff --check`를 통과했다.
- 사용자 소유 개발서버 3002·8883은 종료·재시작하지 않았고 `next build`는 수행하지 않았다.
- 증빙: `COMMON_DOCS_ROOT/작업내용/SFR-012-002-하수관망도 업로드/검증/20260828/01-GIS관리-관리기관-가평군-선택.png`.
- 판정: PASS.
## 10. 2026-08-28 GIS 관리 목록 버튼 문구 검증
- 기본 GIS 업로드 목록 액션에서 `목록` 버튼 표출을 확인했다.
- 오류 확인 화면에서도 같은 버튼이 `목록`으로 표시됐다.
- 오류 화면의 `목록` 클릭 시 `GIS 업로드 목록`으로 정상 복귀했다.
- 전체 TypeScript, 대상 Prettier와 `git diff --check`를 통과했다.
- API·DB 변경 없음. 판정: PASS.
@@ -934,3 +934,10 @@
- Excel 데이터 내보내기는 `엑셀다운로드`, 입력 템플릿은 `양식다운로드`, 일반 첨부파일은 `다운로드`로 구분했다.
- `StandardPopupLayout` 본문을 margin 기반 `space-y` 대신 `flex`와 `gap: 1.2rem`으로 변경했다. 자식 카드의 `!m-0` 때문에 간격이 0으로 덮이던 문제를 공통 레이아웃에서 해결했다.
- 브라우저에서 조사사업 등록·수정의 `사업 정보`와 `사업대상 처리분구` 카드 사이 실제 간격이 모두 12px인 것을 확인했다.
## 45. 2026-08-28 조사 입력양식 다운로드 노출·Blob 처리 보완
- 사업별 조사 입력양식은 저장된 `exmnBizId`와 확정 처리분구가 있어야 생성할 수 있으므로 신규 등록 화면에서는 `양식다운로드` 버튼을 숨겼다.
- 수정 화면에는 `양식다운로드`를 유지하고, 저장과 무관한 공통 `조사보고서 양식다운로드`는 등록·수정 모두 유지한다.
- Blob 다운로드 링크를 DOM에 연결한 뒤 클릭하고 1초 후 object URL을 해제하도록 변경해 Chrome가 파일을 수락하기 전에 URL이 사라지는 문제를 방지했다.
- 사업·처리분구 저장, 양식 생성 API와 DB 계약은 변경하지 않았다.
@@ -333,3 +333,23 @@
- 수정 화면은 기존과 같이 관로정보·준설일자·사진·위치·자동매핑 정보를 모두 제공하므로 조회에 필요한 정보 확인과 편집 기능은 유지된다.
- 수정 화면에서도 사용하는 검색 파라미터 복원 로직은 중립 유틸 파일로 분리했으며 API, 저장 payload, 부모창 갱신 메시지는 변경하지 않았다.
- 요구사항정의서 sheet3의 `SFR-010-013`은 준설 등록·수정·삭제·조회를 요구하지만 별도 상세 버튼을 강제하지 않는다. 화면설계서 슬라이드 51의 `SN_MN040201`과 슬라이드 53의 `SN_MN040202`도 등록·조회·다운로드 중심이며, 슬라이드 57의 별도 세부현황은 `화면 삭제`로 표시되어 있다.
## 20. 2026-08-28 일반 HTTP 준설 팝업 UUID 호환성 보완
- 원격 `http://con.mind-one.co.kr:11302/popup/dredgingRegister`에서 `crypto.randomUUID is not a function` 예외로 등록 팝업이 렌더링 전에 중단됐다.
- `localhost`는 브라우저가 보안 컨텍스트 예외로 취급하지만 일반 HTTP 주소에서는 `crypto.randomUUID()` 또는 `crypto` 자체가 제공되지 않을 수 있다.
- `lib/uuid.ts`에 준설 전용 UUID v4 생성 함수를 추가했다.
- `crypto.randomUUID`가 있으면 기존 동작을 유지한다.
- 없으면 `crypto.getRandomValues`를 사용하고 UUID version·variant 비트를 적용한다.
- Web Crypto 자체가 없으면 36자 UUID v4 형식을 유지하는 최종 fallback을 사용한다.
- 등록 건 ID, 신규 사진 key, 수정 사진 key, 백엔드 `clientRequestId`, mock 작업번호의 직접 `randomUUID` 호출을 모두 공통 함수로 교체했다.
- 백엔드 UUID 계약, 등록 payload, DB 구조는 변경하지 않았다.
- 추적 근거: 요구사항정의서 `SFR-010-012` G84, 화면설계서 슬라이드 53~59와 화면 ID `SN_MN040201~040203`.
## 21. 2026-08-28 촬영일시 날짜 표출 통일
- 등록 화면 사진 표와 수정 화면의 기존·신규 사진 목록에서 촬영일시를 `YYYY-MM-DD`까지만 표시한다.
- `lib/date.ts`에 촬영일시 표출 전용 함수를 추가해 ISO `T` 구분, 공백 구분과 날짜 단독 문자열을 같은 형식으로 처리한다.
- 존재하지 않는 날짜나 빈 값은 기존 화면별 fallback(`-`, `촬영일시 없음`)을 유지한다.
- EXIF 원본 `capturedAt`, 첨부정보와 백엔드 저장 payload는 변경하지 않고 화면 렌더링만 변경했다.
- 추적 근거는 요구사항 `SFR-010-012`, 화면설계서 슬라이드 53의 `SN_MN040201`이며 세부 시간 숨김은 사용자 지시에 따른 표출 보완이다.
@@ -145,3 +145,28 @@
- 두 파일 모두 16,670건, EPSG:5179, SQLite 무결성 `ok`
- `fid INTEGER PRIMARY KEY` 단일 컬럼과 공간 인덱스 확인
- 최종 브라우저 콘솔 오류 및 경고 없음
## 8. 2026-08-28 GIS 관리 관리기관 목록 초기화 보완
### 8.1 추적 근거
- 화면설계서 슬라이드 35 `SN_MN010302`, 요구사항 `SFR-012-002`의 GIS 관리 팝업·시설정보 선택·업로드 흐름을 기준으로 확인했다.
- 요구사항정의서 `3. (기능)요구사항정의 및 추적표`의 `SFR-012-002`를 대조했다.
### 8.2 원인
- 팝업 초기화가 시설유형 API와 관리기관 API를 하나의 `Promise.all` 및 단일 `try/catch`로 처리했다.
- 어느 한 API라도 일시 실패하면 관리기관 API가 정상이어도 `setMngInstOptions`가 실행되지 않아 콤보박스에는 `선택`만 남았다.
### 8.3 변경 내용
- 시설유형과 관리기관 조회를 독립 비동기 함수로 분리했다.
- 시설유형 조회 실패 시 기본 하수관로 설정을 유지하고, 관리기관 조회 결과는 별도로 정렬·반영한다.
- 관리기관 조회 실패와 정상 빈 결과를 구분한 사용자 안내를 추가했다.
- BE API·DB·업로드/다운로드 계약은 변경하지 않았다.
### 8.4 GIS 업로드 목록 이동 버튼 문구
- 업로드 이력을 다시 조회하고 목록 화면으로 전환하는 버튼명을 `조회`에서 `목록`으로 변경했다.
- 기본 업로드 이력 화면과 오류·미리보기 화면의 동일 액션 문구를 함께 통일했다.
- 버튼 이벤트와 API 요청은 변경하지 않았다.