docs: [frontend] 동적 멀티테넌트 페이지 시스템 JSONB 저장 방식 확정

- JSONB vs JSON 비교 및 채택 근거 추가
- DB 테이블 구조 제안 (page_configs)
- JSONB가 config 설계에 미치는 영향 정리
- 백엔드 협의 필요 사항 업데이트
- 문서 버전 1.1 → 1.2
This commit is contained in:
유병철
2026-03-11 22:33:24 +09:00
parent f4620889da
commit 65b6a27479

View File

@@ -179,6 +179,61 @@ After: 백엔드 어드민 UI → 직접 DB 저장 → API로 config 전달
> ⚠️ **백엔드 논의 필요**: JSON 구조의 세부 스펙 확정
#### 2-2. 백엔드 저장 방식: JSONB (확정)
> ✅ **확정**: 페이지 config는 PostgreSQL **JSONB** 타입으로 저장
| 항목 | JSON | JSONB (채택) |
|------|------|:---:|
| 저장 형태 | 텍스트 그대로 | 바이너리 (파싱된 형태) |
| 읽기 속도 | 매번 파싱 필요 | 이미 파싱됨 → **빠름** |
| 인덱싱 | ❌ 불가 | ✅ **GIN 인덱스 가능** |
| 내부 검색 | ❌ 전체 꺼내서 비교 | ✅ **특정 키/값으로 쿼리** |
| 부분 수정 | ❌ 전체 교체 | ✅ **특정 키만 업데이트** |
**JSONB가 필요한 이유 — 우리 시스템과의 연관**:
```sql
-- 1. 테넌트별 특정 타입 페이지만 조회 (인덱싱)
SELECT * FROM page_configs
WHERE tenant_id = 282
AND config->>'pageType' = 'list';
-- 2. 특정 필드 타입을 쓰는 페이지 검색 (내부 검색)
SELECT * FROM page_configs
WHERE config @> '{"layout":{"sections":[{"fields":[{"type":"reference"}]}]}}';
-- 3. 기준관리에서 섹션 하나만 수정 (부분 수정)
UPDATE page_configs
SET config = jsonb_set(config, '{layout,sections,0,title}', '"수정된 섹션명"');
```
**JSONB 채택이 config 구조 설계에 미치는 영향**:
| 영향 | 설명 |
|------|------|
| **구조 단순화** | 하나의 큰 JSONB에 전체 config를 담아도 부분 쿼리/수정 가능 → 테이블 분리 최소화 |
| **테넌트 분기** | JSONB 인덱스로 테넌트+pageType 조합 쿼리가 빠름 → 별도 테이블 불필요 |
| **기준관리 UI** | 섹션 하나만 수정해도 전체 config를 다시 저장할 필요 없음 → UX 향상 |
| **프론트 영향** | **없음** — 프론트는 동일한 JSON을 받아서 렌더링, 저장 방식 무관 |
```
DB 테이블 구조 (제안):
page_configs
├── id (PK)
├── tenant_id (FK, 인덱스)
├── slug (UNIQUE per tenant, 인덱스)
├── config (JSONB) ← 페이지 config 전체
├── created_at
└── updated_at
GIN 인덱스: config에 대해 생성 → 내부 검색 고속화
복합 인덱스: (tenant_id, slug) → 테넌트별 페이지 조회 최적화
```
> ⚠️ **백엔드 논의 필요**: JSONB 기반 테이블 설계 세부 확정 (위 제안 구조 검토)
---
### 규칙 3: 정적 페이지 vs 동적 페이지 분류
@@ -762,6 +817,7 @@ DynamicItemForm의 ComputedField → computed 타입으로 범용화
| 복잡한 계산 수식 | 백엔드에서 전부 처리, 결과만 전달 | 프론트는 단순 사칙연산만 |
| 권한 관리 호환성 | 현재 권한 시스템으로 동적 페이지 컨트롤 가능 | 메뉴 ID + URL 패턴 매칭 방식 |
| 기존 동적 필드 재사용 | DynamicFieldRenderer 14종 등 90%+ 재사용 가능 | 기준관리 UI가 mng로 이동해도 렌더링 컴포넌트 유지 |
| DB 저장 방식 | PostgreSQL **JSONB** 사용 | 인덱싱/부분수정/내부검색 가능, 프론트 영향 없음 |
### 협의 필요 사항
@@ -833,6 +889,6 @@ DynamicItemForm의 ComputedField → computed 타입으로 범용화
---
**문서 버전**: 1.1
**문서 버전**: 1.2
**마지막 업데이트**: 2026-03-11
**다음 단계**: 백엔드 회의 → 협의 필요 항목 확정 → v2.0 작성 → `sam-docs/frontend/v2/`에 최종본 등록