모두의포트폴리오
PE · FDE 직군을 위한 포트폴리오 밀키트
예전 판입니다 (1판)이 문서는 2026-08-02 에 새 판으로 개정됐습니다. 산출물을 웹 그리드 화면에서 마감 대사 리포트를 내는 CLI로 바꾸고, 수신 이벤트를 스스로 판정하던 구조를 고객사 전송 원장과 수신 로그를 대조하는 구조로 다시 썼습니다.최신 판 보기 →
경력위밋모빌리티 · Forward Deployed Engineer (FDE) — 물류 AI 솔루션

고객사가 API·웹훅으로 보낸 주문 이벤트를 표준 스키마로 정규화하고 제약·멱등성·마스터 참조 규칙으로 검사해 적재·보류·거부로 라우팅하는 주문 수신 게이트

위밋모빌리티 공고에서 뽑은 세 가지 시그널.

위밋모빌리티 FDE 는 SAP·ERP·메시징 등 외부 시스템과의 API·웹훅 수신/발신 연동을 재시도·멱등성·정합성·관측성까지 프로덕션 수준으로 완성하고, 표준 기능으로 안 풀리는 고객 요구를 구조화해 코어 팀에 재사용 가능한 형태로 전달합니다. 화주마다 다른 주문 페이로드를 표준 스키마로 정규화해 LIO·ROOUTY 경로최적화 입력 전에 거르는 이 수신 게이트는 그 핵심(연동 경계 멱등성·정합성·마스터 참조 검증·요구 구조화)을 정면으로 입증합니다. 다만 물류·SCM 최적화 도메인 전문성이나 실제 화주 주문 분포는 포트폴리오로 증명되지 않으므로 주장하지 않고, 일반 물류 더미로 기술만 보이며 경로최적화 엔진 자체는 만들지 않습니다. 그 깊이는 면접에서 모르면 모른다고 말하는 편이 낫습니다. 수신을 정규화·규칙·마스터 참조로 잇는 이 사슬은 단순 이벤트 적재 맥락으로는 그대로 만들 수 없습니다.

01

고객사 외부 시스템 연동 경계

SAP·ERP·메시징 API·웹훅 수신/발신 연동을 멱등성·정합성·관측성까지 프로덕션 수준으로 완성합니다. 주문 수신 게이트가 이 경계와 직접 정렬됩니다.

SAP·ERP·메시징 등 외부 시스템과의 API·웹훅 수신/발신 연동을 설계하고, 재시도·멱등성·정합성·관측성까지 프로덕션 수준으로 완성메시지 큐(DLQ)·이벤트 기반 아키텍처대용량 데이터 처리, 무중단 스키마 변경
02

관계형 DB 정합성·시큐어코딩

인덱스·실행계획·락/트랜잭션 근거의 관계형 DB 운영과 입력검증·권한 격리를 다룹니다. 마스터 참조 정합성 규칙이 이 환경과 정렬됩니다.

인덱스·실행계획·락/트랜잭션을 근거로 설명하는 수준입력검증·시큐어코딩(SQL 인젝션 방지, 권한/데이터 격리)관계형 DB 프로덕션 운영
03

고객 요구를 기술로 번역

고객 특화 요구를 구조화해 코어 팀에 재사용 가능한 형태로 전달합니다. 비표준 주문을 표준 스키마로 정규화하는 축이 여기에 정렬됩니다.

현장 요구를 구조화해 코어 팀에 전달하고, 재사용 가능한 형태로 제품에 반영고객·비개발 이해관계자와 직접 소통하며 요구를 기술로 번역해본 경험표준 기능으로 안 풀리는 요구를, 고객 환경을 이해한 뒤 혼자서도 설계·구현·배포

포트폴리오 요약

화주 고객사가 API·웹훅으로 보내는 주문(배송 요청) 이벤트를 연동 경계에서 받아, 표준 주문 스키마로 정규화한 뒤 규칙(스키마 위반·제약 위반·멱등성 중복·마스터 미참조·결측)으로 적재할지 보류할지 거부(DLQ)할지 정합니다. 라우팅 정답은 스키마·제약·멱등성·화주/차량 마스터 참조 규칙이 결정하고, LLM 은 비표준 페이로드의 표준 필드 매핑과 거부 사유 문장화 보조만 맡습니다. LIO·ROOUTY 경로최적화 엔진 자체가 아니라 그 입력 전 정합성 게이트입니다.

고객 정의

위밋모빌리티 FDE(고객사 연동 담당). 화주마다 제각각인 주문 페이로드를 받아 미등록 코드·제약 위반·중복 재전송을 일일이 눈으로 걸러 적재하던 일을, 한 게이트에서 정규화·검증·라우팅 결과를 함께 보고 싶은 사람입니다.

고민 지점

수신 주문을 표준 스키마로 묶고 화주/차량 마스터를 붙이면, (a) 스키마 위반·제약 위반·멱등 중복·미등록 화주를 규칙으로 걸러 DLQ 로 격리하고, (b) 거부 사유를 원문 필드값 인용으로 풀며, (c) 여러 화주의 비표준 주문을 끊김 없이 표준 스키마로 정규화합니다.

주차별 일정

1주차여기까지로 완성

주문 수신 + 정규화 + 규칙 검증 + 라우팅

고객사 주문 이벤트를 받아 표준 스키마로 정규화하고 스키마·제약·멱등성·마스터 참조를 검사해 적재/보류/거부(DLQ)로 라우팅하는 동작하는 게이트입니다. 화주·주문·마스터는 일반 물류 더미로 시작하고 수신 엔드포인트는 사내 API 가정으로 둡니다.

  1. 1일 · 표준 주문 스키마·마스터·규칙 정의주문(주문번호·화주·픽업/배송 시각·좌표·중량·멱등키)·화주/차량 마스터·제약 규칙 스키마 정의
  2. 2-3일 · 수신 엔드포인트 + LLM 정규화주문 이벤트 수신(사내 API 가정) + 비표준 페이로드를 표준 스키마로 정규화(원문 필드값 인용 강제)
  3. 4-5일 · 규칙 검증 + 적재/보류/거부 라우팅스키마 위반·제약 위반·멱등 중복·마스터 미참조·결측 규칙 + DLQ 격리 라우터
  4. 6일 · 주문 수신 게이트 화면화주별 수신 그리드 + 라우팅 카드(주문·정규화·사유) + DLQ 미니뷰 + 거부 사유
  5. 7일 · 7일치 시연 영상 + 심은 정답 기준선여기까지가 1주차 완성품입니다
2주차선택 성장

라우팅이 맞았는지 확인

라우팅 판정을 심은 정답 라벨·운영자 2명 라벨과 비교해 정밀도·재현율과 일치도를 보여주는 화면이고, 이때부터 AWS 로 배포·운영합니다.

  1. 8-11일 · 운영자 2명 라우팅 라벨 + AWS 배포심은 정답 대비 정밀도·재현율 + 일치도 측정(Cohen's κ: 두 사람 답이 우연 이상으로 일치하는 정도, 0~1) + AWS 배포·운영
  2. 12일 · 거부 사유 자동 검사정규화 값의 원문 인용 매칭 + 별도 LLM 검사 + 5% 사람 점검
3주차선택 성장

화주별 정합성 추이

화주·거부 사유별 라우팅 정합성과 멱등 중복률·DLQ 사유 분포를 누적 집계해 약한 연동을 보여주는 화면입니다.

  1. 15-21일 · 화주별 정합성 추이 + 두 번째 화주 스키마화주·거부 사유별 정합성·멱등 중복률·DLQ 사유 분포 집계 + 두 번째 화주 스키마 적용 + 통합 시연 영상(실 화주 데이터·실 운영자 교체 계획 포함)

데모 · 측정 지표

01

정상·제약위반·멱등중복·미등록화주 주문 시나리오 12종을 넣으면, 정규화·검증·라우팅 결과가 몇 초 안에 나오는 걸 시연합니다

02

일부러 만든 악성·결측 주문 30종(좌표 결측·미등록 화주 코드·중량 음수·주소 표기 흔들림·중복 재전송)을 넣어도 출력 형식(스키마)이 한 번도 안 깨집니다

03

더미에 심은 정답 라우팅 40건 중 적재/보류/거부 판정이 일치한 게 36건(약 90%)입니다. 단, 정답·데이터를 모두 작성자가 만든 합성 기준이라 '성능 검증'이 아니라 '데모 조건에서의 동작'임을 명시합니다

정직 경계선

진짜 성능 검증은 여기서 멈춥니다. 위 수치는 전부 작성자가 만든 더미데이터 자가채점이며, 실제 정밀도·재현율은 위밋모빌리티의 실 화주 주문 데이터와 실 운영자가 있어야 측정 가능합니다. 이 게이트는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다

미리 알아둬야 할 것들

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

정답을 작성자가 만들었으니 잘 맞는 게 당연합니다. 그래서 미등록 화주·중량 음수·좌표 결측·화주명 표기 흔들림·중복 재전송 같은 경계 케이스를 더미에 일부러 섞어, 쉬운 주문만 통과시키는 게 아님을 보여줍니다

LLM 이 정규화한 표준 필드는 그럴듯해도 원문 페이로드에 없을 수 있습니다. 정규화 값마다 원문 필드값 인용을 달게 하고, 근거가 없으면 '미매핑'으로 표시해 추측 적재를 막습니다

화주마다 주문 표기가 제각각입니다. 정규화로 표준 코드에 묶고, 못 묶으면 추측하지 말고 '미매핑'으로 보류에 둡니다. 실제 도입 시 화주별 실 양식·마스터가 더미와 다르므로 표준 스키마를 다시 맞춰야 합니다(도입 단계 과제로 분리)

이 포트폴리오가 입증하는 것은 연동 경계 수신·정규화·멱등성·마스터 참조 정합성 검증 기술입니다. LIO·ROOUTY 경로최적화나 물류·SCM 최적화 도메인 전문성은 포트폴리오로 증명되지 않으므로 주장하지 않으며, 경로최적화 엔진 자체는 만들지 않습니다. 그 깊이는 면접에서 모르면 모른다고 말하는 편이 낫습니다

더미 데이터

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

inbound_ordersTABLE· 11 rows

고객사 수신 주문 이벤트 로그. 정합성 규칙이 가장 먼저 질의하는 테이블입니다. 미등록 화주·중량 음수·좌표 결측·화주명 표기 흔들림·중복 재전송을 일부러 섞고, label 로 정답을 심어 자가채점합니다.

② inbound_orders.seed.json 다운로드
① 인라인 샘플 (프리뷰 5 / 11)
order_idshipper_rawshipper_idpickup_tsdeliver_tslatlngweight_kgidem_keyidem_seenschema_okconstraints_okmaster_hitlabelts
ord_001씨제이대한통운cj2026-03-04T08:002026-03-04T15:0037.512712.5u-1001falsetruetruetrueload2026-03-04T08:00
ord_002씨제이대한통운cj2026-03-04T14:002026-03-04T09:0037.51278u-1002falsetruefalsetruereject2026-03-04T09:10
ord_003엘엑스판토스lx2026-03-04T10:002026-03-04T18:0035.112920u-1001truetruetruetruereject2026-03-04T10:05
ord_004무등록화주Z—2026-03-04T11:002026-03-04T17:0036.3127.45u-1003falsetruetruefalsehold2026-03-04T11:00
ord_005CJ 대한통운—2026-03-04T12:002026-03-04T19:0037.4126.99.5u-1004falsetruetruefalsehold2026-03-04T12:00
③ 증강 프롬프트 (본인 LLM 에 붙여서 N 배 늘리기)
아래 Zod 스키마에 맞는 수신 주문 60행 JSON 배열로 생성합니다. 화주 2~3개, 정상 위주에 보류·거부를 섞습니다. label 규칙: schema_ok=false 또는 constraints_ok=false 또는 idem_seen=true → reject, master_hit=false 또는 shipper_id=null → hold, 그 외(스키마·제약·멱등·마스터 모두 정상) → load.

z.object({ order_id: z.string(), shipper_raw: z.string(), shipper_id: z.string().nullable(), pickup_ts: z.string(), deliver_ts: z.string().nullable(), lat: z.number().nullable(), lng: z.number().nullable(), weight_kg: z.number(), idem_key: z.string(), idem_seen: z.boolean(), schema_ok: z.boolean(), constraints_ok: z.boolean(), master_hit: z.boolean(), label: z.enum(["load","hold","reject"]), ts: z.string() })

쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라(쉬운 주문만 통과시키는 함정 회피): (1) 같은 화주의 표기 별칭('씨제이대한통운'/'CJ 대한통운', '엘엑스판토스'/'엘엑스 판토스'처럼 shipper_id 로 정규화돼야 함) 3건 이상, (2) 미등록 화주(shipper_id=null, master_hit=false) 2건, (3) 결측: lat/lng=null 또는 deliver_ts=null 인 행 2~3건, (4) 경계값: 중량 0·음수(constraints_ok=false)·픽업 시각이 배송 시각보다 늦은 제약 위반 각 2건, (5) 멱등 중복: 앞 행과 같은 idem_key 에 idem_seen=true 2건. label 은 위 규칙대로 정직하게. JSON 배열만.
schema (3 층의 단일 출처)
z.object({ order_id: z.string(), shipper_raw: z.string(), shipper_id: z.string().nullable(), pickup_ts: z.string(), deliver_ts: z.string().nullable(), lat: z.number().nullable(), lng: z.number().nullable(), weight_kg: z.number(), idem_key: z.string(), idem_seen: z.boolean(), schema_ok: z.boolean(), constraints_ok: z.boolean(), master_hit: z.boolean(), label: z.enum(["load","hold","reject"]), ts: z.string() })

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

기술 스택 매핑
Node.js주문 수신 워커·정규화·규칙 엔진·출력 스키마를 구동하는 서버 백엔드입니다
TypeScript정규화 파서·검증 규칙·출력 스키마의 구현 언어입니다
API·웹훅 수신고객사 주문 이벤트를 받는 인바운드 연동 경계입니다
멱등성 키같은 주문의 재전송을 중복 적재 없이 한 번만 처리하는 열쇠입니다
메시지 큐(DLQ)규칙 위반·거부 주문을 죽은편지큐로 격리해 재처리 대상과 분리합니다
관계형 DB화주·차량 마스터 참조 정합성 검증과 적재 저장소이며 인덱스·트랜잭션을 씁니다
이벤트 기반 아키텍처주문 이벤트 단위로 수신·정규화·검증·라우팅이 흐르는 골조입니다
관측성(APM·로그·트레이스)수신·거부·지연을 추적하는 지표·로그·트레이스입니다
AWS2주차부터 수신 워커·큐·DB 를 배포·운영합니다
Kubernetes수신 워커와 큐 소비자를 컨테이너로 배포·확장합니다
입력검증·시큐어코딩수신 페이로드 스키마 검증과 화주 데이터 권한 격리입니다
LLM화주별 비표준 주문 페이로드를 표준 스키마로 정규화·매핑하고 거부 사유를 문장화합니다
Claude정규화·사유 문장화 LLM 입니다
LLM 선택
model
Claude Sonnet (주문 페이로드 정규화·거부 사유 문장화) + GPT-4o-mini (정규화 결과 원문 매칭 검사)
prompt
few-shot 3 예시 + 표준 주문 스키마 강제 + 정규화 값마다 원문 필드값 인용 강제 + 매핑 못하면 null·미매핑 가드 + 후행 judge
rationale
적재/보류/거부 결정은 스키마·제약·멱등성·마스터 참조 규칙이 정하므로 LLM 정규화가 틀려도 규칙이 거릅니다. 정규화 품질에 Sonnet 을, judge 는 비용·속도 우선으로 mini 를 씁니다. 마스터 조회는 DB 질의로 하므로 RAG 는 쓰지 않습니다.
결정 게이트
1주차 끝게이트가 주문 이벤트를 받아 표준 스키마로 정규화하고 스키마·제약·멱등성·마스터 참조를 검사해 적재/보류/거부로 라우팅하는가. 여기까지가 그 자체로 제출 가능한 완성품입니다.

✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 2주차(라우팅이 맞았는지 확인)로 진행합니다.

2주차 끝라우팅 판정이 심은 정답 라벨·운영자 라벨로 맞다고 확인되고 정밀도·재현율과 일치도가 붙는가. AWS 배포에서 동일하게 도는가.

✓ pass → 여기서 멈춰도 완결입니다. 더 키우면 3주차(화주별 정합성 추이)로 진행합니다.

재사용 레이어 · 코어 70% / 도메인 30%
core (재사용 가능)
  • 주문 수신 파서 + 표준 스키마 강제
  • 정합성 규칙 엔진(스키마 위반·제약 위반·멱등 중복·마스터 미참조·결측)
  • 멱등성 중복 차단 + DLQ 격리 라우터
  • 화주별 수신 그리드·라우팅 카드·큐 미니뷰 컴포넌트
  • 거부 주문 알림·정합성 리포트 봇
  • 5% 사람 spot-check 샘플러
domain (교체 대상)
  • 표준 주문 스키마(필수 필드·제약 규칙) 정의
  • 화주·차량 마스터 데이터
  • 제약 규칙 enum(픽업<배송 시각·좌표 범위·중량>0)은 도메인별로 갈아끼웁니다
출력 스키마 · route_decision

수신 주문 1건의 라우팅 결정 카드. 결정·요인·근거를 한 스키마로 담아 화면 카드에 씁니다. 경로최적화 판정이 아니라 연동 경계 정합성 게이트입니다.

schema (JSON Schema)
z.object({ order_id: z.string(), shipper_id: z.string().nullable(), decision: z.enum(["load","hold","reject"]), factors: z.array(z.enum(["schema_violation","constraint_violation","idempotent_duplicate","master_miss","missing_field"])), reason: z.string().min(20), evidence: z.string().min(8), hedge: z.string().nullable() })
모범 출력 (3)
[
  {
    "input_ref": "ord_002 (제약 위반)",
    "output": {
      "order_id": "ord_002",
      "shipper_id": "cj",
      "decision": "reject",
      "factors": [
        "constraint_violation"
      ],
      "reason": "픽업 시각이 배송 시각보다 늦어 배차 제약을 위반합니다. 경로최적화 입력으로 넘기지 않고 거부해 DLQ 로 격리합니다.",
      "evidence": "pickup_ts=2026-03-04T14:00, deliver_ts=2026-03-04T09:00",
      "hedge": "제약을 위반해 적재하지 않습니다"
    }
  },
  {
    "input_ref": "ord_003 (멱등 중복)",
    "output": {
      "order_id": "ord_003",
      "shipper_id": "lx",
      "decision": "reject",
      "factors": [
        "idempotent_duplicate"
      ],
      "reason": "이미 처리한 멱등키와 같은 재전송 주문이라 중복 적재하면 배차가 두 번 잡힙니다. 한 번만 처리하도록 거부합니다.",
      "evidence": "idem_key=u-1001, idem_seen=true",
      "hedge": "재전송 중복이라 적재하지 않습니다"
    }
  },
  {
    "input_ref": "ord_004 (미등록 화주)",
    "output": {
      "order_id": "ord_004",
      "shipper_id": null,
      "decision": "hold",
      "factors": [
        "master_miss"
      ],
      "reason": "화주 코드가 마스터에 없어 표준 화주로 잇지 못합니다. 마스터 등록 후 재평가가 필요해 보류로 돌립니다.",
      "evidence": "shipper_raw=무등록화주Z, master_hit=false",
      "hedge": "마스터에 없는 화주라 적재하지 않고 보류로 둡니다"
    }
  }
]
검증 노트 (자동 vs 수동)

[자동 검증] 1. 스키마 parse 로 출력 형식(필드·enum)이 스키마를 통과하는지 확인합니다. 2. decision 이 정합성 규칙(스키마 위반/제약 위반/멱등 중복→reject·미등록 화주/결측 노드→hold·통과→load)과 일치하는지 봅니다. 3. evidence 가 입력 주문의 실제 필드값 인용인지 토큰 매칭으로 확인하고, constraints_ok=false 면 load 가 되지 않게 강제합니다. 4. decision 을 심은 정답 label 과 비교해 정밀도·재현율을 계산합니다. [수동 검증] 1. 운영자 2명이 비동기로 라우팅을 라벨링해 정밀도·재현율과 bootstrap Cohen's κ(두 사람 일치가 우연 이상인 정도, 0~1) 하한 0.6 이상을 봅니다. 2. 전체의 5% 를 사람이 직접 점검합니다.