diff --git a/README.md b/README.md index 09e17ed..692ceb1 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# 종량제 — 쓰레기봉투 물류시스템 (jongryangje) +# 종량제 -- 쓰레기봉투 물류시스템 (jongryangje) -**[종량제 개발목록 (엑셀 다운로드)](https://github.com/wixon-associates/jongryangje/raw/main/assets/종량제_개발목록_20260127.xlsx)** — 로컬 복제 후에는 [`assets/종량제_개발목록_20260127.xlsx`](./assets/종량제_개발목록_20260127.xlsx) +**[종량제 개발목록 (엑셀 다운로드)](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) @@ -18,77 +18,9 @@ | Language | PHP 8.2+ (strict types) | | Database | MySQL / MariaDB (MySQLi) | | 의존성 관리 | Composer 2.x | -| 테스트 | PHPUnit 10.x | +| E2E 테스트 | Playwright (Chromium) | | 세션 | 파일 기반 (`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 -``` +| 프론트엔드 | Tailwind CSS (CDN), Vanilla JS | --- @@ -96,21 +28,119 @@ 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/ # 기획 문서 (엑셀) +├── Config/ # Routes, Database, Roles, Filters, Session 등 (45개) +├── Controllers/ # 28개 컨트롤러 +│ ├── Auth.php # 로그인/로그아웃/회원가입 +│ ├── Bag.php # 사이트 메뉴 페이지 (10개 메뉴) +│ ├── Home.php # 홈/대시보드 +│ └── Admin/ # 관리자 컨트롤러 24개 +│ ├── BagOrder.php # 발주 관리 +│ ├── BagReceiving.php # 입고 관리 +│ ├── BagInventory.php # 재고 현황 +│ ├── BagSale.php # 판매/반품 관리 +│ ├── BagIssue.php # 무료용 불출 관리 +│ ├── ShopOrder.php # 주문 접수 관리 +│ ├── BagPrice.php # 봉투 단가 관리 +│ ├── PackagingUnit.php # 포장 단위 관리 +│ ├── CodeKind.php # 기본코드 종류 +│ ├── CodeDetail.php # 세부코드 +│ ├── SalesAgency.php # 판매 대행소 +│ ├── Manager.php # 담당자 +│ ├── Company.php # 업체 (제작/협회/회수) +│ ├── FreeRecipient.php # 무료용 대상자 +│ ├── SalesReport.php # 리포트 (판매대장/일계표/수불) +│ ├── User.php # 회원 관리 +│ ├── DesignatedShop.php # 지정판매소 +│ ├── LocalGovernment.php # 지자체 +│ ├── Menu.php # 메뉴 관리 +│ ├── PasswordChange.php # 비밀번호 변경 +│ └── ... +├── Models/ # 25개 모델 +├── Views/ # 88개 뷰 템플릿 +│ ├── admin/ # 관리자 뷰 (59개, 엔티티별 하위 디렉토리) +│ ├── bag/ # 사이트 메뉴 뷰 (17개 + 레이아웃) +│ ├── auth/ # 로그인/회원가입 (2개) +│ └── home/ # 대시보드 (1개) +├── Filters/ # AdminAuthFilter (관리자 접근 제어) +├── Helpers/ # admin_helper, pii_encryption_helper +└── Database/ # Migrations, Seeds +public/ # 웹 루트 +writable/database/ # SQL 초기화/시드 스크립트 (21개) +e2e/ # Playwright E2E 테스트 (84개 테스트) +assets/ # 기획 문서 (엑셀) ``` --- +## 데이터베이스 (25개 테이블) + +### 회원/인증 + +| 테이블 | 용도 | +|--------|------| +| `member` | 회원 (mb_id, mb_level, mb_state, PII 암호화, 로그인 실패 lock) | +| `member_log` | 로그인/로그아웃 감사 로그 (IP, User-Agent) | +| `member_approval_request` | 회원가입 역할 승인 요청 (pending/approved/rejected) | + +### 지자체/판매소 + +| 테이블 | 용도 | +|--------|------| +| `local_government` | 지자체 (테넌트 루트, lg_code 기반) | +| `designated_shop` | 지정판매소 (지자체별, 판매소번호 자동생성) | + +### 메뉴 시스템 + +| 테이블 | 용도 | +|--------|------| +| `menu_type` | 메뉴 유형 (admin, site) | +| `menu` | 메뉴 항목 (트리 구조, 역할별 노출, 지자체별) | + +### 기본코드 마스터 + +| 테이블 | 용도 | +|--------|------| +| `code_kind` | 코드 종류 (A~T, 20종) | +| `code_detail` | 세부코드 (행정구역, 봉투구분, 재질, 용량 등) | + +### 단가/포장 + +| 테이블 | 용도 | +|--------|------| +| `bag_price` | 봉투 단가 (발주/도매/소비자가, 적용기간) | +| `bag_price_history` | 단가 변경 이력 | +| `packaging_unit` | 포장 단위 (박스/팩/낱장) | +| `packaging_unit_history` | 포장 단위 변경 이력 | + +### 업체/담당자/대상자 + +| 테이블 | 용도 | +|--------|------| +| `sales_agency` | 판매 대행소 | +| `company` | 업체 (manufacturer/association/collector) | +| `manager` | 담당자 (소속/직위) | +| `free_recipient` | 무료용 대상자 (생보자/시설/수훈자) | + +### 발주/입고/재고 + +| 테이블 | 용도 | +|--------|------| +| `bag_order` | 발주 (UUID, LOT번호, SHA-256 해시) | +| `bag_order_item` | 발주 품목 (봉투코드별 수량/금액) | +| `bag_receiving` | 입고 (발주 연계, 박스/낱장 수량) | +| `bag_inventory` | 재고 현황 (봉투코드별 현재 재고) | + +### 판매/주문/불출 + +| 테이블 | 용도 | +|--------|------| +| `bag_sale` | 판매/반품 (판매소, 봉투코드, 수량/금액) | +| `shop_order` | 주문 접수 (배달일, 결제/입금/수령 상태) | +| `shop_order_item` | 주문 품목 (박스/팩/낱장 단위) | +| `bag_issue` | 무료용 불출 (연도/분기, 불출처, 상태) | + +--- + ## 역할 체계 (RBAC) | Level | 역할 | 설명 | @@ -120,295 +150,329 @@ assets/ # 기획 문서 (엑셀) | 2 | 지정판매소 | 봉투 판매/재고 관리 | | 1 | 일반 사용자 | 기본 조회 (시민) | -- 역할 상수: `Config\Roles` — `LEVEL_SUPER_ADMIN(4)`, `LEVEL_LOCAL_ADMIN(3)`, `LEVEL_SHOP(2)`, `LEVEL_CITIZEN(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')` 기반 테넌트 분리 +- `local_government.lg_idx`가 테넌트 루트 +- 관리자 필터에서 `admin_effective_lg_idx()` 기반 테넌트 분리 - Super Admin은 `/admin/select-local-government`에서 작업 지자체 선택 +- 지자체관리자는 소속 `mb_lg_idx` 자동 적용 --- -## 주요 URL +## 라우트 구조 -| 경로 | 설명 | 인증 | +### 공개 페이지 + +| 경로 | 설명 | +|------|------| +| `/` | 홈 (비로그인: 환영, 로그인: 대시보드) | +| `/login`, `/logout` | 로그인/로그아웃 | +| `/register` | 회원가입 (역할 승인 플로우) | +| `/dashboard/*` | 대시보드 시안 (classic/modern/dense/charts) | + +### 사이트 메뉴 (`/bag/*`) + +| 경로 | 설명 | 기능 | |------|------|------| -| `/` | 홈 (비로그인 시 환영 화면) | 공개 | -| `/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 | +| `/bag/basic-info` | 기본정보관리 | 코드/단가/포장단위 조회 + 관리 링크 | +| `/bag/purchase-inbound` | 발주 입고 관리 | 발주/입고 목록 + 등록 버튼 | +| `/bag/issue` | 불출 관리 | 불출 목록 + 처리/취소 | +| `/bag/inventory` | 재고 관리 | 봉투별 현재 재고 조회 | +| `/bag/sales` | 판매 관리 | 주문/판매/반품 + 등록 | +| `/bag/sales-stats` | 판매 현황 | 기간별 판매 데이터 | +| `/bag/flow` | 봉투 수불 관리 | 봉투코드별 입출고 수불 요약 | +| `/bag/analytics` | 통계 분석 관리 | Phase 6 예정 | +| `/bag/window` | 창 | Phase 6 예정 | +| `/bag/help` | 도움말 | 시스템 안내 | -정확한 라우트는 `app/Config/Routes.php`를 확인하세요. +### 관리자 (`/admin/*`, adminAuth 필터) + +**시스템 관리** + +| 경로 | 기능 | +|------|------| +| `/admin` | 관리자 대시보드 | +| `/admin/users/*` | 회원 관리 (CRUD) | +| `/admin/access/login-history` | 로그인 이력 | +| `/admin/access/approvals` | 회원 승인 대기 처리 | +| `/admin/roles` | 역할 목록 | +| `/admin/menus/*` | 메뉴 관리 (트리 CRUD) | +| `/admin/local-governments/*` | 지자체 관리 (CRUD) | +| `/admin/select-local-government` | 작업 지자체 선택 (Super Admin) | +| `/admin/password-change` | 비밀번호 변경 | +| `/admin/designated-shops/*` | 지정판매소 관리 (CRUD) | + +**기본정보관리 (Phase 2)** + +| 경로 | 기능 | +|------|------| +| `/admin/code-kinds/*` | 기본코드 종류 (CRUD) | +| `/admin/code-details/*` | 세부코드 (CRUD) | +| `/admin/bag-prices/*` | 봉투 단가 (CRUD + 이력) | +| `/admin/packaging-units/*` | 포장 단위 (CRUD + 이력) | +| `/admin/sales-agencies/*` | 판매 대행소 (CRUD) | +| `/admin/managers/*` | 담당자 (CRUD) | +| `/admin/companies/*` | 업체 (CRUD) | +| `/admin/free-recipients/*` | 무료용 대상자 (CRUD) | + +**발주/입고/재고 (Phase 3)** + +| 경로 | 기능 | +|------|------| +| `/admin/bag-orders/*` | 발주 관리 (등록/상세/취소/삭제) | +| `/admin/bag-receivings/*` | 입고 관리 (등록, 재고 자동 반영) | +| `/admin/bag-inventory` | 재고 현황 조회 | + +**판매/주문/불출 (Phase 4)** + +| 경로 | 기능 | +|------|------| +| `/admin/shop-orders/*` | 주문 접수 (등록/취소) | +| `/admin/bag-sales/*` | 판매/반품 (등록) | +| `/admin/bag-issues/*` | 무료용 불출 (등록/취소, 재고 연동) | + +**리포트 (Phase 5)** + +| 경로 | 기능 | +|------|------| +| `/admin/reports/sales-ledger` | 판매 대장 (일자별/기간별) | +| `/admin/reports/daily-summary` | 일계표 (일계 + 월간 누계) | +| `/admin/reports/period-sales` | 기간별 판매현황 | +| `/admin/reports/supply-demand` | 봉투 수불 현황 | --- -## DB 테이블 +## 모델 (25개) -| 테이블 | 용도 | -|--------|------| -| `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` | 메뉴 항목 (트리 구조, 역할별 노출) | +| 모델 | 테이블 | 용도 | +|------|--------|------| +| MemberModel | member | 회원 계정 | +| MemberLogModel | member_log | 로그인 이력 | +| MemberApprovalRequestModel | member_approval_request | 승인 요청 | +| LocalGovernmentModel | local_government | 지자체 | +| DesignatedShopModel | designated_shop | 지정판매소 | +| MenuModel | menu | 메뉴 항목 | +| MenuTypeModel | menu_type | 메뉴 유형 | +| CodeKindModel | code_kind | 코드 종류 | +| CodeDetailModel | code_detail | 세부코드 | +| BagPriceModel | bag_price | 봉투 단가 | +| BagPriceHistoryModel | bag_price_history | 단가 변경 이력 | +| PackagingUnitModel | packaging_unit | 포장 단위 | +| PackagingUnitHistoryModel | packaging_unit_history | 포장 단위 이력 | +| SalesAgencyModel | sales_agency | 판매 대행소 | +| CompanyModel | company | 업체 | +| ManagerModel | manager | 담당자 | +| FreeRecipientModel | free_recipient | 무료 대상자 | +| BagOrderModel | bag_order | 발주 | +| BagOrderItemModel | bag_order_item | 발주 품목 | +| BagReceivingModel | bag_receiving | 입고 | +| BagInventoryModel | bag_inventory | 재고 | +| BagSaleModel | bag_sale | 판매/반품 | +| ShopOrderModel | shop_order | 주문 접수 | +| ShopOrderItemModel | shop_order_item | 주문 품목 | +| BagIssueModel | bag_issue | 무료 불출 | + +--- + +## 보안 + +| 항목 | 구현 | +|------|------| +| 인증 | 세션 기반 로그인, AdminAuthFilter로 관리자 접근 제어 | +| RBAC | 4단계 역할 (Config\Roles), 메뉴별 역할 노출 | +| PII 암호화 | `pii_encryption_helper` (AES, `ENC:` prefix) - 이메일/전화번호 | +| 비밀번호 | `password_hash()` + `password_verify()` (bcrypt) | +| 로그인 보호 | 5회 실패 시 계정 잠금 (mb_login_fail_count, mb_locked_until) | +| CSRF | CodeIgniter 내장 CSRF 필터 | +| 멀티테넌시 | lg_idx 기반 데이터 격리, 세션에서 테넌트 관리 | + +--- + +## 빠른 시작 + +### 1) 저장소 복제 및 의존성 설치 + +```bash +git clone https://github.com/wixon-associates/jongryangje.git +cd jongryangje +composer install +npm install # Playwright E2E 테스트용 +``` + +### 2) 환경 설정 + +```bash +cp env .env +``` + +`.env`에서 설정: + +| 항목 | 설명 | +|------|------| +| `app.baseURL` | 예: `http://localhost:8045/` | +| `database.default.*` | DB 호스트/DB명/사용자/비밀번호 | +| `encryption.key` | PII 암호화용 64자리 hex | + +### 3) 데이터베이스 준비 + +SQL 스크립트 실행 순서: + +| 순서 | 파일 | 용도 | +|------|------|------| +| 1 | `init_jongryangje_dev.sql` | DB/사용자 생성 | +| 2 | `login_tables.sql` | 회원/로그인/지자체/지정판매소 테이블 | +| 3 | `member_approval_request_add.sql` | 승인 요청 테이블 | +| 4 | `member_login_lock_add.sql` | 로그인 잠금 컬럼 | +| 5 | `menu_tables.sql` | 메뉴 시스템 + 시드 | +| 6 | `menu_type_add_site.sql` | 사이트 메뉴 타입 | +| 7 | `local_government_init_daegu.sql` | 대구 8개 구군 지자체 | +| 8 | `code_master_init_daegu.sql` | 기본코드 마스터 (20종) | +| 9 | `bag_price_tables.sql` | 단가 + 단가 이력 테이블 | +| 10 | `packaging_unit_tables.sql` | 포장 단위 + 이력 테이블 | +| 11 | `sales_agency_tables.sql` | 판매 대행소 테이블 | +| 12 | `manager_tables.sql` | 담당자 테이블 | +| 13 | `company_tables.sql` | 업체 테이블 | +| 14 | `free_recipient_tables.sql` | 무료 대상자 테이블 | +| 15 | `order_tables.sql` | 발주/발주품목 테이블 | +| 16 | `sales_tables.sql` | 판매/입고/재고/불출/주문 테이블 | +| 17 | `seed_test_accounts.sql` | 테스터 계정 4개 | +| 18 | `seed_realistic_data.sql` | 실제형 시범 데이터 | + +### 4) 개발 서버 실행 + +```bash +php spark serve --port=8045 +``` + +### 5) 시드 데이터 (선택) + +```bash +node e2e/helpers/db-seed.js # 테스터 계정 생성 +node e2e/helpers/db-seed-realistic.js # 실제형 시범 데이터 +``` + +--- + +## E2E 테스트 (Playwright) + +```bash +# 전체 테스트 +npm test + +# headed 모드 (브라우저 표시) +npm run test:headed + +# 특정 파일 +npx playwright test e2e/auth.spec.js + +# 특정 테스트 +npx playwright test -g "로그인 페이지" +``` + +### 테스터 계정 (비밀번호: `test1234!`) + +| ID | 역할 | Level | +|----|------|-------| +| `tester_admin` | Super Admin | 4 | +| `tester_local` | 지자체관리자 (중구청) | 3 | +| `tester_shop` | 지정판매소 | 2 | +| `tester_user` | 일반 사용자 | 1 | + +### 테스트 파일 (84개 테스트) + +| 파일 | 테스트 수 | 대상 | +|------|-----------|------| +| auth.spec.js | 9 | 로그인/로그아웃/회원가입 | +| admin.spec.js | 10 | 관리자 패널 접근 | +| public.spec.js | 4 | 공개 페이지 | +| bag-site.spec.js | 11 | 사이트 메뉴 /bag/* | +| code-management.spec.js | 7 | 기본코드 CRUD | +| bag-price.spec.js | 6 | 봉투 단가 | +| packaging-unit.spec.js | 3 | 포장 단위 | +| phase2-entities.spec.js | 8 | 대행소/담당자/업체/무료대상자 | +| phase2-extra.spec.js | 4 | 지자체 수정/비밀번호/로그인 lock | +| phase3-order.spec.js | 8 | 발주/입고/재고 | +| phase4-sales.spec.js | 10 | 주문/판매/불출 | +| phase5-reports.spec.js | 4 | 리포트 | --- ## 기본코드 체계 -개발목록 엑셀의 "기본코드 종류" 시트 기준, A~Y 총 25종의 코드 체계: +A~T 총 20종의 코드 체계 (`code_kind` + `code_detail`): | 코드 | 코드명 | 코드 | 코드명 | |------|--------|------|--------| -| 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 | 수불구분 | | | +| A | 도/특별시/광역시 구분 | K | 반품사유 | +| B | 특별시/광역시/시/군코드 | L | 지정판매소 변경사유 | +| C | 구코드 | M | 수불구분 | +| D | 동코드 | N | 동판종류 | +| E | 봉투구분 | O | 봉투명 (상세 봉투코드) | +| F | 봉투재질 | P | 작업권한 | +| G | 용량별 | Q | 예산과목 | +| H | 무상지급 대상 | R | 은행목록 | +| I | 판매형태 | S | 소속 | +| J | 반품형태 | T | 직위 | --- -## 개발 현황 +## 개발 진행 현황 -### 웹 기능목록 (63개 항목) +### Phase별 완료 현황 -기획 문서(`assets/종량제_개발목록_20260127.xlsx`)의 "웹 기능목록" 시트 기준으로 정리합니다. +| Phase | 내용 | 상태 | +|-------|------|------| +| Phase 1 | 프로젝트 초기 세팅, 로그인/회원가입, RBAC, 멀티테넌시, 메뉴 관리, PII 암호화 | **완료** | +| Phase 2 | 기본정보관리 (코드/단가/포장/대행소/담당자/업체/무료대상자/지자체수정/비밀번호/로그인lock) | **완료** | +| Phase 3 | 발주/입고/재고 (발주등록/LOT/취소/삭제/현황/입고처리/재고현황) | **완료** | +| Phase 4 | 주문/판매/불출 (주문접수/판매/반품/불출처리/취소) | **완료** | +| Phase 5 | 리포트 (판매대장/일계표/기간별현황/수불현황) | **완료** | +| Phase 6 | 모바일앱 + 고급기능 (바코드/통계/엑셀/인쇄) | 대기 | -#### 구현 완료 +### Phase 6 이후 대기 작업 -| 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 수불 -통계 분석 관리 ─ 전년대비, 월별/계절별 추이 분석 -``` +- 지정판매소 다조건 조회 + 엑셀 + 인쇄 + 바코드 출력 +- 지정판매소 지도 표시 / 현황 (신규/취소) +- 카카오 주소 검색 API 연동 +- 년 판매 현황 (월별/분기별) +- 지정판매소별 판매현황 +- 홈택스 세금계산서 엑셀 생성 +- 반품/파기 현황, LOT 수불 조회 +- 바코드 스캐너 연동 (Electron + serialport) +- 실사 선별/등록/조회 +- 페이지네이션/엑셀/인쇄 공통 컴포넌트 +- CRUD 로깅 (전체 데이터 변경 이력) +- 2차 인증 적용 +- 대시보드 실 데이터 연동 +- 모바일앱 (15개 기능) --- -## 개발 진행 요약 +## SQL 스크립트 목록 (writable/database/) -| 구분 | 항목 수 | 완료 | 부분완료 | 미구현 | -|------|---------|------|---------|--------| -| 공통 | 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 로깅 (전체 데이터 변경 이력) -- [ ] 대시보드 실 데이터 연동 +| 파일 | 용도 | +|------|------| +| `init_jongryangje_dev.sql` | DB/사용자 생성 | +| `login_tables.sql` | member, member_log, local_government, designated_shop | +| `member_approval_request_add.sql` | 승인 요청 테이블 | +| `member_login_lock_add.sql` | 로그인 실패 잠금 컬럼 | +| `menu_tables.sql` | menu_type, menu + admin/site 시드 | +| `menu_type_add_site.sql` | 사이트 메뉴 타입 추가 | +| `menu_add_lg_idx.sql` | 메뉴에 지자체 컬럼 추가 | +| `menu_site_seed_from_csv.sql` | 사이트 네비게이션 시드 | +| `local_government_init_daegu.sql` | 대구 8개 구군 지자체 | +| `code_master_init_daegu.sql` | 기본코드 20종 + 세부코드 | +| `bag_price_tables.sql` | bag_price, bag_price_history | +| `packaging_unit_tables.sql` | packaging_unit, packaging_unit_history | +| `sales_agency_tables.sql` | sales_agency | +| `manager_tables.sql` | manager | +| `company_tables.sql` | company | +| `free_recipient_tables.sql` | free_recipient | +| `order_tables.sql` | bag_order, bag_order_item | +| `sales_tables.sql` | bag_sale, bag_receiving, bag_inventory, bag_issue, shop_order, shop_order_item | +| `seed_test_accounts.sql` | 테스터 계정 4개 | +| `seed_realistic_data.sql` | 실제형 시범 데이터 (대구 남구청 기준) | +| `fix_double_encoding.sql` | UTF-8 이중인코딩 수정 |