모두의포트폴리오
PE · FDE 직군을 위한 포트폴리오 밀키트
예전 판입니다 (1판)이 문서는 2026-08-02 에 새 판으로 개정됐습니다. 결과만 보여주던 검수 리포트를 담당자가 화면에서 답해야 주문이 제작으로 넘어가는 확인 처리대로 바꿨습니다.최신 판 보기 →
경력칼론

일본 고객이 보낸 팀 유니폼 주문서(선수별 이름·등번호·사이즈·옵션)를 넣으면, 등번호 중복·사이즈 누락·이 종목에 없는 옵션·미등록 옵션·결제 금액 불일치를 근거와 함께 짚고 정정안까지 돌려주는 풀스택 주문 검수 콘솔

칼론 공고에서 뽑은 세 가지 시그널.

이 도구가 입증하는 것은 화면에서 API·데이터베이스·결제·배포까지 잇는 풀스택 구현(TypeScript·Node.js·Python·PostgreSQL·Redis·AWS)과 주문 정합성 검증 엔진, 결제 금액 대조 구조이며, 스포츠 유니폼 제작 공정 자체의 전문성은 주장하지 않습니다. 다만 이 검수 사슬이 말이 되려면 칼론이라는 맥락, 즉 ILB-MAX 로 10,000팀 이상의 제작을 안내해 온 커스텀 유니폼 이커머스, 그리고 야구·축구·배구마다 등번호·사이즈·옵션 규칙이 다르고 KOMOJU·PayVerse 로 결제가 흐르는 제품이 있어야 의미가 있습니다. 선수별 로스터를 규칙으로 검수한다는 각도는 팀 단위 커스텀 주문이 실제로 흐르는 이 서비스에서만 값을 합니다. 실제 원단·프린팅 제작 공정이나 일본 결제·세금 규정의 깊이는 도메인 담당자와의 협업이 있어야 하고, 면접에서 모르는 부분은 모른다고 말하는 편이 낫습니다.

01

AI 개발 도구로 실행 속도를 끌어올리는 개발자

이 팀은 Claude Code 와 OpenAI Codex 를 일상 개발에 씁니다. 도구가 낸 결과를 그대로 넣지 않고 동작·영향·예외를 스스로 확인해 검증하는 사람을 찾으므로, 반복 검수 작업을 자동화해 가설 검증을 빠르게 돌리는 실전 도구가 입증 대상입니다.

Claude CodeOpenAI Codex반복 작업가설을 검증
02

화면에서 결제·데이터베이스·배포까지 잇는 풀스택

이 팀의 풀스택은 문제를 한 기술 영역에 가두지 않고 화면에서 API 로, API 에서 데이터베이스와 결제 시스템으로, 다시 배포와 운영 환경까지 이어가며 해결하는 개발자를 뜻합니다. 검수 콘솔은 그 전 구간을 한 사람이 잇는 구현이 필요합니다.

풀스택데이터베이스와 결제 시스템배포와 운영TypeScript
03

실서비스 주문 흐름을 안정 운영하며 반복 업무를 자동화

이미 실제 고객과 주문이 흐르는 서비스를 안정적으로 운영하면서, 반복되는 운영 업무를 발견해 자동화하거나 더 효율적인 흐름으로 개선하는 역할을 기대합니다. 손으로 대조하던 주문 검수를 규칙으로 고정해 자동화하는 도구가 그 역할과 정확히 맞닿습니다.

안정적으로 운영반복되는 운영 업무자동화주문 경험

포트폴리오 요약

칼론 운영팀 담당자가 일본 고객이 보낸 팀 단위 유니폼 주문서, 즉 선수별 이름·등번호·사이즈·옵션이 담긴 로스터를 넣으면, 규칙 엔진이 상품·옵션 마스터(option_price_master)와 주문 로스터(uniform_order_line)를 대조합니다. 그다음 같은 팀 안 등번호 중복, 사이즈 결측, 종목에 안 맞거나 단종된 옵션, 마스터에 없는 미등록 옵션, 등번호 상한 초과, 결제 금액과 재계산 합계 불일치 같은 위반만 근거와 함께 뽑고 정정안을 제시합니다. 위반 판정은 규칙표와 외래키·금액 대조로 고정되고, LLM 은 일본어 자유서술 디자인 메모를 필드로 바꾸는 파싱과 일본어 정정 안내 문구 생성만 맡습니다. 1주차만으로 구조화된 주문서 검수 콘솔이 완성품이고, 일본어 파싱(2주차)과 AWS 배포·결제 대조 자동화(3주차)로 키웁니다. (근거는 채용공고 정렬입니다.)

고객 정의

칼론 운영팀 담당자. ILB-MAX 로 들어온 일본 고객의 팀 유니폼 주문서를 선수 한 명 한 명 눈으로 대조하며 등번호가 겹치지 않는지, 사이즈가 빠지지 않았는지, 고른 옵션이 이 종목에 실제로 있는지, 결제된 금액이 옵션 합계와 맞는지 확인하다 놓쳐서 제작에 잘못 넘어가는 걸, 주문서를 넣으면 위반과 정정안이 근거와 함께 바로 뜨게 만들어 검수 시간을 줄이고 싶은 사람.

고민 지점

커스텀 유니폼 주문 규칙을 상품·옵션 마스터와 결정론 규칙표로 구조화하면, (a) 팀 로스터를 넣었을 때 등번호 중복·사이즈 결측·종목 불일치 옵션·미등록 옵션·등번호 상한 초과·결제 금액 불일치를 근거와 함께 고정적으로 잡아내고, (b) 종목별 기본가와 옵션 추가가를 더한 합계로 결제 금액을 재계산해 대조하며, (c) 규칙으로 판정되지 않는 애매한 자유서술은 판정을 지어내지 않고 되묻아, 운영팀이 제작 전에 바로 돌려보는 신뢰할 검수 도구가 된다는 걸 보여줍니다.

주차별 일정

1주차여기까지로 완성

팀 주문서 넣기 → 규칙 검수 → 위반 근거·정정안·결제 재계산

구조화된 팀 로스터(JSON·CSV)를 넣으면 상품·옵션 마스터와 대조해 등번호 중복·사이즈 결측·종목 불일치 옵션·미등록 옵션·등번호 상한 초과·결제 금액 불일치를 근거와 함께 뽑고 정정안과 재계산 합계를 보여주는 동작하는 콘솔. 1주차 입력은 이미 필드로 나뉜 주문서를 가정하고, 일본어 자유서술 메모를 필드로 바꾸는 파싱은 2주차로 분리합니다.

  1. 1일 · 상품·옵션·주문을 한 표로 모으기option_price_master 와 uniform_order_line 스키마 설계 + 종목·사이즈·옵션 코드 enum 정규화 + 종목별 기본가·옵션 추가가 규칙표 정의
  2. 2-3일 · 규칙 검수 엔진 만들기Node·Python 검수 엔진에서 같은 팀 등번호 중복·사이즈 결측·종목 불일치 옵션·미등록 옵션(외래키)·등번호 상한 초과 규칙 구현
  3. 4일 · 결제 금액 재계산·대조기본가와 옵션 추가가를 더한 합계로 주문 금액을 재계산하고 결제 금액과 어긋난 건을 위반으로 표기
  4. 5일 · 위반마다 근거·정정안 붙이기각 위반에 어느 행·어느 필드가 문제인지 원문 인용을 달고 정정안(중복 등번호 교체·결측 사이즈 요청 등)을 생성
  5. 6일 · 지어낸 판정 차단마스터에 없는 옵션은 값을 지어내지 않고 미등록으로만 표기하는지, 위반 판정이 실제 규칙표·데이터에서 재현되는지 별도 검사로 대조
  6. 7일 · 30개 주문서 세트 시연 영상 + 직접 만든 정답과 비교한 기준선여기까지가 1주차 완성품
2주차선택 성장

일본어 자유서술 메모를 필드로 파싱해 검수에 붙이기

고객이 자유서술로 남긴 일본어 디자인·주문 메모를 LLM 이 이름·등번호·사이즈·옵션 필드로 파싱해 검수 엔진에 태우고, 운영 담당 페르소나 2명이 파싱이 원문과 맞는지 라벨링해 일치도를 대조하는 단계.

  1. 8-10일 · 일본어 자유서술 메모 파싱 붙이기고객이 남긴 일본어 디자인·주문 메모를 이름·등번호·사이즈·옵션 필드로 파싱해 검수 엔진에 태우고, 옵션 별칭 표기를 마스터 코드로 매핑
  2. 11-13일 · 파싱 일치도·되묻기 보정운영 담당 페르소나 2명이 파싱이 원문과 맞는지 라벨링(Cohen's κ: 두 사람 답이 우연 이상으로 일치하는 정도, 0~1) + 규칙으로 안 되는 모호한 메모는 되묻는 질문으로 반환
3주차선택 성장

AWS 로 배포하고 결제 금액 대조를 자동화

검수 API 를 Amazon EKS 에 배포하고 업로드 주문서는 Amazon S3 에 두며, KOMOJU·PayVerse 결제 캡처 금액을 재계산 합계와 자동 대조해 불일치 주문만 리포트로 올리는 단계.

  1. 15-17일 · AWS 배포검수 API 를 Amazon EKS 에 배포하고 업로드 주문서를 Amazon S3 에 저장, 대량 로스터 검수가 안 밀리는지 확인
  2. 18-19일 · 결제 대조 자동화KOMOJU·PayVerse 결제 캡처 금액을 재계산 합계와 자동 대조해 불일치 주문만 리포트로 올리는 흐름 구현
  3. 20-21일 · 3주 통합 시연 영상 + 실제 도입 계획(실 주문·결제 로그·실 운영 담당 검수 연동)

데모 · 측정 지표

01

등번호 중복·사이즈 결측·미등록 옵션을 일부러 섞은 팀 주문서 30종을 넣으면, 위반 유형별로 어느 행·어느 필드가 문제인지 근거와 정정안을 짚어내는 걸 시연합니다

02

같은 주문서·같은 마스터면 위반 목록과 재계산 합계가 항상 똑같이 나오는지 자동 대조합니다. LLM 이 만든 안내 문구와 무관하게 위반 판정 자체는 규칙 엔진으로 고정되는 걸 보여줍니다

03

일부러 심은 등번호 상한 초과·마스터에 없는 옵션·단종 옵션·표기 흔들림·결측·결제 금액 불일치 30종을 넣어도 출력 형식이 안 깨지고 정상 주문과 구분해 잡아내는 걸 보여줍니다

04

내가 만든 정답 30건 중 위반 검출·재계산 합계가 일치한 게 27건(90%)입니다. 단, 정답·데이터를 모두 작성자가 규칙으로 만든 합성 기준이라 '성능 검증' 이 아니라 '데모 조건 동작' 임을 밝힙니다

정직 경계선

진짜 성능 검증은 여기서 멈춥니다

위 수치는 전부 작성자가 만든 더미데이터 자가채점이며, 실제 위반 검출 정확도·운영 담당 체감 검수 속도는 칼론 실 주문·결제 로그와 실 운영 담당이 있어야 측정 가능합니다. 이 도구는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다

미리 알아둬야 할 것들

이건 사용자·실데이터 없이 혼자 만든 포트폴리오라, 모든 수치는 합성 데이터 자가채점이라 성능 증명이 아닙니다. 면접에서 '데모 동작 + 실검증 준비 상태' 로 솔직히 설명하는 편이 신뢰를 줍니다

정답을 내가 만들었으니 잘 맞는 게 당연합니다. 그래서 등번호 중복·orphan 옵션·단종 옵션·경계값(등번호 0·상한)·결제 금액 불일치·표기 흔들림을 더미에 일부러 섞어, 쉬운 주문서만 통과시키는 게 아님을 보여줍니다

이 포트폴리오가 입증하는 것은 풀스택 제품 구현·주문 정합성 검증·결제 금액 대조·일본어 파싱 기술이지, 스포츠 유니폼 제작 공정이나 일본 이커머스 도메인 자체의 전문성이 아닙니다. 실제 원단·프린팅 공정이나 일본 결제·세금 규정의 깊이는 도메인 담당자 협업이 있어야 하고, 면접에서 모르는 부분은 모른다고 말하는 편이 낫습니다

실제 도입 시 달라지는 것 명시. 칼론 실제 옵션 마스터·가격표·종목 규칙은 더미와 다르므로 규칙표와 기본가·추가가를 실데이터로 다시 맞춰야 하고, 검토자도 실 운영 담당으로 교체해야 합니다(도입 단계 과제로 분리)

일본어 자유서술 메모가 모호하면 파싱이 어긋날 수 있어, 규칙으로 필드가 안 정해지는 메모는 값을 지어내지 않고 되묻는 질문으로 돌려보냅니다. 상관과 인과를 헷갈리지 않도록 위반은 규칙 위반 사실만 표기하고 원인 추정은 하지 않습니다

더미 데이터

① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.

option_price_masterTABLE· 11 rows

종목별 유니폼 옵션과 추가가·등번호 상한·판매 상태의 마스터이자 주문 검수의 기준입니다. 단종 옵션·추가가 결측·옵션명 별칭 표기·등번호 상한 경계를 일부러 섞어, 없는 옵션을 정상으로 보거나 단종 옵션을 통과시키지 않는지 보여줍니다.

② option_price_master.seed.json 다운로드
① 인라인 샘플 (프리뷰 5 / 11)
option_codeoption_name_rawsportadd_price_jpymax_back_numberstatus
OPT-BB-STD야구 기본baseball099active
OPT-BB-PRO야구 프로baseball1,50099active
OPT-BB-EMB야구 자수baseball—99active
OPT-SC-STD축구 기본soccer099active
OPT-SC-PRO축구 프로soccer1,20099active
③ 증강 프롬프트 (본인 LLM 에 붙여서 N 배 늘리기)
아래 JSON Schema 에 맞는 종목별 유니폼 옵션 마스터 30행 JSON 배열로 생성합니다. 야구·축구·배구 옵션과 추가가·등번호 상한을 고루 섞습니다.

{"type":"object","properties":{"option_code":{"type":"string"},"option_name_raw":{"type":"string"},"sport":{"type":"string","enum":["baseball","soccer","volleyball"]},"add_price_jpy":{"type":["integer","null"]},"max_back_number":{"type":"integer"},"status":{"type":"string","enum":["active","discontinued"]}},"required":["option_code","option_name_raw","sport","max_back_number","status"]}

쉬운 데이터만 만들지 말 것. 하드 케이스 의도적 혼입: (1) add_price_jpy 가 null 인 추가가 미입력 2~3건, (2) status=discontinued 인 단종 옵션 2~3건, (3) option_name_raw 가 한글·일본어·괄호 별칭(배구 기본·バレー基本)이라 정규화가 필요한 표기 흔들림 3~4건, (4) max_back_number 가 199 처럼 표준 99 를 벗어난 확장 옵션 1~2건, (5) add_price_jpy=0 인 경계 옵션 여러 건. JSON 배열만.
schema (3 층의 단일 출처)
{"type":"object","properties":{"option_code":{"type":"string"},"option_name_raw":{"type":"string"},"sport":{"type":"string","enum":["baseball","soccer","volleyball"]},"add_price_jpy":{"type":["integer","null"]},"max_back_number":{"type":"integer"},"status":{"type":"string","enum":["active","discontinued"]}},"required":["option_code","option_name_raw","sport","max_back_number","status"]}
uniform_order_lineTABLE· 12 rows

팀 단위 유니폼 주문서의 선수별 로스터 한 행입니다. option_price_master 와 대조해 같은 팀 등번호 중복·사이즈 결측·종목 불일치 옵션·미등록 옵션·등번호 상한 초과·단가 결측을 잡습니다. 등번호 중복·orphan 옵션·팀명 별칭·사이즈 누락을 섞어, 정상 주문만 통과시키는 게 아님을 보여줍니다.

② uniform_order_line.seed.json 다운로드
① 인라인 샘플 (프리뷰 5 / 12)
order_idteam_name_rawteam_idplayer_nameback_numbersportsize_rawsizeoption_codeunit_price_jpyname_print_raw
O-1001横浜ブルーウィングスT-01田中10baseballLLOPT-BB-STD8,800TANAKA
O-1001横浜ブルーウィングスT-01佐藤7baseballMMOPT-BB-PRO10,300SATO
O-1001横浜ブルーウィングスT-01鈴木10baseball—OPT-BB-STD8,800SUZUKI
O-1002大阪FCT-02山本9soccerXLXLOPT-SC-PRO9,600YAMAMOTO
O-1002大阪FCT-02中村99soccer3XL3XLOPT-SC-PRO9,600NAKAMURA
③ 증강 프롬프트 (본인 LLM 에 붙여서 N 배 늘리기)
아래 JSON Schema 에 맞는 팀 유니폼 주문 로스터 30행 JSON 배열로 생성합니다. 한 order_id 는 한 팀의 여러 선수 행을 갖고, sport 는 그 팀 전체가 같습니다.

{"type":"object","properties":{"order_id":{"type":"string"},"team_name_raw":{"type":"string"},"team_id":{"type":["string","null"]},"player_name":{"type":"string"},"back_number":{"type":["integer","null"]},"sport":{"type":"string","enum":["baseball","soccer","volleyball"]},"size_raw":{"type":"string"},"size":{"type":["string","null"],"enum":["XS","S","M","L","XL","2XL","3XL",null]},"option_code":{"type":["string","null"]},"unit_price_jpy":{"type":["integer","null"]},"name_print_raw":{"type":"string"}},"required":["order_id","team_name_raw","player_name","sport","size_raw","option_code"]}

쉬운 데이터만 만들지 말 것. 하드 케이스 의도적 혼입: (1) 같은 order_id 안에서 back_number 가 겹치는 등번호 중복 2~3건, (2) size 가 null 인 사이즈 미입력 2~3건, (3) option_code 가 option_price_master 에 없는 orphan 참조(예: OPT-XX-999) 2건, (4) 옵션의 sport 와 주문 행의 sport 가 다르거나 단종 옵션을 고른 종목 불일치 2건, (5) back_number 가 옵션 상한(99)을 넘는 100 이상 또는 0 인 경계값 2건, (6) team_name_raw 가 같은 팀의 별칭·일본어 표기(コウベVC)라 team_id 가 null 인 미매핑 2건, (7) unit_price_jpy 가 null 인 단가 미입력 1~2건. JSON 배열만.
schema (3 층의 단일 출처)
{"type":"object","properties":{"order_id":{"type":"string"},"team_name_raw":{"type":"string"},"team_id":{"type":["string","null"]},"player_name":{"type":"string"},"back_number":{"type":["integer","null"]},"sport":{"type":"string","enum":["baseball","soccer","volleyball"]},"size_raw":{"type":"string"},"size":{"type":["string","null"],"enum":["XS","S","M","L","XL","2XL","3XL",null]},"option_code":{"type":["string","null"]},"unit_price_jpy":{"type":["integer","null"]},"name_print_raw":{"type":"string"}},"required":["order_id","team_name_raw","player_name","sport","size_raw","option_code"]}

기술 상세 · 아키텍처·운영·출력 스키마

기술 스택 매핑
TypeScript검수 콘솔 화면과 주문 검수 API 를 잇는 공통 언어(스킬의 TypeScript)
Node.js팀 로스터를 받아 규칙 검수와 결제 재계산을 도는 검수 API 서버(스킬의 Node.js)
Python종목·옵션 규칙 엔진과 더미데이터 증강 스크립트(스킬의 Python, 대표 언어)
PostgreSQL상품·옵션·가격 마스터와 주문 로스터의 단일 진실원이자 검수 뷰(스킬의 PostgreSQL)
Redis반복 조회하는 옵션 마스터 캐시와 대량 로스터 검수 작업 큐(스킬의 Redis)
DynamoDB검수 실행마다 남는 위반 이벤트 로그 적재(스킬의 DynamoDB)
AWS3주차부터 검수 API 배포와 서비스 운영 환경(스킬의 AWS)
Amazon EKS검수 API 컨테이너를 배포·운영하는 오케스트레이션(스킬의 Amazon EKS)
Amazon S3업로드된 주문서 파일과 디자인 시안 이미지 저장(스킬의 Amazon S3)
KOMOJU결제 캡처 금액을 옵션 합계 재계산값과 대조하는 결제 흐름(스킬의 KOMOJU)
PayVerse대체 결제 경로의 캡처 금액 대조(스킬의 PayVerse)
Claude Code코드베이스 탐색·구현·테스트·리팩터링에 쓰는 개발 도구, 낸 결과는 동작·영향·예외를 직접 검증(스킬의 Claude Code)
LLM 선택
model
Claude Sonnet (일본어 자유서술 메모를 이름·등번호·사이즈·옵션 필드로 파싱 + 일본어 정정 안내 문구 생성) + Haiku (파싱 결과가 원문과 어긋나지 않는지 sanity judge)
prompt
일본어 메모를 주문 로스터 스키마로 강제 파싱 + few-shot 3 예시(단순 로스터/옵션 별칭 섞인 메모/모호한 요청) + 출력 스키마 강제 + 마스터에 없는 옵션은 미등록으로만 표기하고 값을 지어내지 않도록 차단 + 규칙으로 안 되는 애매한 메모는 되묻는 질문으로 반환
rationale
일본어 파싱과 고객 안내 문구 품질이 중요해 Sonnet, 파싱 sanity 대조는 비용·속도 우선 Haiku 로 둡니다. 위반 판정 자체는 LLM 이 아니라 규칙표와 외래키·금액 재계산으로 결정론 처리하므로, 주문 규모가 커도 검수는 규칙 엔진이 맡고 LLM 호출은 파싱·문구 생성에만 씁니다. 옵션 마스터가 정형이라 별도 RAG 는 두지 않습니다.
결정 게이트
1주차 끝구조화된 팀 로스터를 넣으면 마스터와 대조해 위반을 근거와 함께 뽑고 정정안·재계산 합계를 보여주며, 같은 주문서·같은 마스터면 위반 목록이 항상 똑같이 나오는가(결정론). 여기까지가 그 자체로 제출 가능한 완성품.

✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 2주차(일본어 자유서술 파싱)로 진행합니다.

2주차 끝일본어 메모 파싱 결과가 검수에 태워지고, 운영 담당 페르소나 라벨과 파싱 일치도가 측정되며, 마스터에 없는 옵션을 지어내지 않는가.

✓ pass → 여기서 멈춰도 완결입니다. 더 키우면 3주차(AWS 배포·결제 대조 자동화)로 진행합니다.

재사용 레이어 · 코어 70% / 도메인 30%
core (재사용 가능)
  • 주문 로스터를 스키마로 검증·파싱하는 입력 가드
  • 마스터 대조로 중복·결측·미등록·상한 초과를 판정하는 결정론 규칙 엔진
  • 기본가와 옵션 추가가를 더해 결제 금액을 재계산·대조하는 금액 가드
  • 규칙에 없는 판정을 지어내지 않고 미등록·되묻기로만 표기하는 폴백
  • 위반 리포트 대시보드(위반율·유형별 건수·결제 불일치·파싱 일치도)
  • 일부러 심은 중복·orphan·경계값·표기 흔들림 강건성 테스트 세트
domain (교체 대상)
  • uniform_order_line / option_price_master 도메인 스키마
  • 운영 담당·기획 페르소나 라벨 가이드
  • 종목 enum(baseball·soccer·volleyball)과 사이즈·옵션 규칙표는 상품군·업종별로 갈아끼웁니다
출력 스키마 · order_review_report

팀 유니폼 주문서 한 건에 대한 검수 리포트입니다. 파싱된 로스터 요약(line_count), 위반 건(issues)과 각 위반의 근거(evidence)·정정안(suggested_fix), 결제 대조(payment_check), 최종 판정(verdict)을 한 스키마에 담아, 규칙에 없는 판정을 지어내지 않고 실제 마스터 대조·금액 재계산으로만 위반을 잡았는지 객관 검증합니다.

schema (JSON Schema)
{"type":"object","properties":{"order_id":{"type":"string"},"line_count":{"type":"integer"},"issues":{"type":"array","items":{"type":"object","properties":{"line_ref":{"type":"string"},"rule_id":{"type":"string","enum":["duplicate_number","missing_size","invalid_option_for_sport","orphan_option","number_out_of_range","price_mismatch","name_normalize_needed"]},"evidence":{"type":"string"},"severity":{"type":"string","enum":["high","mid","low"]},"suggested_fix":{"type":"string"}},"required":["line_ref","rule_id","evidence","severity","suggested_fix"]}},"payment_check":{"type":"object","properties":{"stated_total_jpy":{"type":["integer","null"]},"recomputed_total_jpy":{"type":"integer"},"match":{"type":"boolean"}},"required":["recomputed_total_jpy","match"]},"verdict":{"type":"string","enum":["pass","fail","need_clarification"]}},"required":["order_id","line_count","issues","payment_check","verdict"]}
모범 출력 (4)
[
  {
    "input_ref": "주문 O-1004 (정상 3행, 결제 26400엔) 검수",
    "output": {
      "order_id": "O-1004",
      "line_count": 3,
      "issues": [
        {
          "line_ref": "O-1004/松本",
          "rule_id": "number_out_of_range",
          "evidence": "back_number=100 이 OPT-BB-STD 의 max_back_number=99 를 초과",
          "severity": "high",
          "suggested_fix": "등번호를 99 이하로 바꾸거나, 확장번호 옵션(OPT-BB-NUMHI, 상한 199)으로 옵션을 변경하세요."
        }
      ],
      "payment_check": {
        "stated_total_jpy": 26400,
        "recomputed_total_jpy": 26400,
        "match": true
      },
      "verdict": "fail"
    }
  },
  {
    "input_ref": "주문 O-1001 (같은 팀 등번호 중복 + 사이즈 결측) 검수",
    "output": {
      "order_id": "O-1001",
      "line_count": 3,
      "issues": [
        {
          "line_ref": "O-1001/鈴木",
          "rule_id": "duplicate_number",
          "evidence": "back_number=10 이 같은 order_id 의 田中(back_number=10)과 중복",
          "severity": "high",
          "suggested_fix": "鈴木 또는 田中 중 한 명의 등번호를 다른 번호로 바꾸세요."
        },
        {
          "line_ref": "O-1001/鈴木",
          "rule_id": "missing_size",
          "evidence": "size=null, size_raw 가 빈 값이라 사이즈 미입력",
          "severity": "mid",
          "suggested_fix": "鈴木 의 사이즈를 XS~3XL 중 하나로 입력받으세요."
        }
      ],
      "payment_check": {
        "stated_total_jpy": 27900,
        "recomputed_total_jpy": 27900,
        "match": true
      },
      "verdict": "fail"
    }
  },
  {
    "input_ref": "주문 O-1003 (마스터에 없는 옵션 + 단가 결측) 검수",
    "output": {
      "order_id": "O-1003",
      "line_count": 3,
      "issues": [
        {
          "line_ref": "O-1003/伊藤",
          "rule_id": "orphan_option",
          "evidence": "option_code=OPT-XX-999 는 option_price_master 에 없음",
          "severity": "high",
          "suggested_fix": "배구 옵션(OPT-VB-STD·OPT-VB-PRO) 중 하나로 바꾸세요. 없는 옵션이라 단가를 지어내지 않고 미등록으로 표기합니다."
        },
        {
          "line_ref": "O-1003/渡辺",
          "rule_id": "price_mismatch",
          "evidence": "unit_price_jpy=null, OPT-VB-STD 재계산 단가 7700 과 대조 불가",
          "severity": "mid",
          "suggested_fix": "渡辺 의 단가를 재계산값 7700 으로 채우거나 결제 금액을 다시 확인하세요."
        }
      ],
      "payment_check": {
        "stated_total_jpy": 15400,
        "recomputed_total_jpy": 15400,
        "match": true
      },
      "verdict": "fail"
    }
  },
  {
    "input_ref": "자유서술 메모 '一番いいやつで全員分' (규칙으로 옵션·사이즈 특정 불가 → 되묻기)",
    "output": {
      "order_id": "O-1099",
      "line_count": 0,
      "issues": [],
      "payment_check": {
        "stated_total_jpy": null,
        "recomputed_total_jpy": 0,
        "match": false
      },
      "verdict": "need_clarification"
    }
  }
]
검증 노트 (자동 vs 수동)

[자동 검증] 1. 출력이 스키마를 통과하는가(형식·필수 필드·rule_id enum). 2. issues 의 각 위반이 규칙표·마스터 대조·금액 재계산으로 재현되는가. 같은 주문서·같은 마스터면 issues 와 recomputed_total_jpy 가 항상 동일한가(결정론 고정). 3. issues 의 line_ref 가 실제 uniform_order_line 행을 가리키고 evidence 의 값이 그 행·마스터의 실제 필드와 일치하는가(근거 조작 검출). 4. 규칙에 없는 위반을 만들었거나 정상 행을 위반으로 표기하면 실패(과검출). 반대로 등번호 중복·orphan 옵션·단종 옵션·상한 초과·결제 불일치를 놓치면 실패(미검출). 5. 마스터에 없는 옵션에 단가를 지어냈으면 실패. orphan_option 으로만 표기하고 값을 만들지 않았는가. 6. 규칙으로 필드가 안 정해지는 자유서술에 verdict=need_clarification 이 나오고 issues 를 지어내지 않았는가. [수동 검증] 1. 운영 담당·기획 페르소나 2명이 위반 판정·정정안 타당성을 라벨링 → bootstrap Cohen's κ(두 사람 답이 우연 이상으로 일치하는 정도, 0~1) 하한 0.6 이상. 2. 마스터에 없는 옵션에 값을 지어낸 비율 5% 사람 점검.