# 리포트 관리 시스템 설계

## 1. 프로젝트 개요

### 1.1 목적

ERP 시스템에서 다양한 업무 문서(발주서, 청구서, 거래명세서 등)를 동적으로 디자인하고 관리할 수 있는 리포트 관리 시스템을 구축합니다.

### 1.2 주요 기능

- 리포트 목록 조회 및 관리
- 드래그 앤 드롭 기반 리포트 디자이너
- 템플릿 관리 (기본 템플릿 + 사용자 정의 템플릿)
- 쿼리 관리 (마스터/디테일)
- 외부 DB 연동
- 인쇄 및 내보내기 (PDF, WORD)
- 미리보기 기능

## 2. 화면 구성

### 2.1 리포트 목록 화면 (`/admin/report`)

```
┌──────────────────────────────────────────────────────────────────┐
│ 리포트 관리                                       [+ 새 리포트]    │
├──────────────────────────────────────────────────────────────────┤
│ 검색: [____________________] [검색] [초기화]                       │
├──────────────────────────────────────────────────────────────────┤
│ No │ 리포트명      │ 작성자 │ 수정일     │ 액션                   │
├────┼──────────────┼────────┼───────────┼────────────────────────┤
│ 1  │ 발주서 양식   │ 홍길동 │ 2025-10-01 │ 수정 │ 복사 │ 삭제   │
│ 2  │ 청구서 기본   │ 김철수 │ 2025-09-28 │ 수정 │ 복사 │ 삭제   │
│ 3  │ 거래명세서    │ 이영희 │ 2025-09-25 │ 수정 │ 복사 │ 삭제   │
└──────────────────────────────────────────────────────────────────┘
```

**기능**

- 리포트 목록 조회 (페이징, 정렬, 검색)
- 새 리포트 생성
- 기존 리포트 수정
- 리포트 복사
- 리포트 삭제
- 리포트 미리보기

### 2.2 리포트 디자이너 화면

```
┌──────────────────────────────────────────────────────────────────┐
│ 리포트 디자이너  [저장] [미리보기] [초기화] [목록으로]              │
├──────┬────────────────────────────────────────────────┬──────────┤
│      │                                                │          │
│ 템플릿│              작업 영역 (캔버스)                 │ 속성 패널 │
│      │                                                │          │
│ 컴포넌트│           [드래그 앤 드롭]                      │ 쿼리 관리 │
│      │                                                │          │
│      │                                                │ DB 연동  │
└──────┴────────────────────────────────────────────────┴──────────┘
```

### 2.3 미리보기 모달

```
┌──────────────────────────────────────────────────────────────────┐
│ 미리보기                                                    [닫기] │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│                     [리포트 내용 미리보기]                        │
│                                                                  │
├──────────────────────────────────────────────────────────────────┤
│                         [인쇄] [PDF] [WORD]                      │
└──────────────────────────────────────────────────────────────────┘
```

## 3. 데이터베이스 설계

### 3.1 테이블 구조

#### REPORT_TEMPLATE (리포트 템플릿)

```sql
CREATE TABLE report_template (
  template_id VARCHAR(50) PRIMARY KEY,          -- 템플릿 ID
  template_name_kor VARCHAR(100) NOT NULL,      -- 템플릿명 (한국어)
  template_name_eng VARCHAR(100),               -- 템플릿명 (영어)
  template_type VARCHAR(30) NOT NULL,           -- 템플릿 타입 (ORDER, INVOICE, STATEMENT, etc)
  is_system CHAR(1) DEFAULT 'N',                -- 시스템 기본 템플릿 여부 (Y/N)
  thumbnail_url VARCHAR(500),                   -- 썸네일 이미지 경로
  description TEXT,                             -- 템플릿 설명
  layout_config TEXT,                           -- 레이아웃 설정 (JSON)
  default_queries TEXT,                         -- 기본 쿼리 (JSON)
  use_yn CHAR(1) DEFAULT 'Y',                   -- 사용 여부
  sort_order INTEGER DEFAULT 0,                 -- 정렬 순서
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  created_by VARCHAR(50),
  updated_at TIMESTAMP,
  updated_by VARCHAR(50)
);
```

#### REPORT_MASTER (리포트 마스터)

```sql
CREATE TABLE report_master (
  report_id VARCHAR(50) PRIMARY KEY,            -- 리포트 ID
  report_name_kor VARCHAR(100) NOT NULL,        -- 리포트명 (한국어)
  report_name_eng VARCHAR(100),                 -- 리포트명 (영어)
  template_id VARCHAR(50),                      -- 템플릿 ID (FK)
  report_type VARCHAR(30) NOT NULL,             -- 리포트 타입
  company_code VARCHAR(20),                     -- 회사 코드
  description TEXT,                             -- 설명
  use_yn CHAR(1) DEFAULT 'Y',                   -- 사용 여부
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  created_by VARCHAR(50),
  updated_at TIMESTAMP,
  updated_by VARCHAR(50),
  FOREIGN KEY (template_id) REFERENCES report_template(template_id)
);
```

#### REPORT_LAYOUT (리포트 레이아웃)

```sql
CREATE TABLE report_layout (
  layout_id VARCHAR(50) PRIMARY KEY,            -- 레이아웃 ID
  report_id VARCHAR(50) NOT NULL,               -- 리포트 ID (FK)
  canvas_width INTEGER DEFAULT 210,             -- 캔버스 너비 (mm)
  canvas_height INTEGER DEFAULT 297,            -- 캔버스 높이 (mm)
  page_orientation VARCHAR(10) DEFAULT 'portrait', -- 페이지 방향 (portrait/landscape)
  margin_top INTEGER DEFAULT 20,                -- 상단 여백 (mm)
  margin_bottom INTEGER DEFAULT 20,             -- 하단 여백 (mm)
  margin_left INTEGER DEFAULT 20,               -- 좌측 여백 (mm)
  margin_right INTEGER DEFAULT 20,              -- 우측 여백 (mm)
  components TEXT,                              -- 컴포넌트 배치 정보 (JSON)
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  created_by VARCHAR(50),
  updated_at TIMESTAMP,
  updated_by VARCHAR(50),
  FOREIGN KEY (report_id) REFERENCES report_master(report_id)
);
```

## 4. 컴포넌트 목록

### 4.1 기본 컴포넌트

#### 텍스트 관련

- **Text Field**: 단일 라인 텍스트 입력/표시
- **Text Area**: 여러 줄 텍스트 입력/표시
- **Label**: 고정 라벨 텍스트
- **Rich Text**: 서식이 있는 텍스트 (굵게, 기울임, 색상)

#### 숫자/날짜 관련

- **Number**: 숫자 표시 (통화 형식 지원)
- **Date**: 날짜 표시 (형식 지정 가능)
- **Date Time**: 날짜 + 시간 표시
- **Calculate Field**: 계산 필드 (합계, 평균 등)

#### 테이블/그리드

- **Data Table**: 데이터 테이블 (디테일 쿼리 바인딩)
- **Summary Table**: 요약 테이블
- **Group Table**: 그룹핑 테이블

#### 이미지/그래픽

- **Image**: 이미지 표시 (로고, 서명 등)
- **Line**: 구분선
- **Rectangle**: 사각형 (테두리)

#### 특수 컴포넌트

- **Page Number**: 페이지 번호
- **Current Date**: 현재 날짜/시간
- **Company Info**: 회사 정보 (자동)
- **Signature**: 서명란
- **Stamp**: 도장란

### 4.2 컴포넌트 속성

각 컴포넌트는 다음 공통 속성을 가집니다:

```typescript
interface ComponentBase {
  id: string; // 컴포넌트 ID
  type: string; // 컴포넌트 타입
  x: number; // X 좌표
  y: number; // Y 좌표
  width: number; // 너비
  height: number; // 높이
  zIndex: number; // Z-인덱스

  // 스타일
  fontSize?: number; // 글자 크기
  fontFamily?: string; // 폰트
  fontWeight?: string; // 글자 굵기
  fontColor?: string; // 글자 색상
  backgroundColor?: string; // 배경색
  borderWidth?: number; // 테두리 두께
  borderColor?: string; // 테두리 색상
  borderRadius?: number; // 모서리 둥글기
  textAlign?: string; // 텍스트 정렬
  padding?: number; // 내부 여백

  // 데이터 바인딩
  queryId?: string; // 연결된 쿼리 ID
  fieldName?: string; // 필드명
  defaultValue?: string; // 기본값
  format?: string; // 표시 형식

  // 기타
  visible?: boolean; // 표시 여부
  printable?: boolean; // 인쇄 여부
  conditional?: string; // 조건부 표시 (수식)
}
```

## 5. 템플릿 목록

### 5.1 기본 템플릿 (시스템)

#### 구매/발주 관련

- **발주서 (Purchase Order)**: 거래처에 발주하는 문서
- **구매요청서 (Purchase Request)**: 내부 구매 요청 문서
- **발주 확인서 (PO Confirmation)**: 발주 확인 문서

#### 판매/청구 관련

- **청구서 (Invoice)**: 고객에게 청구하는 문서
- **견적서 (Quotation)**: 견적 제공 문서
- **거래명세서 (Transaction Statement)**: 거래 내역 명세
- **세금계산서 (Tax Invoice)**: 세금 계산서
- **영수증 (Receipt)**: 영수 증빙 문서

#### 재고/입출고 관련

- **입고증 (Goods Receipt)**: 입고 증빙 문서
- **출고증 (Delivery Note)**: 출고 증빙 문서
- **재고 현황표 (Inventory Report)**: 재고 현황
- **이동 전표 (Transfer Note)**: 재고 이동 문서

#### 생산 관련

- **작업지시서 (Work Order)**: 생산 작업 지시
- **생산 일보 (Production Daily Report)**: 생산 일일 보고
- **품질 검사표 (Quality Inspection)**: 품질 검사 기록
- **불량 보고서 (Defect Report)**: 불량 보고

#### 회계/경영 관련

- **손익 계산서 (Income Statement)**: 손익 현황
- **대차대조표 (Balance Sheet)**: 재무 상태
- **현금 흐름표 (Cash Flow Statement)**: 현금 흐름
- **급여 명세서 (Payroll Slip)**: 급여 내역

#### 일반 문서

- **기본 양식 (Basic Template)**: 빈 캔버스
- **일반 보고서 (General Report)**: 일반 보고 양식
- **목록 양식 (List Template)**: 목록형 양식

### 5.2 사용자 정의 템플릿

- 사용자가 직접 생성한 템플릿
- 기본 템플릿을 복사하여 수정 가능
- 회사별로 관리 가능

## 6. API 설계

### 6.1 리포트 목록 API

#### GET `/api/admin/reports`

리포트 목록 조회

```typescript
// Request
interface GetReportsRequest {
  page?: number;
  limit?: number;
  searchText?: string;
  reportType?: string;
  useYn?: string;
  sortBy?: string;
  sortOrder?: "ASC" | "DESC";
}

// Response
interface GetReportsResponse {
  items: ReportMaster[];
  total: number;
  page: number;
  limit: number;
}
```

#### GET `/api/admin/reports/:reportId`

리포트 상세 조회

```typescript
// Response
interface ReportDetail {
  report: ReportMaster;
  layout: ReportLayout;
  queries: ReportQuery[];
  components: Component[];
}
```

#### POST `/api/admin/reports`

리포트 생성

```typescript
// Request
interface CreateReportRequest {
  reportNameKor: string;
  reportNameEng?: string;
  templateId?: string;
  reportType: string;
  description?: string;
}

// Response
interface CreateReportResponse {
  reportId: string;
  message: string;
}
```

#### PUT `/api/admin/reports/:reportId`

리포트 수정

```typescript
// Request
interface UpdateReportRequest {
  reportNameKor?: string;
  reportNameEng?: string;
  reportType?: string;
  description?: string;
  useYn?: string;
}
```

#### DELETE `/api/admin/reports/:reportId`

리포트 삭제

#### POST `/api/admin/reports/:reportId/copy`

리포트 복사

### 6.2 템플릿 API

#### GET `/api/admin/reports/templates`

템플릿 목록 조회

```typescript
// Response
interface GetTemplatesResponse {
  system: ReportTemplate[]; // 시스템 템플릿
  custom: ReportTemplate[]; // 사용자 정의 템플릿
}
```

#### POST `/api/admin/reports/templates`

템플릿 생성 (사용자 정의)

```typescript
// Request
interface CreateTemplateRequest {
  templateNameKor: string;
  templateNameEng?: string;
  templateType: string;
  description?: string;
  layoutConfig: any;
  defaultQueries?: any;
}
```

#### PUT `/api/admin/reports/templates/:templateId`

템플릿 수정

#### DELETE `/api/admin/reports/templates/:templateId`

템플릿 삭제

### 6.3 레이아웃 API

#### GET `/api/admin/reports/:reportId/layout`

레이아웃 조회

#### PUT `/api/admin/reports/:reportId/layout`

레이아웃 저장

```typescript
// Request
interface SaveLayoutRequest {
  canvasWidth: number;
  canvasHeight: number;
  pageOrientation: string;
  margins: {
    top: number;
    bottom: number;
    left: number;
    right: number;
  };
  components: Component[];
}
```

### 6.4 인쇄/내보내기 API

#### POST `/api/admin/reports/:reportId/preview`

미리보기 생성

```typescript
// Request
interface PreviewRequest {
  parameters?: { [key: string]: any };
  format?: "HTML" | "PDF";
}

// Response
interface PreviewResponse {
  html?: string; // HTML 미리보기
  pdfUrl?: string; // PDF URL
}
```

#### POST `/api/admin/reports/:reportId/print`

인쇄 (PDF 생성)

```typescript
// Request
interface PrintRequest {
  parameters?: { [key: string]: any };
  format: "PDF" | "WORD" | "EXCEL";
}

// Response
interface PrintResponse {
  fileUrl: string;
  fileName: string;
  fileSize: number;
}
```

## 7. 프론트엔드 구조

### 7.1 페이지 구조

```
/admin/report
├── ReportListPage.tsx          # 리포트 목록 페이지
├── ReportDesignerPage.tsx      # 리포트 디자이너 페이지
└── components/
    ├── ReportList.tsx          # 리포트 목록 테이블
    ├── ReportSearchForm.tsx    # 검색 폼
    ├── TemplateSelector.tsx    # 템플릿 선택기
    ├── ComponentPalette.tsx    # 컴포넌트 팔레트
    ├── Canvas.tsx              # 캔버스 영역
    ├── ComponentRenderer.tsx   # 컴포넌트 렌더러
    ├── PropertyPanel.tsx       # 속성 패널
    ├── QueryManager.tsx        # 쿼리 관리
    ├── QueryCard.tsx           # 쿼리 카드
    ├── ConnectionManager.tsx   # 외부 DB 연결 관리
    ├── PreviewModal.tsx        # 미리보기 모달
    └── PrintOptionsModal.tsx   # 인쇄 옵션 모달
```

### 7.2 상태 관리

```typescript
interface ReportDesignerState {
  // 리포트 기본 정보
  report: ReportMaster | null;

  // 레이아웃
  layout: ReportLayout | null;
  components: Component[];
  selectedComponentId: string | null;

  // 쿼리
  queries: ReportQuery[];
  queryResults: { [queryId: string]: any[] };

  // 외부 연결
  connections: ReportExternalConnection[];

  // UI 상태
  isDragging: boolean;
  isResizing: boolean;
  showPreview: boolean;
  showPrintOptions: boolean;

  // 히스토리 (Undo/Redo)
  history: {
    past: Component[][];
    present: Component[];
    future: Component[][];
  };
}
```

## 8. 구현 우선순위

### Phase 1: 기본 기능 (2주)

- [ ] 데이터베이스 테이블 생성
- [ ] 리포트 목록 화면
- [ ] 리포트 CRUD API
- [ ] 템플릿 목록 조회
- [ ] 기본 템플릿 데이터 생성

### Phase 2: 디자이너 기본 (2주)

- [ ] 캔버스 구현
- [ ] 컴포넌트 드래그 앤 드롭
- [ ] 컴포넌트 선택/이동/크기 조절
- [ ] 속성 패널 (기본)
- [ ] 저장/불러오기

### Phase 3: 쿼리 관리 (1주)

- [ ] 쿼리 추가/수정/삭제
- [ ] 파라미터 감지 및 입력
- [ ] 쿼리 실행 (내부 DB)
- [ ] 쿼리 결과를 컴포넌트에 바인딩

### Phase 4: 쿼리 관리 고급 (1주)

- [ ] 쿼리 필드 매핑
- [ ] 컴포넌트와 데이터 바인딩
- [ ] 파라미터 전달 및 처리

### Phase 5: 미리보기/인쇄 (1주)

- [ ] HTML 미리보기
- [ ] PDF 생성
- [ ] WORD 생성
- [ ] 브라우저 인쇄

### Phase 6: 고급 기능 (2주)

- [ ] 템플릿 생성 기능
- [ ] 컴포넌트 추가 (이미지, 서명, 도장)
- [ ] 계산 필드
- [ ] 조건부 표시
- [ ] Undo/Redo
- [ ] 다국어 지원

## 9. 기술 스택

### Backend

- **Node.js + TypeScript**: 백엔드 서버
- **PostgreSQL**: 데이터베이스
- **Prisma**: ORM
- **Puppeteer**: PDF 생성
- **docx**: WORD 생성

### Frontend

- **Next.js + React**: 프론트엔드 프레임워크
- **TypeScript**: 타입 안정성
- **TailwindCSS**: 스타일링
- **react-dnd**: 드래그 앤 드롭
- **react-grid-layout**: 레이아웃 관리
- **react-to-print**: 인쇄 기능
- **react-pdf**: PDF 미리보기

## 10. 보안 고려사항

### 10.1 쿼리 실행 보안

- SELECT 쿼리만 허용 (INSERT, UPDATE, DELETE 금지)
- 쿼리 결과 크기 제한 (최대 1000 rows)
- 실행 시간 제한 (30초)
- SQL 인젝션 방지 (파라미터 바인딩 강제)
- 위험한 함수 차단 (DROP, TRUNCATE 등)

### 10.2 파일 보안

- 생성된 PDF/WORD 파일은 임시 디렉토리에 저장
- 파일은 24시간 후 자동 삭제
- 파일 다운로드 시 토큰 검증

### 10.3 접근 권한

- 리포트 생성/수정/삭제 권한 체크
- 관리자만 템플릿 생성 가능
- 사용자별 리포트 접근 제어

## 11. 성능 최적화

### 11.1 PDF 생성 최적화

- 백그라운드 작업으로 처리
- 생성된 PDF는 CDN에 캐싱

### 11.2 프론트엔드 최적화

- 컴포넌트 가상화 (많은 컴포넌트 처리)
- 디바운싱/쓰로틀링 (드래그 앤 드롭)
- 이미지 레이지 로딩

### 11.3 데이터베이스 최적화

- 레이아웃 데이터는 JSON 형태로 저장
- 리포트 목록 조회 시 인덱스 활용
- 자주 사용하는 템플릿 캐싱

## 12. 테스트 계획

### 12.1 단위 테스트

- API 엔드포인트 테스트
- 쿼리 파싱 테스트
- PDF 생성 테스트

### 12.2 통합 테스트

- 리포트 생성 → 쿼리 실행 → PDF 생성 전체 플로우
- 템플릿 적용 → 데이터 바인딩 테스트

### 12.3 UI 테스트

- 드래그 앤 드롭 동작 테스트
- 컴포넌트 속성 변경 테스트

## 13. 향후 확장 계획

### 13.1 고급 기능

- 차트/그래프 컴포넌트
- 조건부 서식 (색상 변경 등)
- 그룹핑 및 집계 함수
- 마스터-디테일 관계 자동 설정

### 13.2 협업 기능

- 리포트 공유
- 버전 관리
- 댓글 기능

### 13.3 자동화

- 스케줄링 (정기적 리포트 생성)
- 이메일 자동 발송
- 알림 설정

## 14. 참고 자료

### 14.1 유사 솔루션

- Crystal Reports
- JasperReports
- BIRT (Business Intelligence and Reporting Tools)
- FastReport

### 14.2 라이브러리

- [react-grid-layout](https://github.com/react-grid-layout/react-grid-layout)
- [react-dnd](https://react-dnd.github.io/react-dnd/)
- [puppeteer](https://pptr.dev/)
- [docx](https://docx.js.org/)
