# 종량제 — 쓰레기봉투 물류시스템 (jongryangje)

**[종량제 개발목록 (엑셀 다운로드)](https://github.com/wixon-associates/jongryangje/raw/main/assets/종량제_개발목록_20260127.xlsx)** — 로컬 복제 후에는 [`assets/종량제_개발목록_20260127.xlsx`](./assets/종량제_개발목록_20260127.xlsx)

지자체·지정판매소 등을 대상으로 하는 **종량제 쓰레기봉투 물류·업무 웹 애플리케이션**입니다.
백엔드는 **[CodeIgniter 4](https://codeigniter.com/)** 기반입니다.

**저장소:** [wixon-associates/jongryangje](https://github.com/wixon-associates/jongryangje)
| **[구현 화면 스크린샷](./docs/SCREENSHOTS.md)** | **[Notion 진행상황](https://www.notion.so/31b42b987c3780baba32ded04a1d41bb)** |

---

## 기술 스택

| 항목 | 기술 |
|------|------|
| Framework | CodeIgniter 4.7+ |
| Language | PHP 8.2+ (strict types) |
| Database | MySQL / MariaDB (MySQLi) |
| 의존성 관리 | Composer 2.x |
| 테스트 | PHPUnit 10.x |
| 세션 | 파일 기반 (`writable/session/`) |

---

## 요구 사항

- **PHP** 8.2 이상 (`composer.json` 기준)
- **Composer** 2.x
- **MySQL / MariaDB** (프로젝트는 `MySQLi` 드라이버 사용)
- 권장 PHP 확장: `intl`, `mbstring`, MySQL 사용 시 `mysqlnd`

---

## 빠른 시작 (로컬)

### 1) 저장소 복제

```bash
git clone https://github.com/wixon-associates/jongryangje.git
cd jongryangje
```

### 2) 의존성 설치

```bash
composer install
```

### 3) 환경 설정

루트에 있는 샘플 파일을 복사해 `.env`를 만듭니다.

```bash
cp env .env
```

`.env`에서 최소한 다음을 설정합니다.

| 항목 | 설명 |
|------|------|
| `app.baseURL` | 예: `http://localhost:8080/` (끝에 `/`) |
| `database.default.*` | DB 호스트·DB명·사용자·비밀번호 |
| `encryption.key` | 개인정보(이메일·연락처) 암호화용. **64자리 hex** (예: `php -r "echo bin2hex(random_bytes(32));"`) |

> `.env`는 **Git에 올리지 마세요.** 비밀번호·키가 들어갑니다.

### 4) 데이터베이스 준비

아래 순서대로 SQL 스크립트를 실행합니다.

| 순서 | 파일 | 용도 |
|------|------|------|
| 1 | `writable/database/init_jongryangje_dev.sql` | DB·DB 사용자 생성 |
| 2 | `writable/database/login_tables.sql` | 회원·로그인·지자체·지정판매소 기본 테이블 |
| 3 | `writable/database/member_approval_request_add.sql` | 회원가입 역할 승인 요청 테이블 |
| 4 | `writable/database/menu_tables.sql` | 메뉴 시스템 (메뉴 타입 + 메뉴 항목 + 시드) |
| 5 | `writable/database/local_government_init_daegu.sql` | 대구 시범 지자체 데이터 |
| 6 | `writable/database/code_master_init_daegu.sql` | 기본코드 마스터 초기화 |

### 5) 개발 서버 실행

```bash
php spark serve --port=8045
```

### 6) 테스트

```bash
vendor/bin/phpunit
```

---

## 프로젝트 구조

```
app/
├── Config/          # Routes, Database, Roles, Filters, Session 등
├── Controllers/     # Home, Auth, Admin/* (8개 관리자 컨트롤러)
├── Models/          # 7개 모델 (Member, LocalGovernment, DesignatedShop 등)
├── Views/           # admin/, auth/, bag/, home/ 템플릿
├── Filters/         # AdminAuthFilter (관리자 접근 제어)
├── Helpers/         # admin_helper, pii_encryption_helper
└── Database/        # Migrations, Seeds
public/              # 웹 루트
writable/database/   # SQL 초기화 스크립트
tests/               # unit/, database/, session/
assets/              # 기획 문서 (엑셀)
```

---

## 역할 체계 (RBAC)

| Level | 역할 | 설명 |
|-------|------|------|
| 4 | Super Admin | 전체 시스템 관리, 작업 지자체 선택 필수 |
| 3 | 지자체관리자 | 소속 지자체 범위 내 관리 |
| 2 | 지정판매소 | 봉투 판매/재고 관리 |
| 1 | 일반 사용자 | 기본 조회 (시민) |

- 역할 상수: `Config\Roles` — `LEVEL_SUPER_ADMIN(4)`, `LEVEL_LOCAL_ADMIN(3)`, `LEVEL_SHOP(2)`, `LEVEL_CITIZEN(1)`
- `AdminAuthFilter`가 로그인 + 레벨 3/4 + 지자체 선택 여부 검증

## 멀티테넌시

- `local_government.lg_idx` 가 테넌트 루트
- 관리자 필터에서 `session('admin_lg_idx')` 기반 테넌트 분리
- Super Admin은 `/admin/select-local-government`에서 작업 지자체 선택

---

## 주요 URL

| 경로 | 설명 | 인증 |
|------|------|------|
| `/` | 홈 (비로그인 시 환영 화면) | 공개 |
| `/login`, `/logout` | 로그인·로그아웃 | 공개 |
| `/register` | 회원가입 (역할 승인 플로우 연동) | 공개 |
| `/dashboard` | 로그인 후 메인 대시보드 | 인증 |
| `/dashboard/classic-mock` 등 | UI 시안용 라우트 | 인증 |
| `/bag/*` | 봉투 관련 페이지 (목업) | 인증 |
| `/admin` | 관리자 대시보드 | 관리자 (Lv.3+) |
| `/admin/users` | 회원 관리 (CRUD) | 관리자 |
| `/admin/access/login-history` | 로그인 이력 조회 | 관리자 |
| `/admin/access/approvals` | 회원가입 역할 승인 대기 처리 | 관리자 |
| `/admin/roles` | 역할 목록 조회 | 관리자 |
| `/admin/menus` | 메뉴 관리 (트리 구조 CRUD) | 관리자 |
| `/admin/local-governments` | 지자체 관리 | 관리자 |
| `/admin/designated-shops` | 지정판매소 관리 (CRUD) | 관리자 |
| `/admin/select-local-government` | 작업 지자체 선택 | Super Admin |

정확한 라우트는 `app/Config/Routes.php`를 확인하세요.

---

## DB 테이블

| 테이블 | 용도 |
|--------|------|
| `member` | 회원 (mb_id, mb_level, mb_state, PII 암호화) |
| `member_log` | 로그인/로그아웃 감사 로그 (IP, User-Agent) |
| `member_approval_request` | 회원가입 승인 요청 (pending/approved/rejected) |
| `local_government` | 지자체 (테넌트 루트) |
| `designated_shop` | 지정판매소 (지자체별 관리) |
| `menu_type` | 메뉴 유형 (admin, site) |
| `menu` | 메뉴 항목 (트리 구조, 역할별 노출) |

---

## 기본코드 체계

개발목록 엑셀의 "기본코드 종류" 시트 기준, A~Y 총 25종의 코드 체계:

| 코드 | 코드명 | 코드 | 코드명 |
|------|--------|------|--------|
| A | 도/특별시/광역시 구분 | N | 동판종류 |
| B | 특별시/광역시/시/군코드 | O | 봉투명 |
| C | 구코드 | P | 작업권한 |
| D | 동코드 | Q | 예산과목 |
| E | 봉투구분 (일반/공공/무료/공동주택/재사용/음식물) | R | 은행목록 |
| F | 봉투재질 (고밀도/PP마대/스티커/용기) | S | 소속 |
| G | 용량별 (2L~120L, 1000원~10000원) | T | 직위 |
| H | 무상지급 대상 | U | 배달 |
| I | 판매형태 (무상/일반/관내/교환) | V | 구역 |
| J | 반품형태 | W | 봉투명(약어) |
| K | 반품사유 | X | 봉투구분(대분) |
| L | 지정판매소 변경사유 | Y | 분기 |
| M | 수불구분 | | |

---

## 개발 현황

### 웹 기능목록 (63개 항목)

기획 문서(`assets/종량제_개발목록_20260127.xlsx`)의 "웹 기능목록" 시트 기준으로 정리합니다.

#### 구현 완료

| No | 카테고리 | 기능 | 상태 | 비고 |
|----|---------|------|------|------|
| 1 | 공통 | 로깅 (로그인/로그아웃 이력) | **완료** | `member_log` 테이블, IP/UA 기록 |
| 2 | 공통 | 개인정보 비식별화 | **완료** | `pii_encryption_helper` (ENC: prefix, AES 암호화) |
| 3 | 공통 | 로그인 | **부분** | 로그인/세션/역할별 리다이렉트 완료. 2차 인증 미구현, 5회 실패 lock 미구현 |
| 4 | 관리자단 | 사용자 권한 관리 | **완료** | 4단계 RBAC, Config 기반 |
| 5 | 관리자단 | 사용자 관리 | **완료** | Full CRUD + soft delete + PII 암복호화 |
| 6 | 관리자단 | 사용자 로그인 이력 확인 | **완료** | 기간 지정 조회 구현 |
| 7 | 관리자단 | 사용자 권한 승인 | **완료** | 승인/거절 + 사유 입력 + 트랜잭션 처리 |
| 8 | 관리자단 | 메뉴 관리 | **완료** | 트리 구조 CRUD, 지자체별 메뉴 복사 |
| 9 | 관리자단 | 메뉴 별 권한 설정 | **완료** | `mm_level` 필드로 역할별 노출 제어 |
| 25 | 기본정보관리 | 지정판매소 관리 (리스트/상세) | **완료** | 지자체별 필터링, 판매소 정보 표시 |
| 26 | 기본정보관리 | 지정판매소 등록/수정/삭제 | **완료** | Full CRUD, 판매소번호 자동생성 |
| 29 | 기본정보관리 | PASSWORD 변경 | **미구현** | |

#### 미구현 — 기본정보관리 (SFR-PWB-003)

| No | 기능 | 설명 |
|----|------|------|
| 10-11 | 기본코드 관리 | 코드 종류 및 하위 세부코드 CRUD |
| 12-13 | 단가 관리 | 지자체별 봉투 종류별 단가 CRUD, 이력 관리, 기간별 조회 |
| 14-15 | 포장 단위 관리 | 박스당 팩/팩당 낱장 수량 CRUD, 기간별 조회 |
| 16-18 | 판매 대행소 관리 | 대행소 CRUD, 지자체 연결, 조회 |
| 19-20 | 담당자 관리 | 지자체별 담당자 CRUD (소속: 구/군/대행소/제작업체) |
| 21-22 | 업체 관리 | 협회/제작업체/회수업체 CRUD, 조회/인쇄 |
| 23-24 | 무료용 대상자 관리 | 읍면동/무료대상자/기타 구분별 CRUD |
| 27 | 지정판매소 지도 | 지정판매소 지도상 위치 확인 |
| 28 | 지정판매소 조회 | 다조건 조회, 엑셀 저장, 인쇄, 바코드 출력 |
| 29 | 지정판매소 현황 | 연도별 신규등록/취소 현황 조회 |
| 29 | PASSWORD 변경 | 현재 로그인 사용자 비밀번호 변경 |

#### 미구현 — 발주 입고 관리 (SFR-PWB-004)

| No | 기능 | 설명 |
|----|------|------|
| 30 | 발주 등록 | 발주 form (UUID v4 + SHA-256 해싱 + 블록 저장), LOT 번호 생성 |
| 31 | LOT번호 및 바코드 생성 | AES-256 + RSA 암호화 seed → PDF417 바코드 생성 |
| 32 | 발주 변경 | 동일 UUID 버전 관리, 해시 체인 |
| 33 | 발주 삭제 | 상태 변경 방식 삭제 |
| 34 | 발주 현황 | 기간/제작업체/품명/입고처 조건 조회, 리포트 |
| 35 | 발주 입고 (스캐너) | 바코드 스캐너 연동 (Electron + serialport) |
| 36 | 발주 입고 (스캐너) | 제작업체별 미입고 발주 조회, 스캔 입고 처리 |
| 37 | 일괄 입고 | LOT 단위 전체 입고 처리 |
| 38 | 입고 현황 | 기간/업체/품명/구분별 조회, 리포트 |

#### 미구현 — 불출 관리 (SFR-PWB-005)

| No | 기능 | 설명 |
|----|------|------|
| 39 | 무료용 불출 현황 | 기간별 봉투 종류별 불출 현황 조회 |
| 40 | 무료용 불출 처리 | 불출 기록, 바코드 스캔, 재고 감산, 판매 처리 |
| 41 | 무료용 불출 취소 | 불출 리스트/품목/코드 3분할 화면, 취소 후 재고 복원 |

#### 미구현 — 재고/실사 관리 (SFR-PWB-006~007)

| No | 기능 | 설명 |
|----|------|------|
| 42 | 재고 조회 | 기준일자 봉투/스티커 종류별 재고량, 결재란 인쇄 |
| 43 | 실사 선별 | 바코드 있는 봉투 대상 실사 실시 |
| 44 | 실사 선별 조회 | 전체→박스→팩→낱장 drill-down 조회 |

#### 미구현 — 주문/판매 관리 (SFR-PWB-008)

| No | 기능 | 설명 |
|----|------|------|
| 45 | 주문 접수 관리 메인 | 접수 리스트, 상세, 전화 주문 접수 3분할 화면 |
| 46 | 전화 주문 접수 | 판매소 자동완성 검색, 가상계좌 안내, 포장단위 자동 계산 |
| 47 | 전화 접수 수정/취소 | 접수량 수정, 상태 변경 방식 취소 |
| 48 | 지정판매소 판매 | 바코드 스캔 판매 처리, 중복 스캔 방지 |
| 49 | 지정판매소 판매 취소 | 품목별/봉투코드별 선택 취소 |
| 50 | 지정판매소 반품 | 바코드 스캔 반품 처리 |
| 51 | 지정판매소 반품 취소 | 반품 취소 → 판매 상태 복원 |

#### 미구현 — 판매 현황 (SFR-PWB-009)

| No | 기능 | 설명 |
|----|------|------|
| 52 | 판매 대장 | 일자별/기간별 집계, 수수료/총액, 결재란 인쇄 |
| 53 | 일계표 | 일계 + 월간 누계 (판매수량/금액/수수료/징수액) |
| 54 | 기간별 판매현황 | 일자별/기간별 판매+반품+계, 봉투계/스티커계 소계 |
| 55 | 년 판매 현황 | 월별/분기별 품목별 판매 |
| 56 | 지정판매소별 판매현황 | 읍면동별, 수량/금액 집계, 1~12월 컬럼 |
| 57 | 홈택스 처리 | 세금계산서 일괄발급 엑셀 양식 생성 |

#### 미구현 — 봉투 수불 관리 (SFR-PWB-010)

| No | 기능 | 설명 |
|----|------|------|
| 58 | 기타 입출고 | 상세 기능 확인 필요 |
| 59 | 봉투 수불 현황 | 전일재고/입고/출고/잔량, 일자별/기간별 |
| 60 | 반품/파기 현황 | 기간별 입출고 구분 조회 |
| 61 | 봉투 수급 계획 | 기능 확인 필요 (추가 발주 예정일 산출 방식 불명확) |
| 62 | LOT 수불 조회 | 바코드 스캔으로 개별 봉투 수불 이력 조회 |

#### 미구현 — 봉투 스캔 (SFR-PWB-011)

| No | 기능 | 설명 |
|----|------|------|
| 63 | 봉투 스캔 현황 | 앱 바코드 스캔 횟수 확인, 경위도 위치 지도 표시 |

### 모바일앱 기능목록 (15개 항목) — 전체 미구현

| No | 카테고리 | 기능 |
|----|---------|------|
| 1-3 | 공통 | 로깅, 개인정보 비식별화, 로그인 (2차인증) |
| 4 | 발주 입고 | PDF417 스캐너 연동 입고 처리 |
| 5-6 | 불출 관리 | 무료용/공공용 불출 처리/취소 |
| 7-8 | 판매 관리 | 지정판매소 판매/판매취소 |
| 9-10 | 판매 관리 | 지정판매소 반품/반품취소 |
| 11 | 봉투 수불 | LOT 수불 조회 |
| 12-14 | 봉투 주문 | 주문 내역/주문/주문 수정·취소 |
| 15 | 정품 인증 | PDF417 스캐너 봉투 정품 인증 |

### 전체 메뉴 구조

개발목록 엑셀의 "전체 메뉴" 시트 기준, 10개 대메뉴:

```
기본정보관리 ─ 기본코드, 단가, 포장단위, 대행소, 담당자, 업체, 무료대상자, 지정판매소, 환경설정
발주 입고 관리 ─ 발주 등록/변경, LOT, 발주현황, 입고(스캐너/일괄), 입고현황
불출 관리 ─ 무료 불출 현황/처리/취소
재고 관리 ─ 재고현황, 실사(선별/등록/조회/오류/취소)
판매 관리 ─ 전화접수, 판매소 판매/반품/취소
판매 현황 ─ 판매대장, 일계표, 기간별/년/판매소별 현황, 홈택스
봉투 수불 관리 ─ 기타 입출고, 수불현황, 반품/파기, 수급계획, LOT 수불
통계 분석 관리 ─ 전년대비, 월별/계절별 추이 분석
```

---

## 개발 진행 요약

| 구분 | 항목 수 | 완료 | 부분완료 | 미구현 |
|------|---------|------|---------|--------|
| 공통 | 3 | 2 | 1 | 0 |
| 관리자단 | 6 | 6 | 0 | 0 |
| 기본정보관리 | 20 | 2 | 0 | 18 |
| 발주 입고 관리 | 9 | 0 | 0 | 9 |
| 불출 관리 | 3 | 0 | 0 | 3 |
| 재고/실사 관리 | 3 | 0 | 0 | 3 |
| 주문/판매 관리 | 7 | 0 | 0 | 7 |
| 판매 현황 | 6 | 0 | 0 | 6 |
| 봉투 수불 관리 | 5 | 0 | 0 | 5 |
| 봉투 스캔 | 1 | 0 | 0 | 1 |
| **웹 합계** | **63** | **10** | **1** | **52** |
| 모바일앱 | 15 | 0 | 0 | 15 |
| **전체 합계** | **78** | **10** | **1** | **67** |

> **현재 진척율: 약 13% (웹 기준 약 16%)**

---

## 향후 개발 로드맵

### Phase 2 — 기본정보관리 완성

- [ ] 기본코드 종류/세부코드 관리 (CRUD)
- [ ] 지자체별 봉투 단가 관리 + 이력 관리
- [ ] 포장 단위 관리 (박스/팩/낱장 체계)
- [ ] 판매 대행소 관리 + 지자체 연결
- [ ] 담당자 관리, 업체 관리 (협회/제작업체/회수업체)
- [ ] 무료용 대상자 관리
- [ ] 지정판매소 다조건 조회 + 엑셀 저장 + 인쇄 + 바코드 출력
- [ ] 지정판매소 현황 (신규/취소) + 지도 표시
- [ ] 지자체 수정/삭제 기능
- [ ] PASSWORD 변경 기능
- [ ] 로그인 5회 실패 lock 처리

### Phase 3 — 발주·입고·재고 핵심

- [ ] 발주 등록 (UUID v4 + SHA-256 해싱 + 블록)
- [ ] LOT 번호 생성 + PDF417 바코드 (AES-256 + RSA)
- [ ] 발주 변경/삭제 (버전 관리)
- [ ] 발주 현황 리포트
- [ ] 발주 입고 처리 (바코드 스캐너 / 일괄 입고)
- [ ] 재고 조회 + 결재란 인쇄
- [ ] 실사 선별 / 등록 / 조회

### Phase 4 — 주문·판매·불출

- [ ] 전화 주문 접수 + 자동완성 검색
- [ ] 주문 수정/취소
- [ ] 지정판매소 판매 처리 (바코드 스캔)
- [ ] 판매 취소, 반품, 반품 취소
- [ ] 무료용 불출 현황/처리/취소

### Phase 5 — 현황·리포트·수불

- [ ] 판매 대장 (일자별/기간별)
- [ ] 일계표, 기간별 판매현황, 년 판매 현황
- [ ] 지정판매소별 판매현황 (수량/금액)
- [ ] 홈택스 세금계산서 엑셀 생성
- [ ] 봉투 수불 현황 (전일재고/입고/출고/잔량)
- [ ] 반품/파기 현황, LOT 수불 조회

### Phase 6 — 모바일앱

- [ ] 앱 공통 (로그인, 2차인증, PII)
- [ ] 발주 입고 (PDF417 카메라 스캔)
- [ ] 불출 관리 (카메라 스캔)
- [ ] 판매/반품 처리 (카메라 스캔)
- [ ] 봉투 주문/주문 수정·취소
- [ ] 봉투 정품 인증

### 공통 기술 과제

- [ ] 2차 인증 적용
- [ ] 페이지네이션 구현
- [ ] 엑셀 저장/인쇄 공통 컴포넌트
- [ ] 바코드 스캐너 연동 (Electron + serialport)
- [ ] 카카오 주소 검색 API 연동
- [ ] CRUD 로깅 (전체 데이터 변경 이력)
- [ ] 대시보드 실 데이터 연동
