이 도구가 입증하는 것은 화면에서 API·데이터베이스·결제·배포까지 잇는 풀스택 구현(TypeScript·Node.js·Python·PostgreSQL·Redis·AWS)과 주문 정합성 검증 엔진, 결제 금액 대조 구조이며, 스포츠 유니폼 제작 공정 자체의 전문성은 주장하지 않습니다. 다만 이 검수 사슬이 말이 되려면 칼론이라는 맥락, 즉 ILB-MAX 로 10,000팀 이상의 제작을 안내해 온 커스텀 유니폼 이커머스, 그리고 야구·축구·배구마다 등번호·사이즈·옵션 규칙이 다르고 KOMOJU·PayVerse 로 결제가 흐르는 제품이 있어야 의미가 있습니다. 선수별 로스터를 규칙으로 검수한다는 각도는 팀 단위 커스텀 주문이 실제로 흐르는 이 서비스에서만 값을 합니다. 실제 원단·프린팅 제작 공정이나 일본 결제·세금 규정의 깊이는 도메인 담당자와의 협업이 있어야 하고, 면접에서 모르는 부분은 모른다고 말하는 편이 낫습니다.
이 팀은 Claude Code 와 OpenAI Codex 를 일상 개발에 씁니다. 도구가 낸 결과를 그대로 넣지 않고 동작·영향·예외를 스스로 확인해 검증하는 사람을 찾으므로, 반복 검수 작업을 자동화해 가설 검증을 빠르게 돌리는 실전 도구가 입증 대상입니다.
이 팀의 풀스택은 문제를 한 기술 영역에 가두지 않고 화면에서 API 로, API 에서 데이터베이스와 결제 시스템으로, 다시 배포와 운영 환경까지 이어가며 해결하는 개발자를 뜻합니다. 검수 콘솔은 그 전 구간을 한 사람이 잇는 구현이 필요합니다.
이미 실제 고객과 주문이 흐르는 서비스를 안정적으로 운영하면서, 반복되는 운영 업무를 발견해 자동화하거나 더 효율적인 흐름으로 개선하는 역할을 기대합니다. 손으로 대조하던 주문 검수를 규칙으로 고정해 자동화하는 도구가 그 역할과 정확히 맞닿습니다.
칼론 운영팀 담당자가 일본 고객이 보낸 팀 단위 유니폼 주문서, 즉 선수별 이름·등번호·사이즈·옵션이 담긴 로스터를 넣으면, 규칙 엔진이 상품·옵션 마스터(option_price_master)와 주문 로스터(uniform_order_line)를 대조합니다. 그다음 같은 팀 안 등번호 중복, 사이즈 결측, 종목에 안 맞거나 단종된 옵션, 마스터에 없는 미등록 옵션, 등번호 상한 초과, 결제 금액과 재계산 합계 불일치 같은 위반만 근거와 함께 뽑고 정정안을 제시합니다. 위반 판정은 규칙표와 외래키·금액 대조로 고정되고, LLM 은 일본어 자유서술 디자인 메모를 필드로 바꾸는 파싱과 일본어 정정 안내 문구 생성만 맡습니다. 1주차만으로 구조화된 주문서 검수 콘솔이 완성품이고, 일본어 파싱(2주차)과 AWS 배포·결제 대조 자동화(3주차)로 키웁니다. (근거는 채용공고 정렬입니다.)
칼론 운영팀 담당자. ILB-MAX 로 들어온 일본 고객의 팀 유니폼 주문서를 선수 한 명 한 명 눈으로 대조하며 등번호가 겹치지 않는지, 사이즈가 빠지지 않았는지, 고른 옵션이 이 종목에 실제로 있는지, 결제된 금액이 옵션 합계와 맞는지 확인하다 놓쳐서 제작에 잘못 넘어가는 걸, 주문서를 넣으면 위반과 정정안이 근거와 함께 바로 뜨게 만들어 검수 시간을 줄이고 싶은 사람.
커스텀 유니폼 주문 규칙을 상품·옵션 마스터와 결정론 규칙표로 구조화하면, (a) 팀 로스터를 넣었을 때 등번호 중복·사이즈 결측·종목 불일치 옵션·미등록 옵션·등번호 상한 초과·결제 금액 불일치를 근거와 함께 고정적으로 잡아내고, (b) 종목별 기본가와 옵션 추가가를 더한 합계로 결제 금액을 재계산해 대조하며, (c) 규칙으로 판정되지 않는 애매한 자유서술은 판정을 지어내지 않고 되묻아, 운영팀이 제작 전에 바로 돌려보는 신뢰할 검수 도구가 된다는 걸 보여줍니다.
구조화된 팀 로스터(JSON·CSV)를 넣으면 상품·옵션 마스터와 대조해 등번호 중복·사이즈 결측·종목 불일치 옵션·미등록 옵션·등번호 상한 초과·결제 금액 불일치를 근거와 함께 뽑고 정정안과 재계산 합계를 보여주는 동작하는 콘솔. 1주차 입력은 이미 필드로 나뉜 주문서를 가정하고, 일본어 자유서술 메모를 필드로 바꾸는 파싱은 2주차로 분리합니다.
고객이 자유서술로 남긴 일본어 디자인·주문 메모를 LLM 이 이름·등번호·사이즈·옵션 필드로 파싱해 검수 엔진에 태우고, 운영 담당 페르소나 2명이 파싱이 원문과 맞는지 라벨링해 일치도를 대조하는 단계.
검수 API 를 Amazon EKS 에 배포하고 업로드 주문서는 Amazon S3 에 두며, KOMOJU·PayVerse 결제 캡처 금액을 재계산 합계와 자동 대조해 불일치 주문만 리포트로 올리는 단계.
등번호 중복·사이즈 결측·미등록 옵션을 일부러 섞은 팀 주문서 30종을 넣으면, 위반 유형별로 어느 행·어느 필드가 문제인지 근거와 정정안을 짚어내는 걸 시연합니다
같은 주문서·같은 마스터면 위반 목록과 재계산 합계가 항상 똑같이 나오는지 자동 대조합니다. LLM 이 만든 안내 문구와 무관하게 위반 판정 자체는 규칙 엔진으로 고정되는 걸 보여줍니다
일부러 심은 등번호 상한 초과·마스터에 없는 옵션·단종 옵션·표기 흔들림·결측·결제 금액 불일치 30종을 넣어도 출력 형식이 안 깨지고 정상 주문과 구분해 잡아내는 걸 보여줍니다
내가 만든 정답 30건 중 위반 검출·재계산 합계가 일치한 게 27건(90%)입니다. 단, 정답·데이터를 모두 작성자가 규칙으로 만든 합성 기준이라 '성능 검증' 이 아니라 '데모 조건 동작' 임을 밝힙니다
위 수치는 전부 작성자가 만든 더미데이터 자가채점이며, 실제 위반 검출 정확도·운영 담당 체감 검수 속도는 칼론 실 주문·결제 로그와 실 운영 담당이 있어야 측정 가능합니다. 이 도구는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다
이건 사용자·실데이터 없이 혼자 만든 포트폴리오라, 모든 수치는 합성 데이터 자가채점이라 성능 증명이 아닙니다. 면접에서 '데모 동작 + 실검증 준비 상태' 로 솔직히 설명하는 편이 신뢰를 줍니다
정답을 내가 만들었으니 잘 맞는 게 당연합니다. 그래서 등번호 중복·orphan 옵션·단종 옵션·경계값(등번호 0·상한)·결제 금액 불일치·표기 흔들림을 더미에 일부러 섞어, 쉬운 주문서만 통과시키는 게 아님을 보여줍니다
이 포트폴리오가 입증하는 것은 풀스택 제품 구현·주문 정합성 검증·결제 금액 대조·일본어 파싱 기술이지, 스포츠 유니폼 제작 공정이나 일본 이커머스 도메인 자체의 전문성이 아닙니다. 실제 원단·프린팅 공정이나 일본 결제·세금 규정의 깊이는 도메인 담당자 협업이 있어야 하고, 면접에서 모르는 부분은 모른다고 말하는 편이 낫습니다
실제 도입 시 달라지는 것 명시. 칼론 실제 옵션 마스터·가격표·종목 규칙은 더미와 다르므로 규칙표와 기본가·추가가를 실데이터로 다시 맞춰야 하고, 검토자도 실 운영 담당으로 교체해야 합니다(도입 단계 과제로 분리)
일본어 자유서술 메모가 모호하면 파싱이 어긋날 수 있어, 규칙으로 필드가 안 정해지는 메모는 값을 지어내지 않고 되묻는 질문으로 돌려보냅니다. 상관과 인과를 헷갈리지 않도록 위반은 규칙 위반 사실만 표기하고 원인 추정은 하지 않습니다
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
종목별 유니폼 옵션과 추가가·등번호 상한·판매 상태의 마스터이자 주문 검수의 기준입니다. 단종 옵션·추가가 결측·옵션명 별칭 표기·등번호 상한 경계를 일부러 섞어, 없는 옵션을 정상으로 보거나 단종 옵션을 통과시키지 않는지 보여줍니다.
| option_code | option_name_raw | sport | add_price_jpy | max_back_number | status |
|---|---|---|---|---|---|
| OPT-BB-STD | 야구 기본 | baseball | 0 | 99 | active |
| OPT-BB-PRO | 야구 프로 | baseball | 1,500 | 99 | active |
| OPT-BB-EMB | 야구 자수 | baseball | — | 99 | active |
| OPT-SC-STD | 축구 기본 | soccer | 0 | 99 | active |
| OPT-SC-PRO | 축구 프로 | soccer | 1,200 | 99 | active |
아래 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 배열만.{"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"]}팀 단위 유니폼 주문서의 선수별 로스터 한 행입니다. option_price_master 와 대조해 같은 팀 등번호 중복·사이즈 결측·종목 불일치 옵션·미등록 옵션·등번호 상한 초과·단가 결측을 잡습니다. 등번호 중복·orphan 옵션·팀명 별칭·사이즈 누락을 섞어, 정상 주문만 통과시키는 게 아님을 보여줍니다.
| order_id | team_name_raw | team_id | player_name | back_number | sport | size_raw | size | option_code | unit_price_jpy | name_print_raw |
|---|---|---|---|---|---|---|---|---|---|---|
| O-1001 | 横浜ブルーウィングス | T-01 | 田中 | 10 | baseball | L | L | OPT-BB-STD | 8,800 | TANAKA |
| O-1001 | 横浜ブルーウィングス | T-01 | 佐藤 | 7 | baseball | M | M | OPT-BB-PRO | 10,300 | SATO |
| O-1001 | 横浜ブルーウィングス | T-01 | 鈴木 | 10 | baseball | — | OPT-BB-STD | 8,800 | SUZUKI | |
| O-1002 | 大阪FC | T-02 | 山本 | 9 | soccer | XL | XL | OPT-SC-PRO | 9,600 | YAMAMOTO |
| O-1002 | 大阪FC | T-02 | 中村 | 99 | soccer | 3XL | 3XL | OPT-SC-PRO | 9,600 | NAKAMURA |
아래 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 배열만.{"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) |
| AWS | 3주차부터 검수 API 배포와 서비스 운영 환경(스킬의 AWS) |
| Amazon EKS | 검수 API 컨테이너를 배포·운영하는 오케스트레이션(스킬의 Amazon EKS) |
| Amazon S3 | 업로드된 주문서 파일과 디자인 시안 이미지 저장(스킬의 Amazon S3) |
| KOMOJU | 결제 캡처 금액을 옵션 합계 재계산값과 대조하는 결제 흐름(스킬의 KOMOJU) |
| PayVerse | 대체 결제 경로의 캡처 금액 대조(스킬의 PayVerse) |
| Claude Code | 코드베이스 탐색·구현·테스트·리팩터링에 쓰는 개발 도구, 낸 결과는 동작·영향·예외를 직접 검증(스킬의 Claude Code) |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 2주차(일본어 자유서술 파싱)로 진행합니다.
✓ pass → 여기서 멈춰도 완결입니다. 더 키우면 3주차(AWS 배포·결제 대조 자동화)로 진행합니다.
팀 유니폼 주문서 한 건에 대한 검수 리포트입니다. 파싱된 로스터 요약(line_count), 위반 건(issues)과 각 위반의 근거(evidence)·정정안(suggested_fix), 결제 대조(payment_check), 최종 판정(verdict)을 한 스키마에 담아, 규칙에 없는 판정을 지어내지 않고 실제 마스터 대조·금액 재계산으로만 위반을 잡았는지 객관 검증합니다.
{"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"]}[
{
"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"
}
}
][자동 검증] 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% 사람 점검.