94 lines
3.9 KiB
Markdown
94 lines
3.9 KiB
Markdown
# KBX Excel Import v1 — Foundation v5
|
|
|
|
## 목적
|
|
|
|
모든 입력형 업무 화면에서 별도의 Excel 업로드 기능을 다시 만들지 않고 다음 공통 파이프라인을 사용한다.
|
|
|
|
`Template → Upload → Mapping → Staging → Validation → Preview → Commit → Audit`
|
|
|
|
## 핵심 원칙
|
|
|
|
1. Excel은 DB에 직접 반영하지 않는다.
|
|
2. 원본 행 번호를 유지한다.
|
|
3. Exact → Alias → Saved Mapping → AI Suggestion의 순서로 매핑하되, 저장 매핑은 동일 source signature에 대해서만 우선 적용한다.
|
|
4. AI 추천은 미매핑 컬럼만 제안하며 ImportDefinition에 없는 필드를 만들 수 없다.
|
|
5. 참조 마스터는 행마다 조회하지 않고 batch resolve한다.
|
|
6. 정상 데이터만 Commit 대상으로 사용한다.
|
|
7. Commit Job은 Import Session 상태 전이와 Row status로 중복 실행에 안전해야 한다.
|
|
8. 원본 XLSX와 staging은 14일 기본 보관 후 제거한다. Domain/Audit 데이터는 보존한다.
|
|
9. SignalR 진행률은 편의 채널이고 Source of Truth는 PostgreSQL Import Session이다.
|
|
10. 브라우저 종료 후에도 세션 ID로 진행상태를 복구할 수 있다.
|
|
|
|
## 사용자 흐름
|
|
|
|
- `엑셀 > 업로드 양식 다운로드`
|
|
- 또는 기존 Excel 선택
|
|
- 자동매핑 확인
|
|
- 필요 시 `쿠팡 주문양식` 같은 이름으로 매핑 저장
|
|
- 검증 실행
|
|
- 오류 행은 화면 100건 미리보기 또는 오류 XLSX 다운로드
|
|
- 정상 건 반영
|
|
- 대량 작업은 Hangfire + SignalR로 진행상태 표시
|
|
|
|
## 저장 구조
|
|
|
|
- `kbx.import_sessions`: 수명주기, 매핑, 건수, 진행률
|
|
- `kbx.import_files`: 원본 XLSX bytea. 초기 Modular Monolith용 교체 가능 Adapter 경계
|
|
- `kbx.import_rows`: raw/normalized/error/warning/domain key staging
|
|
- `kbx.saved_import_mappings`: 사용자별 재사용 매핑
|
|
- `kbx.import_job_receipts`: 향후 job observability 확장 지점
|
|
|
|
원본 파일을 session metadata와 별도 table에 둬 일반 조회에서 대용량 bytea가 함께 읽히지 않게 한다.
|
|
|
|
## 주문 Import 예제
|
|
|
|
`oms.orders.v1`은 주문번호별 여러 Excel 행을 하나의 Header/Detail Transaction으로 그룹화한다.
|
|
|
|
검증 시 거래처/창고/품목 코드는 distinct 목록을 한 번에 조회하고 실제 Domain ID로 resolve한다. 같은 주문번호의 Header 값이 행마다 다르면 `ORDER_HEADER_CONFLICT`로 차단한다.
|
|
|
|
기존 주문은 `NEW/DRAFT` 상태만 Excel update를 허용한다. Commit에서는 주문별 transaction 안에서 Header, Lines, Audit, Outbox, staging status를 같이 변경한다.
|
|
|
|
## AI Mapping
|
|
|
|
`IImportMappingSuggester`가 확장 지점이다. 기본 구현은 No-op이다. 실제 AI Adapter는 다음 계약을 지켜야 한다.
|
|
|
|
- 미매핑 컬럼만 입력
|
|
- ImportDefinition 내 target field만 반환
|
|
- confidence/reason 반환
|
|
- 자동 저장 금지
|
|
- 데이터 Commit 금지
|
|
- 사용자 확정 또는 검증 이후만 사용
|
|
|
|
이 경계로 LLM hallucination이 DB field나 Domain Entity 생성으로 연결되지 않게 한다.
|
|
|
|
## Host wiring
|
|
|
|
필요 NuGet/Frontend package 예:
|
|
|
|
- ClosedXML
|
|
- Hangfire.AspNetCore 및 현재 프로젝트가 사용하는 PostgreSQL Hangfire storage
|
|
- Microsoft.AspNetCore.SignalR은 ASP.NET Core shared framework 사용
|
|
- `@microsoft/signalr` client
|
|
|
|
등록 예:
|
|
|
|
```csharp
|
|
builder.Services.AddKbxExcelImport();
|
|
// 기존 Hangfire/Npgsql/FastEndpoints 등록
|
|
|
|
app.MapKbxExcelImport();
|
|
```
|
|
|
|
Hangfire recurring job에서 `PurgeExpiredImportsJob`을 하루 한 번 실행한다.
|
|
|
|
## 향후 교체 지점
|
|
|
|
트래픽 증가 시 다음은 인터페이스를 유지하며 교체한다.
|
|
|
|
- PostgreSQL bytea → object storage
|
|
- 전체 Workbook parsing → streaming OpenXML reader
|
|
- 100k 행 memory grouping → keyset/chunk pipeline
|
|
- Noop AI Mapping → 승인된 내부 AI tool adapter
|
|
|
|
처음부터 분산 스토리지·자체 Excel engine을 만들지는 않는다. 측정된 병목이 생긴 뒤 교체한다.
|