From a204324980d94d30ce6a7131d4ce3528d8ff32fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=84=B1=EC=98=81?= Date: Mon, 20 Oct 2025 16:26:32 +0900 Subject: [PATCH] =?UTF-8?q?CLAUDE.md=20ai=20=EB=B0=8F=20=EA=B0=9C=EB=B0=9C?= =?UTF-8?q?=20=EA=B0=80=EC=9D=B4=EB=93=9C=20=EB=82=B4=EC=9A=A9=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CLAUDE.md | 1393 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1393 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..d7935c3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,1393 @@ +# 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` (엑셀 다운로드) + +--- + +**이 문서는 프로젝트의 전체 구조와 주요 업무 로직을 설명합니다. 새로운 기능 개발 시 이 문서를 참고하여 기존 패턴을 따라주세요.** \ No newline at end of file