Files
frontend/apps/as/docs/sewer-bsc-plan/dmbp-regist-migration.md
T

40 KiB

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-27

1. 마이그레이션 범위

1-1. 포함 (contents만)

JSP 568~1274행: <div class="contents"> ~ <!-- //contents -->

영역 JSP 식별 개요
A gTitle1 페이지 타이틀·브레드크럼
B slide_10 기본계획변경 신청(마스터·연도·개요)
C slide_15 신청자·설계자 정보
D slide_19 개인정보 동의
E slide_11 사업개요(단계별 인구·보급률)
F slide_12 총사업비 — BizCstMatrixFormSection 전용
G slide_13 재원분담
H slide_14 처리시설별 하수도정비기본계획 (Checkbox + Tabs)
I slide_16 체크리스트 + 필수첨부 + 기타첨부
J JSP 상단 saveBtn / presentnBtn React: 폼 하단 액션바 (fnrs-form-page 279~323과 동일 구성, API만 sewer)

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: 처리시설 Tabs 패널·이전계획 Dialog는 next/dynamic 후보
  • rerender-derived-state: 단계 연도·합계·진행률은 render 중 파생, 불필요 effect 금지
  • async-parallel: 등록 진입 시 코드/체크리스트트리/필수첨부트리를 병렬 조회

3. 전체 레이아웃

fnrs-form-page.tsx와 동일한 FormProvider + 세로 섹션 스택 구조를 따르고,
하단 액션바는 fnrs-form-page.tsx 279~323 과 동일 구성(목록·저장·신청완료·삭제·보완완료)이며 API/라우트만 sewer 로 바꾼다.
타이틀·브레드크럼은 폼 밖(PageLayout / regist·edit·view 셸)에서 처리한다.
(상세 View의 sticky FAB·검토/결재 버튼은 본 등록 문서 범위 밖 — fnrs-view-page 대응 후속.)

3-1. 컴포넌트 트리 (fnrs 대응)

PageLayout (title / breadcrumb)
└─ SewerBscPlanRegistPage | SewerBscPlanEditPage | SewerBscPlanViewPage
     └─ SewerBscPlanFormPage | SewerBscPlanViewPage 본문
          FormProvider (등록/수정) / 읽기 섹션 (상세)
          └─ <form|div className="mt-6 space-y-4">
               ├─ BasicInfoFormSection             // JSP slide_10
               ├─ ContactInfoFormSection           // JSP slide_15  (pbadms-sprt)
               ├─ PrivacyConsentSection            // JSP slide_19  (pbadms-sprt, 등록·수정)
               ├─ OutlineFormSection               // JSP slide_11  (사업개요, 신규)
               ├─ BizCstMatrixFormSection          // JSP slide_12  (총사업비 전용, 신규)
               ├─ FnrsCstFormSection               // JSP slide_13  (재원분담, 신규 ※ FnrsShar 아님)
               ├─ TmplntFormSection                // JSP slide_14  (처리시설, Tabs로 시설별 패널)
               ├─ ChecklistFormSection             // JSP slide_16  (pbadms-sprt)
               ├─ AttachmentsFormSection           // JSP 필수·기타첨부 (pbadms-sprt)
               ├─ SplmntDmndFormSection            // edit + SL 상태만 (pbadms-sprt)
               └─ form footer action bar           // fnrs-form-page 279~323 동일
                    // [목록] / [저장] / edit시 [신청완료][삭제] / SL시 [보완완료]

폼 하단 액션바 버튼 구성
기준: fnrs-form-page.tsx 279~323. UI·분기만 동일하고 훅/라우트는 sewer.

순서 버튼 조건 sewer 비고
1 목록 항상 router.push("/sewer-bsc-plan")
2 저장 !isSplmntPrgrsStts type="submit" → saveApply / 임시저장(SV)
3 신청완료 !isSplmntPrgrsStts && isEditMode 체크리스트+필수첨부 검증 → saveApply / LE
4 삭제 !isSplmntPrgrsStts && isEditMode confirm → delete → 목록
5 보완완료 isSplmntPrgrsStts (prgrsSttsComCd=SL) submitSupplement (fnrs onSplmntCmptn 대응)

fnrs와의 차이 (섹션 치환만, 골격 동일)

fnrs-form-page sewer-bsc-plan
BasicInfoFormSection 동일 역할 (마스터·연도·개요 필드는 sewer DTO)
ContactInfoFormSection 동일 (fieldPrefix="sewerBscPlanDtl")
PrivacyConsentSection 동일
BusinessScaleFormSection → OutlineFormSection (단계별 인구·보급률)
BusinessCostFormSection → BizCstMatrixFormSection (단계×원가 계층 전용)
FnrsSharFormSection → FnrsCstFormSection (국고·지방비·원인자·기타)
(없음) TmplntFormSection (체크박스 + Tabs 시설별 매트릭스)
ChecklistFormSection docSeComCd="FNRS" docSeComCd="SEWER" (TBD)
AttachmentsFormSection 동일 패턴
SplmntDmndFormSection 동일 (readOnly={!isSplmntPrgrsStts})
폼 하단 액션바 (목록·저장·신청완료·삭제·보완완료) 동일 구성, API·라우트만 sewer

3-2. 본문 ASCII (폼 페이지)

┌─────────────────────────────────────────────────────────────────┐
│ PageLayout: 하수도기본계획 신청/수정          breadcrumb        │
├─────────────────────────────────────────────────────────────────┤
│ FormProvider                                                    │
│  <form className="mt-6 space-y-4">                              │
│                                                                 │
│  ┌─ SectionCollapsible: 기본계획 신청 ─────────────────────┐    │
│  │ BasicInfoFormSection                                     │   │
│  └──────────────────────────────────────────────────────────┘   │
│  ┌─ 신청자 정보 ────────────────────────────────────────────┐   │
│  │ ContactInfoFormSection                                   │   │
│  └──────────────────────────────────────────────────────────┘   │
│  ┌─ 개인정보 동의 ──────────────────────────────────────────┐   │
│  │ PrivacyConsentSection                                    │   │
│  └──────────────────────────────────────────────────────────┘   │
│  ┌─ 사업개요 ────────────── [이전기본계획조회] ─────────────┐   │
│  │ OutlineFormSection                                       │   │
│  └──────────────────────────────────────────────────────────┘   │
│  ┌─ 총사업비 (백만원) ──────────────────────────────────────┐   │
│  │ BizCstMatrixFormSection                                  │   │
│  └──────────────────────────────────────────────────────────┘   │
│  ┌─ 재원분담 (백만원) ──────────────────────────────────────┐   │
│  │ FnrsCstFormSection                                       │   │
│  └──────────────────────────────────────────────────────────┘   │
│  ┌─ 처리시설별 하수도정비기본계획 ──────────────────────────┐   │
│  │ TmplntFormSection                                        │   │
│  │  ├─ BscFctList Checkbox                                  │   │
│  │  └─ Tabs (선택 시설별 TabsTrigger / TabsContent)         │   │
│  └──────────────────────────────────────────────────────────┘   │
│  ┌─ 체크리스트 ─────────────────────────────────────────────┐   │
│  │ ChecklistFormSection                                     │   │
│  └──────────────────────────────────────────────────────────┘   │
│  ┌─ 첨부파일 ───────────────────────────────────────────────┐   │
│  │ AttachmentsFormSection                                   │   │
│  └──────────────────────────────────────────────────────────┘   │
│  ┌─ 보완요구 (edit + SL) ───────────────────────────────────┐   │
│  │ SplmntDmndFormSection                                    │   │
│  └──────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ┌─ form footer (fnrs-form-page 279~323 동일) ──────────────┐   │
│  │ [목록] [저장]  / edit: [신청완료][삭제]  / SL: [보완완료] │   │
│  │ ※ API·라우트만 sewer — UI 분기는 fnrs와 동일              │   │
│  └──────────────────────────────────────────────────────────┘   │
│  </form>                                                        │
└─────────────────────────────────────────────────────────────────┘

3-3. 액션바 동작 (fnrs-form-page 279~323 동일, API만 sewer)

구현 위치: sewer-bsc-plan-form-page.tsx 하단
(fnrs-form-page.tsx의 mx-4 flex flex-wrap justify-center gap-3 블록을 그대로 옮기고 훅·path만 교체)

버튼 조건 대표 동작
목록 항상 router.push("/sewer-bsc-plan")
저장 !isSplmntPrgrsStts type="submit" → saveApply + 임시저장(SV)
신청완료 edit && !isSplmntPrgrsStts 체크리스트 완료 + 필수 첨부 완료 검증 → saveApply + LE
삭제 edit && !isSplmntPrgrsStts confirm → delete → 목록
보완완료 isSplmntPrgrsStts (SL) form.handleSubmit → useSubmitSupplementSewerBscPlan

신청완료 사전 검증 (fnrs handleApplyClick과 동일 정책)

  1. 체크리스트: isFormChecklistComplete(cklstResultList) — 미완료 시 "모든 체크리스트 항목을 체크해야 신청이 가능합니다."
  2. 필수 첨부: esntlAtchYn === "Y"인 필수첨부 슬롯마다 esntlAtchFileList에 atchFileGroupId가 있어야 함
    • Form: AttachmentsFormSection의 트리 + 폼 esntlAtchFileList
    • 미충족 시 예: "필수 첨부파일을 모두 등록해야 신청이 가능합니다."
    • 헬퍼 후보: isFormEsntlAtchComplete(requiredTree, esntlAtchFileList) (pbadms-sprt에 추가)

저장에는 위 검증을 적용하지 않는다 (임시저장 허용).

저장/제출 버튼을 섹션 헤더(gTitle2 gRt)에 두지 않는다 — 폼 하단 액션바 단일 진입점 (§4-J).

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 하단 액션바 (§3-3, §4-J)

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)

파일: ui/sections/biz-cst-matrix-form-section.tsx (전용 컴포넌트 — fnrs BusinessCostFormSection 재사용 금지)
래퍼: SectionCollapsible title=총사업비 (단위 백만원은 헤더 우측)

JSP 현실: 단계(1~4) × 원가 계층(총사업비, 공사비, 처리시설, 하수관로 신설/보수, 펌프장, 배수설비, 기타, 부대경비, 설계/감리/부대비). 일부 readonly·자동합산 JS.

신규 API: bizCstList: SewerBscPlanBizCstItem[] = { planStpNo, acntgSeCd, cstrnAmt }

구현 방향 (BizCstMatrixFormSection 전용)

  • 행 = useAcntgSeMngTree → buildAcntgCostItems (fnrs BusinessCostFormSection과 동일 출처)
  • costItems 로드 시 useEffect로 bizCstList를 mergeBizCstList(existing, costItems)로 동기화
  • 열 = planStpNo 1~4 (헤더에 목표연도 표시)
  • readonly 행(CostItemDef.readonly=true)은 children 합산으로 자동계산; Input에 readOnly + bg-muted
  • 변경 시 setAmt → recalculateBizCstMatrix(list, costItems) → setValue("bizCstList")
  • 저장 시 섹션 onChange 합산을 신뢰하여 bizCstList 그대로 전송 (toBizCstSaveList identity)

표준사업비 조회 버튼은 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단계 매트릭스 동적 삽입
    → React: 세로 삽입 대신 @common/components Tabs로 시설별 패널 관리 (§아래 Tabs 규칙)
  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          # BscFctList Checkbox 목록 (시설 마스터 API TBD)
  └─ Tabs (@common/components Tabs)  # 선택 시설별 동적 패널
       ├─ TabsList / TabsTrigger     # value=swtrmtFcltCd, 라벨=시설명
       └─ TabsContent (시설 1개당)
            ├─ TmplntMatrixTable     # 당초|현재|변경 매트릭스 (useFieldArray)
            └─ TmplntFacilityAttachments  # 시설별 필수첨부 (선택)

Tabs 관리 규칙 (packages/common/components/src/ui/tabs)

  • BscFctList 체크 선택 → useFieldArray append + 해당 시설 TabsTrigger/TabsContent 추가 → Tabs value를 신규 시설로 전환
  • 체크 해제 → confirm 후 remove + 해당 탭 제거 → 남은 탭 중 하나로 value 이동 (없으면 Tabs 영역 비표시)
  • 선택 시설이 0개면 Tabs UI 숨김; 1개 이상이면 Tabs로 시설별 패널 전환
  • 매트릭스·첨부는 각 TabsContent 안에만 렌더 (JSP의 세로 동적 삽입을 탭 패널로 대체)

매트릭스 열

  • 당초 열: 이전계획 API 조회 결과 읽기 전용 (없으면 빈 칸)
  • 현재 열: 기준년도 시점 값 (API 제공 시)
  • 변경 열: 편집 가능 → 저장 payload의 dtl만 전송

시설 마스터 목록 API: 레거시 BscFctList 대체 — TBD (swtrmtFclt 계열).

bundle-dynamic-imports: TmplntFormSection(또는 TabsContent 내부 매트릭스)을 next/dynamic 후보.


4-I. 체크리스트 + 첨부 (slide_16)

I-1. 체크리스트

재사용: ChecklistFormSection
docSeComCd="<SEWER|DMBP TBD>"
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. 저장 / 제출

UI 구성: fnrs-form-page.tsx 279~323 과 동일.
마크업·분기(isSplmntPrgrsStts / isEditMode)·버튼 색상·disabled={isSubmitting} 패턴을 그대로 두고, 호출 API·목록 path만 sewer 로 교체한다.

<div className="mx-4 flex flex-wrap justify-center gap-3 sm:gap-4">
  <Button color="white" type="button" onClick={() => router.push("/sewer-bsc-plan")} disabled={isSubmitting}>
    목록
  </Button>
  {!isSplmntPrgrsStts ? (
    <>
      <Button type="submit" disabled={isSubmitting}>저장</Button>
      {isEditMode && (
        <>
          <Button color="green" type="button" onClick={handleApplyClick} disabled={isSubmitting}>
            신청완료
          </Button>
          <Button color="red" type="button" onClick={handleDelClick} disabled={isSubmitting}>
            삭제
          </Button>
        </>
      )}
    </>
  ) : (
    <Button type="button" onClick={form.handleSubmit(onSplmntCmptn)} disabled={isSubmitting}>
      보완완료
    </Button>
  )}
</div>
버튼 fnrs 대응 sewer API / 동작
목록 router.push("/fnrs-cnsltn") router.push("/sewer-bsc-plan")
저장 saveApply + 임시저장 useSaveApplySewerBscPlan + prgrsSttsComCd=임시저장(SV)
신청완료 handleApplyClick → 제출 체크리스트+필수첨부 검증 → saveApply + LE (상태코드 TBD)
삭제 handleDelClick useDeleteSewerBscPlan(또는 동등) → 목록
보완완료 onSplmntCmptn useSubmitSupplementSewerBscPlan
JSP 진행값 URL React
저장 SAVE insertFnrscDmbp.do saveApply + 임시저장 코드
제출 PRESENTN insertFnrscDscss.do (!) saveApply + 제출 상태코드 — 백엔드 상태코드 확인 TBD

페이로드 조립 (buildApplyPayload):

SewerBscPlanApplySaveRequestDto {
  sewerBscPlan, sewerBscPlanDtl,
  sewerBscPlanOtlnList, bizCstList, fnrsCstList,
  sewerBscPlanTmplntList, tmplntTmprStrgList?,
  cklstResultList, esntlAtchFileList,
  splmntDmndList?, rvwOpnnList?  // 등록 화면에서는 보통 빈 배열
}

성공 후: invalidateQueries(sewerBscPlanBaseKey) → router.push('/sewer-bsc-plan') (신청완료는 상세로 보낼 수 있음 — fnrs와 동일 정책).

권한: 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 edit + prgrsSttsComCd=SL 시 폼 하단 [보완완료]
기술검토 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/
│       │   └── previous-plan-lookup-dialog.tsx
│       └── sections/
│           ├── basic-info-form-section.tsx
│           ├── outline-form-section.tsx         # 사업개요
│           ├── biz-cst-matrix-form-section.tsx  # 총사업비 (전용)
│           ├── fnrs-cst-form-section.tsx        # 재원분담
│           └── tmplnt-form-section.tsx          # 처리시설 (Checkbox + Tabs)
└── docs/sewer-bsc-plan/
    └── dmbp-regist-migration.md              # 본 문서

공통 재사용 (신규 작성 최소화):

  • ContactInfoFormSection, PrivacyConsentSection
  • ChecklistFormSection, AttachmentsFormSection
  • SectionCollapsible
  • Tabs / TabsList / TabsTrigger / TabsContent (@common/components — 처리시설 패널)

도메인 전용 (재사용 금지):

  • BizCstMatrixFormSection — 총사업비 (fnrs BusinessCostFormSection 미사용)
  • 폼 하단 액션바 — fnrs-form-page 279~323 복제, API만 sewer

7. 화면 데이터 흐름

BEGIN

  // 최초 진입 (등록)
  CALL 로그인사용자조회
  CALL 코드조회(SEWERBSCPLANSE, SEWER, …)   // 병렬
  CALL 체크리스트트리(docSeComCd)           // 병렬
  CALL 필수첨부트리(docSeComCd)             // 병렬
  CALL 처리시설마스터목록                    // TBD (BscFctList)
  DISPLAY 폼 defaultValues

  ON 1단계목표연도 CHANGE DO
      SET 2·3·4단계 연도 (+5/+10/+15)
      DISPLAY E/F/G/H 헤더 연도
  END ON

  ON 처리시설 체크 DO
      ADD tmplntList 항목
      ADD TabsTrigger / TabsContent (시설 패널)
      SET Tabs value = 신규 시설
      CALL 이전기본계획수치(시설코드)  // 당초열, TBD
  END ON

  ON 처리시설 체크해제 DO
      CONFIRM 제거
      REMOVE tmplntList + 해당 Tabs 패널
      SET Tabs value = 남은 시설 (없으면 Tabs 숨김)
  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 BizCstMatrixFormSection 전용 + acntgSeCd 매핑 테이블
3 재원분담 ≠ fnrs shar 전용 fnrs-cst-form-section
4 처리시설 매트릭스(당초/현재/변경) Checkbox 선택 → Tabs 패널; 저장은 변경 dtl 중심; 당초는 조회 전용
5 시설·이전계획 API TBD — 미정 시 체크박스 목록 mock(faker)만
6 docSeComCd 값 CMS/체크리스트 마스터와 합의
7 레거시 multipart vs TUS fnrs 첨부 패턴 준수
8 주석 처리된 상세 formFields (자연발생인구 등) 축소된 formFields만 이관; 주석 블록 복원 금지

9. 구현 순서 (권장)

  1. 라우트 + FormPage 골격 + zod 스키마(마스터·dtl·동의) + 폼 하단 액션바(§4-J)
  2. B·C·D 섹션 (공통 위젯 최대 활용)
  3. E 사업개요 + G 재원분담 (4열 매트릭스 패턴 공유)
  4. F 총사업비 (BizCstMatrixFormSection 전용)
  5. I 체크리스트·첨부
  6. H 처리시설 (BscFctList Checkbox + @common/components Tabs — 가장 복잡)
  7. 저장/신청완료/삭제/보완완료 API 연동 (§4-J)
  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 표)