docs:E-Sign 기술 스택 문서 업데이트 (실제 구현 반영)
- FPDI/FPDF → FPDI/TCPDF (PDF 서명 합성, MNG PdfSignatureService) - DOCX→PDF 변환 추가 (LibreOffice headless, MNG DocxToPdfConverter) - GD 확장, 나눔 폰트, Lucide 아이콘 등 실제 사용 기술 반영 - 4개 문서 일괄 업데이트 (technical-design, implementation-guide, operations-guide, changelog) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -217,7 +217,8 @@ projects/e-sign/
|
||||
|
||||
### v1.1.0 (예정)
|
||||
|
||||
- [ ] PDF 서명 합성 (`EsignPdfService::composeSigned`) - FPDI/FPDF 라이브러리
|
||||
- [x] PDF 서명 합성 - FPDI/TCPDF (MNG `PdfSignatureService`)
|
||||
- [x] DOCX→PDF 변환 - LibreOffice headless (MNG `DocxToPdfConverter`)
|
||||
- [ ] 감사 증적 페이지 추가 (`EsignPdfService::addAuditPage`)
|
||||
- [ ] 만료 계약 자동 처리 (Laravel Scheduler)
|
||||
- [ ] Queue Worker 설정 (이메일 비동기 발송)
|
||||
|
||||
@@ -18,7 +18,8 @@ API 프로젝트에 백엔드 로직(모델, 서비스, 컨트롤러, 라우트)
|
||||
|------|------|
|
||||
| 데이터베이스 | 마이그레이션 4개 (esign_ 접두사 테이블) |
|
||||
| 모델 | 4개 (EsignContract, EsignSigner, EsignSignField, EsignAuditLog) |
|
||||
| 서비스 | 4개 (Contract, Sign, Pdf, Audit) |
|
||||
| API 서비스 | 4개 (Contract, Sign, Pdf, Audit) |
|
||||
| MNG 서비스 | 2개 (DocxToPdfConverter, PdfSignatureService) |
|
||||
| API 컨트롤러 | 2개 (Contract 10엔드포인트, Sign 6엔드포인트) |
|
||||
| FormRequest | 4개 (Store, FieldConfigure, SignSubmit, SignReject) |
|
||||
| 메일 | 1개 (EsignRequestMail) |
|
||||
@@ -86,6 +87,10 @@ app/Http/Controllers/ESign/
|
||||
├── EsignController.php # 인증 필요 (5개 메서드)
|
||||
└── EsignPublicController.php # 비인증 (3개 메서드)
|
||||
|
||||
app/Services/ESign/
|
||||
├── DocxToPdfConverter.php # DOCX→PDF 변환 (LibreOffice headless)
|
||||
└── PdfSignatureService.php # PDF 서명 합성 (FPDI/TCPDF)
|
||||
|
||||
resources/views/esign/
|
||||
├── dashboard.blade.php # 대시보드 (통계 + 목록)
|
||||
├── create.blade.php # 계약 생성 (PDF 업로드)
|
||||
@@ -349,16 +354,46 @@ signer() → BelongsTo(EsignSigner)
|
||||
- 최대 5회 시도 (`otp_attempts`)
|
||||
- 초과 시 토큰 무효화
|
||||
|
||||
### 5.3 EsignPdfService
|
||||
### 5.3 EsignPdfService (API)
|
||||
|
||||
**파일**: `app/Services/ESign/EsignPdfService.php`
|
||||
**파일**: `api/app/Services/ESign/EsignPdfService.php`
|
||||
|
||||
| 메서드 | 설명 | 상태 |
|
||||
|--------|------|------|
|
||||
| `generateHash(string $filePath)` | SHA-256 해시 생성 | 구현 완료 |
|
||||
| `verifyIntegrity(string $filePath, string $expectedHash)` | 해시 비교 검증 (hash_equals) | 구현 완료 |
|
||||
| `composeSigned(...)` | 원본 PDF + 서명 이미지 합성 | 스텁 (FPDI 추후) |
|
||||
| `addAuditPage(...)` | 감사 증적 페이지 추가 | 스텁 (FPDI 추후) |
|
||||
| `composeSigned(...)` | 원본 PDF + 서명 이미지 합성 | 스텁 (MNG로 이관) |
|
||||
| `addAuditPage(...)` | 감사 증적 페이지 추가 | 스텁 (추후) |
|
||||
|
||||
### 5.5 DocxToPdfConverter (MNG)
|
||||
|
||||
**파일**: `mng/app/Services/ESign/DocxToPdfConverter.php`
|
||||
**의존성**: LibreOffice (headless), 나눔 폰트
|
||||
|
||||
| 메서드 | 설명 | 상태 |
|
||||
|--------|------|------|
|
||||
| `convertAndStore(UploadedFile $file)` | DOCX/DOC 파일을 LibreOffice로 PDF 변환 후 저장 | 구현 완료 |
|
||||
|
||||
**동작 방식**:
|
||||
- Word 파일(.doc, .docx) 업로드 시 자동 감지
|
||||
- `libreoffice --headless --convert-to pdf` 명령으로 변환
|
||||
- 나눔 폰트로 한글 정상 렌더링 지원
|
||||
- 변환된 PDF를 `storage/app/private/esign/{tenant_id}/originals/` 에 저장
|
||||
|
||||
### 5.6 PdfSignatureService (MNG)
|
||||
|
||||
**파일**: `mng/app/Services/ESign/PdfSignatureService.php`
|
||||
**의존성**: FPDI, TCPDF, GD 확장
|
||||
|
||||
| 메서드 | 설명 | 상태 |
|
||||
|--------|------|------|
|
||||
| `mergeSignatures(EsignContract $contract)` | 원본 PDF에 모든 서명 이미지 오버레이 합성 | 구현 완료 |
|
||||
|
||||
**동작 방식**:
|
||||
- FPDI로 원본 PDF 임포트
|
||||
- 서명 필드를 페이지별로 그룹핑
|
||||
- 필드 타입별 렌더링: signature/stamp(이미지), date(텍스트), text(텍스트), checkbox(체크마크)
|
||||
- 서명된 PDF를 `storage/app/private/esign/{tenant_id}/signed/` 에 저장
|
||||
|
||||
### 5.4 EsignAuditService
|
||||
|
||||
@@ -691,6 +726,8 @@ NOTIFIED/AUTHENTICATED → REJECTED (거절)
|
||||
| React 하이브리드 | `views/finance/journal-entries.blade.php` | CDN React + Babel 패턴 참고 |
|
||||
| HX-Redirect | 컨트롤러 패턴 | HTMX 부분 로드 시 전체 리로드 |
|
||||
| SidebarMenu | `app/Services/SidebarMenuService.php` | DB 기반 메뉴 |
|
||||
| DOCX→PDF | `app/Services/ESign/DocxToPdfConverter.php` | LibreOffice headless 변환 |
|
||||
| PDF 서명 합성 | `app/Services/ESign/PdfSignatureService.php` | FPDI/TCPDF 서명 오버레이 |
|
||||
|
||||
---
|
||||
|
||||
@@ -698,13 +735,15 @@ NOTIFIED/AUTHENTICATED → REJECTED (거절)
|
||||
|
||||
| 항목 | 우선순위 | 설명 |
|
||||
|------|---------|------|
|
||||
| PDF 합성 (FPDI) | 높음 | 원본 PDF에 서명 이미지 오버레이 |
|
||||
| ~~PDF 합성 (FPDI)~~ | ~~높음~~ | ~~원본 PDF에 서명 이미지 오버레이~~ → **구현 완료** (MNG PdfSignatureService) |
|
||||
| ~~DOCX→PDF 변환~~ | ~~높음~~ | ~~Word 문서 지원~~ → **구현 완료** (MNG DocxToPdfConverter + LibreOffice) |
|
||||
| 감사 증적 페이지 | 높음 | 완료 PDF 마지막에 감사 정보 페이지 추가 |
|
||||
| 파일 암호화 (AES-256) | 중간 | 원본 PDF 암호화 저장 |
|
||||
| 만료 자동 처리 | 중간 | 스케줄러로 expires_at 초과 계약 expired 처리 |
|
||||
| 리마인더 자동 발송 | 낮음 | 만료 3일 전 자동 리마인드 |
|
||||
| SMS OTP | 낮음 | 이메일 외 SMS 인증 지원 |
|
||||
| OTP bcrypt 해싱 | 중간 | 현재 평문 저장 → bcrypt 해싱 |
|
||||
| PDF 서명 텍스트 한글 | 낮음 | TCPDF CJK 폰트 추가 (현재 helvetica만 사용) |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -71,14 +71,21 @@
|
||||
|
||||
### 1.4 기술 스택
|
||||
|
||||
| 항목 | 버전 |
|
||||
|------|------|
|
||||
| PHP | 8.3 |
|
||||
| Laravel | 11 (API), 11 (MNG) |
|
||||
| MySQL | 8.0 |
|
||||
| Nginx | 최신 |
|
||||
| Docker Compose | v2 |
|
||||
| Node.js | React 18 (CDN, 빌드 불필요) |
|
||||
| 항목 | 버전 | 비고 |
|
||||
|------|------|------|
|
||||
| PHP | 8.3 | |
|
||||
| Laravel | 11 (API), 11 (MNG) | |
|
||||
| MySQL | 8.0 | Multi-tenant |
|
||||
| Nginx | 최신 | |
|
||||
| Docker Compose | v2 | |
|
||||
| React | 18 (CDN + Babel) | 브라우저 트랜스파일링 |
|
||||
| FPDI/TCPDF | 2.6 / 6.10 | PDF 서명 합성 (MNG) |
|
||||
| LibreOffice | headless (writer-nogui) | DOCX→PDF 변환 (MNG) |
|
||||
| GD 확장 | PHP 내장 | 서명 이미지 처리 (MNG) |
|
||||
| 나눔 폰트 | fonts-nanum | DOCX 한글 렌더링 (MNG) |
|
||||
| PDF.js | CDN | 브라우저 PDF 표시 |
|
||||
| signature_pad.js | 4.x | 터치/마우스 서명 캡처 |
|
||||
| Lucide | CDN | 아이콘 |
|
||||
|
||||
---
|
||||
|
||||
@@ -803,15 +810,16 @@ docker exec sam-nginx-1 grep "client_max_body_size" /etc/nginx/nginx.conf
|
||||
|
||||
## 11. 확장 가이드
|
||||
|
||||
### 11.1 v1.1 추가 예정 패키지
|
||||
### 11.1 현재 설치된 패키지 (구현 완료)
|
||||
|
||||
```bash
|
||||
# PDF 서명 합성 (FPDI + FPDF)
|
||||
docker exec sam-api-1 composer require setasign/fpdi setasign/fpdf
|
||||
# FPDI/TCPDF (PDF 서명 합성) - MNG 프로젝트에 설치됨
|
||||
# setasign/fpdi: ^2.6, tecnickcom/tcpdf: ^6.10
|
||||
|
||||
# 서버
|
||||
cd /home/webservice/api
|
||||
composer require setasign/fpdi setasign/fpdf
|
||||
# LibreOffice (DOCX→PDF 변환) - MNG Docker 컨테이너에 설치됨
|
||||
# libreoffice-writer-nogui, fonts-nanum, fonts-nanum-extra
|
||||
|
||||
# GD 확장 (서명 이미지 처리) - MNG Docker 컨테이너에 설치됨
|
||||
```
|
||||
|
||||
### 11.2 큐 워커 설정 (운영 권장)
|
||||
|
||||
@@ -39,14 +39,20 @@
|
||||
|
||||
| 영역 | 기술 | 비고 |
|
||||
|------|------|------|
|
||||
| Backend | Laravel 11 (PHP 8.3) | SAM API 프로젝트 확장 |
|
||||
| Frontend | HTMX + Alpine.js + Tailwind CSS | SAM MNG 프로젝트 확장 |
|
||||
| Database | MySQL 8.0 | 기존 SAM DB 공유 |
|
||||
| PDF 렌더링 | pdf.js (프론트) | 브라우저 PDF 표시 |
|
||||
| Backend | Laravel 11 (PHP 8.3) | SAM MNG + API 프로젝트 |
|
||||
| Frontend | React 18 + Babel (CDN) | 브라우저 트랜스파일링 |
|
||||
| Navigation | HTMX | SPA 없이 네비게이션 |
|
||||
| Styling | Tailwind CSS | 유틸리티 퍼스트 |
|
||||
| Database | MySQL 8.0 (Multi-tenant) | 기존 SAM DB 공유 |
|
||||
| PDF 렌더링 | PDF.js (프론트) | 브라우저 PDF 표시 |
|
||||
| 서명 캡처 | signature_pad.js | 터치/마우스 서명 |
|
||||
| PDF 합성 | FPDI + FPDF (백엔드) | 원본 PDF에 서명 삽입 |
|
||||
| 파일 저장 | Laravel Storage (local/S3) | 암호화 저장 |
|
||||
| 알림 | Laravel Notification (Mail) | 이메일 발송 |
|
||||
| DOCX→PDF 변환 | LibreOffice (headless) | MNG Docker 컨테이너 |
|
||||
| PDF 서명 합성 | FPDI + TCPDF (백엔드) | 원본 PDF에 서명 오버레이 |
|
||||
| 서명 이미지 처리 | GD 확장 | PNG 서명 이미지 처리 |
|
||||
| 한글 지원 | 나눔 폰트 (fonts-nanum) | DOCX→PDF 한글 렌더링 |
|
||||
| 아이콘 | Lucide | React 아이콘 라이브러리 |
|
||||
| 파일 저장 | Laravel Storage (local) | MNG 로컬 스토리지 |
|
||||
| 알림 | Laravel Mail | 이메일 발송 |
|
||||
|
||||
---
|
||||
|
||||
@@ -75,10 +81,12 @@
|
||||
│ │ - 계약 관리 화면 │ │ - 계약 CRUD API │ │
|
||||
│ │ - PDF 뷰어/서명 UI │ │ - 서명 처리 API │ │
|
||||
│ │ - 대시보드 │ │ - 인증 API (OTP) │ │
|
||||
│ │ │ │ - PDF 합성 서비스 │ │
|
||||
│ │ HTMX + Alpine.js │ │ - 알림 서비스 (이메일) │ │
|
||||
│ │ + pdf.js │ │ - 감사 로그 서비스 │ │
|
||||
│ │ + signature_pad │ │ - 문서 해시 검증 서비스 │ │
|
||||
│ │ - DOCX→PDF 변환 │ │ - 알림 서비스 (이메일) │ │
|
||||
│ │ - PDF 서명 합성 │ │ - 감사 로그 서비스 │ │
|
||||
│ │ │ │ - 문서 해시 검증 서비스 │ │
|
||||
│ │ React 18 + HTMX │ │ │ │
|
||||
│ │ + PDF.js │ │ │ │
|
||||
│ │ + signature_pad │ │ │ │
|
||||
│ └──────────┬───────────┘ └──────────────┬─────────────────┘ │
|
||||
│ │ │ │
|
||||
│ └────────────┬───────────────────┘ │
|
||||
@@ -104,11 +112,15 @@
|
||||
### 2.2 서비스 레이어 구조
|
||||
|
||||
```
|
||||
app/Services/ESign/
|
||||
api/app/Services/ESign/
|
||||
├── EsignContractService.php # 계약 CRUD, 상태 관리, 발송/리마인더
|
||||
├── EsignSignService.php # 서명 처리, OTP 인증, 토큰 관리
|
||||
├── EsignPdfService.php # PDF 합성, 해시 생성/검증
|
||||
├── EsignPdfService.php # 해시 생성/검증
|
||||
└── EsignAuditService.php # 감사 추적 로그 기록
|
||||
|
||||
mng/app/Services/ESign/
|
||||
├── DocxToPdfConverter.php # DOCX→PDF 변환 (LibreOffice headless)
|
||||
└── PdfSignatureService.php # PDF 서명 합성 (FPDI/TCPDF)
|
||||
```
|
||||
|
||||
---
|
||||
@@ -1021,7 +1033,7 @@ storage/app/esign/
|
||||
| 2주차 | 서명 위치 지정 화면 (pdf.js + 드래그) | MNG |
|
||||
| 2주차 | OTP 인증 + 서명 캡처 (signature_pad) | MNG + API |
|
||||
| 2주차 | 이메일 발송 (서명 요청/완료) | API |
|
||||
| 2주차 | PDF 합성 (FPDI + 서명 이미지) | API |
|
||||
| 2주차 | PDF 서명 합성 (FPDI/TCPDF) + DOCX→PDF (LibreOffice) | MNG |
|
||||
|
||||
### Phase 2: 보안 강화 (1주)
|
||||
|
||||
@@ -1562,8 +1574,9 @@ signer_order = 2 → 현재 계약에서 sign_order = 2인 서명자의 signer_i
|
||||
|
||||
| 기능 | 현재 상태 | 구현 방안 |
|
||||
|------|----------|----------|
|
||||
| PDF 서명 합성 | 스텁 구현 | FPDI + FPDF 라이브러리로 원본 PDF에 서명 이미지 삽입 |
|
||||
| 감사 증적 페이지 | 스텁 구현 | 완료 PDF 마지막 페이지에 서명 이력 자동 추가 |
|
||||
| PDF 서명 합성 | **구현 완료** | FPDI + TCPDF로 원본 PDF에 서명 이미지 오버레이 (MNG PdfSignatureService) |
|
||||
| DOCX→PDF 변환 | **구현 완료** | LibreOffice headless + 나눔 폰트 (MNG DocxToPdfConverter) |
|
||||
| 감사 증적 페이지 | 미구현 | 완료 PDF 마지막 페이지에 서명 이력 자동 추가 |
|
||||
| 파일 암호화 | 미구현 | AES-256-CBC로 원본 PDF 암호화 저장 |
|
||||
| 자동 만료 처리 | 미구현 | Laravel Scheduler로 만료된 계약 상태 자동 변경 |
|
||||
| 자동 리마인더 | 미구현 | 만료 3일 전 자동 알림 이메일 발송 |
|
||||
|
||||
Reference in New Issue
Block a user