기술 진단 보고서 견본 · 가상 시스템 기준

커머스 플랫폼 오픈 전 기술 진단

외주 개발사가 만든 커머스 플랫폼을 오픈 직전에 6일 동안 점검했다고 가정하고 쓴 보고서 견본입니다. 시스템, 코드 경로, 수치, 발견 사항은 모두 가상이며, 실제 보고서는 받은 소스와 설정으로 채웁니다.

점검 대상
PC·모바일 웹, iOS·Android 앱, API 서버(AWS ECS), 주문 DB(RDS), 자체 WMS, ERP, PG 결제
기간
착수일부터 6일
받은 권한
소스 저장소 읽기, AWS 읽기 전용 역할, DB 읽기 전용 계정(모두 기간 한정). 복원 리허설만 그 시간에 따로 받은 권한으로 진행
결과물
기술 진단·개선 보고서 1식, 결과 설명 1회. 코드 수정은 하지 않습니다

요약

오픈 전 항목 7건을 고치고 항목마다 적은 "고친 뒤 확인" 방법으로 다시 돌려 통과하면, 예정대로 오픈해도 됩니다. 그중 치명 2건은 결제 금액과 출고가 실제로 어긋나는 문제라 가장 먼저 고칩니다. 오픈 후 항목 3건은 2주와 1개월 일정에 넣습니다.

치명 2건 높음 5건 중간 2건 낮음 1건

핵심 흐름별 위험 지점

주문 하나가 결제, 출고, 매출 반영까지 지나가는 길을 따라 문제를 찾았습니다. 항목을 누르면 아래 발견 사항으로 이동합니다.

  1. 주문 생성웹·앱 → API 서버 → 주문 DB
  2. 결제 승인API 서버 → PG
  3. 결제 완료 처리PG 웹훅, 결제 완료 화면 복귀
  4. 출고 지시와 완료API 서버 ↔ WMS
  5. 매출·취소 반영API 서버 → ERP
  6. 보관과 복구RDS 백업, 이미지 저장소
  7. 흐름 전체에 걸친 것권한, 비밀값, 로그, 조회 성능

발견 사항

위험도와 고칠 시점으로 걸러 볼 수 있습니다. 제목을 누르면 근거, 영향, 재현 방법, 권고, 고친 뒤 확인 방법이 펼쳐집니다. 외주 개발사가 이 내용만 보고 바로 고칠 수 있게 씁니다.

위험도
고칠 시점
치명결제 완료 통보와 완료 화면 복귀가 동시에 오면 출고 지시가 두 번 나갑니다주문·결제 · 오픈 전
근거
api/src/payment/payment.service.ts의 confirmPayment()가 주문 상태 읽기, PG 결제 조회, 상태를 "결제 완료"로 바꾸기를 잠금이나 조건 없이 따로 실행합니다. PG 웹훅(/webhooks/pg)과 앱의 완료 복귀(/orders/{id}/pay/complete)가 모두 이 함수를 부르고, 상태를 바꾼 직후 WMS 출고 지시를 보냅니다.
영향
같은 주문이 두 번 출고되고 재고가 두 번 빠집니다. 고객이 결제를 마치고 돌아오는 시점이 웹훅 도착과 거의 겹쳐서 오픈 첫날부터 생깁니다.
재현 방법
  1. 테스트 환경에서 결제를 마친 주문 하나를 고릅니다.
  2. 웹훅 요청과 완료 복귀 요청을 50ms 안에 동시에 보냅니다.
  3. 20번 중 6번 WMS 출고 지시가 2건 생겼습니다.
권고
상태 변경을 UPDATE orders SET status = 'PAID' WHERE id = ? AND status = 'PENDING' 같은 조건부 갱신으로 바꾸고, 바뀐 행이 0건이면 이미 처리된 주문으로 보고 끝냅니다. 출고 지시는 같은 트랜잭션에서 출고 대기 테이블에 기록하고, 별도 작업이 주문 번호를 중복 방지 키로 붙여 WMS에 보냅니다.
고친 뒤 확인
같은 동시 요청을 100번 돌려 주문마다 출고 지시가 1건인지 봅니다.
치명결제 승인 금액을 앱이 보낸 값으로 씁니다주문·결제 · 오픈 전
근거
POST /api/v1/orders/{id}/pay가 요청 본문의 amount로 PG에 승인을 요청하고, 서버에 저장된 주문 금액과 비교하지 않습니다. PG 승인 응답의 금액도 대조하지 않습니다.
영향
요청을 가로채 금액을 바꾸면 100원만 내고 정상 주문이 됩니다. 쿠폰과 적립금 계산이 앱과 서버에서 다를 때도 금액이 어긋납니다.
재현 방법
  1. 테스트 환경 앱의 요청을 프록시 도구로 가로챕니다.
  2. amount를 100으로 바꿔 보냅니다.
  3. 주문이 "결제 완료"로 바뀌고 출고 지시까지 나갑니다.
권고
승인 요청 금액은 서버가 주문, 쿠폰, 적립금으로 다시 계산한 값만 씁니다. PG 승인 응답의 금액이 주문 금액과 다르면 바로 승인을 취소하고 기록을 남깁니다.
고친 뒤 확인
금액을 바꾼 요청이 거절되고, 승인 취소 기록이 남는지 봅니다.
높음앱이 주문 요청을 자동으로 다시 보내면 주문이 여러 건 생깁니다앱·API · 오픈 전
근거
앱 네트워크 설정(app/src/network/client.ts)이 10초 안에 응답이 없으면 POST 요청도 2번까지 다시 보냅니다. 서버의 주문 생성에는 같은 요청을 알아보는 키가 없습니다.
영향
주문이 몰려 응답이 느려질 때 한 고객의 주문이 2~3건 생기고, 결제 단계 문의와 취소 처리가 늘어납니다.
재현 방법
테스트 환경에서 주문 생성 응답을 12초 늦추면, 앱에서 주문하기를 한 번 눌렀는데 주문이 3건 생깁니다.
권고
앱이 주문서 화면에 들어올 때 요청 키(UUID)를 만들어 헤더에 담고, 서버는 같은 키로 온 요청에 처음 결과를 그대로 돌려줍니다. POST 자동 재시도는 끕니다. 웹 주문도 같은 키를 씁니다.
고친 뒤 확인
같은 지연 조건에서 주문이 1건만 생기는지 봅니다.
높음WMS 출고 지시에 시간 제한이 없고, 실패하면 로그만 남습니다WMS 연동 · 오픈 전
근거
api/src/wms/wms.client.ts의 HTTP 호출에 연결·응답 시간 제한이 없습니다. 실패하면 logger.error만 남기고 주문 상태는 "출고 요청"으로 바뀝니다.
영향
WMS가 느려지면 주문 API 작업자가 모두 응답을 기다리며 묶여 주문 전체가 멈춥니다. WMS가 실패한 건은 커머스에는 "출고 요청", WMS에는 기록 없음으로 남아 출고가 빠집니다.
재현 방법
  1. WMS 테스트 주소 앞에 응답을 30초 늦추는 프록시를 둡니다.
  2. 주문 20건을 넣으면 4분 동안 주문 API가 응답하지 않습니다.
  3. 프록시가 오류를 돌려주게 바꾸면 20건 모두 "출고 요청" 상태인데 WMS에는 0건입니다.
권고
연결 3초, 응답 10초 제한을 둡니다. 실패 건은 재시도 큐에 넣어 간격을 늘려 가며 다시 보내고, 최종 실패는 운영 담당자에게 알립니다. 주문 상태는 WMS 접수 응답을 받은 뒤 바꿉니다. 매시간 커머스와 WMS의 출고 대상 목록을 맞춰 보는 대사 작업을 둡니다.
고친 뒤 확인
같은 지연·오류 조건에서 주문 API가 계속 응답하고, WMS가 돌아온 뒤 20건이 모두 들어가는지 봅니다.
높음주문 생성 트랜잭션이 외부 API 응답을 기다리는 동안 DB 연결을 붙잡습니다서버·DB 성능 · 오픈 전
근거
createOrder()가 한 트랜잭션 안에서 재고 차감, PG 결제 준비 요청, 알림톡 발송 요청까지 기다립니다. DB 연결 풀은 서버당 10개, 서버는 2대입니다.
영향
외부 응답이 1초만 늦어져도 동시 주문 20건이면 연결이 바닥나고, 상품 조회까지 느려집니다.
부하 시험 결과
검증 환경에서 분당 주문 600건을 흉내 내자 3분째부터 응답 시간(상위 5% 기준)이 0.8초에서 12초로 늘고 연결 대기 오류가 났습니다.
권고
트랜잭션에는 DB 작업만 두고 외부 호출은 트랜잭션 밖으로 뺍니다. 알림톡은 큐로 보냅니다. 연결 풀 크기, RDS 최대 연결 수, 오토스케일링 최대 대수를 함께 맞춥니다.
고친 뒤 확인
같은 부하에서 응답 시간 1초 이하, 연결 대기 오류 0건인지 봅니다.
높음자동 백업 보존 기간이 1일이고, 복원해 본 기록이 없습니다백업·복구 · 오픈 전
근거
RDS 자동 백업 보존 1일, 상품 이미지 S3 버킷의 버전 관리 꺼짐, 복원 절차 문서 없음.
영향
하루 뒤에 발견한 데이터 오류는 되돌릴 수 없습니다. 이미지를 잘못 지우면 복구할 수단이 없습니다.
리허설 결과
최근 스냅샷을 운영과 분리된 임시 DB로 복원하는 데 38분이 걸렸고, 복원본의 주문·결제 건수는 스냅샷 시각의 운영 기록과 같았습니다. 임시 DB는 리허설 뒤 지웠습니다.
권고
보존 기간을 14일로 늘리고 시점 복원 절차를 문서로 둡니다. S3 버전 관리를 켭니다. 복구 목표(몇 분 안에, 몇 분 전 데이터까지)를 정하고 분기마다 리허설합니다.
고친 뒤 확인
RDS·S3 설정과 복원 절차 문서로 봅니다.
높음운영 DB 비밀번호가 저장소 기록에 남아 있고, 개발용 AWS 키가 관리자 권한입니다기본 보안 · 오픈 전
근거
3개월 전 커밋의 config/production.yml에 운영 DB 접속 정보가 있습니다. 지금 파일에서는 지웠지만 저장소 기록에 남아 있습니다. IAM 사용자 3개가 관리자 권한이고 MFA가 꺼져 있습니다.
영향
저장소를 볼 수 있는 사람은 누구나 운영 DB에 접속할 수 있고, 개발용 키 하나가 새면 AWS 계정 전체가 위험합니다.
표기 원칙
비밀번호와 키 값은 보고서에 적지 않고, 커밋 위치와 IAM 사용자 이름만 부록에 적습니다.
권고
DB 비밀번호를 바꾸고 비밀값은 AWS Secrets Manager나 Parameter Store로 옮깁니다. 개발사 계정은 배포에 필요한 권한만 남기고 MFA를 켭니다.
고친 뒤 확인
옛 비밀번호로 접속이 거절되는지, IAM 정책이 바뀌었는지 봅니다.
중간주문 취소가 매출보다 먼저 ERP에 도착하면 취소 전표만 남습니다ERP 연동 · 오픈 후 2주
근거
ERP 전송 작업이 사건마다 따로 병렬로 처리되어, 같은 주문의 매출과 취소 순서가 지켜지지 않습니다. 커머스와 ERP의 금액을 맞춰 보는 작업이 없습니다.
영향
결제 직후 취소한 주문에서 ERP 매출이 실제와 달라지고, 월말 정산 때 사람이 찾아 고쳐야 합니다.
재현 방법
결제 후 1초 안에 취소하면 10번 중 2번 ERP에 취소 전표만 남습니다.
권고
같은 주문 번호의 사건은 한 줄로 순서대로 처리합니다. 매일 새벽 커머스의 결제·취소 합계와 ERP 전표 합계를 맞춰 보고 차이를 알립니다.
고친 뒤 확인
같은 조건 20번에서 ERP 전표가 매출, 취소 순서로 남고 대사 차이가 0인지 봅니다.
중간요청 로그에 주문자 전화번호와 주소가 그대로 남고, 보존 기한이 없습니다개인정보·로그 · 오픈 후 2주
근거
API 요청 본문 전체를 CloudWatch Logs에 남기고, 로그 보존 기간이 "만료 없음"입니다.
영향
로그 열람 권한만 있어도 개인정보를 볼 수 있고, 정한 보유 기간을 넘겨 보관하게 됩니다.
재현 방법
테스트 데이터로 주문 1건을 넣은 뒤 로그를 검색하면 전화번호와 주소가 그대로 보입니다.
권고
이름, 전화번호, 주소, 결제 정보는 로그에 남기기 전에 가립니다. 보존 기간을 정하고(예: 90일) 로그 열람 권한을 줄입니다.
고친 뒤 확인
같은 테스트 주문 뒤 로그에 가린 값만 남는지 봅니다.
낮음관리자 주문 목록 조회가 주문 테이블 전체를 읽습니다DB · 오픈 후 1개월
근거
orders 테이블에 (status, created_at) 인덱스가 없어 관리자 주문 목록이 매번 전체를 읽습니다. 지금 테스트 데이터 3만 건에서는 0.4초입니다.
영향
주문이 50만 건을 넘으면 관리자 화면이 몇 초씩 걸리고 주문 DB에 부담을 줍니다.
재현 방법
주문 50만 건 합성 데이터에서 같은 조회가 4.8초 걸립니다.
권고
(status, created_at) 인덱스를 추가하고, 기본 조회 기간을 최근 30일로 둡니다.
고친 뒤 확인
실행 계획에서 인덱스를 쓰는지, 50만 건에서 0.2초 이하인지 봅니다.

수치는 모두 예시입니다. 실제 보고서에는 직접 재현했거나 코드와 설정으로 확인한 것만 발견 사항으로 적고, 추정은 추정이라고 따로 표시합니다.

점검 항목

공고의 점검 범위를 여덟 영역으로 나눴습니다. 영역마다 무엇을 어떤 방법으로 보는지 정해 두고 6일 안에 모두 봅니다.

영역보는 것방법
아키텍처웹·앱, API 서버, 작업 큐, DB, 외부 연동의 구성과 장애가 번지는 경로소스와 AWS 구성으로 구성도를 그리고, 주문부터 결제, 출고, 매출, 취소·환불·반품까지 핵심 흐름을 따라갑니다
주문·결제 트랜잭션과 예외 처리트랜잭션 범위, 실패했을 때 되돌리기, 결제 금액 검증, 주문 상태 전이코드를 읽고, 테스트 환경에서 결제 실패와 중간 오류를 일부러 일으켜 봅니다
중복 방지중복 결제, 중복 주문, 중복 출고, 웹훅 재전송같은 요청을 동시에, 반복해서 보내 결과가 한 번만 생기는지 봅니다
WMS·ERP·결제 연동시간 제한, 재시도, 중복 방지 키, 처리 순서, 실패 건 보관, 대사테스트 환경에서 연동 상대가 느려지거나 끊긴 상황을 만들어 데이터가 빠지거나 두 번 생기는지 봅니다
앱의 API 호출자동 재시도, 네트워크가 끊긴 뒤 다시 보내기, 앱 버전이 섞일 때의 API 호환앱의 네트워크 코드와 API 명세를 대조하고, 느린 응답을 만들어 앱 동작을 봅니다
주문 폭주서버·DB 병목, 연결 풀, 느린 쿼리, 오토스케일링정해 주신 시간대에 검증 환경에서 주문 시나리오로 부하 시험을 하고, 느린 쿼리 로그와 실행 계획을 봅니다
백업·복구백업 주기와 보존 기간, 시점 복원, 이미지 저장소, 복구 절차최근 백업을 운영과 분리된 임시 DB로 복원해 걸린 시간과 주문·결제 건수를 맞춰 봅니다
기본 보안권한, 비밀값, 로그의 개인정보, 관리자 경로, 보안 그룹IAM·보안 그룹 설정, 저장소 기록 검색, 로그 표본을 봅니다

6일 일정

계약 즉시 시작합니다. 치명 항목은 보고서를 기다리지 않고 찾은 날 바로 알립니다.

1일차착수와 구조 파악

  • 남양주에서 착수 미팅, NDA와 읽기 전용 권한 확인
  • 시스템 구성도와 핵심 흐름(주문, 결제, 출고, 매출, 취소·환불·반품) 정리
  • 점검 순서와 부하 시험 시간대 정하기

2일차주문·결제

  • 트랜잭션 범위, 예외 처리, 결제 금액 검증, 상태 전이
  • 웹훅과 완료 화면 복귀가 동시에 올 때의 처리
  • 웹·앱의 재시도와 중복 요청

3일차연동 정합성

  • WMS·ERP·PG 호출 지점마다 시간 제한, 재시도, 중복 방지, 순서
  • 연동 지연·장애 상황을 테스트 환경에서 만들어 주문·결제·출고 데이터의 누락과 중복 확인

4일차AWS와 DB

  • 네트워크, 권한, 비밀값 관리
  • DB 설정과 연결 수, 느린 쿼리와 인덱스
  • 오토스케일링, 모니터링과 경보

5일차부하와 복구

  • 검증 환경에서 주문 폭주 부하 시험(결제·WMS는 테스트 모드)
  • 최근 백업을 임시 DB로 복원해 걸린 시간과 건수 대조, 끝나면 임시 DB 삭제

6일차보고서

  • 보고서 전달과 온라인 결과 설명(외주 개발사 함께 참석 가능)
  • 받은 자료 삭제와 삭제 확인서 전달, 계정·권한 회수 요청

위험도 기준

위험도는 일어났을 때의 피해와 일어날 가능성을 함께 보고 정합니다. 고칠 시점은 오픈 일정에 맞춰 붙입니다.

위험도기준고칠 시점
치명지금 조건 그대로 돈, 주문, 출고 데이터가 틀어지거나 개인정보가 밖으로 나갈 수 있음오픈 전
높음주문 폭주, 연동 지연·장애, 계정 유출 같은 조건이 생기면 위와 같은 결과로 이어지거나 서비스가 멈춤오픈 전
중간정산 오차, 복구 지연, 개인정보 보관 기준 위반처럼 운영 부담이 쌓이는 문제오픈 후 2주 안
낮음데이터가 늘었을 때의 성능, 유지보수 편의오픈 후 1개월 안 계획

보고서 목차

PDF와 편집할 수 있는 문서로 함께 드립니다.

  1. 요약: 오픈 판단 의견, 오픈 전에 고칠 목록
  2. 점검 범위와 방법, 받은 자료와 권한
  3. 시스템 구성도와 핵심 흐름(주문, 결제, 출고, 매출, 취소·환불·반품)
  4. 발견 사항: 위험도순, 항목마다 근거, 영향, 재현 방법, 권고, 고친 뒤 확인 방법
  5. 연동 정합성 점검표: WMS·ERP·PG 호출 지점별 시간 제한, 재시도, 중복 방지, 순서, 대사
  6. 주문 폭주 부하 시험 결과
  7. 백업·복구 리허설 결과
  8. 실행 계획표: 오픈 전, 오픈 후 2주, 1개월로 나누고 담당(외주 개발사, 회사)을 적음
  9. 부록: 재현에 쓴 요청 예시, 점검한 설정 목록

자료 보안

소스, 연동 구조, 서버 정보는 이 원칙으로만 다룹니다.