핵심 결정
목적
늘품이 찍는 분실(-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으로 주문 차감과 직렬화
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스토리보드 — 실제 화면·연동 포인트
센터 입고/재고 화면에 이지어드민 연동분을 반영
센터 입고 화면 — 이지어드민 입고 연동분 반영
11. 늘품이 이지어드민에 변동 기록 — 늘품 창고가 분실(-1)·실재고 조정을 이지어드민에 찍음. 현재는 어드민에 반영 안 돼 '재고 0인데 발주' 사고의 원인. (외부 시스템, 참고 스크린샷 없음)
22. 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
33. 대사 비교(어드민 잔여 vs 이지 값) — 라인별로 admin_qty_before=stock_balance.total_qty 와 ez_qty 비교 → diff_qty 산출, 일치=matched / 상이=mismatch / 미매핑=unmatched 로 분류. mismatch_lines 집계
44. 매핑·일치 라인 반영(멱등·직렬) — 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
55. 상이·미매핑 → 수기 조정 — mismatch/unmatched 라인은 수기 조정 큐에 남아 17:00까지 담당자가 확인. 수기 반영 시에도 stock_entry append(created_by=조정자), match_status=manual
66. 지연 시 18시 재체크 — 16:05~17:00 내 미수신·지연이면 run_seq=2 배치를 18:00 재실행. 동일 라인은 idempotency_key UNIQUE로 중복 반영 차단(멱등)
04화면 설계
실제 어드민에 어떤 컬럼·화면으로 노출되나
이지어드민 대사 — 회차 목록 (신규 화면)
ez_sync_batch 목록. 상이/미매핑 있으면 클릭 → 라인 상세(수기 조정 큐). 방식(파일/API)은 미확정이라 혼재 표시 가능
대사 라인 상세 — 어드민 잔여 vs 이지 값
ez_sync_line. 반영± = diff_qty(실재고형=이지값−어드민잔여). 미매핑은 DC 작업 코드만 있고 히어로코드 공란 → MD-03 매핑 후 수기 반영. 반영은 stock_entry(source='ez_sync') append로 원장 보존