# CLAUDE.md 이 파일은 이 저장소에서 코드 작업을 할 때 Claude Code (claude.ai/code)에게 제공하는 가이드입니다. # ⚠️ 최우선 규칙 - 반드시 준수 ⚠️ ## 🚨 패턴 통일화 필수 프로세스 (MANDATORY) **모든 코드 작성 전 반드시 아래 프로세스를 따를 것. 이 프로세스를 건너뛰면 작업을 시작하지 말 것.** ### 1단계: 패턴 분석 (ALWAYS FIRST) 새로운 코드를 작성하기 전, **반드시** 유사한 기존 코드의 패턴을 먼저 분석 (참고대상 CRDN-단속 하위 디렉토리 or 패키지 or xml query): - **Controller 작성 시**: - 동일 패키지 내 다른 Controller 파일을 최소 2개 이상 Read로 읽고 분석 - 메서드 구조, 어노테이션 패턴, 파라미터 처리 방식, 응답 구조 확인 - **JSP/JavaScript 작성 시**: - 동일 디렉토리 내 유사한 JSP 파일을 Read로 읽고 분석 - JavaScript 함수 네이밍, AJAX 호출 패턴, 에러 처리 방식 확인 - HTML 구조, CSS 클래스명, 폼 구조 확인 - **Service/Mapper 작성 시**: - 동일 패키지의 기존 Service/Mapper 파일 읽고 분석 - 메서드 네이밍, 트랜잭션 처리, 예외 처리 패턴 확인 ### 2단계: 패턴 적용 검증 (BEFORE WRITING) 코드를 작성하기 전, 다음을 확인: 1. ✅ 기존 파일을 Read 도구로 읽었는가? 2. ✅ 해당 파일의 코딩 스타일(들여쓰기, 주석, 네이밍)을 파악했는가? 3. ✅ 유사한 기능이 어떻게 구현되어 있는지 확인했는가? 4. ✅ 내가 작성할 코드가 기존 패턴과 100% 일치하는가? **위 4가지 중 하나라도 NO면 코드를 작성하지 말고, 먼저 패턴 분석으로 돌아갈 것.** ### 3단계: 작성 후 자체 검증 (AFTER WRITING) 코드 작성 후 제출 전, 다음을 점검: 1. ✅ 들여쓰기(탭/스페이스)가 기존 파일과 동일한가? 2. ✅ 변수/함수 네이밍 규칙이 기존과 동일한가? 3. ✅ 주석 스타일(한글/영문, 위치)이 기존과 동일한가? 4. ✅ 에러 처리 방식이 기존과 동일한가? 5. ✅ API 응답 구조가 기존과 동일한가? 6. ✅ **[필수] VO 파일을 Read 도구로 다시 읽어서 필드가 정상 추가되었는지 확인했는가?** (Edit 결과를 믿지 말고 반드시 Read로 재확인) 7. ✅ **[필수] XML 쿼리를 Read 도구로 다시 읽어서 수정이 정상 반영되었는지 확인했는가?** ### 🔴 절대 금지 사항 - ❌ 기존 코드를 읽지 않고 "추측"으로 작성 - ❌ 기존 파일의 들여쓰기/포맷팅 변경 - ❌ 기존과 다른 스타일의 주석 추가 - ❌ 새로운 패턴이나 "더 나은 방법" 제안 (명시적 요청이 없는 한) - ❌ 임의로 코드 리팩토링 ### 📋 체크리스트 (모든 작업 전 필수 확인) ``` [ ] 1. 유사 기능의 기존 코드를 Read로 읽었는가? [ ] 2. 기존 코드의 패턴(네이밍, 구조, 스타일)을 분석했는가? [ ] 3. 내 코드가 기존 패턴과 100% 일치하는가? [ ] 4. 들여쓰기, 주석, 변수명이 기존과 동일한가? [ ] 5. [작업 후] VO 파일 변경 시 Read로 재확인했는가? [ ] 6. [작업 후] XML 쿼리 변경 시 Read로 재확인했는가? [ ] 7. [작업 후] Service/Mapper 변경 시 Read로 재확인했는가? ``` **이 체크리스트를 모두 완료하지 않으면 코드를 작성하지 말 것.** **특히 Edit 도구 사용 후에는 반드시 Read 도구로 재확인할 것. Edit 결과를 절대 믿지 말 것.** ## 프로젝트 개요 일산 동구 건축물 위법행위 통합관리시스템 - 공무원이 불법 건축물 관련 위반사항을 관리하기 위한 Spring Boot 웹 애플리케이션입니다. ## 빌드 및 개발 명령어 ### 빌드 명령어 ```bash # 프로젝트 빌드 ./gradlew build # 클린 빌드 ./gradlew clean build # 애플리케이션 실행 (기본 포트: 8080) ./gradlew bootRun # 배포용 WAR 파일 빌드 ./gradlew bootWar ``` ### 테스트 이 프로젝트에서는 프로젝트 가이드라인에 따라 테스트가 명시적으로 비활성화되어 있습니다. 테스트 파일을 생성하지 마세요. ## 고수준 아키텍처 ### 기술 스택 - **JDK**: JDK1.8만 사용 - **프레임워크**: Spring Boot 2.7.18 with eGovFrame 4.3.0 (한국 정부 표준 프레임워크) - **데이터베이스**: MariaDB with MyBatis 2.3.1 for ORM - **프론트엔드**: JSP with Apache Tiles 3.0.8 (레이아웃), TOAST UI Grid 4.19.2 (데이터 그리드) - **빌드 도구**: Gradle ### MVC 아키텍처 패턴 프로젝트는 엄격한 MVC 패턴을 따릅니다: - **Model**: `model/` 패키지에 `PagingVO`를 확장한 VO 클래스들 포함 - **View**: Apache Tiles 레이아웃을 사용하는 `src/main/webapp/WEB-INF/views/`의 JSP 파일들 - **Controller**: Swagger 어노테이션을 사용하는 Spring MVC 컨트롤러가 있는 `controller/` 패키지들 ### 비즈니스 도메인별 패키지 구조 ``` go.kr.project/ ├── system/ # 시스템 관리 (사용자, 역할, 메뉴, 코드) ├── login/ # 인증 ├── common/ # 공통 컴포넌트 및 유틸리티 ├── baseData/ # 마스터 데이터 관리 (건축물 지수, 위반 법령) ├── crdn/ # 핵심 비즈니스: 위반 관리 │ ├── crndRegistAndView/ # 위반 등록 및 조회 │ │ ├── main/ # 주요 위반 프로세스 │ │ ├── crdnActInfo/ # 위반 행위 정보 │ │ ├── crdnPstnInfo/ # 위치 정보 │ │ └── crdnOwnrInfo/ # 소유자 정보 │ └── ownac/ # 소유자 조치 관리 └── noti/ # 알림 시스템 ``` ### 데이터베이스 레이어 (MyBatis) - **매퍼**: `mapper/` 패키지의 인터페이스 클래스들 - **SQL**: 동일한 패키지 구조를 따르는 `src/main/resources/mybatis/mapper/`의 XML 파일들 - **시퀀스**: 모든 기본 키는 10자리 LPAD 시퀀스 사용: `SELECT LPAD(NEXTVAL(seq_table_id), 10, '0')` - **네이밍**: camelCase 변환 자동 사용, `DB-DDL/maria/dictionary/`의 컬럼 단어 사전 따름 ### 서비스 레이어 패턴 각 비즈니스 도메인은 다음을 포함합니다: - **Service Interface**: 비즈니스 오퍼레이션 정의 - **ServiceImpl**: 비즈니스 로직 구현, `@RequiredArgsConstructor` 사용하고 매퍼 호출 - **표준 메서드**: 일관된 네이밍을 따르는 `select*`, `insert*`, `update*`, `delete*` ### 프론트엔드 아키텍처 #### 레이아웃 (Apache Tiles) - **base**: 헤더, 메뉴, 콘텐츠 영역을 가진 메인 관리자 레이아웃 - **login**: 로그인 페이지 레이아웃 - **popup**: 팝업 윈도우 레이아웃 (접미사 `TilesConstants.POPUP`) #### UI 컴포넌트 - **모달**: JavaScript로 제어되는 `.modalz` CSS 클래스를 가진 JSP에 임베드 - **팝업**: 팝업 레이아웃을 사용하는 별도 JSP 페이지, `window.open()`으로 열림 - **그리드**: 구성을 위한 `XitTuiGridConfig` 헬퍼 클래스를 가진 TOAST UI Grid #### JavaScript 패턴 - `setTimeout` 사용 피하기 (문제 야기) - 모든 URL에 `` 태그 사용 - `dataSource.api.readData`를 통한 AJAX로 그리드 데이터 로딩 - #### CSS, JavaScript 위치 src/main/webapp/resources/xit src/main/webapp/resources/css #### TUI Grid 는 아래 패턴을 이용 ```javascript /** * 단속 목록 관리 네임스페이스 */ var CrdnRegistAndViewList = { /** * 선택된 행 정보 */ selectedRow: null, /** * 그리드 관련 객체 */ grid: { /** * 그리드 인스턴스 */ instance: null, ``` tui grid 선언 규칙 CrdnRegistAndViewList.grid.instance 해당페이지명명규칙.그리드객체.그리드인스턴스 ## 중요한 개발 가이드라인 ### 모드 표준화 모든 CRUD 작업은 일관된 모드 값을 사용합니다: - `mode: C` = Create (등록) - `mode: U` = Update (수정) - `mode: V` = View (보기) - `mode: D` = Delete (삭제) ### 페이지네이션 패턴 (중요한 순서) ```java // 1. 먼저 총 개수 가져오기 int totalCount = service.selectTotalCount(paramVO); // 2. 총 개수 설정 paramVO.setTotalCount(totalCount); // 3. 페이징 활성화 (선택사항) paramVO.setPagingYn("Y"); ``` ### 보안 및 세션 - 감사 필드에 `SessionUtil.getUserId()` 사용 - 모든 폼에 CSRF 보호 필요 - 하드코딩된 자격증명이나 민감한 데이터 금지 ### 코드 품질 요구사항 - **한글 주석**: 모든 비즈니스 로직은 한글 주석 필수 (중요로직 주석) - **Swagger**: 모든 컨트롤러는 Swagger 어노테이션 필수 (`@Tag`, `@Operation`, `@ApiResponses`) - **포맷팅 변경 금지**: 기존 코드 포맷팅이나 공백 수정 절대 금지 ### 비즈니스 로직 패턴 위반 관리(`crdn`)와 마스터 데이터(`baseData`)의 경우, 다음의 기존 패턴을 따르세요: - 뷰 패턴: `src/main/webapp/WEB-INF/views/baseData/`와 `src/main/webapp/WEB-INF/views/crdn/` - Java 패턴: `src/main/java/go/kr/project/baseData/bldgNewPrcCrtrAmt/`와 `src/main/java/go/kr/project/crdn/` ### 최근 아키텍처 추가: 스마트 CRUD 패턴 `CrdnLevyPrvntcController`는 생성/업데이트 작업을 처리하는 고급 패턴을 보여줍니다: - **통합 저장 API**: `/saveLevyInfo.ajax`가 insert vs update를 자동으로 결정 - **스냅샷 복원**: 그리드 행 선택이 기존 데이터를 로드하여 이전 계산을 복원 - **스마트 데이터 로딩**: 복잡한 조인을 사용하여 표시명과 계산 비율을 함께 가져옴 - **프론트엔드 상태 관리**: JavaScript가 모드 감지와 폼 채우기를 처리 이 패턴은 데이터를 계산 스냅샷으로 저장하고 나중에 복원해야 하는 유사한 위반 처리 워크플로우에서 따라야 합니다. --- # 📘 프로젝트 상세 문서 ## 1. 전체 프로젝트 구조 ### 1.1 Java 패키지 구조 상세 ``` go.kr.project/ │ ├── common/ # 공통 기능 │ ├── controller/ # 공통 컨트롤러 │ │ ├── CommonCodeController # 공통코드 조회 │ │ ├── HtmlEditorController # HTML 에디터 파일 관리 │ │ └── SearchAddressController # 주소 검색 │ ├── service/ # 공통 서비스 │ │ ├── CommonCodeService # 공통코드 서비스 │ │ ├── CommonHeaderService # 공통 헤더 서비스 │ │ └── HtmlEditorService # HTML 에디터 서비스 │ ├── mapper/ # 공통 매퍼 │ └── model/ # 공통 모델 │ ├── PagingVO # 페이징 기본 VO (모든 VO의 부모 클래스) │ ├── FileVO # 파일 정보 VO │ └── CmmnCodeSearchVO # 공통코드 검색 VO │ ├── login/ # 로그인 및 인증 │ ├── service/LoginService # 로그인 서비스 │ ├── mapper/LoginMapper # 로그인 매퍼 │ └── model/ # 로그인 모델 │ ├── SessionVO # 세션 정보 VO │ ├── UserSessionVO # 사용자 세션 VO │ └── LoginUserVO # 로그인 사용자 VO │ ├── mypage/ # 마이페이지 │ ├── controller/MypageController │ ├── service/MypageService │ └── service/impl/MypageServiceImpl │ ├── system/ # 시스템 관리 │ ├── user/ # 사용자 관리 │ │ ├── controller/UserController │ │ ├── service/UserService │ │ ├── service/impl/UserServiceImpl │ │ ├── mapper/UserMapper │ │ └── model/ │ │ ├── SystemUserVO # 시스템 사용자 VO │ │ └── SystemUserSearchVO # 사용자 검색 VO │ ├── group/ # 그룹 관리 │ │ ├── controller/GroupController │ │ ├── service/GroupService │ │ └── model/GroupVO │ ├── role/ # 역할 관리 │ │ ├── controller/RoleController │ │ ├── service/RoleService │ │ └── model/RoleVO │ ├── menu/ # 메뉴 관리 │ │ ├── controller/MenuController │ │ ├── service/MenuService │ │ └── mapper/MenuMapper │ ├── code/ # 코드 관리 │ │ ├── controller/CodeController │ │ ├── service/CodeService │ │ ├── mapper/CodeMapper │ │ └── model/ │ │ ├── CodeGroupVO # 코드 그룹 VO │ │ └── CodeDetailVO # 코드 상세 VO │ ├── auth/ # 권한 관리 │ │ ├── controller/AuthController │ │ ├── service/AuthService │ │ ├── mapper/AuthMapper │ │ └── model/ │ │ ├── AuthVO │ │ ├── GroupRoleVO │ │ ├── RoleMenuVO │ │ └── MenuProgramVO │ ├── loginLog/ # 로그인 로그 │ │ ├── controller/LoginLogController │ │ ├── service/LoginLogService │ │ └── model/LoginLogVO │ └── execquery/ # 쿼리 실행 (개발/디버깅용) │ ├── controller/DbQueryController │ ├── service/DbQueryService │ └── config/IsolatedTransactionManager │ ├── baseData/ # 기초 데이터 관리 │ └── bldgNewPrcCrtrAmt/ # 건축물 신축가격 기준액 관리 │ ├── controller/BldgNewPrcCrtrAmtController (추정) │ ├── service/BldgNewPrcCrtrAmtService │ ├── service/impl/BldgNewPrcCrtrAmtServiceImpl │ ├── mapper/BldgNewPrcCrtrAmtMapper │ └── model/BldgNewPrcCrtrAmtVO │ ├── crdn/ # 단속 관리 (핵심 비즈니스 도메인) │ ├── crndRegistAndView/ # 단속 등록 및 조회 │ │ ├── main/ # 메인 단속 프로세스 │ │ │ ├── controller/ │ │ │ │ ├── CrdnRegistAndViewController # 단속 등록/조회 │ │ │ │ ├── CrdnLevyPrvntcController # 부과예고 관리 │ │ │ │ ├── CrdnRelevyController # 재부과 관리 │ │ │ │ └── CrdnImpltTaskController # 이행 업무 관리 │ │ │ ├── service/ │ │ │ │ ├── CrdnRegistAndViewService │ │ │ │ ├── CrdnLevyPrvntcService │ │ │ │ ├── CrdnRelevyService │ │ │ │ └── CrdnImpltTaskService │ │ │ ├── service/impl/ │ │ │ │ ├── CrdnRegistAndViewServiceImpl │ │ │ │ ├── CrdnLevyPrvntcServiceImpl │ │ │ │ ├── CrdnRelevyServiceImpl │ │ │ │ └── CrdnImpltTaskServiceImpl │ │ │ └── model/ │ │ │ ├── CrdnRegistAndViewVO # 단속 기본 정보 VO │ │ │ ├── CrdnLevyInfoVO # 부과 정보 VO (계산식 포함) │ │ │ ├── CrdnRelevyVO # 재부과 정보 VO │ │ │ ├── CrdnImpltTaskVO # 이행 업무 VO │ │ │ ├── CrdnAdsbmtnRtVO # 가감산율 VO │ │ │ ├── CrdnCmpttnRt2VO # 산정률2 VO │ │ │ └── LevyPrvntcActInfoVO # 부과예고 행위정보 VO │ │ ├── crdnActInfo/ # 행위 정보 관리 │ │ │ ├── controller/CrdnActInfoController │ │ │ ├── service/ │ │ │ │ ├── CrdnActInfoService │ │ │ │ └── CrdnPhotoService # 사진 관리 │ │ │ ├── service/impl/ │ │ │ └── model/ │ │ │ ├── CrdnActInfoVO # 행위 정보 VO │ │ │ └── CrdnVltnLwrgVO # 위반 법령 VO │ │ ├── crdnPstnInfo/ # 위치 정보 관리 │ │ │ ├── controller/CrdnPstnInfoController │ │ │ ├── service/CrdnPstnInfoService │ │ │ └── model/CrdnPstnInfoVO # 위치 정보 VO │ │ ├── crdnOwnrInfo/ # 소유자 정보 관리 │ │ │ ├── controller/CrdnOwnrInfoController │ │ │ ├── service/CrdnOwnrInfoService │ │ │ └── model/CrdnOwnrInfoVO # 소유자 정보 VO │ │ ├── crdnActrInfo/ # 행위자 정보 관리 │ │ │ ├── controller/CrdnActrInfoController │ │ │ ├── service/CrdnActrInfoService │ │ │ └── model/ (추정) │ │ ├── crdnExmnr/ # 조사자 정보 관리 │ │ │ ├── controller/CrdnExmnrController │ │ │ ├── service/CrdnExmnrService │ │ │ ├── mapper/CrdnExmnrMapper │ │ │ └── model/CrdnExmnrVO │ │ └── crdnOwnrSelect/ # 소유자 선택 │ │ ├── controller/CrdnOwnrSelectController │ │ ├── service/CrdnOwnrSelectService │ │ └── service/impl/CrdnOwnrSelectSelectServiceImpl │ ├── ownac/ # 소유자 조치 관리 │ │ ├── controller/OwnActRegistAndViewController │ │ ├── service/OwnActRegistAndViewService │ │ └── service/impl/OwnActRegistAndViewServiceImpl │ └── exmnr/ # 조사자 관리 │ ├── controller/ExmnrController │ ├── service/ExmnrService │ └── service/impl/ExmnrServiceImpl │ ├── noti/ # 알림 시스템 (추정) │ └── ma30/ # MA30 관련 (추정) └── model/ ├── Ma30FindListVO └── Ma30FindRlistSearchVO ``` ### 1.2 View (JSP) 디렉토리 구조 ``` src/main/webapp/WEB-INF/views/ │ ├── common/ # 공통 뷰 │ ├── header.jsp # 헤더 │ ├── footer.jsp # 푸터 │ └── menu.jsp # 메뉴 │ ├── login/ # 로그인 │ └── login.jsp │ ├── system/ # 시스템 관리 │ ├── user/ # 사용자 관리 │ ├── group/ # 그룹 관리 │ ├── role/ # 역할 관리 │ ├── menu/ # 메뉴 관리 │ ├── code/ # 코드 관리 │ └── loginLog/ # 로그인 로그 │ ├── baseData/ # 기초 데이터 │ └── bldgNewPrcCrtrAmt/ # 건축물 신축가격 기준액 │ └── crdn/ # 단속 관리 ├── crndRegistAndView/ │ └── main/ │ ├── list.jsp # 단속 목록 │ ├── crdnRegistPopup.jsp # 단속 등록/수정 팝업 │ ├── detailView-main.jsp # 단속 상세보기 메인 │ └── crdnLevyPrvntc/ │ ├── levyPrvntcPopup.jsp # 부과예고 팝업 │ └── LevyAddMinusPopup.jsp # 가감산 팝업 └── ownac/ # 소유자 조치 ``` ### 1.3 MyBatis Mapper XML 구조 ``` src/main/resources/mybatis/mapper/ │ ├── common/ │ ├── CommonCodeMapper_maria.xml │ └── CommonHeaderMapper_maria.xml │ ├── login/ │ └── LoginMapper_maria.xml │ ├── system/ │ ├── user/UserMapper_maria.xml │ ├── group/GroupMapper_maria.xml │ ├── role/RoleMapper_maria.xml │ ├── menu/MenuMapper_maria.xml │ ├── code/CodeMapper_maria.xml │ ├── auth/AuthMapper_maria.xml │ └── loginLog/LoginLogMapper_maria.xml │ ├── baseData/ │ └── bldgNewPrcCrtrAmt/BldgNewPrcCrtrAmtMapper_maria.xml │ └── crdn/ ├── crndRegistAndView/ │ ├── main/ │ │ ├── CrdnRegistAndViewMapper_maria.xml │ │ ├── CrdnLevyPrvntcMapper_maria.xml │ │ ├── CrdnRelevyMapper_maria.xml │ │ └── CrdnImpltTaskMapper_maria.xml │ ├── crdnActInfo/ │ │ ├── CrdnActInfoMapper_maria.xml │ │ └── CrdnPhotoMapper_maria.xml │ ├── crdnPstnInfo/ │ │ └── CrdnPstnInfoMapper_maria.xml │ ├── crdnOwnrInfo/ │ │ └── CrdnOwnrInfoMapper_maria.xml │ ├── crdnActrInfo/ │ │ └── CrdnActrInfoMapper_maria.xml │ ├── crdnExmnr/ │ │ └── CrdnExmnrMapper_maria.xml │ └── crdnOwnrSelect/ │ └── CrdnOwnrSelectMapper_maria.xml ├── ownact/ │ └── OwnActRegistAndViewMapper_maria.xml └── exmnr/ └── ExmnrMapper_maria.xml ``` --- ## 2. 주요 업무 로직 상세 ### 2.1 단속 관리 프로세스 (crdn 도메인) #### 2.1.1 단속 등록 및 조회 (CrdnRegistAndViewController) **주요 API 엔드포인트:** - `GET /crdn/crndRegistAndView/list.do` - 단속 목록 화면 - `POST /crdn/crndRegistAndView/list.ajax` - 단속 목록 조회 (페이징) - `GET /crdn/crndRegistAndView/crdnRegistPopup.do` - 단속 등록/수정 팝업 - `GET /crdn/crndRegistAndView/detailView.do` - 단속 상세보기 - `POST /crdn/crndRegistAndView/insert.ajax` - 단속 등록 - `POST /crdn/crndRegistAndView/update.ajax` - 단속 수정 - `POST /crdn/crndRegistAndView/delete.ajax` - 단속 삭제 (논리삭제) - `GET /crdn/crndRegistAndView/selectOne.ajax` - 단속 상세 조회 - `POST /crdn/crndRegistAndView/updateStatus.ajax` - 단속 상태 업데이트 - `GET /crdn/crndRegistAndView/checkActCmpltCd.ajax` - 조치처리상태 확인 - `POST /crdn/crndRegistAndView/excel.do` - 단속 목록 엑셀 다운로드 **주요 필드 (CrdnRegistAndViewVO):** - `crdnYr` (단속 연도) + `crdnNo` (단속 번호) = 복합키 - `sggCd` (시군구 코드) - `crdnPrcsSttsCd` (단속 진행 상태 코드) - `dsclMthd` (적발 방법) - `stdgEmdCd` (법정동 읍면동 코드) - `rgnSeCd` (지역 구분 코드) **비즈니스 규칙:** 1. 등록 시 세션의 조직코드(orgCd)를 sggCd로 자동 설정 2. 삭제는 논리삭제 (DEL_YN='Y') 3. 페이징 처리 시 반드시 순서 준수: - 총 개수 조회 → totalCount 설정 → pagingYn='Y' 설정 #### 2.1.2 부과예고 관리 (CrdnLevyPrvntcController) **주요 API 엔드포인트:** - `GET /crdn/crndRegistAndView/crdnLevyPrvntc/selectLevyInfoFirstCheck.ajax` - 부과정보 존재 여부 확인 - `GET /crdn/crndRegistAndView/crdnLevyPrvntc/levyPrvntcPopup.do` - 부과예고 팝업 - `GET /crdn/crndRegistAndView/crdnLevyPrvntc/selectIsAllLevyInfoCompleted.ajax` - 부과정보 완료 여부 - `POST /crdn/crndRegistAndView/crdnLevyPrvntc/actlist.ajax` - 행위정보 목록 조회 - `GET /crdn/crndRegistAndView/crdnLevyPrvntc/LevyAddMinusPopup.do` - 가감산 팝업 - `POST /crdn/crndRegistAndView/crdnLevyPrvntc/adsbmtnRtList.ajax` - 가감산율 목록 조회 - `GET /crdn/crndRegistAndView/crdnLevyPrvntc/selectLevyInfoByActInfoId.ajax` - 기존 부과정보 조회 - `POST /crdn/crndRegistAndView/crdnLevyPrvntc/saveLevyInfo.ajax` - 부과정보 저장 (신규/수정 자동 판단) - `POST /crdn/crndRegistAndView/crdnLevyPrvntc/delLevyInfo.ajax` - 부과정보 삭제 - `POST /crdn/crndRegistAndView/crdnLevyPrvntc/calculateAll.ajax` - **통합 계산 API (핵심 로직)** **주요 필드 (CrdnLevyInfoVO):** - 기본키: `levyInfoId` - 참조키: `crdnYr`, `crdnNo`, `impltTaskSeCd`, `actInfoId` - 계산 관련 필드: - `bldgCrtrMprcAmt` (건물 기준 시가액) - `strctIdx` (구조 지수) - `usgIdx` (용도 지수) - `pstnIdx` (위치 지수) - `elpsYrRdvlrt` (경과 연도 잔가율) - `bscsCstrnRt` (기초 공사율) - `vltnArea` (위반 면적) - `adsbmtnEnfcRt` (가감산 시행률) - `cmpttnRt` (산정률) - `cmpttnRt2` (산정률2) - `bdstTxtnMprc` (건축물 과세 시가) - `mprcStdAmt` (시가 표준액) - `cmpttnAmt` (산정액) - `levyWholAmt` (부과 총액) **핵심 비즈니스 규칙:** 1. **스마트 저장 패턴**: - `saveLevyInfo.ajax`는 기존 데이터 존재 여부를 자동으로 확인 - 존재하면 UPDATE, 없으면 INSERT 자동 실행 2. **사전 검증**: - 부과예고 등록 전 반드시 위치정보, 행위정보가 먼저 등록되어야 함 - `selectLevyInfoFirstCheck.ajax`로 사전 검증 수행 3. **계산 스냅샷 패턴**: - 계산 시점의 모든 값(지수, 비율 등)을 DB에 저장 - 나중에 조회 시 저장된 값으로 복원하여 일관성 유지 #### 2.1.3 행위 정보 관리 (CrdnActInfoController) **주요 데이터:** - 위반 행위의 상세 정보 (행위 유형, 위반 법령 등) - 사진 정보 (CrdnPhotoService 별도 관리) #### 2.1.4 위치 정보 관리 (CrdnPstnInfoController) **주요 데이터:** - 단속 위치 정보 - 지번, 주소, 좌표 등 #### 2.1.5 소유자 정보 관리 (CrdnOwnrInfoController) **주요 데이터:** - 건축물 소유자 정보 - 성명, 연락처, 주소 등 --- ## 3. 데이터 흐름 상세 ### 3.1 표준 CRUD 데이터 흐름 #### 3.1.1 조회 (SELECT) 흐름 ``` [사용자] ↓ [JSP - list.jsp] ↓ (페이지 로드 시 TUI Grid 초기화) ↓ [JavaScript - dataSource.api.readData] ↓ (AJAX POST 요청: /list.ajax) ↓ [Controller - listAjax(@ModelAttribute VO)] ↓ (1. totalCount 조회) ↓ (2. setTotalCount) ↓ (3. setPagingYn("Y")) ↓ (4. Service 호출) ↓ [Service - selectList(VO)] ↓ (비즈니스 로직, 검증) ↓ [Mapper - selectList(VO)] ↓ (MyBatis 호출) ↓ [MyBatis XML - SELECT FROM TB_EXAMPLE WHERE DEL_YN = 'N' AND EXAMPLE_NM LIKE CONCAT('%', #{searchKeyword}, '%') ORDER BY REG_DT DESC LIMIT #{startRow}, #{perPageNum} INSERT INTO TB_EXAMPLE ( EXAMPLE_ID, EXAMPLE_NM, RGTR ) VALUES ( LPAD(NEXTVAL(seq_example_id), 10, '0'), #{exampleNm}, #{rgtr} ) UPDATE TB_EXAMPLE SET EXAMPLE_NM = #{exampleNm}, MDFR = #{mdfr} WHERE EXAMPLE_ID = #{exampleId} AND DEL_YN = 'N' UPDATE TB_EXAMPLE SET DEL_YN = 'Y', DLTR = #{dltr}, DEL_DT = NOW() WHERE EXAMPLE_ID = #{exampleId} AND DEL_YN = 'N' ``` --- ## 6. 주요 상수 및 설정 ### 6.1 모드 상수 ```java // 화면 모드 public static final String MODE_CREATE = "C"; // 등록 public static final String MODE_UPDATE = "U"; // 수정 public static final String MODE_VIEW = "V"; // 보기 public static final String MODE_DELETE = "D"; // 삭제 ``` ### 6.2 이행업무 구분 코드 (ImpltTaskSeConstants) ```java public static final String LEVY_PRVNTC = "1"; // 부과예고 public static final String LEVY = "2"; // 부과 public static final String RELEVY = "3"; // 재부과 public static final String IMPLT_TASK = "4"; // 이행강제금 ``` ### 6.3 삭제 여부 ```java public static final String DEL_YN_N = "N"; // 미삭제 public static final String DEL_YN_Y = "Y"; // 삭제됨 ``` ### 6.4 페이징 설정 ```java // PagingVO 기본값 private int page = 1; // 현재 페이지 private int perPageNum = 10; // 페이지당 행 수 private String pagingYn = "N"; // 페이징 사용 여부 ``` --- ## 7. 보안 및 권한 ### 7.1 세션 정보 사용 ```java // 사용자 ID 가져오기 String userId = SessionUtil.getUserId(); // 사용자 정보 가져오기 SessionVO sessionVO = SessionUtil.getSessionVO(); String orgCd = sessionVO.getUser().getOrgCd(); // 조직코드 String userNm = sessionVO.getUser().getUserNm(); // 사용자명 ``` ### 7.2 CSRF 보호 모든 JSP 폼에 CSRF 토큰 포함: ```jsp
``` --- ## 8. 에러 처리 ### 8.1 MessageException 사용 ```java if (data == null) { throw new MessageException("데이터를 찾을 수 없습니다."); } ``` ### 8.2 ApiResponseUtil 패턴 ```java // 성공 응답 ApiResponseUtil.success(data, "성공 메시지"); ApiResponseUtil.successWithGrid(list, vo); // 실패 응답 ApiResponseUtil.error("에러 메시지"); ``` --- ## 9. 엑셀 다운로드 ### 9.1 엑셀 다운로드 패턴 ```java @PostMapping("/excel.do") public void downloadExcel( @ModelAttribute ExampleVO paramVO, HttpServletRequest request, HttpServletResponse response) { try { // 페이징 없이 전체 조회 paramVO.setPagingYn("N"); List excelList = service.selectListForExcel(paramVO); // 파일명 생성 String filename = "예시목록_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".xlsx"; // 엑셀 파일 생성 및 다운로드 new SxssfExcelFile( ExcelSheetData.of(excelList, ExampleExcelVO.class, "예시 목록 " + excelList.size() + "건"), request, response, filename ); } catch (Exception e) { log.error("엑셀 다운로드 중 오류 발생", e); } } ``` --- ## 10. 참고 파일 경로 ### 10.1 핵심 비즈니스 로직 파일 **단속 등록/조회:** - Controller: `src/main/java/go/kr/project/crdn/crndRegistAndView/main/controller/CrdnRegistAndViewController.java` - Service: `src/main/java/go/kr/project/crdn/crndRegistAndView/main/service/impl/CrdnRegistAndViewServiceImpl.java` - Mapper XML: `src/main/resources/mybatis/mapper/crdn/crndRegistAndView/main/CrdnRegistAndViewMapper_maria.xml` - JSP: `src/main/webapp/WEB-INF/views/crdn/crndRegistAndView/main/list.jsp` **부과예고 관리 (계산 로직 포함):** - Controller: `src/main/java/go/kr/project/crdn/crndRegistAndView/main/controller/CrdnLevyPrvntcController.java` - Service: `src/main/java/go/kr/project/crdn/crndRegistAndView/main/service/impl/CrdnLevyPrvntcServiceImpl.java` - Mapper XML: `src/main/resources/mybatis/mapper/crdn/crndRegistAndView/main/CrdnLevyPrvntcMapper_maria.xml` - VO: `src/main/java/go/kr/project/crdn/crndRegistAndView/main/model/CrdnLevyInfoVO.java` - JSP: `src/main/webapp/WEB-INF/views/crdn/crndRegistAndView/main/crdnLevyPrvntc/levyPrvntcPopup.jsp` ### 10.2 공통 컴포넌트 **페이징:** - `src/main/java/go/kr/project/common/model/PagingVO.java` **공통코드:** - `src/main/java/go/kr/project/common/service/CommonCodeService.java` **유틸리티:** - `egovframework.util.ApiResponseUtil` (API 응답 생성) - `egovframework.util.SessionUtil` (세션 정보 조회) - `egovframework.util.excel.SxssfExcelFile` (엑셀 다운로드) --- **이 문서는 프로젝트의 전체 구조와 주요 업무 로직을 설명합니다. 새로운 기능 개발 시 이 문서를 참고하여 기존 패턴을 따라주세요.**