문제의 출발점
문서를 다시 발급할 때 파일만 새로 만들면 발행 사실과 진위 여부를 추적할 수 없습니다. 공인 성적서는 최신 파일 하나와 함께 이전 발급본의 상태도 남겨야 했습니다.
- 최초 발급본과 재발급본의 관계
- 기존 문서의 유효·폐기 상태
- 재발급·폐기의 주체, 시점과 사유
- 과거 진위 확인 코드에 표시할 상태
- 동시 재발급의 중복 방지
새 발급본으로 기존 파일을 덮는 순간 이전 문서의 식별값과 발행 시점, 유효 상태도 함께 사라집니다. 이 정보가 남도록 발급본마다 이력을 따로 만들고 원본·재발급·폐기 관계를 연결했습니다.
덮어쓰기 모델의 한계
아래 코드는 핵심 동작만 보여 주도록 실제 클래스·테이블·설정 이름을 바꾼 예시입니다.
DOCUMENT_KEY | FILE_KEY | ISSUED_AT | STATUS재발급 시 같은 행을 갱신하면 이전 식별값, 파일, 발행 시점과 진위 확인 상태가 사라집니다. 별도 로그에 변경 전후 문자열을 남기는 방식도 실제 문서와 이력의 관계를 매번 해석해야 합니다.
이 서비스에서 이력은 문서의 유효성을 판단하는 업무 데이터였습니다. 문서 버전을 독립된 행으로 관리해야 관계를 매번 로그 문자열에서 복원하지 않아도 됩니다.
발행 순번을 문서 식별 기준에 넣었습니다
아래 DDL은 실제 운영 스키마가 아니라 개념을 설명하기 위한 공개용 예시입니다. 실제 테이블·컬럼·제약 이름, 타입 길이와 인덱스는 재현하지 않습니다.
CREATE TABLE DOCUMENT_ISSUE (
TENANT_KEY VARCHAR2(20) NOT NULL,
BUSINESS_KEY VARCHAR2(40) NOT NULL,
ISSUE_SEQUENCE NUMBER NOT NULL,
DOCUMENT_KEY VARCHAR2(40),
FILE_KEY VARCHAR2(40),
STATUS VARCHAR2(20),
STATUS_REASON VARCHAR2(200),
CHANGED_AT DATE,
PRIMARY KEY (TENANT_KEY, BUSINESS_KEY, ISSUE_SEQUENCE)
);기존 데이터는 최초 발행본을 의미하는 순번으로 이관하고, 재발급본은 같은 업무 키를 공유하면서 다른 발행 순번을 갖게 했습니다.
- 원본과 재발급본이 같은 업무 대상에 속한다는 사실이 키에 드러납니다.
- 파일과 진위 확인 정보를 발행 단위로 보존할 수 있습니다.
- 원본을 삭제하거나 덮어쓰지 않고 현재 유효한 문서를 결정할 수 있습니다.
- 재발급 이력과 감사 추적을 같은 데이터에서 구성할 수 있습니다.
문서 번호와 유효 상태를 함께 관리했습니다
재발급 문서 번호에는 원본과 구분할 수 있는 접미사를 붙였습니다. 실제 접미사 값과 생성 규칙은 일반화했습니다.
문서 번호의 표시 규칙은 다음 처리와 연결됐습니다.
- 재발급 여부 검색
- 상세 화면의 발행 이력
- 원본·재발급·폐기 문서의 진위 확인 메시지
- 반복 재발급 시 신규 행 생성 여부 판단
삭제 대신 폐기 상태를 기록
이미 발행된 문서를 물리적으로 삭제하면 과거 고객이 보유한 문서와 시스템 기록을 연결할 수 없습니다. 따라서 폐기는 삭제가 아니라 상태 변경으로 관리했습니다.
STATUS
STATUS_REASON
CHANGED_BY
CHANGED_AT폐기된 코드로 조회하면 단순히 “문서 없음”을 반환하지 않고, 실제 존재했던 문서가 더 이상 유효하지 않다는 상태와 후속 문서 관계를 안내했습니다.
동시 재발급은 별도 시나리오로 검증
두 사용자가 같은 원본을 거의 동시에 선택하면 각각 “아직 재발급본이 없다”고 판단할 수 있습니다. 버튼 중복 클릭 방지만으로 해결하지 않고 서버와 DB 양쪽에서 중복 생성을 막고 별도 테스트했습니다.
개념 모델은 다음과 같습니다.
public DocumentIssue reissue(DocumentKey documentKey) {
DocumentIssue current = repository.lockCurrent(documentKey);
if (current.hasActiveReissue()) {
return current.activeReissue();
}
return repository.insertNextIssue(current);
}검증 시나리오
- 폐기 여부·재발급 여부 검색
- 최초 재발급 시 신규 발행 이력 생성
- 반복 재발급에서 불필요한 행이 추가되지 않는지 확인
- 재발급 문서 폐기
- 동시 재발급 시 중복 생성 방지
- 상세 화면의 발행 이력
- 원본·재발급·폐기 상태별 진위 확인 문구
- 발급 파일의 표시명과 저장명 정합성
- 최대 50건 일괄 처리
동시성 테스트와 사용자 확인을 마친 뒤 2024년에 운영에 반영했습니다.
현재 상태와 전체 이력을 함께 조회
현재 유효한 문서는 발행 순번과 상태를 기준으로 선택하고, 감사 이력은 같은 업무 키의 발행 행을 순서대로 조회합니다.
SELECT *
FROM DOCUMENT_ISSUE
WHERE TENANT_KEY = :tenantKey
AND BUSINESS_KEY = :businessKey
ORDER BY ISSUE_SEQUENCE DESC;현재값을 별도 컬럼에 중복 저장하면 갱신 순서와 정합성 규칙을 추가로 관리해야 합니다. 이력형 모델은 조회가 조금 복잡해지는 대신 현재 상태가 만들어진 과정을 설명할 수 있습니다.
정리
감사 추적이 필요한 문서에서 이력은 유효한 발급본을 판단하는 기준입니다.
- 발행된 문서는 덮어쓰거나 삭제하지 않습니다.
- 발행 순번을 문서 식별 기준에 포함합니다.
- 원본·재발급·폐기를 다른 상태와 관계로 모델링합니다.
- 진위 확인 화면도 같은 상태 모델을 사용합니다.
- 동시 요청과 반복 실행을 별도 시나리오로 검증합니다.