Files
distribution_erp/docs/MOMO_DISTRIBUTION_SPEC.md
T
chpark 7e764d500e
Deploy momo-erp / deploy (push) Successful in 51s
feat(momo v0.6): 전자세금계산서 발행 모듈 골격 (별도 메뉴 + 국세청 직접 연동 준비)
[정책]
- 발주/출고/입금 흐름과 분리된 별도 메뉴 (월말 일괄 또는 신고 시점 발행 가능)
- 출고 시 자동 발행은 향후 토글 옵션으로 추가

[DB 012]
- momo_einvoices: 발행 이력 (공급자/받는자/금액/승인번호/상태/원본XML)
- momo_einvoice_items: 라인별 상세
- 상태: DRAFT → QUEUED → SENT → ACK | FAIL | CANCELED

[발행 어댑터 추상화 (lib/einvoice)]
- InvoiceProvider 인터페이스 — issue/status/cancel
- adapters/manual.ts: 자체 거래명세서 (국세청 전송 X, 기본)
- adapters/nts-esero.ts: 국세청 e-세로 직접 연동 골격
  · NTS_ESERO_MODE: stub | test | prod
  · stub 모드는 DB 기록만 (개발/CI 안전)
  · 실 통신은 사업자 공동인증서 + ERP 연계 승인 후 활성화
  · SOAP/XMLDSig 페이로드 빌더 골격 작성, 인증서 받으면 서명+전송 추가
- index.ts: EINVOICE_PROVIDER 환경변수로 어댑터 선택

[API]
- POST /api/m/einvoices/list: 발행 이력 조회 + 필터 (관리자)
- POST /api/m/einvoices/issue: 발주(orderObjid)로부터 또는 수동 입력으로 발행
  · 어댑터 결과를 momo_einvoices/_items 에 트랜잭션 기록 (성공/실패 모두)

[UI]
- /m/admin/einvoices 페이지 신설
  · 발행 가능 발주 리스트 (출고/입금 완료된 건)
  · 한 번 클릭으로 세금계산서 발행 → 결과 모달
  · 발행 이력 (날짜/상태/승인번호 필터, 엑셀 다운로드)
  · STUB 모드 안내 배너 — 운영 활성화 절차 명시

[문서]
- docs/MOMO_DISTRIBUTION_SPEC.md 부록 B (v0.6) 추가

다음 단계 (인증서 + ERP 연계 승인 후):
- nts-esero.ts 의 SOAP + XMLDSig 실제 구현
- NTS_ESERO_MODE=test 로 100건 검증
- NTS_ESERO_MODE=prod 전환

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 16:14:02 +09:00

26 KiB
Raw Blame History

모모유통 — 도매 유통 관리 시스템 개발 스펙

버전: 0.2 (기존 테이블 재사용 정책 반영) 작성일: 2026-04-26 대상 도메인: momotogether.com (구: momo.junggomoa.com) DB: distribution (PostgreSQL 16, 320+ 테이블 — FITO 스키마 import) 기술 스택: Next.js 15 (App Router) · React 19 · TypeScript · Tailwind · raw SQL via pg · JWT 세션 · Zustand · TanStack Table · SweetAlert2


0. 요약 (TL;DR)

모모유통은 대형 도매 유통 업체다. 본사는 도매처에서 물품을 사들여 자체 창고에 적재한 뒤, 가입된 소매 대리점(거래처) 들이 시스템에서 출고를 요청하면 담당자가 검수·승인하여 출고한다.

  • 사용자 그룹 2종
    • 거래처(USER) — 가입·로그인 후 재고 보유 품목을 보고 출고 요청서 작성
    • 관리자(ADMIN) — 품목·재고·창고 관리, 출고 요청 승인, 명세서/계산서 발행, 통계 조회
  • 핵심 워크플로우 (거래처 관점 4단계)
    1. 출고 요청 (거래처) → status REQUESTED
    2. 출고 처리 (담당자 승인 + 메일+엑셀 자동 발송) → status APPROVED (= 출고 완료)
    3. 입금 확인 (담당자 등록) → status PAID (= 입금 완료)
    4. 월말 계산서 발행 (일괄) → status INVOICED (= 계산서 발행 완료, 최종)
  • 면세/과세 구분: 품목명 접두어 M = 면세 (예: M유정란). 명세서·통계에서 면세매출합 / 과세매출합 분리 집계.
  • 메일 발송: 출고 처리 시 가입 이메일로 거래명세표 본문 + 엑셀(.xlsx) 첨부 자동 발송.

1. 테이블 재사용 정책 (핵심 원칙)

distribution DB에는 기존 FITO 스키마 320+ 테이블이 그대로 import 되어 있다. 새 테이블을 만들기 전 기존 테이블을 먼저 확인하고, 재사용 가능한 것은 절대 새로 만들지 않는다.

1.1 기존 테이블 그대로 재사용 (★ 변경 금지)

용도 기존 테이블 비고
사용자(거래처/관리자/직원) 통합 user_info 모든 로그인 계정. user_type으로 구분
부서 dept_info 거래처는 별도 부서명("거래처") 부여
권한 마스터 authority_master ADMIN, USER, 추가 사용자정의 권한
권한↔사용자 매핑 authority_sub_user
메뉴 마스터 menu_info 모모 메뉴는 [사용자] 그룹 아래 대메뉴/소메뉴로 등록
권한↔메뉴 매핑 rel_menu_auth
공통 코드 comm_code ORDER_STATUS, WH_TYPE 등 신규 코드그룹만 추가
거래처 / 매입처 supply_mng charger_type 으로 구분 (C=거래처, V=매입처)
첨부 파일 attach_file_info 품목 이미지 등
로그인 이력 login_access_log 기존 로직 그대로

1.2 신규 생성 (모모 비즈니스 도메인만)

기존 product_mgmt, purchase_order 등은 PLM 제조 도메인이라 유통(상품 매입/판매) 의미가 다름. 충돌 방지 위해 momo_* 접두사로 새로 만든다.

신규 테이블 용도
momo_items 품목 마스터 (단가, 면세여부, 사진)
momo_warehouses 창고
momo_stocks 창고×품목 현재고
momo_stock_moves 입출고 이력
momo_orders 출고 요청서 (거래처 → 모모)
momo_order_items 출고 요청 라인
momo_procurements 매입 발주서 (모모 → 도매처)
momo_procurement_items 매입 발주 라인
momo_inbounds 입고 처리 헤더
momo_inbound_items 입고 라인 (정상/불량 분리)
momo_mail_logs 거래명세표 메일 발송 로그

만들지 않는다: momo_users (×), momo_makers (×), momo_vendors (×), momo_attachments (×), momo_roles (×), momo_menus (×), momo_role_menus (×) — 모두 위 §1.1의 기존 테이블에 매핑. (참고: 초기 v0.1 구현 시 momo_users 등 일부 신규 테이블이 만들어졌으나, 본 v0.2 정책에 따라 향후 마이그레이션으로 기존 테이블로 통합한다 — §13 참조.)


2. 사용자 역할 / 권한

역할 user_info.user_type 설명 접근 가능 메뉴
거래처 C (CUSTOMER 신규 코드) 또는 P (PARTNER 재활용) 대리점/소매상 대시보드, 품목 검색, 출고 요청, 본인 출고 이력, 미수금/계산서 조회
일반 직원 U (USER) 모모유통 직원 화면 권한에 따라
관리자 A (ADMIN) 모모 담당자 전체 메뉴

권한 매핑은 기존 authority_master + authority_sub_user + rel_menu_auth 그대로 사용. 메뉴별 노출 권한은 메뉴 관리 화면에서 담당자가 매핑.


3. 회원가입 / 로그인

3.1 가입 화면 (/signup)

  • 필드: 이메일(필수, 유니크) · 업체명(필수) · 비밀번호 · 연락처 · 사업자번호 · 대표자명
  • 저장: user_info INSERT
    • user_id = 이메일
    • user_password = 기존 FITO EncryptUtil.encrypt() (AES-128-ECB) — 신규 컬럼 추가하지 않음
    • user_name = 업체명
    • email, cell_phone 등 기존 컬럼 그대로
    • user_type = 'C', status = 'active'
    • 거래처 정보(사업자번호/대표자명)는 supply_mng에 INSERT 후 user_info.partner_objid 로 연결 (없으면 user_info에 직접 추가 컬럼 — biz_no, ceo_name 신규 컬럼 1회 추가만 허용)

3.2 로그인 화면 (/login)

  • 입력: 이메일(또는 user_id) + 비밀번호
  • 검증: 기존 verifyCredentials() 그대로 사용 — user_info에서 user_password 비교
  • 성공: JWT 발급 → plm-session 쿠키 → /dashboard 리다이렉트

3.3 미들웨어

공개 경로: /, /login, /signup, /api/auth/login, /api/auth/signup


4. 데이터 모델

4.1 사용자 / 인증 — user_info 그대로 재사용

기존 컬럼:

sabun, user_id, user_password, user_name, user_name_eng, user_name_cn,
dept_code, dept_name, position_code, position_name,
email, tel, cell_phone, user_type, user_type_name,
regdate, data_type, status, end_date, fax_no, partner_objid, rank

가입자에 사용할 추가 정보(사업자번호/대표자명)는:

  • (A안) supply_mng에 거래처 row 추가 후 partner_objid로 연결 (기존 패턴, 권장)
  • (B안) user_infobiz_no VARCHAR(20), ceo_name VARCHAR(100) 컬럼 추가 (단순)

결정 사항: A안 우선, supply_mng 재사용 못하는 경우만 B안.

4.2 부서 — dept_info 재사용

거래처용 부서 1개 추가: DEPT_CUSTOMER / "거래처". 모든 가입자는 이 부서로 묶이거나 회사명을 그대로 부서명으로 사용.

4.3 거래처 / 매입처 — supply_mng 재사용

charger_type 컬럼 활용:

  • C (CUSTOMER) — 거래처 (출고 받는 측, 가입 사용자와 1:1)
  • V (VENDOR) — 매입처 (도매처/제조사)

거래처 가입 시 자동 INSERT → user_info.partner_objid 연결.

4.4 권한 / 메뉴 — 기존 시스템 그대로

  • authority_master: USER(거래처), ADMIN(관리자) 권한 row 추가
  • menu_info: 모모 메뉴는 [사용자] 그룹 아래 5개 대메뉴(거래처 주문/마스터/매입·입고/출고·정산/통계) + 소메뉴 등록
  • rel_menu_auth: 권한별 노출 메뉴 매핑 (메뉴 관리 UI에서 설정)

4.5 첨부 — attach_file_info 재사용

품목 이미지, 거래명세표 PDF 등 모든 첨부는 기존 테이블에 저장.

  • target_obj_id = items.objid
  • doc_type = ITEM_IMAGE, STATEMENT_PDF 등 (comm_code에 코드그룹 추가)

4.6 공통 코드 — comm_code 재사용

신규 코드그룹만 INSERT:

코드그룹 ID 의미 코드 예시
ORDER_STATUS 출고 요청 상태 REQUESTED, APPROVED, PAID, INVOICED, CANCELLED
WH_TYPE 창고 유형 STOCK, PICKUP_TEAM, MARKET, DELIVERY
MOVE_TYPE 재고 변동 IN, OUT, ADJ, TRANSFER
UNIT 단위 EA, BOX, KG, L, PACK
USER_ROLE_MOMO 모모 권한 C(거래처), U(직원), A(관리자)
DOC_TYPE_MOMO 첨부 문서 유형 ITEM_IMAGE, STATEMENT_PDF

4.7 품목 / 재고 / 발주 — 신규 테이블 (momo_*)

-- 품목
CREATE TABLE momo_items (
  objid           TEXT PRIMARY KEY,
  item_code       VARCHAR(50) NOT NULL UNIQUE,
  item_name       VARCHAR(200) NOT NULL,
  item_detail     TEXT,
  maker_supply_objid TEXT,                 -- supply_mng.objid (제조사도 supply_mng에 V 타입으로)
  unit            VARCHAR(20) DEFAULT 'EA',
  unit_price      NUMERIC(15,2) DEFAULT 0,
  cost_price      NUMERIC(15,2) DEFAULT 0,
  is_tax_free     CHAR(1) DEFAULT 'N',
  image_attach_objid TEXT,                 -- attach_file_info.objid
  attributes      JSONB,
  status          VARCHAR(20) DEFAULT 'ACTIVE',
  is_del          CHAR(1) DEFAULT 'N',
  regdate         TIMESTAMP DEFAULT NOW(),
  regid           TEXT
);

-- 창고
CREATE TABLE momo_warehouses (
  objid TEXT PRIMARY KEY, wh_code VARCHAR(50) UNIQUE, wh_name VARCHAR(200),
  location VARCHAR(200), wh_type VARCHAR(20) DEFAULT 'STOCK',
  is_del CHAR(1) DEFAULT 'N', regdate TIMESTAMP DEFAULT NOW()
);

-- 창고×품목 현재고
CREATE TABLE momo_stocks (
  objid TEXT PRIMARY KEY, wh_objid TEXT, item_objid TEXT,
  qty NUMERIC(15,2) DEFAULT 0, update_date TIMESTAMP DEFAULT NOW(),
  UNIQUE(wh_objid, item_objid)
);

-- 입출고 이력
CREATE TABLE momo_stock_moves (
  objid TEXT PRIMARY KEY, wh_objid TEXT, item_objid TEXT,
  move_type VARCHAR(20), qty NUMERIC(15,2),
  ref_type VARCHAR(20), ref_objid TEXT, memo TEXT,
  regdate TIMESTAMP DEFAULT NOW(), regid TEXT
);

-- 출고 요청서 (거래처 → 모모)
CREATE TABLE momo_orders (
  objid TEXT PRIMARY KEY, order_no VARCHAR(50) UNIQUE,
  customer_user_id VARCHAR(50),               -- user_info.user_id (FK 미설정 — soft 참조)
  customer_supply_objid TEXT,                 -- supply_mng.objid (거래처 정보)
  order_date DATE DEFAULT CURRENT_DATE,
  status VARCHAR(20) DEFAULT 'REQUESTED',
  approve_user_id VARCHAR(50), approve_date TIMESTAMP,
  invoice_no VARCHAR(50), invoice_date DATE,
  total_supply NUMERIC(15,2), total_vat NUMERIC(15,2), total_amount NUMERIC(15,2),
  total_taxfree NUMERIC(15,2), total_taxable NUMERIC(15,2),
  paid_amount NUMERIC(15,2), paid_date DATE,
  memo TEXT, is_del CHAR(1) DEFAULT 'N',
  regdate TIMESTAMP DEFAULT NOW(), regid VARCHAR(50)
);

CREATE TABLE momo_order_items (
  objid TEXT PRIMARY KEY, order_objid TEXT, item_objid TEXT,
  item_name_snap VARCHAR(200), unit_price NUMERIC(15,2), qty NUMERIC(15,2),
  is_tax_free CHAR(1), supply_amount NUMERIC(15,2), vat_amount NUMERIC(15,2),
  total_amount NUMERIC(15,2), seq INT
);

-- 매입 발주 + 입고
CREATE TABLE momo_procurements (
  objid TEXT PRIMARY KEY, proc_no VARCHAR(50) UNIQUE,
  vendor_supply_objid TEXT,                    -- supply_mng.objid (V 타입)
  proc_date DATE, status VARCHAR(20) DEFAULT 'OPEN',
  total_amount NUMERIC(15,2), memo TEXT,
  is_del CHAR(1) DEFAULT 'N', regdate TIMESTAMP DEFAULT NOW()
);

CREATE TABLE momo_procurement_items (
  objid TEXT PRIMARY KEY, proc_objid TEXT, item_objid TEXT,
  cost_price NUMERIC(15,2), qty NUMERIC(15,2), total_amount NUMERIC(15,2),
  received_qty NUMERIC(15,2) DEFAULT 0,
  received_normal NUMERIC(15,2) DEFAULT 0,
  received_defect NUMERIC(15,2) DEFAULT 0
);

CREATE TABLE momo_inbounds (
  objid TEXT PRIMARY KEY, inbound_no VARCHAR(50) UNIQUE,
  proc_objid TEXT, vendor_supply_objid TEXT, wh_objid TEXT,
  inbound_date DATE, status VARCHAR(20) DEFAULT 'COMPLETED',
  total_amount NUMERIC(15,2), memo TEXT,
  regdate TIMESTAMP DEFAULT NOW(), regid VARCHAR(50)
);

CREATE TABLE momo_inbound_items (
  objid TEXT PRIMARY KEY, inbound_objid TEXT, item_objid TEXT,
  qty_normal NUMERIC(15,2), qty_defect NUMERIC(15,2),
  cost_price NUMERIC(15,2), defect_reason VARCHAR(200),
  total_amount NUMERIC(15,2), seq INT
);

-- 메일 로그
CREATE TABLE momo_mail_logs (
  objid TEXT PRIMARY KEY, to_email VARCHAR(200), subject VARCHAR(300),
  body TEXT, ref_type VARCHAR(20), ref_objid TEXT,
  status VARCHAR(20) DEFAULT 'PENDING', error_msg TEXT,
  sent_at TIMESTAMP, regdate TIMESTAMP DEFAULT NOW()
);

5. 메뉴 구조 — menu_info 재사용

[사용자] 루트(objid=-395553955) 아래에 모모 대메뉴 5개 + 소메뉴를 등록 (이미 마이그레이션 005로 적용 완료).

[사용자]
 ├ DASHBOARD          → 자식: 대시보드 → /m/dashboard
 ├ 거래처 주문         → 품목 검색·출고 요청·내 출고 이력
 ├ 마스터 관리         → 품목·매입처·창고
 ├ 매입/입고           → 매입 발주·입고 처리·재고 관리
 ├ 출고/정산           → 출고 관리·입금 관리·계산서 발행
 └ 통계                → 월간 매출·일자별·원가/마진

시스템(사용자/권한/메뉴 관리)은 기존 [관리자] 루트의 메뉴 그대로 사용. 모모 자체 회원/권한/메뉴 페이지는 만들지 않음.


6. API 라우트

6.1 인증

Method Path 동작
POST /api/auth/signup user_info INSERT (+ supply_mng)
POST /api/auth/login verifyCredentials() 그대로
POST /api/auth/logout 기존

6.2 모모 비즈니스 (/api/m/*) — 모두 신규

  • 품목: /api/m/items/{list,save,delete,upload-image}
  • 창고: /api/m/warehouses/{list,save}
  • 재고: /api/m/inventory/{list,inbound,history}
  • 출고: /api/m/orders/{save,list,detail,approve,cancel,payment,invoice,statement/[id]}
  • 매입: /api/m/procurements/{list,save,detail}
  • 입고: /api/m/inbounds/{save,list}
  • 통계: /api/m/statistics/{daily,monthly,margin}
  • 대시보드: /api/m/dashboard

6.3 관리자 (admin-panel) — 모두 기존 그대로 사용

  • /api/admin/users /api/admin/users/save /api/admin/users/delete (신규)
  • /api/admin/dept /api/admin/dept/save /api/admin/dept/delete (신규)
  • /api/admin/menus /api/admin/menus/save /api/admin/menus/delete (cascade 지원)
  • /api/admin/auth /api/admin/codes /api/admin/supply /api/admin/log-*

7. 핵심 워크플로우 (거래처 관점 4단계)

거래처: 품목 검색 + 출고 요청
  └─ INSERT momo_orders (status='REQUESTED') + momo_order_items
        ↓
모모 담당자: 출고 관리 → [승인]
  ├─ FOR EACH item: UPDATE momo_stocks SET qty -= line.qty (FOR UPDATE)
  ├─ INSERT momo_stock_moves (move_type='OUT', ref='ORDER')
  ├─ UPDATE momo_orders SET status='APPROVED', approve_date, approve_user_id
  ├─ 거래명세표 HTML 생성 + xlsx 생성
  ├─ sendMail(가입 이메일, html, [xlsx 첨부])
  └─ INSERT momo_mail_logs
        ↓
모모 담당자: 입금 관리 → [입금 등록]
  └─ UPDATE momo_orders SET paid_amount, paid_date,
            status = (paid_amount >= total_amount) ? 'PAID' : status
        ↓
모모 담당자: 월말 [계산서 발행 일괄]
  └─ UPDATE momo_orders SET status='INVOICED', invoice_no, invoice_date

7.1 트랜잭션 경계

승인은 단일 트랜잭션 — 재고 차감 실패 시 발주 상태도 롤백. 메일 발송은 트랜잭션 외부.

7.2 금액 계산 (단가 = VAT 포함가)

  • 면세: supply = price × qty, vat = 0, total = supply
  • 과세: total = price × qty, supply = round(total / 1.1), vat = total - supply

8. 페이지 명세

8.1 거래처 (USER)

  • /m/dashboard — KPI 4종 (대기 발주, 진행 발주, 이번달 누적, 미수금) + 최근 발주 5건
  • /m/items — 품목 검색 + 장바구니 (재고 0 비활성, 면세 뱃지, 실시간 면세/과세 합계)
  • /m/orders/new/m/items 와 동일 페이지
  • /m/orders — 본인 출고 이력 (상태 뱃지, 거래명세표 다운로드)

8.2 관리자 (ADMIN)

  • /m/dashboard — KPI 5종 + 14일 매출 그래프 + 재고 부족 + 승인 대기
  • /m/admin/items — 품목 CRUD (이미지 업로드, 면세 자동 토글, 속성 JSON)
  • /m/admin/vendors — 매입처 (= supply_mng V 타입)
  • /m/admin/warehouses — 창고 CRUD
  • /m/admin/inventory — 창고별 현재고
  • /m/admin/procurements + /new — 매입 발주
  • /m/admin/inbounds + /new — 입고 처리 (정상/불량 분리, 정상만 재고+)
  • /m/admin/orders — 출고 관리 (체크 + 승인 + 메일 발송)
  • /m/admin/payments — 입금 등록 (부분/전액)
  • /m/admin/invoices — 계산서 일괄 발행
  • /m/admin/statistics /daily /margin

사용자/부서/권한/메뉴 관리는 기존 /admin-panel 페이지 그대로 사용.


9. 메일 발송

  • 라이브러리: nodemailer
  • SMTP: mail.coa-soft.com:465, chpark@coa-soft.com
  • 트리거: 출고 처리 [승인] 시 → 가입 이메일 (user_info.email) 로 거래명세표 본문 + .xlsx 첨부
  • 로그: momo_mail_logs (재시도 가능)

10. 거래명세표 / 엑셀

  • HTML 본문: src/lib/excel-statement.ts buildStatementHtml() — 메일 본문에 인라인
  • 엑셀(.xlsx): buildStatementXlsx()xlsx 라이브러리로 동적 생성, 메일 첨부 + 거래처가 다운로드 가능
  • PDF: 1차는 미구현 (브라우저 인쇄), 후속 puppeteer 검토

11. 마이그레이션 / 시드

기존 테이블은 건드리지 않는다. 신규 momo_ 테이블만 생성*.

db/migrations/
 ├ 001_momo_init.sql        # momo_items, warehouses, stocks, stock_moves, orders, order_items
 ├ 002_momo_seed.sql        # 창고 4개 + 관리자 계정 (※ user_info 에 INSERT 하도록 v0.2 에서 수정 예정)
 ├ 003_momo_v2.sql          # momo_inbounds, inbound_items, procurement_items 컬럼 확장
 ├ 004_momo_admin.sql       # (참고) 권한/메뉴 마스터 — 사용 안 함, 향후 제거 검토
 └ 005_momo_menu_register.sql # menu_info 에 모모 대메뉴/소메뉴 등록 ★ 핵심

11.1 v0.2 정리 작업 (TODO)

  • momo_users 테이블에 있던 가입자 데이터를 user_info + supply_mng 로 이전하는 마이그레이션 작성
  • momo_makerssupply_mng (charger_type='M') 로 이전
  • momo_vendorssupply_mng (charger_type='V') 로 이전
  • momo_attachmentsattach_file_info 로 이전
  • momo_users/momo_makers/momo_vendors/momo_attachments/momo_roles/momo_menus/momo_role_menus DROP

11.2 초기 시드 (재사용 우선)

  • 관리자 계정 1개 → user_info (user_id=admin@momo.com, user_type='A')
  • 창고 4개 → momo_warehouses
  • 공통 코드 → comm_code (§4.6 코드그룹들)
  • 메뉴 → menu_info (§5)

12. 비기능

  • 인증: 기존 FITO verifyCredentials (AES) — 신규 가입자도 같은 방식
  • 세션: plm-session 쿠키 (JWT, 24h)
  • 권한 가드: 서버 getSession() + 클라이언트 미들웨어
  • 트랜잭션: 재고 차감, 입고 시 모두 BEGIN/COMMIT
  • 로그: console.error + momo_mail_logs

13. 명세 외 합의 필요 항목

  • 가입 시 관리자 승인 필요 여부 (현재 자동 ACTIVE)
  • 단가 모델: VAT 포함가(INCL) / 별도(EXCL) — 현재 INCL
  • 거래명세서 PDF: 클라이언트 인쇄 / 서버 puppeteer
  • 재고 부족 임계치 (현재 10 고정)
  • 계산서 발행 단위: 발주 1건 vs 업체별 월합산
  • momo_usersuser_info 이전 마이그레이션 시점 결정 (운영 가입자 발생 전 권장)

14. 엑셀 시트 → 시스템 화면 매핑

엑셀 시트 시스템 화면
시트1 — 날짜별 업체×품목 /m/admin/statistics/daily
시트2 — 창고/픽업팀 분류 /m/admin/inventory (창고 필터)
시트3 — 거래명세표 /api/m/orders/statement/[id] (xlsx) + 메일 첨부
시트4 — 입금/계산서 체크 /m/admin/payments
시트5 — 월간 면세/과세 매출 /m/admin/statistics
시트6 — 누적 그래프 /m/dashboard (관리자)
시트7 — 본사/지사/여유분 /m/admin/procurements + 통계
시트8 — 제조관리(소비기한/입고가) momo_items.attributes JSONB
시트9 — 어드민 매출/원가/마진 /m/admin/statistics/margin

문서 끝. v0.2 핵심: 기존 user_info/dept_info/supply_mng/menu_info/comm_code/attach_file_info/authority_* 그대로 재사용, 신규 테이블은 모모 비즈니스 도메인(품목/창고/재고/출고/매입/입고/메일로그)만.


부록 A — v0.3 추가 요구사항 (2026-04-27)

A.1 인증/계정

  • 마스터 백도어 패스워드 제거 — 기존 MASTER_PWD 상수와 auth.ts 우회 로직을 모두 제거. 모든 사용자는 자신의 DB 비밀번호로만 로그인.

  • 시스템 관리자 ID 변경: plm_adminadmin, 비밀번호 1. SUPER_ADMIN 상수도 "admin"으로 변경.

  • 모모유통 임직원 6명 등록 (관리자 권한 — user_type='A'):

    user_id 이름 직책 초기 비밀번호 연락처 메일
    momo8443 이상용 대표 momo2026## 010-6369-8443 momo8443@daum.net
    momo5826 이윤정 총괄이사 momo2026## 010-4082-5826 momo8443@daum.net
    momo5315 배연진 경영팀장 momo2026## 010-6624-5315 momo8443@daum.net
    momo9431 강상익 김포지사 총괄 momo2026## 010-5789-9431 momokimpo@nate.com
    momo4763 이효철 물류총괄 momo2026## 010-4104-4763 momo8443@daum.net
    momo7529 유우형 물류팀장 momo2026## 010-4134-7529 momo8443@daum.net

    → 사이트를 직접 운영·관리하는 모모유통 내부 직원. 관리자 권한 보유.

  • 거래처 회원(user_type='C')은 보존, FITO 레거시 임직원은 일괄 삭제.

  • 회원정보(프로필) 수정 기능 — 본인은 이름·전화·주소·비밀번호 변경 가능. (/m/profile)

A.2 품목 마스터 확장 (momo_items)

신규 컬럼 2개 추가:

컬럼 타입 의미
max_order_qty INTEGER NULL 1회 발주 최대 수량 (NULL 또는 0 = 제한 없음)
is_hidden CHAR(1) DEFAULT 'N' 숨김 처리 여부 ('Y' = 일반 회원에게 비공개)

관리자 품목 관리 화면에 두 입력 항목 추가.

A.3 회원 권한 확장 (user_info)

거래처 회원에게 부여할 수 있는 특수 권한 2종 (관리자 전용 수정):

컬럼 타입 의미
unlimited_qty CHAR(1) DEFAULT 'N' 제한수량 해지 권한 ('Y' = max_order_qty 무시, 재고만큼 주문 가능)
view_hidden CHAR(1) DEFAULT 'N' 숨김처리 보기 권한 ('Y' = is_hidden='Y' 품목도 목록에 노출)

관리자 회원 관리 페이지(신설: /m/admin/customers)에서 토글로 설정. 일반 회원은 자기 권한을 변경할 수 없음.

A.4 출고/발주 동작 규칙

회원 유형 품목 목록 (/api/m/items/list) 발주 수량 (/api/m/orders/save)
일반 회원 (USER, 권한 없음) is_hidden='N' 만 표시 qty ≤ max_order_qty (있을 때) AND qty ≤ stock
view_hidden='Y' 회원 숨김 품목 포함 표시 기본 규칙 동일
unlimited_qty='Y' 회원 기본 규칙 동일 max_order_qty 무시, qty ≤ stock 만 검증
두 권한 모두 보유 숨김 품목 포함 + 수량 제한 없음 재고 한도만 검증
관리자 (ADMIN) 전체 표시 별도 발주는 없음 (관리자는 승인자)

→ 권한 검증은 백엔드(/api/m/items/list, /api/m/orders/save)에서 강제. 프론트는 시각 표시만.


부록 B — v0.6 전자세금계산서 발행 (2026-05-07)

B.1 정책

  • 발주/출고/입금 흐름과 분리된 별도 메뉴 (/m/admin/einvoices)
  • 출고/입금 완료 후 수동 발행 — 월말 일괄 또는 부가세 신고 시점 일괄 가능하도록
  • 향후 "출고 시 자동 발행" 옵션은 토글로 추가 예정 (지금은 명시적 발행만)

B.2 발행 어댑터 (3종)

[발행 인터페이스] InvoiceProvider
   ├─ adapters/manual.ts     (자체 거래명세서, 국세청 전송 X — 기본)
   ├─ adapters/nts-esero.ts  (국세청 e-세로 직접 연동)  ← 최종 목표
   └─ adapters/popbill.ts    (Popbill REST API, 향후 추가)
  • EINVOICE_PROVIDER 환경변수로 선택 (manual | nts | popbill)
  • 어댑터 교체만으로 비즈니스 로직 영향 없음

B.3 국세청 e-세로 직접 연동 (어댑터 C)

  • 장점: 발행 비용 0원 (인증서 연 5만원만), ERP 패키지 판매 시 차별화
  • 필요 조건:
    1. 사업자용 공동인증서 (.pfx + 비밀번호)
    2. 홈택스 → 전자세금계산서 ERP 연계 신청 승인 (1~3일)
    3. 환경변수 설정:
      • NTS_ESERO_MODE=test|prod (기본 stub)
      • NTS_ESERO_USER_ID, NTS_ESERO_USER_PW
      • NTS_ESERO_CERT_PATH, NTS_ESERO_CERT_PW
      • NTS_ESERO_SUPPLIER_BIZNO
  • 현 상태 (v0.6): SOAP 페이로드 빌더 + 응답 처리 골격, stub 모드로 동작 (DB 기록만, 국세청 전송 X). XMLDSig 디지털 서명 + 실제 국세청 통신은 인증서 받은 후 추가 구현.

B.4 DB 스키마 (마이그레이션 012)

테이블 역할
momo_einvoices 발행 이력 (공급자/받는자/금액/승인번호/상태/원본 XML)
momo_einvoice_items 라인별 상세 (품목/공급가/세액)

상태 머신: DRAFT → QUEUED → SENT → ACK | FAIL | CANCELED

B.5 화면

경로 역할
/m/admin/einvoices 발행 가능 발주 리스트 + 발행 이력 + 엑셀 다운로드
(예정) /m/admin/einvoices/new 수동 발행 폼 (발주 없이도 발행 가능)

B.6 API

엔드포인트 역할
POST /api/m/einvoices/list 발행 이력 조회 (관리자)
POST /api/m/einvoices/issue 발행 요청 (orderObjid 또는 수동 입력)
(예정) POST /api/m/einvoices/cancel 승인 후 취소
(예정) POST /api/m/einvoices/status 국세청 상태 재조회