전시로 돌아가기전자계약 · 신규 구축

Ansimsign

안심사인

계약서를 만드는 화면부터, 서명이 끝난 문서까지.

안심사인 실제 앱의 계약 목록. 개인정보가 아닌 예시 계약 데이터입니다.
안심사인 계약 편집기에서 수신자별 서명란을 놓는 화면. 예시 문서입니다.
실제 앱 · 예시 계약 데이터
작업 구분
회사 프로젝트
작업 기간
2026.06 — 현재
현재 상태
서비스 운영 · 후속 개선

출발점과 담당 범위

전자계약 · 신규 구축

맡은 범위

요구사항과 제품 정책, 웹 화면·API·DB의 개발, 검증과 배포, 사용자 대응을 담당했습니다. 계약 작성에서 완료 문서 조회까지 기능별로 끊지 않고 전체 사용 흐름을 맡은 프로젝트입니다.

시작할 때의 상태

전자계약 서비스를 새로 구축했습니다.

개발 범위 · 기술 · 협업 자세히 읽기

시작할 때의 상태

전자계약 서비스를 새로 구축했습니다. 계약을 관리하던 실무 경험을 바탕으로 발신자·수신자가 각각 무엇을 해야 하는지 정리하고, 운영을 시작한 뒤에도 고객 피드백과 배포를 함께 맡았습니다.

작업 개요

계약 작성·발송·본인확인·서명·PDF 봉인과 회사 공간을 하나의 서비스로 연결했습니다. 실제 사용 중 들어온 피드백을 화면 수정으로 끝내지 않고, 데이터가 저장되고 최종 문서로 남는 과정까지 따라가며 개선하고 있습니다.

개발·개선 범위

  • 계약서 업로드·템플릿·필드 배치·수신자 설정과 발송 화면
  • 본인확인·서명 세션·임시 저장·최종 제출 API와 데이터 모델
  • PDF 필드 합성·긴 글 별지·봉인 워커·타임스탬프·파일 검증
  • 사람과 회사별 소속의 분리, 공간 전환·권한·강퇴·탈퇴 정책
  • 이메일·문자·알림톡 발송 연동, 회귀 검증·배포·실사용 피드백 반영
사용한 기술
TypeScript · React · Vite · Node.js · Express · PostgreSQL · Knex · AWS ECS · S3 · Docker · GitHub Actions

기존 자산 · 외부 서비스 · AI 활용

Claude Code와 Codex를 조사·구현·독립 리뷰·테스트에 활용했습니다. 제품 정책과 작업 범위, 배포 여부를 결정하고 재현 결과를 확인했습니다. PASS·메시지·TSA 공급자와 PDF·문서 변환 라이브러리는 연동한 외부 구성요소입니다.

제품 화면과 구조 요약

제품 화면과 구조 요약 보기
안심사인 · 전자계약실제 제품 화면
안심사인 필드 배치 편집 콘솔. 데모 계약서와 예시 인명을 사용한 실제 화면.
계약서 위에 서명 위치를 정하는 화면실제 콘솔 · 데모 계약서 / 예시 인명

문제 해결 / 소속과 로그인 분리

한 회사에서 나가도, 다른 회사의 로그인은 남아야 합니다.

회사에서 나가는 범위와, 사람의 로그인 정보를 지우는 범위를 분리했습니다.

사람 하나, 회사별로 다른 소속

한 사람의 로그인공통 인증 정보
소속 종료회사 A

강퇴·탈퇴 후 쓰기 차단

늦게 도착한 수정 요청도 다시 확인
소속 유지회사 B

공통 로그인 정보 보존

다른 소속까지 함께 지우지 않음

마지막 소속이라면이전 회사에 남은 소셜 연결까지 정리

다른 소속이 남는 경우의 분기입니다. 일시 정지를 강퇴·탈퇴와 같게 취급하지 않습니다.

문제

한 회사의 탈퇴가 다른 회사의 로그인까지 건드릴 수 있었습니다.

바꾼 점

인증 정보와 소속을 나누고, 수정 요청이 끝나기 전에도 강퇴·탈퇴 상태를 다시 확인합니다.

확인한 것

요청 중 강퇴, 다른 소속이 남은 탈퇴, 마지막 소속의 탈퇴를 각각 확인했습니다.

조사·판단·검증 과정 읽기

마주한 문제

한 사람과 한 회사의 계정을 같은 축으로 다루던 구조에 여러 회사 공간이 필요해졌습니다. 회사에서 나가는 행동이 사람의 로그인 정보까지 지우거나, 강퇴 직전에 시작한 수정 요청이 정리한 정보를 다시 쓰는 문제가 생길 수 있었습니다.

확인한 과정

토큰 발급을 바꾸는 것과 실제 비밀번호 조회를 옮기는 것은 다른 작업이었습니다. 로그인·추가 인증·프로필 변경·소셜 연결의 읽기와 쓰기를 각각 추적했습니다. 탈퇴 시 다른 소속을 보존하는 백엔드는 이미 있는 부분도 있어, 새 삭제 기능을 만들기보다 잘못된 화면 안내와 빠진 정리 경로를 구분했습니다.

선택한 방법

사람의 인증 정보와 회사별 소속을 분리했습니다. 같은 트랜잭션에서 쓰기 사본을 맞춘 뒤 토큰 검증, 실제 자격 조회 순서로 전환했습니다. 다른 소속이 남으면 공통 로그인 정보를 보존하고, 마지막 소속이 끝나면 이전 회사에 남은 소셜 연결까지 정리했습니다. 프로필 쓰기와 소셜 콜백에도 강퇴·탈퇴 상태를 다시 확인하는 조건을 뒀습니다.

어떻게 확인했는가

요청 도중 강퇴되는 순서, 다른 회사의 소속이 남는 경우, 마지막 소속에서 탈퇴하는 경우를 나눠 확인했습니다. 쓰기 사본을 다시 켜는 과정에서는 이메일 변경과 신규 가입이 충돌하는 반례를 찾아, 기존 사본 동기화를 신규 백필보다 먼저 하도록 순서를 바꿨습니다. 운영 개방 때는 스냅샷과 백필 재실행 결과를 별도로 확인했습니다.

단계별 처리와 경계

  1. 쓰기 사본 정렬

    기존 인증 경로를 유지하며 실제 갱신 결과를 같은 트랜잭션으로 옮깁니다.

  2. 토큰 검증 전환

    사람·회사·소속의 관계와 각 인증 버전을 함께 확인합니다.

  3. 자격 조회 전환

    비밀번호와 추가 인증이 실제로 읽는 원본까지 옮깁니다.

  4. 탈퇴 범위 확인

    다른 소속이 남는 경우와 마지막 소속이 끝나는 경우를 구분합니다.

  5. 회사 공간 개방

    복구 준비 후 다중 소속을 열고 백필·재실행 결과를 확인합니다.

구조도와 처리 경계 자세히 보기

공통 로그인은 사람에게, 회사 권한은 소속에게

사람의 인증 축과 회사별 권한 축을 나누고, 다른 소속의 존재 여부로 보존·정리 범위를 결정합니다.

  • 처리·명시된 호출
  • 비동기·별도 요청
  • 데이터 읽기·참조
  • 실패·제한 분기
공통 로그인은 사람에게, 회사 권한은 소속에게사람의 인증 축과 회사별 권한 축을 나누고, 다른 소속의 존재 여부로 보존·정리 범위를 결정합니다. 아래 단계별 설명에서 각 처리와 연결을 글로 읽을 수 있습니다.사람·소속의 데이터 관계API / DB 실행남은 소속에 따른 보존·정리다른 소속 있음마지막 소속사람의 인증 정보person·비밀번호·ptv회사 소속과 분리회사별 소속app_user·회사·역할소속별 권한 버전 mav토큰 발급·대조person ptv·소속 mav종결 상태·회사 확인회사 공간 전환같은 사람의 소속 선택원래 만료시각 승계소셜 연결person과 원래 소속보존·회수 범위 분리로그인 자격 조회person에서 비밀번호 조회소속 선택 순서는 별도프로필 쓰기 검사UPDATE 순간 다시 확인removed·withdrawn 차단강퇴·회사 탈퇴대상 소속·회사만 종료서로 다른 DB 진입점다른 소속 판정removed·withdrawn 제외suspended는 남은 소속소셜 콜백 검사연결 도중 강퇴돼도 재검사종결 소속은 신규 연결 X공통 신원 보존person·소셜 연결 유지종료 소속의 권한만 변경마지막 소속 정리사람·소속의 자격 정리person 범위 소셜 회수
좁은 화면에서는 좌우로 움직여 읽으세요. 키보드로 구조도에 초점을 둔 뒤 방향키를 사용할 수 있습니다.
판정·계산식

남은 소속 = 같은 person의 다른 소속 중 status NOT IN (removed, withdrawn)

닫힌 소속과 정지된 소속
removed·withdrawn만 종결로 봅니다. suspended도 다른 소속 수에 포함하지만 모든 기능을 허용하지는 않습니다. 강퇴 함수가 받는 대상은 active뿐입니다.
마지막 회사에서 떠날 때
B회사 탈퇴 때 B의 연결만 지우면 앞서 보존한 A의 연결이 남습니다. 마지막 정리를 person 범위로 넓히고, 소셜 인증 중 강퇴돼도 새 연결 전에 다시 검사합니다.
되돌릴 수 있는 전환 구간
쓰기 사본, 토큰 발급·검증, 자격 조회를 순차 전환했습니다. 다중 소속은 미러·v2 발급을 전제로 엽니다. 첫 공유 person 이후에는 플래그 OFF로 1:1 모델이 복원되지 않습니다.

이 구조의 한계suspended가 모든 기능에서 허용된다는 뜻은 아닙니다. 회사 탈퇴의 보존 정책과 계정·계약 증거 전체 삭제를 구분합니다.

단계별 설명 · 구조도를 글로 읽기
  • 사람의 인증 정보

    person·비밀번호·ptv · 회사 소속과 분리

    • 회사별 소속 (데이터 읽기·참조)
    • 로그인 자격 조회 (데이터 읽기·참조)
  • 회사별 소속

    app_user·회사·역할 · 소속별 권한 버전 mav

    • 토큰 발급·대조 (데이터 읽기·참조)
    • 소셜 콜백 검사 (데이터 읽기·참조)
  • 토큰 발급·대조

    person ptv·소속 mav · 종결 상태·회사 확인

    • 회사 공간 전환 (데이터 읽기·참조)
    • 프로필 쓰기 검사 (처리·명시된 호출)
    • 강퇴·회사 탈퇴 (처리·명시된 호출)
  • 회사 공간 전환

    같은 사람의 소속 선택 · 원래 만료시각 승계

    • 토큰 발급·대조 (처리·명시된 호출)
  • 소셜 연결

    person과 원래 소속 · 보존·회수 범위 분리

  • 로그인 자격 조회

    person에서 비밀번호 조회 · 소속 선택 순서는 별도

    • 토큰 발급·대조 (처리·명시된 호출)
  • 프로필 쓰기 검사

    UPDATE 순간 다시 확인 · removed·withdrawn 차단

  • 강퇴·회사 탈퇴

    대상 소속·회사만 종료 · 서로 다른 DB 진입점

    • 다른 소속 판정 (처리·명시된 호출)
  • 다른 소속 판정

    removed·withdrawn 제외 · suspended는 남은 소속

    • 공통 신원 보존 (다른 소속 있음)
    • 마지막 소속 정리 (마지막 소속)
  • 소셜 콜백 검사

    연결 도중 강퇴돼도 재검사 · 종결 소속은 신규 연결 X

    • 소셜 연결 (처리·명시된 호출)
  • 공통 신원 보존

    person·소셜 연결 유지 · 종료 소속의 권한만 변경

  • 마지막 소속 정리

    사람·소속의 자격 정리 · person 범위 소셜 회수

구조 탐색과 실제 소스 대조를 바탕으로 편집한 작동도입니다. 런타임 전체의 자동 검증을 뜻하지 않습니다.

문제 해결 / 긴 글과 최종 문서

입력할 수 있는 글이라면, 완성된 계약서에서도 읽혀야 합니다.

작은 칸에서 잘리는 긴 글을, 앞뒤를 찾아 읽지 않아도 되는 전문 별지로 옮겼습니다.

칸은 작아도, 문맥은 끊기지 않도록

수신자가 입력한 긴 글
입력 전문
칸을 넘기면
본문과 별지를 합쳐 최종 PDF로
원래 페이지
본문 칸
기존 필드 유지
별지
원래 쪽 번호 · 필드 이름
나머지가 아닌 전문

넘치지 않으면별지를 만들지 않음

표시 방식 설명용 도식입니다. 별지의 페이지 상한을 넘으면 미수록 안내를 남깁니다.

문제

화면에서 입력한 긴 글이 최종 PDF에서는 작아지거나 잘렸습니다.

바꾼 점

칸을 넘친 필드는 나머지만 자르지 않고 전문과 원래 위치를 별지에 싣습니다.

확인한 것

DB 조회부터 PDF 출력까지 연결하고, 문단 보존과 긴 입력의 처리 시간도 확인했습니다.

조사·판단·검증 과정 읽기

마주한 문제

수신자가 긴 내용을 입력해도 최종 PDF의 작은 칸에서는 글이 줄어들거나 뒤가 잘렸습니다. 화면에서 받은 내용과 실제로 전달하는 문서가 달랐습니다.

확인한 과정

입력 길이를 더 제한하려면 PDF의 실제 칸 크기와 페이지 정보를 알아야 했고, 추가 데이터 작업뿐 아니라 정상 서명을 막는 문제도 있었습니다. 넘친 부분만 별지로 보내면 독자가 본문과 뒷장을 이어 읽어야 한다는 점도 검토했습니다.

선택한 방법

기존 한 줄 필드는 유지하고 긴 글 필드는 줄바꿈하도록 나눴습니다. 그래도 넘치는 필드는 잔여 부분이 아닌 전문을 별지에 싣고, 원래 쪽 번호와 필드 이름을 함께 표시했습니다. 첫 장의 종이 규격을 따르며, 넘친 내용이 없을 때는 별지를 만들지 않습니다.

어떻게 확인했는가

렌더 함수만 시험하면 실제 DB 조회에서 필드 이름이 빠져도 통과했습니다. 조회부터 출력까지 이어지는 통합 검증을 추가했습니다. 이후 빈 줄 정리용 AI 초안의 정규식이 긴 입력에서 워커를 오래 점유하는 반례가 나와 줄 단위 처리로 바꿨습니다. 페이지 수뿐 아니라 문단 보존·공백 처리 결과·긴 입력의 시간 상한도 검사하도록 보강했습니다.

단계별 처리와 경계

  1. 최종 입력 조회

    값뿐 아니라 필드 이름·좌표·원본 쪽 정보를 함께 읽습니다.

  2. 본문 칸에 합성

    한 줄 필드와 긴 글 필드의 표시 규칙을 나눕니다.

  3. 넘침 판정

    칸을 넘은 긴 글의 전체 내용과 원래 위치를 별지 입력으로 넘깁니다.

  4. 전문 별지 작성

    문단을 보존하며 배치하고 상한에 도달하면 안내를 남깁니다.

  5. 최종 PDF 봉인

    본문과 별지가 합쳐진 문서를 이후 봉인 처리의 입력으로 사용합니다.

작동 방식 더 살펴보기

입력한 글이 최종 문서에 남는 과정

본문 합성, 넘침 판정, 별지 작성과 봉인까지 단계별로 살펴봅니다.

문제 해결 / 서명 완료와 봉인

서명을 다 받았다는 것과, 최종 파일이 준비됐다는 것은 다릅니다.

서명은 끝났지만 파일은 아직 준비 중인 시간을, 별도의 상태로 다뤘습니다.

완료를 두 번 구분하는 이유

첫 번째 완료서명 완료

모두 제출했음

같은 DB 트랜잭션에서 봉인 작업 생성
이 사이의 시간은 워커가 맡음
  1. 원본 해시 대조
  2. 본문·별지 합성
  3. 외부 TSA 요청
  4. 작업 점유 재확인
봉인 전 체인 헤드최종 PDF 해시두 값을 묶어 타임스탬프에 연결
두 번째 완료봉인 완료

최종 결과 확정

봉인 상태·감사 이벤트·교부 예약 기록
TSA는 봉인 전 헤드와 PDF 해시를 고정합니다. 이후 envelope_sealed까지 포함한 최종 헤드 전체의 앵커는 아닙니다.

문제

서명 완료 뒤에도 PDF 제작과 외부 타임스탬프 발급이 남아 있었습니다.

바꾼 점

봉인 작업을 워커로 넘기고, 봉인 전 감사체인 헤드와 최종 PDF 해시를 TSA에 연결합니다.

확인한 것

두 완료 상태와 해시 연결을 나눠 검사하고, 점유를 잃은 작업의 결과 확정을 차단했습니다.

조사·판단·검증 과정 읽기

마주한 문제

모든 사람이 서명한 뒤에도 PDF 합성, 저장소 쓰기, 외부 타임스탬프 발급이 남습니다. 이를 하나의 완료 상태로 다루면 아직 준비되지 않은 파일을 안내하거나, 외부 서비스 지연을 계약 제출 실패로 오해하게 됩니다.

확인한 과정

입력 임시 저장, 최종 제출, 전체 서명 완료, 봉인 작업의 경계를 나눴습니다. 워커가 오래 걸리거나 재시도할 때 작업을 더 이상 소유하지 않은 실행이 결과를 확정할 수 있는지, 타임스탬프가 정확히 어느 파일과 감사 기록을 가리키는지도 확인했습니다.

선택한 방법

최종 제출 트랜잭션에서 전체 서명 완료와 봉인 작업 생성을 처리하고, PDF 제작은 워커가 이어받도록 연결했습니다. 워커는 원본 해시를 대조하고 최종값을 합성한 뒤, 봉인 전 감사체인 헤드와 최종 PDF 해시를 묶어 TSA 타임스탬프를 요청합니다. 결과 확정 직전에도 작업 점유를 다시 확인합니다.

어떻게 확인했는가

서명 완료와 봉인 완료를 별도로 확인하고, 파일 해시·감사체인·타임스탬프의 연결 및 오래된 작업의 확정 차단을 회귀 검증했습니다. 공개 PDF 업로드 검증은 파일 자체를 검사하는 경로로, 계약 DB의 감사 기록까지 대조하는 검증과 구분했습니다.

단계별 처리와 경계

  1. 서명 최종 제출

    필수값을 검증하고 임시 입력을 확정값으로 옮깁니다.

  2. 전체 서명 완료

    대상자의 제출이 끝나면 같은 DB 트랜잭션에서 봉인 작업을 생성합니다.

  3. PDF 제작

    워커가 원본 해시를 확인하고 본문·별지를 합성해 최종 파일을 만듭니다.

  4. 외부 시점 연결

    봉인 전 체인 헤드와 최종 PDF 해시를 묶어 TSA에 요청합니다.

  5. 봉인 결과 확정

    점유를 재확인한 뒤 봉인 상태·감사 이벤트·교부 예약을 기록합니다.

구조도와 처리 경계 자세히 보기

서명 완료와 PDF 봉인은 서로 다른 상태다

입력 저장·서명 완료·PDF 봉인을 구분하고, 넘친 입력은 DB의 최종값을 조회해 별지로 연결합니다.

  • 처리·명시된 호출
  • 비동기·별도 요청
  • 데이터 읽기·참조
  • 실패·제한 분기
서명 완료와 PDF 봉인은 서로 다른 상태다입력 저장·서명 완료·PDF 봉인을 구분하고, 넘친 입력은 DB의 최종값을 조회해 별지로 연결합니다. 아래 단계별 설명에서 각 처리와 연결을 글로 읽을 수 있습니다.입력·제출 API / DB — 임시 입력은 최종 서명과 다릅니다봉인 워커 — DB 조회 후 외부 I/O·PDF 합성저장·봉인일시 오류파일을 업로드하면서명 세션 확인수신자·만료 재검사인증 방식별 증거임시 입력 저장field_draft에 저장세션·필드 소유 확인서명 최종 확정필수값 검사·값 승격세션 소비·감사 기록전체 서명 판정모든 서명자가 완료?미완료면 대기·다음 차수completed봉투 완료·작업 생성PDF 봉인 완료와 다름봉인 작업 점유워커가 처리할 작업 점유lease·attempt 확인최종 데이터 조회원문값·label·좌표짧은 DB 트랜잭션원본 PDF 확인저장소 읽기·해시 대조DB 잠금 밖 외부 I/O본문·별지 합성넘친 필드의 전문 연결100쪽 상한·잘림 안내PDF 서명 생성최종 바이트·해시 생성PDF 내부 TSA는 조건부PDF 저장주 TSA 요청 전에 put저장소와 DB는 별개TSA 앵커봉인 전 헤드+PDF 해시외부 응답 후 DB 확정sealed 확정lease 대조·교부 예약TSA·감사 함께 기록TSA 일시 지연재시도 시각으로 미룸completed 상태로 대기파일 자체 검증업로드 PDF만 검증계약 DB·감사 조회 없음
좁은 화면에서는 좌우로 움직여 읽으세요. 키보드로 구조도에 초점을 둔 뒤 방향키를 사용할 수 있습니다.
판정·계산식

preimage = 봉인 전 head ∥ SHA256(최종 PDF) · messageImprint = SHA256(preimage)

봉인본이 아직 없는 완료 상태
전체 제출이 끝나면 completed 변경과 봉인 작업 생성을 같은 DB 트랜잭션으로 처리합니다. 워커의 PDF·TSA 처리가 끝나 sealed로 확정되기 전에는 봉인본이 없을 수 있습니다.
렌더 함수 밖에서 빠진 필드 이름
렌더 테스트만으로는 조회에서 label이 빠지는 문제를 잡지 못했습니다. DB의 최종값·이름이 별지까지 전달되는지, 상한을 넘으면 잘림을 안내하는지 연결해서 확인했습니다.
외부 요청과 DB 확정의 간격
교부 예약은 실제 수신과 다릅니다. TSA 일시 장애는 시도를 차감하지 않고 미룹니다. DB 확정 뒤 저장소의 확정본을 다시 쓰지만, DB·저장소·TSA가 함께 롤백되지는 않습니다.

이 구조의 한계주 TSA 앵커 뒤 envelope_sealed 감사가 추가됩니다. 최종 감사 헤드 앵커 완료나 특정 PAdES 등급을 주장하지 않습니다.

단계별 설명 · 구조도를 글로 읽기
  • 서명 세션 확인

    수신자·만료 재검사 · 인증 방식별 증거

    • 임시 입력 저장 (처리·명시된 호출)
  • 임시 입력 저장

    field_draft에 저장 · 세션·필드 소유 확인

    • 서명 최종 확정 (데이터 읽기·참조)
  • 서명 최종 확정

    필수값 검사·값 승격 · 세션 소비·감사 기록

    • 전체 서명 판정 (처리·명시된 호출)
  • 전체 서명 판정

    모든 서명자가 완료? · 미완료면 대기·다음 차수

    • completed (처리·명시된 호출)
  • completed

    봉투 완료·작업 생성 · PDF 봉인 완료와 다름

    • 봉인 작업 점유 (비동기·별도 요청)
  • 봉인 작업 점유

    워커가 처리할 작업 점유 · lease·attempt 확인

    • 최종 데이터 조회 (처리·명시된 호출)
  • 최종 데이터 조회

    원문값·label·좌표 · 짧은 DB 트랜잭션

    • 원본 PDF 확인 (처리·명시된 호출)
  • 원본 PDF 확인

    저장소 읽기·해시 대조 · DB 잠금 밖 외부 I/O

    • 본문·별지 합성 (처리·명시된 호출)
  • 본문·별지 합성

    넘친 필드의 전문 연결 · 100쪽 상한·잘림 안내

    • PDF 서명 생성 (처리·명시된 호출)
  • PDF 서명 생성

    최종 바이트·해시 생성 · PDF 내부 TSA는 조건부

    • PDF 저장 (처리·명시된 호출)
  • PDF 저장

    주 TSA 요청 전에 put · 저장소와 DB는 별개

    • TSA 앵커 (처리·명시된 호출)
  • TSA 앵커

    봉인 전 헤드+PDF 해시 · 외부 응답 후 DB 확정

    • sealed 확정 (처리·명시된 호출)
    • TSA 일시 지연 (일시 오류)
  • sealed 확정

    lease 대조·교부 예약 · TSA·감사 함께 기록

    • 파일 자체 검증 (파일을 업로드하면)
  • TSA 일시 지연

    재시도 시각으로 미룸 · completed 상태로 대기

  • 파일 자체 검증

    업로드 PDF만 검증 · 계약 DB·감사 조회 없음

구조 탐색과 실제 소스 대조를 바탕으로 편집한 작동도입니다. 런타임 전체의 자동 검증을 뜻하지 않습니다.

결과와 현재의 경계

결과, 그리고 지금.

실제 계약 업무에 사용하는 서비스를 구축하고 운영 개선을 이어가고 있습니다. 입력 화면과 최종 PDF의 불일치, 여러 회사에 속한 사람의 탈퇴 범위처럼 사용 중 드러나는 문제를 웹·API·DB를 함께 바꿔 해결했습니다.

이 경험의 범위

회사 업무로 만든 서비스입니다. 제품 개발·운영을 담당한 범위와 외부 인증·문서 도구의 역할을 구분합니다. 공개 사례는 구현과 당시 검증 기록을 설명하며, 특정 법적 효력이나 PAdES 등급을 보증하는 자료는 아닙니다.

작성 기준: 2026년 9월 작업 기록·소스 대조. 과거 검증 결과를 현재의 모든 동작에 대한 보증으로 사용하지 않습니다.

역할과 협업 이야기하기