From cae9f9438854392e0b88381ae10d7ac01f08147c Mon Sep 17 00:00:00 2001 From: bicochan Date: Fri, 24 Jul 2026 09:57:40 +0900 Subject: [PATCH] =?UTF-8?q?[as]=20docs:=20=EC=84=A4=EA=B3=84=EC=9E=90?= =?UTF-8?q?=EB=AC=B8=20=EA=B5=AC=ED=98=84=20=EB=AC=B8=EC=84=9C=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sewer-bsc-plan/dmbp-regist-migration.md | 632 ++++++++++++++++++ 1 file changed, 632 insertions(+) create mode 100644 apps/as/docs/sewer-bsc-plan/dmbp-regist-migration.md diff --git a/apps/as/docs/sewer-bsc-plan/dmbp-regist-migration.md b/apps/as/docs/sewer-bsc-plan/dmbp-regist-migration.md new file mode 100644 index 000000000..47f1047b1 --- /dev/null +++ b/apps/as/docs/sewer-bsc-plan/dmbp-regist-migration.md @@ -0,0 +1,632 @@ +# dmbpRegist.jsp → React 마이그레이션 분석·구현 가이드 + +| 항목 | 내용 | +| ----------- | ------------------------------------------------------ | +| 원본 JSP | `adssNewOld/.../fnrsc/dmbp/dmbpRegist.jsp` | +| 대상 앱 | `frontend/apps/as` | +| 도메인 | 하수도기본계획 (구: 기본계획검토 / dmbp) | +| API 엔티티 | `@/entities/sewer-bsc-plan` (`SewerBscPlanController`) | +| 참조 패턴 | `@/pages/fnrs-cnsltn` + `@/widgets/pbadms-sprt` | +| 문서 목적 | contents 영역 **섹션별** UI·상태·API 매핑 및 구현 방향 | +| 작성 기준일 | 2026-07-23 | + +--- + +## 1. 마이그레이션 범위 + +### 1-1. 포함 (contents만) + +JSP `568~1274`행: `
` ~ `` + +| 영역 | JSP 식별 | 개요 | +| ---- | ---------------------------------- | --------------------------------------------------------------- | +| A | `gTitle1` | 페이지 타이틀·브레드크럼 | +| B | `slide_10` | 기본계획변경 신청(마스터·연도·개요) | +| C | `slide_15` | 신청자·설계자 정보 | +| D | `slide_19` | 개인정보 동의 | +| E | `slide_11` | 사업개요(단계별 인구·보급률) | +| F | `slide_12` | 총사업비(단계×원가 계층) | +| G | `slide_13` | 재원분담 | +| H | `slide_14` | 처리시설별 하수도정비기본계획 | +| I | `slide_16` | 체크리스트 + 필수첨부 + 기타첨부 | +| J | JSP 상단 `saveBtn` / `presentnBtn` | React: sticky FAB (`floating-action-buttons` − 환경청제출·반려) | + +### 1-2. 제외 + +- `<%@ include %>`: top / sideMenu / footer / `bscPlnPopup.jsp` / `sndrdBzAmnt.jsp` +- 레이아웃·메뉴·권한 셸 → 기존 `BaseLayout` / `PageLayout` / AUTH 체계 +- `mStep1` 진행 단계 표시 (미구현 · 마이그레이션 범위 밖) + +팝업(`이전기본계획조회`)은 **별도 Dialog 컴포넌트**로 재구현하며, include JSP 자체는 포팅하지 않는다. + +--- + +## 2. 목표 아키텍처 + +``` +app/(with-base-layout)/sewer-bsc-plan/regist/page.tsx + └─ pages/sewer-bsc-plan/ui/sewer-bsc-plan-regist-page.tsx + └─ sewer-bsc-plan-form-page.tsx # FormProvider + 섹션 조립 + ├─ sections/*-form-section.tsx # 도메인 전용 + └─ widgets/pbadms-sprt/* # 공통 재사용 + +entities/sewer-bsc-plan/ # 이미 구현됨 + saveApply / findDetails / submitSupplement … +``` + +**폼 스택 (fnrs-cnsltn과 동일)** + +- `react-hook-form` + `zod` (`zodResolver`, `mode: "onChange"`) +- 섹션 래퍼: `SectionCollapsible` (Accordion 아님) +- UI: `@common/components` (Input, Select, Textarea, Button, Radio, Tabs, Table 등) +- 그리드가 필요한 곳만 `@tanstack/react-table` + `DataTable` +- 데이터: React Query (`useSaveApplySewerBscPlan` 등) — 목데이터는 API 미연동 구간만 `@faker-js/faker` + +**Vercel React Best Practices (적용 요약)** + +- `client-swr-dedup`: React Query로 체크리스트/필수첨부/코드 조회 중복 제거 +- `bundle-dynamic-imports`: 처리시설 동적 표·이전계획 Dialog는 `next/dynamic` 후보 +- `rerender-derived-state`: 단계 연도·합계·진행률은 render 중 파생, 불필요 effect 금지 +- `async-parallel`: 등록 진입 시 코드/체크리스트트리/필수첨부트리를 병렬 조회 + +--- + +## 3. 전체 레이아웃 + +`fnrs-form-page.tsx`와 동일한 **FormProvider + 세로 섹션 스택** 구조를 따르고, +하단 액션바는 **`floating-action-buttons.tsx`와 동일 구성에서「환경청제출」「반려」만 제외**한다. +타이틀·브레드크럼은 폼 밖(`PageLayout` / regist·edit·view 셸)에서 처리한다. + +### 3-1. 컴포넌트 트리 (fnrs 대응) + +``` +PageLayout (title / breadcrumb) +└─ SewerBscPlanRegistPage | SewerBscPlanEditPage | SewerBscPlanViewPage + └─ SewerBscPlanFormPage | SewerBscPlanViewPage 본문 + FormProvider (등록/수정) / 읽기 섹션 (상세) + └─ + ├─ BasicInfoFormSection // JSP slide_10 + ├─ ContactInfoFormSection // JSP slide_15 (pbadms-sprt) + ├─ PrivacyConsentSection // JSP slide_19 (pbadms-sprt, 등록·수정) + ├─ OutlineFormSection // JSP slide_11 (사업개요, 신규) + ├─ BusinessCostFormSection // JSP slide_12 (pbadms-sprt, 1차) + ├─ FnrsCstFormSection // JSP slide_13 (재원분담, 신규 ※ FnrsShar 아님) + ├─ TmplntFormSection // JSP slide_14 (처리시설, 신규) + ├─ ChecklistFormSection // JSP slide_16 (pbadms-sprt) + ├─ AttachmentsFormSection // JSP 필수·기타첨부 (pbadms-sprt) + ├─ SplmntDmndFormSection // edit + SL 상태만 (pbadms-sprt) + └─ sticky bottom action bar // FloatingActionButtons 계열 + // = fnrs floating-action-buttons.tsx 와 동일 구성 + // 단, 「재원협의 고시」「환경청제출」「반려」 제외 +``` + +**sticky bottom action bar 버튼 구성** +기준: [`floating-action-buttons.tsx`](../../src/pages/fnrs-cnsltn/ui/components/floating-action-buttons.tsx) 렌더 순서. +표시 여부는 역할·`prgrsSttsComCd`·결재단계에 따른 `getButtonConfigs` (sewer용 button-config로 이관). + +| 순서 | 버튼 | 조건/액션 키 (fnrs) | sewer 비고 | +| ---- | ----------------- | -------------------------------- | ------------------------------------------- | +| 1 | 목록 | 항상 | `/sewer-bsc-plan` | +| 2 | 수정 | `canEdit` (등록자 + `strg` 가능) | edit 라우트 | +| 3 | 저장 | `strg` | `saveApply` / SV | +| 4 | 신청완료 | `aply` | 체크리스트+필수첨부 검증 → `saveApply` / LE | +| 5 | 삭제 | `del` | `delete` | +| — | ~~재원협의 고시~~ | `fnrsCnsltnAncmnt` | **제외** | +| — | ~~환경청제출~~ | `envoSbmsn` | **제외** | +| — | ~~반려~~ | `rjct` | **제외** | +| — | ~~인가승인~~ | `sncnAprv` | **제외** | +| 6 | 검토결과 회신 | `rvwRply` | | +| 7 | 기술검토 의뢰 | `rqstTechRvw` | | +| 8 | 검토자지정 | `dsgntRvwr` | ElaprTmpltPickerDialog | +| 9 | 저장 (검토) | `rvwStrg` | `techReview` 저장 분기 | +| 10 | 검토완료 | `rvwCmptn` | `techReview` 완료 분기 | +| 11 | 보완요청 | `dmndSplmnt` | SplmntDmndDialog + `submitReqSupplement` | +| 12 | 결재(승인) | `atrzAprv` | ElaprApprovalDialog | +| 13 | 결재(회신) | `atrzRply` | ElaprApprovalDialog | + +**fnrs와의 차이 (섹션 치환만, 골격 동일)** + +| fnrs-form-page / FAB | sewer-bsc-plan | +| ------------------------------------------ | ------------------------------------------------ | +| `BasicInfoFormSection` | 동일 역할 (마스터·연도·개요 필드는 sewer DTO) | +| `ContactInfoFormSection` | 동일 (`fieldPrefix="sewerBscPlanDtl"`) | +| `PrivacyConsentSection` | 동일 | +| `BusinessScaleFormSection` | → `OutlineFormSection` (단계별 인구·보급률) | +| `BusinessCostFormSection` | 동일 재사용 (회계트리) | +| `FnrsSharFormSection` | → `FnrsCstFormSection` (국고·지방비·원인자·기타) | +| _(없음)_ | `TmplntFormSection` (처리시설 매트릭스) | +| `ChecklistFormSection` `docSeComCd="FNRS"` | `docSeComCd="SEWER"` (TBD) | +| `AttachmentsFormSection` | 동일 패턴 | +| `SplmntDmndFormSection` | 동일 (`readOnly={!isSplmntPrgrsStts}`) | +| sticky FAB (전체) | **동일, 단 `환경청제출`·`반려` 제외** | + +### 3-2. 본문 ASCII (폼 페이지) + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ PageLayout: 하수도기본계획 신청/수정 breadcrumb │ +├─────────────────────────────────────────────────────────────────┤ +│ FormProvider │ +│
│ +│ │ +│ ┌─ SectionCollapsible: 기본계획 신청 ─────────────────────┐ │ +│ │ BasicInfoFormSection │ │ +│ └──────────────────────────────────────────────────────────┘ │ +│ ┌─ 신청자 정보 ────────────────────────────────────────────┐ │ +│ │ ContactInfoFormSection │ │ +│ └──────────────────────────────────────────────────────────┘ │ +│ ┌─ 개인정보 동의 ──────────────────────────────────────────┐ │ +│ │ PrivacyConsentSection │ │ +│ └──────────────────────────────────────────────────────────┘ │ +│ ┌─ 사업개요 ────────────── [이전기본계획조회] ─────────────┐ │ +│ │ OutlineFormSection │ │ +│ └──────────────────────────────────────────────────────────┘ │ +│ ┌─ 총사업비 (백만원) ──────────────────────────────────────┐ │ +│ │ BusinessCostFormSection │ │ +│ └──────────────────────────────────────────────────────────┘ │ +│ ┌─ 재원분담 (백만원) ──────────────────────────────────────┐ │ +│ │ FnrsCstFormSection │ │ +│ └──────────────────────────────────────────────────────────┘ │ +│ ┌─ 처리시설별 하수도정비기본계획 ──────────────────────────┐ │ +│ │ TmplntFormSection │ │ +│ └──────────────────────────────────────────────────────────┘ │ +│ ┌─ 체크리스트 ─────────────────────────────────────────────┐ │ +│ │ ChecklistFormSection │ │ +│ └──────────────────────────────────────────────────────────┘ │ +│ ┌─ 첨부파일 ───────────────────────────────────────────────┐ │ +│ │ AttachmentsFormSection │ │ +│ └──────────────────────────────────────────────────────────┘ │ +│ ┌─ 보완요구 (edit + SL) ───────────────────────────────────┐ │ +│ │ SplmntDmndFormSection │ │ +│ └──────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─ sticky bottom (FloatingActionButtons, 환경청제출·반려 제외) ──┐ │ +│ │ [목록] [수정] [저장] [신청완료] [삭제] │ │ +│ │ [검토결과 회신] [기술검토 의뢰] [검토자지정] │ │ +│ │ [저장(검토)] [검토완료] [보완요청] [결재(승인)] [결재(회신)] │ │ +│ │ * 라벨/핸들러는 sewer 도메인 명칭 TBD │ │ +│ │ ※ 역할·진행상태별 표시 — 한 화면에 전부 노출되지 않음 │ │ +│ └────────────────────────────────────────────────────────────────┘ │ +│
│ +└─────────────────────────────────────────────────────────────────┘ +``` + +### 3-3. 액션바 동작 (`floating-action-buttons` 동일, 환경청제출·반려 제외) + +구현체: `pages/sewer-bsc-plan/ui/components/floating-action-buttons.tsx` +(fnrs FAB를 복제하되 `envoSbmsn`·`rjct` 렌더·핸들러 제거) + +| 버튼 | 액션 키 | 대표 동작 | +| ------------- | ------------- | -------------------------------------------------------------- | +| 목록 | — | `router.push("/sewer-bsc-plan")` | +| 수정 | — (`canEdit`) | `/sewer-bsc-plan/[id]/edit` | +| 저장 | `strg` | `saveApply` + `SV` | +| 신청완료 | `aply` | 체크리스트 완료 + **필수 첨부 완료** 검증 → `saveApply` + `LE` | +| 삭제 | `del` | confirm → `delete` → 목록 | +| 검토결과 회신 | `rvwRply` | 진행상태 갱신 | +| 기술검토 의뢰 | `rqstTechRvw` | 진행상태 갱신 | +| 검토자지정 | `dsgntRvwr` | ElaprTmpltPickerDialog | +| 저장 (검토) | `rvwStrg` | `techReview` (저장) | +| 검토완료 | `rvwCmptn` | `techReview` (검토완료) | +| 보완요청 | `dmndSplmnt` | SplmntDmndDialog → `submitReqSupplement` | +| 결재(승인) | `atrzAprv` | ElaprApprovalDialog | +| 결재(회신) | `atrzRply` | ElaprApprovalDialog | + +**신청완료(`aply`) 사전 검증** + +1. **체크리스트**: `isFormChecklistComplete(cklstResultList)` — 미완료 시 `"모든 체크리스트 항목을 체크해야 신청이 가능합니다."` +2. **필수 첨부**: `esntlAtchYn === "Y"`인 필수첨부 슬롯마다 `esntlAtchFileList`에 `atchFileGroupId`가 있어야 함 + - Form: `AttachmentsFormSection`의 트리 + 폼 `esntlAtchFileList` + - View(FAB): `data.esntlFileList`에서 필수 항목의 `atflCd`(또는 동등 그룹 ID) 존재 여부 + - 미충족 시 예: `"필수 첨부파일을 모두 등록해야 신청이 가능합니다."` + - 헬퍼 후보: `isFormEsntlAtchComplete(requiredTree, esntlAtchFileList)` (`pbadms-sprt`에 추가, Form/FAB 공용) + +저장(`strg`)에는 위 검증을 적용하지 않는다 (임시저장 허용). + +저장/제출 버튼을 섹션 헤더(`gTitle2 gRt`)에 두지 않는다 — **sticky FAB 단일 진입점**. + +### 3-4. 라우트 + +| 화면 | path | 셸 → FormPage | +| ---- | --------------------------- | ------------------------------------------ | +| 등록 | `/sewer-bsc-plan/regist` | `mode="create"` | +| 수정 | `/sewer-bsc-plan/[id]/edit` | `mode="edit"` + `useSewerBscPlanDetails` | +| 상세 | `/sewer-bsc-plan/[id]` | ViewPage (본 문서 범위 밖, fnrs-view 대응) | + +`docSeComCd` 후보: 백엔드 체크리스트·필수첨부 등록값 확인 후 **`SEWER`** (또는 레거시 `DMBP`) — **TBD, CMS 코드와 맞출 것**. + +--- + +## 4. 섹션별 상세 구현 + +### 4-0. Hidden / 세션 컨텍스트 (폼 루트) + +JSP hidden → React 폼 기본값·세션 스토어로 흡수. + +| JSP | 의미 | React | +| ------------------------------- | --------------- | ------------------------------------------------------- | +| `chgSe` / `chgSeSp` / `chgSeCd` | 변경구분 | `sewerBscPlan.sewerBscPlanSeComCd` + 표시용 코드명 | +| `progrsSttus` | SAVE / PRESENTN | 저장·제출 시 `prgrsSttsComCd`로 매핑 (임시저장 vs 제출) | +| `planSeCd` | 고정 `A` | 필요 시 상수 또는 API 필드 확인 | +| `adstDstrCd` / `rgnCd` | 행정구역 | `sewerBscPlan.admdstCd` | +| `sidoNm` / `gugunNm` | 표시용 | 읽기 전용 표시 (`detDto.sido`/`gugun`) | + +구현: `getCreateDefaultValues(userInfo)`에서 로그인 사용자·소속 지자체 주입. + +--- + +### 4-A. 타이틀·브레드크럼 + +| JSP | React | +| ------------------------ | ------------------------------------------------------ | +| `h3` 기본계획검토 | PageLayout title: **하수도기본계획 신청** (IIPBS 명명) | +| 설치인가 및 제원협의 > … | 메뉴 메타 기반 breadcrumb | + +별도 섹션 컴포넌트 불필요. 라우트 `page.tsx` / layout metadata로 처리. + +--- + +### 4-B. 기본계획변경 신청 (`slide_10`) + +**파일**: `ui/sections/basic-info-form-section.tsx` +**래퍼**: `SectionCollapsible` title=`기본계획 신청` +**필드 접두사**: `sewerBscPlan.*` + `sewerBscPlanDtl.*` + +| 표시명 | JSP | API 매핑 | UI | 필수 | 비고 | +| ---------------- | ----------------- | ------------------------------- | ------------------ | ---- | ---------------------------------- | +| 기본계획명 | `drngMtncPlanNm` | `sewerBscPlan.sewerBscPlanNm` | Input | Y | | +| 계획년도 | `planYr` | `sewerBscPlanDtl.planYr` | Select (현재~2005) | Y | | +| 기준년도 | `crtrYr` | `sewerBscPlanDtl.crtrYr` | Select | Y | | +| 1~4단계 목표연도 | `goalYrStep1~4` | `frlvlGoalYr`~`folvlGoalYr` | Select (현재~+30) | Y | 1단계 변경 시 +5/+10/+15 자동 연동 | +| 계획개요 | `bzCn` | `sewerBscPlanDtl.bizOtlnCn` | Textarea | Y | | +| 구분 | `#chgSeNm` | `sewerBscPlanSeComCd` (+코드명) | 읽기 또는 Select | | 신규/변경 등 | +| 신청 지자체 | `${lclgvrnmntNm}` | `admdstCd` | 읽기 전용 | | | + +**동작** + +- `goalYrStep1` onChange → 2·3·4단계 기본값 세팅 + E/F/G 헤더 연도 span 갱신 (`watch` 파생) +- JSP 상단 `gRt` 저장/제출은 사용하지 않음 → FormPage sticky 하단 액션바 (§3-3) + +--- + +### 4-C. 신청자 정보 (`slide_15`) + +**재사용**: `@/widgets/pbadms-sprt`의 `ContactInfoFormSection` +**props**: `fieldPrefix="sewerBscPlanDtl"` (또는 dtl 필드 구조에 맞게) + +| 표시 | JSP | API | +| ---------------------------- | --------------------------- | --------------------------------------------------------------------------------------- | +| 신청자 이름/전화/부서/이메일 | `${UsrNm}` 등 서버렌더 | 로그인 사용자 읽기 전용 → `aplcntNm`, `aplcntMblTelno`, `aplcntOgdpNm`, `aplcntEmlAddr` | +| 설계자 | `dsgnrNm/Telno/Psitn/Email` | `dsgnrNm`, `dsgnrTelno`, `dsgnrOgdpNm`, `dsgnrEmlAddr` | + +신청자 4필드는 세션에서 defaultValues에 채우고 Input `disabled`. + +--- + +### 4-D. 개인정보 동의 (`slide_19`) + +**재사용**: `PrivacyConsentSection` + +| JSP | React | +| ----------------------------- | ------------------------------------------------------------------ | +| 고지 textarea + 보유기간 문구 | 동일 문구 상수/마크다운 | +| `privacyAgree` Y/N | 폼 필드 `privacyAgree: "Y" \| "N"` (API 미전송, 클라이언트 검증만) | + +**검증**: 제출 시 `Y` 필수 (JSP `presentnBtn`과 동일). 저장(임시)은 동의 없이 허용할지 정책 TBD — 기본은 JSP와 같이 **제출만 강제**. + +--- + +### 4-E. 사업개요 (`slide_11`) + +**파일**: `ui/sections/outline-form-section.tsx` (신규, 도메인 전용) +**API**: `sewerBscPlanOtlnList: SewerBscPlanOtlnItem[]` (planStpNo 1~4) + +| 행(구분) | JSP name | Item 필드 | +| ------------ | --------------- | ------------------- | +| 계획인구 | `arrPlanPpltn` | `sewerPlanPpltnCnt` | +| 처리인구 | `arrPrcsPpltn` | `sewerPrcsPpltnCnt` | +| 하수도보급율 | `arrDrngSplyRt` | `sewerPsplyRt` | + +열: 1~4단계 (헤더에 `frlvlGoalYr` 등 표시). + +**버튼**: `이전기본계획조회` → Dialog (`PreviousPlanLookupDialog`) + +- 레거시: `fnbscPlnPopupToggle` + `bscPlnPopup.jsp` +- React: Modal + 조회 API (**TBD**: 이전 계획 조회 엔드포인트; 없으면 1차는 Dialog UI만 + mock) + +숫자 입력: 콤마 제거 후 number 전송 (제출 시 JSP `replaceComma` 대체). + +--- + +### 4-F. 총사업비 (`slide_12`) + +**JSP 현실**: 단계(1~4) × 원가 계층(총사업비, 공사비, 처리시설, 하수관로 신설/보수, 펌프장, 배수설비, 기타, 부대경비, 설계/감리/부대비). 일부 readonly·자동합산 JS. + +**신규 API 현실**: `bizCstList: SewerBscPlanBizCstItem[]` = `{ planStpNo, acntgSeCd, cstrnAmt }` +→ **회계구분 트리(`acntg-se`) 기반 행**으로 모델링 (fnrs `BusinessCostFormSection`과 동일 철학). + +**구현 방향** + +1. **1차(권장)**: `BusinessCostFormSection` 재사용 + `useAcntgSeMngTree` + - JSP 계층 라벨은 회계코드 트리 depth로 표현 + - 합계 행은 `buildAcntgCostItems` / 파생 합계 +2. **JSP 픽셀 단위 복제**가 필요하면: `BizCstMatrixFormSection` 전용 컴포넌트 + 저장 시 `acntgSeCd` 매핑 테이블 — 비용↑, 백엔드 코드 정의 선행 필요 + +단위 표시: `백만원` (섹션 헤더 우측). + +**표준사업비 조회** 버튼은 JSP에서 주석 처리됨 → **미구현**. + +--- + +### 4-G. 재원분담 (`slide_13`) + +**주의**: fnrs의 `FnrsSharFormSection`(재원협의 공유구분 트리)과 **다름**. + +| 행 | JSP | `SewerBscPlanFnrsCstItem` | +| ------------ | -------------- | ------------------------- | +| 총사업비 | `arrTotAmnt` | `sumAmt` (또는 파생) | +| 국고 | `arrNlepAmt` | `gvexpAmt` | +| 지방비 | `arrLcepAmt` | `lcexpAmt` | +| 원인자부담금 | `arrCusrAlotm` | `orgprBdchgAmt` | +| 기타 | `arrEtcAmt` | `etcAmt` | + +**파일**: `ui/sections/fnrs-cst-form-section.tsx` (신규) +데이터: `fnrsCstList` 길이 4 (`planStpNo` 1~4). + +검증(선택): 단계별 `gvexp+lcexp+orgpr+etc === sumAmt` (JSP `calculateTotalFunding` 참고). + +--- + +### 4-H. 처리시설별 하수도정비기본계획 (`slide_14`) — 핵심 복잡도 + +**JSP 동작** + +1. `BscFctList` 체크박스로 처리시설 다중 선택 (`arrBscFctCd`) +2. 선택 시 `createFormSection(code, name)`로 **당초 4단계 | 현재 | 변경 4단계** 매트릭스 동적 삽입 +3. 활성 `formFields`(축소판): 처리구역면적, 하수처리인구, 계획하수량, 시설용량, 분류식 오수/우수, 합류식, 차집, 배수설비, 오수중계/일반/우수 펌프 +4. 시설별 필수첨부 `createFileAttachmentSection` +5. `fetchBasicPlanData`로 당초(이전) 데이터 바인딩 + +**API 매핑** + +| UI | DTO | +| -------------------- | ------------------------------------------------------------- | +| 선택 시설 목록 | `sewerBscPlanTmplntList[].swtrmtFcltCd` (+ `atchFileGroupId`) | +| 단계별 수치 (변경측) | `sewerBscPlanTmplntDtlList[]` → `SewerBscPlanTmplntDtlItem` | +| 임시저장 | `tmplntTmprStrgList` (편집 중 임시, 필요 시) | + +필드 대응 (변경 단계 기준): + +| UI 라벨 | `SewerBscPlanTmplntDtlItem` | +| -------------- | --------------------------- | +| 처리구역면적 | `prcsZoneArea` | +| 하수처리인구 | `swtrmtPpltnCnt` | +| 계획하수량 | `planSwqty` | +| 시설용량 | `fcltCpct` | +| 분류식 오수 | `sprsysDrtwPplLen` | +| 분류식 우수 | `sprsysExlnPplLen` | +| 합류식 | `cbsysPplLen` | +| 차집관로 | `icptgPplLen` | +| 배수설비 | `drgCnt` | +| 오수 중계 펌프 | `drtwRlyPumpCnt` | +| 오수 일반 펌프 | `drtwPumpCnt` | +| 우수 펌프 | `exlnPumpCnt` | + +**구현 구성** + +``` +ui/sections/tmplnt-form-section.tsx + ├─ TmplntFacilityPicker # Checkbox 목록 (시설 마스터 API TBD) + ├─ TmplntMatrixTable # 시설 1개당 표 (useFieldArray) + └─ TmplntFacilityAttachments # 시설별 필수첨부 (선택) +``` + +- 체크 추가 → `useFieldArray` append; 해제 → remove + confirm +- **당초 열**: 이전계획 API 조회 결과 읽기 전용 (없으면 빈 칸) +- **현재 열**: 기준년도 시점 값 (API 제공 시) +- **변경 열**: 편집 가능 → 저장 payload의 dtl만 전송 +- 시설 마스터 목록 API: 레거시 `BscFctList` 대체 — **TBD** (`swtrmtFclt` 계열) + +`bundle-dynamic-imports`: 매트릭스 섹션을 dynamic import 권장. + +--- + +### 4-I. 체크리스트 + 첨부 (`slide_16`) + +#### I-1. 체크리스트 + +**재사용**: `ChecklistFormSection` +`docSeComCd=""` +`fieldPrefix`: 마스터에서 `taskSeComCd`를 읽는 경로 (예: `sewerBscPlan`) + +| JSP | React | +| ----------------------- | ------------------------------------------- | +| 업무탭 `ceckEssntlArr` | 코드 `taskSeComCd` 다중 → Tabs | +| 진행률 / 전체 예·아니오 | 위젯 내장 로직 | +| `exmntResult` Y/N | `cklstResultList[].selected` (+ `picRvwCn`) | + +저장: `cklstResultList: CklstResultItem[]` + +#### I-2. 필수 첨부 (탭별) + +**재사용**: `AttachmentsFormSection` +`docSeComCd` 동일, `esntlAtchFileList` + +레거시: 체크리스트 탭마다 `essntlList` + `uploadFile` multipart. +신규: TUS/`attach-service` + `esntlAtchFileId` / `atchFileGroupId` (fnrs와 동일). + +#### I-3. 기타 첨부 + +`AttachmentsFormSection`의 etc 영역 또는 `atchFileGroupId` on `sewerBscPlanDtl`. +JSP `uploadFileETC` multiple → Zip 안내 문구 유지. + +--- + +### 4-J. 저장 / 제출 + +| JSP | 진행값 | URL | React | +| ---- | ---------- | ------------------------- | -------------------------------------------------------------------- | +| 저장 | `SAVE` | `insertFnrscDmbp.do` | `useSaveApplySewerBscPlan` + `prgrsSttsComCd` = 임시저장 코드 | +| 제출 | `PRESENTN` | `insertFnrscDscss.do` (!) | 동일 `saveApply` 또는 제출용 상태코드 — **백엔드 상태코드 확인 TBD** | + +페이로드 조립 (`buildApplyPayload`): + +```ts +SewerBscPlanApplySaveRequestDto { + sewerBscPlan, sewerBscPlanDtl, + sewerBscPlanOtlnList, bizCstList, fnrsCstList, + sewerBscPlanTmplntList, tmplntTmprStrgList?, + cklstResultList, esntlAtchFileList, + splmntDmndList?, rvwOpnnList? // 등록 화면에서는 보통 빈 배열 +} +``` + +성공 후: `invalidateQueries(sewerBscPlanBaseKey)` → `router.push('/sewer-bsc-plan')`. + +권한: JSP `AUTH3` → 기존 AS 권한 훅/역할로 버튼 `disabled`/`hidden`. + +--- + +## 5. API / DTO 연결 + +Base: `/as-service/api/v1/sewer-bsc-plans` +엔티티: `@/entities/sewer-bsc-plan` + +| 화면 동작 | Hook / Service | 비고 | +| -------------- | ---------------------------------------- | ---------------- | +| 등록 저장·제출 | `useSaveApplySewerBscPlan` → `saveApply` | 본 문서 핵심 | +| 수정 로드 | `useSewerBscPlanDetails(docNo, chgCycl)` | 편집 시 | +| 마스터만 | `useSewerBscPlan` | 목록 행 클릭 등 | +| 보완 제출 | `useSubmitSupplementSewerBscPlan` | 등록 JSP 범위 밖 | +| 기술검토 | `useTechReviewSewerBscPlan` | 등록 JSP 범위 밖 | + +등록 JSP에 없는 섹션(보완요구·검토의견)은 **상세/검토 화면**에서 `SplmntDmndFormSection` / 검토의견 섹션으로 후속 구현. + +--- + +## 6. 권장 파일 배치 + +``` +apps/as/ +├── app/(with-base-layout)/sewer-bsc-plan/ +│ └── regist/page.tsx +├── src/pages/sewer-bsc-plan/ +│ ├── lib/ +│ │ ├── sewer-bsc-plan-regist-schema.ts # zod +│ │ └── form-data-mapper.ts # Det ↔ Form, Apply payload +│ ├── model/ +│ │ └── (필요 시 table columns) +│ └── ui/ +│ ├── sewer-bsc-plan-regist-page.tsx +│ ├── sewer-bsc-plan-form-page.tsx +│ ├── components/ +│ │ ├── floating-action-buttons.tsx +│ │ └── previous-plan-lookup-dialog.tsx +│ └── sections/ +│ ├── basic-info-form-section.tsx +│ ├── outline-form-section.tsx # 사업개요 +│ ├── fnrs-cst-form-section.tsx # 재원분담 +│ └── tmplnt-form-section.tsx # 처리시설 +└── docs/sewer-bsc-plan/ + └── dmbp-regist-migration.md # 본 문서 +``` + +공통 재사용 (신규 작성 최소화): + +- `ContactInfoFormSection`, `PrivacyConsentSection` +- `ChecklistFormSection`, `AttachmentsFormSection` +- `BusinessCostFormSection` (총사업비 1차안) +- `SectionCollapsible` + +--- + +## 7. 화면 데이터 흐름 + +``` +BEGIN + + // 최초 진입 (등록) + CALL 로그인사용자조회 + CALL 코드조회(SEWERBSCPLANSE, SEWER, …) // 병렬 + CALL 체크리스트트리(docSeComCd) // 병렬 + CALL 필수첨부트리(docSeComCd) // 병렬 + CALL 회계구분트리 // 총사업비용 + CALL 처리시설마스터목록 // TBD + DISPLAY 폼 defaultValues + + ON 1단계목표연도 CHANGE DO + SET 2·3·4단계 연도 (+5/+10/+15) + DISPLAY E/F/G/H 헤더 연도 + END ON + + ON 처리시설 체크 DO + ADD tmplntList 항목 + 매트릭스 UI + CALL 이전기본계획수치(시설코드) // 당초열, TBD + END ON + + ON [이전기본계획조회] CLICK DO + OPEN PreviousPlanLookupDialog + END ON + + ON [저장] CLICK DO + VALIDATE zod (동의 제외 가능) + CALL saveApply(payload, 임시저장 상태) + NAVIGATE 목록 + END ON + + ON [신청완료] CLICK DO + VALIDATE zod + privacyAgree=Y + 체크리스트 완료 + 필수첨부(esntlAtchYn=Y) 완료 + CONFIRM 신청 확인 + CALL saveApply(payload, 제출 상태 LE) + NAVIGATE 상세 + END ON + +END +``` + +--- + +## 8. JSP ↔ 신규 갭·리스크 + +| # | 이슈 | 대응 | +| --- | ---------------------------------------------------- | ------------------------------------------------- | +| 1 | JSP 제출 URL이 `dscss`로 분기 (오타/구프로세스 가능) | 신규는 `saveApply` 단일 진입으로 통일 | +| 2 | 총사업비 UI 계층 ≠ `BizCstItem` | 회계트리 매핑 우선; 픽셀 복제는 2차 | +| 3 | 재원분담 ≠ fnrs shar | 전용 `fnrs-cst-form-section` | +| 4 | 처리시설 매트릭스(당초/현재/변경) | 저장은 변경 dtl 중심; 당초는 조회 전용 | +| 5 | 시설·이전계획 API | TBD — 미정 시 체크박스 목록 mock(`faker`)만 | +| 6 | `docSeComCd` 값 | CMS/체크리스트 마스터와 합의 | +| 7 | 레거시 multipart vs TUS | fnrs 첨부 패턴 준수 | +| 8 | 주석 처리된 상세 `formFields` (자연발생인구 등) | **축소된 formFields만** 이관; 주석 블록 복원 금지 | + +--- + +## 9. 구현 순서 (권장) + +1. 라우트 + `FormPage` 골격 + zod 스키마(마스터·dtl·동의) +2. B·C·D 섹션 (공통 위젯 최대 활용) +3. E 사업개요 + G 재원분담 (4열 매트릭스 패턴 공유) +4. F 총사업비 (`BusinessCostFormSection` 연동) +5. I 체크리스트·첨부 +6. H 처리시설 (가장 복잡 — 마지막) +7. 저장/제출 + 권한 +8. 이전계획 Dialog (API 확정 후) + +--- + +## 10. 체크리스트 (jsp-migration-as) + +- [ ] contents만 이관 (include 제외) +- [ ] vercel-react-best-practices 적용 (Query 병렬·파생상태·dynamic) +- [ ] `@common/components` + 필요 시 DataTable +- [ ] API·모델은 `@/entities/sewer-bsc-plan` 우선 +- [ ] 목데이터는 `@faker-js/faker`만 (시설 마스터 등 TBD 구간) +- [ ] 로딩·빈·에러 상태 +- [ ] `router.push`로 목록 복귀 + +--- + +## 11. 후속 문서 + +- 목록(`dmbpList.jsp`) / 상세(`dmbpView.jsp`) / 수정(`dmbpModify.jsp`)은 본 문서와 동일 섹션 체계로 별도 확장 +- 화면설계서 SPEC 형식이 필요하면 `docs/sewer-bsc-plan/SPEC.md`로 분리 (영역 A~J 표 + API 표)