diff --git a/docs/화면관리_시스템_설계.md b/docs/화면관리_시스템_설계.md
index d39421a8..69b96058 100644
--- a/docs/화면관리_시스템_설계.md
+++ b/docs/화면관리_시스템_설계.md
@@ -19,15 +19,16 @@
### 화면관리 시스템이란?
-화면관리 시스템은 실제 서비스되는 화면을 드래그앤드롭으로 설계하고 관리할 수 있는 시스템입니다. 테이블 타입관리와 연계하여 각 필드가 웹에서 어떻게 표시될지를 정의하고, 사용자가 직관적으로 화면을 구성할 수 있습니다.
+화면관리 시스템은 사용자가 속한 회사에 맞춰 화면을 드래그앤드롭으로 설계하고 관리할 수 있는 시스템입니다. 테이블 타입관리와 연계하여 각 필드가 웹에서 어떻게 표시될지를 정의하고, 사용자가 직관적으로 화면을 구성할 수 있습니다.
### 주요 특징
+- **회사별 화면 관리**: 사용자 회사 코드에 따른 화면 접근 제어
- **드래그앤드롭 인터페이스**: 직관적인 화면 설계
+- **컨테이너 그룹화**: 컴포넌트를 깔끔하게 정렬하는 그룹 기능
- **테이블 타입 연계**: 컬럼의 웹 타입에 따른 자동 위젯 생성
-- **실시간 미리보기**: 설계한 화면을 즉시 확인 가능
-- **반응형 디자인**: 다양한 화면 크기에 대응
-- **템플릿 시스템**: 재사용 가능한 화면 템플릿 제공
+- **실시간 미리보기**: 설계한 화면을 실제 화면과 동일하게 확인 가능
+- **메뉴 연동**: 각 회사의 메뉴에 화면 할당 및 관리
### 🎯 **현재 테이블 구조와 100% 호환**
@@ -42,6 +43,15 @@
**별도의 테이블 구조 변경 없이 바로 개발 가능!** 🚀
+### 🏢 **회사별 화면 관리 시스템**
+
+**사용자 권한에 따른 화면 접근 제어:**
+
+- ✅ **일반 사용자**: 자신이 속한 회사의 화면만 제작/수정 가능
+- ✅ **관리자 (회사코드 '\*')**: 모든 회사의 화면을 제어 가능
+- ✅ **회사별 메뉴 할당**: 각 회사의 메뉴에만 화면 할당 가능
+- ✅ **권한 격리**: 회사 간 화면 데이터 완전 분리
+
### 지원하는 웹 타입
테이블 타입관리에서 각 컬럼별로 설정할 수 있는 웹 타입입니다:
@@ -118,6 +128,25 @@
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
+### 회사별 권한 관리 구조
+
+```
+┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
+│ 사용자 │ │ 권한 검증 │ │ 화면 데이터 │
+│ │ │ │ │ │
+│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
+│ │ 회사코드 │ │───▶│ │ 권한 검증 │ │───▶│ │ 회사별 │ │
+│ │ (company_ │ │ │ │ 미들웨어 │ │ │ │ 화면 │ │
+│ │ code) │ │ │ │ │ │ │ │ 격리 │ │
+│ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │
+│ │ │ │ │ │
+│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
+│ │ 권한 레벨 │ │ │ │ 회사별 │ │ │ │ 메뉴 할당 │ │
+│ │ (admin: '*')│ │ │ │ 데이터 │ │ │ │ 제한 │ │
+│ └─────────────┘ │ │ │ 필터링 │ │ │ └─────────────┘ │
+└─────────────────┘ └─────────────────┘ └─────────────────┘
+```
+
### 데이터 흐름
1. **테이블 타입 정의**: 테이블 타입관리에서 컬럼의 웹 타입 설정
@@ -132,28 +161,42 @@
- **드래그앤드롭 인터페이스**: 컴포넌트를 캔버스에 배치
- **그리드 시스템**: 12컬럼 그리드 기반 레이아웃
-- **반응형 설정**: 화면 크기별 레이아웃 조정
-- **실시간 미리보기**: 설계한 화면을 즉시 확인
+- **컨테이너 그룹화**: 컴포넌트를 깔끔하게 정렬하는 그룹 기능
+- **실시간 미리보기**: 설계한 화면을 실제 화면과 동일하게 확인
### 2. 컴포넌트 라이브러리
- **입력 컴포넌트**: text, number, date, textarea 등
- **선택 컴포넌트**: select, checkbox, radio 등
- **표시 컴포넌트**: label, display, image 등
-- **레이아웃 컴포넌트**: container, row, column 등
+- **레이아웃 컴포넌트**: container, row, column, group 등
+- **컨테이너 컴포넌트**: 컴포넌트들을 그룹으로 묶는 기능
-### 3. 테이블 연계 시스템
+### 3. 회사별 권한 관리
+
+- **회사 코드 기반 접근 제어**: 사용자 회사 코드에 따른 화면 접근
+- **관리자 권한**: 회사 코드 '\*'인 사용자는 모든 회사 화면 제어
+- **회사별 메뉴 할당**: 각 회사의 메뉴에만 화면 할당 가능
+- **데이터 격리**: 회사 간 화면 데이터 완전 분리
+
+### 4. 테이블 연계 시스템
- **자동 위젯 생성**: 컬럼의 웹 타입에 따른 위젯 자동 생성
- **데이터 바인딩**: 컬럼과 위젯의 자동 연결
- **유효성 검증**: 컬럼 설정에 따른 자동 검증 규칙 적용
-### 4. 템플릿 시스템
+### 5. 템플릿 시스템
- **기본 템플릿**: CRUD, 목록, 상세 등 기본 패턴
- **사용자 정의 템플릿**: 자주 사용하는 레이아웃 저장
- **템플릿 공유**: 팀원 간 템플릿 공유 및 재사용
+### 6. 메뉴 연동 시스템
+
+- **회사별 메뉴 할당**: 각 회사의 메뉴에만 화면 할당
+- **메뉴-화면 연결**: 메뉴와 화면의 1:1 또는 1:N 연결
+- **권한 기반 메뉴 표시**: 사용자 권한에 따른 메뉴 표시 제어
+
## 🗄️ 데이터베이스 설계
### 1. 기존 테이블 구조 (테이블 타입관리)
@@ -221,6 +264,7 @@ CREATE TABLE screen_definitions (
screen_name VARCHAR(100) NOT NULL,
screen_code VARCHAR(50) UNIQUE NOT NULL,
table_name VARCHAR(100) NOT NULL, -- 🎯 table_labels와 연계
+ company_code VARCHAR(50) NOT NULL, -- 🎯 회사 코드 (권한 관리용)
description TEXT,
is_active CHAR(1) DEFAULT 'Y',
created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
@@ -232,6 +276,9 @@ CREATE TABLE screen_definitions (
CONSTRAINT fk_screen_definitions_table_name
FOREIGN KEY (table_name) REFERENCES table_labels(table_name)
);
+
+-- 회사 코드 인덱스 추가
+CREATE INDEX idx_screen_definitions_company_code ON screen_definitions(company_code);
```
#### screen_layouts (화면 레이아웃)
@@ -283,12 +330,43 @@ CREATE TABLE screen_templates (
template_id SERIAL PRIMARY KEY,
template_name VARCHAR(100) NOT NULL,
template_type VARCHAR(50) NOT NULL, -- CRUD, LIST, DETAIL 등
+ company_code VARCHAR(50) NOT NULL, -- 🎯 회사 코드 (권한 관리용)
description TEXT,
layout_data JSONB, -- 레이아웃 데이터
is_public BOOLEAN DEFAULT FALSE, -- 공개 여부
created_by VARCHAR(50),
created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
+
+-- 회사 코드 인덱스 추가
+CREATE INDEX idx_screen_templates_company_code ON screen_templates(company_code);
+```
+
+#### screen_menu_assignments (화면-메뉴 할당)
+
+```sql
+CREATE TABLE screen_menu_assignments (
+ assignment_id SERIAL PRIMARY KEY,
+ screen_id INTEGER NOT NULL,
+ menu_id INTEGER NOT NULL,
+ company_code VARCHAR(50) NOT NULL, -- 🎯 회사 코드 (권한 관리용)
+ display_order INTEGER DEFAULT 0,
+ is_active CHAR(1) DEFAULT 'Y',
+ created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ created_by VARCHAR(50),
+
+ -- 외래키 제약조건
+ CONSTRAINT fk_screen_menu_assignments_screen_id
+ FOREIGN KEY (screen_id) REFERENCES screen_definitions(screen_id),
+ CONSTRAINT fk_screen_menu_assignments_menu_id
+ FOREIGN KEY (menu_id) REFERENCES menu_info(menu_id),
+
+ -- 유니크 제약조건 (한 메뉴에 같은 화면 중복 할당 방지)
+ CONSTRAINT uk_screen_menu_company UNIQUE (screen_id, menu_id, company_code)
+);
+
+-- 회사 코드 인덱스 추가
+CREATE INDEX idx_screen_menu_assignments_company_code ON screen_menu_assignments(company_code);
```
### 3. 테이블 간 연계 관계
@@ -303,6 +381,8 @@ screen_definitions (화면 정의)
screen_layouts (화면 레이아웃)
↓ (1:N)
screen_widgets (화면 위젯)
+ ↓ (1:N)
+screen_menu_assignments (화면-메뉴 할당)
```
**핵심 연계 포인트:**
@@ -310,6 +390,8 @@ screen_widgets (화면 위젯)
- ✅ `screen_definitions.table_name` ↔ `table_labels.table_name`
- ✅ `screen_widgets.table_name, column_name` ↔ `column_labels.table_name, column_name`
- ✅ `screen_widgets.widget_type` ↔ `column_labels.web_type` (자동 동기화)
+- ✅ `screen_definitions.company_code` ↔ 사용자 회사 코드 (권한 관리)
+- ✅ `screen_menu_assignments.company_code` ↔ 메뉴 회사 코드 (메뉴 할당 제한)
## 🎨 화면 구성 요소
@@ -327,6 +409,29 @@ interface ContainerProps {
margin: number;
backgroundColor?: string;
border?: string;
+ borderRadius?: number;
+ shadow?: string;
+}
+```
+
+#### Group (그룹)
+
+```typescript
+interface GroupProps {
+ id: string;
+ type: "group";
+ title?: string;
+ width: number; // 1-12
+ height: number;
+ padding: number;
+ margin: number;
+ backgroundColor?: string;
+ border?: string;
+ borderRadius?: number;
+ shadow?: string;
+ collapsible?: boolean; // 접을 수 있는 그룹
+ collapsed?: boolean; // 접힌 상태
+ children: string[]; // 포함된 컴포넌트 ID 목록
}
```
@@ -440,16 +545,27 @@ interface DragState {
draggedItem: ComponentData | null;
dragSource: "toolbox" | "canvas";
dropTarget: string | null;
+ dropZone?: DropZone; // 드롭 가능한 영역 정보
}
+// 그룹화 상태 관리
+interface GroupState {
+ isGrouping: boolean;
+ selectedComponents: string[];
+ groupTarget: string | null;
+ groupMode: "create" | "add" | "remove";
+}
+```
+
// 드롭 영역 정의
interface DropZone {
- id: string;
- accepts: string[]; // 허용되는 컴포넌트 타입
- position: { x: number; y: number };
- size: { width: number; height: number };
+id: string;
+accepts: string[]; // 허용되는 컴포넌트 타입
+position: { x: number; y: number };
+size: { width: number; height: number };
}
-```
+
+````
### 2. 컴포넌트 배치 로직
@@ -478,7 +594,7 @@ function resizeComponent(
height: Math.max(50, newHeight),
};
}
-```
+````
### 3. 실시간 미리보기
@@ -492,21 +608,40 @@ function generatePreview(layout: LayoutData): React.ReactElement {
);
}
-// 컴포넌트 렌더링
-function renderComponent(component: ComponentData): React.ReactElement {
- switch (component.type) {
- case "text":
- return ;
- case "select":
- return ;
- case "date":
- return ;
- default:
- return
+ );
+}
+
// GridItem.tsx
interface GridItemProps {
width: number; // 1-12
@@ -1080,15 +1370,22 @@ export default function GridItem({
```typescript
// screenManagementService.ts
export class ScreenManagementService {
- // 화면 정의 생성
+ // 화면 정의 생성 (회사별)
async createScreen(
- screenData: CreateScreenRequest
+ screenData: CreateScreenRequest,
+ userCompanyCode: string
): Promise {
+ // 권한 검증: 사용자 회사 코드 확인
+ if (userCompanyCode !== "*" && userCompanyCode !== screenData.companyCode) {
+ throw new Error("해당 회사의 화면을 생성할 권한이 없습니다.");
+ }
+
const screen = await prisma.screen_definitions.create({
data: {
screen_name: screenData.screenName,
screen_code: screenData.screenCode,
table_name: screenData.tableName,
+ company_code: screenData.companyCode,
description: screenData.description,
created_by: screenData.createdBy,
},
@@ -1097,6 +1394,30 @@ export class ScreenManagementService {
return this.mapToScreenDefinition(screen);
}
+ // 회사별 화면 목록 조회
+ async getScreensByCompany(
+ companyCode: string,
+ page: number = 1,
+ size: number = 20
+ ): Promise<{ screens: ScreenDefinition[]; total: number }> {
+ const whereClause = companyCode === "*" ? {} : { company_code: companyCode };
+
+ const [screens, total] = await Promise.all([
+ prisma.screen_definitions.findMany({
+ where: whereClause,
+ skip: (page - 1) * size,
+ take: size,
+ orderBy: { created_date: "desc" },
+ }),
+ prisma.screen_definitions.count({ where: whereClause }),
+ ]);
+
+ return {
+ screens: screens.map(this.mapToScreenDefinition),
+ total,
+ };
+
+
// 레이아웃 저장
async saveLayout(screenId: number, layoutData: LayoutData): Promise {
// 기존 레이아웃 삭제
@@ -1449,7 +1770,23 @@ export class TableTypeIntegrationService {
## 🎬 사용 시나리오
-### 1. 웹 타입 설정 (테이블 타입관리)
+### 1. 회사별 화면 관리
+
+#### 일반 사용자 (회사 코드: 'COMP001')
+
+1. **로그인**: 자신의 회사 코드로 시스템 로그인
+2. **화면 목록 조회**: 자신이 속한 회사의 화면만 표시
+3. **화면 생성**: 회사 코드가 자동으로 설정되어 생성
+4. **메뉴 할당**: 자신의 회사 메뉴에만 화면 할당 가능
+
+#### 관리자 (회사 코드: '\*')
+
+1. **로그인**: 관리자 권한으로 시스템 로그인
+2. **전체 화면 조회**: 모든 회사의 화면을 조회/수정 가능
+3. **회사별 화면 관리**: 각 회사별로 화면 생성/수정/삭제
+4. **크로스 회사 메뉴 할당**: 모든 회사의 메뉴에 화면 할당 가능
+
+### 2. 웹 타입 설정 (테이블 타입관리)
1. **테이블 선택**: 테이블 타입관리에서 웹 타입을 설정할 테이블 선택
2. **컬럼 관리**: 해당 테이블의 컬럼 목록에서 웹 타입을 설정할 컬럼 선택
@@ -1462,38 +1799,48 @@ export class TableTypeIntegrationService {
5. **저장**: 웹 타입 설정을 데이터베이스에 저장
6. **연계 확인**: 화면관리 시스템에서 자동 위젯 생성 확인
-### 2. 새로운 화면 설계
+### 3. 새로운 화면 설계
1. **테이블 선택**: 테이블 타입관리에서 설계할 테이블 선택
2. **웹 타입 확인**: 각 컬럼의 웹 타입 설정 상태 확인
-3. **화면 생성**: 화면명과 코드를 입력하여 새 화면 생성
+3. **화면 생성**: 화면명과 코드를 입력하여 새 화면 생성 (회사 코드 자동 설정)
4. **자동 위젯 생성**: 컬럼의 웹 타입에 따라 자동으로 위젯 생성
5. **컴포넌트 배치**: 드래그앤드롭으로 컴포넌트를 캔버스에 배치
-6. **속성 설정**: 각 컴포넌트의 속성을 Properties 패널에서 설정
-7. **미리보기**: 실시간으로 설계한 화면 확인
-8. **저장**: 완성된 화면 레이아웃을 데이터베이스에 저장
+6. **컨테이너 그룹화**: 관련 컴포넌트들을 그룹으로 묶어 깔끔하게 정렬
+7. **속성 설정**: 각 컴포넌트의 속성을 Properties 패널에서 설정
+8. **실시간 미리보기**: 설계한 화면을 실제 화면과 동일하게 확인
+9. **저장**: 완성된 화면 레이아웃을 데이터베이스에 저장
-### 2. 기존 화면 수정
+### 4. 기존 화면 수정
-1. **화면 선택**: 수정할 화면을 목록에서 선택
+1. **화면 선택**: 수정할 화면을 목록에서 선택 (권한 확인)
2. **레이아웃 로드**: 기존 레이아웃을 캔버스에 로드
3. **컴포넌트 수정**: 컴포넌트 추가/삭제/이동/수정
-4. **속성 변경**: 컴포넌트 속성 변경
-5. **변경사항 확인**: 미리보기로 변경사항 확인
-6. **저장**: 수정된 레이아웃 저장
+4. **그룹 구조 조정**: 컴포넌트 그룹화/그룹 해제/그룹 속성 변경
+5. **속성 변경**: 컴포넌트 속성 변경
+6. **변경사항 확인**: 실시간 미리보기로 변경사항 확인
+7. **저장**: 수정된 레이아웃 저장
-### 3. 템플릿 활용
+### 5. 템플릿 활용
-1. **템플릿 선택**: 적합한 템플릿을 목록에서 선택
+1. **템플릿 선택**: 적합한 템플릿을 목록에서 선택 (회사별 템플릿)
2. **템플릿 적용**: 선택한 템플릿을 현재 화면에 적용
3. **커스터마이징**: 템플릿을 기반으로 필요한 부분 수정
4. **저장**: 커스터마이징된 화면 저장
-### 4. 화면 배포
+### 6. 메뉴 할당 및 관리
+
+1. **메뉴 선택**: 화면을 할당할 메뉴 선택 (회사별 메뉴만 표시)
+2. **화면 할당**: 선택한 화면을 메뉴에 할당
+3. **할당 순서 조정**: 메뉴 내 화면 표시 순서 조정
+4. **할당 해제**: 메뉴에서 화면 할당 해제
+5. **권한 확인**: 메뉴 할당 시 회사 코드 일치 여부 확인
+
+### 7. 화면 배포
1. **화면 활성화**: 설계 완료된 화면을 활성 상태로 변경
-2. **권한 설정**: 화면 접근 권한 설정
-3. **메뉴 연결**: 메뉴 시스템에 화면 연결
+2. **권한 설정**: 화면 접근 권한 설정 (회사별 권한)
+3. **메뉴 연결**: 메뉴 시스템에 화면 연결 (회사별 메뉴)
4. **테스트**: 실제 환경에서 화면 동작 테스트
5. **배포**: 운영 환경에 화면 배포
@@ -1545,6 +1892,25 @@ export class TableTypeIntegrationService {
## 🎯 결론
-화면관리 시스템은 테이블 타입관리와 연계하여 사용자가 직관적으로 웹 화면을 설계할 수 있는 강력한 도구입니다. 드래그앤드롭 인터페이스와 자동 위젯 생성 기능을 통해 개발자가 아닌 사용자도 전문적인 웹 화면을 쉽게 구성할 수 있습니다.
+화면관리 시스템은 **회사별 권한 관리**와 **테이블 타입관리 연계**를 통해 사용자가 직관적으로 웹 화면을 설계할 수 있는 강력한 도구입니다.
-이 시스템을 통해 ERP 시스템의 화면 개발 생산성을 크게 향상시키고, 사용자 요구사항에 따른 빠른 화면 구성이 가능해질 것입니다.
+### 🏢 **회사별 화면 관리의 핵심 가치**
+
+- **권한 격리**: 사용자는 자신이 속한 회사의 화면만 제작/수정 가능
+- **관리자 통제**: 회사 코드 '\*'인 관리자는 모든 회사의 화면을 제어
+- **메뉴 연동**: 각 회사의 메뉴에만 화면 할당하여 완벽한 데이터 분리
+
+### 🎨 **향상된 사용자 경험**
+
+- **드래그앤드롭 인터페이스**: 직관적인 화면 설계
+- **컨테이너 그룹화**: 컴포넌트를 깔끔하게 정렬하는 그룹 기능
+- **실시간 미리보기**: 설계한 화면을 실제 화면과 동일하게 확인
+- **자동 위젯 생성**: 컬럼의 웹 타입에 따른 스마트한 위젯 생성
+
+### 🚀 **기술적 혜택**
+
+- **기존 테이블 구조 100% 호환**: 별도 스키마 변경 없이 바로 개발 가능
+- **권한 기반 보안**: 회사 간 데이터 완전 격리
+- **확장 가능한 아키텍처**: 새로운 웹 타입과 컴포넌트 쉽게 추가
+
+이 시스템을 통해 ERP 시스템의 화면 개발 생산성을 크게 향상시키고, **회사별 맞춤형 화면 구성**과 **사용자 요구사항에 따른 빠른 화면 구성**이 가능해질 것입니다.