# 화면설계서: 코드관리 ## 1. 기본 정보 | 항목 | 내용 | | ---------- | -------------------------------------------- | | 버전 | 0.1 | | 프로세스명 | UI설계 | | 화면명 | 코드관리 | | 화면 유형 | [v] 조회 [v] 입력 [v] 수정 [v] 삭제 [ ] 출력 | | 메뉴 경로 | 디지털행정지원 > 사이트관리 > 코드관리 | --- ## 2. 화면 목적 설치인가 등 AS 업무에서 참조하는 **공종구분코드**(공종코드)와 **회계구분코드**(회계코드)를 한 화면에서 조회·등록·수정·삭제한다. 좌측 **공종코드 관리**와 우측 **회계코드 관리**는 독립된 목록·CRUD 영역이며, 각 섹션은 자체 API(`cnstp-se`, `acntg-se`)와 연동한다. --- ## 3. 화면 구성 ### 3-1. 전체 레이아웃 ``` ┌───────────────────────────────────────────────────────────────────────────────────────────────────┐ │ 페이지 타이틀: 코드관리 브레드크럼: 디지털행정지원 > 사이트관리 > 코드관리 │ ├──────────────────────────────────────────────────┬────────────────────────────────────────────────┤ │ [영역 A] 공종코드 관리 │ [영역 B] 회계코드 관리 │ │ [등록] │ [등록] │ │ ┌────────────────────────────────────────────┐ │ ┌──────────────────────────────────────────┐ │ │ │ 코드 | 코드명 | 설명 | 사용여부 | 관리 │ │ │ 코드 | 코드명 | 설명 | 사용여부 | 관리 │ │ │ ├────────────────────────────────────────────┤ │ ├──────────────────────────────────────────┤ │ │ │ WC001 공공하수처리시설 … 사용 [수정][삭제]│ │ │ AC101 시설비 … 사용 [수정][삭제] │ │ │ │ WC002 하수관로정비 … 사용 [수정][삭제]│ │ │ AC102 용역비 … 사용 [수정][삭제] │ │ │ │ WC003 재이용시설 … 사용 [수정][삭제]│ │ │ AC103 운영비 … 미사용 [수정][삭제] │ │ │ └────────────────────────────────────────────┘ │ └──────────────────────────────────────────┘ │ │ « 1 2 3 … » │ « 1 2 3 … » │ └──────────────────────────────────────────────────┴────────────────────────────────────────────────┘ ``` ### 3-2. 화면 데이터 흐름 ``` BEGIN // 최초 진입 — 좌·우 독립 조회 CALL cnstpSeMngService.findAll({ page, size }) DISPLAY 공종코드 그리드 (영역 A) CALL acntgSeMngService.findAll({ page, size }) DISPLAY 회계코드 그리드 (영역 B) // 영역 A: 공종코드 등록 ON 영역 A [등록] 버튼 CLICK DO OPEN 공종코드 등록 다이얼로그 ON [저장] DO VALIDATE cnstpSeCd CALL cnstpSeMngService.save(CnstpSeMngSaveRequestDto) CALL cnstpSeMngService.findAll CLOSE 다이얼로그 END ON ON [취소] / [닫기] DO CLOSE 다이얼로그 END ON END ON // 영역 A: 공종코드 수정 ON 영역 A 행 [수정] CLICK DO CALL cnstpSeMngService.findById(cnstpSeCd) OPEN 공종코드 수정 다이얼로그 (기존 값 초기화) ON [저장] DO CALL cnstpSeMngService.update(cnstpSeCd, CnstpSeMngSaveRequestDto) CALL cnstpSeMngService.findAll CLOSE 다이얼로그 END ON END ON // 영역 A: 공종코드 삭제 ON 영역 A 행 [삭제] CLICK DO CONFIRM "선택한 공종코드를 삭제하시겠습니까?" CALL cnstpSeMngService.delete(cnstpSeCd) CALL cnstpSeMngService.findAll END ON // 영역 B: 회계코드 등록 ON 영역 B [등록] 버튼 CLICK DO OPEN 회계코드 등록 다이얼로그 ON [저장] DO VALIDATE acntgSeCd, acntgSeCdNm CALL acntgSeMngService.save(AcntgSeMngSaveRequestDto) CALL acntgSeMngService.findAll CLOSE 다이얼로그 END ON ON [취소] / [닫기] DO CLOSE 다이얼로그 END ON END ON // 영역 B: 회계코드 수정 ON 영역 B 행 [수정] CLICK DO CALL acntgSeMngService.findById(acntgSeCd) OPEN 회계코드 수정 다이얼로그 (기존 값 초기화) ON [저장] DO CALL acntgSeMngService.update(acntgSeCd, AcntgSeMngSaveRequestDto) CALL acntgSeMngService.findAll CLOSE 다이얼로그 END ON END ON // 영역 B: 회계코드 삭제 ON 영역 B 행 [삭제] CLICK DO CONFIRM "선택한 회계코드를 삭제하시겠습니까?" CALL acntgSeMngService.delete(acntgSeCd) CALL acntgSeMngService.findAll END ON END ``` --- ## 4. 영역 A: 공종코드 관리 백엔드 **공종구분코드**(`CnstpSeMng`) CRUD. 계층 구조(`upCnstpCd`, `cdLvNo`)를 지원하나, 본 화면은 **평면 목록**으로 표시. ### 4-1. 헤더 / 툴바 | 항목 | 내용 | | ----------- | ------------------------------------- | | 섹션 타이틀 | 공종코드 관리 | | 우측 버튼 | **[등록]** — 공종코드 등록 다이얼로그 | ### 4-2. 그리드 컬럼 | 컬럼명 | Field | 타입 | 비고 | | -------- | ------------- | ------ | ------------------------ | | 코드 | `cnstpSeCd` | string | PK, 최대 10자 | | 코드명 | `cnstpSeCdNm` | string | 최대 100자 | | 설명 | `expln` | string | 최대 1000자, 선택 | | 사용여부 | `useYn` | string | `Y`→사용, `N`→미사용 | | 관리 | — | — | 행별 **[수정] · [삭제]** | - 행 클릭 시 별도 상세 이동 없음. 수정은 **[수정]** 버튼으로 다이얼로그 진입. - 페이지네이션: Spring `Pageable` (`page`, `size`, `sort`) — **UI 노출**. 기본 `size: 10`, `@common/components` 공통 페이지네이션 컴포넌트 사용. ### 4-3. 버튼 | 버튼명 | 위치 | 동작 | | ------ | -------------- | ---------------------------------------- | | 등록 | 섹션 우측 상단 | 공종코드 등록 다이얼로그 오픈 | | 수정 | 행별 | 상세 조회 후 수정 다이얼로그 (값 초기화) | | 삭제 | 행별 | 확인 후 삭제, 목록 갱신 | ### 4-4. 다이얼로그: 공종코드 등록 / 수정 다이얼로그 입력 필드는 **코드 · 코드명 · 설명 · 사용여부** 4개만 노출한다. | 표시명 | 입력 유형 | 필수 | 기본값 | API 파라미터 매핑 | 비고 | | -------- | --------- | ---- | ------ | ----------------- | ------------------------------- | | 코드 | Input | Y | — | `cnstpSeCd` | 등록 시 입력, 수정 시 읽기 전용 | | 코드명 | Input | N | — | `cnstpSeCdNm` | 최대 100자 | | 설명 | Input | N | — | `expln` | 최대 1000자 | | 사용여부 | Radio | N | Y | `useYn` | `Y`→사용, `N`→미사용 | > UI에 노출하지 않는 API 필드(`upCnstpCd`, `cdLvNo`): 등록 시 `cdLvNo: 1` 등 기본값 전송, 수정 시 `findById` 응답값 유지. | 버튼명 | 동작 | | ------ | ------------------------------------------------ | | 저장 | POST(등록) 또는 PUT(수정) 후 `findAll` 목록 갱신 | | 취소 | 다이얼로그 닫기, 입력값 폐기 | | 닫기 | 다이얼로그 닫기 | --- ## 5. 영역 B: 회계코드 관리 백엔드 **회계구분관리**(`AcntgSeMng`) CRUD. 영역 A와 동일한 **평면 목록** UI 패턴을 따른다. ### 5-1. 헤더 / 툴바 | 항목 | 내용 | | ----------- | ------------------------------------- | | 섹션 타이틀 | 회계코드 관리 | | 우측 버튼 | **[등록]** — 회계코드 등록 다이얼로그 | ### 5-2. 그리드 컬럼 | 컬럼명 | Field | 타입 | 비고 | | -------- | ------------- | ------ | ------------------------ | | 코드 | `acntgSeCd` | string | PK, 최대 10자 | | 코드명 | `acntgSeCdNm` | string | 최대 100자 | | 설명 | `expln` | string | 최대 1000자, 선택 | | 사용여부 | `useYn` | string | `Y`→사용, `N`→미사용 | | 관리 | — | — | 행별 **[수정] · [삭제]** | - 페이지네이션: 영역 A와 동일 — **UI 노출**, 기본 `size: 10`. ### 5-3. 버튼 | 버튼명 | 위치 | 동작 | | ------ | -------------- | ---------------------------------------- | | 등록 | 섹션 우측 상단 | 회계코드 등록 다이얼로그 오픈 | | 수정 | 행별 | 상세 조회 후 수정 다이얼로그 (값 초기화) | | 삭제 | 행별 | 확인 후 삭제, 목록 갱신 | ### 5-4. 다이얼로그: 회계코드 등록 / 수정 다이얼로그 입력 필드는 **코드 · 코드명 · 설명 · 사용여부** 4개만 노출한다. (영역 A와 동일 패턴) | 표시명 | 입력 유형 | 필수 | 기본값 | API 파라미터 매핑 | 비고 | | -------- | --------- | ---- | ------ | ----------------- | ------------------------------- | | 코드 | Input | Y | — | `acntgSeCd` | 등록 시 입력, 수정 시 읽기 전용 | | 코드명 | Input | Y | — | `acntgSeCdNm` | 최대 100자 | | 설명 | Input | N | — | `expln` | 최대 1000자 | | 사용여부 | Radio | N | Y | `useYn` | `Y`→사용, `N`→미사용 | > UI에 노출하지 않는 API 필드(`upAcntgSeCd`, `cdLvNo`): 등록 시 `cdLvNo: 1` 등 기본값 전송, 수정 시 `findById` 응답값 유지. | 버튼명 | 동작 | | ------ | ------------------------------------------------ | | 저장 | POST(등록) 또는 PUT(수정) 후 `findAll` 목록 갱신 | | 취소 | 다이얼로그 닫기, 입력값 폐기 | | 닫기 | 다이얼로그 닫기 | --- ## 6. API/DTO 명세 ### 6-1. 공통 | 항목 | 내용 | | ----------- | ---------------------------------------------------------------------------------- | | 서비스 | `as-service` | | Base prefix | `/as-service/api/v1` (`ENDPOINT.AS_COMMON_SERVICE`) | | 인증 | JWT (`Authorization` 헤더), `X-Site-Id`, `token-id` | | 페이징 | Spring `Pageable`: `page`, `size`, `sort` → `PageResponse` | | 엔티티 | `@/entities/cnstp` (`cnstpSeMngService`), `@/entities/acntg` (`acntgSeMngService`) | **부가 API (본 화면 목록 외 참조용)** | 리소스 | Method | URL | Response | 용도 | | ------------ | ------ | --------------------- | --------------------- | --------------------------------- | | 공종구분코드 | GET | `/cnstp-se/list/tree` | `CnstpSeMngTreeDto[]` | 계층 트리 (타 화면·상위코드 선택) | | 회계구분관리 | GET | `/acntg-se/list/tree` | `AcntgSeMngTreeDto[]` | 계층 트리 (타 화면·상위코드 선택) | ### 6-2. 공종구분코드 (영역 A) — `cnstp-se` | 기능 | Method | URL | Request / Query | Response | 클라이언트 | | --------- | ------ | ----------------------- | -------------------------------- | ----------------------------- | ---------------------------- | | 목록 조회 | GET | `/cnstp-se` | `CnstpSeMngSearchDto` + Pageable | `Page` | `cnstpSeMngService.findAll` | | 트리 조회 | GET | `/cnstp-se/list/tree` | — | `CnstpSeMngTreeDto[]` | `cnstpSeMngService.findTree` | | 상세 조회 | GET | `/cnstp-se/{cnstpSeCd}` | — | `CnstpSeMngResponseDto` | `cnstpSeMngService.findById` | | 등록 | POST | `/cnstp-se` | `CnstpSeMngSaveRequestDto` | `string` (cnstpSeCd) | `cnstpSeMngService.save` | | 수정 | PUT | `/cnstp-se/{cnstpSeCd}` | `CnstpSeMngSaveRequestDto` | `string` (cnstpSeCd) | `cnstpSeMngService.update` | | 삭제 | DELETE | `/cnstp-se/{cnstpSeCd}` | — | `string` (cnstpSeCd) | `cnstpSeMngService.delete` | **CnstpSeMngResponseDto** | Field | 타입 | 설명 | | ------------- | ------- | ------------------ | | `cnstpSeCd` | string | 공종구분코드 | | `cnstpSeCdNm` | string | 공종구분코드명 | | `upCnstpCd` | string? | 상위공종코드 | | `cdLvNo` | number | 코드레벨번호 | | `useYn` | string | 사용여부 | | `expln` | string? | 설명 (최대 1000자) | | `rgtr` | string? | 등록자 UUID | | `rgtrNm` | string? | 등록자명 | | `mdfr` | string? | 수정자 UUID | | `regDt` | string? | 등록일시 | | `mdfcnDt` | string? | 수정일시 | **CnstpSeMngSaveRequestDto**: `cnstpSeCd`, `cnstpSeCdNm?`, `upCnstpCd?`, `cdLvNo?`, `useYn?`, `expln?` **CnstpSeMngSearchDto**: `cnstpSeCd?`, `cnstpSeCdNm?`, `useYn?` + `page`, `size`, `sort` **React Query hooks**: `useCnstpSeMngPage`, `useCnstpSeMngTree`, `useCnstpSeMng`, `useSaveCnstpSeMng`, `useUpdateCnstpSeMng`, `useDeleteCnstpSeMng` ### 6-3. 회계구분관리 (영역 B) — `acntg-se` | 기능 | Method | URL | Request / Query | Response | 클라이언트 | | --------- | ------ | ----------------------- | -------------------------------- | ----------------------------- | ---------------------------- | | 목록 조회 | GET | `/acntg-se` | `AcntgSeMngSearchDto` + Pageable | `Page` | `acntgSeMngService.findAll` | | 트리 조회 | GET | `/acntg-se/list/tree` | — | `AcntgSeMngTreeDto[]` | `acntgSeMngService.findTree` | | 상세 조회 | GET | `/acntg-se/{acntgSeCd}` | — | `AcntgSeMngResponseDto` | `acntgSeMngService.findById` | | 등록 | POST | `/acntg-se` | `AcntgSeMngSaveRequestDto` | `string` (acntgSeCd) | `acntgSeMngService.save` | | 수정 | PUT | `/acntg-se/{acntgSeCd}` | `AcntgSeMngSaveRequestDto` | `string` (acntgSeCd) | `acntgSeMngService.update` | | 삭제 | DELETE | `/acntg-se/{acntgSeCd}` | — | `string` (acntgSeCd) | `acntgSeMngService.delete` | **AcntgSeMngResponseDto** | Field | 타입 | 설명 | | ------------- | ------- | ------------------ | | `acntgSeCd` | string | 회계구분코드 | | `acntgSeCdNm` | string | 회계구분코드명 | | `upAcntgSeCd` | string? | 상위회계구분코드 | | `cdLvNo` | number | 코드레벨번호 | | `useYn` | string | 사용여부 | | `expln` | string? | 설명 (최대 1000자) | | `rgtr` | string? | 등록자 UUID | | `rgtrNm` | string? | 등록자명 | | `mdfr` | string? | 수정자 UUID | | `regDt` | string? | 등록일시 | | `mdfcnDt` | string? | 수정일시 | **AcntgSeMngSaveRequestDto**: `acntgSeCd`, `acntgSeCdNm`, `upAcntgSeCd?`, `cdLvNo`, `useYn?`, `expln?` **AcntgSeMngSearchDto**: `acntgSeCd?`, `acntgSeCdNm?`, `useYn?` + `page`, `size`, `sort` **React Query hooks**: `useAcntgSeMngPage`, `useAcntgSeMngTree`, `useAcntgSeMng`, `useSaveAcntgSeMng`, `useUpdateAcntgSeMng`, `useDeleteAcntgSeMng` --- ## 7. UI 구현 가이드 ### 7-1. 기술 스택·원칙 - Next.js App Router, React Query (`@tanstack/react-query`) - `@common/components` — `Card`, `Button`, `Dialog`, `DataTable` / `useDataTable` - `@tanstack/react-table` — 컬럼 정의는 `model/*-table-columns.tsx` 분리 - 기존 entity 레이어 재사용: `@/entities/cnstp`, `@/entities/acntg` (service·queries·interface 구현 완료) - 좌·우 2열 레이아웃: `grid grid-cols-1 lg:grid-cols-2 gap-4` (모바일 1열 스택) - 삭제 전 `confirm` / Toast 피드백 — 프로젝트 공통 패턴 준수 - 목록 하단 **페이지네이션 UI 노출** — 영역 A·B 각각 독립 page state - **검색 필터 UI 미제공** — `findAll` 호출 시 `page`, `size`만 전달 - **등록/수정 다이얼로그** — 코드·코드명·설명은 `Input`, 사용여부는 `Radio` (4필드만 노출) - 상위 코드 삭제 시 **하위 코드 연쇄 삭제 UI·로직 미구현** — 단건 삭제만 수행 ### 7-2. 모듈·파일 배치 | 구분 | 경로 (제안) | | ----------------- | -------------------------------------------------------------------- | | 라우트 | `apps/as/src/app/(authenticated)/site/code-management/page.tsx` | | 페이지 컴포넌트 | `apps/as/src/pages/code-management/ui/code-management-page.tsx` | | 공종 그리드 컬럼 | `apps/as/src/pages/code-management/model/cnstp-se-table-columns.tsx` | | 회계 그리드 컬럼 | `apps/as/src/pages/code-management/model/acntg-se-table-columns.tsx` | | 공종 등록/수정 폼 | `apps/as/src/pages/code-management/ui/cnstp-se-form-dialog.tsx` | | 회계 등록/수정 폼 | `apps/as/src/pages/code-management/ui/acntg-se-form-dialog.tsx` | | API·타입 (기존) | `@/entities/cnstp`, `@/entities/acntg` | ### 7-3. 영역별 UI 매핑 | 영역 | UI 컴포넌트 | 데이터 소스 | 비고 | | ------------ | ------------------------------------- | ------------------------------------------- | ------------------------------ | | A | `CnstpSeSection` + Table + Pagination | `useCnstpSeMngPage({ page, size })` | 독립 page state·mutation | | B | `AcntgSeSection` + Table + Pagination | `useAcntgSeMngPage({ page, size })` | A와 상호 의존 없음 | | A 다이얼로그 | `CnstpSeFormDialog` | `useCnstpSeMng`, `useSave/UpdateCnstpSeMng` | Input 4필드 + Radio 사용여부 | | B 다이얼로그 | `AcntgSeFormDialog` | `useAcntgSeMng`, `useSave/UpdateAcntgSeMng` | Input 4필드 + Radio 사용여부 | ### 7-4. 다이얼로그·라우팅 | 다이얼로그 | 트리거 | 라우팅 | | ------------- | ---------------- | -------------------- | | 공종코드 등록 | 영역 A [등록] | URL 변경 없음 (모달) | | 공종코드 수정 | 영역 A 행 [수정] | URL 변경 없음 (모달) | | 회계코드 등록 | 영역 B [등록] | URL 변경 없음 (모달) | | 회계코드 수정 | 영역 B 행 [수정] | URL 변경 없음 (모달) | ### 7-5. 데이터 흐름 (구현 관점) ``` BEGIN // 페이지 마운트 — 검색 조건 없이 page·size만 전달 const cnstpQuery = useCnstpSeMngPage({ page: 0, size: 20 }) const acntgQuery = useAcntgSeMngPage({ page: 0, size: 20 }) DISPLAY CodeManagementPage ├─ CnstpSeSection(data=cnstpQuery.data, pagination) └─ AcntgSeSection(data=acntgQuery.data, pagination) // 페이지 변경 ON pagination page/size CHANGE DO refetch cnstpQuery | acntgQuery with new page, size END ON // mutation 성공 시 ON save/update/delete SUCCESS DO invalidateQueries cnstp-se | acntg-se baseKey TOAST "저장되었습니다." | "삭제되었습니다." END ON END ```