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 = "영업 실적") }),
    ownerPolicy = @QfOwnerPolicy(enabled = true, attribute = "orgId")
)
public class SalesRecordEntity {

    @QfI18n(defaultMessage = "Amount")
    @QfListAttribute(sortable = true)
    private Long amount;

    @QfI18n(defaultMessage = "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> getAllOrganizations() {
        return organizationRepository.findAll()
            .stream()
            .map(org -> QfOrganization.builder()
                .id(org.getId())
                .parentId(org.getParentId())
                .name(org.getName())
                .depth(org.getDepth())
                .build())
            .collect(Collectors.toList());
    }

    @Override
    public List<QfOrganization> getOrganizations(Object userId) {
        return organizationRepository.findByUserId(userId)
            .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.