docs: 온보딩 가이드 + 권한 화이트리스트 문서 추가
- 00-onboarding: 신규 합류자 가이드 (시스템 개요, 도메인 맵, 읽기 순서) - 12-permission-whitelist: PermissionGate 화이트리스트 접근 제어 - _index.md: 문서 목록 업데이트 - v2/01: 관련 문서 참조 추가 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# SAM ERP Frontend Documentation
|
||||
|
||||
> **프로젝트**: SAM ERP Next.js 프론트엔드
|
||||
> **최종 갱신**: 2026-03-10
|
||||
> **최종 갱신**: 2026-03-18
|
||||
> **현재 문서 버전**: v1 (운영 중) / v2 (설계 중)
|
||||
|
||||
---
|
||||
@@ -26,6 +26,7 @@ frontend/
|
||||
|
||||
| # | 문서 | 버전 | 최종 수정 | 담당 | 대상 | 설명 |
|
||||
|---|------|------|----------|------|------|------|
|
||||
| 00 | [onboarding](v1/00-onboarding.md) | 1.0.0 | 2026-03-20 | Frontend | 전체 | 신규 합류자 온보딩 (시스템 개요, 도메인 맵, 읽기 순서) |
|
||||
| 01 | [architecture](v1/01-architecture.md) | 1.0.0 | 2026-03-09 | Frontend | 전체 | 프로젝트 구조, 기술 스택, 디렉토리 설계 |
|
||||
| 02 | [api-pattern](v1/02-api-pattern.md) | 1.0.0 | 2026-03-09 | Frontend | FE/BE | API 통신 패턴 (프록시, Server Action, buildApiUrl) |
|
||||
| 03 | [component-design](v1/03-component-design.md) | 1.0.0 | 2026-03-09 | Frontend | FE/기획 | 컴포넌트 계층 (atoms → templates), 페이지 유형 |
|
||||
@@ -37,12 +38,13 @@ frontend/
|
||||
| 09 | [conventions](v1/09-conventions.md) | 1.0.0 | 2026-03-09 | Frontend | FE | 네이밍, import, 파일 배치, Git 규칙 |
|
||||
| 10 | [document-api-integration](v1/10-document-api-integration.md) | 1.0.0 | 2026-02-05 | API Team | FE/BE | 문서 관리 API 연동 (검사 성적서 resolve/upsert) |
|
||||
| 11 | [browser-navigation-rules](v1/11-browser-navigation-rules.md) | 1.0.0 | 2026-03-10 | Frontend | AI/QA | 브라우저 네비게이션 규칙 (URL 추측 금지, 메뉴 클릭 필수) |
|
||||
| 12 | [permission-whitelist](v1/12-permission-whitelist.md) | 1.0.0 | 2026-03-20 | Frontend | FE/BE | 권한 기반 페이지 접근 제어 (화이트리스트, 바이패스, 모듈 역할 분담) |
|
||||
|
||||
### v2 — 동적 멀티테넌트 시스템 (설계 중)
|
||||
|
||||
| # | 문서 | 버전 | 최종 수정 | 담당 | 대상 | 설명 |
|
||||
|---|------|------|----------|------|------|------|
|
||||
| 01 | [dynamic-multi-tenant-page-system](v2/01-dynamic-multi-tenant-page-system.md) | 1.1.0 | 2026-03-11 | FE/BE | 전체 | 동적 멀티테넌트 페이지 시스템 설계 (17개 규칙, JSON config, 동적 라우팅, 권한 통합) |
|
||||
| 01 | [dynamic-multi-tenant-page-system](v2/01-dynamic-multi-tenant-page-system.md) | 1.3.0 | 2026-03-18 | FE/BE | 전체 | 동적 멀티테넌트 페이지 시스템 설계 (17개 규칙, JSON config, 동적 라우팅, 권한 통합, 테넌트 분류, 선결과제) |
|
||||
|
||||
> **v2 상태**: 초안 — 백엔드 회의 후 협의 항목 확정 예정
|
||||
|
||||
@@ -62,6 +64,7 @@ frontend/
|
||||
| 날짜 | 문서 | 변경 | 버전 |
|
||||
|------|------|------|------|
|
||||
| 2026-03-11 | 01 | 동적 멀티테넌트 페이지 시스템 설계 초안 작성 | 1.1.0 |
|
||||
| 2026-03-18 | 01 | JSONB 저장 확정, 테넌트 분류(3종), 선결과제 4개, 의존성 위반 목록 추가 | 1.3.0 |
|
||||
|
||||
### v1 (2026-03-09 ~)
|
||||
|
||||
@@ -70,6 +73,8 @@ frontend/
|
||||
| 2026-03-09 | 01~09 | 초기 작성 | 1.0.0 |
|
||||
| 2026-02-05 | 10 | 문서 API 연동 가이드 작성 (api-specs에서 이관) | 1.0.0 |
|
||||
| 2026-03-10 | 11 | 브라우저 네비게이션 규칙 추가 (AI/E2E URL 추측 금지) | 1.0.0 |
|
||||
| 2026-03-20 | 12 | 권한 기반 페이지 접근 제어 — PermissionGate 화이트리스트 전환, 바이패스 경로, 모듈 시스템 역할 분담 | 1.0.0 |
|
||||
| 2026-03-20 | 00 | 신규 합류자 온보딩 가이드 — 시스템 개요, 테넌트 구조, 도메인 맵, 상태관리, 라우팅 패턴, 읽기 순서 | 1.0.0 |
|
||||
|
||||
---
|
||||
|
||||
@@ -104,6 +109,7 @@ PATCH: 오탈자, 코드 예시 수정, 사소한 수정
|
||||
|
||||
| 할 일 | 읽을 문서 |
|
||||
|-------|----------|
|
||||
| **프로젝트에 처음 합류** | **v1/00-onboarding (여기서 시작)** |
|
||||
| 프로젝트 전체 구조 이해 | v1/01-architecture |
|
||||
| API 호출 방법 알기 | v1/02-api-pattern |
|
||||
| 새 리스트 페이지 만들기 | v1/03-component-design → v1/04-common-components |
|
||||
@@ -114,4 +120,5 @@ PATCH: 오탈자, 코드 예시 수정, 사소한 수정
|
||||
| 코딩 컨벤션 확인 | v1/09-conventions |
|
||||
| 문서 관리 API 연동 | v1/10-document-api-integration |
|
||||
| AI/E2E 페이지 이동 규칙 | v1/11-browser-navigation-rules |
|
||||
| 권한 기반 접근 제어 이해 | v1/12-permission-whitelist |
|
||||
| **동적 멀티테넌트 설계** | **v2/01-dynamic-multi-tenant-page-system** |
|
||||
|
||||
386
frontend/v1/00-onboarding.md
Normal file
386
frontend/v1/00-onboarding.md
Normal file
@@ -0,0 +1,386 @@
|
||||
# 00. 신규 합류자 온보딩 가이드
|
||||
|
||||
> **대상**: 프로젝트에 새로 합류하는 개발자 (시니어 포함)
|
||||
> **버전**: 1.0.0
|
||||
> **최종 수정**: 2026-03-20
|
||||
> **읽는 시간**: 15분
|
||||
|
||||
---
|
||||
|
||||
## 1. SAM ERP 한눈에 보기
|
||||
|
||||
SAM은 **멀티테넌트 폐쇄형 ERP** 시스템입니다.
|
||||
인증된 사용자만 접근 가능하며, 테넌트(고객사)별로 필요한 모듈만 활성화됩니다.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ SAM ERP Platform │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────┐ │
|
||||
│ │ 공통 ERP (~165 페이지) │ │
|
||||
│ │ 회계 | 영업 | 인사 | 결재 | 게시판 | 설정 │ │
|
||||
│ │ 고객센터 | 기준정보 | 자재/재고 | 출고/배송 │ │
|
||||
│ └─────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────┐ ┌──────────────────────────┐ │
|
||||
│ │ 경동 MES (~27p) │ │ 주일 건설 (~48p) │ │
|
||||
│ │ 생산관리 │ │ 시공/프로젝트 │ │
|
||||
│ │ 품질관리 │ │ 입찰/계약 │ │
|
||||
│ └──────────────────┘ │ 기성관리 │ │
|
||||
│ └──────────────────────────┘ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ 옵션 모듈 │ │
|
||||
│ │ 차량관리 │ │
|
||||
│ └──────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 테넌트 구조
|
||||
|
||||
현재 3개 테넌트가 운영됩니다.
|
||||
|
||||
| 테넌트 | 업종 | 전용 모듈 | 특징 |
|
||||
|--------|------|-----------|------|
|
||||
| 경동 | 셔터 제조 (MES) | 생산, 품질 | 작업지시/실적, 설비관리, QMS |
|
||||
| 주일 | 건설 시공 | 건설/프로젝트 | 현장관리, 입찰, 기성 |
|
||||
| (신규) | 일반 | 공통만 | 공통 ERP 기능만 사용 |
|
||||
|
||||
### 테넌트별 접근 제어
|
||||
|
||||
```
|
||||
로그인 → 백엔드가 해당 테넌트의 메뉴 목록 반환
|
||||
→ PermissionGate가 화이트리스트로 접근 제어
|
||||
→ 메뉴에 없는 페이지 = 접근 불가 (URL 직접 입력도 차단)
|
||||
|
||||
경동 유저: 회계, 영업, 생산, 품질 등 접근 가능 / 건설 차단
|
||||
주일 유저: 회계, 영업, 건설 등 접근 가능 / 생산, 품질 차단
|
||||
```
|
||||
|
||||
상세: [v1/12-permission-whitelist.md](12-permission-whitelist.md)
|
||||
|
||||
---
|
||||
|
||||
## 3. 기술 스택
|
||||
|
||||
| 영역 | 기술 |
|
||||
|------|------|
|
||||
| 프레임워크 | Next.js 15 (App Router) |
|
||||
| 런타임 | React 19 |
|
||||
| 언어 | TypeScript (strict) |
|
||||
| UI | shadcn/ui (Radix UI) + Tailwind CSS 4 |
|
||||
| 상태관리 | Zustand |
|
||||
| 폼 | react-hook-form + Zod |
|
||||
| 백엔드 | PHP Laravel 12 (별도 프로젝트) |
|
||||
| 모바일 | Capacitor (하이브리드 앱) |
|
||||
|
||||
### 핵심 제약
|
||||
|
||||
- **모든 페이지 Client Component**: `'use client'` 필수 (HttpOnly 쿠키 인증 때문)
|
||||
- **Server Component 사용 금지**: SEO 불필요 + 쿠키 수정 불가
|
||||
- **API 호출은 반드시 프록시**: `/api/proxy/` 또는 Server Action 경유
|
||||
|
||||
---
|
||||
|
||||
## 4. 프로젝트 구조
|
||||
|
||||
```
|
||||
sam_project/
|
||||
├── sam-next/sam-react-prod/ ← 프론트엔드 (현재 프로젝트)
|
||||
├── sam-api/sam-api/ ← 백엔드 (PHP Laravel)
|
||||
├── sam-design/sam-design/ ← 디자인 시스템
|
||||
└── sam-docs/ ← 프로젝트 문서
|
||||
```
|
||||
|
||||
### 프론트엔드 디렉토리
|
||||
|
||||
```
|
||||
src/
|
||||
├── app/[locale]/(protected)/ # 라우트 (도메인별 폴더)
|
||||
│ ├── accounting/ # 회계
|
||||
│ ├── sales/ # 영업
|
||||
│ ├── hr/ # 인사
|
||||
│ ├── approval/ # 결재
|
||||
│ ├── production/ # 생산 (경동 전용)
|
||||
│ ├── quality/ # 품질 (경동 전용)
|
||||
│ ├── construction/ # 건설 (주일 전용)
|
||||
│ ├── dashboard/ # CEO 대시보드
|
||||
│ └── settings/ # 설정
|
||||
│
|
||||
├── components/ # 컴포넌트 (계층 구조)
|
||||
│ ├── ui/ # atoms (shadcn/ui)
|
||||
│ ├── molecules/ # molecules (FormField, DateRangeSelector 등)
|
||||
│ ├── organisms/ # organisms (PageLayout, IntegratedListTemplateV2 등)
|
||||
│ ├── templates/ # templates (UniversalListPage 등)
|
||||
│ ├── {domain}/ # 도메인별 비즈니스 컴포넌트
|
||||
│ └── document-system/ # 모듈 경계 넘는 공유 컴포넌트
|
||||
│
|
||||
├── stores/ # Zustand 전역 상태
|
||||
├── hooks/ # 커스텀 훅
|
||||
├── lib/ # 유틸리티, API 래퍼
|
||||
├── modules/ # 모듈 시스템 (테넌트 분리)
|
||||
└── contexts/ # React Context (Permission 등)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 전역 상태 (Zustand Stores)
|
||||
|
||||
| 스토어 | 역할 | 지속성 |
|
||||
|--------|------|--------|
|
||||
| `authStore` | 로그인 유저, 테넌트, 역할 정보 | localStorage |
|
||||
| `menuStore` | 사이드바 메뉴 목록, 활성 메뉴, 접힘 상태 | localStorage |
|
||||
| `permissionStore` | 메뉴별 권한 매트릭스 (view/create/update/delete) | 메모리 |
|
||||
| `masterDataStore` | 기준정보 캐시 (품목, 공정 등) | 메모리 |
|
||||
| `themeStore` | 테마 설정 | localStorage |
|
||||
| `useUIStore` | UI 상태 (사이드바 너비 등) | 메모리 |
|
||||
| `useItemMasterStore` | 품목 마스터 폼 상태 | 메모리 |
|
||||
| `favoritesStore` | 즐겨찾기 메뉴 | localStorage |
|
||||
| `useCalendarScheduleStore` | 캘린더 일정 | 메모리 |
|
||||
| `useTableColumnStore` | 테이블 컬럼 설정 (표시/숨김) | localStorage |
|
||||
|
||||
---
|
||||
|
||||
## 6. 라우팅 패턴
|
||||
|
||||
### 페이지 모드 (mode 쿼리파라미터)
|
||||
|
||||
```
|
||||
/sales/order-management → 목록 (기본)
|
||||
/sales/order-management?mode=new → 등록 폼
|
||||
/sales/order-management/123 → 상세 (view)
|
||||
/sales/order-management/123?mode=edit → 수정 폼
|
||||
```
|
||||
|
||||
- 별도 `/new`, `/edit` 경로 사용 금지
|
||||
- 목록과 등록을 같은 page.tsx에서 mode로 분기
|
||||
|
||||
### 페이지 유형
|
||||
|
||||
| 유형 | 컴포넌트 | 특징 |
|
||||
|------|----------|------|
|
||||
| 목록 | `UniversalListPage` | 검색, 페이지네이션, 컬럼 설정, 모바일 카드 |
|
||||
| 상세/폼 | `Card` + `FormField` | sticky 하단 액션 바, 모드별 분기 |
|
||||
| 대시보드 | 섹션 기반 | 모듈별 조건부 렌더링 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 도메인 맵
|
||||
|
||||
### 공통 ERP (모든 테넌트)
|
||||
|
||||
```
|
||||
회계 (accounting/)
|
||||
├── 매출/매입 관리
|
||||
├── 입출금 관리
|
||||
├── 세금계산서
|
||||
├── 거래처 원장
|
||||
├── 경조사비/접대비
|
||||
└── 일보/결산
|
||||
|
||||
영업 (sales/)
|
||||
├── 견적/수주 관리
|
||||
├── 단가 관리
|
||||
├── 생산지시 (공유 API)
|
||||
└── 거래처 관리
|
||||
|
||||
인사 (hr/)
|
||||
├── 직원 관리
|
||||
├── 근태/출결
|
||||
├── 급여/휴가
|
||||
└── 인사 이력
|
||||
|
||||
결재 (approval/)
|
||||
├── 기안/수신/참조
|
||||
└── 결재 양식 관리
|
||||
|
||||
기준정보 (master-data/)
|
||||
├── 품목 마스터
|
||||
├── 공정 관리
|
||||
└── 단가 테이블
|
||||
|
||||
자재/재고 (material/, stocks/)
|
||||
├── 입고 관리
|
||||
├── 재고 현황
|
||||
└── 재고 생산
|
||||
|
||||
출고/배송 (outbound/)
|
||||
├── 출하 관리
|
||||
└── 차량 배차
|
||||
```
|
||||
|
||||
### 경동 전용 (셔터 제조 MES)
|
||||
|
||||
```
|
||||
생산 (production/)
|
||||
├── 작업지시
|
||||
├── 작업실적
|
||||
├── 작업자 화면
|
||||
└── 생산 대시보드
|
||||
|
||||
품질 (quality/)
|
||||
├── 설비 관리/점검/수리
|
||||
├── 검사 관리
|
||||
├── QMS (문서관리)
|
||||
└── 성적서/작업일지
|
||||
```
|
||||
|
||||
### 주일 전용 (건설 시공)
|
||||
|
||||
```
|
||||
건설 (construction/)
|
||||
├── 수주/현장 관리
|
||||
├── 프로젝트 관리
|
||||
│ ├── 계약/실행예산
|
||||
│ ├── 입찰 관리
|
||||
│ ├── 시공 관리
|
||||
│ └── 인력 현황
|
||||
└── 기성 관리
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 데이터 흐름
|
||||
|
||||
```
|
||||
[컴포넌트] → Server Action (또는 fetch /api/proxy/...)
|
||||
│
|
||||
↓
|
||||
[authenticatedFetch]
|
||||
│
|
||||
├── 정상 → 데이터 반환
|
||||
├── 401 → 자동 토큰 갱신 → 재시도
|
||||
└── 실패 → 로그인 페이지 이동
|
||||
|
||||
Server Action 위치: src/components/{domain}/actions.ts
|
||||
URL 빌더: buildApiUrl('/api/v1/path', { search, page })
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 모듈 분리 현황
|
||||
|
||||
코드 아키텍처 레벨에서 공통 ERP와 테넌트 전용 코드의 경계를 관리합니다.
|
||||
|
||||
| 단계 | 상태 | 내용 |
|
||||
|------|------|------|
|
||||
| Phase 0 | 완료 | 공통 -> 테넌트 import 의존성 해소 |
|
||||
| Phase 1 | 완료 | 모듈 레지스트리 + useModules() 훅 |
|
||||
| Phase 2 | 완료 | CEO 대시보드 모듈화 (섹션/API 최적화) |
|
||||
| Phase 3 | 완료 | 검증 스크립트 + 경계 문서 (MODULE.md) |
|
||||
| 화이트리스트 | 완료 | PermissionGate 화이트리스트 전환 |
|
||||
|
||||
### 모듈 경계 규칙
|
||||
|
||||
```
|
||||
허용: 테넌트 → 공통 import (production → ui/)
|
||||
금지: 공통 → 테넌트 import (approval → production/)
|
||||
금지: 테넌트 간 import (production → construction/)
|
||||
|
||||
공유 필요 시: document-system/ 또는 lib/api/ 래퍼 경유
|
||||
```
|
||||
|
||||
검증: `scripts/verify-module-separation.sh`
|
||||
|
||||
---
|
||||
|
||||
## 10. 향후 로드맵
|
||||
|
||||
```
|
||||
v1 (현재) ──── 모듈 분리 완료, 권한 화이트리스트
|
||||
│
|
||||
v2 (진행) ──── 백엔드에서 모듈/페이지 정보 JSON API 제공
|
||||
│ useModules() 내부를 API 호출로 교체
|
||||
│
|
||||
v3 (목표) ──── JSON 스키마 기반 동적 페이지 조립
|
||||
테넌트 추가 = 어드민 설정만 → 코드 변경 0줄
|
||||
```
|
||||
|
||||
상세: [v2/01-dynamic-multi-tenant-page-system.md](../v2/01-dynamic-multi-tenant-page-system.md)
|
||||
|
||||
---
|
||||
|
||||
## 11. 문서 읽기 순서
|
||||
|
||||
### 첫째 날: 전체 구조 파악
|
||||
|
||||
| 순서 | 문서 | 핵심 |
|
||||
|------|------|------|
|
||||
| 1 | 이 문서 (00-onboarding) | 시스템 전체 그림 |
|
||||
| 2 | [01-architecture](01-architecture.md) | 기술 스택, 디렉토리 구조 |
|
||||
| 3 | [07-auth-flow](07-auth-flow.md) | 인증/토큰 흐름 |
|
||||
| 4 | [12-permission-whitelist](12-permission-whitelist.md) | 접근 제어 |
|
||||
|
||||
### 둘째 날: 개발 패턴 익히기
|
||||
|
||||
| 순서 | 문서 | 핵심 |
|
||||
|------|------|------|
|
||||
| 5 | [02-api-pattern](02-api-pattern.md) | API 호출 방법 |
|
||||
| 6 | [03-component-design](03-component-design.md) | 컴포넌트 계층 |
|
||||
| 7 | [04-common-components](04-common-components.md) | UniversalListPage 등 사용법 |
|
||||
| 8 | [05-form-pattern](05-form-pattern.md) | 폼 패턴 (Zod, FormField) |
|
||||
|
||||
### 셋째 날: 세부 규칙
|
||||
|
||||
| 순서 | 문서 | 핵심 |
|
||||
|------|------|------|
|
||||
| 9 | [06-styling-guide](06-styling-guide.md) | Tailwind, 색상 |
|
||||
| 10 | [08-dashboard-system](08-dashboard-system.md) | 대시보드 아키텍처 |
|
||||
| 11 | [09-conventions](09-conventions.md) | 네이밍, Git 규칙 |
|
||||
|
||||
---
|
||||
|
||||
## 12. Git 브랜치 전략
|
||||
|
||||
```
|
||||
main ────── 배포용 (검증된 것만, 기능별 squash merge)
|
||||
│
|
||||
develop ─── 평소 작업 (자유롭게 커밋)
|
||||
│
|
||||
feature/* ─ 큰 기능/실험적 작업 시 사용
|
||||
```
|
||||
|
||||
- develop에서 자유롭게 작업
|
||||
- main에는 기능별 squash merge (cherry-pick + 정리)
|
||||
- main 직접 push 금지
|
||||
|
||||
---
|
||||
|
||||
## 13. 개발 환경 셋업
|
||||
|
||||
```bash
|
||||
# 1. 의존성 설치
|
||||
npm install
|
||||
|
||||
# 2. 환경변수 (.env.local)
|
||||
# 팀원에게 받거나 sam-docs 참고
|
||||
|
||||
# 3. 개발 서버
|
||||
npm run dev
|
||||
|
||||
# 4. 접속
|
||||
http://localhost:3000
|
||||
```
|
||||
|
||||
### 주요 명령어
|
||||
|
||||
| 명령어 | 용도 |
|
||||
|--------|------|
|
||||
| `npm run dev` | 개발 서버 |
|
||||
| `npm run build` | 프로덕션 빌드 |
|
||||
| `npx tsc --noEmit` | 타입 체크 |
|
||||
|
||||
---
|
||||
|
||||
## 14. 자주 하는 실수
|
||||
|
||||
| 실수 | 올바른 방법 |
|
||||
|------|-------------|
|
||||
| Server Component 사용 | `'use client'` 필수 |
|
||||
| localStorage 직접 접근 | `typeof window` 가드 필요 |
|
||||
| API 직접 fetch | Server Action 또는 `/api/proxy/` 사용 |
|
||||
| `/new`, `/edit` 라우트 생성 | `?mode=new`, `?mode=edit` 쿼리 사용 |
|
||||
| `DatePicker` 2개 직접 조합 | `DateRangeSelector` 사용 |
|
||||
| `Label + Input` 수동 조합 | `FormField` molecule 사용 |
|
||||
| 공통에서 테넌트 코드 import | `document-system/` 래퍼 경유 |
|
||||
134
frontend/v1/12-permission-whitelist.md
Normal file
134
frontend/v1/12-permission-whitelist.md
Normal file
@@ -0,0 +1,134 @@
|
||||
# 12. 권한 기반 페이지 접근 제어 (화이트리스트)
|
||||
|
||||
> **대상**: 프론트엔드/백엔드 개발자
|
||||
> **버전**: 1.0.0
|
||||
> **최종 수정**: 2026-03-20
|
||||
|
||||
---
|
||||
|
||||
## 1. 개요
|
||||
|
||||
PermissionGate가 **화이트리스트 방식**으로 동작합니다.
|
||||
메뉴 권한에 등록되지 않은 페이지는 접근이 차단됩니다.
|
||||
|
||||
```
|
||||
메뉴 권한에 있음 + view: true → 허용
|
||||
메뉴 권한에 있음 + view: false → 차단 (AccessDenied)
|
||||
메뉴 권한에 없음 → 차단 (AccessDenied)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 왜 화이트리스트?
|
||||
|
||||
| 방식 | 동작 | 문제 |
|
||||
|------|------|------|
|
||||
| 블랙리스트 (이전) | 권한에 없으면 허용 | 메뉴 미할당 페이지에 URL 직접 접근 가능 |
|
||||
| **화이트리스트 (현재)** | 권한에 없으면 차단 | 메뉴 등록된 페이지만 접근 가능 |
|
||||
|
||||
기존 정책과 일치:
|
||||
```
|
||||
테넌트 생성 → 글로벌 메뉴 동기화 → 역할 생성 → 메뉴 권한 설정 → 접근 가능
|
||||
```
|
||||
|
||||
메뉴 권한이 설정되지 않은 페이지는 접근할 수 없는 것이 정상 동작입니다.
|
||||
|
||||
---
|
||||
|
||||
## 3. 바이패스 경로
|
||||
|
||||
메뉴 권한 없이도 항상 접근 가능한 시스템 페이지:
|
||||
|
||||
| 경로 | 이유 |
|
||||
|------|------|
|
||||
| `/settings/permissions` | 자기 잠금 방지 (권한 설정 페이지) |
|
||||
| `/settings/account-info` | 내 계정 설정 |
|
||||
| `/dashboard` | 대시보드 (모든 유저 필수, `startsWith`로 type2~5 포함) |
|
||||
| `/company-info` | 회사 정보 |
|
||||
| `/subscription` | 구독 관리 |
|
||||
| `/dev`, `/test` | 개발 도구 (개발 환경에서만 활성화) |
|
||||
|
||||
### 바이패스 추가/관리
|
||||
|
||||
파일: `src/contexts/PermissionContext.tsx`
|
||||
|
||||
```typescript
|
||||
const BYPASS_PATHS = [
|
||||
'/settings/permissions',
|
||||
'/settings/account-info',
|
||||
'/dashboard',
|
||||
'/company-info',
|
||||
'/subscription',
|
||||
...(process.env.NODE_ENV === 'development' ? ['/dev', '/test'] : []),
|
||||
];
|
||||
```
|
||||
|
||||
- `startsWith` 매칭: `/dashboard` → `/dashboard_type2`, `/dashboard_type3` 등 모두 포함
|
||||
- 비즈니스 페이지는 바이패스에 추가하지 않음 (권한으로 제어)
|
||||
|
||||
---
|
||||
|
||||
## 4. 접근 제어 흐름
|
||||
|
||||
```
|
||||
유저가 페이지 접근
|
||||
│
|
||||
├─ 권한 로딩 중 → 빈 화면 (로딩)
|
||||
│
|
||||
├─ permissionMap 없음 (로딩 실패) → 통과 (안전장치)
|
||||
│
|
||||
├─ BYPASS_PATHS 매칭 → 통과
|
||||
│
|
||||
└─ findMatchingUrl (longest prefix match)
|
||||
├─ 매칭됨 + view: true → 허용
|
||||
├─ 매칭됨 + view: false → AccessDenied
|
||||
└─ 매칭 없음 → AccessDenied
|
||||
```
|
||||
|
||||
### findMatchingUrl 동작
|
||||
|
||||
```
|
||||
접근: /accounting/deposits/123
|
||||
permissionMap: { "/accounting/deposits": { view: true, ... } }
|
||||
|
||||
1. 정확히 매칭: /accounting/deposits/123 → 없음
|
||||
2. Prefix 매칭: /accounting/deposits → 있음! → view 확인
|
||||
```
|
||||
|
||||
상위 경로에 권한이 있으면 하위 경로도 접근 가능합니다.
|
||||
|
||||
---
|
||||
|
||||
## 5. 프론트엔드 개발자 체크리스트
|
||||
|
||||
| 항목 | 설명 |
|
||||
|------|------|
|
||||
| 새 페이지 추가 시 | 백엔드 메뉴 등록 필수 (미등록 = 접근 불가) |
|
||||
| 시스템 페이지 추가 시 | BYPASS_PATHS에 추가 검토 |
|
||||
| 개발 중 접근 차단 시 | 해당 메뉴의 권한 설정 확인 |
|
||||
| 테넌트별 접근 제어 | 메뉴 권한으로 제어 (프론트 코드 변경 불필요) |
|
||||
|
||||
---
|
||||
|
||||
## 6. 백엔드 개발자 참고
|
||||
|
||||
| 항목 | 설명 |
|
||||
|------|------|
|
||||
| 새 메뉴 추가 시 | 글로벌 메뉴 등록 → 테넌트 동기화 → 역할별 권한 설정 |
|
||||
| 테넌트별 페이지 차단 | 해당 테넌트에 메뉴 미할당 또는 view: false |
|
||||
| industry 기반 프리셋 (향후) | 테넌트 생성 시 업종별 메뉴 프리셋 자동 적용 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 모듈 시스템과의 역할 분담
|
||||
|
||||
| 역할 | PermissionGate | 모듈 시스템 (useModules) |
|
||||
|------|---|---|
|
||||
| 페이지 접근 차단 | O | X (제거 검토) |
|
||||
| 메뉴 표시/숨김 | O (백엔드 메뉴 응답) | X |
|
||||
| 대시보드 섹션 ON/OFF | X | O |
|
||||
| 대시보드 API 호출 최적화 | X | O |
|
||||
| JSON 동적 페이지 초석 | X | O |
|
||||
|
||||
- **PermissionGate**: 접근 제어 ("누가 어디에 들어갈 수 있는가")
|
||||
- **모듈 시스템**: 화면 구성 ("들어간 페이지에 뭘 보여줄 것인가")
|
||||
@@ -1,11 +1,16 @@
|
||||
# 동적 멀티테넌트 페이지 시스템 설계
|
||||
|
||||
> 작성일: 2026-03-11
|
||||
> 상태: 초안 (백엔드 논의 필요)
|
||||
> 최종 업데이트: 2026-03-20
|
||||
> 상태: 초안 (백엔드 논의 진행 중)
|
||||
> 관련 문서:
|
||||
> - `[VISION-2026-02-19] dynamic-rendering-platform-strategy.md`
|
||||
> - `[PLAN-2026-02-06] multi-tenancy-optimization-roadmap.md`
|
||||
> - `[DESIGN-2026-02-11] dynamic-field-type-extension.md`
|
||||
> - `[ANALYSIS-2026-03-17] tenant-module-separation-dependency-audit.md`
|
||||
> - `[PLAN-2026-03-17] tenant-module-separation-plan.md` — Phase 0~3 실행 계획
|
||||
> - `[IMPL-2026-03-20] permission-whitelist-gate.md` — PermissionGate 화이트리스트 전환
|
||||
> - `sam-docs/frontend/v1/12-permission-whitelist.md` — 권한 기반 접근 제어 가이드
|
||||
|
||||
---
|
||||
|
||||
@@ -761,9 +766,61 @@ DynamicItemForm의 ComputedField → computed 타입으로 범용화
|
||||
|
||||
### 규칙 17: 점진적 마이그레이션 전략
|
||||
|
||||
#### 17-1. 3단계 아키텍처 방향 (2026-03-17 확인)
|
||||
|
||||
```
|
||||
1단계: 현재 → 모듈 분리
|
||||
- 공통 ERP / 테넌트별 모듈 물리적 분리
|
||||
- 선결과제 해소 (아래 17-2 참조)
|
||||
|
||||
2단계: 모듈 분리 → JSON 동적 조립
|
||||
- 테넌트 모듈을 manifest/JSON 기반으로 전환
|
||||
- 동적 페이지 렌더러 도입
|
||||
|
||||
3단계: 최종 — 빈 페이지 셸 + 백엔드 JSON으로 페이지 자동 조립
|
||||
- 이 문서의 최종 목표
|
||||
```
|
||||
|
||||
#### 17-2. 선결과제 (모듈 분리 전 해결 필수)
|
||||
|
||||
| # | 과제 | 내용 | 예상 |
|
||||
|---|------|------|------|
|
||||
| 1 | CEO 대시보드 테넌트 의존성 해소 | 생산/건설 섹션 직접 import → 동적 로딩 전환 | - |
|
||||
| 2 | 공유 컴포넌트 추출 | 결재/영업(공통)이 생산(경동) 코드 직접 import | - |
|
||||
| 3 | 라우트 가드 추가 | 테넌트 미보유 모듈 URL 직접 접근 차단 | - |
|
||||
| 4 | dashboard-invalidation 동적화 | production/construction 도메인 키 하드코딩 제거 | - |
|
||||
|
||||
> 선결과제 해소 예상: 3~4일, 이후 모듈 분리 본작업은 별도 산정
|
||||
|
||||
**핵심 의존성 위반 (공통 → 테넌트 방향, 수정 필요)**:
|
||||
```
|
||||
ApprovalBox → production/InspectionReportModal
|
||||
Sales/production-orders → production/ProductionOrders (actions+types+UI)
|
||||
Sales → router.push("/production/work-orders") 하드코딩
|
||||
CEODashboard → DailyProductionSection, ConstructionSection 직접 import
|
||||
dashboard-invalidation.ts → production/construction 도메인 키
|
||||
```
|
||||
|
||||
**안전한 부분**:
|
||||
- 테넌트 간 교차 의존성 없음 (생산↔건설 = 0)
|
||||
- 건설(주일) 모듈 완전 독립 → 바로 분리 가능
|
||||
- Zustand 스토어, API 프록시, 메뉴 시스템은 무관
|
||||
|
||||
#### 17-3. 테넌트별 페이지 현황 (2026-03-17 분석)
|
||||
|
||||
| 테넌트 | 업종 | 전용 모듈 | 페이지 수 |
|
||||
|--------|------|----------|:---:|
|
||||
| 공통 ERP | 전 업종 | 회계, 인사, 결재, 게시판, 설정, 고객센터 등 | ~165 |
|
||||
| 경동 | 셔터 제조 (MES) | 생산, 품질관리 | ~27 |
|
||||
| 주일 | 건설 시공 | 건설/프로젝트, 입찰, 기성 | ~48 |
|
||||
| (옵션) | - | 차량관리 | ~13 |
|
||||
|
||||
#### 17-4. 마이그레이션 Phase
|
||||
|
||||
| Phase | 범위 | 예상 기간 | 상태 |
|
||||
|-------|------|----------|------|
|
||||
| **Phase 0** | 인프라 구축 | 2-3주 | ⏳ 준비 |
|
||||
| **선결과제** | 의존성 해소 (17-2) | 3-4일 | ⏳ 준비 |
|
||||
| **Phase 0** | 인프라 구축 | 2-3주 | ⏳ |
|
||||
| | - catch-all 라우터 | | |
|
||||
| | - pageConfigStore | | |
|
||||
| | - DynamicListPage/FormPage 렌더러 | | |
|
||||
@@ -776,13 +833,13 @@ DynamicItemForm의 ComputedField → computed 타입으로 범용화
|
||||
| | - 거래처관리, 설비관리 등 | | |
|
||||
| **Phase 3** | 복잡한 비즈니스 페이지 전환 | 6-8주 | ⏳ |
|
||||
| | - 견적, 수주, 생산 등 로직 있는 페이지 | | |
|
||||
| | - 로직 블록 구축 병행 | | |
|
||||
| **Phase 4** | 기존 정적 → 동적 완전 전환 | 지속적 | ⏳ |
|
||||
| | - 남은 하드코딩 페이지 점진적 전환 | | |
|
||||
|
||||
```
|
||||
전환 판단 기준:
|
||||
|
||||
[선행] 선결과제 해소 (의존성 분리) → 선결과제 Phase
|
||||
[쉬움] 순수 CRUD (리스트+폼) → Phase 2에서 전환
|
||||
[보통] CRUD + 단순 계산 → Phase 2~3
|
||||
[어려움] 복잡한 비즈니스 로직 → Phase 3
|
||||
@@ -886,9 +943,10 @@ DynamicItemForm의 ComputedField → computed 타입으로 범용화
|
||||
| 동적 필드 타입 설계 | `claudedocs/architecture/[DESIGN-2026-02-11]` | 4-Level 구조, 14종 필드 |
|
||||
| 동적 필드 구현 현황 | `claudedocs/architecture/[IMPL-2026-02-11]` | Phase 1~3 프론트 구현 완료 |
|
||||
| 백엔드 API 스펙 | `claudedocs/item-master/[API-REQUEST-2026-02-12]` | 동적 필드 타입 백엔드 요청서 |
|
||||
| 테넌트 모듈 의존성 분석 | `claudedocs/architecture/[ANALYSIS-2026-03-17]` | 3테넌트 분리, 선결과제 4개, 의존성 위반 목록 |
|
||||
|
||||
---
|
||||
|
||||
**문서 버전**: 1.2
|
||||
**마지막 업데이트**: 2026-03-11
|
||||
**문서 버전**: 1.3
|
||||
**마지막 업데이트**: 2026-03-18
|
||||
**다음 단계**: 백엔드 회의 → 협의 필요 항목 확정 → v2.0 작성 → `sam-docs/frontend/v2/`에 최종본 등록
|
||||
|
||||
Reference in New Issue
Block a user