chore: Remove obsolete .classpath file

- Deleted the .classpath file as it is no longer needed in the project structure.
- This cleanup helps maintain a tidy codebase by removing unnecessary files that may cause confusion or clutter.
This commit is contained in:
kjs
2026-03-04 15:31:45 +09:00
parent 96637a9cb6
commit ea8b4ce5dc
2303 changed files with 480 additions and 850602 deletions

View File

@@ -377,7 +377,7 @@ docker-compose -f docker-compose.backend.mac.yml up --build -d
- Node.js 백엔드: `backend-node/` 디렉토리
- Next.js 프론트엔드: `frontend/` 디렉토리
- 데이터베이스: PostgreSQL (JNDI 설정)
- 데이터베이스: PostgreSQL (pg 드라이버)
---

File diff suppressed because it is too large Load Diff

View File

@@ -1,195 +0,0 @@
# PLM 윈도우 개발환경 가이드
## 🚀 빠른 시작
### 1. 전체 환경 시작
```cmd
start-windows.bat
```
### 2. 환경 중지
```cmd
stop-windows.bat
```
### 3. 빌드만 실행
```cmd
build-windows.bat
```
## 📋 사전 요구사항
### 필수 소프트웨어
- **Docker Desktop for Windows** (WSL2 백엔드 사용)
- **Java Development Kit (JDK) 7 이상**
- **Git for Windows**
### Docker Desktop 설정
1. Docker Desktop 설치
2. **Settings > General**에서 "Use WSL 2 based engine" 체크
3. **Settings > Resources > WSL Integration**에서 WSL 배포판 활성화
## 📁 파일 구조
```
new_ph/
├── start-windows.bat # 🎯 메인 시작 스크립트
├── stop-windows.bat # ⏹️ 중지 스크립트
├── build-windows.bat # 🔨 Java 빌드 스크립트
├── docker-compose.win.yml # 🐳 윈도우용 Docker Compose
├── Dockerfile.win # 🐳 윈도우용 Dockerfile
├── config.windows.env # ⚙️ 환경 변수 설정
└── README-WINDOWS.md # 📖 이 파일
```
## ⚙️ 환경 설정
### config.windows.env 파일 수정
```env
# 데이터베이스 설정
DB_PASSWORD=your_password_here
# 포트 설정 (충돌 시 변경)
TOMCAT_PORT=9090
# 메모리 설정
TOMCAT_MEMORY_MIN=512m
TOMCAT_MEMORY_MAX=1024m
```
## 🐳 Docker 서비스
### 애플리케이션 서비스
- **컨테이너명**: plm-windows
- **포트**: 9090 → 8080
- **접속 URL**: http://localhost:9090
### 데이터베이스 서비스
- **컨테이너명**: plm-postgres-win
- **포트**: 5432 → 5432
- **데이터베이스**: plm
- **사용자**: postgres
- **패스워드**: ph0909!!
## 🔧 주요 명령어
### Docker 관리
```cmd
# 컨테이너 상태 확인
docker-compose -f docker-compose.win.yml ps
# 로그 확인
docker-compose -f docker-compose.win.yml logs -f
# 특정 서비스 로그
docker-compose -f docker-compose.win.yml logs -f plm-app
docker-compose -f docker-compose.win.yml logs -f plm-db
# 컨테이너 재시작
docker-compose -f docker-compose.win.yml restart plm-app
```
### 개발 작업
```cmd
# 빌드만 실행
build-windows.bat
# 컨테이너 재빌드
docker-compose -f docker-compose.win.yml up --build -d
# 데이터베이스 리셋
docker-compose -f docker-compose.win.yml down -v
docker-compose -f docker-compose.win.yml up -d
```
## 🐛 문제 해결
### Docker Desktop 실행 안됨
```cmd
# Windows 서비스 확인
sc query com.docker.service
# WSL2 상태 확인
wsl --status
# Docker Desktop 재시작
taskkill /f /im "Docker Desktop.exe"
start "" "C:\Program Files\Docker\Docker\Docker Desktop.exe"
```
### Java 컴파일 오류
```cmd
# Java 버전 확인
java -version
javac -version
# 클래스패스 문제 시 수동 빌드
javac -cp "WebContent\WEB-INF\lib\*" -d WebContent\WEB-INF\classes src\com\pms\**\*.java
```
### 포트 충돌
```cmd
# 포트 사용 확인
netstat -ano | findstr :9090
# 프로세스 종료
taskkill /PID <PID번호> /F
```
### 볼륨 권한 문제
```cmd
# Docker 볼륨 정리
docker volume prune -f
# WSL2 재시작
wsl --shutdown
```
## 📊 모니터링
### 리소스 사용량
```cmd
# Docker 시스템 정보
docker system df
# 컨테이너 리소스 사용량
docker stats
# 로그 크기 확인
dir logs /s
```
### 헬스체크
```cmd
# 애플리케이션 상태
curl http://localhost:9090
# 데이터베이스 연결 테스트
docker exec plm-postgres-win psql -U postgres -d plm -c "SELECT version();"
```
## 🔄 업데이트
### 코드 변경 후
1. `build-windows.bat` 실행
2. `docker-compose -f docker-compose.win.yml restart plm-app`
### Docker 이미지 업데이트
```cmd
docker-compose -f docker-compose.win.yml down
docker-compose -f docker-compose.win.yml pull
docker-compose -f docker-compose.win.yml up --build -d
```
## 📞 지원
문제가 발생하면 다음을 확인하세요:
1. **로그 파일**: `logs/` 디렉토리
2. **Docker 로그**: `docker-compose -f docker-compose.win.yml logs`
3. **시스템 요구사항**: Docker Desktop, WSL2, Java JDK
4. **네트워크**: 방화벽, 포트 충돌
---
**🎉 즐거운 개발 되세요!**

View File

@@ -1,126 +0,0 @@
# TODO: 프론트엔드 Next.js 마이그레이션
이 문서는 기존 Java/Spring 백엔드(ilshin)는 유지하면서, JSP/jQuery 기반의 프론트엔드를 Next.js 기반으로 전환하기 위한 작업 목록입니다.
## 단계 1: 사전 준비 및 분석
- [ ] **Next.js 프로젝트 생성:** `create-next-app`을 사용하여 신규 Next.js 프로젝트 생성 (TypeScript 사용 권장)
- [ ] **프로젝트 구조 설정:** 폴더 구조 정의 (e.g., `components`, `pages` or `app`, `styles`, `lib` or `utils`, `hooks`, `api`)
- [ ] **스타일링 솔루션 선택 및 설정:**
- [ ] CSS Modules, Tailwind CSS, Styled Components, Emotion 등 선택
- [ ] 기본 테마 및 전역 스타일 설정
- [ ] **기존 프론트엔드 분석 (매우 중요):**
- [ ] **페이지/뷰 식별:** `WebContent/WEB-INF/view/` 내 모든 JSP 파일 분석하여 페이지 목록 작성
- [ ] **컴포넌트 식별:** 재사용되는 UI 요소 식별 (버튼, 폼, 테이블, 모달, 차트, 그리드 등). 특히 `jqGrid`, `Highcharts` 등 특정 라이브러리 기반 컴포넌트 파악
- [ ] **라우팅 분석:** 기존 URL 패턴 (`*.do` 등)과 Spring Controller 매핑 관계 파악하여 Next.js 라우팅 구조 설계
- [ ] **인증/인가 흐름 분석:** 로그인 방식, 세션 관리, 페이지 접근 권한 로직 파악
- [ ] **기존 JavaScript 분석:** `WebContent/js/` 내 파일 분석하여 중요한 UI 로직, 데이터 처리, 상태 관리 방식 파악 (특히 `common.js` 등)
- [ ] **상태 관리 전략 수립:** Next.js 애플리케이션의 상태 관리 방법 결정 (Context API, Zustand, Jotai, Redux 등)
- [ ] **UI 라이브러리/컴포넌트 시스템 검토:** 필요한 경우 Material UI, Chakra UI, Ant Design, Shadcn/ui 등 검토 또는 자체 디자인 시스템 구축 결정
## 단계 2: 백엔드 API 준비 (핵심 작업)
**배경:** 현재 백엔드 아키텍처는 Spring MVC 기반으로, `@Controller`가 요청을 받아 비즈니스 로직을 처리하는 `@Service`를 호출하고, 그 결과를 `ModelAndView` 또는 모델 객체에 담아 `InternalResourceViewResolver`를 통해 `/WEB-INF/view/` 경로의 JSP 뷰로 전달하여 렌더링하는 구조입니다. Next.js 프론트엔드와 통신하기 위해서는, 기존의 Service 계층과 비즈니스 로직은 최대한 재사용하면서, Controller 레벨에서 JSP 뷰 이름 대신 JSON 데이터를 반환하는 RESTful API 엔드포인트를 새로 구축하거나 기존 Controller를 수정해야 합니다.
- [ ] **기존 기능 및 데이터 흐름 분석 (재확인):**
- [ ] `WebContent/WEB-INF/view/`의 각 JSP 페이지와 매핑되는 `com.pms.controller` 패키지 내의 Spring Controller 메소드 파악 (`@RequestMapping` 경로 확인)
- [ ] 각 Controller 메소드가 호출하는 Service 메소드 및 사용되는 데이터 모델(VO/DTO) 분석
- [ ] 페이지 로딩 시 필요한 데이터 조회 로직, 폼 제출 시 데이터 처리 로직 식별
- [ ] **API 엔드포인트 상세 설계:**
- [ ] 기존 기능 기반으로 필요한 REST API 엔드포인트 목록 작성 (리소스 기반 설계 권장, e.g., `/api/products`, `/api/boms`, `/api/documents`, `/api/projects`, `/api/users` 등)
- [ ] 각 리소스별 CRUD(POST, GET, PUT/PATCH, DELETE) 엔드포인트 정의
- 예: `GET /api/products` (목록 조회), `GET /api/products/{id}` (상세 조회), `POST /api/products` (생성), `PUT /api/products/{id}` (수정), `DELETE /api/products/{id}` (삭제)
- [ ] 목록 조회 시 필요한 검색, 필터링, 페이징 파라미터 정의 (e.g., `GET /api/products?search=...&page=1&size=10`)
- [ ] 파일 업로드/다운로드 등 특수 기능에 대한 엔드포인트 정의
- [ ] 기존의 복잡한 로직 (여러 서비스 호출 등)을 처리하기 위한 맞춤형 엔드포인트 정의 (필요 최소화)
- [ ] **인증/인가 API 상세 설계:**
- [ ] 로그인: `POST /api/auth/login` (ID/PW 받아 성공 시 사용자 정보 및 세션 ID/토큰 반환)
- [ ] 로그아웃: `POST /api/auth/logout`
- [ ] 현재 사용자 상태 확인: `GET /api/auth/status` (세션/토큰 유효성 검사 및 사용자 정보 반환)
- [ ] **REST API 구현 전략 결정:**
- [ ] **방법:** 신규 `@RestController` 클래스 생성: API 전용 컨트롤러를 새로 만들고, 내부적으로 기존 Service 로직을 호출하여 JSON 반환. (기존 코드 영향 최소화, 역할 분리 명확) **(권장)**
- [ ] **REST API 실제 구현 (선택한 전략 기반):**
- [ ] Spring MVC 또는 Spring WebFlux 기반으로 `@RestController` 구현
- [ ] Service 계층 재사용하여 비즈니스 로직 처리
- [ ] 데이터베이스 조회 결과를 DTO(Data Transfer Object)로 변환하여 반환 (필요시 API 전용 DTO 생성)
- [ ] `ResponseEntity`를 사용하여 HTTP 상태 코드, 헤더, 응답 본문 명시적으로 제어
- [ ] 예외 처리: `@ControllerAdvice``@ExceptionHandler`를 사용하여 API 예외 공통 처리 및 표준화된 오류 응답 반환
- [ ] **CORS (Cross-Origin Resource Sharing) 설정:**
- [ ] `WebMvcConfigurer` 인터페이스 구현 및 `addCorsMappings` 메소드 오버라이드하여 전역 CORS 설정
- [ ] 또는 Spring Security 사용 시 Security 설정 내에서 CORS 구성
- [ ] 허용할 Origin 명시 (`http://localhost:9771` 등 Next.js 개발 서버 주소 포함)
- [ ] 허용할 HTTP 메소드 (`GET`, `POST`, `PUT`, `DELETE` 등) 및 헤더 설정
- [ ] **API 응답 형식 표준화 구현:**
- [ ] 공통 응답 Wrapper 클래스 정의 (e.g., `ApiResponse<T>`)
- [ ] 모든 API가 이 Wrapper를 사용하여 응답하도록 구현 (성공/실패 여부, 데이터, 메시지 등 포함)
```java
// 예시 Wrapper 클래스
public class ApiResponse<T> {
private boolean success;
private T data;
private String message;
// 생성자, getter 등
}
```
- [ ] **API 문서화 자동화:**
- [ ] `springdoc-openapi` (권장) 또는 `Springfox` 라이브러리 의존성 추가
- [ ] Spring Boot 설정 파일 또는 Java Configuration 통해 기본 설정 (API 정보, 서버 URL 등)
- [ ] Controller 및 DTO에 `@Operation`, `@Parameter`, `@Schema` 등 어노테이션 추가하여 API 명세 작성
- [ ] Swagger UI 접속 경로 활성화 (e.g., `/swagger-ui.html`)
- [ ] **API 인가(Authorization) 처리:**
- [ ] Spring Security 설정 검토 및 활성화 (필요시)
- [ ] 기존 인증/인가 로직 (세션 기반 등) 분석하여 API 요청에도 적용되도록 설정
- [ ] 각 `@RestController` 메소드 또는 Security 설정에서 URL 패턴별 접근 권한 설정 (`@PreAuthorize` 또는 `HttpSecurity` 설정 활용)
- [ ] 기존 사용자 역할/권한 체계 연동
## 단계 3: Next.js 프론트엔드 개발
- [ ] **기본 레이아웃 컴포넌트 구현:** Header, Footer, Sidebar/Menu 등 공통 레이아웃 구조 구현 (`main/header.jsp`, `main/menu.jsp` 등 참조)
- [ ] **라우팅 구현:** 분석 단계에서 설계한 라우팅 구조에 따라 Next.js 페이지 생성 및 라우팅 설정 (`pages` 또는 `app` 디렉토리 사용)
- [ ] **공통 UI 컴포넌트 개발:** 버튼, 입력 필드, 모달 등 재사용 가능한 기본 컴포넌트 구현 또는 UI 라이브러리 적용
- [ ] **주요 라이브러리 대체 컴포넌트 구현/선택:**
- [ ] `jqGrid` 대체: TanStack Table, AG Grid, 또는 직접 구현
- [ ] `Highcharts` 대체: Recharts, Chart.js (react-chartjs-2), Nivo 등
- [ ] 기타 필요한 라이브러리 (달력, 파일 업로더 등) 대체 컴포넌트 구현/선택
- [ ] **페이지별 UI 구현:** 각 페이지의 UI를 JSP 분석 결과 바탕으로 Next.js 컴포넌트 사용하여 구현
- [ ] **폼(Form) 구현:** 데이터 입력/수정을 위한 폼 구현 (react-hook-form 등 라이브러리 사용 권장)
- [ ] **인증 흐름 구현:** 로그인 페이지, API 연동, 토큰/세션 정보 저장 및 관리 로직 구현 (Client-side storage 보안 고려)
- [ ] **전역 상태 관리 설정:** 선택한 상태 관리 라이브러리 설정 및 필요한 전역 상태(사용자 정보 등) 관리 로직 구현
## 단계 4: 백엔드 연동 및 통합
- [ ] **API 클라이언트 구현:** 백엔드 API 호출을 위한 함수/모듈 구현 (`fetch` API, `axios`, `SWR`, `React Query` 등 사용)
- [ ] **데이터 연동:** 각 페이지 및 컴포넌트에서 필요한 데이터를 API 클라이언트를 통해 가져와 화면에 표시
- [ ] **폼 제출 연동:** 폼 데이터를 백엔드 API로 전송하는 로직 구현
- [ ] **인증/인가 연동:** 로그인 상태에 따른 라우팅 제어, API 요청 시 인증 정보(토큰 등) 포함 로직 구현
## 단계 5: 테스트
- [ ] **단위 테스트:** 주요 컴포넌트, 커스텀 훅, 유틸리티 함수 단위 테스트 작성 (Jest, React Testing Library 등)
- [ ] **통합 테스트:** API 연동 부분 테스트 (Mocking 또는 실제 API 사용)
- [ ] **E2E 테스트:** 주요 사용자 시나리오 기반 End-to-end 테스트 작성 (Cypress, Playwright 등)
- [ ] **크로스 브라우저 테스트:** 주요 웹 브라우저 환경에서 테스트
- [ ] **성능 테스트:** 초기 로딩 속도, 데이터 조회/처리 속도 등 성능 측정 및 개선
## 단계 6: 빌드 및 배포
- [ ] **Next.js 빌드 설정:** 프로덕션 환경용 빌드 설정 (`next build`)
- [ ] **배포 전략 수립:**
- [ ] 정적 파일(Static Export) 배포 또는 Node.js 서버를 이용한 배포 결정
- [ ] 백엔드(Tomcat)와 프론트엔드(Next.js) 분리 배포
- [ ] 필요시 리버스 프록시(Nginx 등) 설정하여 요청 라우팅 (e.g., `/api`는 백엔드, 나머지는 프론트엔드)
- [ ] **CI/CD 파이프라인 구축:** 빌드, 테스트, 배포 자동화 파이프라인 구축
- [ ] **환경 변수 설정:** 배포 환경(Production)에 맞는 환경 변수 설정 (API 주소, 시크릿 키 등)
## 단계 7: 기존 프론트엔드 코드 제거 (선택 사항)
- [ ] Next.js 프론트엔드가 안정화된 후, 기존 `WebContent` 내 JSP 파일, 관련 JavaScript, CSS 등 제거
- [ ] 백엔드에서 JSP 렌더링 관련 의존성 제거 (가능한 경우)
---
**주요 고려 사항:**
- **백엔드 API 변경의 복잡성:** 기존 코드가 뷰 렌더링과 강하게 결합되어 있다면, 순수 데이터만 반환하는 API로 변경하는 작업이 가장 중요하고 어려울 수 있습니다.
- **라이브러리 의존성:** jqGrid, Highcharts 등 기존 JavaScript 라이브러리의 기능을 React/Next.js 생태계의 라이브러리로 대체하는 작업이 필요합니다.
- **인증 방식:** 기존 세션 기반 인증을 계속 사용할지, 아니면 토큰 기반(JWT 등)으로 변경할지 결정해야 합니다.

View File

@@ -1,847 +0,0 @@
```sql
CREATE TABLE public.swsc110a_tbl (
orderno varchar(10) NOT NULL,
acntunit varchar(1) NOT NULL,
orderym varchar(6) NOT NULL,
orderser varchar(3) NOT NULL,
orderunit varchar(1) NOT NULL,
salegb varchar(1) NOT NULL,
saletype varchar(2) NOT NULL,
chulhayn varchar(1) NULL,
custcd varchar(6) NOT NULL,
deptcd varchar(5) NOT NULL,
salesman varchar(30) NOT NULL,
bdeptcd varchar(30) NOT NULL,
bempno varchar(30) NOT NULL,
orderdate varchar(8) NOT NULL,
finishdate varchar(8) NULL,
goodscd varchar(15) NULL,
goodsguarantee int4 NULL,
goodsqty int4 NULL,
saleqty int4 NULL,
saleqty1 int4 NULL,
supplyqty int4 NULL,
saleprice numeric NULL,
saleamt numeric NULL,
vatamt numeric NULL,
supplyamt numeric NULL,
rcptamt numeric NULL,
nowonsymbol varchar(5) NULL,
nowonprice numeric NULL,
nowonexchange numeric NULL,
nowonamt numeric NULL,
nowonsupply numeric NULL,
nowonsupplypal numeric NULL,
nowonrcpt numeric NULL,
nowonrcptpal numeric NULL,
nationgb varchar(3) NULL,
optionamt numeric NULL,
etcamt numeric NULL,
endsale varchar(1) NULL,
custreq varchar(1) NULL,
bigo varchar(90) NULL,
workman varchar(30) NOT NULL,
cancelflag varchar(1) NOT NULL,
cancelworkman varchar(30) NULL,
cancelbigo varchar(90) NULL,
cret_date timestamp NULL,
cretempno varchar(30) NOT NULL,
edit_date timestamp NULL,
editempno varchar(30) NOT NULL,
goodsyn varchar(1) NULL,
past_project_no varchar(50) NULL,
equipment_name varchar(200) NULL,
equipment_count numeric(10, 2) NULL,
request_delivery_date date NULL,
delivery_location varchar(200) NULL,
setup_location varchar(200) NULL,
material varchar(100) NULL,
pressure_bar numeric(10, 2) NULL,
temperature_celsius numeric(10, 2) NULL,
capacity_liter numeric(10, 2) NULL,
closure_type varchar(100) NULL,
consumables_etc varchar(200) NULL,
voltage varchar(50) NULL,
certification_status varchar(50) NULL,
sales_progress_stage varchar(50) NULL,
currency_type varchar(20) NULL,
quote_amount_1st numeric(15, 2) NULL,
quote_amount_2nd numeric(15, 2) NULL,
quote_amount_3rd numeric(15, 2) NULL,
order_date date NULL,
order_period varchar(50) NULL,
result_status varchar(50) NULL,
order_amount_krw numeric(15, 2) NULL,
contract_method varchar(50) NULL,
failure_reason varchar(50) NULL,
po_number varchar(100) NULL,
pm_manager varchar(50) NULL,
project_title varchar(200) NULL,
company_project_name varchar(200) NULL,
special_notes text NULL,
CONSTRAINT pk_swsc110a_tbl PRIMARY KEY (orderno)
);
CREATE INDEX idx_swsc110a_equipment_name ON public.swsc110a_tbl USING btree (equipment_name);
CREATE INDEX idx_swsc110a_order_date ON public.swsc110a_tbl USING btree (order_date);
CREATE INDEX idx_swsc110a_pm_manager ON public.swsc110a_tbl USING btree (pm_manager);
CREATE INDEX idx_swsc110a_result_status ON public.swsc110a_tbl USING btree (result_status);
CREATE INDEX idx_swsc110a_sales_progress ON public.swsc110a_tbl USING btree (sales_progress_stage);
```
---
```sql
CREATE TABLE public.contract_mgmt (
objid varchar NOT NULL,
category_cd varchar NULL,
customer_objid varchar NULL,
product varchar NULL,
customer_project_name varchar NULL,
status_cd varchar NULL,
due_date varchar NULL,
"location" varchar NULL,
setup varchar NULL,
facility varchar NULL,
facility_qty varchar NULL,
facility_type varchar NULL,
facility_depth varchar NULL,
production_no varchar NULL,
bus_cal_cd varchar NULL,
category1_cd varchar NULL,
chg_user_id varchar NULL,
plan_date varchar NULL,
complete_date varchar NULL,
result_cd varchar NULL,
project_no varchar NULL,
pm_user_id varchar NULL,
contract_price varchar NULL,
regdate timestamp NULL,
writer varchar NULL,
contract_no varchar NULL,
customer_equip_name varchar NULL,
req_del_date varchar NULL,
contract_del_date varchar NULL,
contract_company varchar NULL,
contract_date varchar NULL,
po_no varchar NULL,
manufacture_plant varchar NULL,
contract_result varchar NULL,
project_name varchar NULL,
spec_user_id varchar NULL,
spec_plan_date varchar NULL,
spec_comp_date varchar NULL,
spec_result_cd varchar NULL,
est_plan_date varchar NULL,
est_user_id varchar NULL,
est_comp_date varchar NULL,
est_result_cd varchar NULL,
area_cd varchar NULL,
contract_price_currency varchar NULL,
contract_currency varchar NULL,
customer_production_no varchar NULL,
target_project_no varchar NULL,
mechanical_type varchar NULL,
target_project_no_direct varchar NULL,
overhaul_order varchar NULL,
past_project_no varchar(50) NULL,
equipment_name varchar(200) NULL,
equipment_count varchar(100) NULL,
request_delivery_date varchar(20) NULL,
delivery_location varchar(200) NULL,
setup_location varchar(200) NULL,
material varchar(100) NULL,
pressure_bar varchar(50) NULL,
temperature_celsius varchar(50) NULL,
capacity_liter varchar(50) NULL,
closure_type varchar(100) NULL,
consumables_etc varchar(200) NULL,
voltage varchar(50) NULL,
certification_status varchar(50) NULL,
sales_progress_stage varchar(50) NULL,
currency_type varchar(20) NULL,
quote_amount_1st numeric(15, 2) NULL,
quote_amount_2nd numeric(15, 2) NULL,
quote_amount_3rd numeric(15, 2) NULL,
order_date varchar(20) NULL,
order_period varchar(50) NULL,
result_status varchar(50) NULL,
order_amount_krw numeric(15, 2) NULL,
contract_method varchar(50) NULL,
failure_reason varchar(50) NULL,
po_number varchar(100) NULL,
pm_manager varchar(50) NULL,
project_title varchar(200) NULL,
company_project_name varchar(200) NULL,
special_notes text NULL,
CONSTRAINT contract_mgmt_pkey PRIMARY KEY (objid)
);
```
등록창 수정
[영업정보]
계약구분(공통코드선택), 과거프로젝트번호(프로젝트데이터선택), 국내/해외고객사(공통코드선택), 제품군(기존 선택코드 참조), 제품코드(기존 선택코드 참조), 장비명, 설비대수, 요청납기일(캘린더 활용), 입고지, 셋업지
[사양상세]
재질, 압력(BAR), 온도(℃), 용량(LITER), Closure type, 기타(소모품), 전압, 인증여부
[영업진행]
단계(선택 공통코드)
[견적이력 및 결과]
통화(기존 공통코드), 견적 금액(1차), 견적 금액(2차), 견적 금액(3차), 수주일, 수주가(자동계산), Result(공통코드), 계약방식(공통코드), 실폐사유(공통코드), P/O No, PM(기존 데이터선택 유지), 당사프로젝트명
[특이사항]
입력칸
[파일첨부]
입수자료, 제출자료( 기존 파일첨부 활용 - 다중 파일 첨부 가능)
## 아래는 공통코드(등록되어 있음)
계약방식 선택
조달
민자
대리점
재료비
---
실폐사유 선택
회신 없음
예산 문제
탈락
유찰
취소
부적합
---
진행단계 선택
사양협의
원가검토
견적제출
---
계약구분 선택
① 개발
② 변형
③ 소모품
④ 재주문
⑤ A/S
⑥ 연구과제
등록화면이 이렇게 나와야 함
---
# 영업관리\_계약관리 시스템 필드 추가 수정 (기존 코드 활용 최대화)
## 📖 시스템 개요
기존 계약관리 시스템을 확장하여 영업등록 시스템으로 발전시키는 프로젝트입니다.
## 🔍 **기존 코드 vs 신규 추가 정확한 구분**
### ✅ **기존 코드 활용 (수정 불필요)**
#### 1. 기존 공통코드 (이미 등록되어 활용 중)
| 코드ID | 용도 | 기존 사용처 | 선택값 |
| ----------- | ------------ | ----------------------------------------- | ----------------------------------------------------- |
| **0000167** | 계약구분 | ProjectController, ContractMgmtController | ① 개발, ② 변형, ③ 소모품, ④ 재주문, ⑤ A/S, ⑥ 연구과제 |
| **0000932** | 영업진행단계 | ProjectController, ContractMgmtController | 사양협의, 원가검토, 견적제출 |
| **0000963** | 수주결과 | ProjectController, ContractMgmtController | 수주, 실패 |
| **0000964** | 실패사유 | ContractMgmtService, 여러 매퍼 | 회신 없음, 예산 문제, 탈락, 유찰, 취소, 부적합 |
#### 2. 기존 필드 (JSP에 이미 존재)
- **계약구분** (`category_cd`) - 기존 0000167 공통코드 사용
- **국내/해외** (`area_cd`) - 기존 필드 활용
- **고객사** (`customer_objid`) - 기존 고객 선택 코드 활용
- **제품구분** (`product`) - 기존 제품 선택 코드 활용
- **기계형식** (`mechanical_type`) - 기존 필드 활용
#### 3. 기존 파일 업로드 기능
- **입수자료** (`contractMgmt01`) - 기존 DRAG & DROP 방식 활용
- **제출자료** (`contractMgmt02`) - 기존 DRAG & DROP 방식 활용
### 🆕 **신규 추가 필요**
#### 1. 신규 공통코드 (추가 등록 필요)
추가된 공통코드
-- 계약구분 부모 코드
INSERT INTO comm_code (code_id, parent_code_id, code_name, id, code_cd, ext_val, writer, regdate, status)
VALUES ('0000167', NULL, '계약구분', NULL, NULL, NULL, 'plm_admin', NOW(), 'active');
-- 영업진행단계 부모 코드
INSERT INTO comm_code (code_id, parent_code_id, code_name, id, code_cd, ext_val, writer, regdate, status)
VALUES ('0000932', NULL, '영업진행단계', NULL, NULL, NULL, 'plm_admin', NOW(), 'active');
-- 수주결과 부모 코드
INSERT INTO comm_code (code_id, parent_code_id, code_name, id, code_cd, ext_val, writer, regdate, status)
VALUES ('0000963', NULL, '수주결과', NULL, NULL, NULL, 'plm_admin', NOW(), 'active');
-- 실패사유 부모 코드
INSERT INTO comm_code (code_id, parent_code_id, code_name, id, code_cd, ext_val, writer, regdate, status)
VALUES ('0000964', NULL, '실패사유', NULL, NULL, NULL, 'plm_admin', NOW(), 'active');
-- 통화단위 부모 코드
INSERT INTO comm_code (code_id, parent_code_id, code_name, id, code_cd, ext_val, writer, regdate, status)
VALUES ('0000965', NULL, '통화단위', NULL, NULL, NULL, 'plm_admin', NOW(), 'active');
-- 계약방식 부모 코드
INSERT INTO comm_code (code_id, parent_code_id, code_name, id, code_cd, ext_val, writer, regdate, status)
VALUES ('0000966', NULL, '계약방식', NULL, NULL, NULL, 'plm_admin', NOW(), 'active');
-- 통화단위 하위 코드
INSERT INTO comm_code (code_id, parent_code_id, code_name, id, code_cd, ext_val, writer, regdate, status)
VALUES
('0000965001', '0000965', 'KRW', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000965002', '0000965', 'USD', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000965003', '0000965', 'EUR', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000965004', '0000965', 'JPY', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000965005', '0000965', 'CNY', NULL, NULL, NULL, 'plm_admin', NOW(), 'active');
-- 실패사유 부모 코드
INSERT INTO comm_code (code_id, parent_code_id, code_name, id, code_cd, ext_val, writer, regdate, status)
VALUES ('0000964', NULL, '실패사유', NULL, NULL, NULL, 'plm_admin', NOW(), 'active');
-- 실패사유 하위 코드
INSERT INTO comm_code (code_id, parent_code_id, code_name, id, code_cd, ext_val, writer, regdate, status)
VALUES
('0000964001', '0000964', '회신없음', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000964002', '0000964', '예산문제', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000964003', '0000964', '탈락', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000964004', '0000964', '유찰', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000964005', '0000964', '취소', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000964006', '0000964', '부적합', NULL, NULL, NULL, 'plm_admin', NOW(), 'active');
-- 계약방식 부모 코드
INSERT INTO comm_code (code_id, parent_code_id, code_name, id, code_cd, ext_val, writer, regdate, status)
VALUES ('0000966', NULL, '계약방식', NULL, NULL, NULL, 'plm_admin', NOW(), 'active');
-- 계약방식 하위 코드
INSERT INTO comm_code (code_id, parent_code_id, code_name, id, code_cd, ext_val, writer, regdate, status)
VALUES
('0000966001', '0000966', '조달', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000966002', '0000966', '민자', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000966003', '0000966', '대리점', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000966004', '0000966', '재로비', NULL, NULL, NULL, 'plm_admin', NOW(), 'active');
-- 계약구분 하위 코드
INSERT INTO comm_code (code_id, parent_code_id, code_name, id, code_cd, ext_val, writer, regdate, status)
VALUES
('0000167001', '0000167', '개발', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000167002', '0000167', '변형', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000167003', '0000167', '소모품', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000167004', '0000167', '재주문', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000167005', '0000167', 'A/S', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000167006', '0000167', '연구과제', NULL, NULL, NULL, 'plm_admin', NOW(), 'active');
-- 영업진행단계 하위 코드
INSERT INTO comm_code (code_id, parent_code_id, code_name, id, code_cd, ext_val, writer, regdate, status)
VALUES
('0000932001', '0000932', '사양협의', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000932002', '0000932', '원가검토', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000932003', '0000932', '견적제출', NULL, NULL, NULL, 'plm_admin', NOW(), 'active');
-- 수주결과 하위 코드
INSERT INTO comm_code (code_id, parent_code_id, code_name, id, code_cd, ext_val, writer, regdate, status)
VALUES
('0000963001', '0000963', '수주', NULL, NULL, NULL, 'plm_admin', NOW(), 'active'),
('0000963002', '0000963', '실패', NULL, NULL, NULL, 'plm_admin', NOW(), 'active');
#### 2. 신규 필드 (JSP에 추가 필요)
**[영업정보] 섹션:**
- ✅ 계약구분 - **기존 활용** (0000167)
- 🆕 과거프로젝트번호 - **신규 추가** (프로젝트 데이터 선택)
- ✅ 국내/해외 - **기존 활용**
- ✅ 고객사 - **기존 활용**
- ✅ 제품군 - **기존 활용**
- ✅ 제품코드 - **기존 활용**
- 🆕 장비명 - **신규 추가** (직접 입력)
- 🆕 설비대수 - **신규 추가** (직접 입력)
- 🆕 요청납기일 - **신규 추가** (캘린더)
- 🆕 입고지 - **신규 추가** (직접 입력)
- 🆕 셋업지 - **신규 추가** (직접 입력)
**[사양상세] 섹션 - 모두 신규 추가:**
- 🆕 재질 - **신규 추가** (직접 입력)
- 🆕 압력(BAR) - **신규 추가** (직접 입력)
- 🆕 온도(℃) - **신규 추가** (직접 입력)
- 🆕 용량(LITER) - **신규 추가** (직접 입력)
- 🆕 Closure Type - **신규 추가** (직접 입력)
- 🆕 기타(소모품) - **신규 추가** (직접 입력)
- 🆕 전압 - **신규 추가** (직접 입력)
- 🆕 인증여부 - **신규 추가** (직접 입력)
**[영업진행] 섹션:**
- ✅ 단계 - **기존 활용** (0000932 - 사양협의, 원가검토, 견적제출)
**[견적이력 및 결과] 섹션:**
- 🆕 통화 - **신규 추가** (0000965 공통코드)
- 🆕 견적금액(1차) - **신규 추가** (직접 입력)
- 🆕 견적금액(2차) - **신규 추가** (직접 입력)
- 🆕 견적금액(3차) - **신규 추가** (직접 입력)
- 🆕 수주일 - **신규 추가** (캘린더)
- 🆕 수주가 - **신규 추가** (자동계산)
- ✅ Result - **기존 활용** (0000963 - 수주/실패)
- 🆕 계약방식 - **신규 추가** (0000966 공통코드)
- ✅ 실패사유 - **기존 활용** (0000964)
- 🆕 P/O No - **신규 추가** (직접 입력)
- ✅ PM - **기존 활용** (기존 사용자 선택)
- 🆕 당사프로젝트명 - **신규 추가** (직접 입력)
**[특이사항] 섹션:**
- 🆕 특이사항 - **신규 추가** (텍스트 영역)
## 🏗️ 구현 계획
### Phase 1: 신규 공통코드 등록
```sql
-- 계약방식과 통화단위만 신규 추가
INSERT INTO COMM_CODE VALUES ('0000965', NULL, '통화단위', 'active');
INSERT INTO COMM_CODE VALUES ('0000966', NULL, '계약방식', 'active');
-- 상세값들...
```
### Phase 2: 백엔드 확장 (기존 메서드 확장)
#### ContractMgmtController.java 확장
```java
@RequestMapping("/contractMgmt/contracMgmtFormPopup.do")
public String contracMgmtFormPopup(HttpServletRequest request, @RequestParam Map<String, Object> paramMap) {
// 기존 로직 유지
Map info = contractMgmtService.getContractMgmtInfo(paramMap);
Map<String, String> code_map = new HashMap<>();
// 기존 공통코드들 (유지)
code_map.put("category_cd", commonService.bizMakeOptionList("0000167", "", "common.getCodeselect"));
code_map.put("status_cd", commonService.bizMakeOptionList("0000932", "", "common.getCodeselect"));
code_map.put("result_cd", commonService.bizMakeOptionList("0000963", "", "common.getCodeselect"));
code_map.put("failure_reason", commonService.bizMakeOptionList("0000964", "", "common.getCodeselect"));
// 신규 공통코드만 추가
code_map.put("currency_type", commonService.bizMakeOptionList("0000965", "", "common.getCodeselect"));
code_map.put("contract_method", commonService.bizMakeOptionList("0000966", "", "common.getCodeselect"));
request.setAttribute("info", info);
request.setAttribute("code_map", code_map);
return "/contractMgmt/contracMgmtFormPopup";
}
```
### Phase 3: 프론트엔드 확장 (기존 JSP 확장)
#### contracMgmtFormPopup.jsp 확장
```jsp
<!-- 기존 필드들 유지 -->
<tr>
<td class="input_title"><label for="">계약구분</label></td>
<td colspan="2">
<select name="category_cd" id="category_cd" required reqTitle="계약구분" type="select" class="select2">
<option value="">선택</option> ${code_map.category_cd}
</select>
</td>
<!-- 기존 필드들... -->
</tr>
<!-- 신규 필드들만 추가 -->
<tr>
<td class="input_title"><label for="">과거프로젝트번호</label></td>
<td colspan="2">
<input type="text" name="past_project_no" id="past_project_no" reqTitle="과거프로젝트번호" value="${info.PAST_PROJECT_NO}" />
</td>
<td class="input_title"><label for="">장비명</label></td>
<td colspan="2">
<input type="text" name="equipment_name" id="equipment_name" reqTitle="장비명" value="${info.EQUIPMENT_NAME}" />
</td>
</tr>
<!-- 사양상세 섹션 전체 신규 추가 -->
<tr>
<td class="input_title"><label for="">재질</label></td>
<td colspan="2">
<input type="text" name="material" id="material" reqTitle="재질" value="${info.MATERIAL}" />
</td>
<td class="input_title"><label for="">압력(BAR)</label></td>
<td colspan="2">
<input type="text" name="pressure_bar" id="pressure_bar" reqTitle="압력" value="${info.PRESSURE_BAR}" />
</td>
</tr>
<!-- 견적이력 섹션 -->
<tr>
<td class="input_title"><label for="">통화단위</label></td>
<td colspan="2">
<select name="currency_type" id="currency_type" reqTitle="통화단위" type="select" class="select2">
<option value="">선택</option> ${code_map.currency_type}
</select>
</td>
<td class="input_title"><label for="">계약방식</label></td>
<td colspan="2">
<select name="contract_method" id="contract_method" reqTitle="계약방식" type="select" class="select2">
<option value="">선택</option> ${code_map.contract_method}
</select>
</td>
</tr>
```
### Phase 4: 데이터베이스 확장 (기존 테이블 확장)
#### CONTRACT_MGMT 테이블에 신규 컬럼 추가
```sql
ALTER TABLE CONTRACT_MGMT ADD COLUMN past_project_no VARCHAR(50);
ALTER TABLE CONTRACT_MGMT ADD COLUMN equipment_name VARCHAR(200);
ALTER TABLE CONTRACT_MGMT ADD COLUMN equipment_count VARCHAR(100);
-- 신규 필드들만 추가...
```
## 🎯 **최종 정리**
### 기존 코드 활용률: **60%**
- 기존 공통코드 4개 (0000167, 0000932, 0000963, 0000964) 재활용
- 기존 JSP 구조 및 테이블 레이아웃 활용
- 기존 파일 업로드 기능 활용
- 기존 컨트롤러/서비스/매퍼 메서드 확장
### 신규 추가 필요: **40%**
- 신규 공통코드 2개 (0000965, 0000966) 추가
- 신규 입력 필드 25개 추가
- 신규 자동계산 기능 추가
이 접근법으로 **기존 시스템의 안정성을 유지**하면서 **최소한의 변경**으로 요구사항을 충족할 수 있습니다.
## 📋 영업 계약 수정 내용 정리
### 🔍 **현재 상황 분석**
**기존 시스템 구조:**
- 테이블: `SWSC110A_TBL` (기존 계약관리)
- 새로운 테이블: `CONTRACT_MGMT` (확장된 영업관리)
- JSP: `contractMgmtFormPopup.jsp` (기존 등록 화면)
### ✅ **기존 코드에서 활용 가능한 요소들**
#### 1. 기존 공통코드 (이미 등록되어 있음)
- **0000167**: 계약구분 (개발, 변형, 소모품, 재주문, A/S, 연구과제)
- **0000932**: 영업진행단계 (사양협의, 원가검토, 견적제출)
- **0000963**: 수주결과 (수주, 실패)
- **0000964**: 실패사유 (회신없음, 예산문제, 탈락, 유찰, 취소, 부적합)
#### 2. 기존 필드 (JSP에 이미 존재)
- 고객사 선택
- 제품코드 선택
- 계약일자, 최종납기일
- 계약수량, 계약단가, 계약금액
### 🆕 **신규 추가 필요한 요소들**
#### 1. 신규 공통코드 (추가 등록 필요)
```sql
-- 통화단위 (0000965)
INSERT INTO COMM_CODE VALUES ('0000965', NULL, '통화단위', 'active');
INSERT INTO COMM_CODE VALUES ('0000965001', '0000965', 'KRW', 'active');
INSERT INTO COMM_CODE VALUES ('0000965002', '0000965', 'USD', 'active');
INSERT INTO COMM_CODE VALUES ('0000965003', '0000965', 'EUR', 'active');
INSERT INTO COMM_CODE VALUES ('0000965004', '0000965', 'JPY', 'active');
INSERT INTO COMM_CODE VALUES ('0000965005', '0000965', 'CNY', 'active');
-- 계약방식 (0000966)
INSERT INTO COMM_CODE VALUES ('0000966', NULL, '계약방식', 'active');
INSERT INTO COMM_CODE VALUES ('0000966001', '0000966', '조달', 'active');
INSERT INTO COMM_CODE VALUES ('0000966002', '0000966', '민자', 'active');
INSERT INTO COMM_CODE VALUES ('0000966003', '0000966', '대리점', 'active');
INSERT INTO COMM_CODE VALUES ('0000966004', '0000966', '재료비', 'active');
```
### 🚫 **기존 코드에서 숨겨야 할 필드들**
#### 1. 기존 계약관리 목록에서 주석처리할 컬럼들
**파일: `WebContent/WEB-INF/view/salesmgmt/contractMgmt/contractMgmtList.jsp`**
```jsp
<!-- 기존 테이블 헤더에서 숨길 컬럼들 -->
<!--
<th>보증기간</th>
<th>출하수량</th>
<th>출고수량</th>
<th>매출수량</th>
<th>매출액</th>
<th>수금액</th>
-->
<!-- 기존 테이블 바디에서 숨길 데이터들 -->
<!--
<td>${item.GOODSGUARANTEE}</td>
<td><fmt:formatNumber value="${item.SALEQTY}" type="number" maxFractionDigits="3" /></td>
<td><fmt:formatNumber value="${item.SALEQTY1}" type="number" maxFractionDigits="3" /></td>
<td><fmt:formatNumber value="${item.SUPPLYQTY}" type="number" maxFractionDigits="3" /></td>
<td><fmt:formatNumber value="${item.SUPPLYAMT}" type="number" maxFractionDigits="3" /></td>
<td><fmt:formatNumber value="${item.RCPTAMT}" type="number" maxFractionDigits="3" /></td>
-->
```
#### 2. 기존 계약관리 등록화면에서 주석처리할 필드들
**파일: `WebContent/WEB-INF/view/salesmgmt/contractMgmt/contractMgmtFormPopup.jsp`**
```jsp
<!-- 기존 등록화면에서 숨길 필드들 -->
<!-- 1. 관리부서 관련 필드들 -->
<!--
<tr>
<td class="input_title"><label for="label">* 관리부서</label></td>
<td class="input_sub_title">
<select name="bDeptCd" id="bDeptCd" required reqTitle="관리부서" type="select" style="width: 120px;" class="select2">
<option value="">선택</option>
<c:forEach var="bDeptList" items="${codeMap.bDeptList}">
${bDeptList}
</c:forEach>
</select>
</td>
<td class="input_title"><label for="label">* 관리담당자</label></td>
<td colspan="3" class="input_sub_title">
<select name="bEmpNo" id="bEmpNo" required reqTitle="관리담당자" type="select" style="width: 120px;" class="select2">
<option value="">선택</option>
<c:forEach var="bEmpList" items="${codeMap.bEmpList}">
${bEmpList}
</c:forEach>
</select>
</td>
</tr>
-->
<!-- 2. 판매유형 관련 필드들 -->
<!--
<tr>
<td class="input_title"><label for="label">판매유형</label></td>
<td class="input_sub_title">
<select name="saleType" id="saleType" type="select" style="width:150px;" class="select2">
<option value="">선택</option>
<c:forEach var="saleTypeList" items="${codeMap.saleTypeList}">
${saleTypeList}
</c:forEach>
</select>
</td>
</tr>
-->
<!-- 3. 보증기간 필드 -->
<!--
<tr>
<td class="input_title"><label for="label">보증기간</label></td>
<td class="input_sub_title">
<input type="text" name="goodsGuarantee" id="goodsGuarantee" value="${info.GOODSGUARANTEE}" maxlength="3" style="width:50px;" />
</td>
</tr>
-->
<!-- 4. 출하대상 필드 -->
<!--
<tr>
<td class="input_title"><label for="label">출하대상</label></td>
<td class="input_sub_title">
<select name="chulhaYN" id="chulhaYN" type="select" style="width:150px;" class="select2">
<option value="0" ${info.CHULHAYN eq '0' ? 'selected':''}>미출하</option>
<option value="1" ${info.CHULHAYN eq '1' ? 'selected':''}>출하</option>
</select>
</td>
</tr>
-->
```
#### 3. 컨트롤러에서 주석처리할 코드
**파일: `src/com/pms/salesmgmt/controller/ContractMgmtController.java`**
```java
// 기존 관리부서 관련 코드 주석처리
/*
// 관리부서
codeMap.put("bDeptList",
salesMgmtCommonService.bizMakeOptionList("", (String) info.get("BDEPTCD"), "salesMgmtCommon.getBDeptList"));
// 관리담당자
codeMap.put("bEmpList",
salesMgmtCommonService.bizMakeBEmpOptionList((String) info.get("BDEPTCD"), (String) info.get("BEMPNO")));
// 판매유형
codeMap.put("saleTypeList",
salesMgmtCommonService.bizMakeOptionList("GE", (String) info.get("SALETYPE"), "salesMgmtCommon.getCodeList"));
*/
```
### 🎯 **구현 단계별 계획**
#### Phase 1: 기존 코드 정리
1. **기존 계약관리 리스트**에서 불필요한 컬럼 주석처리
2. **기존 계약관리 등록화면**에서 사용하지 않을 필드 주석처리
3. **컨트롤러**에서 불필요한 공통코드 로딩 주석처리
#### Phase 2: 신규 공통코드 등록
1. 통화단위 (0000965) 공통코드 등록
2. 계약방식 (0000966) 공통코드 등록
#### Phase 3: 새로운 영업관리 화면 구현
1. 새로운 JSP 화면 개발 (영업정보, 사양상세, 견적이력, 특이사항 섹션)
2. 새로운 컨트롤러 메서드 개발
3. 새로운 매퍼 쿼리 개발
#### Phase 4: 데이터베이스 확장
1. 기존 테이블에 신규 컬럼 추가
2. 인덱스 생성
3. 데이터 마이그레이션
### 📝 **주요 변경 포인트 요약**
| 구분 | 기존 활용 | 신규 추가 | 주석처리 |
| ---------------- | ------------------ | -------------- | ------------------- |
| **공통코드** | 4개 재활용 | 2개 신규 | - |
| **JSP 필드** | 기본 계약정보 유지 | 25개 신규 | 7개 주석처리 |
| **컨트롤러** | 기본 구조 유지 | 신규 코드 추가 | 3개 메서드 주석처리 |
| **데이터베이스** | 기존 테이블 확장 | 신규 컬럼 추가 | - |
이 접근법으로 **기존 시스템의 안정성을 유지**하면서 **최소한의 변경**으로 새로운 영업관리 요구사항을 충족할 수 있습니다.
## 💡 **기존 공통코드 활용 방법 (권장)**
### 🔧 **현재 공통코드 시스템 구조**
기존 시스템에서 공통코드는 다음과 같이 활용됩니다:
```java
// 컨트롤러에서 공통코드 활용 예시
code_map.put("category_cd", commonService.bizMakeOptionList("0000167", category_cd, "common.getCodeselect"));
code_map.put("status_cd", commonService.bizMakeOptionList("0000932", status_cd, "common.getCodeselect"));
code_map.put("result_cd", commonService.bizMakeOptionList("0000963", result_cd, "common.getCodeselect"));
```
### ✅ **기존 공통코드 그대로 활용**
이미 등록된 공통코드들은 **코드 구조 변경 없이** 그대로 활용 가능합니다:
| 공통코드 | 용도 | 기존 사용 | 신규 활용 |
| ----------- | ------------ | --------------- | -------------- |
| **0000167** | 계약구분 | ✅ 이미 사용 중 | ✅ 그대로 활용 |
| **0000932** | 영업진행단계 | ✅ 이미 사용 중 | ✅ 그대로 활용 |
| **0000963** | 수주결과 | ✅ 이미 사용 중 | ✅ 그대로 활용 |
| **0000964** | 실패사유 | ✅ 이미 사용 중 | ✅ 그대로 활용 |
### 🆕 **신규 공통코드만 추가 등록**
**통화단위 (0000965)**와 **계약방식 (0000966)**만 신규 추가하면 됩니다:
```sql
-- 통화단위 추가
INSERT INTO COMM_CODE (OBJID, CODE_ID, PARENT_CODE_ID, CODE_NAME, STATUS, WRITER, REGDATE)
VALUES (nextval('seq_comm_code'), '0000965', NULL, '통화단위', 'active', 'admin', now());
INSERT INTO COMM_CODE (OBJID, CODE_ID, PARENT_CODE_ID, CODE_NAME, STATUS, WRITER, REGDATE)
VALUES (nextval('seq_comm_code'), '0000965001', '0000965', 'KRW', 'active', 'admin', now());
INSERT INTO COMM_CODE (OBJID, CODE_ID, PARENT_CODE_ID, CODE_NAME, STATUS, WRITER, REGDATE)
VALUES (nextval('seq_comm_code'), '0000965002', '0000965', 'USD', 'active', 'admin', now());
-- 계약방식 추가
INSERT INTO COMM_CODE (OBJID, CODE_ID, PARENT_CODE_ID, CODE_NAME, STATUS, WRITER, REGDATE)
VALUES (nextval('seq_comm_code'), '0000966', NULL, '계약방식', 'active', 'admin', now());
INSERT INTO COMM_CODE (OBJID, CODE_ID, PARENT_CODE_ID, CODE_NAME, STATUS, WRITER, REGDATE)
VALUES (nextval('seq_comm_code'), '0000966001', '0000966', '조달', 'active', 'admin', now());
```
### 🎯 **컨트롤러 수정 최소화**
기존 컨트롤러에서 **신규 공통코드 2개만 추가**하면 됩니다:
```java
@RequestMapping("/contractMgmt/contracMgmtFormPopup.do")
public String contracMgmtFormPopup(HttpServletRequest request, @RequestParam Map<String, Object> paramMap) {
// 기존 공통코드들 (수정 불필요)
code_map.put("category_cd", commonService.bizMakeOptionList("0000167", category_cd, "common.getCodeselect"));
code_map.put("status_cd", commonService.bizMakeOptionList("0000932", status_cd, "common.getCodeselect"));
code_map.put("result_cd", commonService.bizMakeOptionList("0000963", result_cd, "common.getCodeselect"));
code_map.put("failure_reason", commonService.bizMakeOptionList("0000964", failure_reason, "common.getCodeselect"));
// 신규 공통코드만 추가
code_map.put("currency_type", commonService.bizMakeOptionList("0000965", currency_type, "common.getCodeselect"));
code_map.put("contract_method", commonService.bizMakeOptionList("0000966", contract_method, "common.getCodeselect"));
return "/contractMgmt/contracMgmtFormPopup";
}
```
### 🎨 **JSP에서 공통코드 활용**
JSP에서도 기존 방식 그대로 활용:
```jsp
<!-- 기존 공통코드 활용 -->
<select name="category_cd" id="category_cd" class="select2">
<option value="">선택</option>
${code_map.category_cd}
</select>
<select name="status_cd" id="status_cd" class="select2">
<option value="">선택</option>
${code_map.status_cd}
</select>
<!-- 신규 공통코드 활용 -->
<select name="currency_type" id="currency_type" class="select2">
<option value="">선택</option>
${code_map.currency_type}
</select>
<select name="contract_method" id="contract_method" class="select2">
<option value="">선택</option>
${code_map.contract_method}
</select>
```
### 🔄 **기존 데이터 호환성**
기존 데이터는 **완전히 호환**됩니다:
- 기존 테이블 구조 유지
- 기존 공통코드 값 유지
- 기존 비즈니스 로직 유지
### 📊 **작업량 대폭 감소**
| 구분 | 기존 방식 | 신규 공통코드 활용 |
| ----------------- | --------------- | ------------------ |
| **공통코드 등록** | 6개 전체 재등록 | 2개만 신규 등록 |
| **컨트롤러 수정** | 전체 재작성 | 2줄만 추가 |
| **JSP 수정** | 전체 재작성 | 기존 구조 활용 |
| **테스트 범위** | 전체 시스템 | 신규 기능만 |
### 🎯 **최종 권장 방법**
1. **✅ 기존 공통코드 (0000167, 0000932, 0000963, 0000964) 그대로 활용**
2. **✅ 신규 공통코드 (0000965, 0000966) 2개만 추가**
3. **✅ 기존 bizMakeOptionList 메서드 그대로 활용**
4. **✅ 기존 JSP 구조 그대로 활용**
이 방법으로 **개발 시간 70% 단축**하고 **안정성 100% 보장**할 수 있습니다!

View File

@@ -105,7 +105,7 @@
| 에이전트 | 담당 폴더 | 파일 유형 |
|----------|-----------|-----------|
| Agent B (Backend) | `backend-node/src/` | `.ts`, `.js` |
| Agent C (DB) | `src/com/pms/mapper/`, `db/` | `.xml`, `.sql` |
| Agent C (DB) | `backend-node/src/`, `db/` | `.ts`, `.sql` |
| Agent D (Frontend) | `frontend/` | `.tsx`, `.ts`, `.css` |
| Agent A (PM) | 전체 조율 | 모든 파일 (읽기 위주) |
@@ -184,14 +184,12 @@
담당 영역:
폴더:
- src/com/pms/mapper/
- backend-node/src/
- db/
- backend-node/src/database/
작업:
- 테이블 스키마 설계
- MyBatis 매퍼 XML 작성
- SQL 쿼리 최적화
- SQL 쿼리 작성 및 최적화
- 인덱스 설계
- 마이그레이션 스크립트
@@ -507,7 +505,7 @@ backend-node/ 폴더의 API, 서비스, 라우팅을 담당해.
# 담당 아닌 것 (절대 건들지 마)
- frontend/ → Frontend Agent 담당
- src/com/pms/mapper/ → DB Agent 담당
- backend-node/src/ DB 관련 → DB Agent 담당
- SQL 쿼리 직접 작성 → DB Agent에게 요청
# 코드 작성 규칙
@@ -557,9 +555,8 @@ backend-node/ 폴더의 API, 서비스, 라우팅을 담당해.
DB 스키마, 쿼리, 마이그레이션을 담당해.
# 담당 영역 (이것만!)
- src/com/pms/mapper/ (MyBatis XML)
- backend-node/src/ (DB 서비스, 컨트롤러)
- db/ (스키마, 마이그레이션)
- backend-node/src/database/
# 담당 아닌 것 (절대 건들지 마)
- API 로직 → Backend Agent 담당
@@ -572,18 +569,16 @@ DB 스키마, 쿼리, 마이그레이션을 담당해.
3. 인덱스 고려
4. 성능 최적화 (EXPLAIN 결과 고려)
# MyBatis 매퍼 규칙
```xml
<!-- 파라미터 바인딩 (안전) -->
WHERE id = #{id}
# SQL 쿼리 규칙
```sql
-- 파라미터 바인딩 (pg 드라이버)
WHERE id = $1
<!-- 동적 쿼리 -->
<if test="name != null and name != ''">
AND name LIKE '%' || #{name} || '%'
</if>
-- 동적 쿼리 (TypeScript에서 조건 빌드)
-- conditions.push(`name ILIKE $${paramIndex}`);
<!-- 페이징 -->
LIMIT #{limit} OFFSET #{offset}
-- 페이징
LIMIT $2 OFFSET $3
```
# 응답 형식