# 프로젝트 코딩 가이드라인 (Java Backend)

AI 에디터(Agent)는 다음 규칙을 항상 준수하여 코드를 작성하고 수정해야 합니다.

## 0. 기본 소통 규칙 (Communication)
- **언어**: 사용자에 대한 모든 답변과 코드 설명은 항상 **한글(Korean)**로만 작성해야 합니다.

## 1. 패키지 구성 (Package Structure)
- **컨트롤러 (Controller)**: `ctrl`
- **서비스 (Service)**: `svc`
- **DTO (Data Transfer Object)**: `dto`
- **매퍼 (Mapper)**: `mapper`
- **공통 서비스**: `com.madeu.common.service` (LogHistoryService 등 시스템 공통 모듈)

## 2. 파일 명명 규칙 및 구성 (File Naming Conventions)
- **컨트롤러 (Controller)**: `[도메인명]Controller.java` (예: `ABCDController.java`)
- **서비스 (Service)**: `[도메인명]Service.java` (인터페이스와 구현체(impl)를 분리하지 않고 Service 클래스 파일 하나로만 구현, 예: `ABCDService.java`)
- **DTO**: `[도메인명]DTO.java` (예: `ABCDDTO.java`)
- **매퍼 (Mapper)**: `[도메인명]Mapper.java` (예: `ABCDMapper.java`)
- **XML Mapper**: `[도메인명]SqlMap.xml` (namespace는 Mapper 인터페이스의 **FQCN**과 반드시 일치)

## 3. URL 및 메소드 명명 규칙 (RequestMapping & Method Naming)

### 1) RequestMapping (URL) 및 컨트롤러 메소드명
- 페이지 이동하는 url : `moveXXXX.do`
- 팝업 오픈하는 url : `openXXXX.do`
- 조회 url : `getXXXX.do`
- 저장 url : `putXXXX.do`
- 수정 url : `modXXXX.do`
- 삭제 url : `delXXXX.do`
- **단, 컨트롤러 메소드명은 위 url에서 `.do`를 제외한 이름과 동일하게 명명합니다.**

### 2) 서비스 메소드명
- 서비스 메소드명은 **컨트롤러 메소드명과 동일**하게 명명합니다.
  - 조회: `getXXXX` / 목록 조회: `getXXXXList`
  - 저장: `putXXXX`
  - 수정: `modXXXX`
  - 삭제: `delXXXX`

### 3) Mapper 인터페이스 메소드명
- 단일조회 : `selectXXXX`
- 리스트조회 : `selectListXXXX`
- insert : `insertXXXX`
- update : `updateXXXX`
- delete : `deleteXXXX`

## 4. 데이터베이스 연동 정보 (DB Connection)
- `application-local.yml`의 설정을 기반으로 한 공통 접속 정보입니다.
- **Host**: 183.98.184.84
- **Port**: 3306
- **Database**: madeu
- **User**: madeu
- **Password**: apdlemdb12#$

## 5. 아키텍처 및 코딩 원칙 (Architecture & Coding Principles)

### 5-1. 컨트롤러 원칙 (Skinny Controller)
- 컨트롤러에는 비즈니스 로직이나 예외처리 로직을 넣지 않고, **서비스 메서드를 호출하는 1줄로만 작성**합니다.
- 컨트롤러 클래스는 `@Controller` 대신 **`@RestController`**를 사용하며, `@ResponseBody`는 생략합니다.
- 데이터 입출력 메소드의 파라미터는 **단일 DTO 하나만 `@RequestBody`**로 받습니다.
- 파일 업로드가 포함된 경우에만 `@ModelAttribute` + `@RequestParam MultipartFile`을 허용합니다.
- 화면 이동(`move~`) 메소드는 **`ModelAndView`를 리턴**합니다. (`@RestController`에서 String 리턴 시 뷰 이름이 아닌 응답 바디로 해석되므로)
- 화면 이동 메소드의 뷰 경로는 **컨트롤러에서 직접 명시**합니다. (서비스에 위임 금지)

### 5-2. 서비스 원칙 (Service Layer)
- 에러 처리(try-catch), 응답 메시지(msgCode, msgDesc) 설정은 **서비스 계층에서 전담**합니다.
- `HttpServletRequest`, `HttpSession`은 `@Autowired`로 직접 주입받아 사용합니다. (Spring이 Request-scope 프록시로 제공)
- `session.getAttribute("loginMemberId")`를 통해 로그인 ID를 가져오고, DTO에 설정합니다.
- 권한 체크는 `request.getAttribute("selectUseYn")` 등 인터셉터가 설정한 값을 참조합니다.

### 5-3. DTO 원칙 (DTO Communication)
- **HashMap 사용 금지**. 컨트롤러 ↔ 서비스 ↔ 매퍼 간 모든 데이터는 **DTO 객체만 사용**합니다.
- DTO에는 `@Data` (Lombok)을 사용합니다.
- DTO 필드 구성:
  - **DB 컬럼 매핑 필드**: `muProcedureReviewId`, `title`, `content` 등
  - **조회 결과 전용 필드**: `rowNum`, `writeDate`, `writeName` 등
  - **검색/UI 변수**: `startDate`, `endDate`, `start`, `limit`, `sort`, `dir` 등
  - **접근/로직 변수**: `loginMemberId`
  - **응답 매핑 변수**: `msgCode`, `msgDesc`, `success`, `totalCount`, `rows`(Object 타입), `tId`

### 5-4. Mapper 원칙 (MyBatis Mapper)
- Mapper는 **`@Mapper` 어노테이션을 사용한 인터페이스**로 작성합니다. (`SqlSessionDaoSupport` 상속 금지)
- XML Mapper의 `namespace`는 Mapper 인터페이스의 **FQCN(Fully Qualified Class Name)**과 일치시킵니다.
- XML의 `resultType`은 `hashmap` 대신 **DTO FQCN**을 사용합니다.
  - 예외: 도메인 외부 테이블 조회(카테고리 등)는 `hashmap` 허용
- XML alias는 **DTO 필드명(camelCase)**과 정확히 일치시킵니다.
- 단건 조회는 `List` 대신 **DTO 단일 객체를 리턴**합니다.

## 6. 공통 모듈 사용 규칙 (Common Modules)

### 6-1. 로그 히스토리 (LogHistoryService)
- 위치: `com.madeu.common.service.LogHistoryService`
- CUD 작업 후 반드시 호출합니다:
  ```java
  logHistoryService.save("기능명", "서비스명", requestObj, responseObj, errorMsg);
  ```
- `request`, `session`은 LogHistoryService 내부에서 자동 주입되므로 호출 시 전달할 필요 없습니다.

### 6-2. 메시지 서비스 (MessageSource)
- 위치: `src/main/resources/messages.properties`
- 서비스에서 하드코딩 메시지 대신 **메시지 코드**를 사용합니다:
  ```java
  @Autowired
  private MessageSource messageSource;

  private String msg(String code) {
      return messageSource.getMessage(code, null, Locale.getDefault());
  }

  // 사용 예
  dto.setMsgDesc(msg("auth.error.select"));
  dto.setMsgDesc(msg("success.insert"));
  ```
- 공통 메시지 코드 규칙:
  - 권한 오류: `auth.error.{select|insert|update|delete|noAuth}`
  - CRUD 성공: `success.{insert|update|delete}`
  - CRUD 실패: `error.{select|insert|update|delete}`
  - 모듈별 메시지: `{모듈명}.{카테고리}.{설명}` (예: `procedureReview.error.noData`)

## 7. 인터셉터 및 필터 규칙 (Interceptor & Filter)

### 7-1. WebLoginInterceptor
- 인터셉터 `postHandle`에서 권한 속성(`selectUseYn`, `insertUseYn`, `updateUseYn`, `deleteUseYn`)을 ModelAndView에 주입합니다.
- 서비스에서 `request.getAttribute("xxxUseYn")`으로 권한을 체크합니다.

### 7-2. RequestCachingFilter (CachedBodyRequestWrapper)
- `application/json` 요청만 `CachedBodyRequestWrapper`로 래핑합니다.
- Multipart, GET 등 다른 요청은 래핑하지 않습니다.

## 8. 파일 업로드 규칙 (File Upload)
- `MultipartFile.transferTo()` 사용 시 반드시 **절대경로를 명시**합니다:
  ```java
  File dest = new File(outDir, savedName);
  file.transferTo(dest.toPath().toAbsolutePath());
  ```
- 상대경로 사용 시 Tomcat 임시 디렉토리 기준으로 해석되어 오류가 발생합니다.

## 9. 참조 구현체 (Reference Implementation)
- **`ProcedureReview`** 모듈이 위 규칙의 기준 구현체입니다.
- 새로운 모듈 개발 시 `com.madeu.crm.procedureReview` 패키지 구조를 참고합니다:
  - `ctrl/ProcedureReviewController.java` - Skinny Controller 패턴
  - `svc/ProcedureReviewService.java` - MessageSource + LogHistoryService + DTO 기반
  - `dto/ProcedureReviewDTO.java` - 응답/검색/DB 매핑 필드 분류
  - `mapper/ProcedureReviewMapper.java` - @Mapper 인터페이스
  - `mappers/ProcedureReviewSqlMap.xml` - DTO resultType + FQCN namespace
