code-gen popup 개발자 가이드¶
****_hera-code-gen의 popup 프로파일은 DB 테이블 메타데이터를 기준으로 팝업 전용 HTML fragment를 생성하고, 필요하면 부모 화면에 팝업 호출 버튼과 layout:insert까지 자동으로 추가하는 프로세스다.
1. 개요¶
목적¶
- 기존 webapp 화면에 붙일
offcanvas또는modal팝업 fragment를 생성한다. - 입력 화면과 조회 전용 화면을 분리해서 생성한다.
- DB 컬럼 기반 초안 생성 후 개발자가 YAML로 필드 순서, 레이아웃, 컨트롤 타입을 보정한다.
- 최종 렌더 단계에서 부모 페이지의 toolbar 버튼과 fragment insert 영역을 패치한다.
실행 모드¶
| 항목 | 값 |
|---|---|
| Spring profile | popup |
| code-generator.mode | popup |
| ConfigBuilder | PopupConfigBuilder |
| Generator | WebappPopupGenerator |
| 출력 위치 | hera-webapp/src/main/resources/templates/{module}/ |
지원 유형¶
| popup.type | popup.page-type | 템플릿 | 출력 suffix | 기본 fragment |
|---|---|---|---|---|
offcanvas | input | OC0101-html.tmpl | o01 | offcanvas |
offcanvas | view | OC0102-html.tmpl | o01-ro | offcanvas |
modal | input | MD0101-html.tmpl | m01 | modal |
modal | view | MD0102-html.tmpl | m01-ro | modal |
3단계 산출 흐름¶
application-codegen-popup.yml
-> table 단계: popup-table/{domain-code}-popup-table.yml 생성
-> layout 단계: popup-config/{domain-code}-popup-config.yml 생성
-> render 단계: hera-webapp templates HTML 생성 + 부모 페이지 패치
popup.stage=auto이면 파일 존재 여부와 수정 시간을 기준으로 다음 단계가 자동 결정된다.
popup-table파일이 없으면tablepopup-table은 있고popup-config가 없으면layoutpopup-table이popup-config보다 최신이면layout- 그 외에는
render
2. 빠른 시작¶
1. 설정 파일 수정¶
_hera-code-gen/src/main/resources/application-codegen-popup.yml을 열고 대상 정보를 지정한다.
code-generator:
mode: popup
run-mode: output-module
package:
module: sys
target-table: sys_board_content_reply
webapp:
domain-code: sys9902
popup:
type: offcanvas
page-type: input
size: md
stage: auto
parent-page-id: sys0101
핵심 설정은 다음과 같다.
| 설정 | 설명 |
|---|---|
target-table | DB 메타데이터를 읽을 원본 테이블 |
package.module | 출력 템플릿 하위 모듈 경로. 예: sys |
webapp.domain-code | 출력 파일명과 popup YAML 파일명 기준 |
popup.type | offcanvas 또는 modal |
popup.page-type | input 또는 view |
popup.size | sm: 1열, md: 2열, lg: 3열. 기본 컬럼 수와 width 산정에 사용 |
popup.parent-page-id | 버튼과 layout:insert를 추가할 부모 화면 id |
2. 1차 실행: popup-table 생성¶
_hera-code-gen AppRunner 실행
또는
생성 파일:
이 파일에서 화면에 보여줄 필드와 숨김 필드를 정리한다.
3. 2차 실행: popup-config 생성¶
_hera-code-gen AppRunner 실행
또는
생성 파일:
이 파일에서 팝업 제목, 크기, 행/열 배치, 컨트롤 타입, readonly, 검색 버튼, 공통코드 그룹 등을 보정한다.
4. 3차 실행: HTML 렌더 및 부모 페이지 패치¶
_hera-code-gen AppRunner 실행
또는
생성 파일 예시:
parent-page-id가 있으면 부모 페이지에도 다음 항목이 추가된다.
<div class="card-options toolbar">내부 팝업 열기 버튼- 부모 page-content 종료 전
layout:insert="~{sys/sys9902-o01 :: offcanvas}"
3. 단계별 적용 가이드¶
Step 1. popup 기본 설정 확정¶
먼저 application-codegen-popup.yml에는 실행에 필요한 최소값만 둔다.
target-table: sys_board_content_reply
webapp:
domain-code: sys9902
popup:
type: offcanvas
page-type: input
size: md
stage: auto
parent-page-id: sys0101
page-id, page-title, width, height는 처음부터 고정하지 않아도 된다. popup-config 생성 후 화면 요구사항에 맞춰 수정하는 편이 관리하기 쉽다.
Step 2. popup-table 보정¶
popup-table은 화면 필드 후보를 고르는 1차 설계 파일이다.
table:
name: "sys_board_content_reply"
title: "댓글"
hidden-fields:
- boardContentReplyId
fields:
- boardContentId
- replyContent
- useYn
# additional-fields:
# - name: "replyTypeName"
# label: "댓글 유형명"
# input-type: "text"
적용 규칙:
- PK 컬럼은 기본적으로
hidden-fields에 들어간다. - 화면에 노출할 컬럼은
fields에 둔다. - 필드 순서는 화면 출력 순서가 된다.
- DB에 없는 보조 필드는
additional-fields에 정의하고fields에도 같은name을 추가한다. - 숨김 필드를 화면에 보이게 하려면
hidden-fields에서 제거하고fields로 옮긴다. - additional-fields: table에 정의되지 않은 field를 추가한다.
name속성을fields에 추가하고label과input-type을 정의한다.
additional-fields 추가 예제
table:
name: "sys_board_content_reply"
title: "댓글"
hidden-fields:
- boardContentReplyId
fields:
- boardContentId
- replyContent
- useYn
- replyTypeName
additional-fields:
- name: "replyTypeName"
label: "댓글 유형명"
input-type: "text"
Step 3. popup-config 보정¶
popup-config는 실제 HTML 렌더링의 source of truth다.
popup:
type: "offcanvas"
page-type: "input"
page-id: "boardContentReplyRegOffcanvas"
domain-code: "sys9902"
page-title: "댓글 등록"
width: "720px"
height: "340px"
parent-page-id: "sys0101"
card:
title: "기본 정보"
hidden-fields:
- name: "boardContentReplyId"
value: ""
col-groups:
- key: "label-1"
width: "120px"
- key: "field-1"
width: "auto"
rows:
- row:
- label: "댓글 내용"
required: true
col-group: "field-1"
colspan: 3
rowspan: 1
controls:
- name: "replyContent"
input-type: "textarea"
align: "left"
readonly: false
disabled: false
search-btn: false
rows: 3
common-code-group: ""
주요 컨트롤 타입:
| input-type | 렌더링 |
|---|---|
text | 일반 input |
number | 숫자 input, 우측 정렬 권장 |
date | datepicker 클래스 포함 input |
textarea | textarea |
select | select2 대상 select |
select-yn | Y/N select |
radio | inline radio |
check, checkbox | inline checkbox |
Step 4. 렌더 결과 확인¶
최종 생성 HTML에서 다음을 확인한다.
- fragment 이름이
offcanvas또는modal인지 확인 page-id가 중복되지 않는지 확인name,id, hidden field가 후속 JS에서 기대하는 값과 맞는지 확인select,radio,check에 필요한 공통코드 map 주석을 실제 데이터 바인딩 방식에 맞게 해제/수정view화면이면 입력 컨트롤이 읽기 전용 표시 목적에 맞는지 확인
Step 5. 부모 페이지 패치 확인¶
parent-page-id가 sys0101이면 패치 대상은 다음 규칙으로 계산된다.
hera-webapp/src/main/resources/templates/{rootDomain}/{parent-page-id}.html
rootDomain = parent-page-id 앞 3자리
예: sys0101 -> templates/sys/sys0101.html
부모 페이지에는 다음 구조가 있어야 자동 버튼 생성이 가능하다.
그리고 page-content를 감싸는 마지막 </th:block>이 있어야 layout:insert 블록을 삽입할 수 있다.
4. 핵심 패턴 & 안티패턴¶
핵심 패턴¶
| 패턴 | 설명 |
|---|---|
auto stage 유지 | 일반 작업에서는 stage: auto로 두고 파일 상태로 다음 단계를 판단하게 한다. |
popup-table은 필드 선별 전용 | 필드 노출 여부와 순서만 빠르게 정리한다. 세부 레이아웃은 popup-config에서 한다. |
popup-config를 최종 설계 파일로 관리 | 실제 렌더링 기준은 popup-config다. 제목, 크기, id, rows, controls를 여기서 확정한다. |
page-id 명시 | 같은 부모 화면에 팝업이 여러 개 붙는 경우 DOM id 충돌을 피하기 위해 명시한다. |
parent-page-id는 최종 렌더 단계에서만 사용 | YAML 초안 생성과 fragment 렌더링은 부모 패치 없이도 가능하다. |
DB 외 필드는 additional-fields 사용 | 임의 필드를 코드에 하드코딩하지 않고 YAML 입력으로 유지한다. |
안티패턴¶
| 안티패턴 | 문제 |
|---|---|
| 생성된 HTML을 먼저 직접 수정 | 재렌더 시 덮어쓰기 위험이 있다. 반복 가능한 변경은 popup-config에 반영한다. |
popup-table만 수정하고 바로 render 기대 | popup-table이 바뀌면 layout 단계가 다시 돌아 popup-config를 갱신해야 한다. |
parent-page-id를 잘못 지정 | 존재하지 않는 부모 페이지면 렌더 마지막에 실패한다. |
| 부모 toolbar 구조 변경 | patcher는 <div class="card-options toolbar"> 패턴을 찾는다. 구조가 다르면 버튼 삽입에 실패한다. |
popup.type, popup.page-type 임의 값 사용 | 허용 값 외에는 예외가 발생한다. |
domain-code 대소문자 혼용 | 출력 파일과 YAML 파일명은 소문자 기준으로 처리된다. 도메인 코드는 일관되게 소문자로 쓰는 편이 안전하다. |
5. 트러블슈팅¶
[CODE-GEN] popup mode requires code-generator.target-table.¶
application-codegen-popup.yml에 code-generator.target-table이 비어 있다. 팝업 초안은 DB 테이블 메타데이터를 기반으로 하므로 대상 테이블을 반드시 지정해야 한다.
[POPUP] popup.stage must be auto, table, layout or render¶
popup.stage 값이 허용 범위를 벗어났다. 아래 중 하나로 수정한다.
강제로 특정 단계만 실행해야 할 때만 table, layout, render를 사용한다.
[POPUP] popup.stage=layout requires ...popup-table.yml¶
layout 단계에 필요한 popup-table/{domain-code}-popup-table.yml이 없다. stage: auto 또는 stage: table로 1차 파일을 먼저 생성한다.
[POPUP] popup.stage=render requires ...popup-config.yml¶
render 단계에 필요한 popup-config/{domain-code}-popup-config.yml이 없다. popup-table을 만든 뒤 다시 실행해서 popup-config를 먼저 생성한다.
[CODE-GEN] popup.type must be offcanvas or modal¶
popup.type은 offcanvas, modal만 허용된다. 대소문자는 내부에서 소문자로 정규화되지만 다른 값은 사용할 수 없다.
[CODE-GEN] popup.page-type must be input or view¶
popup.page-type은 input, view만 허용된다.
[POPUP] parent page not found¶
popup.parent-page-id로 계산한 부모 HTML 파일이 없다. 예를 들어 parent-page-id: sys0101이면 hera-webapp/src/main/resources/templates/sys/sys0101.html이 존재해야 한다.
[POPUP] parent toolbar not found¶
부모 페이지에 다음 toolbar 구조가 없다.
부모 페이지 구조를 기존 webapp 패턴에 맞추거나, parent-page-id를 비워 fragment만 생성한 뒤 수동으로 붙인다.
[POPUP] parent page-content closing </th:block> not found¶
부모 페이지에서 layout:insert 블록을 넣을 기준이 되는 마지막 </th:block>을 찾지 못했다. 부모 템플릿의 page-content 구조를 확인한다.
한글 주석이나 placeholder가 깨져 보임¶
일부 generator 소스의 문자열은 기존 인코딩 이슈로 깨져 보일 수 있다. 새로 생성/수정하는 YAML과 Markdown은 UTF-8로 저장하고, 실제 화면 문구는 popup-config에서 명시적으로 보정한다.
6. 레퍼런스 링크¶
설정과 실행¶
_hera-code-gen/src/main/resources/application-codegen-popup.yml_hera-code-gen/src/main/resources/application.yml_hera-code-gen/src/main/java/kr/co/dandisoft/hera/config/CodeGenConfig.java_hera-code-gen/src/main/java/kr/co/dandisoft/hera/codegen/config/GlobalConfigFactory.java_hera-code-gen/src/main/java/kr/co/dandisoft/hera/codegen/config/PopupConfigBuilder.java
generator 구현¶
_hera-code-gen/src/main/java/kr/co/dandisoft/hera/codegen/generator/GeneratorFactory.java_hera-code-gen/src/main/java/kr/co/dandisoft/hera/codegen/core/constant/GenTypeConst.java_hera-code-gen/src/main/java/kr/co/dandisoft/hera/codegen/core/config/WebappPopupConfig.java_hera-code-gen/src/main/java/kr/co/dandisoft/hera/codegen/generator/webapp/WebappPopupGenerator.java_hera-code-gen/src/main/java/kr/co/dandisoft/hera/codegen/generator/webapp/WebappPopupParentPagePatcher.java
YAML 스펙¶
_hera-code-gen/src/main/java/kr/co/dandisoft/hera/codegen/generator/webapp/popup/PopupTableSpec.java_hera-code-gen/src/main/java/kr/co/dandisoft/hera/codegen/generator/webapp/popup/PopupTableSpecIO.java_hera-code-gen/src/main/java/kr/co/dandisoft/hera/codegen/generator/webapp/popup/PopupSpec.java_hera-code-gen/src/main/java/kr/co/dandisoft/hera/codegen/generator/webapp/popup/PopupSpecIO.java
템플릿¶
_hera-code-gen/src/main/resources/templates/popup/OC0101-html.tmpl_hera-code-gen/src/main/resources/templates/popup/OC0102-html.tmpl_hera-code-gen/src/main/resources/templates/popup/MD0101-html.tmpl_hera-code-gen/src/main/resources/templates/popup/MD0102-html.tmpl
관련 문서¶
docs/references/code-gen-form-field-guide.md.agents/skills/project/hera-codegen/SKILL.md