# 시나리오: SAP ERP 영업 분석

SAP ERP의 SD(판매 유통)·MM(자재 관리) 원시 테이블을 수집·결합·변환하여 분석용 뷰를 생성하고, 시계열·고객·자재·지역별 집계 요약을 산출하는 시나리오입니다.

---

## 엔티티 관계 개요

```text
SAP 원시 테이블
  tb_sap_vbak  tb_sap_vbap  tb_sap_kna1  tb_sap_mara  tb_sap_makt

               ┌─────────────────────────────────────────────────┐
               │  sap_pipeline_join_sales                        │
               │  VBAK + VBAP → tb_sales_all → tb_sales          │
               └─────────────────────────────────────────────────┘

               ┌─────────────────────────────────────────────────┐
               │  sap_pipeline_join_material                     │
               │  MARA → tb_mara_info                            │
               │  MAKT → tb_makt_lang_filter                     │
               │  mara_info + makt_lang → tb_material            │
               └─────────────────────────────────────────────────┘

               ┌─────────────────────────────────────────────────┐
               │  sap_pipeline_transform_customer                │
               │  KNA1 → tb_customer                             │
               └─────────────────────────────────────────────────┘

               ┌─────────────────────────────────────────────────┐
               │  sap_pipeline_unification_total                 │
               │  tb_material + tb_sales → tb_sales_material     │
               │  tb_customer + tb_sales_material                │
               │                       → tb_sales_master         │
               └─────────────────────────────────────────────────┘

  tb_sales_master ──► 연도 / 월 / 일자 / 고객 /
                      국가 / 대륙 / 산업 / 자재 유형 집계
  집계 데이터 + tb_sales + tb_sales_master ──► ontology_materialization
                                      → 고객/주문/주문라인/자재 그래프
```

---

## 데이터셋

| 이름 | 설명 |
| ---- | ---- |
| `tb_sap_vbak` | SAP SD 수주 헤더 (주문번호, 일자, 조직, 고객) |
| `tb_sap_vbap` | SAP SD 수주 라인 아이템 (자재, 수량, 순가치) |
| `tb_sap_kna1` | SAP SD 고객 마스터 (이름, 국가, 지역) |
| `tb_sap_mara` | SAP MM 자재 마스터 (유형, 산업, 기본 단위) |
| `tb_sap_makt` | SAP MM 자재 설명 (언어, 단·장 텍스트) |
| `tb_sales_all` | VBAK + VBAP 원시 조인 결과 |
| `tb_sales` | 주문 일자 파싱·처리가 완료된 영업 데이터 |
| `tb_customer` | KNA1에서 처리된 고객 차원 테이블 |
| `tb_mara_info` | MARA에서 매핑된 자재 속성 |
| `tb_makt_lang_filter` | 대상 언어로 필터링된 자재 설명 |
| `tb_material` | MARA + MAKT 결합 최종 자재 차원 테이블 |
| `tb_sales_material` | 자재 차원이 조인된 영업 데이터 |
| `tb_sales_master` | 영업 + 자재 + 고객이 통합된 마스터 테이블 |
| `tb_year_info` | 연도별 영업 집계 |
| `tb_month_info` | 월별 영업 집계 |
| `tb_date_info` | 일별 영업 집계 |
| `tb_customer_summary` | 고객별 영업 요약 |
| `tb_customer_country_summary` | 국가별 고객 집계 |
| `tb_customer_continent_summary` | 대륙별 고객 집계 |
| `tb_industry_summary` | 산업별 영업 집계 |
| `tb_material_summary` | 자재 유형별 영업 집계 |

---

## 파이프라인

### `sap_pipeline_join_sales`

**목적:** SAP 수주 헤더(VBAK)와 라인 아이템(VBAP)을 결합하고 날짜 차원을 부여해 영업 팩트 테이블의 기반을 구축합니다. 주문 데이터가 필요한 모든 하위 파이프라인은 `tb_sales`에서 읽습니다.

| 스텝 | 스크립트 | 입력 → 출력 | 역할 |
| ---- | -------- | ----------- | ---- |
| `join_vbak_vbap` | `join_vbak_vbap` | `tb_sap_vbak` + `tb_sap_vbap` → `tb_sales_all` | 주문번호 기준 수주 헤더와 라인 아이템 조인 |
| `processing_order_date` | `processing_order_date` | `tb_sales_all` → `tb_sales` | SAP 날짜 형식 파싱; 연·월·일 컬럼 추출 |

---

### `sap_pipeline_join_material`

**목적:** 자재 마스터 속성(MARA)과 필터링된 자재 설명(MAKT)을 결합해 자재 차원 테이블을 구축합니다. 영업 데이터 조인에 활용되는 깨끗한 자재 참조 테이블을 제공합니다.

| 스텝 | 스크립트 | 입력 → 출력 | 역할 |
| ---- | -------- | ----------- | ---- |
| `mapping_mara_info` | `mapping_mara_info` | `tb_sap_mara` → `tb_mara_info` | MARA 원시 필드를 분석 가능한 속성으로 매핑 |
| `filtering_makt_lang` | `filtering_makt_lang` | `tb_sap_makt` → `tb_makt_lang_filter` | 자재 설명을 대상 언어 단건으로 필터링 |
| `join_mara_makt` | `join_mara_makt` | `tb_mara_info` + `tb_makt_lang_filter` → `tb_material` | 속성과 설명을 결합해 자재 차원 테이블 완성 |

---

### `sap_pipeline_transform_customer`

**목적:** SAP 고객 마스터(KNA1)를 표준화된 국가·지역 코드가 포함된 고객 차원 테이블로 변환해 지역별 집계에 활용할 수 있게 합니다.

| 스텝 | 스크립트 | 입력 → 출력 | 역할 |
| ---- | -------- | ----------- | ---- |
| `processing_customer_info` | `processing_customer_info` | `tb_sap_kna1` → `tb_customer` | 고객 마스터 필드 표준화 및 보강 |

---

### `sap_pipeline_unification_total`

**목적:** 모든 집계 파이프라인이 읽는 단일 통합 마스터 테이블(`tb_sales_master`)을 생성합니다. 영업·자재·고객 세 가지 핵심 차원을 집계에 최적화된 비정규화 팩트 테이블로 결합합니다.

| 스텝 | 스크립트 | 입력 → 출력 | 역할 |
| ---- | -------- | ----------- | ---- |
| `join_sales_material` | `join_sales_material` | `tb_material` + `tb_sales` → `tb_sales_material` | 영업 레코드에 자재 속성 추가 |
| `join_customer_sales_material` | `join_customer_sales_material` | `tb_customer` + `tb_sales_material` → `tb_sales_master` | 고객 차원을 붙여 통합 마스터 완성 |

---

### 집계 파이프라인

아래 파이프라인들은 각각 `tb_sales_master`(또는 중간 집계 테이블)를 읽어 단일 집계 결과를 생성합니다. `sap_pipeline_unification_total` 완료 후 독립적으로 병렬 실행 가능합니다.

| 파이프라인 | 입력 → 출력 | 목적 |
| ---------- | ----------- | ---- |
| `sap_pipeline_year_summary` | `tb_sales_master` → `tb_year_info` | 트렌드 분석용 연도별 영업 합계 |
| `sap_pipeline_month_summary` | `tb_sales_master` → `tb_month_info` | 계절성 분석용 월별 영업 합계 |
| `sap_pipeline_date_summary` | `tb_sales_master` → `tb_date_info` | 운영 모니터링용 일별 영업 합계 |
| `sap_pipeline_customer_summary` | `tb_sales_master` → `tb_customer_summary` | 고객별 매출·주문 수·거래 금액 요약 |
| `sap_pipeline_country_summary` | `tb_customer_summary` → `tb_customer_country_summary` | 국가별 매출 집계 |
| `sap_pipeline_continent_summary` | `tb_customer_summary` → `tb_customer_continent_summary` | 대륙별 매출 집계 |
| `sap_pipeline_industry_summary` | `tb_sales_master` → `tb_industry_summary` | 자재 산업 코드별 매출 분석 |
| `sap_pipeline_material_type` | `tb_sales_master` → `tb_material_summary` | 자재 유형별 매출 분석 |

### `ontology_materialization`

**목적:** SAP 요약 데이터셋과 처리된 영업 팩트 테이블에서 그래프 적재용 온톨로지 엔티티·관계 테이블을 생성합니다.

라인 레벨 그래프는 현재 3,413개 주문 라인으로 구성된 번들 샘플 규모를 기준으로 합니다. 운영 SAP export처럼 데이터가 커지는 경우 import 전 배치 materialization 또는 주문/자재 집계 뷰 방식으로 전환하는 것을 권장합니다. 자재 유형이나 산업 분류가 비어 있는 라인은 `UNKNOWN` 차원 노드로 매핑해 sparse master data 때문에 그래프 생성이 중단되지 않도록 합니다.

| 스텝 | 스크립트 | 입력 → 출력 | 역할 |
| ---- | -------- | ----------- | ---- |
| `build_ontology_tables` | `build_sap_ontology` | SAP 요약 데이터 + `tb_sales` + `tb_sales_master` → `SAP_*` 엔티티·관계 | 상위 집계 완료 후 온톨로지 import 테이블 materialize |

---

## 온톨로지

| 유형 | 이름 | 관계 |
| ---- | ---- | ---- |
| 엔티티 | `sap_customer` | 고객 차원 |
| 엔티티 | `sap_sales_order` | 수량/순매출 집계를 포함한 판매 주문 |
| 엔티티 | `sap_sales_order_line` | 자재·수량·순매출을 포함한 판매 주문 라인 |
| 엔티티 | `sap_country` | 국가 차원 |
| 엔티티 | `sap_continent` | 대륙 차원 |
| 엔티티 | `sap_order_date` | 주문일 차원 |
| 엔티티 | `sap_order_month` | 주문월 차원 |
| 엔티티 | `sap_order_year` | 주문연도 차원 |
| 엔티티 | `sap_material_type` | 자재 유형 차원 |
| 엔티티 | `sap_material_industry` | 자재 산업군 차원 |
| 관계 | `sap_located_in` | sap_customer → sap_country |
| 관계 | `sap_customer_placed_order` | sap_customer → sap_sales_order |
| 관계 | `sap_order_on_date` | sap_sales_order → sap_order_date |
| 관계 | `sap_order_has_line` | sap_sales_order → sap_sales_order_line |
| 관계 | `sap_line_material_type` | sap_sales_order_line → sap_material_type |
| 관계 | `sap_line_material_industry` | sap_sales_order_line → sap_material_industry |
| 관계 | `sap_part_of` | sap_country → sap_continent |
| 관계 | `sap_placed_order` | sap_customer → sap_order_date |
| 관계 | `sap_partof_year` | sap_order_date → sap_order_year |
| 관계 | `sap_partof_month` | sap_order_date → sap_order_month |

---

## 샘플 데이터

추적되는 샘플 데이터는 `data/parquet/` 아래에 있습니다. CSV export는 `data/csv/README.md`에 문서화되어 있고 repository에는 포함하지 않습니다.

- `tb_sap_vbak.csv` — mandt, vbeln, audat, auart, vkorg, vtweg, spart, knumv, kunnr, recordstamp
- `tb_sap_vbap.csv` — mandt, vbeln, posnr, matnr, arktx, pstyv, kwmeng, vrkme, netwr, recordstamp
- `tb_sap_kna1.csv` — mandt, kunnr, name1, land1, ort01, regio, anred, recordstamp
- `tb_sap_mara.csv` — mandt, matnr, mtart, mbrsh, meins, recordstamp
- `tb_sap_makt.csv` — mandt, matnr, spras, maktx, maktg, recordstamp
