Files
sdl_base/board_spec.md
T
koreafood 12c40c6004 feat(board-generator): add board code generator and sample CRUD artifacts
Add Node.js CLI tool with Handlebars templates for generating standard CRUD artifacts: Java entity, service, DAO, controller, MyBatis mapper XML, and Vue frontend pages.
Also generate the full SampleTableBoard CRUD reference implementation, update README with backend execution instructions, and add project plan documentation.
2026-05-31 13:22:03 +09:00

606 lines
14 KiB
Markdown

# Board Generator Specification
## 1. 문서 목적
이 문서는 `board_plan.md`를 기반으로 `Node.js CLI` 기반 보드 소스 생성기의 구현 명세를 정의한다.
이 문서의 목적은 아래와 같다.
- CLI 입력값을 확정한다.
- 생성 파일 범위와 출력 경로를 확정한다.
- DB 메타데이터 조회 항목을 확정한다.
- 템플릿 렌더링 규칙을 확정한다.
- 재생성 정책과 비범위를 명확히 한다.
이 문서는 구현자가 바로 MVP 개발을 시작할 수 있는 수준의 기준 문서로 사용한다.
## 2. 생성기 개요
생성기 이름은 임시로 `generate-board` 로 정의한다.
생성기는 PostgreSQL 테이블 메타데이터를 조회한 뒤, 현재 프로젝트의 실행 가능한 샘플 템플릿 규칙에 맞춰 아래 파일을 생성한다.
- Java Entity
- Java Service Interface
- Java Service Impl
- Java Dao
- Java Controller
- MyBatis Mapper XML
- Vue CRUD Page
생성 결과는 완성본이 아니라 공통 초기 코드를 빠르게 확보하기 위한 초안 산출물이다.
## 3. 구현 대상 범위
### 3.1 포함 범위
- PostgreSQL 단일 테이블 기준 생성
- 단일 PK 기준 생성
- Java 백엔드 CRUD 코드 생성
- MyBatis XML 생성
- Vue CRUD 초기 페이지 생성
- 컬럼 추가 후 재생성 지원
### 3.2 제외 범위
- 복합 PK
- 조인 조회
- 첨부파일 기능
- 메뉴 자동 등록
- 라우터 자동 등록
- 권한 정책 자동 삽입
- 기존 수정본 자동 병합
- 다국어 리소스 자동 생성
## 4. CLI 명령 규격
### 4.1 기본 명령
```bash
generate-board --table <table_name>
```
### 4.2 권장 명령
```bash
generate-board \
--table sample_board \
--module sample/board \
--entity SampleBoard \
--menu-name "Sample Board" \
--output generated
```
### 4.3 옵션 정의
- `--table`
- 필수
- DB 테이블명
- 예: `samples`, `sample_board`
- `--module`
- 선택
- Java 패키지 및 디렉터리 기준 모듈 경로
- 예: `sample/board`
- `--entity`
- 선택
- 생성할 Entity 클래스명
- 예: `SampleBoard`
- `--menu-name`
- 선택
- Vue 화면 제목과 설명 기본값
- 예: `Sample Board`
- `--output`
- 선택
- 생성 파일 묶음을 저장할 루트 경로 또는 그룹명
- 예: `.`, `generated`, `generated/v1`
- `--force`
- 선택
- 기존 생성 대상이 존재할 때 덮어쓰기 허용
- 기본값은 `false`
- `--preview`
- 선택
- 실제 파일 생성 없이 생성 대상 목록과 계산된 이름만 출력
- `--scope`
- 선택
- 생성 범위 제한
- 허용값: `all`, `backend`, `xml`, `frontend`
## 5. 입력값 보정 규칙
입력값 일부가 생략되면 생성기가 기본값을 계산한다.
### 5.1 테이블명 기반 기본값 계산
- `sample_board` -> Entity 기본값 `SampleBoard`
- `sample_board` -> module 기본값 `sample/board`
- `samples` -> Entity 추천값 `Sample`
- `samples` -> module 추천값 `samples`
### 5.2 추천 후 확정 정책
테이블명만으로 Entity 명과 module 명을 완벽히 결정할 수 없으므로 아래 정책을 적용한다.
- 기본값을 자동 계산한다.
- preview 출력 시 계산 결과를 보여준다.
- 사용자는 필요 시 `--module`, `--entity` 로 명시한다.
MVP에서는 대화형 입력 없이 명령 인자 우선으로 처리한다.
## 6. 출력 경로 규칙
### 6.1 기본 출력 루트
기본 출력은 프로젝트 루트 기준 실제 소스 위치에 바로 생성하는 것을 기본 정책으로 한다.
예시:
- `src/main/java/com/samsung/sample/board/entity/SampleBoard.java`
- `src/main/java/com/samsung/sample/board/SampleBoardService.java`
- `src/main/java/com/samsung/sample/board/dao/SampleBoardDao.java`
- `src/main/java/com/samsung/sample/board/impl/SampleBoardServiceImpl.java`
- `src/main/java/com/samsung/sample/board/controller/SampleBoardController.java`
- `src/main/resources/sql/mybatis/postgresql/mapper-mybatis-sample-board.xml`
- `frontend/src/components/view/admin/pgBoard/SampleBoardPage.vue`
### 6.2 출력 경로 정책
- 기본값은 실제 소스 경로에 직접 생성한다.
- 기존 파일이 이미 있으면 `--force` 없이는 덮어쓰지 않는다.
- 필요 시 `--output generated` 같은 별도 경로를 지정해 우회 생성할 수 있다.
### 6.3 `--output` 사용 예
- `--output generated`
- `--output generated/v2`
- `--output output/sample-board`
## 7. 샘플 템플릿 기준 파일
생성기는 아래 파일들을 기준 템플릿의 원형으로 사용한다.
- `src/main/java/com/samsung/sample/board/entity/SampleBoard.java`
- `src/main/java/com/samsung/sample/board/SampleBoardService.java`
- `src/main/java/com/samsung/sample/board/impl/SampleBoardServiceImpl.java`
- `src/main/java/com/samsung/sample/board/dao/SampleBoardDao.java`
- `src/main/java/com/samsung/sample/board/controller/SampleBoardController.java`
- `src/main/resources/sql/mybatis/postgresql/mapper-mybatis-sample-board.xml`
- `frontend/src/components/view/admin/pgBoard/SampleBoardPage.vue`
이 파일들은 단순 예제가 아니라 실제로 동작 가능한 샘플 템플릿이어야 한다.
## 8. 템플릿 엔진 규격
MVP 템플릿 엔진은 `Handlebars` 를 우선 권장한다.
선정 이유는 아래와 같다.
- 반복 렌더링이 쉽다.
- 조건부 블록 표현이 쉽다.
- Java 필드, XML resultMap, Vue 입력 항목 반복 생성에 적합하다.
대체안으로 `Mustache` 도 가능하지만, 조건 분기가 필요한 Vue 템플릿 생성에는 `Handlebars` 가 조금 더 유리하다.
## 9. 템플릿 변수 규격
모든 템플릿은 아래 공통 변수를 사용할 수 있어야 한다.
### 9.1 전역 변수
- `tableName`
- `modulePath`
- `entityName`
- `entityVarName`
- `serviceName`
- `serviceImplName`
- `daoName`
- `controllerName`
- `mapperNamespace`
- `menuName`
- `requestBasePath`
- `vueComponentName`
- `mapperFileName`
### 9.2 컬럼 변수
각 컬럼은 아래 속성을 가진다.
- `columnName`
- `propertyName`
- `dbType`
- `javaType`
- `nullable`
- `primaryKey`
- `autoIncrement`
- `ordinalPosition`
- `isAuditColumn`
- `isSearchCandidate`
- `isListCandidate`
- `isFormCandidate`
### 9.3 파생 변수
- `primaryKeyColumn`
- `primaryKeyProperty`
- `primaryKeyJavaType`
- `normalColumns`
- `insertColumns`
- `updateColumns`
- `listColumns`
- `formColumns`
## 10. DB 메타데이터 조회 명세
생성기는 아래 정보를 반드시 조회해야 한다.
- 테이블 존재 여부
- 컬럼 목록
- 컬럼 타입
- PK 컬럼
- nullable 여부
- identity 또는 sequence 기반 자동 증가 여부
- 컬럼 순서
### 10.1 메타데이터 조회 순서
1. 테이블 존재 확인
2. 컬럼 목록 조회
3. PK 조회
4. 자동 증가 여부 조회
5. 결과 통합
### 10.2 실패 조건
아래 조건이면 생성 중단한다.
- 테이블이 존재하지 않음
- PK가 없음
- PK가 2개 이상임
- 지원하지 않는 DB 타입 존재
## 11. 타입 매핑 명세
PostgreSQL -> Java 매핑 규칙은 아래를 기본으로 한다.
- `varchar`, `text`, `char` -> `String`
- `int2`, `int4`, `serial` -> `Integer`
- `int8`, `bigserial` -> `Long`
- `numeric`, `decimal` -> `BigDecimal`
- `bool` -> `Boolean`
- `date` -> `Date`
- `timestamp`, `timestamptz` -> `Date`
MVP에서는 현재 샘플 스타일을 맞추기 위해 `java.util.Date` 를 사용한다.
## 12. 컬럼 분류 규칙
생성기는 컬럼을 의미상 분류해서 Vue 및 SQL 생성에 활용한다.
### 12.1 기본 분류
- PK 컬럼
- 일반 입력 컬럼
- 생성일 컬럼
- 수정일 컬럼
- 제외 컬럼
### 12.2 기본 제외 후보
아래 컬럼은 기본적으로 등록 입력 폼에서 제외 가능 대상으로 본다.
- `created_at`
- `created_datetime`
- `updated_at`
- `updated_datetime`
- `first_reg_datetime`
- `last_mod_datetime`
### 12.3 기본 목록 후보
기본적으로 아래 규칙을 따른다.
- PK는 목록에 포함
- 문자형 일반 컬럼은 목록에 포함
- 긴 본문 컬럼은 목록에서 제외 가능
- 생성일, 수정일은 목록에 포함 가능
MVP에서는 단순 규칙 기반으로 처리하고, 이후 설정 파일로 분리할 수 있다.
## 13. 파일별 생성 명세
### 13.1 Entity
생성 내용:
- package 선언
- import 선언
- `@Data`
- 컬럼 필드 선언
스타일:
- 현재 프로젝트 Java 스타일 유지
- 탭 들여쓰기 유지
### 13.2 Service Interface
생성 메서드:
- `getXxxList()`
- `getXxx(PK id)`
- `createXxx(Xxx entity)`
- `updateXxx(Xxx entity)`
- `deleteXxx(PK id)`
### 13.3 Service Impl
생성 내용:
- DAO 의존성 주입
- CRUD 메서드 구현
- 등록 후 재조회
- 수정 후 재조회
### 13.4 Dao
생성 내용:
- MyBatis `SqlSession` 사용
- mapper namespace 상수
- CRUD DAO 메서드
### 13.5 Controller
생성 규칙:
- `@RestController`
- `@RequestMapping`
- `@Log4j2`
- `main.do?method=...` 패턴
생성 메서드:
- `page`
- `list_search`
- `item_get...`
- `item_regist`
- `item_update`
- `item_delete`
응답 정책:
- 목록, 상세, 등록, 수정은 `Map<String, Object>`
- 삭제는 `"success"`
### 13.6 MyBatis XML
생성 내용:
- `mapper`
- `resultMap`
- `selectList`
- `selectOne`
- `insert`
- `update`
- `delete`
SQL 규칙:
- 컬럼명은 DB 원본 유지
- property는 camelCase 사용
- insert, update 대상 컬럼은 PK 및 제외 컬럼 기준 분리
### 13.7 Vue Page
생성 내용:
- 목록 화면
- 상세/등록/수정 화면
- form 상태
- 목록 조회 API
- 상세 조회 API
- 등록 API
- 수정 API
- 삭제 API
화면 정책:
- 생성 결과는 기본 CRUD 화면 수준으로 제한
- 레이아웃과 스타일은 샘플 보드 기준 유지
## 14. API URL 생성 규칙
Vue 페이지는 백엔드 Controller 생성 규칙과 맞아야 한다.
기본 규칙:
- 목록 조회: `.../list/main.do?method=search`
- 상세 조회: `.../item/main.do?method=get<Entity>`
- 등록: `.../item/main.do?method=regist`
- 수정: `.../item/main.do?method=update`
- 삭제: `.../item/main.do?method=delete`
예시:
- `/pg-board/samples/list/main.do?method=search`
- `/pg-board/samples/item/main.do?method=getSampleBoard`
## 15. 재생성 정책 명세
### 15.1 목적
재생성은 기존 파일을 안전하게 병합하는 기능이 아니라, 최신 DB 메타데이터 기준으로 새 초기 코드를 다시 만드는 기능이다.
### 15.2 동작 방식
- 컬럼이 추가되면 생성기를 다시 실행한다.
- 생성기는 새 파일 세트를 다시 만든다.
- 기존 변경 파일은 건드리지 않는다.
- 개발자는 새 생성본과 기존 파일을 비교해 필요한 부분만 반영한다.
### 15.3 비지원 정책
아래 기능은 지원하지 않는다.
- 기존 Java 파일 내부 AST 기반 병합
- 기존 Vue 파일 diff 병합
- 기존 XML 구문 병합
## 16. 샘플 템플릿 변경 반영 정책
샘플 템플릿은 미래 생성물의 기준이므로 아래 규칙을 적용한다.
- 샘플 템플릿은 항상 실행 가능한 상태를 유지한다.
- 샘플 템플릿 변경은 생성기 템플릿 변경과 동일한 의미를 가진다.
- 새로 generate 하는 모든 소스는 최신 샘플 템플릿 기준으로 생성한다.
따라서 템플릿 관련 개선은 생성기 로직보다 샘플 템플릿과 치환 규칙 정리가 우선이다.
## 17. 설정 파일 명세
설정 파일은 `tools/board-generator/config/board-generator.yml` 을 기본 경로로 가정한다.
예시 항목:
```yaml
database:
client: postgresql
host: 127.0.0.1
port: 5432
database: app
user: app
password: app
paths:
basePackage: com.samsung
javaRoot: src/main/java
resourceRoot: src/main/resources
mapperRoot: src/main/resources/sql/mybatis/postgresql
vueRoot: frontend/src/components/view/admin
generatedRoot: .
conventions:
controllerStyle: formula_like
dateType: java.util.Date
apiStyle: main_do_method
indent: tab
```
MVP에서는 CLI 인자 우선, 설정 파일 보조 정책을 따른다.
## 18. 내부 모듈 구조 명세
권장 구조:
```text
tools/board-generator/
src/
cli/
index.js
config/
loadConfig.js
metadata/
postgresMetadataReader.js
naming/
namingRules.js
render/
renderJava.js
renderXml.js
renderVue.js
write/
fileWriter.js
validate/
schemaValidator.js
optionValidator.js
utils/
pathUtils.js
templates/
java/
xml/
vue/
config/
board-generator.yml
```
## 19. 로그 및 출력 규격
CLI 출력은 아래 순서를 따른다.
1. 입력값 출력
2. 계산된 이름 출력
3. 조회된 테이블 메타데이터 요약 출력
4. 생성 대상 파일 목록 출력
5. preview 또는 생성 결과 출력
예시 메시지:
- `Table found: sample_board`
- `Primary key: id(Integer)`
- `Generate target: src/main/java/...`
- `Preview mode enabled`
- `Files generated: 7`
## 20. 오류 처리 규칙
오류 메시지는 가능한 한 명확해야 한다.
예시:
- `Table not found: sample_board`
- `Composite primary key is not supported`
- `Unsupported column type: jsonb`
- `Output path already exists. Use --force to overwrite`
MVP에서는 예외 스택 전체 출력보다 원인 중심 메시지를 우선한다.
## 21. 검증 기준
생성기 완료 후 아래 검증을 통과해야 한다.
### 21.1 샘플 기준 검증
- `samples` 또는 `sample_board` 기준으로 생성한 결과가 현재 샘플 구조와 유사해야 한다.
### 21.2 백엔드 검증
- 생성된 Java 코드 컴파일 가능
- import 오류 없음
- MyBatis XML 파싱 가능
### 21.3 프론트 검증
- Vue 문법 오류 없음
- axios URL 패턴 정상
### 21.4 재생성 검증
- 컬럼 추가 후 다시 generate 했을 때 새 컬럼이 Entity, XML, Vue에 반영되어야 한다.
- 기존 수정 파일은 변경되지 않아야 한다.
## 22. MVP 완료 기준
아래 조건을 만족하면 MVP 완료로 본다.
- PostgreSQL 단일 테이블 기준으로 소스 생성 가능
- Entity, Service, ServiceImpl, Dao, Controller, XML, Vue 생성 가능
- preview 가능
- 실제 소스 경로 또는 지정한 `--output` 경로에 파일 생성 가능
- 컬럼 추가 후 재생성 가능
- 기존 파일 병합 없이 새 생성 정책 유지
## 23. 다음 작업
이 문서 다음 단계는 아래 순서를 따른다.
1. PostgreSQL 메타데이터 조회 SQL 작성
2. Node.js CLI 프로젝트 골격 생성
3. 템플릿 파일 분리
4. naming 규칙 구현
5. `samples` 기준 MVP 생성 테스트