라플라스테크놀로지스
경력근거: 3rd Party API를 이용한 데이터 소싱 및 통합
※ 실제 산출물이 아닌 AI 예측 시안입니다.
공고가 주요 업무에 '다양한 고객사의 요구사항을 분석하고 커스텀 대시보드 및 데이터 기능을 구현합니다' 를 적었고, 제품 소개에는 '주문, 고객, 광고, 재무, 재고, 인플루언서, 검색 트렌드, 리뷰 등 이커머스 전방위 데이터를 라플라스에 통합하여' 가 있습니다. 채널마다 다른 원장을 한 지표로 접는 자리가 이 포지션의 일이고, 이 포트폴리오는 그 접는 과정에서 빠지는 행을 사전과 규칙으로 드러냅니다. 'SQL을 활용한 ELT 프로세스 개발' 과 '3rd Party API를 이용한 데이터 소싱 및 통합' 도 같은 지점을 가리킵니다. 이 포트폴리오가 보여주는 것은 채널별 사전을 데이터로 두고 원장과 맞춰 지표 반영 여부를 가르는 기술이며, 이커머스 정산 실무나 광고 데이터 분석 전문성은 주장하지 않습니다. 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
'고객 대면을 통해 파악한 실제 문제를 해결하는 CEO 직속 조직입니다'. 대시보드가 그 해결의 표면입니다.
'주문, 고객, 광고, 재무, 재고, 인플루언서, 검색 트렌드, 리뷰 등 이커머스 전방위 데이터를 라플라스에 통합'. 통합 지점의 어긋남이 이 화면의 주제입니다.
'SQL을 활용한 ELT 프로세스 개발' 과 '3rd Party API를 이용한 데이터 소싱 및 통합'. 채널마다 다른 원장을 받는 자리입니다.
주문 행이 통합 지표에 들어갔는지 가릅니다. 채널별 상태 사전과 환율·수수료율을 표로 두고 원장 행과 맞춰, 사전에 있는 상태면 원화로 접어 지표에 넣고 아니면 상태 미등록으로 남깁니다. 통화가 비면 금액을 지어 채우지 않고 빼며, 환불이 가리키는 원주문이 원장에 없으면 짝 없음으로, 같은 주문번호가 두 행이면 중복으로 묶습니다. 사전에 없는 채널은 미등록으로 남겨 사전을 먼저 채우게 합니다. 원장은 실 고객사 파일 대신 지원자가 공개 커머스 데이터셋을 채널별 내려받기 양식으로 다시 적어 만든 것을 가정합니다.
고객사마다 다른 채널 원장을 받아 통합 지표에 얹는 자리에 앉는 FDE 입니다. 합계가 안 맞는다는 말을 들으면 어느 행이 왜 빠졌는지를 매번 원장을 열어 눈으로 뒤지던 사람입니다.
채널별 상태 사전과 환율·수수료율을 표로 두고 원장 행과 맞추면, 지표에 들어간 행과 빠진 행이 규칙으로 갈리고 빠진 행마다 이유가 근거로 남는다는 가정입니다. 사전에 없는 채널과 상태는 미등록으로 빠지므로 아직 사전이 없는 구간이 그대로 드러납니다.
주문 원장과 채널 사전을 받아 행마다 지표 반영·제외를 판정하고, 제외면 상태 미등록·통화 누락·환불 짝 없음·중복·채널 미등록 중 어느 쪽인지 붙여 사유별로 묶어 보여주는 관리자 페이지가 도는 완결품입니다.
공개 데이터셋을 다시 적어 만든 주문 400건에 손으로 붙인 정답 판정과 대조해 일치율을 내고, 미등록이 몰리는 채널과 상태를 모아 사전에 없는 구간을 화면에서 바로 채우게 합니다.
사전을 채운 뒤 지표가 얼마나 달라졌는지 채우기 전후로 나란히 내고, 어느 채널의 어느 상태를 채운 것이 가장 크게 되돌렸는지 보여주는 단계입니다.
FDE 가 주문 원장과 채널 사전을 넣으면 행마다 지표 반영 여부와 빠진 이유가 사유별로 묶여 나오는 과정을 시연합니다.
공개 데이터셋을 다시 적어 만든 주문 400건과 손으로 붙인 정답 판정을 대조해 일치율을 냅니다. 단, 정답과 원장을 모두 작성자가 만든 합성 기준이라 성능 검증이 아니라 데모 조건 동작입니다.
통화가 비었거나 채널 표기가 흔들리거나 사전에 없는 상태가 섞인 입력 30종을 넣어도 화면이 안 깨지고 사유별로 빠지는 비율을 보여줍니다.
사전을 고쳤을 때 옛 판정과 합계가 어떻게 달라지는지 회귀로 확인합니다.
진짜 성능 검증은 여기서 멈춥니다. 위 수치는 작성자가 만든 원장의 자가채점이며, 실제 지표 정합은 라플라스 고객사의 실 채널 원장과 실 정산 자료가 있어야 측정됩니다. 이 포트폴리오는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다.
수치는 합성 데이터 자가채점이라 성능 증명이 아니므로, 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명합니다.
정답을 작성자가 붙였으니 잘 맞는 게 당연하므로, 통화 결측과 짝 없는 환불, 사전에 없는 채널을 일부러 섞어 쉬운 행만 푸는 함정을 피합니다.
이 포트폴리오가 보여주는 것은 채널별 사전을 데이터로 두고 원장과 맞춰 지표 반영 여부를 가르는 기술이며, 이커머스 정산 실무나 광고 데이터 분석 전문성은 주장하지 않습니다. 판정은 사전 대조와 환산이 하고 LLM 은 담당자가 읽을 사유 문장만 맡습니다.
환율을 사전에 적힌 고정값으로 쓰기 때문에 실제 정산 환율과 어긋날 수 있어서, 환산 금액에 쓴 환율을 함께 실어 담당자가 확인하게 둡니다.
실제 도입 때는 고객사마다 채널 구성과 수수료 계약이 다르므로, 사전을 새로 채우는 일을 도입 단계 과제로 둡니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
채널별로 내려받은 주문 원장입니다. 주문번호와 채널 표기 원문, 상태 이름 원문, 주문일, 결제 금액, 통화, 환불이 가리키는 원주문, 구매자 키를 한 행에 둡니다. 채널 표기는 담당자가 손으로 적어 '스마트스토어'와 '스마트 스토어'처럼 흔들립니다. 통화가 비어 있는 행, 원주문이 원장에 없는 환불 행, 같은 주문번호가 두 행으로 올라온 경우, 사전에 없는 채널과 상태를 일부러 섞어 두어 사유가 갈리게 둡니다.
| order_no | channel_raw | status_raw | ordered_at | gross_amount | currency_raw | refund_of_order_no | buyer_key | buyer_name |
|---|---|---|---|---|---|---|---|---|
| ORD-24081101 | 스마트스토어 | 결제완료 | 2026-08-11 | 48,000 | KRW | — | BK-1001 | 김하린 |
| ORD-24081102 | 스마트 스토어 | 배송중 | 2026-08-11 | 132,000 | KRW | — | BK-1002 | 이준서 |
| ORD-24081103 | 쿠팡 | 출고완료 | 2026-08-11 | 29,800 | KRW | — | BK-1003 | — |
| ORD-24081104 | 쿠팡 | 부분취소 | 2026-08-11 | 15,000 | KRW | — | BK-1004 | 박서윤 |
| ORD-24081105 | Shopify | paid | 2026-08-11 | 89 | USD | — | BK-1005 | Emma L. |
아래 JSON Schema 를 그대로 만족하는 주문 행을 200개 더 만들어 주세요. 채널 표기는 '스마트스토어'와 '스마트 스토어'처럼 띄어쓰기를 흔들어 적습니다. 2할은 통화나 구매자 이름을 비우고, 몇 건은 원주문이 원장에 없는 환불로 두며, 몇 건은 같은 주문번호를 두 행으로 올리고, 몇 건은 사전에 없는 채널을 씁니다. 지표 반영 여부나 사유는 넣지 마세요.
{"type": "object", "properties": {"order_no": {"type": "string"}, "channel_raw": {"type": "string"}, "status_raw": {"type": "string"}, "ordered_at": {"type": "string"}, "gross_amount": {"type": "number"}, "currency_raw": {"type": ["string", "null"]}, "refund_of_order_no": {"type": ["string", "null"]}, "buyer_key": {"type": "string"}, "buyer_name": {"type": ["string", "null"]}}, "required": ["order_no", "channel_raw", "status_raw", "ordered_at", "gross_amount", "currency_raw", "buyer_key"]}{"type": "object", "properties": {"order_no": {"type": "string"}, "channel_raw": {"type": "string"}, "status_raw": {"type": "string"}, "ordered_at": {"type": "string"}, "gross_amount": {"type": "number"}, "currency_raw": {"type": ["string", "null"]}, "refund_of_order_no": {"type": ["string", "null"]}, "buyer_key": {"type": "string"}, "buyer_name": {"type": ["string", "null"]}}, "required": ["order_no", "channel_raw", "status_raw", "ordered_at", "gross_amount", "currency_raw", "buyer_key"]}채널별 상태 사전이자 계수표입니다. 채널 표기와 상태 이름 원문, 그 상태가 옮겨질 공통 코드, 통화, 원화 환율, 수수료율을 한 행에 둡니다. 환율과 수수료율이 여기에 있어야 원화 금액이 사전 값과 원장 값만으로 다시 계산됩니다. 원장에 나오는 채널과 상태 중 일부는 일부러 넣지 않아 미등록이 도출되게 둡니다.
| map_no | channel_raw | status_raw | status_code | currency_raw | fx_to_krw | fee_rate |
|---|---|---|---|---|---|---|
| CM-1001 | 스마트스토어 | 결제완료 | paid | KRW | 1 | 0.055 |
| CM-1002 | 스마트스토어 | 배송중 | shipped | KRW | 1 | 0.055 |
| CM-1003 | 스마트스토어 | 구매확정 | delivered | KRW | 1 | 0.055 |
| CM-1004 | 쿠팡 | 출고완료 | shipped | KRW | 1 | 0.108 |
| CM-1005 | 쿠팡 | 배송완료 | delivered | KRW | 1 | 0.108 |
아래 JSON Schema 를 그대로 만족하는 채널 사전 행을 40개 더 만들어 주세요. 채널마다 상태 이름을 서너 개씩 붙이고 공통 코드를 다섯 값으로 고루 씁니다. 통화·환율·수수료율은 채널마다 다르게 두고, 원장에 나오는 채널과 상태 중 일부는 일부러 넣지 마세요 — 미등록이 있어야 사전의 구멍이 드러납니다.
{"type": "object", "properties": {"map_no": {"type": "string"}, "channel_raw": {"type": "string"}, "status_raw": {"type": "string"}, "status_code": {"type": "string", "enum": ["paid", "shipped", "delivered", "refunded", "cancelled"]}, "currency_raw": {"type": "string"}, "fx_to_krw": {"type": "number"}, "fee_rate": {"type": "number"}}, "required": ["map_no", "channel_raw", "status_raw", "status_code", "currency_raw", "fx_to_krw", "fee_rate"]}{"type": "object", "properties": {"map_no": {"type": "string"}, "channel_raw": {"type": "string"}, "status_raw": {"type": "string"}, "status_code": {"type": "string", "enum": ["paid", "shipped", "delivered", "refunded", "cancelled"]}, "currency_raw": {"type": "string"}, "fx_to_krw": {"type": "number"}, "fee_rate": {"type": "number"}}, "required": ["map_no", "channel_raw", "status_raw", "status_code", "currency_raw", "fx_to_krw", "fee_rate"]}| Python | 원장과 사전을 맞춰 지표 반영 여부를 정하는 판정기를 맡습니다. |
| SQL | 채널별 원장을 한 모양으로 접어 올리는 ELT 단계를 맡습니다. |
| FastAPI | 판정 결과를 화면이 읽을 형태로 내려주는 백엔드를 맡습니다. |
| React | 사유별로 묶은 목록과 원장 원문을 나란히 펴는 화면을 맡습니다. |
✗ fail → 미등록이 절반을 넘으면 사전을 먼저 채웁니다.
✓ pass → 2주차 정답 대조로 넘어갑니다.
✗ fail → 어긋난 유형을 모아 상태 코드의 범위를 다시 봅니다.
✓ pass → 3주차 전후 비교로 넘어갑니다.
위 예측 UI 는 3주차까지 완주했을 때의 화면입니다. 1주차에 실제로 만드는 것은 아래 표시된 화면 하나입니다.
rollup_code사유 라벨 · order_no + 한 줄 요약(근거 수치 포함)화면·코드·면접에서 이 단어를 그대로 씁니다. 키는 출력 스키마의 enum 과 같습니다.
counted지표 반영status_unmapped상태 미등록currency_missing통화 누락refund_pair_broken환불 짝 없음duplicate_order주문번호 중복channel_unmapped채널 미등록주문 행 하나가 채널 사전과 만나는 자리마다 통합 지표에 들어가는지를 정합니다. 들어가면 원화로 접은 금액을 싣고, 빠지면 상태 미등록·통화 누락·환불 짝 없음·중복·채널 미등록 중 어느 쪽인지 싣습니다. 화면은 이 사유 코드로 묶습니다.
{"type": "object", "properties": {"verdict_no": {"type": "string"}, "order_no": {"type": "string"}, "channel_raw": {"type": "string"}, "map_no": {"type": ["string", "null"]}, "status_code": {"type": ["string", "null"]}, "rollup_code": {"type": "string", "enum": ["counted", "status_unmapped", "currency_missing", "refund_pair_broken", "duplicate_order", "channel_unmapped"]}, "net_krw": {"type": ["number", "null"], "description": "gross_amount 에 fx_to_krw 를 곱하고 (1 - fee_rate) 를 곱해 원 단위로 반올림한 값입니다. rollup_code 가 counted 일 때만 채웁니다."}, "twin_order_no": {"type": ["string", "null"]}, "evidence": {"type": "array", "items": {"type": "object", "properties": {"field": {"type": "string"}, "agg": {"type": ["string", "null"]}, "value": {}}, "required": ["field", "value"]}}, "summary": {"type": "string"}, "hedge": {"type": ["string", "null"]}}, "required": ["verdict_no", "order_no", "channel_raw", "rollup_code", "evidence", "summary"]}[
{
"verdict_no": "OV-001",
"order_no": "ORD-24081101",
"channel_raw": "스마트스토어",
"map_no": "CM-1001",
"status_code": "paid",
"rollup_code": "counted",
"net_krw": 45360,
"twin_order_no": null,
"evidence": [
{
"field": "gross_amount",
"agg": null,
"value": 48000
},
{
"field": "fx_to_krw",
"agg": null,
"value": 1
},
{
"field": "fee_rate",
"agg": null,
"value": 0.055
}
],
"summary": "결제완료를 paid 로 읽고 수수료를 뺀 45,360원이 지표에 들어갑니다.",
"hedge": null
},
{
"verdict_no": "OV-002",
"order_no": "ORD-24081105",
"channel_raw": "Shopify",
"map_no": "CM-1007",
"status_code": "paid",
"rollup_code": "counted",
"net_krw": 119670,
"twin_order_no": null,
"evidence": [
{
"field": "gross_amount",
"agg": null,
"value": 89
},
{
"field": "fx_to_krw",
"agg": null,
"value": 1385
},
{
"field": "fee_rate",
"agg": null,
"value": 0.029
}
],
"summary": "달러 결제를 원화로 환산하고 수수료를 뺀 119,670원이 지표에 들어갑니다.",
"hedge": "환율은 사전에 적힌 고정값이라 실제 정산 환율과 다를 수 있습니다."
},
{
"verdict_no": "OV-003",
"order_no": "ORD-24081109",
"channel_raw": "쿠팡",
"map_no": null,
"status_code": null,
"rollup_code": "status_unmapped",
"net_krw": null,
"twin_order_no": null,
"evidence": [
{
"field": "status_raw",
"agg": null,
"value": "교환접수"
},
{
"field": "map_no",
"agg": "count",
"value": 4
}
],
"summary": "교환접수가 사전의 쿠팡 상태 넷 어디에도 없어 지표에 넣지 않고 남깁니다.",
"hedge": null
},
{
"verdict_no": "OV-004",
"order_no": "ORD-24081108",
"channel_raw": "스마트스토어",
"map_no": "CM-1001",
"status_code": "paid",
"rollup_code": "currency_missing",
"net_krw": null,
"twin_order_no": null,
"evidence": [
{
"field": "currency_raw",
"agg": null,
"value": null
},
{
"field": "gross_amount",
"agg": null,
"value": 76000
}
],
"summary": "통화가 비어 있어 원화로 접을 근거가 없으므로 금액을 지표에 넣지 않습니다.",
"hedge": "채널이 원화만 쓰더라도 원장이 비었으면 채워 넣지 않고 원본을 다시 받습니다."
},
{
"verdict_no": "OV-005",
"order_no": "ORD-24081107",
"channel_raw": "Shopify",
"map_no": "CM-1009",
"status_code": "refunded",
"rollup_code": "refund_pair_broken",
"net_krw": null,
"twin_order_no": "ORD-24079931",
"evidence": [
{
"field": "refund_of_order_no",
"agg": null,
"value": "ORD-24079931"
},
{
"field": "order_no",
"agg": "count",
"value": 12
}
],
"summary": "환불이 가리키는 원주문이 이번 원장 열두 건에 없어 차감할 대상을 못 찾습니다.",
"hedge": "지난 기간 주문일 수 있어 원장 범위를 넓혀 다시 봅니다."
},
{
"verdict_no": "OV-006",
"order_no": "ORD-24081111",
"channel_raw": "스마트스토어",
"map_no": "CM-1001",
"status_code": "paid",
"rollup_code": "duplicate_order",
"net_krw": null,
"twin_order_no": "ORD-24081111",
"evidence": [
{
"field": "order_no",
"agg": "count",
"value": 2
},
{
"field": "gross_amount",
"agg": null,
"value": 21000
}
],
"summary": "같은 주문번호가 두 행으로 올라와 한 번만 세도록 묶고 지표에서 뺍니다.",
"hedge": null
},
{
"verdict_no": "OV-007",
"order_no": "ORD-24081110",
"channel_raw": "라이브커머스",
"map_no": null,
"status_code": null,
"rollup_code": "channel_unmapped",
"net_krw": null,
"twin_order_no": null,
"evidence": [
{
"field": "channel_raw",
"agg": null,
"value": "라이브커머스"
},
{
"field": "map_no",
"agg": "count",
"value": 12
}
],
"summary": "사전 열두 행에 이 채널이 없어 미등록으로 남기고 사전을 먼저 채웁니다.",
"hedge": null
}
][자동 검증 · 코드가 판정합니다] 1. rollup_code 가 enum 여섯 값 중 하나인지 확인합니다. 2. verdict_no·order_no·channel_raw·rollup_code·evidence·summary 가 모두 채워졌는지 확인합니다. 3. order_no 가 원장에 실재하는 주문번호인지 대조합니다. 4. map_no 가 있으면 채널 사전에 실재하는 행 번호인지 대조합니다. 5. map_no 가 있으면 status_code 가 그 사전 행의 값과 같은지 대조합니다. 6. channel_raw 를 공백·기호를 지워 접은 뒤 사전의 채널과 맞고, 맞는 행이 없으면 rollup_code 가 channel_unmapped 인지 확인합니다. 7. 채널은 맞는데 status_raw 가 그 채널의 사전 행 어디에도 없으면 rollup_code 가 status_unmapped 인지 확인합니다. 8. currency_raw 가 비어 있으면 rollup_code 가 currency_missing 이고 net_krw 가 비었는지 확인합니다. 9. refund_of_order_no 가 있는데 그 주문번호가 원장에 없으면 rollup_code 가 refund_pair_broken 인지 확인합니다. 10. 같은 order_no 가 원장에 둘 이상이면 rollup_code 가 duplicate_order 이고 twin_order_no 가 채워졌는지 확인합니다. 11. rollup_code 가 counted 이면 net_krw 를 gross_amount × fx_to_krw × (1 − fee_rate) 로 다시 계산해 원 단위 반올림 값이 같은지 확인합니다. 12. rollup_code 가 counted 가 아니면 net_krw 가 비었는지 확인합니다. 13. evidence 의 field 이름이 원장과 사전에 실재하는 컬럼인지 대조합니다. 14. agg 가 없는 evidence 의 value 가 그 컬럼에 수록된 행 값과 같은지 확인합니다. 15. summary 가 존댓말로 끝나는지 확인합니다. [평가 러너 · 2주차] 공개 데이터셋을 다시 적어 만든 주문 400건에 손으로 붙인 정답 판정과 대조해 일치율과 사유 코드별 분포를 내고, 미등록이 몰리는 채널과 상태를 모아 사전에 없는 구간을 목록으로 냅니다. [수동 검증 · 사람이 봅니다] 1. 어느 상태 코드까지 지표에 넣을지 담당자가 정합니다. 2. 짝을 못 찾은 환불을 지난 기간까지 넓혀 볼지 담당자가 정합니다.