어노테이션 레퍼런스
엔티티 어노테이션
@QfEntity
클래스를 Q-Framework 엔티티로 선언합니다. 도메인 엔티티 클래스에 선언합니다.
@QfEntity(
appKey = "app",
name = @QfI18n(
defaultMessage = "Product",
texts = { @QfI18nText(locale = "ko", message = "상품") }
),
autoHistoryEnabled = false,
deletePolicy = @QfCrudPolicy(enabled = true),
capabilityKey = "product-management"
)
public class ProductEntity { }| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
appKey | String | 소속 클라이언트 앱 키 | "" (선언된 앱 사용) |
name | @QfI18n | 다국어 표시명 | @QfI18n(texts = {}) |
autoHistoryEnabled | boolean | 자동 변경 이력 활성화 | false |
deletePolicy | @QfCrudPolicy | 삭제 작업 정책 | @QfCrudPolicy(enabled = false) |
treePolicy | @QfTreePolicy | 트리/계층 구조 설정 | @QfTreePolicy (비활성) |
ownerPolicy | @QfOwnerPolicy | 데이터 소유 및 가시 범위 정책 (조직 또는 사용자) | @QfOwnerPolicy(enabled = false) |
masterRelation | @QfMasterRelation | 마스터-디테일 관계 | @QfMasterRelation(enabled = false) |
capabilityKey | String | 연결된 Capability 키 | "" (클래스명에서 도출) |
excelDownloadable | boolean | Excel 내보내기 엔드포인트 활성화 | true |
excelUploadable | boolean | Excel 가져오기 엔드포인트 활성화 | true |
displayTextRules | @QfComposedText[] | 여러 필드를 조합한 표시 텍스트 생성 규칙 | {} |
requireSearchTrigger | boolean | 명시적 검색 실행 전 데이터 로딩 금지 | false |
hideRowNumber | boolean | 행 번호 컬럼 숨김 | false |
autoSelectSingleResult | boolean | 쿼리 결과가 1건일 때 자동 선택 | false |
forceRowSelection | boolean | 엔티티 수준 액션 전 행 선택 강제 | false |
masterEntityDependentMode | QfMasterEntityDependentMode | DEPENDENT: 이 엔티티 타입의 structural reference로 마스터 엔티티가 존재해야 함. INDEPENDENT: 프레임워크가 마스터 엔티티 존재를 검증하지 않음. | DEPENDENT |
buttons | @QfButton[] | 엔티티 수준 액션 버튼 | {} |
exposeOn | @QfExposeOn[] | 앱/Capability 노출 규칙 | {} |
managementConditions | @QfConditionExpr[] | 관리 화면에 적용할 추가 조건 | {} |
excludedApiTypes | QfGeneratedApiTypeEnum[] | 코드 생성에서 제외할 API 엔드포인트 타입 | {} |
apiGenerationGroup | QfGeneratedApiTypeGroupEnum | API 생성 그룹 | all |
QfGeneratedApiTypeEnum 값
| 값 | 설명 |
|---|---|
create | 엔티티 레코드 생성 |
list | 페이징/필터 목록 조회 |
detail | 키/조건으로 단건 조회 |
load_update | 수정 화면 초기 데이터 로드 |
update | 기존 레코드 수정 |
delete | 레코드 삭제 (정책에 따라 소프트/하드) |
histories | 변경 이력 / 감사 레코드 조회 |
unique | 속성 값 중복 여부 확인 |
order | 정렬 순서 업데이트 |
tree | 계층형 트리 데이터 조회 |
key_value | 단순 키-값 데이터셋 조회 (셀렉터, 코드 테이블) |
update_key_value | 키-값 형태 설정 레코드 업데이트 |
excel_create | 엑셀 업로드/다운로드 작업 등록 |
excel_process | 업로드된 엑셀 데이터 파싱/검증/적용 |
excel_download | 데이터를 엑셀 파일로 내보내기 |
excel_sample_download | 업로드용 엑셀 템플릿 다운로드 |
excel_download_poll | 비동기 엑셀 다운로드 진행 상태 폴링 |
excel_download_cancel | 비동기 엑셀 다운로드 작업 취소 |
excel_process_poll | 비동기 엑셀 처리 진행 상태 폴링 |
excel_process_cancel | 비동기 엑셀 처리 작업 취소 |
excel_download_result | 작업 완료 후 다운로드 가능한 결과 정보 반환 |
asyncsearch | 오래 걸릴 수 있는 검색을 비동기 작업으로 실행 |
QfGeneratedApiTypeGroupEnum 값
| 값 | 생성되는 API | 설명 |
|---|---|---|
all | 모든 타입 | 지원하는 모든 API 타입 생성 (제외 없음) |
only_crud | CRUD + 조회 API | 엑셀 워크플로우 API 및 asyncsearch 제외 |
excel | 엑셀 워크플로우 API | 일반 CRUD/조회 및 비엑셀 유틸리티 제외 |
only_read | list, detail | 목록 및 단건 조회만 생성 |
only_list | list | 목록 조회만 생성 |
@QfClientApp
클라이언트 앱을 선언합니다. 설정 클래스에 선언합니다.
@QfClientApp(
key = "app",
name = @QfI18n(
defaultMessage = "App",
texts = { @QfI18nText(locale = "ko", message = "일반 앱") }
)
)
public class AppConfig { }| 속성 | 타입 | 필수 | 설명 | 기본값 |
|---|---|---|---|---|
key | String | ✅ | 클라이언트 앱 고유 키 | |
name | @QfI18n | 다국어 표시명 | @QfI18n(defaultMessage = "app", texts = {}) | |
description | String | 앱 간단 설명 | "Client app" | |
order | int | 표시 순서 (낮을수록 앞) | 0 |
Capability / 권한 어노테이션
@QfCapability
업무 기능 영역(Capability)을 선언합니다. 전용 클래스에 선언합니다.
@QfCapability(
key = "product-management",
name = @QfI18n(defaultMessage = "Product Management", texts = {}),
entities = { ProductEntity.class },
privileges = {
@QfPrivilege(key = "product-management__create"),
@QfPrivilege(key = "product-management__delete")
}
)
public final class ProductManagementCapability { }| 속성 | 타입 | 필수 | 설명 |
|---|---|---|---|
key | String | ✅ | 고유 Capability 키 |
name | @QfI18n | 다국어 표시명 | |
entities | Class[] | 관리하는 주요 엔티티 클래스 목록 | |
privileges | @QfPrivilege[] | 이 Capability에서 정의하는 권한 목록 |
엔티티는 엔티티 클래스에 @QfCapability를 선언하는 것이 아니라, @QfEntity(capabilityKey = "...")를 통해 Capability에 연결됩니다.
@QfPrivilege
@QfCapability 내에서 권한 단위를 선언합니다.
@QfPrivilege(
key = "product-management__create",
name = @QfI18n(defaultMessage = "Create Product", texts = {})
)| 속성 | 타입 | 필수 | 설명 |
|---|---|---|---|
key | String | ✅ | 고유 키 (Capability 내 유니크) |
name | @QfI18n | 다국어 표시명 |
보안 어노테이션
@QfCrypto
필드를 자동 암호화/복호화 처리합니다. 필드에 선언합니다.
@QfCrypto
private String email;
@QfCrypto(algorithm = QfCrypto.CryptoAlgorithm.bcrypt)
private String password;제약
@QfSearch와 함께 사용 불가 (컴파일 오류)
| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
algorithm | CryptoAlgorithm | 저장 알고리즘 | aes256 |
CryptoAlgorithm 값 목록
| 값 | 방향 | 설명 |
|---|---|---|
aes256 | 대칭 (복호화 가능) | AES-256 암호화 |
sha256 | 단방향 | SHA-256 해시 |
pbkdf2 | 단방향 | PBKDF2 키 파생 |
bcrypt | 단방향 | BCrypt 비밀번호 해시 |
argon2 | 단방향 | Argon2 비밀번호 해시 / KDF |
rsaCipher | 비대칭 (복호화 가능) | RSA 암호화 |
rsaKey | — | RSA 키 소재 저장 |
rsaSignature | — | RSA 서명 |
@QfOwnerPolicy (요소 어노테이션)
엔티티의 데이터 소유 및 가시 범위 정책을 선언합니다. 두 가지 소유 모델을 지원합니다.
ORGANIZATION— 조직 소유: 조직 계층 탐색 기반 필터USER— 사용자 소유:principalId일치 기반 필터
@QfEntity 안에서 요소로 사용합니다:
// 조직 소유 — 자신의 조직만 (기본)
@QfEntity(
ownerPolicy = @QfOwnerPolicy(enabled = true, attribute = "orgId")
)
// 조직 소유 — 자신의 조직 + 모든 하위 조직
@QfEntity(
ownerPolicy = @QfOwnerPolicy(
enabled = true,
attribute = "orgId",
include = QfOrganizationInclude.ANCHOR_AND_DESCENDANTS
)
)
// 사용자 소유 — 데이터 생성자만 조회 가능
@QfEntity(
ownerPolicy = @QfOwnerPolicy(
enabled = true,
ownerType = QfOwnerType.USER,
attribute = "createdBy"
)
)| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
enabled | boolean | 소유 필터링 활성화 | true |
ownerType | QfOwnerType | ORGANIZATION 또는 USER | ORGANIZATION |
attribute | String | 소유자 ID를 담는 필드명 | "" |
anchorKind | QfOrganizationAnchorKind | 앵커 전략 (ORGANIZATION 전용) | SELF |
anchorDepth | int | 앵커 깊이 (ORGANIZATION 전용) | 0 |
include | QfOrganizationInclude | 탐색 방향 (ORGANIZATION 전용) | ANCHOR_ONLY |
maxAncestorDepth | int | 최대 상위 조직 탐색 깊이, -1 = 무제한 | -1 |
maxDescendantDepth | int | 최대 하위 조직 탐색 깊이, -1 = 무제한 | -1 |
overrideMode | QfOrganizationPolicyOverrideMode | 전역 정책 오버라이드 방식 | REPLACE |
QfOrganizationAnchorKind 값 목록
| 값 | 설명 |
|---|---|
ROOT | 조직 계층 최상위(루트) 노드를 앵커로 사용 |
SELF | 현재 조직을 앵커로 사용 (기본값) |
ANCESTOR_RELATIVE_DEPTH | 현재 조직에서 상대 깊이의 상위 조직을 앵커로 사용 (0=현재, 1=부모, …) |
ANCESTOR_ABSOLUTE_DEPTH | 루트에서 절대 깊이가 anchorDepth인 조직을 앵커로 사용 |
QfOrganizationInclude 값 목록
| 값 | 설명 |
|---|---|
ANCHOR_ONLY | 앵커 조직만 포함 (기본값) |
ANCHOR_AND_DESCENDANTS | 앵커 + 모든 하위 조직 포함 |
ANCHOR_AND_ANCESTORS | 앵커 + 모든 상위 조직 포함 |
ANCHOR_AND_ANCESTORS_AND_DESCENDANTS | 앵커 + 상위 전체 + 하위 전체 포함 |
CUSTOM | 커스텀 탐색 전략 (애플리케이션 정의) |
QfOrganizationPolicyOverrideMode 값 목록
| 값 | 설명 |
|---|---|
REPLACE | 엔티티 정책이 전역 정책을 완전히 대체 (기본값) |
RESTRICT | 엔티티 정책이 전역 정책을 좁히는 방향으로만 적용 (권한 확대 방지) |
검증 어노테이션
@QfValidationRule
필드에 검증 규칙을 선언합니다. 반복 선언 가능.
@QfValidationRule(
rule = QfValidationRule.Rule.regex,
params = {"^[A-Za-z0-9_]+$"},
invalidValueMessageKey = "validation.loginId.invalid"
)
private String loginId;| 속성 | 타입 | 필수 | 설명 |
|---|---|---|---|
rule | Rule | ✅ | 검증 규칙 타입 |
params | String[] | 규칙 파라미터 (regex의 경우 패턴) | |
invalidValueMessageKey | String | 오류 메시지 리소스 키 (invalidValueMessages와 상호 배타적) | |
invalidValueMessages | @QfI18n | 인라인 오류 메시지 (invalidValueMessageKey와 상호 배타적) | |
serverOnly | boolean | 서버 측 전용 검증 | |
applyOn | @QfConditionExpr[] | 규칙 적용 조건 | |
references | @QfValidationRuleReference[] | 교차 속성 참조 (예: 비밀번호 확인, 날짜 비교) |
상호 배타적
invalidValueMessageKey와 invalidValueMessages는 동시에 사용할 수 없습니다. 메시지 리소스 파일에 정의된 경우 invalidValueMessageKey를, 인라인으로 정의하려면 invalidValueMessages를 사용하세요.
Rule 열거값:
| 규칙 | 설명 | params |
|---|---|---|
regex | 커스텀 정규식 | params[0] = 패턴 |
unique | 서버 중복 검사 | params[0] = URL (선택) |
login_id | 로그인 ID 형식 (설정에서 가져옴) | — |
user_pwd | 비밀번호 정책 (설정에서 가져옴) | — |
화면 노출 어노테이션
@QfListAttribute
목록 화면에 컬럼으로 표시합니다.
@QfListAttribute(sortable = true)
private String name;| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
sortable | boolean | false | 정렬 가능 여부 |
cannotHide | boolean | false | 사용자가 컬럼 숨김 방지 |
order | int | 0 | 컬럼 표시 순서 (낮을수록 앞) |
uiClasses | @QfUiClasses[] | {} | 해당 컬럼의 UI 클래스 정의 |
subattributes | Subattribute[] | {} | 엔티티 타입 속성의 하위 항목 표시 |
showOn | @QfConditionExpr[] | {} | 조건부 표시 표현식 |
buttons | @QfButton[] | {} | 행 단위 액션 버튼 |
exposeOn | @QfExposeOn[] | {} | 앱/Capability 가시성 규칙 |
@QfListAttribute.Subattribute 내부 어노테이션
엔티티 타입 필드의 내부 속성을 목록 셀의 하위 줄로 표시할 때 subattributes 안에서 사용합니다.
@QfListAttribute(
subattributes = {
@QfListAttribute.Subattribute(attributeName = "code"),
@QfListAttribute.Subattribute(attributeName = "name")
}
)
private CategoryEntity category;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
attributeName | String | 표시할 내부 속성 이름 | (필수) |
name | @QfI18n | 하위 속성 다국어 레이블 | @QfI18n(texts = {}) |
displayTextRules | @QfComposedText[] | 표시 텍스트 조합 규칙 | {} |
controlType | QfControlType.Type | 렌더링 컨트롤 타입 | text |
@QfDetailAttribute
상세 조회 화면에 표시합니다.
@QfDetailAttribute
private String name;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
uiClasses | @QfUiClasses[] | UI 클래스 정의 | {} |
exposeOn | @QfExposeOn[] | 앱/Capability 가시성 규칙 | {} |
showOn | @QfConditionExpr[] | 표시 조건 | {} |
order | int | 표시 순서 (낮을수록 앞) | 0 |
@QfCreateAttribute
등록 폼에 입력 필드로 표시합니다.
@QfCreateAttribute(
requiredOn = @QfRequiredOn(always = true)
)
private String name;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
exposeOn | @QfExposeOn[] | 앱/Capability 가시성 규칙 | {} |
requiredOn | @QfRequiredOn | 필수 규칙 | @QfRequiredOn |
readonlyOn | @QfReadonlyOn | 읽기 전용 규칙 | @QfReadonlyOn |
initialValue | String | 정적 초기값 | "" |
dynamicInitialValue | @QfComposedText[] | 동적 초기값 (initialValue보다 우선 적용) | {} |
uiClasses | @QfUiClasses[] | UI 클래스 정의 | {} |
showOn | @QfConditionExpr[] | 표시 조건 | {} |
disableOn | @QfConditionExpr[] | 비활성화 조건 | {} |
syncValueFrom | String | 다른 속성 경로에서 값 복사 | "" |
initialValues | InitialValue[] | 엔티티 타입 속성의 중첩 초기값 | {} |
setValuesFrom | String[] | 이전 입력값을 기본값으로 이어받을 속성 이름 목록 | {} |
@QfUpdateAttribute
수정 폼에 입력 필드로 표시합니다.
@QfUpdateAttribute(
requiredOn = @QfRequiredOn(always = true)
)
private String name;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
exposeOn | @QfExposeOn[] | 앱/Capability 가시성 규칙 | {} |
requiredOn | @QfRequiredOn | 필수 규칙 | @QfRequiredOn |
readonlyOn | @QfReadonlyOn | 읽기 전용 규칙 | @QfReadonlyOn |
uiClasses | @QfUiClasses[] | UI 클래스 정의 | {} |
showOn | @QfConditionExpr[] | 표시 조건 | {} |
disableOn | @QfConditionExpr[] | 비활성화 조건 | {} |
syncValueFrom | String | 다른 속성 경로에서 값 복사 | "" |
order | int | 컬럼 표시 순서 (낮을수록 앞) | 0 |
TIP
@QfUpdateAttribute에는 initialValue / dynamicInitialValue 파라미터가 없습니다. 이 파라미터들은 @QfCreateAttribute 전용입니다.
@QfSearch
목록 화면의 검색 조건으로 활성화합니다.
@QfSearch(type = QfSearch.Type.text)
private String name;
@QfSearch(type = QfSearch.Type.select)
private String status;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
type | Type | 검색 컨트롤 타입 | auto |
exposeOn | @QfExposeOn[] | 앱/Capability 가시성 규칙 | {} |
showOn | @QfConditionExpr[] | 표시 조건 | {} |
caseSensitive | CaseSensitive | 대소문자 구분 (sensitive/insensitive) | insensitive |
condition | Condition | 검색 조건 (like/exact) | like |
conditions | @QfConditionExpr[] | 옵션/검색 데이터에 적용할 추가 조건 | {} |
target | String | 연관 경로로 직접 검색할 대상 (예: "invcNo.hdry") | "" |
multiple | QfControlType.MultipleValue | 다중값 허용 정책 | unset |
Type 열거값
| 타입 | 설명 |
|---|---|
auto | 필드 타입 기반 자동 감지 |
text | 일반 텍스트 입력 |
select | 단일 선택 드롭다운 |
true_or_false | 불리언 토글 |
multiselect | 다중 선택 |
period_date | 날짜 범위 |
period_datetime | 날짜시간 범위 |
자동 감지 규칙 (type = auto)
- 기본형 / 래퍼 /
String→text String+@QfCodeGroup→select- 사용자 정의 클래스 타입 →
select
select로 결정되면 caseSensitive는 sensitive로, condition은 exact로 강제됩니다.
@QfOptions
선택형 컨트롤(select, multiselect, radio 등)의 옵션 메타데이터를 선언합니다.
코드 기반 또는 엔티티 타입 속성의 경우 기본적으로 옵션이 자동으로 해석됩니다. @QfOptions는 기본 해석을 재정의하거나 추가 조건을 적용하거나 수동 옵션을 정의할 때 사용합니다.
@QfOptions(
conditions = {
@QfConditionExpr({
@QfCondToken(type = QfCondTokenType.ATOM,
atom = @QfCondition(attributeName = "alias", notIn = {"user_status.system"}))
})
}
)
private UserStatus status;| 파라미터 | 타입 | 설명 | 기본값 |
|---|---|---|---|
conditions | @QfConditionExpr[] | 옵션 후보 필터링 조건 | {} |
optionModel | @QfOptionModel | 명시적 옵션 모델 (엔티티 또는 코드 그룹) | @QfOptionModel |
name | String | 관계 모델 내 현재 엔티티를 참조하는 속성명 | "" |
referencedAttributeName | String | 관계 모델 키에 조인하는 현재 엔티티 속성명 | "" |
searchAttributeName | String | 관계 모델 내 검색 속성명 | "" |
displayTextRules | @QfComposedText[] | 옵션 레이블 구성 규칙 | {} |
asyncSearch | @QfAsyncSearch | 비동기 검색 설정 (대용량/동적 옵션 세트용) | @QfAsyncSearch |
customOptions | @QfCustomOption[] | 수동 옵션 목록 (비어있지 않으면 다른 모든 설정 무시) | {} |
수동 옵션 우선 정책
customOptions가 비어있지 않으면 conditions, optionModel, asyncSearch 등 다른 모든 설정이 무시됩니다.
@QfOptionModel 파라미터
| 파라미터 | 타입 | 설명 | 기본값 |
|---|---|---|---|
codeGroup | String | 코드 테이블 기반 옵션 그룹 식별자 | "" |
condition | String | 옵션 조회 추가 필터 조건 (예: JPQL 구문) | "" |
@QfAsyncSearch 파라미터
| 파라미터 | 타입 | 설명 | 기본값 |
|---|---|---|---|
watch | String | 감시할 속성명; 비어있으면 현재 속성의 입력값 사용 | "" |
target | String[] | 옵션 모델 내 검색/매칭 대상 속성명 목록 | {} |
url | String | 비동기 옵션 조회용 커스텀 API 엔드포인트 | "" |
@QfCustomOption 파라미터
| 파라미터 | 타입 | 설명 | 기본값 |
|---|---|---|---|
names | @QfI18n | 옵션 표시명 (다국어) | (필수) |
value | String | 제출/저장될 실제 옵션 값 | (필수) |
@QfComposedText (요소 어노테이션)
표시 텍스트 조합 규칙을 선언합니다. 반복 가능(Repeatable) — 선언 순서대로 처리됩니다.
| 파라미터 | 타입 | 설명 | 기본값 |
|---|---|---|---|
segments | @QfTextSegment[] | 순서대로 이어붙여 표시 텍스트를 구성하는 세그먼트 목록 | (필수) |
useI18n | boolean | true이면 조합된 문자열을 메시지 키로 해석하여 i18n 조회 | false |
@QfCrudPolicy (요소 어노테이션)
CRUD 작업 정책을 선언합니다. @QfEntity 내 요소로 사용합니다 (예: deletePolicy = @QfCrudPolicy(...)).
| 파라미터 | 타입 | 설명 | 기본값 |
|---|---|---|---|
enabled | boolean | 해당 작업의 활성화 여부 | true |
forbiddenTooltip | String | 작업이 비활성화될 때 표시할 툴팁 메시지 키 | "" |
conditions | @QfConditionExpr[] | 런타임 컨텍스트 기반 조건부 제약 | {} |
@QfControlType
필드의 UI 컨트롤 타입을 선언합니다.
@QfControlType(QfControlType.Type.email)
private String email;
@QfControlType(QfControlType.Type.textarea)
private String description;
@QfControlType(value = QfControlType.Type.number, minValue = 0, maxValue = 100)
private Integer score;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
value | Type | 컨트롤 타입 | (필수) |
hint | @QfI18n | 플레이스홀더 / 도움말 텍스트 | @QfI18n(texts = {}) |
multiple | MultipleValue | 다중값 허용 정책 (multiple/single/unset) | unset |
regex | String | random_string 타입용 정규식 | "" |
minValue | long | 최솟값 (number 타입) | Long.MIN_VALUE |
maxValue | long | 최댓값 (number 타입) | Long.MAX_VALUE |
uniqueOn | String | section_list 내 중복 방지 키 속성명 | "" |
passwordConfirm | boolean | 비밀번호 확인 입력 요청 (password 타입) | false |
Type 열거값
| 값 | 설명 |
|---|---|
text | 일반 텍스트 입력 |
display | 표시 전용 (읽기 전용) |
random_string | 랜덤 문자열 자동 생성 (regex 사용) |
password | 비밀번호 입력 |
textarea | 여러 줄 텍스트 |
html_editor | 리치 텍스트(HTML) 에디터 |
select | 단일 선택 |
multiselect | 다중 선택 |
file | 파일 업로드 |
number | 숫자 입력 |
i18n | 다국어 텍스트 |
weekday | 단일 요일 선택 |
weekdays | 복수 요일 선택 |
icon | 아이콘 선택기 |
date | 날짜 선택 |
time | 시간 선택 |
datetime | 날짜시간 선택 |
date_simple_string | 날짜 문자열 (예: yyyyMMdd) |
time_simple_string | 시간 문자열 (예: HHmm) |
tel | 전화번호 |
email | 이메일 주소 |
point | 좌표 (위도/경도) |
zip | 우편번호 |
checkbox | 체크박스 |
section | 레이아웃 구분선 |
section_list | 반복 섹션 리스트 |
map | 지도 / 위치 컨트롤 |
radio | 라디오 버튼 그룹 |
paint | 드로잉 영역 |
hidden | 숨김 필드 (값 있음, 화면 미표시) |
버튼 어노테이션
@QfButton
목록 컬럼 또는 엔티티 툴바에 버튼을 선언합니다. @QfListAttribute(buttons = ...) 또는 @QfEntity(buttons = ...)의 요소로 사용합니다.
@QfListAttribute(
buttons = {
@QfButton(
frontendComponent = "ProductDetailModal",
name = @QfI18n(defaultMessage = "상세"),
icon = "cilInfo",
color = "primary",
size = "xl"
)
}
)| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
frontendComponent | String | 모달에서 렌더링할 프런트엔드 컴포넌트명 | (필수) |
name | @QfI18n | 버튼 표시명 | @QfI18n(defaultMessage = "button", texts = {}) |
icon | String | 아이콘 식별자 (CoreUI) | "" |
color | String | 버튼 색상 (CoreUI) | "secondary" |
size | String | 모달 크기 (sm / lg / xl / full) | "xl" |
actionType | ActionType | 클릭 액션 유형 (MODAL / NONE) | MODAL |
enabledOnChecked | boolean | 항목 체크 시에만 활성화 여부 | false |
modalCloseOnly | boolean | 닫기 전용 모달 여부 | false |
inputs | Input[] | 모달 내 입력 필드 정의 | {} |
conditions | @QfConditionExpr[] | 버튼 표시 조건 | {} |
displayTextRules | @QfComposedText[] | 표시 텍스트 조합 규칙 | {} |
@QfButton.Input 파라미터
| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
key | String | 입력 파라미터 식별자 | (필수) |
type | String | 입력 타입 (예: text, number) | (필수) |
placeholder | @QfI18n | 플레이스홀더 텍스트 | @QfI18n(texts = {}) |
구조 어노테이션
@QfMasterRelation (요소 어노테이션)
마스터-디테일 관계를 선언합니다. @QfEntity 안에서 요소로 사용합니다:
@QfEntity(
masterRelation = @QfMasterRelation(
enabled = true,
masterEntityFqcn = "com.example.OrderEntity",
masterKeyAttribute = "orderId",
onMasterDelete = QfMasterRelation.OnMasterDelete.CASCADE_DELETE
)
)
public class OrderItemEntity { }| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
enabled | boolean | 마스터 관계 활성화 | false |
masterEntityFqcn | String | 마스터 엔티티의 FQCN | "" |
masterKeyAttribute | String | 마스터 ID를 담는 이 엔티티의 속성명 | "" |
onMasterDelete | OnMasterDelete | 마스터 삭제 시 연계 정책 | IGNORE |
onMasterDelete | 설명 |
|---|---|
CASCADE_DELETE | 마스터 삭제 시 디테일 레코드 자동 삭제 |
RESTRICT | 디테일이 존재하면 마스터 삭제 거부 |
IGNORE | 디테일 레코드를 고아 상태로 유지 |
@QfTreePolicy (요소 어노테이션)
트리 동작 정책을 선언합니다. @QfEntity 안에서 요소로 사용합니다:
@QfEntity(
treePolicy = @QfTreePolicy(editableRoot = true, draggable = false)
)
public class CategoryEntity { }| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
editableRoot | boolean | 현재 트리 뷰의 루트 노드 편집 가능 여부 | false |
draggable | boolean | 드래그 앤 드롭 순서 변경 활성화 | true |
@QfParent / @QfTreeDepth / @QfChildren
트리 구조 필드를 선언합니다.
@QfParent
private String parentId;
@QfTreeDepth
private Integer depth;
@QfChildren
private List<CategoryEntity> children;@QfParent 파라미터
| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
defaultValue | String | 루트 노드(부모 없음)를 나타내는 센티넬 값 | "" |
defaultNull | boolean | 루트 노드의 부모 값으로 null 사용 여부 | false |
@QfTreeDepth 파라미터
| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
defaultValue | int | 기본 깊이 값 (1 = 루트) | 1 |
@QfGroup
관련 필드를 UI에서 그룹으로 묶습니다.
@QfGroup(alias = "address_info")
private String address;
@QfGroup(alias = "address_info")
private String zipCode;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
alias | String | 그룹 식별자 (템플릿·UI 렌더링에서 사용하는 안정적 키) | (필수) |
name | @QfI18n | 다국어 그룹 레이블 | @QfI18n(defaultMessage = "group", texts = {}) |
uiClasses | @QfUiClasses[] | 그룹에 적용할 UI 클래스 정의 | {} |
라이프사이클 훅 어노테이션
@QfOn
CRUD 파이프라인의 특정 시점에 실행될 훅 메서드를 선언합니다. 반복 선언 가능.
@QfOn(phase = QfOnPhase.BEFORE, op = QfOnOp.CREATE)
public void beforeCreate(QfPipelineContext ctx) { ... }
@QfOn(phase = QfOnPhase.AFTER, op = QfOnOp.UPDATE, when = QfOnWhen.SUCCESS)
public void afterUpdate(QfPipelineContext ctx) { ... }| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
phase | QfOnPhase | 실행 시점 | (필수) |
op | QfOnOp | 대상 작업 | (필수) |
layer | QfOnLayer | 실행 레이어 | DOMAIN |
io | QfOnIo | I/O 유형 | NONE |
scope | QfOnScope | 데이터 범위 | SINGLE |
when | QfOnWhen | 실행 조건 (AFTER 단계) | ALWAYS |
order | int | 같은 시점 내 훅 실행 순서 | 0 |
QfOnPhase
| 값 | 설명 |
|---|---|
BEFORE | 작업 전 실행 |
AFTER | 작업 후 실행 |
QfOnOp
| 값 | 설명 |
|---|---|
CREATE | 등록 |
READ | 단건 조회 |
UPDATE | 수정 |
DELETE | 삭제 |
LIST | 목록 조회 |
DETAIL | 상세 조회 |
TREE | 트리 조회 |
EXPORT | 데이터 내보내기 (Excel/CSV) |
IMPORT | 데이터 가져오기 (Excel/CSV) |
SEARCH | 검색/필터 |
UNIQUE_SEARCH | 고유값 검증 검색 |
MASTER_ENTITY | 마스터 엔티티 조회 |
QfOnLayer
| 값 | 설명 |
|---|---|
REQUEST | 요청 경계 (API 엔드포인트 진입/종료) |
DOMAIN | 도메인/서비스 처리 (기본값) |
COMMIT | 트랜잭션 커밋 이후 |
QfOnScope
| 값 | 설명 |
|---|---|
SINGLE | 단건 (기본값) |
LIST | 복수 레코드 |
BULK | 일괄 처리 |
QfOnWhen (AFTER 단계에서 의미 있음)
| 값 | 설명 |
|---|---|
ALWAYS | 항상 실행 (기본값) |
SUCCESS | 성공 시에만 실행 |
FAILURE | 실패 시에만 실행 |
QfOnIo
| 값 | 설명 |
|---|---|
NONE | 특별한 I/O 없음 (기본값) |
EXCEL | Excel 입출력 |
CSV | CSV 입출력 |
감사 추적 어노테이션
프레임워크가 쓰기 시점에 자동으로 채웁니다:
| 어노테이션 | 설명 |
|---|---|
@QfRgsOperId | 등록자 ID 자동 기록 |
@QfRgsOperDt | 등록일시 자동 기록 |
@QfRgsOperIp | 등록자 IP 주소 자동 기록 |
@QfUpdtOperId | 최종 수정자 ID 자동 기록 |
@QfUpdtOperDt | 최종 수정일시 자동 기록 |
@QfUpdtOperIp | 수정자 IP 주소 자동 기록 |
@QfDeleteOperId | 삭제자 ID 자동 기록 |
@QfDeleteOperDt | 삭제일시 자동 기록 |
@QfDeleteOperIp | 삭제자 IP 주소 자동 기록 |
@QfDeleteFlag | 소프트 삭제 표시 |
@QfDeleteFlag 파라미터
| 파라미터 | 타입 | 설명 | 기본값 |
|---|---|---|---|
deletedValues | String[] | 삭제 상태로 해석할 값 목록 (예: {"Y"}, {"1"}, {"true"}) | {} |
valueType | QfDeleteValueType | 플래그 값 비교 타입 강제 지정 | AUTO |
valueType | 설명 |
|---|---|
AUTO | 속성 타입에 따라 자동 감지 |
STRING | 문자열 비교 |
BOOLEAN | boolean 비교 |
INTEGER | Integer 비교 |
LONG | Long 비교 |
결과 코드 어노테이션
@QfResultCode
결과 코드를 선언합니다. 타입에 선언합니다.
@QfResultCode(
code = "Q-MY-APP-000001",
messageKey = "result_code.text.q_my_app_000001",
cause = "Product not found",
resolution = "Check the product ID and retry.",
target = "Product"
)
public interface ProductResultCode { }| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
code | String | 시스템 내 유일한 결과 코드 (예: Q-MY-APP-000001) | (필수) |
cause | String | 발생 원인에 대한 간결한 설명 | (필수) |
resolution | String | 해결 또는 처리 방법 | (필수) |
target | String | 적용 대상 (모듈/컴포넌트/핸들러 등) | (필수) |
messageKey | String | 메시지 리소스 키 (미지정 시 자동 생성) | "" |
자세한 내용은 결과 코드 레퍼런스를 참고하세요.
다국어 어노테이션
@QfI18n
다국어 메시지 번들을 선언합니다. 다른 어노테이션 안에서 요소로 사용합니다.
@QfI18n(
defaultMessage = "Product Name",
texts = {
@QfI18nText(locale = "ko", message = "상품명"),
@QfI18nText(locale = "ja", message = "商品名")
},
key = "entity.product.name.label", // 선택 사항; 비어 있으면 자동 생성
sync = false
)| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
defaultMessage | String | "" | 로케일 불일치 시 대체 텍스트 |
texts | @QfI18nText[] | {} | 로케일별 메시지 |
key | String | "" | 메시지 조회 키 (비어 있으면 자동 생성) |
sync | boolean | false | 시작 시마다 소스와 동기화 |
@QfI18nText
@QfI18n 번들 내 하나의 로케일별 메시지입니다.
@QfI18nText(locale = "ko", message = "상품명")| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
locale | String | 로케일 코드 (예: ko, en) | (필수) |
message | String | 로케일별 메시지 텍스트 | (필수) |
sync | boolean | 시작 시마다 이 로케일 항목을 강제 동기화 | false |
열거형 레퍼런스
QfMenuDisplayLocationEnum
메뉴 항목이 클라이언트 UI에서 렌더링되는 위치를 정의합니다. 다양한 프런트엔드 구현에서 메뉴 배치를 표준화하는 데 사용됩니다.
| 값 | 설명 |
|---|---|
main | 기본 탐색 영역 |
top | 상단 / 헤더 바 |
bottom | 하단 / 푸터 바 |
left | 좌측 보조 영역 |
right | 우측 보조 영역 |
@QfDisplayHint
필드의 힌트(툴팁 / 플레이스홀더)를 선언합니다.
@QfDisplayHint(text = "상품명을 입력하세요")
private String name;
@QfDisplayHint(key = "hint.product.name") // 메시지 리소스에서 조회
private String name;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
key | String | i18n 조회용 메시지 리소스 키 | "" |
text | String | 리터럴 힌트 텍스트 (key 미지정 또는 조회 실패 시 대체값) | "" |
정렬 및 데이터 어노테이션
@QfOrder
목록 기본 정렬 기준 속성을 선언합니다.
@QfOrder(direction = QfOrder.Direction.desc)
private LocalDateTime createdAt;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
direction | Direction | 정렬 방향 | asc |
Direction 값: asc, desc
@QfSeparator
컬렉션 타입 속성 직렬화 시 사용할 구분자를 선언합니다.
@QfSeparator("|")
private List<String> tags;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
value | String | 컬렉션 요소 구분자 | (필수) |
@QfCodeGroup
속성을 코드 테이블 기반으로 처리되는 코드 속성으로 선언합니다.
@QfCodeGroup(alias = "STATUS_CODE")
private String status;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
alias | String | 코드 그룹 식별자 | (필수) |
구조적 데이터 어노테이션
@QfEmbeddedId
속성을 복합/임베디드 식별자로 선언합니다. 파라미터 없음.
@QfEmbeddedId
private OrderId id;@QfMap
지도(위치) 가상 속성을 선언합니다. UI에서는 지도 컴포넌트로 표시되고, 실제 데이터는 주소/좌표 속성에 저장됩니다.
@QfMap(
addressAttributeName = "address",
latitudeAttributeName = "lat",
longitudeAttributeName = "lng"
)
private Object location;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
addressAttributeName | String | 주소를 저장하는 속성명 | (필수) |
latitudeAttributeName | String | 위도를 저장하는 속성명 | (필수) |
longitudeAttributeName | String | 경도를 저장하는 속성명 | (필수) |
조건부 동작 어노테이션
@QfForceTransfer
목록/생성/수정/상세 속성으로 노출되지 않아도 전송 페이로드에 항상 포함되도록 강제합니다.
@QfForceTransfer
private String internalCode;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
exposeOn | @QfExposeOn[] | 앱/Capability별 노출 규칙 | {} |
conditions | @QfConditionExpr[] | 강제 전송 적용 조건 | {} |
@QfRequiredOn (요소 어노테이션)
속성의 필수 여부를 선언합니다. @QfCreateAttribute / @QfUpdateAttribute의 중첩 파라미터로 사용합니다.
| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
always | boolean | 항상 필수 (conditions는 비어야 함) | false |
conditions | @QfConditionExpr[] | 필수로 만드는 조건 | {} |
@QfReadonlyOn (요소 어노테이션)
속성의 읽기 전용 여부를 선언합니다. @QfCreateAttribute / @QfUpdateAttribute의 중첩 파라미터로 사용합니다.
| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
always | boolean | 항상 읽기 전용 (conditions는 비어야 함) | false |
conditions | @QfConditionExpr[] | 읽기 전용으로 만드는 조건 | {} |
@QfExposeOn (요소 어노테이션)
앱/Capability별 노출 규칙을 선언합니다. 속성 어노테이션의 중첩 파라미터로 사용합니다.
| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
appKeys | String[] | 노출할 클라이언트 앱 키 목록 (비어있으면 전체 앱) | {} |
capabilities | String[] | 노출할 Capability alias 목록 (비어있으면 전체 Capability) | {} |
@QfUiClasses
속성에 조건부로 적용할 UI 클래스를 선언합니다. 반복 선언 가능.
@QfUiClasses(value = {"text-danger", "fw-bold"})
private String status;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
value | String[] | 적용할 CSS/UI 클래스명 목록 | {} |
exposeOn | @QfExposeOn[] | 앱/Capability별 노출 규칙 | {} |
conditions | @QfConditionExpr[] | 클래스 적용 조건 | {} |
조건 어노테이션
conditions, showOn, disableOn 등에서 사용하는 조건 표현식을 구성하는 어노테이션입니다.
@QfConditionExpr
플랫 토큰 스트림으로 조건 표현식을 선언합니다.
// A == "Y" AND (B IS NOT EMPTY OR C != "N")
@QfConditionExpr({
@QfCondToken(type = QfCondTokenType.ATOM, atom = @QfCondition(attributeName = "a", equal = "Y")),
@QfCondToken(type = QfCondTokenType.AND),
@QfCondToken(type = QfCondTokenType.LPAREN),
@QfCondToken(type = QfCondTokenType.ATOM, atom = @QfCondition(attributeName = "b", isNotEmpty = true)),
@QfCondToken(type = QfCondTokenType.OR),
@QfCondToken(type = QfCondTokenType.ATOM, atom = @QfCondition(attributeName = "c", notEqual = "N")),
@QfCondToken(type = QfCondTokenType.RPAREN)
})| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
value | @QfCondToken[] | 조건 표현식을 구성하는 토큰 목록 | (필수) |
@QfCondToken / QfCondTokenType
조건 표현식의 단일 토큰입니다.
| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
type | QfCondTokenType | 토큰 유형 | (필수) |
atom | @QfCondition | 원자 조건 (type이 ATOM일 때만 유효) | @QfCondition |
QfCondTokenType 값: ATOM, AND, OR, LPAREN, RPAREN
@QfCondition
단일 원자 비교 조건입니다.
| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
source | Source | 비교 대상 값의 소스 | other_attribute_value |
attributeName | String | 비교 대상 속성명 (other_attribute_value 사용 시) | "" |
masterEntityAttributeName | String | 마스터 엔티티 속성명 (master_entity 사용 시) | "" |
equal | String | 동등(=) 비교값 | "" |
notEqual | String | 불일치(!=) 비교값 | "" |
like | String | LIKE 패턴 | "" |
notLike | String | NOT LIKE 패턴 | "" |
in | String[] | IN 비교값 목록 | {} |
notIn | String[] | NOT IN 비교값 목록 | {} |
lessThan | String | 미만(<) 비교값 | "" |
lessThanOrEqual | String | 이하(<=) 비교값 | "" |
moreThan | String | 초과(>) 비교값 | "" |
moreThanOrEqual | String | 이상(>=) 비교값 | "" |
have | String | 권한 보유 조건 (privilege 사용 시) | "" |
notHave | String | 권한 미보유 조건 (privilege 사용 시) | "" |
isEmpty | boolean | IS EMPTY 조건 | false |
isNotEmpty | boolean | IS NOT EMPTY 조건 | false |
treeDepth | int | 트리 깊이 비교값 (tree_depth 사용 시) | -1 |
Source 값: other_attribute_value, master_entity, user_info, tree_depth, privilege, app, menu, capability
파일/미디어 어노테이션
@QfFile
파일 업로드 메타데이터를 선언합니다.
@QfFile(maxFiles = 5, accept = "image/*")
private String thumbnailId;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
purpose | String | 파일 목적 식별자 | "file_purpose.general" |
maxFileSize | long | 최대 파일 크기 (바이트, 0 = 무제한) | 0 |
maxFiles | int | 최대 파일 수 | 1 |
accept | String | 허용 MIME 타입 (예: "image/*") | "*/*" |
defaultImage | String | 파일 미등록 시 기본 이미지 경로 | "thumb/defaultPicture.png" |
usePrimary | boolean | 대표 파일만 사용 여부 | false |
@QfZip
우편번호 속성을 선언합니다. 주소 속성과 연동하여 우편번호 조회를 지원합니다.
@QfZip(addressAttributeName = "address", detailAddressAttributeName = "detailAddress")
private String zipCode;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
addressAttributeName | String | 조회된 주소를 저장할 속성명 | (필수) |
detailAddressAttributeName | String | 상세 주소를 저장할 속성명 | "" |
텍스트 조합 어노테이션
@QfAffixes
생성/수정 시 자동으로 앞/뒤에 붙는 고정 텍스트를 선언합니다.
@QfAffixes(
prefixes = { @QfTextSegment(source = QfTextSegment.Source.static_value, value = "PREFIX-") },
postfixes = { @QfTextSegment(source = QfTextSegment.Source.static_value, value = "-SUFFIX") }
)
private String code;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
prefixes | @QfTextSegment[] | 접두사 세그먼트 정의 | {} |
postfixes | @QfTextSegment[] | 접미사 세그먼트 정의 | {} |
@QfTextSegment (요소 어노테이션)
조합 텍스트의 단일 세그먼트입니다. @QfAffixes, @QfComposedText 등의 중첩 요소로 사용합니다.
| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
source | Source | 세그먼트 값을 가져올 소스 | this_attribute_value |
value | String | 정적 값 또는 속성명/조회 키 (source에 따라 해석) | "" |
Source 값
| 값 | 설명 |
|---|---|
this_attribute_value | 현재 속성의 값 |
other_attribute_value | 다른 속성의 값 (value로 속성명 지정) |
user_info | 현재 사용자 컨텍스트 정보 |
master_entity | 마스터 엔티티의 값 |
static_value | value의 리터럴 문자열 |
unknown | 미정의/구현 정의 |
뷰 전용 속성 어노테이션
@QfExcelAttribute
엑셀 내보내기 출력에 속성을 포함하도록 선언합니다.
@QfExcelAttribute(order = 1)
private String productName;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
order | int | 엑셀 출력 컬럼 순서 | 0 |
exposeOn | @QfExposeOn[] | 앱/Capability별 노출 규칙 | {} |
@QfTreeAttribute
트리 뷰 출력에 속성을 노출하도록 선언합니다.
@QfTreeAttribute(isName = true, sortable = true, order = 1)
private String categoryName;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
isName | boolean | 트리 노드 표시명으로 사용할 속성 여부 | false |
order | int | 트리 뷰 컬럼 순서 | 0 |
sortable | boolean | 트리 뷰에서 정렬 가능 여부 | false |
exposeOn | @QfExposeOn[] | 앱/Capability별 노출 규칙 | {} |
퍼시스턴스 어노테이션
@QfAllowedDirectAccess
Q-Framework 관리 추상화를 우회하는 직접 데이터 접근을 허용합니다. qf.persistence.access.mode가 permissive(기본값)일 때 필요합니다.
@QfAllowedDirectAccess(reason = "SPI 구현체 — 사용자 저장소에 직접 접근 필요")
private final UserRepository userRepository;| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
reason | String | 우회 이유 (소스 코드 내 감사 기록) | "" |