# 마이그레이션 063-064: 재고 관리 테이블 생성 ## 목적 재고 현황 관리 및 입출고 이력 추적을 위한 테이블 생성 **테이블 타입관리 UI와 동일한 방식으로 생성됩니다.** ### 생성되는 테이블 | 테이블명 | 설명 | 용도 | |----------|------|------| | `inventory_stock` | 재고 현황 | 품목+로트별 현재 재고 상태 | | `inventory_history` | 재고 이력 | 입출고 트랜잭션 기록 | --- ## 테이블 타입관리 UI 방식 특징 1. **기본 컬럼 자동 포함**: `id`, `created_date`, `updated_date`, `writer`, `company_code` 2. **데이터 타입 통일**: 날짜는 `TIMESTAMP`, 나머지는 `VARCHAR(500)` 3. **메타데이터 등록**: - `table_labels`: 테이블 정보 - `column_labels`: 컬럼 정보 (라벨, input_type, detail_settings) - `table_type_columns`: 회사별 컬럼 타입 정보 --- ## 테이블 구조 ### 1. inventory_stock (재고 현황) | 컬럼명 | 타입 | input_type | 설명 | |--------|------|------------|------| | id | VARCHAR(500) | text | PK (자동생성) | | created_date | TIMESTAMP | date | 생성일시 | | updated_date | TIMESTAMP | date | 수정일시 | | writer | VARCHAR(500) | text | 작성자 | | company_code | VARCHAR(500) | text | 회사코드 | | item_code | VARCHAR(500) | text | 품목코드 | | lot_number | VARCHAR(500) | text | 로트번호 | | warehouse_id | VARCHAR(500) | entity | 창고 (FK → warehouse_info) | | location_code | VARCHAR(500) | text | 위치코드 | | current_qty | VARCHAR(500) | number | 현재고량 | | safety_qty | VARCHAR(500) | number | 안전재고 | | last_in_date | TIMESTAMP | date | 최종입고일 | | last_out_date | TIMESTAMP | date | 최종출고일 | ### 2. inventory_history (재고 이력) | 컬럼명 | 타입 | input_type | 설명 | |--------|------|------------|------| | id | VARCHAR(500) | text | PK (자동생성) | | created_date | TIMESTAMP | date | 생성일시 | | updated_date | TIMESTAMP | date | 수정일시 | | writer | VARCHAR(500) | text | 작성자 | | company_code | VARCHAR(500) | text | 회사코드 | | stock_id | VARCHAR(500) | text | 재고ID (FK) | | item_code | VARCHAR(500) | text | 품목코드 | | lot_number | VARCHAR(500) | text | 로트번호 | | transaction_type | VARCHAR(500) | code | 구분 (IN/OUT) | | transaction_date | TIMESTAMP | date | 일자 | | quantity | VARCHAR(500) | number | 수량 | | balance_qty | VARCHAR(500) | number | 재고량 | | manager_id | VARCHAR(500) | text | 담당자ID | | manager_name | VARCHAR(500) | text | 담당자명 | | remark | VARCHAR(500) | text | 비고 | | reference_type | VARCHAR(500) | text | 참조문서유형 | | reference_id | VARCHAR(500) | text | 참조문서ID | | reference_number | VARCHAR(500) | text | 참조문서번호 | --- ## 실행 방법 ### Docker 환경 (권장) ```bash # 재고 현황 테이블 docker exec -i erp-node-db-1 psql -U postgres -d ilshin < db/migrations/063_create_inventory_stock.sql # 재고 이력 테이블 docker exec -i erp-node-db-1 psql -U postgres -d ilshin < db/migrations/064_create_inventory_history.sql ``` ### 로컬 PostgreSQL ```bash psql -U postgres -d ilshin -f db/migrations/063_create_inventory_stock.sql psql -U postgres -d ilshin -f db/migrations/064_create_inventory_history.sql ``` ### pgAdmin / DBeaver 1. 각 SQL 파일 열기 2. 전체 내용 복사 3. SQL 쿼리 창에 붙여넣기 4. 실행 (F5 또는 Execute) --- ## 검증 방법 ### 1. 테이블 생성 확인 ```sql SELECT table_name FROM information_schema.tables WHERE table_name IN ('inventory_stock', 'inventory_history'); ``` ### 2. 메타데이터 등록 확인 ```sql -- table_labels SELECT * FROM table_labels WHERE table_name IN ('inventory_stock', 'inventory_history'); -- column_labels SELECT table_name, column_name, column_label, input_type, display_order FROM column_labels WHERE table_name IN ('inventory_stock', 'inventory_history') ORDER BY table_name, display_order; -- table_type_columns SELECT table_name, column_name, company_code, input_type, display_order FROM table_type_columns WHERE table_name IN ('inventory_stock', 'inventory_history') ORDER BY table_name, display_order; ``` ### 3. 샘플 데이터 확인 ```sql -- 재고 현황 SELECT * FROM inventory_stock WHERE company_code = 'WACE'; -- 재고 이력 SELECT * FROM inventory_history WHERE company_code = 'WACE' ORDER BY transaction_date; ``` --- ## 화면에서 사용할 조회 쿼리 예시 ### 재고 현황 그리드 (좌측) ```sql SELECT s.item_code, i.item_name, i.size as specification, i.unit, s.lot_number, w.warehouse_name, s.location_code, s.current_qty::numeric as current_qty, s.safety_qty::numeric as safety_qty, CASE WHEN s.current_qty::numeric < s.safety_qty::numeric THEN '부족' WHEN s.current_qty::numeric > s.safety_qty::numeric * 2 THEN '과다' ELSE '정상' END AS stock_status, s.last_in_date, s.last_out_date FROM inventory_stock s LEFT JOIN item_info i ON s.item_code = i.item_number AND s.company_code = i.company_code LEFT JOIN warehouse_info w ON s.warehouse_id = w.id WHERE s.company_code = 'WACE' ORDER BY s.item_code, s.lot_number; ``` ### 재고 이력 패널 (우측) ```sql SELECT h.transaction_type, h.transaction_date, h.quantity, h.balance_qty, h.manager_name, h.remark FROM inventory_history h WHERE h.item_code = 'A001' AND h.lot_number = 'LOT-2024-001' AND h.company_code = 'WACE' ORDER BY h.transaction_date DESC, h.created_date DESC; ``` --- ## 데이터 흐름 ``` [입고 발생] │ ├─→ inventory_history에 INSERT (+수량, 잔량) │ └─→ inventory_stock에 UPDATE (current_qty 증가, last_in_date 갱신) [출고 발생] │ ├─→ inventory_history에 INSERT (-수량, 잔량) │ └─→ inventory_stock에 UPDATE (current_qty 감소, last_out_date 갱신) ``` --- ## 롤백 방법 (문제 발생 시) ```sql -- 테이블 삭제 DROP TABLE IF EXISTS inventory_history; DROP TABLE IF EXISTS inventory_stock; -- 메타데이터 삭제 DELETE FROM column_labels WHERE table_name IN ('inventory_stock', 'inventory_history'); DELETE FROM table_labels WHERE table_name IN ('inventory_stock', 'inventory_history'); DELETE FROM table_type_columns WHERE table_name IN ('inventory_stock', 'inventory_history'); ``` --- ## 관련 테이블 (마스터 데이터) | 테이블 | 역할 | 연결 컬럼 | |--------|------|-----------| | item_info | 품목 마스터 | item_number | | warehouse_info | 창고 마스터 | id | | warehouse_location | 위치 마스터 | location_code | --- **작성일**: 2025-12-09 **영향 범위**: 재고 관리 시스템 **생성 방식**: 테이블 타입관리 UI와 동일