본문으로 건너뛰기
retail
90

리테일 재고 인텔리전스

지점별 재고 현황과 경쟁사 가격 데이터를 모아 가격 경쟁력 대시보드를 완성합니다.

워크숍 목표

다 끝내고 나면 D.Hub 안에서 다음 흐름을 손으로 한 번 통과한 셈이 됩니다.

  • 시나리오 1개를 포털로 적재해 컬렉션·데이터셋·코드·파이프라인·온톨로지·대시보드를 한꺼번에 등록합니다.
  • 지점별 재고와 채널별 경쟁사 가격을 같은 컬렉션에 모으고, 두 원천 데이터셋의 스키마를 살펴봅니다.
  • update_competitor_prices 파이프라인으로 재고 데이터에 최신 경쟁사 가격을 덮어씁니다.
  • RI_Product, RI_Branch, RI_Region, RI_Supplier 4개 엔티티와 3개 관계로 짠 온톨로지를 둘러봅니다.
  • 가격 경쟁력 KPI와 지점·지역별 시각화를 묶은 inventory_overview 대시보드를 뜯어 봅니다.
  • (선택) 어시스턴트 에이전트로 그래프에 자연어 질의를 한 사이클 돌립니다.

분석가·엔지니어 코스에서 익힌 컬렉션·파이프라인·온톨로지·대시보드 개념을 실제 시나리오 하나로 묶어 보는 통합 실습입니다. 권장 소요 시간은 90분, 선택 섹션까지 합치면 100분쯤 걸립니다.

사전 준비

  • D.Hub 포털 접근 가능한 분석가 또는 엔지니어 계정 (Editor 권한 이상)
  • 약 2MB 의 zip 한 개를 받을 다운로드 여유

터미널·Python·dhub2-examples 클론은 필요 없습니다. 입문 튜토리얼인 시나리오 zip 으로 한 번에 가져오기첫 컬렉션 만들기 를 먼저 끝내 두면 1단계가 매끄럽게 풀립니다. 두 튜토리얼은 이 워크숍 페이지 상단의 사전 학습 카드에서 바로 열 수 있습니다.

1. 시나리오 적재 (10분)

zip 한 개를 받아 포털의 가져오기 다이얼로그로 올리면 시나리오에 묶인 자산이 한꺼번에 등록됩니다.

retail_inventory_intelligence.zip 다운로드

zip 을 받았다면 포털에서 좌측 사이드바의 컬렉션 으로 들어갑니다. Explorer 상단 헤더 — 페이지 제목 컬렉션 영역 — 오른쪽 더보기(⋯) 메뉴에 가져오기 항목이 있습니다. 이 항목을 눌러 가져오기 다이얼로그를 열고 방금 받은 zip 을 선택합니다. 업로드 진행률이 다이얼로그 안에 표시되고, 끝나면 컬렉션 한 개가 자동으로 만들어집니다.

manifest.json 순서대로 다음 자산이 차례로 올라갑니다.

  1. 컬렉션 retail_inventory_intelligence (alias: 리테일 재고 분석)
  2. 데이터셋 3종 — retail_inventory, competitor_prices, update_competitor_price
  3. 코드 2종 — update_competitor_price (python), build_retail_ontology (python)
  4. 파이프라인 2종 — update_competitor_prices, ontology_materialization
  5. 온톨로지 — 엔티티 4종(RI_Product, RI_Branch, RI_Region, RI_Supplier), 관계 3종(RI_LOCATED_IN, RI_STOCKED_AT, RI_SUPPLIED_BY)
  6. 대시보드 inventory_overview
  7. 에이전트 retail-assistant 와 도구 정의

적재가 끝나면 포털 좌측 컬렉션 트리에서 retail_inventory_intelligence 가 보일 겁니다. 보이면 1단계 끝입니다. 컬렉션 카드 헤더의 자산 개수가 위 목록 숫자와 맞는지도 한 번 확인합니다.

2. 데이터 둘러보기 (10분)

컬렉션 안의 Explorer 탐색기 를 열어 자산이 어떻게 묶여 있는지 봅니다.

데이터셋 카드 3종부터.

  • retail_inventory (alias: 제품 정보) — 지점별 상품 재고. 27개 컬럼. 지점 11개, 상품 코드, inventory_qty, outbound_qty, inventory_turnover_rate, selling_price_krw_synth, competitor_price_krw_synth, stockout_risk_flag_synth, 위·경도 좌표가 한 행에 다 들어 있습니다.
  • competitor_prices (alias: 경쟁사 가격 데이터) — 채널·지점·상품별 경쟁사 가격 관측. 10개 컬럼. retail_inventory 와의 조인 키는 item_code.
  • update_competitor_price (alias: 경쟁사 가격 업데이트 결과) — 파이프라인 산출물. 적재 직후엔 비어 있거나 샘플 parquet 만 들어 있는 경우도 있습니다.

데이터셋 카드를 하나씩 클릭해 봅니다.

  • 스키마 탭 — 컬럼 이름·타입·코멘트가 제대로 매핑됐는지
  • 미리 보기 탭 — 행 수가 0이 아닌지 (retail_inventory 기준 수백 행)
  • 버전 탭 — import 직후 v1 이 찍혀 있는지

이어서 코드 자산 2종(update_competitor_price.py, build_retail_ontology.py)을 한 번씩 열어 봅니다. 본문은 안 읽어도 됩니다. 입출력 시그니처만 슥 보고, 코드 노드가 어떤 데이터셋을 받아 어떤 데이터셋을 뱉는지만 머리에 남기면 충분합니다. 다음 단계의 파이프라인 그림과 같은 모양일 겁니다.

3. 파이프라인 한 번 실행 (15분)

이제 데이터를 한 번 흘려 봅니다. 컬렉션의 파이프라인 섹션에서 update_competitor_prices 를 눌러 워크플로우 편집기를 엽니다.

편집기에서 노드 세 개가 보입니다.

  • 좌측 입력: retail_inventory, competitor_prices 데이터셋 노드
  • 가운데: update_competitor_price 코드 노드 (python, cdc read mode)
  • 우측 출력: update_competitor_price 데이터셋 노드 (overwrite write mode)

코드 노드를 클릭하고 우측 패널의 스크립트 미리 보기를 펼치면 핵심 한 줄이 잡힙니다. item_code 를 키로 retail_inventorycompetitor_prices 를 left join 하고, competitor_price_krw_synth 컬럼을 최신 값으로 덮어씁니다. 출력은 늘 현재 시장 상태를 반영해야 하니 overwrite 모드입니다.

상단 Run 을 눌러 실행합니다. 실행 패널 아래쪽에 진행률과 단계 로그가 흐르고, 끝나면 우측 출력 노드 상태가 fresh 로 바뀝니다. 컬렉션 트리로 돌아가 update_competitor_price 의 행 수와 freshness timestamp 가 갱신됐는지 봅니다.

4. 온톨로지 확인 (15분)

이번엔 그래프 시점입니다. 좌측 사이드바의 온톨로지 영역으로 가서 retail_inventory_intelligence 컬렉션 컨텍스트의 엔티티 목록을 펼칩니다.

엔티티 4개, 관계 3개가 올라가 있어야 합니다.

종류이름의미
엔티티RI_Product상품 마스터. id = item_code, name, price, PROD_GRP
엔티티RI_Branch지점 마스터. id = branch_code, name, location, 위·경도
엔티티RI_Region지역 마스터. id = region_name (예: 서울 강남)
엔티티RI_Supplier공급업체 마스터. id = supplier_name
관계RI_LOCATED_INRI_BranchRI_Region
관계RI_STOCKED_ATRI_ProductRI_Branch. 재고·회전율·가격·품절 위험 속성을 모두 갖습니다
관계RI_SUPPLIED_BYRI_ProductRI_Supplier

RI_Product 카드를 누르고 빌더 탭에서 짚어 봅니다.

  • Backing datasetupdate_competitor_price 로 잡혀 있는지 (이 시나리오는 가공 후 데이터셋을 그래프로 올립니다)
  • 식별 키id, 표시 컬럼name 인지
  • 속성 매핑에서 PROD_GRP, price 가 데이터셋 컬럼과 1:1로 묶여 있는지

이어서 그래프 탐색기를 엽니다. 데이터가 비어 있으면 ontology_materialization 파이프라인을 한 번 더 돌려야 합니다. 이 파이프라인은 update_competitor_price 를 입력으로 받아 RI_* 테이블 7개(엔티티 4 + 관계 3)를 upsert 모드로 적재합니다. 끝나면 탐색기에서 Cypher 한 줄로 첫 인스턴스를 띄워 봅니다.

MATCH (p:RI_Product)-[r:RI_STOCKED_AT]->(b:RI_Branch)
RETURN p, r, b
LIMIT 25

상품–지점 간선 25개가 그래프 패널에 뜨면 4단계 끝입니다. 노드를 더블 클릭해 이웃을 확장하면 RI_LOCATED_IN 으로 지역까지, RI_SUPPLIED_BY 로 공급업체까지 펼쳐 들어갈 수 있습니다.

쿼리는 이런 모양이 됩니다.

MATCH (b:RI_Branch)-[:RI_STOCKED_AT]-(p:RI_Product)-[:RI_SUPPLIED_BY]-(s:RI_Supplier)
WHERE b.name = '강남파이낸스점'
RETURN p, s
LIMIT 50

5. 대시보드 확인 (15분)

마지막 정착점은 대시보드입니다. 컬렉션의 대시보드 섹션에서 inventory_overview (alias: 재고 인텔리전스 대시보드)를 엽니다. 위젯 13개가 4단으로 배치돼 있을 겁니다. 위 단의 5종부터.

  • 총 재고량 (statistic) — update_competitor_priceSUM(inventory_qty) 를 단위 EA 와 함께 표시
  • 총 출고량 (statistic) — SUM(outbound_qty)
  • 평균 회전율 (statistic) — AVG(inventory_turnover_rate) 를 % 로 표시
  • 품절위험 (statistic) — stockout_risk_flag_synth = 1 인 행 수
  • 평균할인율 (statistic) — AVG(discount_rate_synth) * 100

이 5종은 모두 SQL 쿼리 모드 로 짠 위젯입니다. 위젯 카드 우측 ⋯ 메뉴에서 편집을 누르면 쿼리 본문이 그대로 보입니다. 분석가 코스에서 익힌 간편 모드 vs 쿼리 모드 토글이 어떻게 적용됐는지 옆에 두고 비교해 봐도 좋습니다.

아래 단으로 내려가면 시각화 위젯이 이어집니다.

  • 지점별 재고/출고 현황 — 누적 막대 차트. branch_name 기준 재고 vs 출고를 UNION ALL 로 묶어 한 차트에 그립니다.
  • 일별 출고 추이 — 라인 차트. delivery_date 를 X축으로, 지점별 멀티 시리즈입니다.
  • 시간대별 출고 히트맵delivery_time × branch_name 강도 맵.
  • 지점별 재고 비율 — 도넛 차트. 비율 라벨이 표시됩니다.
  • 재고 상세 데이터 — 데이터 테이블. 페이지 크기 10, 정렬·검색 활성화.

마지막 단은 가격 경쟁력 위젯 3종입니다. 경쟁사 대비 고가 품목 통계, 지점별 평균 가격차이 막대, 가격 조정 후보 테이블 — 셋 다 selling_price_krw_synth > competitor_price_krw_synth 조건을 공유합니다. 3단계 파이프라인을 돌리지 않았다면 이 세 위젯의 값은 의미가 없습니다.

6. (선택) 어시스턴트 에이전트 (10분)

시간이 남으면 시나리오에 함께 들어 있는 retail-assistant 에이전트를 호출해 봅니다. 컬렉션의 에이전트 영역에서 리테일 어시스턴트 카드를 열고 새 세션을 시작합니다. 질문 두 개로 한 사이클을 돌려 봅니다.

  • "강남파이낸스점에서 판매하는 상품과 공급업체를 보여 주세요."
  • "경쟁사 대비 가격 경쟁력이 가장 낮은 지점 5곳을 알려 주세요."

에이전트는 ontology_graph_query 도구로 Cypher 를 실행하고, 결과를 한국어 표·막대 차트·지도로 같이 답합니다. 응답 본문에 [[강남파이낸스점]] 같은 노드 마커가 보이면 그래프 탐색기와 양방향으로 연동됐다는 신호입니다.

이 단계는 핵심 경로는 아닙니다. 다만 같은 그래프를 사람·도구·LLM 세 시각에서 만져 본다는 점에서, 다음 라운드의 자동화 학습으로 넘어가는 디딤돌이 됩니다.

7. 다음 단계 (5분)

여기까지 왔다면 학습 센터가 그려 둔 학습 지도 위에서 분석가 코스의 분석·시각화엔지니어 코스의 데이터 모델링·파이프라인 두 갈래가 한 시나리오로 합쳐지는 지점을 통과한 셈입니다. 끌리는 방향으로 한 발 더 들어갑니다.

  • 분석가 코스의 차트·DRS 레슨을 다시 열어, 이 워크숍 위젯의 쿼리 모드 동작을 코드로 분해해 봅니다.
  • 엔지니어 코스로 가서 코드 노드·파이프라인 옵션을 더 깊이 팝니다. cdc 읽기 모드, overwrite 쓰기 모드가 다음 라운드의 주제입니다.
  • 자기 도메인 시나리오dhub2-examples 에 씁니다. Authoring 페이지에 새 시나리오를 만들 때 따라야 할 매니페스트 구조와 PR 체크리스트가 정리돼 있습니다.

여기까지 도달한 학습자는 dhub2-examples 의 한 시나리오가 포털 안에서 살아 움직이는 자원으로 풀리는 흐름을 한 사이클 직접 통과한 셈입니다. 분석가의 위젯과 엔지니어의 파이프라인이 한 시나리오 안에서 만나는 지점을 손으로 거쳤다면, 다른 도메인 시나리오(SAP · IoT · 공공 데이터)를 import 할 때도 이 흐름이 거의 그대로 형판처럼 작동합니다.

검증 체크리스트

워크숍이 끝났는지는 다음 5가지로 자가 점검합니다.

  • 컬렉션 트리에 retail_inventory_intelligence 가 보이고, 자산 개수가 7종(데이터셋 3, 코드 2, 파이프라인 2 — 온톨로지·대시보드·에이전트 제외)으로 맞는지
  • update_competitor_prices 실행 뒤 update_competitor_price 의 freshness 가 최신 timestamp 인지
  • 대시보드 KPI 품절위험 값이 0보다 큰지 (시나리오 데이터에 일부러 stockout flag 가 섞여 있습니다)
  • 그래프 탐색기에서 상품 하나를 시작점으로 RI_STOCKED_AT 관계를 따라 지점 노드를 펼칠 수 있는지
  • 대시보드 위젯 13종 중 빈 카드가 없는지 — 비어 있다면 3단계 파이프라인이나 의존 데이터셋 freshness 를 점검