docs: add project docs and test updates

This commit is contained in:
taekyoungc
2026-04-08 00:23:55 +09:00
parent 06fedc866a
commit 06aa401048
238 changed files with 8373 additions and 148 deletions

View File

@@ -0,0 +1,135 @@
# DB 테이블 목록 및 ERD
> 노션 ERD·웹 기능목록·`06-데이터베이스정리구조.md` 네이밍 규칙을 반영한 테이블 설계.
> 지자체(`lg_idx`) 기준 멀티테넌트, 데이터 격리.
---
## 1. 테이블 목록 및 역할
| 테이블 | PK | 지자체 FK | 설명 |
|--------|-----|-----------|------|
| **local_government** | lg_idx | — | 지자체 마스터(테넌트 루트) |
| **member** | mb_idx | mb_lg_idx (nullable) | 회원(로그인·권한). 지자체관리자만 lg 연결 |
| **member_log** | mll_idx | — | 로그인/로그아웃 이력 |
| **designated_shop** | ds_idx | ds_lg_idx | 지정 판매소. 고정 가상계좌(va) 보유 |
| **code_kind** | ck_idx | — | 기본코드 종류(도/시/구, 봉투 구분 등) |
| **code_detail** | cd_idx | — | 종류별 세부 코드. ck_idx FK |
| **product** | pr_idx | pr_lg_idx | 지자체별 취급 품목(규격·용량) |
| **product_price** | pp_idx | pp_lg_idx | 적용일자별 단가(발주/도매/소비자가) |
| **packaging_unit** | pu_idx | pu_lg_idx | 박스당 팩·팩당 낱장 등 포장 단위 |
| **agent** | ag_idx | ag_lg_idx | 판매 대행소(은행 등) |
| **contact** | ct_idx | ct_lg_idx | 담당자(구/군/대행소/제작업체) |
| **company** | co_idx | co_lg_idx | 업체(협회·제작업체·회수업체) |
| **beneficiary** | bf_idx | bf_lg_idx | 무료용 대상자 |
| **purchase_order** | po_idx | po_lg_idx | 발주(지자체 → 제작업체) |
| **inbound_receipt** | ir_idx | ir_lg_idx | 입고 내역(LOT·바코드 연동) |
| **sales_order** | so_idx | so_lg_idx | 판매소 주문. 데이터 격리용 lg_idx |
| **stock_transaction** | st_idx | st_lg_idx | 수불(입고/판매/불출/파기) |
---
## 2. 엔티티 관계 다이어그램 (ERD)
```mermaid
erDiagram
local_government ||--o{ member : "mb_lg_idx (지자체관리자)"
local_government ||--o{ designated_shop : "ds_lg_idx"
designated_shop ||--o| member : "ds_mb_idx (로그인 1:1)"
local_government ||--o{ product : "pr_lg_idx"
local_government ||--o{ product_price : "pp_lg_idx"
local_government ||--o{ packaging_unit : "pu_lg_idx"
local_government ||--o{ agent : "ag_lg_idx"
local_government ||--o{ contact : "ct_lg_idx"
local_government ||--o{ company : "co_lg_idx"
local_government ||--o{ beneficiary : "bf_lg_idx"
local_government ||--o{ purchase_order : "po_lg_idx"
local_government ||--o{ inbound_receipt : "ir_lg_idx"
local_government ||--o{ sales_order : "so_lg_idx"
local_government ||--o{ stock_transaction : "st_lg_idx"
designated_shop ||--o{ sales_order : "so_ds_idx"
product ||--o{ product_price : "pp_pr_idx"
product ||--o{ inbound_receipt : "ir_pr_idx"
product ||--o{ stock_transaction : "st_pr_idx"
purchase_order ||--o{ inbound_receipt : "ir_po_idx (LOT)"
sales_order ||--o{ stock_transaction : "참조"
local_government {
int lg_idx PK
string lg_name
string lg_code
string lg_sido
string lg_gugun
tinyint lg_state
datetime lg_regdate
}
member {
int mb_idx PK
int mb_lg_idx FK "nullable"
string mb_id
string mb_passwd
string mb_name
tinyint mb_level "1=일반,2=지정판매소,3=지자체,4=super"
tinyint mb_state
datetime mb_regdate
}
designated_shop {
int ds_idx PK
int ds_lg_idx FK
int ds_mb_idx FK "nullable"
string ds_shop_no
string ds_name
string ds_va_number "고정 가상계좌"
string ds_status "정상,폐업,직권해지"
datetime ds_regdate
}
product {
int pr_idx PK
int pr_lg_idx FK
string pr_type "일반,음식물,재사용"
string pr_capacity "3L,5L,10L"
datetime pr_regdate
}
sales_order {
int so_idx PK
int so_lg_idx FK "데이터 격리"
int so_ds_idx FK
datetime so_order_date
int so_total_amount
string so_payment_status "입금대기,완료,취소"
}
inbound_receipt {
int ir_idx PK
int ir_lg_idx FK
int ir_pr_idx FK
int ir_po_idx FK "LOT"
string ir_lot_number
int ir_quantity
datetime ir_receipt_date
}
stock_transaction {
int st_idx PK
int st_lg_idx FK
int st_pr_idx FK
string st_trans_type "IN,OUT,FREE,DISCARD"
int st_quantity
int st_reference_id "so_idx or ir_idx 등"
datetime st_trans_date
}
```
---
## 3. 참조 자료
- **ERD·요구사항**: `docs/종량제 관련 자료/종량제 개발목록/노션_정리_03-WBS_데이터베이스_ERD.md`
- **ERD 이미지**: `docs/종량제 관련 자료/ss_gbms/ss_gbms/1-5.png`
- **네이밍 규칙**: `docs/개발 규칙/06-데이터베이스정리구조.md`

View File

@@ -0,0 +1,190 @@
# 마스터 테이블 DDL
> 지자체·회원·지정판매소·기본코드·대행소·담당자·업체·무료대상자.
> `06-데이터베이스정리구조.md` 네이밍 규칙 적용.
---
## 1. local_government (지자체)
```sql
CREATE TABLE IF NOT EXISTS `local_government` (
`lg_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '지자체 PK',
`lg_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '지자체명(예: OO구청)',
`lg_code` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '지자체/구군 코드(행정코드)',
`lg_sido` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '시/도',
`lg_gugun` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '구/군',
`lg_addr` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '주소',
`lg_state` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1=사용, 0=미사용',
`lg_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`lg_idx`),
UNIQUE KEY `uk_lg_code` (`lg_code`),
KEY `idx_lg_state` (`lg_state`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='지자체(테넌트 루트)';
```
---
## 2. member (회원) — 기존 테이블 확장
기존 `member` 테이블에 지자체 FK 추가.
```sql
ALTER TABLE `member`
ADD COLUMN `mb_lg_idx` INT UNSIGNED NULL DEFAULT NULL COMMENT '소속 지자체 PK(지자체관리자만 사용)' AFTER `mb_group`,
ADD KEY `idx_mb_lg_idx` (`mb_lg_idx`);
```
| mb_level | mb_lg_idx | 비고 |
|----------|-----------|------|
| 4 (super admin) | NULL | 전체 지자체 접근 |
| 3 (지자체관리자) | 지자체 PK | 해당 지자체만 |
| 2 (지정판매소) | NULL | 소속은 designated_shop.ds_lg_idx 로 판단 |
| 1 (일반) | NULL | 지자체 필터 없음 |
---
## 3. designated_shop (지정 판매소)
노션 ERD의 Retailer. 고정 가상계좌(`ds_va_number`) 보유.
```sql
CREATE TABLE IF NOT EXISTS `designated_shop` (
`ds_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '지정판매소 PK',
`ds_lg_idx` INT UNSIGNED NOT NULL COMMENT '소속 지자체 FK',
`ds_mb_idx` INT UNSIGNED NULL DEFAULT NULL COMMENT '로그인 회원 FK(1:1)',
`ds_shop_no` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '판매소번호',
`ds_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '상호명',
`ds_biz_no` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '사업자번호',
`ds_rep_name` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '대표자명',
`ds_va_number` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '고정 가상계좌 번호',
`ds_zip` VARCHAR(10) NOT NULL DEFAULT '' COMMENT '우편번호',
`ds_addr` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '도로명주소',
`ds_addr_jibun` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '지번주소',
`ds_tel` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '일반전화',
`ds_rep_phone` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '개인전화',
`ds_email` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '이메일',
`ds_gugun_code` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '구코드',
`ds_designated_at` DATE NULL DEFAULT NULL COMMENT '지정일자',
`ds_state` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1=정상, 2=폐업, 3=직권해지',
`ds_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`ds_idx`),
KEY `idx_ds_lg_idx` (`ds_lg_idx`),
KEY `idx_ds_mb_idx` (`ds_mb_idx`),
UNIQUE KEY `uk_ds_shop_no` (`ds_shop_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='지정판매소';
```
---
## 4. code_kind / code_detail (기본코드)
기능목록 F-MD-01: 도/특별시/광역시, 구군 코드, 봉투 구분(일반·재사용·음식물), 용량별 코드, 작업 권한 등.
```sql
CREATE TABLE IF NOT EXISTS `code_kind` (
`ck_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '코드종류 PK',
`ck_code` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '종류 코드(A~Y 등)',
`ck_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '종류 명칭',
`ck_state` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1=사용, 0=미사용',
`ck_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`ck_idx`),
UNIQUE KEY `uk_ck_code` (`ck_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='기본코드 종류';
CREATE TABLE IF NOT EXISTS `code_detail` (
`cd_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '세부코드 PK',
`cd_ck_idx` INT UNSIGNED NOT NULL COMMENT 'code_kind FK',
`cd_code` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '세부 코드',
`cd_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '세부 명칭',
`cd_sort` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '정렬 순서',
`cd_state` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1=사용, 0=미사용',
`cd_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`cd_idx`),
KEY `idx_cd_ck_idx` (`cd_ck_idx`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='세부 기본코드';
```
---
## 5. agent (판매 대행소)
F-MD-04: 새마을금고, 우체국, 농협 등. 지자체별 소속 설정.
```sql
CREATE TABLE IF NOT EXISTS `agent` (
`ag_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '대행소 PK',
`ag_lg_idx` INT UNSIGNED NOT NULL COMMENT '소속 지자체 FK',
`ag_code` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '대행소 코드',
`ag_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '대행소 명칭',
`ag_state` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1=사용, 0=미사용',
`ag_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`ag_idx`),
KEY `idx_ag_lg_idx` (`ag_lg_idx`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='판매 대행소';
```
---
## 6. contact (담당자)
F-MD-05: 지자체별 소속(구/군/대행소/제작업체), 담당자명, 전화번호.
```sql
CREATE TABLE IF NOT EXISTS `contact` (
`ct_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '담당자 PK',
`ct_lg_idx` INT UNSIGNED NOT NULL COMMENT '지자체 FK',
`ct_affinity` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '소속 구분: 구군,대행소,제작업체',
`ct_name` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '담당자명',
`ct_phone` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '전화번호',
`ct_ref_id` INT UNSIGNED NULL DEFAULT NULL COMMENT '소속 대상 ID(업체/대행소 등)',
`ct_state` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1=사용, 0=미사용',
`ct_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`ct_idx`),
KEY `idx_ct_lg_idx` (`ct_lg_idx`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='담당자';
```
---
## 7. company (업체)
F-MD-05: 제작업체, 협회, 회수업체. 지자체별.
```sql
CREATE TABLE IF NOT EXISTS `company` (
`co_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '업체 PK',
`co_lg_idx` INT UNSIGNED NOT NULL COMMENT '지자체 FK',
`co_type` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '협회,제작업체,회수업체',
`co_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '업체명',
`co_rep` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '대표자명',
`co_addr` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '주소',
`co_tel` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '전화',
`co_biz_no` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '사업자번호',
`co_state` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1=사용, 0=미사용',
`co_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`co_idx`),
KEY `idx_co_lg_idx` (`co_lg_idx`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='업체';
```
---
## 8. beneficiary (무료용 대상자)
F-MD-06 무료 대상자: 읍/면/동 사무소, 무료대상자, 기타. 구분별 명칭·종료일·상태.
```sql
CREATE TABLE IF NOT EXISTS `beneficiary` (
`bf_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '무료대상자 PK',
`bf_lg_idx` INT UNSIGNED NOT NULL COMMENT '지자체 FK',
`bf_kind` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '읍면동사무소,무료대상자,기타',
`bf_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '명칭',
`bf_end_date` DATE NULL DEFAULT NULL COMMENT '종료일자',
`bf_memo` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '비고',
`bf_state` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1=정상, 0=삭제',
`bf_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`bf_idx`),
KEY `idx_bf_lg_idx` (`bf_lg_idx`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='무료용 대상자';
```

View File

@@ -0,0 +1,180 @@
# 물류·판매 테이블 DDL
> 품목·단가·포장단위·발주·입고·주문·수불. 노션 ERD(Product, InboundReceipt, SalesOrder, StockTransaction) 반영.
---
## 1. product (지자체별 취급 품목)
지자체별 봉투 규격·용량. 단가는 `product_price`에서 적용일자별 관리.
```sql
CREATE TABLE IF NOT EXISTS `product` (
`pr_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '품목 PK',
`pr_lg_idx` INT UNSIGNED NOT NULL COMMENT '지자체 FK',
`pr_code` VARCHAR(30) NOT NULL DEFAULT '' COMMENT '봉투/규격 코드',
`pr_type` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '일반,음식물,재사용',
`pr_capacity` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '3L,5L,10L 등',
`pr_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '품목 명칭',
`pr_state` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1=사용, 0=미사용',
`pr_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`pr_idx`),
KEY `idx_pr_lg_idx` (`pr_lg_idx`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='지자체별 취급 품목';
```
---
## 2. product_price (적용일자별 단가)
F-MD-02: 발주 단가, 도매가, 소비자가. 시계열 이력(적용일자 변경 시 이전 구간 보존).
```sql
CREATE TABLE IF NOT EXISTS `product_price` (
`pp_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '단가 PK',
`pp_lg_idx` INT UNSIGNED NOT NULL COMMENT '지자체 FK',
`pp_pr_idx` INT UNSIGNED NOT NULL COMMENT 'product FK',
`pp_apply_from` DATE NOT NULL COMMENT '적용 시작일',
`pp_apply_to` DATE NULL DEFAULT NULL COMMENT '적용 종료일(NULL=현재 유효)',
`pp_purchase` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '발주 단가',
`pp_wholesale` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '도매가',
`pp_retail` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '소비자가',
`pp_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`pp_idx`),
KEY `idx_pp_lg_idx` (`pp_lg_idx`),
KEY `idx_pp_pr_idx` (`pp_pr_idx`),
KEY `idx_pp_apply` (`pp_apply_from`, `pp_apply_to`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='품목별 단가(적용일자)';
```
---
## 3. packaging_unit (포장 단위)
F-MD-03: 박스당 팩 수, 팩당 낱장 수, 총 수량. 적용일자 이력 관리.
```sql
CREATE TABLE IF NOT EXISTS `packaging_unit` (
`pu_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '포장단위 PK',
`pu_lg_idx` INT UNSIGNED NOT NULL COMMENT '지자체 FK',
`pu_pr_idx` INT UNSIGNED NOT NULL COMMENT 'product FK',
`pu_apply_from` DATE NOT NULL COMMENT '적용 시작일',
`pu_apply_to` DATE NULL DEFAULT NULL COMMENT '적용 종료일',
`pu_box_to_pack` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '박스당 팩 수',
`pu_pack_to_sheet` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '팩당 낱장 수',
`pu_total` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '총 수량(박스당 낱장)',
`pu_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`pu_idx`),
KEY `idx_pu_lg_idx` (`pu_lg_idx`),
KEY `idx_pu_pr_idx` (`pu_pr_idx`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='포장 단위';
```
---
## 4. purchase_order (발주)
지자체 → 제작업체 발주. 구/군·동 코드, 제작업체, 봉투 종류, 수량, LOT·버전·상태.
```sql
CREATE TABLE IF NOT EXISTS `purchase_order` (
`po_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '발주 PK',
`po_lg_idx` INT UNSIGNED NOT NULL COMMENT '지자체 FK',
`po_uuid` CHAR(36) NOT NULL DEFAULT '' COMMENT '버전 관리용 UUID',
`po_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT '버전(수정 시 +1 insert)',
`po_gugun_code` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '구/군 코드',
`po_dong_code` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '동 코드',
`po_co_idx` INT UNSIGNED NULL DEFAULT NULL COMMENT '제작업체 company FK',
`po_pr_idx` INT UNSIGNED NOT NULL COMMENT '품목 FK',
`po_unit_price` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '발주 단가',
`po_box_qty` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '발주 박스 수량',
`po_order_date` DATE NOT NULL COMMENT '발주일',
`po_mb_idx` INT UNSIGNED NULL DEFAULT NULL COMMENT '발주자 member FK',
`po_state` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1=정상, 2=취소, 0=삭제',
`po_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`po_idx`),
KEY `idx_po_lg_idx` (`po_lg_idx`),
KEY `idx_po_uuid_version` (`po_uuid`, `po_version`),
KEY `idx_po_order_date` (`po_order_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='발주';
```
---
## 5. inbound_receipt (입고 내역)
노션 ERD InboundReceipt. LOT 번호·PDF417 바코드 연동. 발주(purchase_order) 단위 입고.
```sql
CREATE TABLE IF NOT EXISTS `inbound_receipt` (
`ir_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '입고 PK',
`ir_lg_idx` INT UNSIGNED NOT NULL COMMENT '지자체 FK',
`ir_po_idx` INT UNSIGNED NOT NULL COMMENT '발주 FK(LOT 단위)',
`ir_pr_idx` INT UNSIGNED NOT NULL COMMENT '품목 FK',
`ir_lot_number` VARCHAR(50) NOT NULL DEFAULT '' COMMENT 'LOT 번호(PDF417 연동)',
`ir_quantity` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '입고 수량',
`ir_unit` VARCHAR(10) NOT NULL DEFAULT 'BOX' COMMENT 'BOX,PACK,SHEET',
`ir_receipt_date` DATETIME NOT NULL COMMENT '입고일시',
`ir_mb_idx` INT UNSIGNED NULL DEFAULT NULL COMMENT '인수자 member FK',
`ir_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`ir_idx`),
KEY `idx_ir_lg_idx` (`ir_lg_idx`),
KEY `idx_ir_po_idx` (`ir_po_idx`),
KEY `idx_ir_lot_number` (`ir_lot_number`),
KEY `idx_ir_receipt_date` (`ir_receipt_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='입고 내역';
```
---
## 6. sales_order (판매소 주문)
노션 ERD SalesOrder. 지정판매소 주문, 결제상태. `so_lg_idx` = 데이터 격리용.
```sql
CREATE TABLE IF NOT EXISTS `sales_order` (
`so_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '주문 PK',
`so_lg_idx` INT UNSIGNED NOT NULL COMMENT '지자체 FK(데이터 격리)',
`so_ds_idx` INT UNSIGNED NOT NULL COMMENT '지정판매소 FK',
`so_order_no` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '접수/주문 번호',
`so_order_date` DATETIME NOT NULL COMMENT '주문일시',
`so_delivery_date` DATE NULL DEFAULT NULL COMMENT '배달일',
`so_total_amount` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '총 금액',
`so_payment_status` VARCHAR(20) NOT NULL DEFAULT 'PENDING' COMMENT '입금대기,완료,취소',
`so_state` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1=정상, 0=취소',
`so_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`so_idx`),
KEY `idx_so_lg_idx` (`so_lg_idx`),
KEY `idx_so_ds_idx` (`so_ds_idx`),
KEY `idx_so_order_date` (`so_order_date`),
KEY `idx_so_payment_status` (`so_payment_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='판매소 주문';
```
- 주문 상세(품목·수량·금액)는 별도 `sales_order_item` 테이블로 확장 가능.
---
## 7. stock_transaction (수불)
노션 ERD StockTransaction. 입고(IN), 판매(OUT), 불출(FREE), 파기(DISCARD). reference로 주문/입고 연결.
```sql
CREATE TABLE IF NOT EXISTS `stock_transaction` (
`st_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '수불 PK',
`st_lg_idx` INT UNSIGNED NOT NULL COMMENT '지자체 FK',
`st_pr_idx` INT UNSIGNED NOT NULL COMMENT '품목 FK',
`st_trans_type` VARCHAR(20) NOT NULL DEFAULT '' COMMENT 'IN,OUT,FREE,DISCARD',
`st_quantity` INT NOT NULL DEFAULT 0 COMMENT '수량(+입고/-출고)',
`st_ref_table` VARCHAR(30) NOT NULL DEFAULT '' COMMENT '참조 테이블: inbound_receipt,sales_order 등',
`st_ref_id` INT UNSIGNED NULL DEFAULT NULL COMMENT '참조 PK',
`st_trans_date` DATETIME NOT NULL COMMENT '수불 일시',
`st_mb_idx` INT UNSIGNED NULL DEFAULT NULL COMMENT '처리자 member FK',
`st_regdate` DATETIME NOT NULL COMMENT '등록일시',
PRIMARY KEY (`st_idx`),
KEY `idx_st_lg_idx` (`st_lg_idx`),
KEY `idx_st_pr_idx` (`st_pr_idx`),
KEY `idx_st_trans_type` (`st_trans_type`),
KEY `idx_st_trans_date` (`st_trans_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='수불 내역';
```

View File

@@ -0,0 +1,59 @@
# 지자체 데이터 필터 및 권한
> 멀티테넌트 환경에서 **해당 지자체 데이터만** 조회·수정하기 위한 필터 규칙과 권한별 접근.
---
## 1. 로그인 사용자의 지자체 결정
| mb_level | 지자체 식별 | 비고 |
|----------|-------------|------|
| **4 (super admin)** | 없음 | `lg_idx` 조건 없이 전체 조회 |
| **3 (지자체관리자)** | `member.mb_lg_idx` | 해당 지자체만 접근 |
| **2 (지정판매소)** | `designated_shop.ds_lg_idx` (로그인 회원의 `ds_mb_idx`로 조회한 판매소의 지자체) | 해당 지자체 내에서도 자기 판매소(`ds_idx`) 데이터 위주 제한 가능 |
| **1 (일반)** | 없음 | 지자체 필터 없음 또는 본인 데이터만 |
---
## 2. 쿼리 필터 적용
- 지자체별 테이블(`local_government` 제외) 조회·수정·삭제 시 **현재 사용자에 따른 `lg_idx`** 를 구한 뒤 `WHERE lg_idx = ?` 조건 추가.
- **지정판매소 사용자**: 주문 목록 등은 `so_ds_idx = (자기 ds_idx)` 로 추가 제한.
```phpV
// 예: 지자체관리자 — 담당 지자체 데이터만
$lgIdx = session()->get('mb_lg_idx'); // mb_level == 3 일 때 설정
$builder = $productModel->where('pr_lg_idx', $lgIdx);
// 예: 지정판매소 — 자기 판매소 주문만
$dsIdx = session()->get('ds_idx'); // 로그인 시 ds_mb_idx 로 조회한 ds_idx
$builder = $salesOrderModel->where('so_ds_idx', $dsIdx);
```
---
## 3. 적용 위치
- **컨트롤러/서비스**: 목록·상세·등록·수정·삭제 시 "현재 사용자 지자체(ds_idx 포함 여부)"를 세션 또는 서비스에서 구해 쿼리에 반영.
- **필터/미들웨어**: 관리자 라우트에서 `mb_lg_idx`, `ds_idx` 등을 세션·뷰에 넣어 두고, 지자체별 API/화면에서 일괄 적용하면 누락을 줄일 수 있음.
---
## 4. 테이블별 지자체 FK 요약
| 테이블 | 지자체 FK | 비고 |
|--------|-----------|------|
| local_government | — | 테넌트 루트 |
| member | mb_lg_idx (nullable) | 지자체관리자만 설정 |
| designated_shop | ds_lg_idx | |
| product | pr_lg_idx | |
| product_price | pp_lg_idx | |
| packaging_unit | pu_lg_idx | |
| agent | ag_lg_idx | |
| contact | ct_lg_idx | |
| company | co_lg_idx | |
| beneficiary | bf_lg_idx | |
| purchase_order | po_lg_idx | |
| inbound_receipt | ir_lg_idx | |
| sales_order | so_lg_idx | 데이터 격리용 |
| stock_transaction | st_lg_idx | |

View File

@@ -0,0 +1,215 @@
## 04. 마스터 데이터 선행 정리
이 문서는 **종량제 시스템 전역에서 공통으로 사용하는 기준 값(코드·마스터 데이터)** 중,
**서비스 오픈 전/개발 초기에 미리 DB에 적재해 두는 것이 좋은 항목**을 정리한다.
목표:
- 행정구역·코드·상태값·역할 등을 사전에 정의하여 **설계 변경을 최소화**한다.
- 화면 구현 시 **드롭다운(콤보박스)·검색 조건·통계 축**으로 재사용한다.
---
## 1. 행정구역·지자체 관련 마스터
### 1-1. 시/도, 구/군, 동 코드
- **구분**
- 시/도: 행정구역 상위 단위 (서울특별시, 부산광역시, ○○도 등)
- 구/군: 시/도 하위 행정구역 (○○구, ○○군)
- 동: 구/군 하위 동/읍/면
- **출처**
- `종량제_개발목록_20260127(기본코드 종류).csv`**코드 A, B, C, D** 및 하위 데이터
- **권장 구조(예시)**
- `local_government`:
- `lg_idx`: PK
- `lg_name`: 지자체 명칭 (예: 대구광역시 북구청)
- `lg_code`: 행정 코드(구/군 코드) 기본코드 B/C 기반
- `district` (또는 `gu`):
- `dt_idx`: PK
- `dt_lg_idx`: FK → `local_government.lg_idx`
- `dt_code`: 구/군 코드 (기본코드 C)
- `dt_name`: 구/군 명칭
- `dong`:
- `dg_idx`: PK
- `dg_dt_idx`: FK → `district.dt_idx`
- `dg_code`: 동 코드 (기본코드 D)
- `dg_name`: 동/읍/면 명칭
> 운영 방침: **행정구역은 문자열이 아니라 코드·PK로 정규화**해서 관리한다.
### 1-2. 지자체별 기본 설정
- 예시 항목
- 사용 봉투 종류(일반/공공/음식물/재사용 등)
- 사용 단위(리터/장/팩), VAT 포함 여부
- 지자체별 회수업체/제작업체 기본 설정
- 구현 방식
- `local_government_config` 테이블 등으로 별도 관리하거나,
- 코드 테이블(`code_detail`)과 조합해서 지자체별 설정값을 유지.
---
## 2. 기본 코드 체계 (code_kind / code_detail)
### 2-1. CSV 기반 코드 종류
다음 코드는 **CSV 기준으로 이미 정의되어 있으므로, 초기에 모두 `code_kind`/`code_detail`로 적재**하는 것을 권장한다.
- **봉투·판매 관련**
- 코드 E: 봉투구분 (일반/공공/무료/공동주택/음식물/재사용 등)
- 코드 F: 봉투재질 (고밀도, PP마대, 스티커, 용기 등)
- 코드 G: 용량별 (2L, 3L, 5L, 10L, 20L, 50L, 100L 등)
- 코드 H: 무상지급 구분 (시설보호대상자, 생보자, 사회복지시설 등)
- 코드 I: 판매형태 (무상지급, 일반판매, 관내판매, 교환판매 등)
- 코드 J: 반품형태 (일반반품, 관내반품 등)
- 코드 K: 반품사유 (봉투훼손, 지정판매소 폐업, 스티커 미사용 등)
- **수불·재고 관련**
- 코드 M: 수불구분
- 실사입고, 신청입고, 무료입고, 발주입고, 반품입고(정상/불용), 이동입고
- 실사출고, 신청불출, 무료불출, 일반판매, 공공출고, 반품출고(정상/불용), 이동출고, 파기처리, 시찰 등
- **조직·권한 관련**
- 코드 S: 소속 (청소과, 청소행정과, 자원순환과, 도시미화과, 영업부, 관리부, 기술부 등)
- 코드 T: 직위 (7급, 8급, 9급, 기능, 계장, 과장, 사장, 상무 등)
- 코드 P: 작업권한 (향후 역할·권한 체계와 연동 가능)
- **예산·금융 관련**
- 코드 Q: 예산과목 (관·항·목 수준 코드)
- 코드 R: 은행목록 (국민은행, 수협, 우리은행, 부산은행, 새마을금고 등)
### 2-2. code_kind / code_detail 설계 원칙
- `code_kind`:
- 코드 종류를 정의 (예: `E`, `F`, `G` …)
- 설명 필드에 한글 설명(봉투구분, 봉투재질 등) 저장
- `code_detail`:
- `ck_id` 또는 `ck_code` FK → `code_kind`
- `cd_code`: 세부코드 값 (예: 10, 11, 12 …)
- `cd_name`: 코드명 (예: 일반용 10L, 음식물 2L, 폐기물 스티커 1,000원 등)
- 필요 시 `cd_sort`, `cd_state`, `cd_memo` 등 추가
> 화면에서는 **code_detail 기반으로 selectbox·radio·checkbox**를 구성하며,
> 비즈니스 로직에서는 **하드코딩 대신 코드값 비교**를 사용한다.
---
## 3. 상품·포장·단가 관련 기본값
### 3-1. 품목 타입(pr_type)
- 예시 값
- 일반, 음식물, 재사용, 스티커, 용기 등
- 사용처
- `product.pr_type` 값으로 사용
- 보고서/통계·단가 정책 분기 등에 활용
- 구현
- 코드 테이블(`code_kind` / `code_detail`)로 관리하거나,
- 소수의 고정값일 경우 ENUM 역할을 하는 코드로 고정.
### 3-2. 포장 단위 기본 룰
- 개념
- 1박스 = N팩
- 1팩 = M장
- 1장 = 1EA
- 사용처
- `packaging_unit` 테이블의 기본 데이터
- 입고·출고·재고 실사에서 수량 변환(박스↔팩↔장) 시 사용
- 구현
- 지자체별/봉투별로 **포장단위 기본값을 설정하는 레코드**를 선행 입력.
### 3-3. 단가 정책 유형
- 항목
- 발주단가, 도매가, 소비자가, 유효기간
- 사용처
- `product_price` 테이블에서 지자체·봉투별 단가 관리
- 선행 정의
- 어떤 단가가 필수인지(소비자가 필수, 도매가는 옵션 등) 정책을 정리하고 문서화.
---
## 4. 권한·메뉴·업무 상태 마스터
### 4-1. 역할/권한 마스터
- 현재 역할
- SUPER_ADMIN, LOCAL_ADMIN, SHOP, CITIZEN (및 향후 추가 가능 역할)
- 사용처
- `member.mb_level` 및 RBAC 구현
- 선행 정리
- 역할별:
- 접근 가능한 메뉴
- 관리 대상 지자체 범위 (전체/단일 지자체/미제한)
- 수행 가능한 업무(등록/수정/삭제/승인 등)를 표로 정의.
### 4-2. 메뉴·기능 코드
- 출처
- 웹·모바일 기능목록 CSV의 **PWB-XXXXXX-YYY** 형식 코드
- 사용처
- 메뉴 트리 구성, 권한 제어, 변경 이력 로깅
- 권장 구조
- `menu` 또는 `feature` 테이블:
- 기능코드, 명칭, 상위메뉴, URL/라우트, 정렬순서, 사용 여부 등
### 4-3. 업무 상태값
- 예시
- 발주 상태: 정상, 취소, 삭제 등
- 입고 상태: 정상입고, 반품입고(정상/불용), 파기 등
- 가상계좌 상태: 입금대기, 입금완료, 취소
- 구현
- 가능한 한 **코드 테이블로 공통 관리**하고,
- 테이블별 상태 컬럼(`*_state`, `*_status`)는 코드값을 참조.
---
## 5. 결제·가상계좌·바코드 정책
### 5-1. 가상계좌·정산 관련 기본값
- 예시 항목
- 사용 은행 목록 (은행 코드, 은행명)
- 지자체별 계약 은행/계좌 구분 방식
- 입금 마감시간, 입금 허용 요일 등 정책성 값
- 구현
- 은행 목록은 코드 R 기반으로 `code_detail`에 저장.
- 지자체별 VA 정책은 별도 설정 테이블 또는 `local_government_config`에 저장.
### 5-2. 바코드·LOT 번호 정책
- 정의할 항목
- LOT 번호 자리수, 구성 요소(지자체 코드, 발주일자, 시퀀스 등)
- 박스/팩/낱장 바코드 규칙 (prefix, 길이, 체크섬 여부 등)
- 구현
- 단순 문자열 규칙으로 하드코딩하지 않고,
- 바코드 정책 테이블 또는 설정값으로 정의해 두고,
- 바코드 생성·검증 로직은 이 설정을 참조.
---
## 6. 우선 순위 정리
**1단계(필수, 즉시 적재 추천)**
- 행정구역·지자체 코드:
- 시/도, 구/군, 동 코드 (local_government, district, dong)
- 기본코드:
- 봉투구분(E), 봉투재질(F), 용량(G), 무상지급(H), 판매형태(I), 수불구분(M)
- 조직·은행:
- 소속(S), 직위(T), 은행목록(R)
**2단계(초기 개발기·시범 운영 전 정리 추천)**
- 반품형태(J), 반품사유(K), 작업권한(P), 예산과목(Q)
- 상품 타입(pr_type), 포장 단위 기본값, 단가 정책 유형
- 역할별 권한 정의, 메뉴/기능 코드 마스터
**3단계(실 서비스 준비 단계)**
- 지자체별 기본 설정(운영 정책, 단가 정책, 사용 봉투 종류)
- 가상계좌 정책, 바코드·LOT 정책 세부 정의
> 이 문서는 “어떤 값을 코드·마스터로 선행 정의해야 하는지”를 개략적으로 정리한 것이며,
> 실제 DDL 및 컬럼명은 `00-테이블_목록_및_ERD.md`, `01-마스터_테이블_DDL.md`, `02-물류_판매_테이블_DDL.md`의 규칙을 따른다.

View File

@@ -0,0 +1,24 @@
# 테이블 설계 (기본 개발계획)
노션 ERD·웹 기능목록·`06-데이터베이스정리구조.md`를 반영한 **DB 테이블 및 관계** 설계.
지자체(`lg_idx`) 기준 멀티테넌트, 데이터 격리.
---
## 문서 목록
| 파일 | 내용 |
|------|------|
| [00-테이블_목록_및_ERD.md](00-테이블_목록_및_ERD.md) | 전체 테이블 목록, 엔티티 관계 다이어그램(mermaid), 참조 자료 |
| [01-마스터_테이블_DDL.md](01-마스터_테이블_DDL.md) | local_government, member 확장, designated_shop, code_kind/code_detail, agent, contact, company, beneficiary |
| [02-물류_판매_테이블_DDL.md](02-물류_판매_테이블_DDL.md) | product, product_price, packaging_unit, purchase_order, inbound_receipt, sales_order, stock_transaction |
| [03-지자체_데이터_필터_및_권한.md](03-지자체_데이터_필터_및_권한.md) | 권한별 지자체 결정, 쿼리 필터 적용, 테이블별 lg_idx 요약 |
---
## 참조
- **ERD·요구사항**: `docs/종량제 관련 자료/종량제 개발목록/노션_정리_03-WBS_데이터베이스_ERD.md`
- **ERD 이미지**: `docs/종량제 관련 자료/ss_gbms/ss_gbms/1-5.png`
- **운영 방식(단일 vs 멀티테넌트)**: 상위 `20-지자체_운영_방식_정리.md`
- **네이밍 규칙**: `docs/개발 규칙/06-데이터베이스정리구조.md`