MD-14 · 재고 이지어드민 연동

재고 이지어드민 연동 (입출고 동기화)

늘품 이지어드민의 분실·조정·실재고를 마감 대사로 받아 어드민 잔여재고(MD-01)에 멱등·직렬 반영 — '재고 0인데 발주' 사고 차단

🟡 MD-01·03 선행 이지어드민 입출고 반영 분실·미입고 처리 재고 정합성

핵심 결정

목적
늘품이 찍는 분실(-1)·실재고 조정이 어드민 미반영 → '재고 0인데 발주 들어오는 사고' 차단
소스오브트루스
우리(어드민) 재고가 메인 · 이지어드민은 분실·조정·실재고 보정만
대사창
마감 운영요일 16:05~17:00 대사 · 상이 시 수기 조정 · 지연이면 18시 재체크(run_seq=2)
반영 경로
이지 라인 → DC 작업 코드 매핑(MD-03) → stock_entry append(source='ez_sync', MD-01)
선행/외부
MD-01(재고)·MD-03(DC 작업 코드) 뒤 · 연동방식(파일/API) 미확정(Stan·AX API 수요일 확인) · 늘품 폐기 예정이라 실행은 뒤
안전장치
멱등키 UNIQUE(중복 반영 방지) + (hero,center) advisory lock으로 주문 차감과 직렬화
01

정책 / 정의

용어를 못 박고, 규칙을 명확히

용어 정의
용어정의
이지어드민늘품이 쓰는 외부 재고 관리 시스템. 자체 ERP 전환으로 폐기 예정이라 명칭·코드를 정식 자산으로 쓰지 않음
DC 작업 코드히어로코드에 매핑되는 늘품(이지어드민) 측 코드(MD-03). 1 DC 코드 ↔ 여러 히어로(복제코드) 가능. '이지어드민 코드'로 부르지 않음
분실(loss)판매·발주 외 재고 감소(예: 분실 -1). 어드민 원장에 없던 변동
실재고 조정(actual/adjust)늘품 실사로 확정한 절대 수량. 어드민 잔여와의 차이만 원장에 append(덮어쓰기 금지)
마감 대사16:05~17:00 이지 값과 어드민 잔여재고(stock_balance)를 라인별로 비교·분류하는 회차
멱등키(idempotency_key)같은 변동 라인의 재수신(18시 재체크 포함)을 중복 반영하지 못하게 막는 UNIQUE 키
넷공급가우리 매입 순공급가. 이지 연동 라인은 수량 변동만 다루며 단가는 기존 로트(stock_entry.net_supply_price) 유지
정책 (규칙)
#규칙비고
1우리 재고가 메인 — 이지어드민은 분실·조정·실재고만 보정판매/발주 차감은 어드민 원장(stock_entry)이 소스오브트루스. 이지 값으로 잔여를 통째 덮어쓰지 않는다
2대사 시각 16:05~17:00 · 상이 시 수기 조정 · 지연이면 18시 재체크1차=run_seq 1(16:05). 미수신·지연이면 run_seq 2(18:00) 배치 재실행. 상이 라인은 match_status=mismatch로 수기 조정 큐에 남김
3멱등(중복 반영 방지)idempotency_key = sync_date+dc_work_code+change_type+ez_qty 해시 등으로 UNIQUE. 재체크가 같은 라인을 다시 밀어도 stock_entry append는 1건
4동시 차감 꼬임 방지반영은 pg_advisory_xact_lock(hero_code,center_code) 안에서 stock_entry INSERT + stock_balance 재계산을 원자적으로. 주문 차감과 직렬화
5매핑된 라인만 자동 반영dc_work_code가 MD-03(supplier_product.dc_work_code)로 히어로코드에 매핑돼야 반영. 미매핑은 match_status=unmatched로 보류→수기
6실재고(actual)도 원장 보존change_qty = ez_qty − admin_qty_before(diff_qty)로 append. 음수/양수 모두 로그 1건. 절대치 세팅·row 덮어쓰기 금지
7연동방식(파일/API) 미확정 → 어댑터 분리파일이든 API든 동일 스테이징(ez_sync_line)으로 수렴. 어댑터만 교체. Stan·AX에서 API 끌어오는 작업은 Buggy 수요일 확인
8외부 의존·폐기 예정 대비늘품 이지어드민 폐기 시 어댑터·배치만 비활성. DC 작업 코드는 허브코드로 유지(MD-03), 이지 명칭에 종속시키지 않음
02

ERD

데이터 구조 · 관계 · DDL

ez_sync_batch 신규
idPK bigint
sync_datedate
run_seqint
methodvarchar
statusvarchar
total_linesint
mismatch_linesint
source_reftext
started_attimestamptz
finished_attimestamptz
마감 대사 회차(하루 1~2회). 16:05 run_seq=1, 지연 시 18시 run_seq=2
ez_sync_line 신규
idPK bigint
batch_idFK→EZ_SYNC_BATCH bigint
dc_work_codevarchar
hero_codeFK→PRODUCT varchar
center_codeFK→CENTER varchar
change_typevarchar
ez_qtyint
admin_qty_beforeint
diff_qtyint
match_statusvarchar
applied_entry_idFK→STOCK_ENTRY bigint
idempotency_keyvarchar
이지어드민이 찍은 변동/실재고 라인 + 대사 결과. 멱등키로 중복 반영 차단
stock_entry WRITE
idPK bigint
hero_codeFK→PRODUCT varchar
center_codeFK→CENTER varchar
change_qtyint
net_supply_priceint
sourcevarchar
memotext
created_byvarchar
created_attimestamptz
MD-01 수불 원장(append-only). 이지 반영분은 source='ez_sync'로 1건 append
supplier_product READ
hero_codePK varchar
dc_work_codevarchar
group_namevarchar
MD-03 선행. dc_work_code↔hero_code 매핑 소스(1 DC ↔ 여러 히어로)
stock_balance READ
hero_codePK varchar
center_codePK varchar
total_qtyint
MD-01 집계. admin_qty_before 산출·대사 비교 기준
-- ==========================================================
-- [MD-14] 이지어드민(늘품) 재고 연동 — 대사 스테이징
-- MD-01(stock_entry)·MD-03(DC 작업 코드 매핑) 선행. 우리 재고가 메인.
-- 파일/API 미확정 → 어댑터만 교체, 아래 스테이징 테이블로 수렴.
-- ==========================================================

-- 마감 대사 회차 (운영요일 16:05~17:00, 지연 시 18시 재체크)
CREATE TABLE ez_sync_batch (
  id            BIGSERIAL   PRIMARY KEY,
  sync_date     DATE        NOT NULL,               -- 마감 운영일
  run_seq       INT         NOT NULL DEFAULT 1,     -- 1=16:05 대사, 2=18:00 재체크
  method        VARCHAR     NOT NULL,               -- 'api' | 'file' (연동방식 미확정)
  source_ref    TEXT,                               -- 수신 파일명 / API 응답ID
  status        VARCHAR     NOT NULL DEFAULT 'received',
                                                    -- received/matched/mismatch/applied/manual/delayed
  total_lines   INT         NOT NULL DEFAULT 0,
  mismatch_lines INT        NOT NULL DEFAULT 0,     -- 상이+미매핑 건수 (수기 조정 대상)
  started_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
  finished_at   TIMESTAMPTZ,
  created_by    VARCHAR     NOT NULL DEFAULT 'batch',
  UNIQUE (sync_date, run_seq)                       -- 하루 회차 유일
);

-- 이지어드민이 찍은 변동/실재고 라인 (수신 원본 + 대사 결과)
CREATE TABLE ez_sync_line (
  id            BIGSERIAL   PRIMARY KEY,
  batch_id      BIGINT      NOT NULL REFERENCES ez_sync_batch(id),
  dc_work_code  VARCHAR     NOT NULL,               -- 이지어드민(늘품) DC 작업 코드 (MD-03)
  hero_code     VARCHAR     REFERENCES product(hero_code),      -- 매핑 결과, 미매핑 NULL
  center_code   VARCHAR     REFERENCES center(center_code),
  change_type   VARCHAR     NOT NULL,               -- 'loss'(분실) | 'adjust'(조정) | 'actual'(실재고)
  ez_qty        INT         NOT NULL,               -- 이지 값 (분실 -1 등 / 실재고=절대치)
  admin_qty_before INT,                             -- 대사시점 어드민 잔여(stock_balance)
  diff_qty      INT,                                -- 반영할 ± (실재고=ez-admin, 분실/조정=ez_qty)
  match_status  VARCHAR     NOT NULL DEFAULT 'unmatched',
                                                    -- unmatched/matched/mismatch/applied/manual
  applied_entry_id BIGINT   REFERENCES stock_entry(id),  -- 반영 결과 로그(멱등 성공 시 1건)
  idempotency_key VARCHAR   NOT NULL,               -- 중복 반영 방지: 같은 변동 재수신 차단
  memo          TEXT,
  created_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
  UNIQUE (idempotency_key)                          -- 멱등: 18시 재체크가 다시 밀어도 1건
);
CREATE INDEX ON ez_sync_line (batch_id, match_status);
CREATE INDEX ON ez_sync_line (hero_code, center_code);

-- MD-01 stock_entry.source 에 신규 출처값 'ez_sync' 사용 (스키마 변경 없음, 값만 추가)
-- 반영 규칙: 실재고(actual)도 원장 보존 → 절대치 덮어쓰기 금지,
--            change_qty = (ez_qty - admin_qty_before) 로 append.
-- 반영 트랜잭션: SELECT pg_advisory_xact_lock(hash(hero_code,center_code)) 로
--            주문 차감과 직렬화(동시 차감 꼬임 방지) 후 stock_entry INSERT + balance 재계산.

-- MD-03 선행: supplier_product 에 dc_work_code 컬럼(빈값 허용, 1 DC ↔ 여러 히어로) 존재 가정.
-- ALTER TABLE supplier_product ADD COLUMN dc_work_code VARCHAR;  -- (MD-03 소관)
03

스토리보드 — 실제 화면·연동 포인트

센터 입고/재고 화면에 이지어드민 연동분을 반영

센터 입고 화면 — 이지어드민 입고 연동분 반영
센터 입고 화면 — 이지어드민 입고 연동분 반영
센터 재고 목록 — 연동 후 정합성
센터 재고 목록 — 연동 후 정합성
1
1. 늘품이 이지어드민에 변동 기록 — 늘품 창고가 분실(-1)·실재고 조정을 이지어드민에 찍음. 현재는 어드민에 반영 안 돼 '재고 0인데 발주' 사고의 원인. (외부 시스템, 참고 스크린샷 없음)
2
2. 16:05 대사 배치 수신·매핑 — 운영요일 16:05 배치가 파일/API로 이지 라인을 받아 ez_sync_batch(run_seq=1)+ez_sync_line 적재. dc_work_code를 MD-03(supplier_product.dc_work_code)로 히어로코드에 매핑. 미매핑=unmatched
3
3. 대사 비교(어드민 잔여 vs 이지 값) — 라인별로 admin_qty_before=stock_balance.total_qty 와 ez_qty 비교 → diff_qty 산출, 일치=matched / 상이=mismatch / 미매핑=unmatched 로 분류. mismatch_lines 집계
4
4. 매핑·일치 라인 반영(멱등·직렬) — advisory lock(hero,center) 안에서 idempotency_key 확인 후 stock_entry(source='ez_sync', change_qty=diff_qty) 1건 append → stock_balance 재계산. applied_entry_id 기록, match_status=applied
5
5. 상이·미매핑 → 수기 조정 — mismatch/unmatched 라인은 수기 조정 큐에 남아 17:00까지 담당자가 확인. 수기 반영 시에도 stock_entry append(created_by=조정자), match_status=manual
6
6. 지연 시 18시 재체크 — 16:05~17:00 내 미수신·지연이면 run_seq=2 배치를 18:00 재실행. 동일 라인은 idempotency_key UNIQUE로 중복 반영 차단(멱등)
04

화면 설계

실제 어드민에 어떤 컬럼·화면으로 노출되나

이지어드민 대사 — 회차 목록 (신규 화면)
대사일회차방식상태총라인상이/미매핑반영시각
2026-07-291차(16:05)API반영완료124316:22
2026-07-292차(18:00)API재체크5018:07
2026-07-281차(16:05)파일수기대기987-
ez_sync_batch 목록. 상이/미매핑 있으면 클릭 → 라인 상세(수기 조정 큐). 방식(파일/API)은 미확정이라 혼재 표시 가능
대사 라인 상세 — 어드민 잔여 vs 이지 값
DC 작업 코드히어로코드센터변동유형이지값어드민잔여반영±상태
85156HERO-008737성동광진분실-1135-1반영완료
85160HERO-008902성동광진실재고4042-2반영완료
90021(미매핑)성동광진조정-3--미매핑·수기
ez_sync_line. 반영± = diff_qty(실재고형=이지값−어드민잔여). 미매핑은 DC 작업 코드만 있고 히어로코드 공란 → MD-03 매핑 후 수기 반영. 반영은 stock_entry(source='ez_sync') append로 원장 보존