SAM E-Sign 요구사항 정의서
프로젝트명: SAM E-Sign (전자계약 서명 솔루션)
작성일: 2026-02-12
버전: v1.0
작성자: DX 추진팀
상태: 구현 완료
1. 프로젝트 개요
1.1 배경
현재 계약 서명 업무는 대면 또는 우편으로 진행되어 시간과 비용이 소요된다.
외부 전자계약 서비스(모두싸인 등)를 사용할 수 있으나, SAM 시스템과의 통합 및 데이터 주권 확보를 위해 자체 솔루션을 구축한다.
1.2 목적
두 당사자(계약 생성자 A, 상대방 B)가 온라인으로 PDF 계약서에 전자서명하고, 서명 완료된 문서를 법적 효력이 있는 형태로 보관하는 시스템을 구축한다.
1.3 목표
| 목표 |
측정 기준 |
| 계약 처리 시간 단축 |
대면 서명 대비 80% 이상 시간 절감 |
| 보안 요건 충족 |
문서 무결성 검증, 본인인증, 감사 추적 |
| 법적 효력 확보 |
전자서명법 제2조 요건 충족 |
| 사용 편의성 |
3단계 이내 계약 생성, 비로그인 서명 |
1.4 이해관계자
| 역할 |
설명 |
시스템 내 역할 |
| 계약 생성자 (A) |
계약서를 작성하고 서명을 요청하는 사람 |
SAM MNG 로그인 사용자 |
| 서명 상대방 (B) |
이메일 링크를 통해 서명하는 사람 |
비로그인, 토큰 기반 접근 |
| 시스템 관리자 |
SAM 시스템 운영자 |
테넌트 관리 |
2. 범위
2.1 포함 범위 (v1.0)
| # |
기능 |
설명 |
| 1 |
2인 서명 |
생성자(갑) + 상대방(을) |
| 2 |
PDF 기반 계약 |
PDF 파일 업로드 및 관리 |
| 3 |
순차 서명 |
상대방 먼저 또는 작성자 먼저 |
| 4 |
이메일 OTP 인증 |
6자리 코드, 5분 유효 |
| 5 |
캔버스 직접 서명 |
터치/마우스 서명 입력 |
| 6 |
문서 무결성 검증 |
SHA-256 해시 비교 |
| 7 |
감사 추적 로그 |
모든 행위 기록 (삭제 불가) |
| 8 |
이메일 알림 |
서명 요청, 리마인더 발송 |
| 9 |
서명 거절 |
사유 입력 후 거절 처리 |
| 10 |
계약 관리 대시보드 |
통계, 목록, 필터, 검색 |
2.2 제외 범위 (v2 이후)
| 기능 |
사유 |
| 3인 이상 다자간 서명 |
v1 안정화 후 확장 |
| 카카오/PASS 본인인증 |
외부 API 연동 필요 |
| SMS OTP |
외부 서비스 비용 발생 |
| 워드/한글 문서 편집 |
PDF 전환 후 사용 |
| 공인인증서 연동 |
별도 모듈 개발 필요 |
| 블록체인 공증 |
기술 검토 후 결정 |
| 템플릿 관리 |
v2에서 추가 |
| 외부 API 제공 |
v2에서 추가 |
3. 기능 요구사항
FR-001: 계약 생성
| 항목 |
내용 |
| ID |
FR-001 |
| 제목 |
전자계약 생성 |
| 우선순위 |
필수 |
| 설명 |
로그인 사용자가 PDF 파일을 업로드하고 계약 정보를 입력하여 전자계약을 생성한다 |
상세 요구사항:
| # |
요구사항 |
비고 |
| 1 |
계약 제목 입력 (필수, 최대 200자) |
|
| 2 |
계약 설명 입력 (선택, 최대 2000자) |
|
| 3 |
PDF 파일 업로드 (필수, 최대 20MB) |
PDF 형식만 허용 |
| 4 |
서명 순서 선택 |
상대방 먼저(기본) / 작성자 먼저 |
| 5 |
서명 기한 설정 (기본 7일) |
현재 시점 이후 날짜 |
| 6 |
작성자(갑) 정보 입력 |
이름(필수), 이메일(필수), 전화번호(선택) |
| 7 |
상대방(을) 정보 입력 |
이름(필수), 이메일(필수), 전화번호(선택) |
| 8 |
계약 코드 자동 생성 |
형식: ES-YYYYMMDD-RANDOM6 |
| 9 |
업로드 시 SHA-256 해시 자동 생성 |
문서 무결성 검증용 |
| 10 |
생성 완료 후 서명 위치 지정 화면으로 이동 |
|
비즈니스 규칙:
- 계약 생성 시 초기 상태는 "초안(draft)"
- 서명자 2인이 자동 생성됨 (작성자 + 상대방)
- 각 서명자에게 128자 고유 접근 토큰 발급
FR-002: 서명 위치 지정
| 항목 |
내용 |
| ID |
FR-002 |
| 제목 |
PDF 서명 위치 지정 |
| 우선순위 |
필수 |
| 설명 |
업로드된 PDF 위에 각 서명자의 서명 필드 위치를 시각적으로 지정한다 |
상세 요구사항:
| # |
요구사항 |
비고 |
| 1 |
PDF를 브라우저에서 렌더링 (PDF.js) |
페이지 네비게이션 제공 |
| 2 |
클릭으로 서명 필드 추가 |
서명자별 색상 구분 (갑:파랑, 을:빨강) |
| 3 |
드래그로 필드 위치 이동 |
|
| 4 |
필드 크기 조절 |
|
| 5 |
필드 타입 선택 |
서명, 도장, 텍스트, 날짜, 체크박스 |
| 6 |
필드 라벨 입력 |
예: "갑 서명", "을 서명" |
| 7 |
필수 여부 설정 |
기본값: 필수 |
| 8 |
좌표값은 % 기반 저장 |
다양한 PDF 크기 대응 |
| 9 |
저장 시 기존 필드 삭제 후 재생성 |
|
| 10 |
초안(draft) 상태에서만 설정 가능 |
|
비즈니스 규칙:
- 최소 1개 이상의 서명 필드가 있어야 서명 요청 발송 가능
- 필드 좌표는 페이지 기준 백분율(0~100%)로 저장
FR-003: 서명 요청 발송
| 항목 |
내용 |
| ID |
FR-003 |
| 제목 |
서명 요청 이메일 발송 |
| 우선순위 |
필수 |
| 설명 |
서명 필드 설정 완료 후 첫 번째 서명자에게 서명 요청 이메일을 발송한다 |
상세 요구사항:
| # |
요구사항 |
비고 |
| 1 |
발송 전 체크리스트 표시 |
필드 설정 여부, 서명자 정보, PDF 무결성 |
| 2 |
서명 순서 최종 확인 |
변경 불가 (생성 시 결정) |
| 3 |
발송 버튼 클릭 시 이메일 발송 |
서명 링크 포함 |
| 4 |
계약 상태 변경 |
draft → pending |
| 5 |
첫 서명자 상태 변경 |
waiting → notified |
| 6 |
이메일에 계약 제목, 서명 링크, 기한 포함 |
|
비즈니스 규칙:
- 서명 필드가 설정되지 않으면 발송 불가
- 초안(draft) 상태에서만 발송 가능
- 서명 순서에 따라 첫 번째 서명자에게만 이메일 발송
FR-004: 본인인증 (OTP)
| 항목 |
내용 |
| ID |
FR-004 |
| 제목 |
이메일 OTP 본인인증 |
| 우선순위 |
필수 |
| 설명 |
서명자가 서명 링크에 접속하면 이메일 OTP로 본인인증을 수행한다 |
상세 요구사항:
| # |
요구사항 |
비고 |
| 1 |
서명 링크 접속 시 계약 정보 표시 |
제목, 서명자, 기한 |
| 2 |
인증 코드 발송 버튼 |
등록된 이메일로 발송 |
| 3 |
6자리 숫자 OTP 생성 |
random_int(100000, 999999) |
| 4 |
OTP 유효 시간: 5분 |
초과 시 재발송 필요 |
| 5 |
최대 시도 횟수: 5회 |
초과 시 인증 차단 |
| 6 |
인증 성공 시 세션 토큰 발급 |
sign_session_token |
| 7 |
인증 후 서명 화면으로 자동 이동 |
|
| 8 |
재발송 기능 제공 |
|
비즈니스 규칙:
- 비로그인 접근 (토큰 기반)
- OTP 시도 횟수 초과 시 해당 토큰으로 재인증 불가
- 인증 완료 시각을 DB에 기록 (auth_verified_at)
FR-005: 전자서명 수행
| 항목 |
내용 |
| ID |
FR-005 |
| 제목 |
전자서명 수행 |
| 우선순위 |
필수 |
| 설명 |
본인인증 완료 후 계약서를 확인하고 캔버스에 직접 서명한다 |
상세 요구사항:
| # |
요구사항 |
비고 |
| 1 |
3단계 프로세스 |
문서 확인 → 서명 입력 → 서명 확인 |
| 2 |
PDF 문서 다운로드/열람 링크 |
|
| 3 |
동의 체크박스 |
"계약 내용 확인 및 전자서명 동의" |
| 4 |
캔버스 서명 입력 |
SignaturePad 라이브러리 |
| 5 |
터치 및 마우스 지원 |
모바일/PC 모두 대응 |
| 6 |
서명 지우기 기능 |
|
| 7 |
서명 미리보기 |
확인 단계에서 표시 |
| 8 |
서명 이미지 저장 |
base64 PNG → 파일 저장 |
| 9 |
서명 시 IP, User-Agent 기록 |
|
| 10 |
서명 완료 후 done 화면으로 이동 |
|
비즈니스 규칙:
- 동의 체크 없이 서명 단계 진행 불가
- 서명이 비어있으면 제출 불가
- 서명 완료 시 signer 상태: authenticated → signed
- 모든 서명자 완료 시 계약 자동 완료(completed) 처리
FR-006: 서명 거절
| 항목 |
내용 |
| ID |
FR-006 |
| 제목 |
서명 거절 |
| 우선순위 |
필수 |
| 설명 |
서명자가 계약 내용에 동의하지 않을 경우 거절할 수 있다 |
상세 요구사항:
| # |
요구사항 |
비고 |
| 1 |
서명 화면에서 거절 버튼 제공 |
|
| 2 |
거절 사유 입력 (필수, 최대 1000자) |
|
| 3 |
거절 시 계약 상태 → rejected |
|
| 4 |
계약 담당자에게 알림 |
|
비즈니스 규칙:
- 거절 후 해당 계약은 더 이상 서명 불가
- 거절 사유는 감사 로그에 기록
FR-007: 계약 관리 대시보드
| 항목 |
내용 |
| ID |
FR-007 |
| 제목 |
계약 관리 대시보드 |
| 우선순위 |
필수 |
| 설명 |
로그인 사용자가 자신의 계약 현황을 조회하고 관리한다 |
상세 요구사항:
| # |
요구사항 |
비고 |
| 1 |
상태별 통계 카드 |
전체, 진행중, 완료, 만료 등 |
| 2 |
계약 목록 테이블 |
코드, 제목, 상대방, 상태, 기한, 생성일 |
| 3 |
상태 필터 |
드롭다운 |
| 4 |
키워드 검색 |
제목 기준 |
| 5 |
날짜 범위 필터 |
생성일 기준 |
| 6 |
페이지네이션 |
기본 20건 |
| 7 |
상태 배지 색상 구분 |
초안:회색, 진행:파랑, 완료:녹색, 만료:빨강 |
FR-008: 계약 상세 조회
| 항목 |
내용 |
| ID |
FR-008 |
| 제목 |
계약 상세 조회 |
| 우선순위 |
필수 |
| 설명 |
개별 계약의 상세 정보, 서명 현황, 감사 로그를 조회한다 |
상세 요구사항:
| # |
요구사항 |
비고 |
| 1 |
계약 기본 정보 표시 |
코드, 제목, 설명, 순서, 기한, 상태 |
| 2 |
서명자별 현황 카드 |
이름, 상태, 인증/서명 시각 |
| 3 |
감사 추적 타임라인 |
시간순 이벤트 목록, IP 포함 |
| 4 |
액션 버튼 동적 표시 |
상태에 따라 발송/리마인더/취소/다운로드/검증 |
FR-009: 계약 취소
| 항목 |
내용 |
| ID |
FR-009 |
| 제목 |
계약 취소 |
| 우선순위 |
필수 |
| 설명 |
계약 생성자가 진행 중인 계약을 취소한다 |
비즈니스 규칙:
- 초안(draft) 또는 대기(pending) 상태에서만 취소 가능
- 완료/만료 상태는 취소 불가
- 취소 시 계약 상태 → cancelled
FR-010: 리마인더 발송
| 항목 |
내용 |
| ID |
FR-010 |
| 제목 |
서명 리마인더 발송 |
| 우선순위 |
보통 |
| 설명 |
미서명 상태인 서명자에게 리마인드 이메일을 재발송한다 |
비즈니스 규칙:
- 대기(pending) 또는 부분서명(partially_signed) 상태에서만 가능
- 다음 서명 순서 서명자에게 발송
FR-011: 문서 다운로드
| 항목 |
내용 |
| ID |
FR-011 |
| 제목 |
계약 문서 다운로드 |
| 우선순위 |
필수 |
| 설명 |
로그인 사용자가 원본 또는 서명 완료 PDF를 다운로드한다 |
비즈니스 규칙:
- 서명 완료 PDF가 있으면 서명본 다운로드
- 없으면 원본 PDF 다운로드
- 다운로드 시 감사 로그 기록
FR-012: 문서 무결성 검증
| 항목 |
내용 |
| ID |
FR-012 |
| 제목 |
문서 무결성 검증 |
| 우선순위 |
필수 |
| 설명 |
저장된 문서가 업로드 시점과 동일한지 SHA-256 해시로 검증한다 |
상세 요구사항:
| # |
요구사항 |
비고 |
| 1 |
원본 PDF 해시 검증 |
업로드 시 저장된 해시와 현재 파일 해시 비교 |
| 2 |
서명 완료 PDF 해시 검증 |
|
| 3 |
검증 결과 표시 |
무결성 확인/위변조 감지 |
| 4 |
hash_equals() 사용 |
타이밍 공격 방지 |
4. 비기능 요구사항
NFR-001: 보안
| # |
요구사항 |
상세 |
| 1 |
접근 토큰 |
128자 랜덤 문자열, URL-safe |
| 2 |
OTP 보안 |
6자리, 5분 유효, 5회 제한 |
| 3 |
파일 무결성 |
SHA-256 해시 생성 및 검증 |
| 4 |
감사 추적 |
모든 행위 기록, 삭제 불가 |
| 5 |
IP/UA 기록 |
서명 시점의 네트워크 정보 기록 |
| 6 |
HTTPS 통신 |
모든 API 호출은 HTTPS |
| 7 |
파일 접근 제어 |
직접 URL 접근 불가, Controller 스트리밍만 허용 |
NFR-002: 성능
| # |
요구사항 |
기준 |
| 1 |
PDF 업로드 |
20MB 이하, 10초 이내 |
| 2 |
API 응답 시간 |
일반 조회 500ms 이내 |
| 3 |
목록 페이지네이션 |
기본 20건, 1초 이내 |
| 4 |
OTP 발송 |
요청 후 30초 이내 이메일 도착 |
NFR-003: 가용성
| # |
요구사항 |
기준 |
| 1 |
서명 링크 유효 기간 |
계약 만료일까지 |
| 2 |
서명 세션 |
인증 후 유지 (별도 만료 없음) |
| 3 |
동시 접속 |
동일 계약에 여러 서명자 동시 접근 가능 |
NFR-004: 호환성
| # |
요구사항 |
비고 |
| 1 |
브라우저 지원 |
Chrome, Edge, Safari, Firefox 최신 2버전 |
| 2 |
모바일 지원 |
반응형 UI, 터치 서명 |
| 3 |
PDF 렌더링 |
PDF.js 기반 클라이언트 렌더링 |
NFR-005: 법적 요건
| # |
요구사항 |
전자서명법 조항 |
| 1 |
서명자 확인 |
이메일 OTP 본인인증 (제2조) |
| 2 |
서명 의사 확인 |
동의 체크박스 (제2조) |
| 3 |
문서 변경 감지 |
SHA-256 해시 비교 (제2조) |
| 4 |
서명 후 변경 불가 |
서명 완료 후 수정 차단 (제2조) |
| 5 |
개인정보 보호 |
수집: 이름, 이메일, IP / 보관: 5년 |
NFR-006: 멀티테넌트
| # |
요구사항 |
비고 |
| 1 |
데이터 격리 |
tenant_id 기반 글로벌 스코프 |
| 2 |
공개 서명 시 스코프 해제 |
withoutGlobalScopes() 사용 |
| 3 |
감사 로그에 tenant_id 포함 |
|
NFR-007: 국제화 (i18n)
| # |
요구사항 |
비고 |
| 1 |
하드코딩 메시지 금지 |
__('message.esign.*') 패턴 사용 |
| 2 |
성공 메시지 12개 |
lang/ko/message.php |
| 3 |
에러 메시지 16개 |
lang/ko/error.php |
| 4 |
다국어 확장 가능 |
lang/en/ 추가로 영문 지원 |
5. 사용자 시나리오
US-001: 계약 생성부터 완료까지 (정상 플로우)
사후 조건: 계약 상태 = completed, 양쪽 서명 이미지 저장됨, 감사 로그 기록됨
US-002: 서명 거절
US-003: 리마인더 발송
US-004: 계약 취소
6. 상태 전이 규칙
6.1 계약 상태
| 현재 상태 |
이벤트 |
다음 상태 |
| - |
계약 생성 |
draft |
| draft |
서명 요청 발송 |
pending |
| draft |
취소 |
cancelled |
| pending |
첫 서명 완료 |
partially_signed |
| pending |
취소 |
cancelled |
| pending |
거절 |
rejected |
| pending |
기한 초과 |
expired |
| partially_signed |
모든 서명 완료 |
completed |
| partially_signed |
거절 |
rejected |
| partially_signed |
기한 초과 |
expired |
변경 불가 상태: completed, expired, cancelled, rejected
6.2 서명자 상태
| 현재 상태 |
이벤트 |
다음 상태 |
| - |
서명자 생성 |
waiting |
| waiting |
이메일 발송 |
notified |
| notified |
OTP 인증 완료 |
authenticated |
| authenticated |
서명 완료 |
signed |
| notified/authenticated |
거절 |
rejected |
7. 데이터 요구사항
7.1 주요 엔티티
| 엔티티 |
테이블명 |
설명 |
| 계약 |
esign_contracts |
계약 마스터 정보 |
| 서명자 |
esign_signers |
서명자 정보 및 인증/서명 상태 |
| 서명 필드 |
esign_sign_fields |
PDF 위의 서명 위치 정보 |
| 감사 로그 |
esign_audit_logs |
모든 행위 기록 (삭제 불가) |
7.2 데이터 보관 규칙
| 데이터 |
보관 기간 |
근거 |
| 계약 정보 |
5년 |
전자상거래법 |
| 서명 이미지 |
5년 |
전자상거래법 |
| 감사 로그 |
영구 |
법적 증거력 확보 |
| PDF 파일 |
5년 |
전자상거래법 |
7.3 관계
8. 인터페이스 요구사항
8.1 화면 목록
| # |
화면ID |
화면명 |
경로 |
접근 권한 |
| 1 |
ES_DASH |
계약 대시보드 |
/esign |
로그인 필요 |
| 2 |
ES_CREATE |
새 계약 생성 |
/esign/create |
로그인 필요 |
| 3 |
ES_DETAIL |
계약 상세 |
/esign/{id} |
로그인 필요 |
| 4 |
ES_FIELDS |
서명 위치 지정 |
/esign/{id}/fields |
로그인 필요 |
| 5 |
ES_SEND |
서명 요청 발송 |
/esign/{id}/send |
로그인 필요 |
| 6 |
ES_AUTH |
본인인증 (OTP) |
/esign/sign/{token} |
공개 (토큰) |
| 7 |
ES_SIGN |
전자서명 수행 |
/esign/sign/{token}/sign |
공개 (토큰) |
| 8 |
ES_DONE |
서명 완료 |
/esign/sign/{token}/done |
공개 (토큰) |
8.2 API 목록
인증 필요 (10개):
| Method |
엔드포인트 |
설명 |
| GET |
/api/v1/esign/contracts |
계약 목록 |
| POST |
/api/v1/esign/contracts |
계약 생성 |
| GET |
/api/v1/esign/contracts/stats |
통계 |
| GET |
/api/v1/esign/contracts/{id} |
상세 |
| POST |
/api/v1/esign/contracts/{id}/cancel |
취소 |
| POST |
/api/v1/esign/contracts/{id}/fields |
필드 설정 |
| POST |
/api/v1/esign/contracts/{id}/send |
발송 |
| POST |
/api/v1/esign/contracts/{id}/remind |
리마인더 |
| GET |
/api/v1/esign/contracts/{id}/download |
다운로드 |
| GET |
/api/v1/esign/contracts/{id}/verify |
검증 |
토큰 기반 (6개):
| Method |
엔드포인트 |
설명 |
| GET |
/api/v1/esign/sign/{token} |
계약 정보 |
| POST |
/api/v1/esign/sign/{token}/otp/send |
OTP 발송 |
| POST |
/api/v1/esign/sign/{token}/otp/verify |
OTP 검증 |
| GET |
/api/v1/esign/sign/{token}/document |
PDF 조회 |
| POST |
/api/v1/esign/sign/{token}/submit |
서명 제출 |
| POST |
/api/v1/esign/sign/{token}/reject |
거절 |
8.3 이메일 템플릿
| 이메일 |
발송 시점 |
수신자 |
| 서명 요청 |
서명 발송/리마인더 시 |
다음 서명자 |
| OTP 코드 |
OTP 발송 요청 시 |
서명자 본인 |
9. 제약사항
| # |
제약사항 |
영향 |
| 1 |
SAM 기존 DB 공유 |
esign_ 접두사로 테이블명 충돌 방지 |
| 2 |
마이그레이션은 API 프로젝트에서만 |
MNG에서 마이그레이션 생성 금지 |
| 3 |
메뉴 시더 실행 금지 |
tinker 명령어로 수동 추가 |
| 4 |
Docker 환경 |
모든 artisan 명령은 docker exec 사용 |
| 5 |
PDF만 지원 |
워드/한글 문서는 PDF 변환 후 사용 |
| 6 |
2인 서명만 |
v1에서 3인 이상 미지원 |
| 7 |
React 하이브리드 |
CDN + Babel 브라우저 트랜스파일링 |
10. 용어 정의
| 용어 |
정의 |
| 갑 (Creator) |
계약서를 생성하고 서명을 요청하는 당사자 |
| 을 (Counterpart) |
이메일 링크를 통해 서명하는 상대방 |
| OTP |
One-Time Password, 일회용 인증 코드 |
| 감사 로그 (Audit Trail) |
계약 관련 모든 행위의 시간순 기록 |
| 접근 토큰 (Access Token) |
서명 링크에 포함되는 128자 고유 식별자 |
| 세션 토큰 (Session Token) |
OTP 인증 후 발급되는 서명 세션 식별자 |
| 서명 필드 (Sign Field) |
PDF 위에 배치되는 서명/텍스트/날짜 입력 영역 |
| 순차 서명 |
지정된 순서대로 한 명씩 서명하는 방식 |
11. 변경 이력
| 버전 |
날짜 |
작성자 |
변경 내용 |
| v1.0 |
2026-02-12 |
DX 추진팀 |
초기 작성 (구현 완료 기준) |
12. 관련 문서
본 요구사항 정의서는 SAM E-Sign v1.0의 구현 결과를 기반으로 작성되었습니다.