/SimpleHR project
SimpleHR project

플랜별 메뉴 접근 제한 설계

conceptedited by Cairni · 방금 · AIv1

개요

요금제 시스템 구현 설계의 일환으로, 가입 플랜에 따라 특정 메뉴 접근을 제한하는 메커니즘을 정의한다. 전체 이용요금 및 과금 정책과 연계되며, 플랜 코드(PLAN_FREE, PLAN_BASIC, PLAN_STD, PLAN_SPC)를 기준으로 동작한다. 설계 원문


권위 소스: Menu.visible_tiers

기존 LicenseMenuMapping 별도 테이블 대신 Menu.visible_tiers JSONB 필드를 단일 권위 소스로 사용한다. 설계 원문

방식설명
기존 (LicenseMenuMapping)별도 테이블 JOIN 필요, 동기화 이슈 발생 가능
신규 (Menu.visible_tiers)메뉴와 허용 플랜 정보가 한 곳에 집중 → 동기화 이슈 없음, JOIN 불필요

기본값: ["PLAN_FREE", "PLAN_BASIC", "PLAN_STD", "PLAN_SPC"]


플랜별 메뉴 허용 규칙

AI · 출처 클릭
PLAN_FREE1
PLAN_BASIC1
PLAN_STD2
PLAN_SPC2
메뉴 그룹PLAN_FREEPLAN_BASICPLAN_STDPLAN_SPC
급여관리 (4개)
이러닝센터 (5개)
전자근로계약서
나머지 전체
  • 이러닝/전자근로계약서 메뉴의 visible_tiers["PLAN_STD", "PLAN_SPC"]
  • 그 외 전체 메뉴 → ["PLAN_FREE", "PLAN_BASIC", "PLAN_STD", "PLAN_SPC"]

이용요금(과금) 정책 스펙과 함께 참고할 것. 설계 원문


미들웨어 연동 구조

기존 menu_permission_guard 미들웨어(main.py L672)에 플랜 체크 단계를 추가한다.

두 가지 조건을 모두 통과해야만 접근이 허용된다. 설계 원문


메모리 캐시 전략

매 요청마다 DB를 조회하는 오버헤드를 피하기 위해 앱 시작 시 Menu.visible_tiers 데이터를 메모리에 로드한다.

python
# {menu_url: set(plan_codes)} — 해당 메뉴에 접근 가능한 플랜 목록
_MENU_PLAN_CACHE: dict[str, set[str]] = {}
시점동작
앱 시작Menu 테이블 전체 조회 → 캐시 1회 로드
라이센스 메뉴 수정 시캐시 즉시 갱신
일반 API 요청DB 조회 없이 딕셔너리 lookup

설계 원문


라이센스 메뉴 관리 페이지 전환

기존 license-menus/page.tsxLicenseMenuMapping 테이블을 참조하고 있으나, Menu.visible_tiers를 직접 읽고 쓰도록 전환한다.

작업변경 내용
GETMenu 테이블에서 visible_tiers 조회
PUTMenu.visible_tiers 업데이트 + 메모리 캐시 갱신
UI플랜 열을 4종(FREE/BASIC/STD/SPC)으로 표시 — PLAN_PRM 제거

설계 원문


프론트엔드 반영

로그인 응답의 menu_keys에 플랜 제한을 반영하여 사이드바가 자동으로 비허용 메뉴를 숨기도록 한다.

  • resolve_menu_keys() 함수 내에 플랜 기반 필터링 로직 추가
  • 기존 사이드바 menu_keys 기반 렌더링 로직 그대로 활용 (추가 UI 변경 최소화)

설계 원문


마이그레이션 연동

마이그레이션(billing_plan_migration.py) 실행 시 Menu.visible_tiers 일괄 업데이트가 포함된다.

  • 이러닝/전자근로계약서 메뉴 → ["PLAN_STD", "PLAN_SPC"]
  • 그 외 전체 메뉴 → ["PLAN_FREE", "PLAN_BASIC", "PLAN_STD", "PLAN_SPC"]

마이그레이션 전략 전체는 요금제 시스템 구현 설계 참고. 설계 원문


관련 스펙

Made with CairniExplore public wikis →