Skip to content

조직 모델

Q-Framework는 계층적 조직 구조 기반의 데이터 접근 제어를 지원합니다. 별도의 WHERE 절 작성 없이 선언만으로 조직 범위 데이터 격리가 자동으로 적용됩니다.

조직 계층 구조

본사 (ROOT)
  ├── 서울 본부 (BRANCH)
  │     ├── 영업1팀 (TEAM)
  │     ├── 영업2팀 (TEAM)
  │     └── 지원팀 (TEAM)
  └── 부산 지사 (BRANCH)
        ├── 영업팀 (TEAM)
        └── 지원팀 (TEAM)

각 조직은 고유 ID를 가지며, 부모-자식 계층 관계로 구성됩니다.


조직 가시 범위 (Organization Visibility Scope)

사용자가 어떤 조직의 데이터를 볼 수 있는지를 결정합니다.

핵심 구성 요소

구성 요소설명
Anchor (기준점)데이터 접근의 기준이 되는 조직
Include Rule (포함 범위)기준점 기준으로 어디까지 포함할지
Depth Limit (깊이 제한)포함 범위의 최대 깊이

Include Rule 옵션

규칙설명예시
SELF기준점 조직만자신의 팀 데이터만
CHILDREN기준점 하위 조직 포함자신과 하위 팀 모두
ROOT_TO_SELF루트부터 기준점까지본사부터 자신의 팀까지 상위 모두

조직 정책 선언

java
@QfEntity(
    appKey = "app",
    name = @QfI18n(defaultMessage = "Sales Record", texts = { @QfI18nText(locale = "ko", message = "영업 실적") }),
    organizationPolicy = @QfOrganizationPolicy(enabled = true)
)
public class SalesRecordEntity {

    @QfDisplayLabel(text = "Amount")
    @QfListAttribute(sortable = true)
    private Long amount;

    @QfDisplayLabel(text = "Sales Date")
    @QfListAttribute(sortable = true)
    private LocalDate salesDate;
}

조직 가시 정책 설정

application.yml에서 조직 가시 정책을 설정합니다.

yaml
qf:
  organization:
    visibility:
      anchor: SELF          # 기준점: 본인 조직
      include-rule: CHILDREN  # 범위: 본인 + 하위 조직
      depth-limit: 2          # 최대 2단계 하위까지

정책별 동작 예시

시나리오: 서울 본부 소속 사용자가 데이터를 조회하는 경우

조직 트리:
본사
  └── 서울 본부 ← 현재 사용자
        ├── 영업1팀
        ├── 영업2팀
        └── 지원팀
anchorinclude-ruledepth-limit접근 가능 범위
SELFSELF서울 본부 데이터만
SELFCHILDREN1서울 본부 + 직속 팀 3개
SELFCHILDREN무제한서울 본부 + 모든 하위 조직
SELFROOT_TO_SELF본사 + 서울 본부

런타임 적용 방식

조직 범위 쿼리는 자동으로 생성됩니다. 개발자가 직접 작성할 필요가 없습니다.

sql
-- Q-Framework가 자동 생성하는 조건 예시
-- (anchor=SELF, include-rule=CHILDREN, depth-limit=2)
WHERE organization_id IN (
    SELECT id FROM organization
    WHERE id = :currentUserOrgId
       OR parent_id = :currentUserOrgId
       OR (parent_id IN (
           SELECT id FROM organization WHERE parent_id = :currentUserOrgId
       ))
)

SaaS 환경에서의 조직 모델 활용

Q-Framework의 조직 모델은 멀티 테넌트 SaaS 환경을 자연스럽게 지원합니다.

테넌트 = 최상위 조직

테넌트A (Root)              테넌트B (Root)
  └── 서울 지점              └── 본사
        └── 영업팀                  └── 개발팀

각 테넌트가 루트 조직이 되며, anchor=SELF, include-rule=CHILDREN으로 설정하면 다른 테넌트의 데이터가 자동으로 격리됩니다.

일반적인 Tenant 중심 모델과의 차이

구분일반 멀티 테넌트Q-Framework 조직 모델
격리 방식tenant_id 컬럼 하드코딩계층 조직 가시 범위
내부 계층 지원별도 구현 필요기본 제공
권한 세분화복잡한 RBAC 구현조직 계층 + Privilege
선언 방식코드 레벨 구현어노테이션 선언

조직 정보 제공 (SPI)

조직 정보는 QfOrganizationProvider SPI를 통해 제공합니다.

java
@Component
public class MyOrganizationProvider implements QfOrganizationProvider {

    @Override
    public List<QfOrganization> getOrganizationHierarchy(String rootOrgId) {
        // 조직 계층 데이터 반환
        return organizationRepository.findHierarchyByRoot(rootOrgId)
            .stream()
            .map(org -> QfOrganization.builder()
                .id(org.getId())
                .parentId(org.getParentId())
                .name(org.getName())
                .depth(org.getDepth())
                .build())
            .collect(Collectors.toList());
    }
}

다음 단계

Released under the Apache 2.0 License.