3.9 KiB
KBX Excel Import v1 — Foundation v5
목적
모든 입력형 업무 화면에서 별도의 Excel 업로드 기능을 다시 만들지 않고 다음 공통 파이프라인을 사용한다.
Template → Upload → Mapping → Staging → Validation → Preview → Commit → Audit
핵심 원칙
- Excel은 DB에 직접 반영하지 않는다.
- 원본 행 번호를 유지한다.
- Exact → Alias → Saved Mapping → AI Suggestion의 순서로 매핑하되, 저장 매핑은 동일 source signature에 대해서만 우선 적용한다.
- AI 추천은 미매핑 컬럼만 제안하며 ImportDefinition에 없는 필드를 만들 수 없다.
- 참조 마스터는 행마다 조회하지 않고 batch resolve한다.
- 정상 데이터만 Commit 대상으로 사용한다.
- Commit Job은 Import Session 상태 전이와 Row status로 중복 실행에 안전해야 한다.
- 원본 XLSX와 staging은 14일 기본 보관 후 제거한다. Domain/Audit 데이터는 보존한다.
- SignalR 진행률은 편의 채널이고 Source of Truth는 PostgreSQL Import Session이다.
- 브라우저 종료 후에도 세션 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 stagingkbx.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/signalrclient
등록 예:
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을 만들지는 않는다. 측정된 병목이 생긴 뒤 교체한다.