20 KiB
20 KiB
리포트 관리 시스템 설계
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 (리포트 템플릿)
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 (리포트 마스터)
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 (리포트 레이아웃)
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 컴포넌트 속성
각 컴포넌트는 다음 공통 속성을 가집니다:
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
리포트 목록 조회
// 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
리포트 상세 조회
// Response
interface ReportDetail {
report: ReportMaster;
layout: ReportLayout;
queries: ReportQuery[];
components: Component[];
}
POST /api/admin/reports
리포트 생성
// 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
리포트 수정
// 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
템플릿 목록 조회
// Response
interface GetTemplatesResponse {
system: ReportTemplate[]; // 시스템 템플릿
custom: ReportTemplate[]; // 사용자 정의 템플릿
}
POST /api/admin/reports/templates
템플릿 생성 (사용자 정의)
// 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
레이아웃 저장
// 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
미리보기 생성
// 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 생성)
// 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 상태 관리
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