# 리포트 페이지 관리 시스템 설계 ## 1. 개요 리포트 디자이너에 다중 페이지 관리 기능을 추가하여 여러 페이지에 걸친 복잡한 문서를 작성할 수 있도록 합니다. ## 2. 주요 기능 ### 2.1 페이지 관리 - 페이지 추가/삭제 - 페이지 복사 - 페이지 순서 변경 (드래그 앤 드롭) - 페이지 이름 지정 ### 2.2 페이지 네비게이션 - 좌측 페이지 썸네일 패널 - 페이지 간 전환 (클릭) - 이전/다음 페이지 이동 - 페이지 번호 표시 ### 2.3 페이지별 설정 - 페이지 크기 (A4, A3, Letter, 사용자 정의) - 페이지 방향 (세로/가로) - 여백 설정 - 배경색 ### 2.4 컴포넌트 관리 - 컴포넌트는 특정 페이지에 속함 - 페이지 간 컴포넌트 복사/이동 - 현재 페이지의 컴포넌트만 표시 ## 3. 데이터베이스 스키마 ### 3.1 기존 구조 활용 (변경 없음) **report_layout 테이블의 layout_config (JSONB) 활용** 기존: ```json { "width": 210, "height": 297, "orientation": "portrait", "components": [...] } ``` 변경 후: ```json { "pages": [ { "page_id": "page-uuid-1", "page_name": "표지", "page_order": 0, "width": 210, "height": 297, "orientation": "portrait", "margins": { "top": 20, "bottom": 20, "left": 20, "right": 20 }, "background_color": "#ffffff", "components": [ { "id": "comp-1", "type": "text", "x": 100, "y": 50, ... } ] }, { "page_id": "page-uuid-2", "page_name": "본문", "page_order": 1, "width": 210, "height": 297, "orientation": "portrait", "margins": { "top": 20, "bottom": 20, "left": 20, "right": 20 }, "background_color": "#ffffff", "components": [...] } ] } ``` ### 3.2 마이그레이션 전략 기존 단일 페이지 리포트 자동 변환: ```typescript // 기존 구조 감지 시 if (layoutConfig.components && !layoutConfig.pages) { // 자동으로 pages 구조로 변환 layoutConfig = { pages: [ { page_id: uuidv4(), page_name: "페이지 1", page_order: 0, width: layoutConfig.width || 210, height: layoutConfig.height || 297, orientation: layoutConfig.orientation || "portrait", margins: { top: 20, bottom: 20, left: 20, right: 20 }, background_color: "#ffffff", components: layoutConfig.components, }, ], }; } ``` ## 4. 프론트엔드 구조 ### 4.1 타입 정의 (types/report.ts) ```typescript export interface ReportPage { page_id: string; report_id: string; page_order: number; page_name: string; // 페이지 설정 width: number; height: number; orientation: 'portrait' | 'landscape'; // 여백 margin_top: number; margin_bottom: number; margin_left: number; margin_right: number; // 배경 background_color: string; created_at?: string; updated_at?: string; } export interface ComponentConfig { id: string; // page_id 불필요 (페이지의 components 배열에 포함됨) type: 'text' | 'label' | 'image' | 'table' | ...; x: number; y: number; width: number; height: number; // ... 기타 속성 } export interface ReportLayoutConfig { pages: ReportPage[]; } ``` ### 4.2 Context 구조 변경 ```typescript interface ReportDesignerContextType { // 페이지 관리 pages: ReportPage[]; currentPageId: string | null; currentPage: ReportPage | null; addPage: () => void; deletePage: (pageId: string) => void; duplicatePage: (pageId: string) => void; reorderPages: (sourceIndex: number, targetIndex: number) => void; selectPage: (pageId: string) => void; updatePage: (pageId: string, updates: Partial) => void; // 컴포넌트 (현재 페이지만) currentPageComponents: ComponentConfig[]; // ... 기존 기능들 } ``` ### 4.3 UI 구조 ``` ┌─────────────────────────────────────────────────────────────┐ │ ReportDesignerToolbar (저장, 미리보기, 페이지 추가 등) │ ├──────────┬────────────────────────────────────┬─────────────┤ │ │ │ │ │ PageList │ ReportDesignerCanvas │ Right │ │ (좌측) │ (현재 페이지만 표시) │ Panel │ │ │ │ (속성) │ │ - Page 1 │ ┌──────────────────────────┐ │ │ │ - Page 2 │ │ │ │ │ │ * Page 3 │ │ [컴포넌트들] │ │ │ │ (현재) │ │ │ │ │ │ │ └──────────────────────────┘ │ │ │ [+ 추가] │ │ │ │ │ 이전 | 다음 (페이지 네비게이션) │ │ └──────────┴────────────────────────────────────┴─────────────┘ ``` ## 5. 컴포넌트 구조 ### 5.1 새 컴포넌트 #### PageListPanel.tsx ```typescript - 좌측 페이지 목록 패널 - 페이지 썸네일 표시 - 드래그 앤 드롭으로 순서 변경 - 페이지 추가/삭제/복사 버튼 - 현재 페이지 하이라이트 ``` #### PageNavigator.tsx ```typescript - 캔버스 하단의 페이지 네비게이션 - 이전/다음 버튼 - 현재 페이지 번호 표시 - 페이지 점프 (1/5 형식) ``` #### PageSettingsPanel.tsx ```typescript - 우측 패널 내 페이지 설정 섹션 - 페이지 크기, 방향 - 여백 설정 - 배경색 ``` ### 5.2 수정할 컴포넌트 #### ReportDesignerContext.tsx - pages 상태 추가 - currentPageId 상태 추가 - 페이지 관리 함수들 추가 - components를 currentPageComponents로 필터링 #### ReportDesignerCanvas.tsx - currentPageComponents만 렌더링 - 캔버스 크기를 currentPage 기준으로 설정 - 컴포넌트 추가 시 page_id 포함 #### ReportDesignerToolbar.tsx - "페이지 추가" 버튼 추가 - 저장 시 pages도 함께 저장 #### ReportPreviewModal.tsx - 모든 페이지 순서대로 미리보기 - 페이지 구분선 표시 - PDF 저장 시 모든 페이지 포함 ## 6. API 엔드포인트 ### 6.1 페이지 관리 ```typescript // 페이지 목록 조회 GET /api/report/:reportId/pages Response: { pages: ReportPage[] } // 페이지 생성 POST /api/report/:reportId/pages Body: { page_name, width, height, orientation, margins } Response: { page: ReportPage } // 페이지 수정 PUT /api/report/pages/:pageId Body: Partial Response: { page: ReportPage } // 페이지 삭제 DELETE /api/report/pages/:pageId Response: { success: boolean } // 페이지 순서 변경 PUT /api/report/:reportId/pages/reorder Body: { pageOrders: Array<{ page_id, page_order }> } Response: { success: boolean } // 페이지 복사 POST /api/report/pages/:pageId/duplicate Response: { page: ReportPage } ``` ### 6.2 레이아웃 (기존 수정) ```typescript // 레이아웃 저장 (페이지별) PUT /api/report/:reportId/layout Body: { pages: ReportPage[], components: ComponentConfig[] // page_id 포함 } ``` ## 7. 구현 단계 ### Phase 1: DB 및 백엔드 (0.5일) 1. ✅ DB 스키마 생성 2. ✅ API 엔드포인트 구현 3. ✅ 기존 리포트 마이그레이션 (단일 페이지 생성) ### Phase 2: 타입 및 Context (0.5일) 1. ✅ 타입 정의 업데이트 2. ✅ Context에 페이지 상태/함수 추가 3. ✅ API 연동 ### Phase 3: UI 컴포넌트 (1일) 1. ✅ PageListPanel 구현 2. ✅ PageNavigator 구현 3. ✅ PageSettingsPanel 구현 ### Phase 4: 통합 및 수정 (1일) 1. ✅ Canvas에서 현재 페이지만 표시 2. ✅ 컴포넌트 추가/수정 시 page_id 처리 3. ✅ 미리보기에서 모든 페이지 표시 4. ✅ PDF/WORD 저장에서 모든 페이지 처리 ### Phase 5: 테스트 및 최적화 (0.5일) 1. ✅ 페이지 전환 성능 확인 2. ✅ 썸네일 렌더링 최적화 3. ✅ 버그 수정 **총 예상 기간: 3-4일** ## 8. 주의사항 ### 8.1 성능 최적화 - 페이지 썸네일은 저해상도로 렌더링 - 현재 페이지 컴포넌트만 DOM에 유지 - 페이지 전환 시 애니메이션 최소화 ### 8.2 호환성 - 기존 리포트는 자동으로 단일 페이지로 마이그레이션 - 템플릿도 페이지 구조 포함 ### 8.3 사용자 경험 - 페이지 삭제 시 확인 다이얼로그 - 컴포넌트가 있는 페이지 삭제 시 경고 - 페이지 순서 변경 시 즉시 반영 ## 9. 추후 확장 기능 ### 9.1 페이지 템플릿 - 자주 사용하는 페이지 레이아웃 저장 - 페이지 추가 시 템플릿 선택 ### 9.2 마스터 페이지 - 모든 페이지에 공통으로 적용되는 헤더/푸터 - 페이지 번호 자동 삽입 ### 9.3 페이지 연결 - 테이블 데이터가 여러 페이지에 자동 분할 - 페이지 오버플로우 처리 ## 10. 참고 자료 - 오즈리포트 메뉴얼 - Crystal Reports 페이지 관리 - Adobe InDesign 페이지 시스템