docs: add project docs and test updates
52
README.md
@@ -213,47 +213,39 @@ assets/ # 기획 문서 (엑셀)
|
||||
| `/admin/menus/*` | 메뉴 관리 (트리 CRUD) |
|
||||
| `/admin/local-governments/*` | 지자체 관리 (CRUD) |
|
||||
| `/admin/select-local-government` | 작업 지자체 선택 (Super Admin) |
|
||||
| `/admin/password-change` | 비밀번호 변경 |
|
||||
| `/admin/designated-shops/*` | 지정판매소 관리 (CRUD) |
|
||||
|
||||
**기본정보관리 (Phase 2)**
|
||||
**기본코드 CRUD만 관리자 경로 (목록·조회는 `/bag/*`)**
|
||||
|
||||
| 경로 | 기능 |
|
||||
|------|------|
|
||||
| `/admin/code-kinds/*` | 기본코드 종류 **CRUD만** (create/edit/store/update/delete; **목록 없음** — 조회는 `/bag/code-kinds`) |
|
||||
| `/admin/code-details/*` | 세부코드 **CRUD만** (**목록 없음** — 조회는 `/bag/code-details/{ck_idx}`) |
|
||||
| (호환) `GET /admin/code-details/{ck_idx}` | `/bag/code-details/{ck_idx}` 로 리다이렉트 |
|
||||
| `/admin/bag-prices/*` | 봉투 단가 (CRUD + 이력) |
|
||||
| `/admin/packaging-units/*` | 포장 단위 (CRUD + 이력) |
|
||||
| `/admin/sales-agencies/*` | 판매 대행소 (CRUD) |
|
||||
| `/admin/managers/*` | 담당자 (CRUD) |
|
||||
| `/admin/companies/*` | 업체 (CRUD) |
|
||||
| `/admin/free-recipients/*` | 무료용 대상자 (CRUD) |
|
||||
|
||||
**발주/입고/재고 (Phase 3)**
|
||||
### 업무 화면 (`/bag/*`, adminAuth 필터)
|
||||
|
||||
동일 `Admin\*` 컨트롤러·뷰를 쓰며 메인 사이트 레이아웃으로 렌더된다. `GET /admin/managers` 등 옛 업무 URL은 `301`·`POST` 는 `307`로 `/bag/...`에 리다이렉트된다.
|
||||
|
||||
| 경로 | 기능 |
|
||||
|------|------|
|
||||
| `/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` | 봉투 수불 현황 |
|
||||
| `/bag/password-change` | 비밀번호 변경 |
|
||||
| `/bag/designated-shops/*` | 지정판매소 관리 (CRUD) |
|
||||
| `/bag/bag-prices/*` | 봉투 단가 (CRUD + 이력) |
|
||||
| `/bag/packaging-units/manage/*` | 포장 단위 (CRUD + 이력; 조회 전용은 `/bag/packaging-units`) |
|
||||
| `/bag/sales-agencies/*` | 판매 대행소 (CRUD) |
|
||||
| `/bag/managers/*` | 담당자 (CRUD) |
|
||||
| `/bag/companies/*` | 업체 (CRUD) |
|
||||
| `/bag/free-recipients/*` | 무료용 대상자 (CRUD) |
|
||||
| `/bag/bag-orders/*` | 발주 관리 (등록/상세/취소/삭제) |
|
||||
| `/bag/bag-receivings/*` | 입고 관리 (등록, 재고 자동 반영) |
|
||||
| `/bag/bag-inventory` | 재고 현황 조회 |
|
||||
| `/bag/shop-orders/*` | 주문 접수 (등록/취소) |
|
||||
| `/bag/bag-sales/*` | 판매/반품 (등록) |
|
||||
| `/bag/bag-issues/*` | 무료용 불출 (등록/취소, 재고 연동) |
|
||||
| `/bag/reports/sales-ledger` | 판매 대장 (일자별/기간별) |
|
||||
| `/bag/reports/daily-summary` | 일계표 (일계 + 월간 누계) |
|
||||
| `/bag/reports/period-sales` | 기간별 판매현황 |
|
||||
| `/bag/reports/supply-demand` | 봉투 수불 현황 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
133
docs/2차인증-TOTP-개발계획.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# 2차 인증(TOTP) 개발 계획
|
||||
|
||||
종량제(쓰레기봉투 물류) 시스템 로그인에 **시간 기반 일회용 암호(TOTP, RFC 6238)** 를 도입하기 위한 계획서입니다.
|
||||
웹 기능 목록(CSV)의 “로그인 2차 인증” 요구에 대응합니다.
|
||||
|
||||
---
|
||||
|
||||
## 1. 목표 및 범위
|
||||
|
||||
| 구분 | 내용 |
|
||||
|------|------|
|
||||
| **목표** | 아이디·비밀번호 이후 **인증 앱(Google/Microsoft Authenticator 등)** 6자리 코드로 2차 검증 |
|
||||
| **범위** | CodeIgniter 4 앱, `session` 기반 로그인(`Auth`), `member` 테이블 |
|
||||
| **비범위(초기)** | SMS/이메일 OTP, WebAuthn, 공동인증서 연동 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 정책(적용 대상)
|
||||
|
||||
- **1차 권장:** 관리자 계정만 TOTP **필수** — `mb_level` 지자체 관리자(3), super admin(4), 본부 관리자(5)
|
||||
- **일반 사용자(1)·지정판매소(2):** 초기에는 **미적용 또는 선택 적용** 검토(지원 부담·UX)
|
||||
- 최종 정책은 보안/감사 요구에 맞춰 `Roles` 또는 설정으로 **한 함수에 모아** 판단 (`needsTotpForMember()` 등)
|
||||
|
||||
---
|
||||
|
||||
## 3. 사용자 흐름
|
||||
|
||||
### 3.1 로그인
|
||||
|
||||
1. 기존과 동일: `login_id`, `password`, 승인 상태 검증
|
||||
2. **TOTP 대상**이고 시크릿이 **등록됨**(`mb_totp_enabled = 1`):
|
||||
- `logged_in` **세팅하지 않음**
|
||||
- 세션에 `pending_2fa`, `pending_mb_idx`, (선택) 만료 시각만 저장
|
||||
- `GET /login/two-factor` 로 이동 → 6자리 입력 → 검증 성공 시 기존과 동일 세션 + `mb_latestdate` 갱신
|
||||
3. **TOTP 대상**인데 **미등록:**
|
||||
- 정책 A: 최초 로그인 시 **시크릿 생성 + QR 표시** → 확인 코드 1회 검증 후 `mb_totp_enabled = 1`
|
||||
- 정책 B: 관리자가 수동으로 등록 유도(별도 화면)
|
||||
|
||||
### 3.2 로그아웃
|
||||
|
||||
- `pending_2fa` 등 임시 키 **반드시 제거**
|
||||
|
||||
### 3.3 인증 앱
|
||||
|
||||
- 표준 TOTP 앱이면 동일 시크릿으로 사용 가능(Google / Microsoft Authenticator 등)
|
||||
|
||||
---
|
||||
|
||||
## 4. 데이터베이스
|
||||
|
||||
`member` 테이블에 컬럼 추가(예시):
|
||||
|
||||
| 컬럼명 | 타입 | 설명 |
|
||||
|--------|------|------|
|
||||
| `mb_totp_secret` | `VARBINARY` 또는 `TEXT` | Base32 시크릿 — **저장 시 암호화** 권장(`encryption.key` 등) |
|
||||
| `mb_totp_enabled` | `TINYINT(1)` | 0=미사용, 1=등록 완료·로그인 시 검증 대상 |
|
||||
|
||||
선택:
|
||||
|
||||
- `mb_totp_enabled_at` — 감사
|
||||
- **백업 코드** — 별도 테이블 또는 컬럼에 **일회용 코드의 해시만** 저장
|
||||
|
||||
DDL은 `writable/database/` 에 `member_add_totp.sql` 등으로 관리 가능.
|
||||
|
||||
---
|
||||
|
||||
## 5. 기술 스택
|
||||
|
||||
- **TOTP 생성·검증:** Composer 패키지 (예: `spomky-labs/otphp` 또는 `robthree/twofactorauth`)
|
||||
- **QR(otpauth URI):** 라이브러리 또는 URL 문자열만 표시 후 앱 수동 입력
|
||||
- **시크릿 보관:** 평문 DB 저장 지양, CI `Encrypter` 또는 기존 PII 암호화 헬퍼와 동일 정책
|
||||
|
||||
---
|
||||
|
||||
## 6. 코드 변경 요약
|
||||
|
||||
| 영역 | 작업 |
|
||||
|------|------|
|
||||
| `app/Config/Routes.php` | `login/two-factor` GET·POST, (선택) `setup` 라우트 |
|
||||
| `app/Controllers/Auth.php` | 로그인 분기, 2단계 검증 액션, 로그아웃 시 pending 제거 |
|
||||
| `app/Models/MemberModel.php` | `allowedFields` 확장 |
|
||||
| 신규 뷰 | `auth/login_two_factor.php`, (선택) `auth/totp_setup.php` |
|
||||
| `app/Config/` | (선택) `Auth.php` 또는 기존 설정에 `requireTotp` 등 |
|
||||
| `app/Filters/` | `pending_2fa` 상태에서는 보호 URL 접근 불가(원칙상 `logged_in` 없음으로 자연 차단, 허용 화이트리스트만 정리) |
|
||||
| `writable/database/*.sql` | 마이그레이션/ALTER |
|
||||
|
||||
기존 `MemberLogModel`에 “2차 성공/실패” 구분 기록 여부 결정.
|
||||
|
||||
---
|
||||
|
||||
## 7. 개발 환경에서 2FA 생략
|
||||
|
||||
- `.env` 예: `auth.requireTotp = false` (로컬만)
|
||||
- 운영/스테이징: `true`
|
||||
- 로직: `비밀번호 검증 성공` 후 `needsTotp && config('Auth')->requireTotp` 일 때만 2단계로 보냄
|
||||
- **운영에 `false`가 배포되지 않도록** CI·배포 체크리스트에 포함
|
||||
|
||||
---
|
||||
|
||||
## 8. 보안·운영
|
||||
|
||||
- TOTP 검증 **실패 횟수 제한** 및 짧은 잠금(브루트포스 방지)
|
||||
- 시간 윈도우: 라이브러리 기본(예: ±1 step) 및 서버 NTP 권장
|
||||
- 기기 분실: **백업 코드** 또는 관리자 **시크릿 재발급(감사 로그)** 절차
|
||||
- `admin_selected_lg_idx` 등 기존 세션은 **2차 완료 후**에만 의미 있게 유지
|
||||
|
||||
---
|
||||
|
||||
## 9. 테스트 시나리오(초안)
|
||||
|
||||
1. TOTP 미등록 관리자 — 등록 플로우 후 로그인 성공
|
||||
2. TOTP 등록 관리자 — 잘못된 코드 거부, 올바른 코드 성공
|
||||
3. 일반 사용자 — 정책에 따라 2단계 생략 확인
|
||||
4. `requireTotp = false` — 개발 모드에서 1단계만으로 `logged_in`
|
||||
5. 로그아웃 — `pending_2fa` 잔존 없음
|
||||
|
||||
---
|
||||
|
||||
## 10. 구현 단계(제안)
|
||||
|
||||
| 단계 | 내용 |
|
||||
|------|------|
|
||||
| **Phase 1** | DB 컬럼, 패키지, 시크릿 생성·저장·검증 유틸, 관리자만 TOTP 필수 |
|
||||
| **Phase 2** | 등록 UI(QR), 백업 코드 또는 재설정 프로세스 |
|
||||
| **Phase 3** | 일반 사용자 확대·정책 조정, 로그/감사 보강 |
|
||||
|
||||
---
|
||||
|
||||
## 11. 참고
|
||||
|
||||
- 역할 상수: `app/Config/Roles.php`
|
||||
- 현재 로그인 완료 지점: `app/Controllers/Auth.php` (세션에 `logged_in` 설정)
|
||||
- 기존 내부 문서는 `docs/` 에 둘 수 있으나 **현재 `.gitignore`에 포함**되어 저장소에는 올라가지 않음. 팀 저장소 공유용으로 본 파일은 `documentation/` 에 둠.
|
||||
30
docs/README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# 종량제 프로젝트 문서 (docs)
|
||||
|
||||
Cursor AI 및 개발자가 **작업 내역·기능 요구사항**을 파악할 수 있도록, CSV로 업로드된 기능 요구사항을 정리한 문서입니다.
|
||||
|
||||
---
|
||||
|
||||
## 문서 목차
|
||||
|
||||
| 파일 | 내용 |
|
||||
|------|------|
|
||||
| **00-project-overview.md** | 프로젝트 개요, 사용자 권한, 문서 구성 |
|
||||
| **01-web-features.md** | 웹 기능 목록 63건 (SFR-PWB-001 ~ 011, 대분류별 요약) |
|
||||
| **02-mobile-features.md** | 모바일앱 기능 목록 15건 (PDF417 스캔·권한별) |
|
||||
| **03-basic-codes.md** | 기본코드 종류 A~Y (지역·봉투·수불·판매 등) |
|
||||
| **04-menu-structure.md** | 전체 메뉴 구조 (1차정리/SMT) |
|
||||
| **05-meeting-notes.md** | 회의 내용 참고 (스캐너·재고·전화접수·단가·바코드 등) |
|
||||
| **06-development-plan.md** | 앞으로의 개발 계획 (단계별 Phase 1~11) |
|
||||
| **07-local-db-setup.md** | 로컬 DB 설정 (MariaDB 설치·DB 생성·.env) |
|
||||
|
||||
---
|
||||
|
||||
## 원본 자료
|
||||
|
||||
- `종량제_개발목록_20260127(웹 기능목록).csv`
|
||||
- `종량제_개발목록_20260127(모바일앱 기능목록).csv`
|
||||
- `종량제_개발목록_20260127(기본코드 종류).csv`
|
||||
- `종량제_개발목록_20260127(전체 메뉴 - 1차정리).csv` / `(전체 메뉴 - SMT).csv`
|
||||
- `종량제_개발목록_20260127(회의 내용 참고).csv`
|
||||
|
||||
위 CSV는 기준일 2024-08-19, 개발목록 기준 2026-01-27 문서를 요약·정리한 것입니다.
|
||||
@@ -57,11 +57,11 @@ Super Admin 전용. 등록된 지자체 목록.
|
||||
### 지자체 등록 (`/admin/local-governments/create`)
|
||||

|
||||
|
||||
### 지정판매소 관리 (`/admin/designated-shops`)
|
||||
### 지정판매소 관리 (`/bag/designated-shops`)
|
||||
현재 지자체 소속 지정판매소 목록.
|
||||

|
||||
|
||||
### 지정판매소 등록 (`/admin/designated-shops/create`)
|
||||
### 지정판매소 등록 (`/bag/designated-shops/create`)
|
||||
판매소번호 자동생성, 상세 정보 입력.
|
||||

|
||||
|
||||
|
||||
244
docs/ai용 개발계획/관리자단_개발_설계.md
Normal file
@@ -0,0 +1,244 @@
|
||||
# 관리자단 기능 개발 설계서
|
||||
|
||||
> 웹 기능목록 CSV(관리자단 PWB-020000) 기준 · Auth 프로젝트와 동일한 방식으로 구현
|
||||
|
||||
**참조 CSV**: `docs/종량제 관련 자료/종량제 개발목록/종량제_개발목록_20260127(웹 기능목록) (1).csv`
|
||||
**참조 구현**: `app/Controllers/Auth.php`, `app/Views/auth/`, `app/Models/MemberModel.php`, `app/Config/Routes.php`
|
||||
|
||||
---
|
||||
|
||||
## 1. Auth 프로젝트 구조 (참조 패턴)
|
||||
|
||||
### 1.1 디렉터리/파일 구조
|
||||
|
||||
```
|
||||
app/
|
||||
├── Controllers/
|
||||
│ └── Auth.php # showLoginForm, login, logout, showRegisterForm, register
|
||||
├── Models/
|
||||
│ ├── MemberModel.php # 회원 CRUD, findByLoginId
|
||||
│ └── MemberLogModel.php # 로그인 이력
|
||||
├── Views/
|
||||
│ └── auth/
|
||||
│ ├── login.php # 로그인 폼
|
||||
│ └── register.php # 회원가입 폼
|
||||
└── Config/
|
||||
└── Routes.php # login, logout, register 라우트
|
||||
```
|
||||
|
||||
### 1.2 네이밍 규칙
|
||||
|
||||
| 구분 | 규칙 | 예시 |
|
||||
|------|------|------|
|
||||
| 컨트롤러 | PascalCase, 단수/역할명 | `Auth`, `Home` |
|
||||
| 메서드 | camelCase, 동사+명사 | `showLoginForm`, `login` |
|
||||
| 뷰 폴더 | 컨트롤러명 소문자 | `auth/`, `home/` |
|
||||
| 뷰 파일 | 소문자+언더스코어 | `login.php`, `register.php` |
|
||||
| 라우트 URI | 소문자, 케밥 또는 경로 | `login`, `logout`, `register` |
|
||||
| 모델 | PascalCase + Model | `MemberModel`, `MemberLogModel` |
|
||||
|
||||
### 1.3 라우트 패턴 (Auth 기준)
|
||||
|
||||
```php
|
||||
// GET = 폼 표시 (showXxxForm 또는 index)
|
||||
// POST = 처리 (login, register)
|
||||
$routes->get('login', 'Auth::showLoginForm');
|
||||
$routes->post('login', 'Auth::login');
|
||||
$routes->get('logout', 'Auth::logout');
|
||||
$routes->get('register', 'Auth::showRegisterForm');
|
||||
$routes->post('register', 'Auth::register');
|
||||
```
|
||||
|
||||
### 1.4 컨트롤러 메서드 패턴
|
||||
|
||||
- **폼 표시**: `showXxxForm()` → `return view('auth/xxx');`
|
||||
- **처리**: `xxx()` → 유효성 검사 → Model 호출 → `redirect()->to(...)->with(...)`
|
||||
- **유효성**: `$this->validate($rules, $messages)` 사용
|
||||
- **에러 시**: `redirect()->back()->withInput()->with('errors', ...)`
|
||||
|
||||
### 1.5 뷰 공통 사항
|
||||
|
||||
- `base_url()`, `csrf_field()`, `esc()`, `old()` 사용
|
||||
- 플래시: `session()->getFlashdata('success')`, `getFlashdata('error')`, `getFlashdata('errors')`
|
||||
|
||||
---
|
||||
|
||||
## 2. 관리자단 기능 목록 (CSV 매핑)
|
||||
|
||||
| No | SFR 2레벨 | SFR 3레벨 | 기능 ID | 기능명 | 비고 |
|
||||
|----|-----------|-----------|---------|--------|------|
|
||||
| 4 | PWB-020100 | PWB-020101 | PWB-020101-001 | 사용자 권한 관리 | 권한 등록/수정/삭제, 역할별 설명 |
|
||||
| 5 | PWB-020200 | PWB-020201 | PWB-020201-001 | 사용자 관리 | 사용자 등록/수정/삭제(삭제상태 5년 유지) |
|
||||
| 6 | PWB-020300 | PWB-020301 | PWB-020301-001 | 사용자 로그인 이력 확인 | 기간 지정 조회 |
|
||||
| 7 | PWB-020300 | PWB-020301 | PWB-020301-001 | 사용자 권한 승인 | 브라우저 회원가입 시 권한 승인 루틴 |
|
||||
| 8 | PWB-020400 | PWB-020401 | PWB-020401-001 | 메뉴 관리 | 메뉴 등록/수정/삭제, "전체 메뉴" 시트 참고 |
|
||||
| 9 | PWB-020400 | PWB-020401 | PWB-020401-001 | 메뉴 별 권한 설정 | 메뉴별 사용자 접근 권한 설정 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 관리자단 구현 설계 (Auth 방식 적용)
|
||||
|
||||
### 3.1 URL/라우트 구조
|
||||
|
||||
관리자 전용 prefix `admin` 사용, 인증 필터 적용 대상.
|
||||
|
||||
```
|
||||
admin/ # 관리자 대시보드 (선택)
|
||||
admin/users # 사용자 관리 목록 (GET)
|
||||
admin/users/create # 사용자 등록 폼 (GET)
|
||||
admin/users/store # 사용자 등록 처리 (POST)
|
||||
admin/users/(:num)/edit # 사용자 수정 폼 (GET)
|
||||
admin/users/(:num)/update # 사용자 수정 처리 (POST)
|
||||
admin/users/(:num)/delete # 사용자 삭제(상태변경) (POST)
|
||||
|
||||
admin/roles # 사용자 권한 관리 (목록/등록/수정/삭제)
|
||||
admin/roles/create
|
||||
admin/roles/store
|
||||
admin/roles/(:num)/edit
|
||||
admin/roles/(:num)/update
|
||||
admin/roles/(:num)/delete
|
||||
|
||||
admin/access # 사용자 접근 관리 (하위: 로그인이력, 권한승인)
|
||||
admin/access/login-history # 로그인 이력 조회 (GET, 기간 조건)
|
||||
admin/access/approvals # 권한 승인 대기 목록 (GET)
|
||||
admin/access/approvals/(:num) # 권한 승인/반려 처리 (POST)
|
||||
|
||||
admin/menus # 메뉴 관리 (목록/등록/수정/삭제)
|
||||
admin/menus/create
|
||||
admin/menus/store
|
||||
admin/menus/(:num)/edit
|
||||
admin/menus/(:num)/update
|
||||
admin/menus/(:num)/delete
|
||||
admin/menus/permissions # 메뉴별 권한 설정
|
||||
```
|
||||
|
||||
### 3.2 컨트롤러 구성 (Auth와 동일 패턴)
|
||||
|
||||
| 컨트롤러 | 파일 | 역할 | 주요 메서드 |
|
||||
|----------|------|------|-------------|
|
||||
| Admin\Dashboard | `Controllers/Admin/Dashboard.php` | 관리자 첫 화면 | `index()` |
|
||||
| Admin\User | `Controllers/Admin/User.php` | 사용자 관리 | `index()`, `create()`, `store()`, `edit($id)`, `update($id)`, `delete($id)` |
|
||||
| Admin\Role | `Controllers/Admin/Role.php` | 사용자 권한 관리 | `index()`, `create()`, `store()`, `edit($id)`, `update($id)`, `delete($id)` |
|
||||
| Admin\Access | `Controllers/Admin/Access.php` | 접근 관리 | `loginHistory()`, `approvals()`, `approve($id)`, `reject($id)` |
|
||||
| Admin\Menu | `Controllers/Admin/Menu.php` | 메뉴 관리 | `index()`, `create()`, `store()`, `edit($id)`, `update($id)`, `delete($id)`, `permissions()` |
|
||||
|
||||
- **목록/폼**: GET → `view('admin/xxx/yyy')`
|
||||
- **저장/수정/삭제**: POST → `validate` → Model → `redirect()->to(...)->with(...)`
|
||||
- **에러**: `redirect()->back()->withInput()->with('errors', ...)` (Auth와 동일)
|
||||
|
||||
### 3.3 모델 구성
|
||||
|
||||
| 모델 | 파일 | 테이블 | 비고 |
|
||||
|------|------|--------|------|
|
||||
| MemberModel | (기존) | member | 사용자 관리에서 재사용 |
|
||||
| MemberLogModel | (기존) | member_log | 로그인 이력에서 재사용 |
|
||||
| RoleModel | `Models/RoleModel.php` | role (신규) | 권한/역할 마스터 |
|
||||
| MenuModel | `Models/MenuModel.php` | menu (신규) | 메뉴 마스터 |
|
||||
| MenuPermissionModel | `Models/MenuPermissionModel.php` | menu_permission (신규) | 메뉴별 권한 |
|
||||
|
||||
- `member.mb_level`은 `Roles` 설정과 연동 유지.
|
||||
- 권한 테이블(role)이 있으면 `member.mb_level`과 매핑 또는 확장.
|
||||
|
||||
### 3.4 뷰 디렉터리 구조
|
||||
|
||||
```
|
||||
app/Views/
|
||||
└── admin/
|
||||
├── layout.php # 관리자 공통 레이아웃 (선택)
|
||||
├── dashboard/
|
||||
│ └── index.php
|
||||
├── user/
|
||||
│ ├── index.php # 목록
|
||||
│ ├── create.php # 등록 폼
|
||||
│ └── edit.php # 수정 폼
|
||||
├── role/
|
||||
│ ├── index.php
|
||||
│ ├── create.php
|
||||
│ └── edit.php
|
||||
├── access/
|
||||
│ ├── login_history.php # 로그인 이력 조회
|
||||
│ └── approvals.php # 권한 승인 목록/처리
|
||||
└── menu/
|
||||
├── index.php
|
||||
├── create.php
|
||||
├── edit.php
|
||||
└── permissions.php # 메뉴별 권한 설정
|
||||
```
|
||||
|
||||
- 공통: `base_url()`, `csrf_field()`, `esc()`, `old()`, 플래시 메시지 (Auth와 동일).
|
||||
|
||||
### 3.5 인증/권한
|
||||
|
||||
- **관리자 구분**: `mb_level`이 `Roles::LEVEL_SUPER_ADMIN` 또는 `LEVEL_LOCAL_ADMIN`인 경우만 `admin/*` 접근 허용.
|
||||
- **필터**: `app/Config/Filters.php`에 `adminAuth` 등 필터 등록 후, `admin/*` before에 적용.
|
||||
- **필터 내부**: `session()->get('logged_in')` 및 `session()->get('mb_level')` 확인 후 미인증/비관리자면 `redirect()->to('login')` 또는 전용 에러 페이지.
|
||||
|
||||
---
|
||||
|
||||
## 4. Routes.php 등록 예시
|
||||
|
||||
```php
|
||||
// 관리자단 (admin prefix, 인증 필터 적용)
|
||||
$routes->group('admin', ['filter' => 'adminAuth'], static function ($routes) {
|
||||
$routes->get('/', 'Admin\Dashboard::index');
|
||||
$routes->get('users', 'Admin\User::index');
|
||||
$routes->get('users/create', 'Admin\User::create');
|
||||
$routes->post('users/store', 'Admin\User::store');
|
||||
$routes->get('users/(:num)/edit', 'Admin\User::edit/$1');
|
||||
$routes->post('users/(:num)/update', 'Admin\User::update/$1');
|
||||
$routes->post('users/(:num)/delete', 'Admin\User::delete/$1');
|
||||
|
||||
$routes->get('roles', 'Admin\Role::index');
|
||||
$routes->get('roles/create', 'Admin\Role::create');
|
||||
$routes->post('roles/store', 'Admin\Role::store');
|
||||
$routes->get('roles/(:num)/edit', 'Admin\Role::edit/$1');
|
||||
$routes->post('roles/(:num)/update', 'Admin\Role::update/$1');
|
||||
$routes->post('roles/(:num)/delete', 'Admin\Role::delete/$1');
|
||||
|
||||
$routes->get('access/login-history', 'Admin\Access::loginHistory');
|
||||
$routes->get('access/approvals', 'Admin\Access::approvals');
|
||||
$routes->post('access/approvals/(:num)', 'Admin\Access::approve/$1');
|
||||
|
||||
$routes->get('menus', 'Admin\Menu::index');
|
||||
$routes->get('menus/create', 'Admin\Menu::create');
|
||||
$routes->post('menus/store', 'Admin\Menu::store');
|
||||
$routes->get('menus/(:num)/edit', 'Admin\Menu::edit/$1');
|
||||
$routes->post('menus/(:num)/update', 'Admin\Menu::update/$1');
|
||||
$routes->post('menus/(:num)/delete', 'Admin\Menu::delete/$1');
|
||||
$routes->get('menus/permissions', 'Admin\Menu::permissions');
|
||||
$routes->post('menus/permissions', 'Admin\Menu::savePermissions');
|
||||
});
|
||||
```
|
||||
|
||||
- `adminAuth`는 별도 필터 클래스에서 로그인 + 관리자 레벨 체크.
|
||||
|
||||
---
|
||||
|
||||
## 5. 구현 순서 제안
|
||||
|
||||
1. **관리자 필터**
|
||||
- `Filters.php`에 `adminAuth` 등록, 필터 클래스에서 `logged_in` + `mb_level` 검사.
|
||||
2. **사용자 관리 (PWB-020201)**
|
||||
- `Admin\User` 컨트롤러, `admin/user` 뷰, 기존 `MemberModel` 활용.
|
||||
- 삭제는 상태값 변경, 5년 유지 정책은 정책/스케줄로 처리.
|
||||
3. **사용자 권한 관리 (PWB-020101)**
|
||||
- `Role` 테이블/모델 정비, `Admin\Role` 컨트롤러·뷰.
|
||||
- `member.mb_level`과 역할 매핑 유지.
|
||||
4. **사용자 접근 관리 (PWB-020301)**
|
||||
- 로그인 이력: `Admin\Access::loginHistory`, 기간 조건, `MemberLogModel` 조회.
|
||||
- 권한 승인: 대기 목록용 테이블/플로우 정한 뒤 `approvals`, `approve`/`reject` 구현.
|
||||
5. **메뉴 관리 (PWB-020401)**
|
||||
- `menu`, `menu_permission` 테이블, `MenuModel`, `MenuPermissionModel`.
|
||||
- `Admin\Menu` CRUD + `permissions`/`savePermissions`.
|
||||
|
||||
---
|
||||
|
||||
## 6. 정리
|
||||
|
||||
- **웹 기능목록 CSV**의 관리자단(No 4~9)을 **Auth와 같은 방식**으로 구현한다.
|
||||
- **컨트롤러**: GET은 폼/목록, POST는 처리; 유효성 검사 후 Model 호출, 실패 시 `redirect()->back()->withInput()->with('errors', ...)`.
|
||||
- **뷰**: `auth`와 동일하게 `base_url()`, `csrf_field()`, `esc()`, `old()`, 플래시 메시지 사용.
|
||||
- **라우트**: `admin` 그룹 + 필터로 인증/권한 통제.
|
||||
- **모델**: 기존 Member/MemberLog 활용하고, 권한·메뉴·메뉴권한은 신규 테이블/모델로 추가.
|
||||
|
||||
이 설계에 따라 단위 기능별로 Controller → Model → View → Route 순으로 구현하면 Auth와 일관된 관리자단을 만들 수 있다.
|
||||
44
docs/portfolio-jongryangje.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# 종량제(Jongryangje) — 포트폴리오 소개
|
||||
|
||||
## 한 줄 요약 (채용 담당자용)
|
||||
|
||||
지자체 **종량제 봉투 유통·재고·매출**을 다루는 **웹 시스템**을 **기획·디자인부터 구현까지** 주도했습니다. 백엔드는 **PHP(CodeIgniter 4)**, **역할·지자체별 데이터 분리**, **보안·자동 테스트**를 전제로 두었고, UI 초안에는 **Stitch**(Google), 개발 보조에는 **Cursor**를 사용했습니다.
|
||||
|
||||
---
|
||||
|
||||
## 프로젝트 소개
|
||||
|
||||
**종량제(Jongryangje)**는 지자체 단위 **봉투 판매·재고·보고**를 한곳에서 처리하는 **관리·조회 웹앱**입니다. 시민·판매소·관리자 등 **역할에 맞는 화면**으로 업무 데이터를 나누고, **지자체별로 데이터 범위를 분리**합니다.
|
||||
|
||||
**세부 기획과 디자인**은 본인이 맡았습니다. 화면 흐름과 정보 구조를 정하고, **Stitch**로 시안·레이아웃을 빠르게 시도한 뒤 실제 화면은 **코드로 맞춰 반영**했습니다.
|
||||
|
||||
**Cursor**로는 구조 파악·반복 코드 초안·디버깅 단서에 시간을 썼고, **권한·민감정보·배포·요구사항 일치**는 **직접 검증**했습니다.
|
||||
|
||||
*(스크린샷 1~2장을 넣으면 좋습니다.)*
|
||||
|
||||
---
|
||||
|
||||
## 프로젝트 하이라이트
|
||||
|
||||
| 초점 | 한 줄 |
|
||||
| --- | --- |
|
||||
| **역할** | 기획·디자인(Stitch)·풀스택 구현·품질 확인까지 **엔드투엔드 소유권**이 있습니다. |
|
||||
| **제품 구조** | **역할별 접근**과 **지자체(테넌트) 단위 분리**를 전제로 설계했습니다. |
|
||||
| **품질·보안** | 민감정보 보호·관리자 통제, **브라우저 자동 테스트(E2E)**로 주요 흐름을 검증합니다. |
|
||||
| **도구** | Stitch·Cursor는 **속도**용이며, **최종 판단과 동작 보증은 본인**이 합니다. |
|
||||
|
||||
---
|
||||
|
||||
## 서비스 범위 (간단히)
|
||||
|
||||
**봉투 입출고·가격·코드 마스터·보고·관리자/현장 화면** 등 **기관 운영에 필요한 기능 묶음**을 웹으로 제공합니다. 세부 메뉴명·화면별 스펙은 포트폴리오 분량에서 생략합니다.
|
||||
|
||||
---
|
||||
|
||||
## 기술·도구 (요약)
|
||||
|
||||
**PHP 8 + CodeIgniter 4**, **MySQL/MariaDB**, 서버 렌더링 기반 화면, **PHPUnit·Playwright** 등으로 테스트합니다. 기획·UI 탐색 **Stitch**, 코딩 보조 **Cursor**.
|
||||
|
||||
---
|
||||
|
||||
*기관명·저장소 링크·캡처는 공개 범위에 맞게 조정하시면 됩니다.*
|
||||
27
docs/개발 규칙/00-README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# 개발 규칙 (Development Rules)
|
||||
|
||||
> **AI 코드 생성 시 반드시 참고**: 본 폴더의 규칙을 따라 Auth 프로젝트와 동일한 스타일로 개발한다.
|
||||
|
||||
## 문서 목록
|
||||
|
||||
| 파일 | 내용 |
|
||||
|------|------|
|
||||
| [01-개발스타일.md](01-개발스타일.md) | 전체 개발 스타일·흐름 (Auth 기준) |
|
||||
| [02-코딩컨벤션.md](02-코딩컨벤션.md) | PHP/네이밍/포맷 규칙 |
|
||||
| [03-파일분리구조.md](03-파일분리구조.md) | Controller / Model / Config 분리 구조 |
|
||||
| [04-CSS정리구조.md](04-CSS정리구조.md) | CSS·Tailwind·커스텀 스타일 정리 |
|
||||
| [05-View정리구조.md](05-View정리구조.md) | 뷰 디렉터리·파일·공통 요소 |
|
||||
| [06-데이터베이스정리구조.md](06-데이터베이스정리구조.md) | 테이블·컬럼·Model 매핑 규칙 |
|
||||
| [07-전체구조.md](07-전체구조.md) | 프로젝트 전체 디렉터리·역할 요약 |
|
||||
| [08-디자인규칙.md](08-디자인규칙.md) | **디자인 기준**·레이아웃·색상·버튼·테이블 (기준: `app/Views/bag/daily_inventory.php`) |
|
||||
|
||||
## 참조 구현 (기준 코드)
|
||||
|
||||
- **Controller**: `app/Controllers/Auth.php`
|
||||
- **Model**: `app/Models/MemberModel.php`, `app/Models/MemberLogModel.php`
|
||||
- **View**: `app/Views/auth/login.php`, `app/Views/auth/register.php`
|
||||
- **디자인 기준 뷰**: `app/Views/bag/daily_inventory.php` (일관된 디자인 시 이 파일 참고)
|
||||
- **Route**: `app/Config/Routes.php`
|
||||
- **Config**: `app/Config/Roles.php`
|
||||
|
||||
새 기능 추가 시 위 파일들의 패턴을 따르고, 본 폴더 규칙과 충돌 시 **본 폴더 규칙을 우선**한다.
|
||||
50
docs/개발 규칙/01-개발스타일.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# 개발 스타일 (Development Style)
|
||||
|
||||
> Auth 프로젝트(`Auth.php`, `auth/login.php`, `MemberModel`)를 기준으로 한 개발 스타일. AI 생성 코드는 이 스타일을 따른다.
|
||||
|
||||
## 1. 요청 흐름
|
||||
|
||||
- **GET**: 폼 표시 또는 목록 조회 → `view('폴더/파일')` 반환.
|
||||
- **POST**: 유효성 검사 → Model 호출 → 성공 시 `redirect()->to(...)->with('success', ...)`, 실패 시 `redirect()->back()->withInput()->with('error'|'errors', ...)`.
|
||||
|
||||
## 2. 컨트롤러 메서드 패턴
|
||||
|
||||
| 용도 | 메서드명 예시 | 동작 |
|
||||
|------|----------------|------|
|
||||
| 폼 표시 | `showLoginForm()`, `create()`, `edit($id)` | `return view('auth/login');` 등 |
|
||||
| 처리 | `login()`, `store()`, `update($id)`, `delete($id)` | `$this->validate()` → Model → `redirect()` |
|
||||
|
||||
- 폼 표시 메서드는 가능하면 `showXxxForm()` 또는 리소스형 `index`, `create`, `edit` 사용.
|
||||
- 처리 메서드는 동사형(`login`, `store`, `update`, `delete`).
|
||||
|
||||
## 3. 유효성 검사
|
||||
|
||||
- 규칙·메시지는 배열로 정의, 한글 메시지 사용.
|
||||
- 실패 시: `redirect()->back()->withInput()->with('errors', $this->validator->getErrors())`.
|
||||
- 단일 에러 메시지는 `with('error', '메시지')`.
|
||||
|
||||
```php
|
||||
$rules = ['login_id' => 'required|max_length[50]', ...];
|
||||
$messages = ['login_id' => ['required' => '아이디를 입력해 주세요.', ...]];
|
||||
if (! $this->validate($rules, $messages)) {
|
||||
return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
|
||||
}
|
||||
```
|
||||
|
||||
## 4. Model 사용
|
||||
|
||||
- `model(MemberModel::class)` 형태로 로드.
|
||||
- 조회·추가·수정·삭제는 Model 메서드에 위임. 컨트롤러에서 직접 쿼리 빌더 노출 최소화.
|
||||
|
||||
## 5. 리다이렉트
|
||||
|
||||
- 성공: `redirect()->to(site_url('/'))->with('success', '...')` 또는 `redirect()->to('login')->with('success', '...')`.
|
||||
- 실패: `redirect()->back()->withInput()->with('error', '...')` 또는 `with('errors', ...)`.
|
||||
- 내부 URL은 `site_url()` 또는 `base_url()` 사용.
|
||||
|
||||
## 6. 뷰 공통
|
||||
|
||||
- 출력 시 `esc()` 사용. 폼에는 `csrf_field()`, `old('필드명')` 사용.
|
||||
- 플래시: `session()->getFlashdata('success')`, `getFlashdata('error')`, `getFlashdata('errors')` 표시.
|
||||
|
||||
이 스타일을 유지하면 Auth와 동일한 톤으로 확장된다.
|
||||
42
docs/개발 규칙/02-코딩컨벤션.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# 코딩 컨벤션 (Coding Convention)
|
||||
|
||||
> PHP 8.2+, CodeIgniter 4 기준. Auth·MemberModel·MemberLogModel 스타일을 따른다.
|
||||
|
||||
## 1. PHP 기본
|
||||
|
||||
- **네임스페이스**: `App\Controllers`, `App\Models`, `Config` 등 CI4 규칙 준수.
|
||||
- **클래스명**: PascalCase. 컨트롤러는 단수/역할명(`Auth`, `Home`). 모델은 `~Model` 접미사(`MemberModel`).
|
||||
- **메서드명**: camelCase. 동사+명사(`showLoginForm`, `findByLoginId`).
|
||||
- **상수**: 클래스 상수는 `UPPER_SNAKE_CASE` (`MB_STATE_NORMAL`, `LEVEL_SUPER_ADMIN`).
|
||||
- **private/protected**: 비공개 로직은 `private` 메서드로 분리(예: `buildLogData`, `insertMemberLog`).
|
||||
|
||||
## 2. 타입·공백
|
||||
|
||||
- 메서드 인자·반환 타입 선언 권장. 예: `function findByLoginId(string $mbId): ?object`, `function buildLogData(string $mbId, ?int $mbIdx): array`.
|
||||
- 연산자·쉼표 뒤 공백. `if (! $this->validate(...))` 처럼 `!` 뒤 공백.
|
||||
- 배열 키·값 정렬 시 화살표 정렬로 가독성 유지(선택).
|
||||
|
||||
## 3. 네이밍 규칙 요약
|
||||
|
||||
| 구분 | 규칙 | 예시 |
|
||||
|------|------|------|
|
||||
| 컨트롤러 | PascalCase, 단수/역할 | `Auth`, `Home`, `Admin\User` |
|
||||
| 메서드 | camelCase | `showLoginForm`, `login`, `create`, `store` |
|
||||
| 뷰 폴더 | 소문자, 컨트롤러 대응 | `auth/`, `home/`, `admin/user/` |
|
||||
| 뷰 파일 | 소문자, 언더스코어 가능 | `login.php`, `register.php`, `daily_inventory.php` |
|
||||
| 라우트 URI | 소문자, 케밥 또는 경로 | `login`, `logout`, `admin/users` |
|
||||
| 모델 | PascalCase + Model | `MemberModel`, `MemberLogModel` |
|
||||
| 테이블 | 소문자, 언더스코어 | `member`, `member_log` |
|
||||
| 테이블 PK | 테이블 약어_idx | `mb_idx`, `mll_idx` |
|
||||
| 테이블 컬럼 | 테이블 약어_컬럼명 | `mb_id`, `mb_name`, `mll_regdate` |
|
||||
|
||||
## 4. 주석
|
||||
|
||||
- 클래스 상단·복잡한 비즈니스 로직에 한글 주석 허용. 예: `/** mb_state: 1=정상, 2=정지, 0=탈퇴 */`.
|
||||
- PHPDoc: `@param`, `@return`, `@var` 등 필요 시 사용.
|
||||
|
||||
## 5. Config 참조
|
||||
|
||||
- 설정은 `config('Roles')`, `config('App')` 등으로 접근. `config('Roles')->getLevelName($level)` 형태 사용.
|
||||
|
||||
이 컨벤션을 지키면 Auth와 동일한 코드 스타일로 유지된다.
|
||||
57
docs/개발 규칙/03-파일분리구조.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# 파일 분리 구조 (File Separation Structure)
|
||||
|
||||
> Auth·Home·Member·MemberLog 기준. 컨트롤러/모델/설정 역할별 분리 규칙.
|
||||
|
||||
## 1. 컨트롤러 (Controllers)
|
||||
|
||||
- **위치**: `app/Controllers/`
|
||||
- **네임스페이스**: `App\Controllers` 또는 서브(예: `App\Controllers\Admin`).
|
||||
- **기준**: `Auth.php` — 로그인/로그아웃/회원가입 등 한 도메인당 한 컨트롤러.
|
||||
- **상속**: `extends BaseController`.
|
||||
- **역할**: 요청 수신 → 유효성 → Model 호출 → view() 또는 redirect(). 비즈니스 로직은 Model·별도 클래스로 분리.
|
||||
|
||||
```
|
||||
app/Controllers/
|
||||
├── BaseController.php # 공통 상속
|
||||
├── Auth.php # 로그인/로그아웃/회원가입
|
||||
├── Home.php # 홈/대시보드
|
||||
└── Admin/ # 관리자단(선택)
|
||||
├── Dashboard.php
|
||||
├── User.php
|
||||
└── ...
|
||||
```
|
||||
|
||||
## 2. 모델 (Models)
|
||||
|
||||
- **위치**: `app/Models/`
|
||||
- **네임스페이스**: `App\Models`
|
||||
- **기준**: `MemberModel.php`, `MemberLogModel.php` — 테이블 1:1, `$table`, `$primaryKey`, `$allowedFields` 정의.
|
||||
- **역할**: DB 접근·조회/추가/수정/삭제. 컨트롤러는 Model 메서드만 호출.
|
||||
|
||||
```
|
||||
app/Models/
|
||||
├── MemberModel.php # member 테이블
|
||||
└── MemberLogModel.php # member_log 테이블
|
||||
```
|
||||
|
||||
## 3. 설정 (Config)
|
||||
|
||||
- **위치**: `app/Config/`
|
||||
- **기준**: `Routes.php`, `Roles.php` — 라우트·역할 등 앱 전역 설정.
|
||||
- **역할**: URL 라우팅, 역할 코드·한글명 매핑 등. 비즈니스 로직은 넣지 않는다.
|
||||
|
||||
```
|
||||
app/Config/
|
||||
├── Routes.php # 라우트 정의
|
||||
├── Roles.php # mb_level 상수·levelNames
|
||||
├── App.php
|
||||
├── Database.php
|
||||
└── ...
|
||||
```
|
||||
|
||||
## 4. 라우트 규칙
|
||||
|
||||
- **GET** = 폼/목록, **POST** = 처리. 같은 URI를 GET/POST로 나누는 패턴 사용(예: `get('login')`, `post('login')`).
|
||||
- 그룹 필요 시 `$routes->group('admin', ['filter' => 'adminAuth'], function ($routes) { ... });` 형태.
|
||||
|
||||
새 기능 추가 시 위 구조에 맞춰 Controller/Model/Config를 분리하고, Auth·Member와 동일한 패턴을 따른다.
|
||||
42
docs/개발 규칙/04-CSS정리구조.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# CSS 정리 구조 (CSS Organization)
|
||||
|
||||
> Auth·일일봉투 수불현황 뷰 기준. Tailwind + 페이지 단위 커스텀 스타일.
|
||||
|
||||
## 1. 기본 원칙
|
||||
|
||||
- **Tailwind CSS**를 메인으로 사용. CDN: `https://cdn.tailwindcss.com?plugins=forms,container-queries`.
|
||||
- **페이지/화면 단위**로 필요한 경우에만 `tailwind.config` 확장(colors, fontFamily 등)과 `<style>` 블록 사용.
|
||||
- 프로젝트 공통 스타일이 있으면 한 곳에 모아서 참조(예: 레이아웃·버튼 클래스).
|
||||
|
||||
## 2. Tailwind 설정 (페이지 내)
|
||||
|
||||
- 뷰 파일 `<head>` 안 `<script>` 에서 `tailwind.config.theme.extend` 로 커스텀 색·폰트 정의.
|
||||
- **Auth(로그인) 예**: `page-bg`, `brand-blue`, `brand-blue-hover`, `text-primary`, `text-secondary`, `input-border`, `fontFamily.sans`, `boxShadow.soft`.
|
||||
- **업무 화면(일일봉투 등) 예**: `system-header`, `title-bar`, `control-panel`, `btn-search`, `btn-excel-border`, `btn-excel-text`, `btn-print-border`, `btn-exit`, `fontSize.xxs`.
|
||||
|
||||
## 3. 커스텀 CSS 블록
|
||||
|
||||
- **용도**: 테이블, 스크롤, 레이아웃 등 Tailwind만으로 표현하기 어려운 부분.
|
||||
- **위치**: 같은 뷰 파일 내 `<style data-purpose="...">` 로 구분. 예: `data-purpose="typography"`, `data-purpose="table-layout"`.
|
||||
- **네이밍**: 클래스명은 소문자·하이픈. 예: `.data-table`, `.main-content-area`. 페이지 특화 클래스는 해당 뷰에만 두기.
|
||||
|
||||
## 4. 폰트
|
||||
|
||||
- **로그인/간단 폼**: Inter 등 (예: Google Fonts `Inter`).
|
||||
- **업무 화면**: `Malgun Gothic`, `Noto Sans KR` 등 (예: `fontFamily.sans` 에 배열로 지정).
|
||||
|
||||
## 5. 반응형·접근성
|
||||
|
||||
- `min-h-screen`, `max-w-[420px]` 등 유틸리티로 레이아웃. 필요 시 `md:` 브레이크포인트 사용.
|
||||
- 포커스 링 등은 Tailwind `focus:`, `focus-visible:` 로 통일.
|
||||
|
||||
## 6. 정리
|
||||
|
||||
| 구분 | 사용처 | 비고 |
|
||||
|------|--------|------|
|
||||
| Tailwind 유틸리티 | 전체 | 기본 스타일 |
|
||||
| tailwind.config.extend | 뷰별 | 색, 폰트, 그림자 등 |
|
||||
| <style> 블록 | 뷰별 | 테이블, 스크롤, 레이아웃 |
|
||||
| data-purpose | <style> | 블록 용도 구분 |
|
||||
|
||||
새 화면 추가 시 기존 Auth·일일봉투 수불현황 뷰의 Tailwind·config·style 구조를 참고해 동일한 방식으로 정리한다. **디자인 일관성**(레이아웃·색상·버튼·테이블)은 [08-디자인규칙.md](08-디자인규칙.md)를 따른다.
|
||||
67
docs/개발 규칙/05-View정리구조.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# View 정리 구조 (View Organization)
|
||||
|
||||
> Auth·Home·bag 뷰 기준. 디렉터리·파일명·공통 요소 규칙.
|
||||
|
||||
## 1. 디렉터리 구조
|
||||
|
||||
- **컨트롤러와 1:1 대응**하는 폴더. 컨트롤러명 소문자 = 뷰 폴더명.
|
||||
- **한글/공백 없음**. 소문자·언더스코어 사용.
|
||||
|
||||
```
|
||||
app/Views/
|
||||
├── auth/ # Auth 컨트롤러
|
||||
│ ├── login.php
|
||||
│ └── register.php
|
||||
├── home/ # Home 컨트롤러
|
||||
│ └── dashboard.php
|
||||
├── bag/ # 업무 화면(뷰만 있을 수 있음)
|
||||
│ └── daily_inventory.php
|
||||
├── admin/ # 관리자단(선택)
|
||||
│ ├── user/
|
||||
│ │ ├── index.php
|
||||
│ │ ├── create.php
|
||||
│ │ └── edit.php
|
||||
│ └── ...
|
||||
└── errors/ # CI4 기본 에러 뷰
|
||||
```
|
||||
|
||||
## 2. 파일명 규칙
|
||||
|
||||
- **소문자**, 단어 구분은 **언더스코어** 가능. 예: `login.php`, `register.php`, `daily_inventory.php`.
|
||||
- **목록**: `index.php`. **폼**: `create.php`(등록), `edit.php`(수정). **기능별**: `login.php`, `login_history.php` 등.
|
||||
|
||||
## 3. 뷰 호출 (컨트롤러)
|
||||
|
||||
- `return view('auth/login');` — 확장자 없음, 경로는 `Views/` 기준 상대 경로.
|
||||
- 서브폴더: `view('admin/user/create')`.
|
||||
|
||||
## 4. 공통 요소 (필수·권장)
|
||||
|
||||
- **출력 이스케이프**: `<?= esc($변수) ?>`, `<?= esc(session()->getFlashdata('success')) ?>`.
|
||||
- **폼**: `action="<?= base_url('login') ?>"`, `method="POST"`, `<?= csrf_field() ?>`.
|
||||
- **입력값 복원**: `value="<?= esc(old('login_id')) ?>"`.
|
||||
- **플래시 메시지**: `success`, `error`, `errors` 표시.
|
||||
|
||||
```php
|
||||
<?php if (session()->getFlashdata('success')): ?>
|
||||
<div class="..."><?= esc(session()->getFlashdata('success')) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (session()->getFlashdata('error')): ?> ... <?php endif; ?>
|
||||
<?php if (session()->getFlashdata('errors')): ?>
|
||||
<?php foreach (session()->getFlashdata('errors') as $error): ?>
|
||||
<p><?= esc($error) ?></p>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
```
|
||||
|
||||
## 5. 레이아웃 (선택)
|
||||
|
||||
- 공통 헤더·푸터가 있으면 레이아웃 뷰를 두고, 각 뷰는 본문만 포함. (현재 Auth·bag은 풀 페이지 HTML.)
|
||||
- 링크: `base_url()`, `base_url('logout')` 등으로 통일.
|
||||
|
||||
## 6. HTML 기본
|
||||
|
||||
- `lang="ko"`, `charset="utf-8"`, viewport 메타.
|
||||
- 제목: `<title>화면명 - 쓰레기봉투 물류시스템</title>` 형태 권장.
|
||||
|
||||
새 뷰 추가 시 `auth/login.php`, `auth/register.php`, `bag/daily_inventory.php` 구조를 참고해 같은 규칙으로 만든다.
|
||||
39
docs/개발 규칙/06-데이터베이스정리구조.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# 데이터베이스 정리 구조 (Database Organization)
|
||||
|
||||
> member, member_log 테이블·MemberModel·MemberLogModel 기준. 테이블·컬럼·Model 매핑 규칙.
|
||||
|
||||
## 1. 테이블 네이밍
|
||||
|
||||
- **소문자**, 단어 구분 **언더스코어**. 예: `member`, `member_log`.
|
||||
- 복수형보다 **단수형** 선호. 예: `member` (회원 테이블).
|
||||
|
||||
## 2. PK·컬럼 네이밍
|
||||
|
||||
- **PK**: `테이블약어_idx`. 예: `mb_idx`(member), `mll_idx`(member_log).
|
||||
- **컬럼**: `테이블약어_컬럼명` 또는 **공통 약어** 유지.
|
||||
- member: `mb_id`, `mb_passwd`, `mb_name`, `mb_email`, `mb_phone`, `mb_lang`, `mb_level`, `mb_group`, `mb_state`, `mb_regdate`, `mb_latestdate`, `mb_leavedate`.
|
||||
- member_log: `mll_success`, `mb_idx`, `mb_id`, `mll_regdate`, `mll_ip`, `mll_msg`, `mll_useragent`, `mll_logout_date`, `mll_url`, `mll_referer` 등.
|
||||
|
||||
## 3. Model 매핑
|
||||
|
||||
- **파일명**: `테이블명을 PascalCase로 + Model`. 예: `member` → `MemberModel.php`, `member_log` → `MemberLogModel.php`.
|
||||
- **클래스**: `$table = 'member'`, `$primaryKey = 'mb_idx'`, `$returnType = 'object'`, `$useTimestamps = false`, `$allowedFields = [...]` 명시.
|
||||
- **역할**: 해당 테이블에 대한 조회·추가·수정·삭제만. 복잡한 비즈니스 로직은 서비스/헬퍼로 분리 가능.
|
||||
|
||||
## 4. 타입·일자
|
||||
|
||||
- **일자/시간**: DB·PHP 모두 `Y-m-d H:i:s` (또는 DB DATETIME) 사용. 예: `mb_regdate`, `mb_latestdate`, `mll_regdate`, `mll_logout_date`.
|
||||
- **상태값**: 숫자 상수 사용. 예: `mb_state` 1=정상, 2=정지, 0=탈퇴. 상수는 컨트롤러 또는 Config에 정의.
|
||||
|
||||
## 5. FK·참조
|
||||
|
||||
- 다른 테이블 PK 참조 시 컬럼명에 **참조 테이블 약어** 사용. 예: `member_log.mb_idx` → member 테이블 PK 참조.
|
||||
- Model에서는 `allowedFields`에 FK 컬럼 포함. 조인 필요 시 메서드에서 처리.
|
||||
|
||||
## 6. 새 테이블 추가 시
|
||||
|
||||
1. 테이블명·PK·컬럼명을 위 규칙으로 정한다.
|
||||
2. `app/Models/` 에 `XxxModel.php` 생성, `$table`, `$primaryKey`, `$allowedFields` 설정.
|
||||
3. 마이그레이션 사용 시 CI4 Migrations 규칙 준수. (현재 프로젝트는 마이그레이션 없이 테이블 직접 생성 가능.)
|
||||
|
||||
이 구조를 따르면 member·member_log와 동일한 네이밍·Model 패턴으로 확장된다.
|
||||
53
docs/개발 규칙/07-전체구조.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# 전체 구조 (Overall Project Structure)
|
||||
|
||||
> 종량제 쓰레기봉투 물류시스템(CodeIgniter 4) 프로젝트 전체 구조. AI 생성 시 이 구조를 유지한다.
|
||||
|
||||
## 1. 프로젝트 루트
|
||||
|
||||
```
|
||||
jongryangje/
|
||||
├── app/
|
||||
│ ├── Config/ # 설정 (Routes, Roles, App, Database 등)
|
||||
│ ├── Controllers/ # 컨트롤러 (Auth, Home, Admin/* 등)
|
||||
│ ├── Models/ # 모델 (MemberModel, MemberLogModel 등)
|
||||
│ ├── Views/ # 뷰 (auth/, home/, bag/, admin/ 등)
|
||||
│ ├── Database/ # 마이그레이션·시더(선택)
|
||||
│ └── ...
|
||||
├── public/ # DOCROOT (index.php, .htaccess)
|
||||
├── writable/ # 로그, 캐시, 세션
|
||||
├── docs/ # 문서 (개발 규칙, ai용 개발계획 등)
|
||||
├── tests/이름의 첫글자, 마지막 글자를 제외한 나머지는 * 로가림
|
||||
- 개인 휴대전화 번호의 중간 번호는 *로 가림
|
||||
└── vendor/
|
||||
```
|
||||
|
||||
## 2. app 디렉터리 역할
|
||||
|
||||
| 디렉터리 | 역할 | 기준 예시 |
|
||||
|----------|------|-----------|
|
||||
| **Config** | 라우트·역할·DB·앱 전역 설정 | Routes.php, Roles.php |
|
||||
| **Controllers** | 요청 처리·유효성·Model 호출·view/redirect | Auth.php, Home.php |
|
||||
| **Models** | 테이블 접근·CRUD·조회 메서드 | MemberModel, MemberLogModel |
|
||||
| **Views** | HTML·폼·플래시 메시지·base_url/csrf_field/esc/old | auth/login.php, bag/daily_inventory.php |
|
||||
|
||||
## 3. 요청 흐름 (전체)
|
||||
|
||||
1. **진입**: `public/index.php` → Boot → Routes.
|
||||
2. **라우트**: `Routes.php`에서 URI → `Controller::method` 매핑.
|
||||
3. **컨트롤러**: BaseController 상속, `validate` → Model → `view()` 또는 `redirect()`.
|
||||
4. **뷰**: `Views/폴더/파일.php` 렌더, `esc()`, `base_url()`, `csrf_field()`, 플래시 표시.
|
||||
5. **모델**: DB 접근, 컨트롤러에서 `model(XxxModel::class)` 호출.
|
||||
|
||||
## 4. 참조 구현 요약
|
||||
|
||||
- **인증**: `Auth::showLoginForm`, `Auth::login`, `Auth::logout`, `auth/login.php`, `auth/register.php`, `MemberModel`, `MemberLogModel`.
|
||||
- **홈**: `Home::index` → 로그인 시 `bag/daily_inventory`, 비로그인 시 `welcome_message`.
|
||||
- **설정**: `Roles.php` — mb_level 상수·levelNames. `Routes.php` — GET/POST 라우트.
|
||||
|
||||
## 5. 문서·규칙 위치
|
||||
|
||||
- **개발 규칙**: `docs/개발 규칙/` (00~07 번호 부여).
|
||||
- **AI용 개발계획**: `docs/ai용 개발계획/` (관리자단 설계 등).
|
||||
- **기본 개발계획**: `docs/기본 개발계획/`.
|
||||
|
||||
새 기능·새 화면 추가 시 위 전체 구조와 `docs/개발 규칙/` 내 규칙을 함께 참고해 Auth와 동일한 스타일로 구현한다.
|
||||
106
docs/개발 규칙/08-디자인규칙.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# 디자인 규칙 (Design Rules)
|
||||
|
||||
> **디자인 기준(Reference)**: `app/Views/bag/daily_inventory.php` (일일 봉투 수불 현황)
|
||||
> 새 화면·뷰는 이 파일과 **일관성 있게** 디자인한다.
|
||||
|
||||
---
|
||||
|
||||
## 1. 기준 뷰
|
||||
|
||||
| 항목 | 값 |
|
||||
|------|-----|
|
||||
| 기준 파일 | `app/Views/bag/daily_inventory.php` |
|
||||
| 화면명 | 일일 봉투 수불 현황 |
|
||||
| 기술 스택 | Tailwind CSS v3 (CDN), Noto Sans KR |
|
||||
|
||||
---
|
||||
|
||||
## 2. 레이아웃 구조
|
||||
|
||||
업무 화면은 아래 순서로 구성한다. (일일 봉투 수불과 동일한 구조 권장)
|
||||
|
||||
| 구역 | 클래스/역할 | 비고 |
|
||||
|------|-------------|------|
|
||||
| **상단 네비** | `header` | 배경 흰색, 하단 보더, h-12, 로고·메뉴·로그아웃(종료) |
|
||||
| **타이틀 바** | `bg-title-bar` | 배경 `#2c3e50`, 흰색 글자, 화면 제목 표시 |
|
||||
| **조건/버튼 패널** | `bg-control-panel` | 배경 `#f8f9fa`, 조회 조건·버튼 영역 |
|
||||
| **본문** | `main` (`.main-content-area`) | 테이블 등 콘텐츠, `height: calc(100vh - 170px)`, overflow auto |
|
||||
| **푸터** | `footer` | 배경 gray-200, 상태/버전/일시 등 |
|
||||
|
||||
- `body`: `flex flex-col h-screen`, 전체 높이 고정·스크롤은 본문만.
|
||||
|
||||
---
|
||||
|
||||
## 3. 색상 (Tailwind config)
|
||||
|
||||
`tailwind.config.theme.extend.colors` 에 아래를 정의하고 사용한다.
|
||||
|
||||
| 이름 | 값 | 용도 |
|
||||
|------|-----|------|
|
||||
| `system-header` | `#ffffff` | 상단 헤더 배경 |
|
||||
| `title-bar` | `#2c3e50` | 타이틀 바 배경 |
|
||||
| `control-panel` | `#f8f9fa` | 조건/버튼 패널 배경 |
|
||||
| `btn-search` | `#1c4e80` | 조회 버튼 배경 |
|
||||
| `btn-excel-border` | `#28a745` | 엑셀 버튼 테두리 |
|
||||
| `btn-excel-text` | `#28a745` | 엑셀 버튼 글자 |
|
||||
| `btn-print-border` | `#ced4da` | 인쇄 버튼 테두리 |
|
||||
| `btn-print-text` | `#000000` | 인쇄 버튼 글자 |
|
||||
| `btn-exit` | `#d9534f` | 종료 버튼 배경 |
|
||||
|
||||
- 링크/강조: `text-gray-600` + `hover:text-blue-600`, 선택 메뉴: `text-blue-700 font-bold border-b-2 border-blue-700`.
|
||||
|
||||
---
|
||||
|
||||
## 4. 폰트
|
||||
|
||||
- **fontFamily.sans**: `'"Malgun Gothic"', '"Noto Sans KR"', 'sans-serif'`
|
||||
- **Google Fonts**: `<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700&display=swap" rel="stylesheet"/>`
|
||||
- 필요 시 `fontSize.xxs` (`0.65rem`) 등 확장 정의.
|
||||
|
||||
---
|
||||
|
||||
## 5. 버튼 스타일
|
||||
|
||||
| 종류 | 클래스 예시 | 용도 |
|
||||
|------|-------------|------|
|
||||
| **조회** | `bg-btn-search text-white px-4 py-1.5 rounded-sm ... shadow hover:opacity-90` | 주 액션(조회·검색) |
|
||||
| **엑셀** | `bg-white text-btn-excel-text border border-btn-excel-border ... hover:bg-green-50` | 보조(엑셀 저장 등) |
|
||||
| **인쇄** | `bg-white text-black border border-btn-print-border ... hover:bg-gray-50` | 보조(인쇄) |
|
||||
| **종료** | `bg-btn-exit text-white ... hover:bg-red-700` | 로그아웃·닫기 |
|
||||
|
||||
- 아이콘은 SVG, `w-4 h-4` 등으로 크기 통일.
|
||||
|
||||
---
|
||||
|
||||
## 6. 테이블
|
||||
|
||||
- **클래스**: `data-table` (커스텀 스타일 블록에서 정의)
|
||||
- **스타일 요약**:
|
||||
- `th`/`td`: border `#ccc`, padding `4px 8px`, font-size `13px`
|
||||
- `th`: 배경 `#e9ecef`, 굵게, 가운데 정렬
|
||||
- 짝수 행: 배경 `#f9f9f9` (zebra)
|
||||
- 행 hover: 배경 `#e6f7ff`
|
||||
- 정렬: `.text-left`, `.text-right`, `.text-center` 활용.
|
||||
|
||||
---
|
||||
|
||||
## 7. 상단 네비·로고
|
||||
|
||||
- **로고**: 파란 사각형(`#2563eb`) 위 흰 사각형 두 개 겹친 SVG (기준 뷰와 동일 형태 권장).
|
||||
- **시스템명**: "쓰레기봉투 물류시스템", `base_url()` 링크.
|
||||
- **메뉴**: `text-sm font-medium text-gray-600`, hover 시 `text-blue-600`, 현재 메뉴는 `text-blue-700 font-bold border-b-2 border-blue-700`.
|
||||
- **종료(로그아웃)**: X 아이콘, `hover:text-red-600`, `base_url('logout')` 링크.
|
||||
|
||||
---
|
||||
|
||||
## 8. 플래시 메시지
|
||||
|
||||
- 성공: `bg-green-50 text-green-700 text-sm`, `rounded-lg`, `p-3`.
|
||||
- 에러: 동일 구조로 `bg-red-50 text-red-700` 등으로 통일.
|
||||
|
||||
---
|
||||
|
||||
## 9. 일관성 원칙
|
||||
|
||||
- 새로 만드는 **업무 화면**(목록·조회·입력 폼 등)은 위 레이아웃·색상·버튼·테이블 규칙을 따르고, `daily_inventory.php`와 **시각적으로 어울리도록** 구성한다.
|
||||
- **Auth(로그인/회원가입)** 등 단순 폼은 기존대로 카드형·Inter 폰트 등 유지해도 되며, 필요 시 본 규칙의 색·버튼만 참고해 통일감을 맞출 수 있다.
|
||||
69
docs/결정_필요한_사항들/01-DB_및_도메인_구조.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# 결정 필요: DB 및 도메인 구조
|
||||
|
||||
> 자료에 **테이블·스키마 정의가 없어** 설계 결정이 필요한 항목.
|
||||
|
||||
---
|
||||
|
||||
## 1. 지자체 저장 방식
|
||||
|
||||
**상황**: 기능목록에는 "지자체별 단가", "지자체별 담당자", "소속 지자체 설정" 등 **지자체 단위** 관리가 나오나, **지자체를 저장하는 테이블/키**에 대한 기술이 없음.
|
||||
|
||||
**결정 필요**:
|
||||
- [ ] **지자체**를 별도 테이블(`local_government` 또는 `organization` 등)로 두고 PK(예: `lg_idx`)로 관리할지, 아니면 **코드(구/군 코드)만** 쓰고 테이블은 두지 않을지.
|
||||
- [ ] 지자체 테이블을 둔다면 **컬럼**: 지자체명, 시/도, 구/군, 사용 여부 등 어떤 항목을 넣을지.
|
||||
- [ ] **다중 지자체**를 한 시스템에서 관리하는지(멀티테넌트), 아니면 **1개 지자체 1 인스턴스**로 배포할지.
|
||||
|
||||
**참고**: 발주·단가·지정판매소 조회 등에서 "구/군 코드", "동 코드"가 등장. 지자체 = 시/도·구/군 레벨로 해석 가능.
|
||||
|
||||
---
|
||||
|
||||
## 2. 지정판매소 테이블 및 지자체 연결
|
||||
|
||||
**상황**: 웹 기능목록에 지정판매소 **등록 항목**(상호명, 사업자번호, 주소, 구코드, 가상계좌 등)은 나오나 **테이블명·전체 컬럼·DDL**은 없음.
|
||||
|
||||
**결정 필요**:
|
||||
- [ ] **테이블명**: 예) `designated_shop`, `shop` 등. PK 컬럼명(예: `ds_idx`, `shop_idx`).
|
||||
- [ ] **지자체(또는 구/군)와의 연결**: 지정판매소가 **어느 지자체(구/군) 소속인지** 저장할 컬럼 — 지자체 PK FK, 또는 구코드/동코드만 저장할지.
|
||||
- [ ] **판매소번호** 규칙: "기본코드 B, C, D + 판매소 일련번호" — 기본코드 B/C/D는 어디서 오는지(기본코드 테이블? 지자체별?).
|
||||
- **결정됨**: **일련번호는 지자체별**로 부여. → [22-판매소번호_일련번호_결정.md](../기본%20개발계획/22-판매소번호_일련번호_결정.md)
|
||||
- [ ] **구코드**: "판매소 주소를 바탕으로 기본코드 C 할당" — 기본코드 테이블이 있는지, 코드 체계(시/도/구/군/동)를 어떻게 저장할지.
|
||||
|
||||
---
|
||||
|
||||
## 3. 사용자(member)와 지자체·지정판매소 연결
|
||||
|
||||
**상황**: 지자체관리자는 "각 지자체에서" 접속, 지정판매소는 "지자체에 주문" — **member가 어느 지자체/지정판매소에 소속되는지** 자료에 명시 없음.
|
||||
|
||||
**결정 필요**:
|
||||
- [ ] **지자체관리자(mb_level=3)**: 담당 **지자체**를 어떻게 저장할지.
|
||||
- 예: `member`에 `mb_lg_idx`(지자체 FK) 추가, 또는 `member.mb_group`에 지자체 코드 저장 등.
|
||||
- [ ] **지정판매소(mb_level=2)**: 담당 **지정판매소** 1개와 1:1 연결할지.
|
||||
- 예: `member`에 `mb_shop_idx`(지정판매소 FK) 추가, 또는 지정판매소 테이블에 `mb_idx`(로그인 회원 FK) 추가.
|
||||
- [ ] **일반 사용자(mb_level=1)**: 지자체/지정판매소 연결 필요 여부(앱 바코드 확인만 쓰는 경우 연결 없을 수 있음).
|
||||
|
||||
---
|
||||
|
||||
## 4. 그 외 엔티티 테이블
|
||||
|
||||
**상황**: 담당자, 업체, 판매 대행소, 무료용 대상자, 발주, 단가, 포장단위 등 **지자체별** 데이터가 나오나, 전부 **테이블 구조 미정**.
|
||||
|
||||
**결정 필요**:
|
||||
- [ ] **담당자**: 테이블 유무, 지자체 FK, 소속 종류(구/군/대행소/제작업체) 저장 방식.
|
||||
- [ ] **업체**(협회, 제작업체, 회수업체): 테이블 1개에 업체종류 구분할지, 테이블 분리할지. 지자체 FK.
|
||||
- [ ] **판매 대행소**: 테이블 정의, "소속 지자체 설정" 시 지자체 FK.
|
||||
- [ ] **발주**: 기능목록의 "발주 저장 테이블 컬럼"을 기준으로 **테이블명·PK·타입** 확정. 구/군 코드·동 코드는 어느 테이블(기본코드?)과 연결할지.
|
||||
- [ ] **단가·포장단위**: "지역별 봉투 코드" — 지역=지자체인지 구/군인지, 봉투 종류 테이블과의 관계.
|
||||
|
||||
---
|
||||
|
||||
## 5. 기본코드(기본코드 종류·세부 코드)
|
||||
|
||||
**상황**: "기본코드 종류" 시트 참고, "세부 기본코드" 시트 참고라고만 되어 있고, **테이블 구조·코드 체계**는 자료에 없음.
|
||||
|
||||
**결정 필요**:
|
||||
- [ ] 기본코드용 테이블 개수(종류 1개 + 세부 1개 등), PK/코드 컬럼 설계.
|
||||
- [ ] 판매소번호·구코드에서 말하는 "기본코드 B, C, D"가 이 테이블과 동일한지, 코드 값 정의 주체(초기 데이터·마이그레이션).
|
||||
|
||||
---
|
||||
|
||||
**정리**: 지자체·지정판매소·사용자 연결·그 외 엔티티·기본코드까지 **DB 구조를 한 번에 설계할지**, 아니면 **기능 단위(예: 지정판매소 관리 먼저)** 로 테이블을 정해 나갈지도 결정이 필요함.
|
||||
53
docs/결정_필요한_사항들/02-사용자_및_수집정보.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# 결정 필요: 사용자 및 수집 정보
|
||||
|
||||
> 회원(사용자) 관련해 **자료에 명시되지 않아 결정이 필요한** 항목.
|
||||
|
||||
---
|
||||
|
||||
## 1. 회원가입 시 수집 항목
|
||||
|
||||
**상황**: 웹 기능목록에는 "사용자 등록/수정/삭제"만 있고, **가입·등록 시 어떤 항목을 필수/선택으로 수집할지** 목록이 없음. 개인정보처리에서는 "이름", "개인 휴대전화" 비식별화 표시만 언급됨.
|
||||
|
||||
**결정 필요**:
|
||||
- [ ] **필수 수집 항목**: 아이디, 비밀번호, 이름 외에 **이메일·전화번호**를 필수로 할지. (현재 구현은 이메일/연락처 선택)
|
||||
- [ ] **지정판매소·지자체관리자** 가입 시 추가 수집 항목: 사업자번호, 소속 지자체/판매소 등 — 회원가입 폼에 넣을지, 승인 후 관리자가 입력할지.
|
||||
- [ ] **개인정보보호법**·내부 정책에 맞는 최소 수집 항목 정리 후, 기능목록·화면에 반영할지.
|
||||
|
||||
**참고**: 지정판매소·담당자·업체의 "등록 항목"은 CSV에 있으나, 이는 **회원(로그인 계정)** 과는 별개 주체일 수 있음. "지정판매소 사용자"가 지정판매소 1곳과 연결되는 구조라면, 회원 수집 항목과 지정판매소 등록 항목을 구분해 정의하는 것이 좋음.
|
||||
|
||||
---
|
||||
|
||||
## 2. 사용자 권한 승인 플로우
|
||||
|
||||
**상황**: "사용자가 브라우저에서 사용자 등록했을 때, 요청 권한을 확인 후 승인하는 루틴 구현" — **어떤 권한을 요청 가능한지, 승인 시 어떤 데이터를 넣는지** 미정.
|
||||
|
||||
**결정 필요**:
|
||||
- [ ] **요청 가능 권한**: 일반(1), 지정판매소(2), 지자체관리자(3) 전부 허용할지. 지정판매소/지자체는 **승인 전용**으로 할지.
|
||||
- [ ] **승인 대기 저장**: 승인 대기 건을 저장할 **테이블** (예: `member_approval_request`) — 저장 필드: 요청자 mb_idx, 요청 mb_level, 요청 시각, 승인/반려 여부, 승인자 등.
|
||||
- [ ] **지정판매소 승인 시**: "어느 지정판매소와 연결할지"를 승인 단계에서 선택하게 할지, 지정판매소는 미리 등록되어 있고 회원가입 시 지정판매소 코드를 입력하게 할지.
|
||||
- [ ] **지자체관리자 승인 시**: 담당 지자체(또는 구/군)를 승인 시 지정할지.
|
||||
|
||||
---
|
||||
|
||||
## 3. 삭제(탈퇴) 후 5년 유지
|
||||
|
||||
**상황**: "삭제 상태로 관리, 5년 유지" — **5년 경과 후 처리**는 기능목록에 없음.
|
||||
|
||||
**결정 필요**:
|
||||
- [ ] 5년이 지난 삭제(탈퇴) 데이터를 **물리 삭제**할지, **별도 아카이브**로 옮길지.
|
||||
- [ ] 5년 정책을 **배치(스케줄)** 로 수행할지, 수동 점검으로 할지.
|
||||
- [ ] "5년" 기준: `mb_leavedate` 기준 5년인지, 별도 정책일지.
|
||||
|
||||
---
|
||||
|
||||
## 4. 로그인 실패 lock·2차 인증
|
||||
|
||||
**상황**: "5회 이상 로그인 실패 시 lock", "2차인증 적용" — **lock 해제 방법, 2차 인증 방식** 미정.
|
||||
|
||||
**결정 필요**:
|
||||
- [ ] **Lock 해제**: 시간 경과(예: 30분) 자동 해제, 관리자만 해제, 비밀번호 찾기로 해제 등.
|
||||
- [ ] **2차 인증**: SMS/이메일 OTP, TOTP(앱), 없음 등. 적용 대상(전체/지자체관리자 이상만 등).
|
||||
|
||||
---
|
||||
|
||||
**정리**: 회원 수집 항목·권한 승인 플로우·5년 유지·로그인 lock/2차인증은 **보안·개인정보·운영**과 직결되므로, 결정 후 개발 규칙·완료된 개발 내역에 반영하는 것이 좋음.
|
||||
74
docs/결정_필요한_사항들/03-기능_명세_보완.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# 결정 필요: 기능 명세 보완
|
||||
|
||||
> 회의 내용 참고·기능목록에서 **"확인 필요"·"조합"·"구청마다"** 등으로 남은 사항.
|
||||
|
||||
---
|
||||
|
||||
## 1. 전화 주문·구청별 기본 단위 (회의 내용 참고)
|
||||
|
||||
**자료**: `종량제_개발목록_20260127(회의 내용 참고).csv`
|
||||
|
||||
- "**주문시 구청마다 기본 단위가 달리 설정** 될 수 있어야 함"
|
||||
- "**조합 방식 확인 필요** - 전화 주문 관리"
|
||||
|
||||
**결정 필요**:
|
||||
- [ ] "기본 단위" 의미: 주문 수량 입력 시 **박스/팩/낱장** 중 기본 선택 단위를 구청(지자체)별로 다르게 둘지.
|
||||
- [ ] 해당 설정을 저장할 **테이블·컬럼**: 지자체(또는 구/군)별 설정 1행에 "기본 주문 단위" 등.
|
||||
- [ ] "조합 방식": 전화 주문과 웹/앱 주문의 **처리 흐름 통합** 여부, 조합(패키지) 상품 존재 여부 등 — 요구사항 구체화 필요.
|
||||
|
||||
---
|
||||
|
||||
## 2. 봉투 단가 (회의 내용 참고)
|
||||
|
||||
- "**봉투단가는 지자체마다 정해져있지는 않음**"
|
||||
- "현재는 구청으로 부터 7원 받음" 등
|
||||
|
||||
**결정 필요**:
|
||||
- [ ] 단가 테이블 구조: **지자체별**로 다를 수 있게 할지, **공통 단가 + 지자체별 오버라이드** 구조로 할지.
|
||||
- [ ] "지자체마다 정해져있지는 않음"을 **기능으로 어떻게 반영**할지(기본 단가만 사용, 지자체별 단가 선택 사용 등).
|
||||
|
||||
---
|
||||
|
||||
## 3. 대행소·권한 (회의·기능목록)
|
||||
|
||||
- "**대행소 : ex 달성군은 읍, 면에서 판매**"
|
||||
- "**권한별 메뉴 접근 제어 필요**"
|
||||
- 재고 현황은 "**로그인 한 구/군과 대행소**의 봉투 및 스티커 종류별 재고량 표시"
|
||||
|
||||
**결정 필요**:
|
||||
- [ ] **대행소**가 지자체(구/군)와 동급인지, 하위인지(구/군 소속 대행소). 재고·판매 단위가 "구/군"과 "대행소" 둘 다 필요한지.
|
||||
- [ ] 메뉴 접근 제어: **메뉴별로** super admin / 지자체관리자 / 지정판매소 / 일반 **노출 여부**를 DB(메뉴·권한 테이블)로 관리할지, 코드로만 제어할지.
|
||||
|
||||
---
|
||||
|
||||
## 4. 접수·배달일·수령 (회의 내용 참고)
|
||||
|
||||
- "**접수는 당일, 배달일은 익일로 표시**"
|
||||
- "**창구 수령인 경우 '수령' 처리** 가능해야함"
|
||||
|
||||
**결정 필요**:
|
||||
- [ ] 주문(전화 접수) 테이블에 **접수일**, **배달일**, **수령 구분**(배달/창구수령) 등 컬럼 정의.
|
||||
- [ ] "수령" 처리 시 재고·정산 반영 방식 일치 여부.
|
||||
|
||||
---
|
||||
|
||||
## 5. 가상계좌·입금 조회 (회의·기능목록)
|
||||
|
||||
- "**가상계좌 입금 실시간 조회** 가능해야함 - **헥토파이낸셜 연계?**"
|
||||
- 지정판매소마다 할당된 가상계좌 표시
|
||||
|
||||
**결정 필요**:
|
||||
- [ ] 가상계좌·입금 조회를 **헥토파이낸셜(또는 특정 PG사)** API로 할지, 수동 입력만 할지.
|
||||
- [ ] 가상계좌를 **지정판매소별**로 저장할지(기능목록에는 "지정판매소마다 할당된 가상계좌"로 나옴).
|
||||
|
||||
---
|
||||
|
||||
## 6. 기타
|
||||
|
||||
- **무료용 불출**: "구청 있는 구청 없는 구청 있기 때문에 구분 필요" — 구청 유무에 따른 **화면/프로세스 분기** 정의 필요.
|
||||
- **인쇄 시 결재란**: "인쇄 시 결재란 출력되어야 함" — 어떤 메뉴/리포트에 적용할지, 레이아웃 정의.
|
||||
- **블록 해싱·블록 저장**: 발주에 "블록 해싱값", "블록에는 … 저장" — **블록**을 별도 테이블로 둘지, 발주 테이블 컬럼만으로 둘지, Phase 1에서 제외할지.
|
||||
|
||||
---
|
||||
|
||||
**정리**: 위 항목은 **업무·정책·외부 연동** 쪽 결정이 필요하므로, 실무·발주처와 정리 후 기능 명세·DB 설계에 반영하는 것이 좋음.
|
||||
22
docs/결정_필요한_사항들/README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# 결정 필요한 사항들
|
||||
|
||||
> 종량제 관련 자료·기능목록에서 **명확하지 않아 결정이 필요한 항목** 정리. 확정 후 개발·DB 설계에 반영.
|
||||
|
||||
---
|
||||
|
||||
## 문서 목록
|
||||
|
||||
| 파일 | 분류 | 요약 |
|
||||
|------|------|------|
|
||||
| [01-DB_및_도메인_구조.md](01-DB_및_도메인_구조.md) | DB·도메인 | 지자체/지정판매소/사용자 저장 구조, 테이블 설계 |
|
||||
| [02-사용자_및_수집정보.md](02-사용자_및_수집정보.md) | 회원·개인정보 | 회원 수집 항목, 권한 승인 플로우 |
|
||||
| [03-기능_명세_보완.md](03-기능_명세_보완.md) | 기능·업무 | 회의 참고 사항, 구청별 단위·조합 방식 등 |
|
||||
|
||||
---
|
||||
|
||||
## 참조 자료
|
||||
|
||||
- `docs/종량제 관련 자료/종량제 개발목록/종량제_개발목록_20260127(웹 기능목록) (1).csv`
|
||||
- `docs/종량제 관련 자료/종량제 개발목록/종량제_개발목록_20260127(회의 내용 참고).csv`
|
||||
- `docs/개발 규칙/06-데이터베이스정리구조.md`
|
||||
- `writable/database/login_tables.sql` (현재 정의된 테이블: member, member_log만 존재)
|
||||
1
docs/기본 개발계획/.gitkeep
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
33
docs/기본 개발계획/00-project-overview.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# 종량제 프로젝트 개요
|
||||
|
||||
CSV 기반 기능 요구사항 정리 문서입니다. 기준일: 2024-08-19, 개발목록 기준: 2026-01-27.
|
||||
|
||||
---
|
||||
|
||||
## 1. 프로젝트 목적
|
||||
|
||||
**종량제 봉투·스티커 관리 시스템**
|
||||
지자체(구청/군)·대행소·지정판매소가 **종량제 봉투·음식물 스티커**의 발주·입고·불출·재고·판매·수불을 관리하는 **웹 + 모바일앱** 프로젝트.
|
||||
|
||||
---
|
||||
|
||||
## 2. 사용자 권한
|
||||
|
||||
| 권한 | 대상 | 용도 |
|
||||
|------|------|------|
|
||||
| **super admin** | wixon / 서진 | 전 영역 관리 |
|
||||
| **지자체관리자** | 구청 등 | 발주, 단가·포장단위·대행소 등 기본정보 입력·관리 |
|
||||
| **지정판매소** | 판매소 | 웹/앱으로 봉투·스티커 주문·주문 내역 확인 |
|
||||
| **일반 사용자** | 시민 | 앱으로 바코드(정품) 확인 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 문서 구성
|
||||
|
||||
- `01-web-features.md` — 웹 기능 목록 (63건, SFR-PWB-001 ~ 011)
|
||||
- `02-mobile-features.md` — 모바일앱 기능 목록 (15건)
|
||||
- `03-basic-codes.md` — 기본코드 종류 (A~Y)
|
||||
- `04-menu-structure.md` — 전체 메뉴 구조 (1차정리)
|
||||
- `05-meeting-notes.md` — 회의 내용 참고
|
||||
|
||||
원본 CSV는 `종량제_개발목록_20260127(*).csv` 시트들 기준으로 정리됨.
|
||||
132
docs/기본 개발계획/01-web-features.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# 웹 기능 목록 (Web application)
|
||||
|
||||
총 **63건**, SFR-PWB-001 ~ SFR-PWB-011. 프로세스 ID 형식: PWB-대분류5자리(예: PWB-010000).
|
||||
|
||||
---
|
||||
|
||||
## PWB-010000 공통 (SFR-PWB-001)
|
||||
|
||||
| No | 3 Level | 4 Level / ID | 요약 |
|
||||
|----|---------|--------------|------|
|
||||
| 1 | 작업이력 추적 / 로깅 | PWB-010101-001 | DB CRUD 로깅 |
|
||||
| 2 | 개인정보처리 / 비식별화 | PWB-010201-001 | 이름·휴대전화 가림 |
|
||||
| 3 | 로그인 | PWB-010301-001 | 2차인증, 5회 실패 시 lock |
|
||||
|
||||
---
|
||||
|
||||
## PWB-020000 관리자단 (SFR-PWB-002)
|
||||
|
||||
| No | 3 Level | 4 Level / ID | 요약 |
|
||||
|----|---------|--------------|------|
|
||||
| 4 | 사용자 권한 관리 | PWB-020101-001 | 권한 등록/수정/삭제, super admin·지자체·지정판매소·일반 사용자 구분 |
|
||||
| 5 | 사용자 관리 | PWB-020201-001 | 사용자 등록/수정/삭제(삭제 상태 5년 유지) |
|
||||
| 6 | 사용자 접근 관리 / 로그인 이력 | PWB-020301-001 | 로그인 이력 조회(기간 지정) |
|
||||
| 7 | 사용자 접근 관리 / 권한 승인 | PWB-020301-001 | 브라우저 사용자 등록 시 권한 승인 루틴 |
|
||||
| 8 | 메뉴 관리 | PWB-020401-001 | 메뉴 등록/수정/삭제(전체 메뉴 시트 참고) |
|
||||
| 9 | 메뉴 별 권한 설정 | PWB-020401-001 | 메뉴별 사용자 접근 권한 |
|
||||
|
||||
---
|
||||
|
||||
## PWB-030000 기본정보관리 (SFR-PWB-003)
|
||||
|
||||
| No | 3 Level | 4 Level / ID | 요약 |
|
||||
|----|---------|--------------|------|
|
||||
| 10 | 기본코드관리 / 종류 | PWB-030101-001 | 기본 코드 종류 등록/수정/삭제 |
|
||||
| 11 | 기본코드관리 / 세부코드 | PWB-030101-001 | 종류별 하위 세부 코드 등록/수정/삭제 |
|
||||
| 12 | 단가 관리 | PWB-030201-001 | 지자체별 봉투 종류별 단가, YYYY-MM-DD 적용일, 변경 이력 저장 |
|
||||
| 13 | 단가관리 / 조회 | PWB-030301-001 | 기간별 단가 조회/인쇄 |
|
||||
| 14 | 포장 단위 관리 | PWB-030401-001 | 박스당 팩·팩당 낱장·총 수량·유효기간, 적용일·이력 |
|
||||
| 15 | 포장 단위 조회 | PWB-030401-001 | 기간별 포장단위 조회/인쇄 |
|
||||
| 16~18 | 판매 대행소 관리 | PWB-030501-001 | 대행소 등록/수정/삭제, 지자체 연결, 조회/인쇄 |
|
||||
| 19~20 | 담당자 관리 | PWB-030601-001, 002 | 소속·담당자명·전화 등록/조회, 구/군/대행소/제작업체 구분 |
|
||||
| 21~22 | 업체 관리 | PWB-030701-001 | 협회·제작업체·회수업체 등록/조회/인쇄 |
|
||||
| 23~24 | 무료용 대상자 관리 | PWB-030801-001 | 읍면동/무료대상자/기타, 종료일·비고·상태(정상/삭제) |
|
||||
| 25~29 | 지정판매소 관리·조회·현황 | PWB-030901-001 | 리스트·상세·등록/수정/삭제·지도·조회·엑셀·인쇄·바코드 출력·신규/취소 현황 |
|
||||
| 29 | PASSWORD 변경 | PWB-031001-001 | 로그인 사용자 비밀번호 변경 |
|
||||
|
||||
---
|
||||
|
||||
## PWB-040000 발주 입고 관리 (SFR-PWB-004)
|
||||
|
||||
| No | 3 Level | 4 Level / ID | 요약 |
|
||||
|----|---------|--------------|------|
|
||||
| 30 | 발주 등록 | PWB-040101-001 | 발주 이력·form·단가표, UUID·SHA-256·LOT·블록 저장 |
|
||||
| 31 | LOT·바코드 생성 | PWB-040101-001 | AES-256·RSA, PDF417 박스/팩/낱장 |
|
||||
| 32 | 발주 변경 | PWB-040201-001 | 버전+1 insert, SHA-256, 블록에 수정 전/후 해시 |
|
||||
| 33 | 발주 삭제 | PWB-040301-001 | 상태 삭제로 변경 |
|
||||
| 34 | 발주 현황 | PWB-040401-001 | 기간·제작업체·품명·입고처 조회, 엑셀·인쇄 |
|
||||
| 35~38 | 발주 입고 | PWB-040501-001 | 바코드스캐너 연동(serialport), 스캐너 입고·일괄 입고·입고 현황 |
|
||||
|
||||
---
|
||||
|
||||
## PWB-050000 불출 관리 (SFR-PWB-005)
|
||||
|
||||
| No | 3 Level | 4 Level / ID | 요약 |
|
||||
|----|---------|--------------|------|
|
||||
| 39 | 무료용 불출 현황 조회 | PWB-050101-001 | 기간별 무료용 봉투별 불출 현황 |
|
||||
| 40 | 무료용 불출 처리 | PWB-050201-001 | 년도·분기·불출일·불출처·봉투코드·저장, 재고 감산·판매 처리 |
|
||||
| 41 | 무료용 불출 취소 | PWB-050301-001 | 취소 수량 저장·재고 합산·판매 취소 or 재입고(T.B.D) |
|
||||
|
||||
---
|
||||
|
||||
## PWB-060000 재고 관리 (SFR-PWB-006)
|
||||
|
||||
| No | 3 Level | 4 Level / ID | 요약 |
|
||||
|----|---------|--------------|------|
|
||||
| 42 | 재고 조회 | PWB-060101-001 | 기준일·구/군·대행소별 봉투·스티커 재고, 엑셀·인쇄(결재란) |
|
||||
|
||||
---
|
||||
|
||||
## PWB-070000 실사 관리 (SFR-PWB-007)
|
||||
|
||||
| No | 3 Level | 4 Level / ID | 요약 |
|
||||
|----|---------|--------------|------|
|
||||
| 43 | 실사 선별 | PWB-070101-001 | 봉투·스티커 checkbox, 전산 선별 실행 confirm |
|
||||
| 44 | 실사 선별 조회 | PWB-070101-001 | 기간·품목·박스/팩, 전체 리스트·박스 정보·낱장 정보 |
|
||||
|
||||
---
|
||||
|
||||
## PWB-080000 주문·판매 관리 (SFR-PWB-008)
|
||||
|
||||
| No | 3 Level | 4 Level / ID | 요약 |
|
||||
|----|---------|--------------|------|
|
||||
| 45 | 주문 접수 관리 메인 | PWB-080101-001 | 전화 주문 접수 내역, 배달일자·인쇄(집계·영수증·list) |
|
||||
| 46 | 전화 주문 접수 | PWB-080101-001 | 판매소 검색(SLOW 자동완성), 접수번호·가상계좌·주문접수표·저장 |
|
||||
| 47 | 전화 접수 수정/취소 | PWB-080101-001 | 접수량 변경·주문 수정 저장·주문 취소(STATUS) |
|
||||
| 48 | 지정 판매소 판매 | PWB-080101-001 | 판매소 검색·봉투코드·바코드 스캔·판매 저장 |
|
||||
| 49 | 지정 판매소 판매 취소 | PWB-080201-001 | 판매일·취소 checkbox·품목/봉투코드별 취소 |
|
||||
| 50 | 지정 판매소 반품 | PWB-080301-001 | 판매소·봉투코드 스캔·반품 저장 |
|
||||
| 51 | 지정 판매소 반품 취소 | PWB-080301-001 | 반품 일자 조회·취소 선택·반품 취소 저장 |
|
||||
|
||||
---
|
||||
|
||||
## PWB-090000 판매 현황 (SFR-PWB-009)
|
||||
|
||||
| No | 3 Level | 4 Level / ID | 요약 |
|
||||
|----|---------|--------------|------|
|
||||
| 52 | 지정 판매소 판매 대장 | PWB-090101-001 | 기간·일자별/기간별·엑셀·인쇄(결재란) |
|
||||
| 53 | 일계표 | PWB-090201-001 | 특정일 일계·누계(월간) |
|
||||
| 54 | 기간별 판매현황 | PWB-090301-001 | 일자별/기간별 판매·반품·합계 |
|
||||
| 55 | 년 판매 현황 | PWB-090401-001 | 년도·품목별·월/분기 |
|
||||
| 56 | 지정 판매소 별 판매 현황 | PWB-090501-001 | 수량/금액·1~12월 컬럼 |
|
||||
| 57 | 홈택스 처리 | PWB-090601-001 | 세금계산서 일괄발급 엑셀 양식 |
|
||||
|
||||
---
|
||||
|
||||
## PWB-100000 봉투 수불 관리 (SFR-PWB-010)
|
||||
|
||||
| No | 3 Level | 4 Level / ID | 요약 |
|
||||
|----|---------|--------------|------|
|
||||
| 58 | 기타 입출고 | PWB-100101-001 | 수불 년월·봉투코드·구분·상세 확인 필요 |
|
||||
| 59 | 봉투 수불 현황 | PWB-100201-001 | 기간·품목·대행소·일자별/기간별·전일재고·입고/출고·잔량 |
|
||||
| 60 | 반품/파기 현황 | PWB-100301-001 | 기간·입출고 구분·조회/엑셀/인쇄 |
|
||||
| 61 | 봉투 수급 계획 | PWB-100401-001 | 기능 추가 확인 필요 |
|
||||
| 62 | LOT 수불 조회 | PWB-100501-001 | 바코드/봉투번호 입력·일자·입고출처·구분 |
|
||||
|
||||
---
|
||||
|
||||
## PWB-110000 봉투 스캔 현황 (SFR-PWB-011)
|
||||
|
||||
| No | 3 Level | 4 Level / ID | 요약 |
|
||||
|----|---------|--------------|------|
|
||||
| 63 | 봉투 스캔 횟수/위치 조회 | PWB-110101-001 | 낱장별 앱 스캔 횟수·경위도·지도 표시(옵션) |
|
||||
53
docs/기본 개발계획/02-mobile-features.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# 모바일앱 기능 목록 (Mobile App)
|
||||
|
||||
총 **15건**. PDF417 카메라 스캔·상하 2분할 화면이 공통 패턴. 권한: super admin·지자체 담당자 또는 지정판매소 담당자.
|
||||
|
||||
---
|
||||
|
||||
## 공통 (SFR-PWB-001, PWB-010000)
|
||||
|
||||
| No | 3 Level | 4 Level | 요약 |
|
||||
|----|---------|---------|------|
|
||||
| 1 | 작업이력 추적 / 로깅 | PWB-010101-001 | DB CRUD 로깅 |
|
||||
| 2 | 개인정보처리 / 비식별화 | PWB-010201-001 | 이름·휴대전화 가림 |
|
||||
| 3 | 로그인 | PWB-010301-001 | 2차인증, 5회 실패 시 lock |
|
||||
|
||||
---
|
||||
|
||||
## 발주 입고 관리 (PWB-020000)
|
||||
|
||||
| No | 3 Level | 4 Level | 요약 |
|
||||
|----|---------|---------|------|
|
||||
| 4 | 발주 입고 관리 / 발주 입고 처리 | PWB-020101-001 | super admin·지자체 담당자. 상단: 구/군 발주 이력·발주 내역 / 하단: PDF417 스캐너 연속 스캔. 바코드→LOT 매칭 입고량 가산. "저장" 터치로 입고 처리 |
|
||||
|
||||
---
|
||||
|
||||
## 불출 관리 (PWB-020000)
|
||||
|
||||
| No | 3 Level | 4 Level | 요약 |
|
||||
|----|---------|---------|------|
|
||||
| 5 | 불출 관리 / 무료용·공공용 불출 | PWB-020101-001 | 년도·분기·불출일·불출처(동) 설정 후 봉투코드 지정·저장. 하단 스캐너로 불출 대상 봉투 지정 |
|
||||
| 6 | 불출 관리 / 무료용·공공용 불출 취소 | PWB-020101-001 | 동일 화면 구성, 바코드 스캔으로 불출 취소 처리 |
|
||||
|
||||
---
|
||||
|
||||
## 판매 관리 (PWB-020000, PWB-030000)
|
||||
|
||||
| No | 3 Level | 4 Level | 요약 |
|
||||
|----|---------|---------|------|
|
||||
| 7 | 지정 판매소 판매 / 판매 처리 | PWB-020101-001 | 상단: 판매 대상 지정판매소 / 하단: 스캐너. 바코드로 품목 등록·"저장" 터치로 판매 처리 |
|
||||
| 8 | 지정 판매소 판매 / 판매 취소 | PWB-020101-001 | 지정판매소·판매이력 확인, 스캔으로 판매 취소할 품목 등록·저장 |
|
||||
| 9 | 지정 판매소 반품 / 반품 처리 | PWB-020201-001 | 지정판매소·판매 이력, 스캔으로 반품 대상 등록·저장 |
|
||||
| 10 | 지정 판매소 반품 / 반품 취소 | PWB-020201-001 | 반품 이력 확인, 스캔으로 반품 취소 대상 등록·저장 |
|
||||
|
||||
---
|
||||
|
||||
## 봉투 수불·주문·정품 인증 (PWB-030000)
|
||||
|
||||
| No | 3 Level | 4 Level | 요약 |
|
||||
|----|---------|---------|------|
|
||||
| 11 | 봉투 수불 관리 / LOT 수불 조회 | PWB-030101-001 | 상단: 입고 출처·일자 세부 / 하단: 스캐너. 바코드로 해당 봉투 내역 확인 |
|
||||
| 12 | 봉투 주문 관리 / 주문 내역 | PWB-030101-001 | **지정판매소 담당자**. 기간 지정·해당 지정판매소 주문 이력 확인 |
|
||||
| 13 | 봉투 주문 관리 / 봉투 주문 | PWB-030101-001 | 봉투 종류별 수량 입력→종류별 금액·총 합계·전용 가상계좌 표시. "저장" 터치로 주문 저장 |
|
||||
| 14 | 봉투 주문 관리 / 주문 수정·취소 | PWB-030101-001 | 이력 목록에서 수정/취소 대상 터치→수량 수정 또는 주문 취소 |
|
||||
| 15 | 봉투 정품 인증 | PWB-030101-001 | **모든 권한**. PDF417 스캐너·스캔 후 코드 번호 표시·해당 봉투 스캔 횟수 +1 |
|
||||
57
docs/기본 개발계획/03-basic-codes.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# 기본코드 종류 (기본 코드 종류 시트)
|
||||
|
||||
지역·봉투·수불·판매 등에 쓰이는 **기본 코드 종류(A~Y)** 와 세부코드 예시.
|
||||
|
||||
---
|
||||
|
||||
## 지역·행정 코드
|
||||
|
||||
| 코드 | 코드 명 | 비고 |
|
||||
|------|---------|------|
|
||||
| A | 도/특별시/광역시 구분 | 10 특별시, 11 광역시, 20 경기도 … |
|
||||
| B | 특별시/광역시/시/군코드 | 1001 서울, 1101 부산, 1102 대구 … |
|
||||
| C | 구코드 | 코드 B + 구 순번 2자리 |
|
||||
| D | 동코드 | 코드 C + 동 순번 2자리 (예: 11020901 검단동) |
|
||||
|
||||
---
|
||||
|
||||
## 봉투·용도·판매 구분
|
||||
|
||||
| 코드 | 코드 명 | 세부 예시 |
|
||||
|------|---------|-----------|
|
||||
| E | 봉투구분 | 10 일반용, 20 공공용, 30 무료용, 40 공동주택용, 50 재사용, 60 음식물 봉투, 61 음식물 스티커, 62 음식물 용기, 70 대형폐기물 스티커 |
|
||||
| F | 봉투재질 | 2 고밀도, 6 PP마대, 7 스티커, 8 용기 … |
|
||||
| G | 용량별 | 10 2L, 11 3L, 12 5L, 13 10L, 15 20L, 16 30L, 17 50L, 18 60L, 19 75L, 20 100L, 21 120L, 70 1000원, 72 3000원, 74 5000원, 77 8000원, 78 10000원 |
|
||||
| H | 무상지급 | 1 시설보호대상자, 10 생보자, 2 통·반장, 3 대한민국무공수훈자, 4 사회복지시설 |
|
||||
| I | 판매형태 | 1 무상지급, 2 일반판매, 3 관내판매, 4 교환판매 |
|
||||
|
||||
---
|
||||
|
||||
## 반품·수불·기타
|
||||
|
||||
| 코드 | 코드 명 | 세부 예시 |
|
||||
|------|---------|-----------|
|
||||
| J | 반품형태 | 1 일반반품, 2 관내반품, 3 반품 |
|
||||
| K | 반품사유 | 1 봉투훼손, 2 지정판매소 폐업, 4 스티커 미사용 |
|
||||
| L | 지정판매소 변경사유 | 1, 2 … |
|
||||
| M | 수불구분 | 10 실사입고, 11 신청입고, 12 무료입고, 13 발주입고, 16 반품입고(정상), 17 반품입고(불용), 18 이동입고, 1A 교환입고, 1B 기타입고, 20 실사출고, 21 신청불출, 22 무료불출, 23 일반판매, 24 공공출고, 26 반품출고(정상), 27 반품출고(불용), 28 이동출고, 29 파기처리, 2A 교환출고, 2B 기타출고, 99 시찰 |
|
||||
| N | 동판종류 | 10, 20 … |
|
||||
| O | 봉투명 | 10112 일반용 3L, 10122 일반용 5L, 10132 일반용 10L, … 60102 음식물 2L, 61107 음식물 스티커 2L, 70707 폐기물 스티커 1,000원 등 |
|
||||
| P | 작업권한 | 111 등록-다시 … |
|
||||
| Q | 예산과목 | 1000 관, 1001 보건및생활환경개선비, 2000 항, 2010 환경관리 |
|
||||
| R | 은행목록 | 4 국민은행, 7 수협, 20 우리은행, 32 부산은행, 99 새마을금고 |
|
||||
| S | 소속 | 1 청소과, 2 청소행정과, 3 자원순환과 … |
|
||||
| T | 직위 | 1 7급, 2 8급, … 7 사장, 8 상무 |
|
||||
| U | 배달 | 1 월 … 7 일 |
|
||||
| V | 구역 | 1 1구역, 2 2구역 |
|
||||
| W | 봉투명(약어) | 10132 일반용 10L 등 |
|
||||
| X | 봉투구분(대분) | 1 일반용, 2 공공용, 3 무료용, 4 공동주택용, 6 음식물 |
|
||||
| Y | 분기 | 1 1/4분기 … 4 4/4분기 |
|
||||
|
||||
---
|
||||
|
||||
## 참고
|
||||
|
||||
- **판매소번호**: 기본코드 B, C, D + 판매소 일련번호.
|
||||
- **구코드**: 판매소 주소 기준 기본코드 C 할당.
|
||||
- 세부코드 전체 목록은 원본 CSV `종량제_개발목록_20260127(기본코드 종류).csv` 참고.
|
||||
125
docs/기본 개발계획/04-menu-structure.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# 전체 메뉴 구조 (1차정리 / SMT)
|
||||
|
||||
웹 메뉴 대분류와 하위 메뉴. CSV "전체 메뉴 - 1차정리" / "전체 메뉴 - SMT" 기준.
|
||||
|
||||
---
|
||||
|
||||
## 기본정보관리
|
||||
|
||||
- 기본 코드 관리
|
||||
- 단가 관리
|
||||
- 포장 단위 관리
|
||||
- 판매 대행소 관리
|
||||
- 담당자 관리
|
||||
- 업체 관리
|
||||
- 무료용 대상자 관리
|
||||
- 지정판매소 관리
|
||||
- 지정판매소 조회
|
||||
- 지정판매소 신규/취소 현황
|
||||
- 지정판매소 바코드 출력
|
||||
- PC → PDA로 자료 전송
|
||||
- PDA → PC로 자료 전송
|
||||
- 올린 자료 처리
|
||||
- 시찰 처리
|
||||
- PASSWORD 변경
|
||||
- 환경 설정
|
||||
- 지정판매소 현황
|
||||
|
||||
---
|
||||
|
||||
## 발주 입고 관리
|
||||
|
||||
- 발주 등록
|
||||
- 발주 변경
|
||||
- LOT-No 디스켓 불출
|
||||
- 발주 현황
|
||||
- 발주 입고[스캐너]
|
||||
- 일괄입고
|
||||
- 입고 현황
|
||||
|
||||
---
|
||||
|
||||
## 불출 관리
|
||||
|
||||
- 무료 불출 현황
|
||||
- 무료용 불출 처리
|
||||
- 무료용 불출 취소
|
||||
|
||||
---
|
||||
|
||||
## 재고 관리
|
||||
|
||||
- 재고 현황
|
||||
- 실사 관리
|
||||
- 실사 선별
|
||||
- 실사 선별 조회
|
||||
- 실사 등록
|
||||
- 실사 재고 조회
|
||||
- 실사 오류 조회
|
||||
- 실사 선별 취소
|
||||
- 실사 등록 취소
|
||||
|
||||
---
|
||||
|
||||
## 판매 관리
|
||||
|
||||
- 전화 접수
|
||||
- 전화 접수 관리
|
||||
- 지정 판매소 판매
|
||||
- 지정 판매소 반품
|
||||
- 지정 판매소 판매 취소
|
||||
- 지정 판매소 반품 취소
|
||||
|
||||
---
|
||||
|
||||
## 판매 현황
|
||||
|
||||
- 지정 판매소 일 판매대장
|
||||
- 지정 판매소 기간별 판매대장
|
||||
- 일계표
|
||||
- 기간별 판매현황[일집계]
|
||||
- 기간별 판매현황[기간집계]
|
||||
- 년 판매 현황
|
||||
- 지정 판매소 별 판매현황(수량)
|
||||
- 지정 판매소 별 판매현황(금액)
|
||||
- 지정판매소별 거래현황
|
||||
- 홈텍스 처리
|
||||
|
||||
---
|
||||
|
||||
## 봉투 수불 관리
|
||||
|
||||
- 기타 입출고
|
||||
- 기간별 봉투 수불 현황
|
||||
- 일일 봉투 수불 현황
|
||||
- 반품/파기 현황
|
||||
- 쓰레기 봉투 수급 계획
|
||||
- LOT 수불 조회
|
||||
|
||||
---
|
||||
|
||||
## 통계 분석 관리
|
||||
|
||||
- 전년 대비 판매 분석
|
||||
- 월별 판매 추이 분석
|
||||
- 계절별 판매 추이 분석
|
||||
|
||||
---
|
||||
|
||||
## 창
|
||||
|
||||
- PDA 수정 (바둑판식 배열, 계단식 배열, 계층식 배열)
|
||||
- 원격 요청
|
||||
- pda 리셋
|
||||
- 번호알기
|
||||
- Data Backup
|
||||
- 컴포트 설정
|
||||
- Version 정보
|
||||
- 종료
|
||||
- 1GBMS
|
||||
|
||||
---
|
||||
|
||||
## 도움말
|
||||
|
||||
- 도움말 항목
|
||||
71
docs/기본 개발계획/05-meeting-notes.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# 회의 내용 참고
|
||||
|
||||
CSV "회의 내용 참고" 시트 기반 요약. 개발 시 반영할 사항.
|
||||
|
||||
---
|
||||
|
||||
## 스캐너·입출고
|
||||
|
||||
- 스캐너 신호 수신 처리 필요.
|
||||
- 발주 입고 관리 → 발주 등록 → 발주 입고(스캐너) → (일괄 입고).
|
||||
- 불출: **입고 처리된 봉투·스티커만** 불출 관리. 무료용 있는 구청 / 없는 구청 구분 필요.
|
||||
- 공공용 불출: 구청에서 사용하는 용도로 처리.
|
||||
|
||||
---
|
||||
|
||||
## 재고·실사
|
||||
|
||||
- 재고 현황: **일자별**, 인쇄 시 **결재란** 출력.
|
||||
- 일반용(손잡이 없음), 재사용(손잡이 있음) 구분.
|
||||
- 대행소: 예) 달성군은 읍·면에서 판매.
|
||||
- **권한별 메뉴 접근 제어** 필요.
|
||||
- 실사 선별/선별 조회: 구청 봉투 종류별·박스 번호별 재고, 바코드 번호 리스트 확인.
|
||||
|
||||
---
|
||||
|
||||
## 판매·전화 접수
|
||||
|
||||
- 전화 접수: 전화번호 등으로 조회 후 봉투 종류별 **박스/팩 수량** 입력 → 저장.
|
||||
- 전화 접수 관리 화면 개선.
|
||||
- **봉투종류·금액 확인·영수증 출력**이 가장 중요.
|
||||
- 접수는 **당일**, 배달일은 **익일** 표시.
|
||||
- 창구 수령 시 **수령** 처리 가능해야 함.
|
||||
- 집계·영수증·list 선택 후 인쇄 가능.
|
||||
|
||||
---
|
||||
|
||||
## 단가·비용
|
||||
|
||||
- 봉투 단가는 지자체마다 상이. 현재 구청으로부터 7원 수령.
|
||||
- 1안: 봉투당 0.5원. (서울·경기권: wixon 영업 시 wixon이 서진에 0.5원 지불.)
|
||||
|
||||
---
|
||||
|
||||
## 기본정보·코드
|
||||
|
||||
- 기본정보관리 → 코드관리: **조합 방식 확인 필요**.
|
||||
|
||||
---
|
||||
|
||||
## 전화 주문 관리
|
||||
|
||||
- 판매소 담당자 사정에 따라 **전화 주문**도 가능해야 함.
|
||||
- 주문 시 **구청마다 기본 단위**가 다르게 설정될 수 있어야 함.
|
||||
- 흐름: 1) 판매소가 구청에 전화 2) 담당자가 봉투 종류별 주문 수량 입력 3) 총 비용 산출·통화로 전달 4) 판매소가 구청 통장 입금.
|
||||
- 웹(앱) 주문도 많음.
|
||||
- **가상계좌 입금 실시간 조회** 필요 (헥토파이낸셜 연계 검토).
|
||||
|
||||
---
|
||||
|
||||
## 발주·바코드
|
||||
|
||||
- 생산 발주: 현재 박스 단위 맞춤 → 공무원은 전체 예산 기준 수량 조정.
|
||||
- 라벨나라로 바코드 정보 생성. 일반 상용 바코드 프린터용(2차원 바코드).
|
||||
- **박스 - 팩 - 낱장** 계층.
|
||||
- 이슈: 생산 시 박스에 다른 팩이 섞여 들어가면, 구청에서 미판매 팩 바코드를 찍었을 때 판매 처리되는 경우 있음. → **LOT 번호 조회** 메뉴로 확인.
|
||||
|
||||
---
|
||||
|
||||
## 실사 선별 조회
|
||||
|
||||
- 구청 창고 재고 확인용. 봉투 종류 선택 시 **박스 번호 - 잔량** 표시.
|
||||
318
docs/기본 개발계획/06-development-plan.md
Normal file
@@ -0,0 +1,318 @@
|
||||
# 종량제 프로젝트 개발 계획
|
||||
|
||||
앞으로의 개발 순서와 단계별 목표를 정리한 문서입니다.
|
||||
기능 상세는 `01-web-features.md`, 권한·개요는 `00-project-overview.md`를 참고합니다.
|
||||
|
||||
---
|
||||
|
||||
## 0. 참조 프로젝트·환경·정책
|
||||
|
||||
### 0.1 참조 프로젝트: slow-auth-application
|
||||
|
||||
- **위치**: `PhpstormProjects/slow-auth-application` (jongryangje와 동일 상위 폴더)
|
||||
- **역할**: **admin 단(메뉴관리, 회원관리)** 을 이 프로젝트 구조를 참고해 가져와 개발을 시작한다.
|
||||
- **auth 구조 요약**:
|
||||
- **프레임워크**: CodeIgniter 3 (jongryangje는 CI4 + PHP 8)
|
||||
- **베이스 컨트롤러**: `SL_Controller` — 로그인 체크, `_setting_view()` 로 레이아웃(header + sidebar + page) 출력
|
||||
- **admin 경로**: `setting/` — `setting/Menu`(메뉴 관리), `setting/Member`(회원 관리)
|
||||
- **레이아웃**: `layout_main_v` — App__sidebar + App_container(header + 본문), sidebar에 권한별 메뉴
|
||||
- **모델 네이밍**: `Menu_m`, `Member_m`, `Define_m` — 테이블 `menu`, `member` 등, 컬럼 `mm_idx`, `mb_idx` 등 짧은 식별자
|
||||
- **뷰**: `setting/menu/main_v`, `setting/member/list_v`, `write_v` 등
|
||||
- **jongryangje 적용**: CI4 구조로 옮기되, **기능(메뉴 CRUD, 회원 CRUD, 권한별 메뉴 노출)** 과 **화면 흐름**은 auth와 맞춘다. PHP 버전·프레임워크가 다르므로 코드를 그대로 복사하지 않고 동작을 이식한다.
|
||||
|
||||
### 0.2 개발 환경
|
||||
|
||||
- **서버**: 아직 미정. 테스트 서버는 대구사장님과 협의 후 결정 예정.
|
||||
- **당분간**: 개발자 **로컬에 DB까지 설정**하여 진행. 상세 절차는 **`07-local-db-setup.md`** 참고.
|
||||
|
||||
### 0.3 프론트엔드·디자인
|
||||
|
||||
- **Stitch(Google)**: UI 디자인·시안에 활용. 기존 화면 스크린샷을 올려 “웹 전환·최신 스타일” 시안 요청 가능.
|
||||
- **admin 디자인**: 현재 auth admin 그대로 사용해도 되고, 필요 시 Stitch에 admin 화면 스크린샷 올려 프론트 시안 후 적용 가능.
|
||||
|
||||
### 0.4 메뉴 통합 방향
|
||||
|
||||
- 전체 메뉴는 `04-menu-structure.md` 1차 정리 기준으로 하되, **화면 수는 줄여서** 개발한다.
|
||||
- **예시**:
|
||||
- **무료용 불출**: “무료용 불출 현황” 한 화면에서 **불출 처리 / 불출 취소** 함께 처리.
|
||||
- **판매관리**: 전화 접수·지정판매소 판매·취소·반품 등을 **한 화면 또는 소수 탭/섹션**으로 묶어 처리.
|
||||
- 상세 설계 시 메뉴별로 “한 화면에서 처리 가능한 것”을 묶어 세분화된 메뉴 수를 줄인다.
|
||||
|
||||
### 0.5 우선 진행 순서(요약)
|
||||
|
||||
1. **로컬 DB 설정** — MariaDB 등으로 `jongryangje_dev` DB·사용자 생성.
|
||||
2. **Phase 1** — 로그인·로그아웃·세션.
|
||||
3. **Phase 2** — auth의 admin(메뉴관리, 회원관리)을 CI4로 이식하여 관리자 화면·권한별 메뉴 구성.
|
||||
4. 이후 Phase 3(기본정보)부터 기능 목록 순으로 진행.
|
||||
|
||||
---
|
||||
|
||||
## 1. 개발 원칙
|
||||
|
||||
- **의존 관계 우선**: 다른 기능이 참조하는 기반(로그인·권한·기본정보)을 먼저 구현한다.
|
||||
- **웹 우선**: 웹 기능을 먼저 진행하고, 모바일앱은 웹 API·데이터가 안정된 뒤 진행한다.
|
||||
- **단계별 검증**: 각 단계 완료 시 로그인·권한·메뉴와 연동해 동작을 확인한다.
|
||||
|
||||
---
|
||||
|
||||
## 2. 코딩 컨벤션·네이밍
|
||||
|
||||
- **auth와의 일관성**: 프로젝트 구조·화면 흐름·역할은 slow-auth-application과 맞추되, **CI4·PHP 8 문법**에 맞게 작성한다. (네임스페이스, PSR-4, CI4 Controller/Model 규칙.)
|
||||
- **변수명·클래스명**: **너무 길지 않게** 한다. auth처럼 `mm_idx`, `mb_idx`, `get_item`, `insert_item` 같은 짧은 이름을 선호한다.
|
||||
- **컨트롤러/모델**: CI4 규칙에 따라 `PascalCase`(예: `Menu`, `Member`, `MenuModel`, `MemberModel`). 내부 변수·메서드는 `camelCase` 또는 auth 스타일 짧은 식별자(`midx`, `list`, `write`) 혼용 가능.
|
||||
- **DB 컬럼**: auth와 유사하게 `mm_idx`, `mb_id`, `mb_name` 등 약어 사용 시 일관성 유지. 새 테이블도 과도하게 긴 컬럼명은 지양.
|
||||
|
||||
---
|
||||
|
||||
## 3. 단계별 개발 계획
|
||||
|
||||
### Phase 1: 공통·인증 (PWB-010000)
|
||||
|
||||
**목표**: 로그인·세션·최소 보안과 로깅 기반을 갖춘다.
|
||||
|
||||
| 순서 | 작업 | 참조 ID | 비고 |
|
||||
|------|------|---------|------|
|
||||
| 1-1 | 로그인 | PWB-010301-001 | 아이디/비밀번호, 세션. 2차인증·5회 실패 lock은 2단계에서 |
|
||||
| 1-2 | 로그아웃 | — | 세션 파기 |
|
||||
| 1-3 | 작업 이력/로깅 | PWB-010101-001 | DB CRUD 로깅(최소: 로그인 이력) |
|
||||
| 1-4 | 개인정보 비식별화 | PWB-010201-001 | 이름·휴대전화 마스킹 규칙 적용 |
|
||||
|
||||
**산출물**: 로그인/로그아웃 동작, 사용자·권한 테이블 설계(Phase 2와 연계).
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: 관리자·메뉴 (PWB-020000)
|
||||
|
||||
**목표**: **slow-auth-application의 admin 단(메뉴관리, 회원관리)을 CI4로 이식**하여, 권한별 사용자와 메뉴 접근 제어를 구현한다.
|
||||
|
||||
| 순서 | 작업 | 참조 ID | 비고 |
|
||||
|------|------|---------|------|
|
||||
| 2-1 | 메뉴 관리 | PWB-020401-001 | auth `setting/Menu` 참고. 메뉴 등록/수정/삭제/순서, `04-menu-structure.md` 반영 |
|
||||
| 2-2 | 메뉴별 권한 설정 | PWB-020401-001 | 메뉴별 접근 가능 권한(레벨·그룹) 매핑, sidebar 권한별 노출 |
|
||||
| 2-3 | 사용자 권한 관리 | PWB-020101-001 | super admin·지자체·지정판매소·일반 등 권한(레벨/그룹) CRUD |
|
||||
| 2-4 | 사용자 관리 | PWB-020201-001 | auth `setting/Member` 참고. 사용자 등록/수정/삭제(삭제 상태 5년 유지) |
|
||||
| 2-5 | 로그인 이력 조회 | PWB-020301-001 | 기간 지정 조회 |
|
||||
| 2-6 | 권한 승인 루틴 | PWB-020301-001 | 브라우저 사용자 등록 시 권한 승인 |
|
||||
|
||||
**산출물**: auth와 유사한 admin 레이아웃(header + sidebar + 본문), 메뉴·회원 CRUD, 권한별 메뉴 노출.
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: 기본정보 관리 (PWB-030000)
|
||||
|
||||
**목표**: 발주·입고·불출·판매에서 공통으로 쓰는 마스터 데이터를 구축한다.
|
||||
|
||||
| 순서 | 작업 | 참조 ID | 비고 |
|
||||
|------|------|---------|------|
|
||||
| 3-1 | 기본코드 종류 | PWB-030101-001 | `03-basic-codes.md` 코드 종류(A~Y) 등록/수정/삭제 |
|
||||
| 3-2 | 기본코드 세부코드 | PWB-030101-001 | 종류별 하위 세부 코드 CRUD |
|
||||
| 3-3 | 단가 관리 | PWB-030201-001 | 지자체별·봉투 종류별 단가, 적용일·변경 이력 |
|
||||
| 3-4 | 단가 조회 | PWB-030301-001 | 기간별 단가 조회/인쇄 |
|
||||
| 3-5 | 포장 단위 관리 | PWB-030401-001 | 박스당 팩·팩당 낱장·유효기간·적용일·이력 |
|
||||
| 3-6 | 포장 단위 조회 | PWB-030401-001 | 기간별 조회/인쇄 |
|
||||
| 3-7 | 판매 대행소 관리 | PWB-030501-001 | 대행소 CRUD, 지자체 연결, 조회/인쇄 |
|
||||
| 3-8 | 담당자 관리 | PWB-030601-001, 002 | 소속·담당자명·전화, 구/군/대행소/제작업체 구분 |
|
||||
| 3-9 | 업체 관리 | PWB-030701-001 | 협회·제작업체·회수업체 등록/조회/인쇄 |
|
||||
| 3-10 | 무료용 대상자 관리 | PWB-030801-001 | 읍면동/무료대상자/기타, 종료일·상태 |
|
||||
| 3-11 | 지정판매소 관리·조회·현황 | PWB-030901-001 | 리스트·상세·CRUD·지도·엑셀·인쇄·바코드·신규/취소 현황 |
|
||||
| 3-12 | PASSWORD 변경 | PWB-031001-001 | 로그인 사용자 비밀번호 변경 |
|
||||
|
||||
**산출물**: 기본코드·단가·포장단위·대행소·지정판매소 등 기본정보 화면 및 API.
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: 발주·입고 관리 (PWB-040000)
|
||||
|
||||
**목표**: 발주부터 입고까지 흐름을 구현하고, LOT·바코드 정책을 확정한다.
|
||||
|
||||
| 순서 | 작업 | 참조 ID | 비고 |
|
||||
|------|------|---------|------|
|
||||
| 4-1 | 발주 등록 | PWB-040101-001 | 발주 이력·폼·단가표, UUID·SHA-256·LOT·블록 저장 |
|
||||
| 4-2 | LOT·바코드 생성 | PWB-040101-001 | AES-256·RSA, PDF417 박스/팩/낱장 |
|
||||
| 4-3 | 발주 변경 | PWB-040201-001 | 버전+1 insert, SHA-256, 수정 전/후 해시 |
|
||||
| 4-4 | 발주 삭제 | PWB-040301-001 | 상태 삭제로 변경 |
|
||||
| 4-5 | 발주 현황 | PWB-040401-001 | 기간·제작업체·품명·입고처 조회, 엑셀·인쇄 |
|
||||
| 4-6 | 발주 입고(스캐너) | PWB-040501-001 | 바코드 스캐너 연동(serialport), 스캔 입고 |
|
||||
| 4-7 | 일괄 입고 | PWB-040501-001 | 일괄 입고 처리 |
|
||||
| 4-8 | 입고 현황 | PWB-040501-001 | 입고 현황 조회 |
|
||||
|
||||
**산출물**: 발주 CRUD, 입고 처리, 입고된 봉투 기준 재고 반영. (실사는 Phase 6에서.)
|
||||
|
||||
---
|
||||
|
||||
### Phase 5: 불출 관리 (PWB-050000)
|
||||
|
||||
**목표**: 무료용 불출·취소를 구현하고, 재고와 연동한다.
|
||||
|
||||
| 순서 | 작업 | 참조 ID | 비고 |
|
||||
|------|------|---------|------|
|
||||
| 5-1 | 무료용 불출 현황 조회 | PWB-050101-001 | 기간별 무료용 봉투별 불출 현황 |
|
||||
| 5-2 | 무료용 불출 처리 | PWB-050201-001 | 년도·분기·불출일·불출처·봉투코드·저장, 재고 감산·판매 처리 |
|
||||
| 5-3 | 무료용 불출 취소 | PWB-050301-001 | 취소 수량 저장·재고 합산·판매 취소 또는 재입고(T.B.D) |
|
||||
|
||||
**산출물**: 불출 처리/취소 화면, 재고·판매 데이터와 연동. (`05-meeting-notes.md` 참고.)
|
||||
|
||||
---
|
||||
|
||||
### Phase 6: 재고·실사 관리 (PWB-060000, PWB-070000)
|
||||
|
||||
**목표**: 재고 조회와 실사 선별로 재고 정확도를 확보한다.
|
||||
|
||||
| 순서 | 작업 | 참조 ID | 비고 |
|
||||
|------|------|---------|------|
|
||||
| 6-1 | 재고 조회 | PWB-060101-001 | 기준일·구/군·대행소별 봉투·스티커 재고, 엑셀·인쇄(결재란) |
|
||||
| 6-2 | 실사 선별 | PWB-070101-001 | 봉투·스티커 선택, 전산 선별 실행 confirm |
|
||||
| 6-3 | 실사 선별 조회 | PWB-070101-001 | 기간·품목·박스/팩, 리스트·박스/낱장 정보 |
|
||||
|
||||
**산출물**: 재고 현황 화면, 실사 선별·조회. (`04-menu-structure.md` 재고/실사 메뉴 반영.)
|
||||
|
||||
---
|
||||
|
||||
### Phase 7: 주문·판매 관리 (PWB-080000)
|
||||
|
||||
**목표**: 전화 접수와 지정판매소 판매·반품·취소를 구현한다.
|
||||
|
||||
| 순서 | 작업 | 참조 ID | 비고 |
|
||||
|------|------|---------|------|
|
||||
| 7-1 | 주문 접수 관리 메인 | PWB-080101-001 | 전화 주문 접수 내역, 배달일자·인쇄(집계·영수증·list) |
|
||||
| 7-2 | 전화 주문 접수 | PWB-080101-001 | 판매소 검색(SLOW 자동완성), 접수번호·가상계좌·주문접수표·저장 |
|
||||
| 7-3 | 전화 접수 수정/취소 | PWB-080101-001 | 접수량 변경·주문 수정·주문 취소(STATUS) |
|
||||
| 7-4 | 지정 판매소 판매 | PWB-080101-001 | 판매소 검색·봉투코드·바코드 스캔·판매 저장 |
|
||||
| 7-5 | 지정 판매소 판매 취소 | PWB-080201-001 | 판매일·취소 선택·품목/봉투코드별 취소 |
|
||||
| 7-6 | 지정 판매소 반품 | PWB-080301-001 | 판매소·봉투코드 스캔·반품 저장 |
|
||||
| 7-7 | 지정 판매소 반품 취소 | PWB-080301-001 | 반품 일자 조회·취소 선택·반품 취소 저장 |
|
||||
|
||||
**산출물**: 전화 접수·판매·반품·취소 화면. 가상계좌 실시간 조회는 별도 검토(`05-meeting-notes.md`).
|
||||
|
||||
---
|
||||
|
||||
### Phase 8: 판매 현황 (PWB-090000)
|
||||
|
||||
**목표**: 판매·반품 데이터 기반 대장·일계표·기간별·년도별 조회를 제공한다.
|
||||
|
||||
| 순서 | 작업 | 참조 ID | 비고 |
|
||||
|------|------|---------|------|
|
||||
| 8-1 | 지정 판매소 판매 대장 | PWB-090101-001 | 기간·일자별/기간별·엑셀·인쇄(결재란) |
|
||||
| 8-2 | 일계표 | PWB-090201-001 | 특정일 일계·누계(월간) |
|
||||
| 8-3 | 기간별 판매현황 | PWB-090301-001 | 일자별/기간별 판매·반품·합계 |
|
||||
| 8-4 | 년 판매 현황 | PWB-090401-001 | 년도·품목별·월/분기 |
|
||||
| 8-5 | 지정 판매소 별 판매 현황 | PWB-090501-001 | 수량/금액·1~12월 컬럼 |
|
||||
| 8-6 | 홈택스 처리 | PWB-090601-001 | 세금계산서 일괄발급 엑셀 양식 |
|
||||
|
||||
**산출물**: 판매 대장·일계표·기간별/년도별/판매소별 현황, 홈택스용 엑셀.
|
||||
|
||||
---
|
||||
|
||||
### Phase 9: 봉투 수불 관리 (PWB-100000)
|
||||
|
||||
**목표**: 수불 이력·현황·반품/파기·LOT 수불 조회를 구현한다.
|
||||
|
||||
| 순서 | 작업 | 참조 ID | 비고 |
|
||||
|------|------|---------|------|
|
||||
| 9-1 | 기타 입출고 | PWB-100101-001 | 수불 년월·봉투코드·구분·상세(요구사항 확인) |
|
||||
| 9-2 | 봉투 수불 현황 | PWB-100201-001 | 기간·품목·대행소·일자별/기간별·전일재고·입고/출고·잔량 |
|
||||
| 9-3 | 반품/파기 현황 | PWB-100301-001 | 기간·입출고 구분·조회/엑셀/인쇄 |
|
||||
| 9-4 | 봉투 수급 계획 | PWB-100401-001 | 기능 범위 추가 확인 |
|
||||
| 9-5 | LOT 수불 조회 | PWB-100501-001 | 바코드/봉투번호 입력·일자·입고출처·구분 |
|
||||
|
||||
**산출물**: 수불 현황·반품/파기·LOT 수불 조회.
|
||||
|
||||
---
|
||||
|
||||
### Phase 10: 봉투 스캔 현황 (PWB-110000)
|
||||
|
||||
**목표**: 앱 스캔 이력을 웹에서 조회할 수 있게 한다.
|
||||
|
||||
| 순서 | 작업 | 참조 ID | 비고 |
|
||||
|------|------|---------|------|
|
||||
| 10-1 | 봉투 스캔 횟수/위치 조회 | PWB-110101-001 | 낱장별 앱 스캔 횟수·경위도·지도 표시(옵션) |
|
||||
|
||||
**산출물**: 스캔 횟수/위치 조회 화면(지도는 옵션).
|
||||
|
||||
---
|
||||
|
||||
### Phase 11: 모바일앱 (선택·별도 일정)
|
||||
|
||||
**목표**: 웹 API·데이터가 안정된 뒤, `02-mobile-features.md` 15건을 앱에서 구현한다.
|
||||
|
||||
- 공통: 로그인·로깅·비식별화
|
||||
- 발주 입고, 불출·불출 취소
|
||||
- 지정판매소 판매·취소·반품·반품 취소
|
||||
- LOT 수불 조회, 주문 내역·주문·수정/취소, 봉투 정품 인증
|
||||
|
||||
웹과 동일한 권한·기본정보·발주·입고·판매 데이터를 사용한다.
|
||||
|
||||
---
|
||||
|
||||
## 4. 요약 타임라인(개념)
|
||||
|
||||
| Phase | 영역 | 의존 |
|
||||
|-------|------|------|
|
||||
| 1 | 공통·인증 | — |
|
||||
| 2 | 관리자·메뉴 | Phase 1 |
|
||||
| 3 | 기본정보 | Phase 2 |
|
||||
| 4 | 발주·입고 | Phase 3 |
|
||||
| 5 | 불출 | Phase 4 |
|
||||
| 6 | 재고·실사 | Phase 4, 5 |
|
||||
| 7 | 주문·판매 | Phase 3, 4, 5 |
|
||||
| 8 | 판매 현황 | Phase 7 |
|
||||
| 9 | 봉투 수불 | Phase 4, 5, 7 |
|
||||
| 10 | 봉투 스캔 | Phase 4, 앱 스캔 기능 |
|
||||
| 11 | 모바일앱 | Phase 1~7 안정화 후 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 문서 갱신
|
||||
|
||||
- 단계 완료 시 이 문서에 **완료일·담당·비고**를 추가해 두면 진행 상황 파악에 유리합니다.
|
||||
- 요구사항 변경은 `01-web-features.md`, `05-meeting-notes.md`에 반영하고, 필요 시 이 개발 계획도 함께 수정합니다.
|
||||
|
||||
---
|
||||
|
||||
## 6. 상위 설계 문서(Notion)와의 매핑
|
||||
|
||||
최근 Notion 설계 문서(“종량제봉투 웹 플랫폼 개발”) 기준으로, 상위 아키텍처·WBS 는 다음과 같이 이 계획의 Phase들과 대응됩니다.
|
||||
|
||||
- **기본 정보 관리 체계 (Master Data, F-MD-01~06)**
|
||||
→ 이 문서의 **Phase 3 기본정보 관리**와 매핑. 공통 코드, 단가, 포장 단위, 대행소·업체·담당자·지정판매소 관리가 포함됩니다.
|
||||
- **발주 및 입고 프로세스 (F-PO-01~04)**
|
||||
→ **Phase 4 발주·입고 관리**와 매핑. 발주 등록/변경, LOT-No·PDF417 바코드 생성, 스캐너 기반 입고, 일괄 입고·입고 현황을 포함합니다.
|
||||
- **재고 및 실사 관리 요구사항**
|
||||
→ **Phase 6 재고·실사 관리**, **Phase 9 봉투 수불 관리**와 매핑. 실시간 재고, 다단계 실사, 수급 계획, LOT 수불 추적 기능을 여기서 구현합니다.
|
||||
- **판매 및 결제 시스템 (고정 가상계좌, Webhook, 홈택스 연동)**
|
||||
→ **Phase 7 주문·판매 관리**(주문/판매/반품/취소)와 **Phase 8 판매 현황**(리포트·홈택스용 엑셀)에서 1차 구현하고, PG/Webhook·홈택스 API 연동은 **웹 1차 안정화 이후 단계적 고도화 항목**으로 둡니다.
|
||||
- **데이터 흐름·제어 흐름·UML/ERD**
|
||||
→ 이 문서의 각 Phase에서 구현해야 할 **비즈니스 플로우와 테이블 설계에 대한 상위 가이드**로 삼고, 실제 마이그레이션/엔티티 설계는 Phase 착수 시점에 Notion 내용을 참고해 구체화합니다.
|
||||
- **블록체인/불변 원장 구조(SQL-Ledger)**
|
||||
→ 종량제 v1(웹 1차)에서는 **일반 RDBMS 기반 수불·이력 관리**를 우선 완성하고, 이후 “블록체인/Immutable Ledger 기반 이력 보강”을 **별도 고도화 Phase**로 추가하는 것을 전제로 합니다.
|
||||
|
||||
즉, Notion 문서는 “전체 시스템 설계·데이터/제어 흐름·블록체인·고정 가상계좌 등 상위 아키텍처”를 제시하고 있고,
|
||||
이 문서(`06-development-plan.md`)는 그 중 **웹 애플리케이션 기능 개발 순서와 범위(Phase 1~11)** 에 초점을 맞춘 실행 계획으로 사용합니다.
|
||||
|
||||
---
|
||||
|
||||
## 7. 추가 비즈니스/운영 요구사항 (25.11.24 미팅 요약)
|
||||
|
||||
- **가격·수익 구조**
|
||||
- 봉투 1장당 바코드 비용은 **약 7원**, 이 중 **0.5원(약 7%)을 영업 파트너(Wixon 등)와 분배**하는 모델을 전제로 함.
|
||||
- 개발비 5천만 원은 “설계도까지 사 오는 것”이 아니라, **서진이 프로그램 소유권을 가지되, 윅슨이 영업 시 일정 수익을 공유하는 투자 개념**으로 이해함.
|
||||
- **프로그램 소유권**
|
||||
- 개발비를 서진이 부담하는 만큼 **프로그램 소유권은 서진**이 갖고,
|
||||
- 윅슨이 서울/경기에서 영업하는 것은 **막지 않는 방향(라이선스 제공)** 으로 합의.
|
||||
- 별도 2안으로는 **프로그램 소유권까지 전부 이전(매입)** 하는 조건도 논의됨.
|
||||
- **서버·배포 방식**
|
||||
- 지자체 정보통신과를 거치지 않고 **지자체 내부 서버에 설치하는 응용프로그램 방식**을 우선 고려 (현재도 원격 접속으로 운영 중).
|
||||
- 동시에, 경쟁사(예: IT플러스)가 **외부 서버 방식**을 쓰는 점을 감안해,
|
||||
**지자체 내 서버 설치형 + 외부 서버/클라우드형을 모두 지원하는 유연한 구조**가 영업 전략상 유리하다는 의견.
|
||||
- **블록체인·특허**
|
||||
- 순수 기술 관점에서는 **주기적 백업 + 암호화** 만으로도 충분하나,
|
||||
- **특허(블록체인 기반 종량제 봉투 관리)와 연계해 입찰 없이 수의계약·영업 차별화**를 하기 위해,
|
||||
설계 상 **블록체인/불변 원장 아키텍처를 반영**해야 함.
|
||||
- v1 웹 개발에서는 RDBMS 기반으로 구현하되, 데이터 구조와 로그(수불 이력 등)는 **나중에 블록체인/Immutable Ledger로 확장 가능하도록 설계**하는 것을 목표로 함.
|
||||
- **운영·테스트**
|
||||
- “검수 및 관공서 설치 테스트” 기간은 **약 1개월**을 기준으로, 실제 환경에서 잘 돌아가는지 모니터링.
|
||||
- 오래된 레거시 메뉴가 많아, 웹 전환 시 **기능 통합·정리로 메뉴 수를 줄이는 것**도 중요한 목표.
|
||||
- **기타 운영 요구**
|
||||
- PC가 안 되는 경우 **PDA에서 먼저 입고/불출 처리 후 나중에 PC와 동기화**해야 하는 케이스가 있으므로,
|
||||
온라인/오프라인 혼합 시나리오를 고려한 **동기화 로직**이 필요함.
|
||||
- 각 기능별 **로그(감사 이력) 기록**은 필수이며, 이는 향후 블록체인/불변 원장 도입 시에도 핵심 데이터가 됨.
|
||||
139
docs/기본 개발계획/07-local-db-setup.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# 종량제 로컬 DB 설정 (MariaDB)
|
||||
|
||||
로컬에서 개발을 시작할 때 MariaDB 설치·DB 생성·프로젝트 연결 방법입니다.
|
||||
|
||||
---
|
||||
|
||||
## 1. MariaDB 버전
|
||||
|
||||
- **권장**: **MariaDB 10.11 LTS** 또는 **11.x 최신 안정(stable)** 중 하나를 사용하면 됩니다.
|
||||
- **10.11 LTS**: 장기 지원 버전. 운영 서버와 버전을 맞추고 싶을 때 적합.
|
||||
- **11.x (최신 stable)**: 최신 기능·성능 개선이 필요할 때 적합. PHP 8 + CI4와 호환됩니다.
|
||||
- **정리**: “꼭 최신이어야 한다”는 필요는 없고, **10.11 이상**이면 충분합니다. Homebrew로 설치 시 `brew install mariadb` 는 보통 최신 stable을 설치합니다.
|
||||
|
||||
---
|
||||
|
||||
## 2. 설치 (macOS, Homebrew)
|
||||
|
||||
```bash
|
||||
# MariaDB 설치
|
||||
brew install mariadb
|
||||
|
||||
# 서비스 기동 (재부팅 후에도 자동 기동 원하면)
|
||||
brew services start mariadb
|
||||
```
|
||||
|
||||
- **포트**: 기본 `3306`. 다른 MySQL/MariaDB가 이미 쓰고 있으면 충돌할 수 있으니, 필요 시 `brew services list` 등으로 확인합니다.
|
||||
|
||||
---
|
||||
|
||||
## 3. DB·사용자 생성
|
||||
|
||||
터미널에서 MariaDB에 접속한 뒤 아래 SQL을 실행합니다.
|
||||
|
||||
```bash
|
||||
mariadb -u root
|
||||
```
|
||||
|
||||
비밀번호를 물어보면, 설치 직후에는 비밀번호가 없을 수 있어 **Enter**만 누르면 됩니다. (이미 root 비밀번호를 설정했다면 해당 비밀번호 입력.)
|
||||
|
||||
SQL:
|
||||
|
||||
```sql
|
||||
CREATE DATABASE IF NOT EXISTS jongryangje_dev
|
||||
CHARACTER SET utf8mb4
|
||||
COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
CREATE USER IF NOT EXISTS 'jongryangje'@'localhost'
|
||||
IDENTIFIED BY 'jongryangje_dev';
|
||||
|
||||
GRANT ALL PRIVILEGES ON jongryangje_dev.* TO 'jongryangje'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
EXIT;
|
||||
```
|
||||
|
||||
- **DB 이름**: `jongryangje_dev`
|
||||
- **사용자**: `jongryangje`
|
||||
- **비밀번호**: `jongryangje_dev`
|
||||
→ 비밀번호를 다르게 쓰려면 아래 `.env` 설정에서 같이 바꿉니다.
|
||||
|
||||
---
|
||||
|
||||
## 4. 프로젝트 .env 설정
|
||||
|
||||
프로젝트 루트에 `.env` 파일이 없으면 `env` 를 복사한 뒤 DB 설정만 넣어도 됩니다.
|
||||
|
||||
```bash
|
||||
cd /Users/tae/PhpstormProjects/jongryangje
|
||||
cp env .env
|
||||
```
|
||||
|
||||
`.env` 에서 다음 항목의 **주석(#)을 제거**하고 값을 수정합니다.
|
||||
|
||||
```ini
|
||||
# ENVIRONMENT
|
||||
CI_ENVIRONMENT = development
|
||||
|
||||
# APP (로컬 주소에 맞게)
|
||||
app.baseURL = 'http://jongryangje.local/'
|
||||
# 또는 PHP 내장 서버 사용 시:
|
||||
# app.baseURL = 'http://localhost:8080/'
|
||||
|
||||
# DATABASE
|
||||
database.default.hostname = localhost
|
||||
database.default.database = jongryangje_dev
|
||||
database.default.username = jongryangje
|
||||
database.default.password = jongryangje_dev
|
||||
database.default.DBDriver = MySQLi
|
||||
database.default.port = 3306
|
||||
```
|
||||
|
||||
- **비밀번호**를 3단계에서 다르게 정했다면 `database.default.password` 에 같은 값을 넣습니다.
|
||||
|
||||
---
|
||||
|
||||
## 5. 연결 확인
|
||||
|
||||
CI4에서 DB를 쓰는 코드(예: 로그인·모델)를 넣은 뒤 브라우저로 접속해 보거나, 아래처럼 스파크로 확인할 수 있습니다.
|
||||
|
||||
```bash
|
||||
cd /Users/tae/PhpstormProjects/jongryangje
|
||||
php spark db:table
|
||||
```
|
||||
|
||||
(마이그레이션을 아직 안 했다면 테이블 목록이 비어 있을 수 있습니다. 에러 없이 실행되면 연결은 된 것입니다.)
|
||||
|
||||
---
|
||||
|
||||
## 6. 프로젝트 내 초기화 SQL (선택)
|
||||
|
||||
DB·사용자 생성을 한 번에 하려면 프로젝트에 포함된 SQL을 사용할 수 있습니다.
|
||||
|
||||
```bash
|
||||
# MariaDB가 실행 중일 때 (프로젝트 루트에서)
|
||||
mariadb -u root < writable/database/init_jongryangje_dev.sql
|
||||
```
|
||||
|
||||
- **파일 위치**: `writable/database/init_jongryangje_dev.sql`
|
||||
- root 비밀번호가 있으면: `mariadb -u root -p < writable/database/init_jongryangje_dev.sql`
|
||||
|
||||
---
|
||||
|
||||
## 7. MariaDB가 기동되지 않을 때
|
||||
|
||||
- `brew services start mariadb` 후에도 `Can't connect to local server through socket` 이 나오면:
|
||||
- 터미널을 새로 연 뒤 다시 `brew services start mariadb` 실행
|
||||
- 또는 **재부팅** 후 `brew services start mariadb`
|
||||
- macOS에서 launchctl 오류(예: Bootstrap failed 5)가 나오면, 재부팅 후 재시도하거나 [Homebrew MariaDB 문서](https://formulae.brew.sh/formula/mariadb) 참고
|
||||
- 수동 기동: `mariadbd --datadir=/opt/homebrew/var/mysql &` (경로는 `brew --prefix mariadb`/var/mysql 로 확인)
|
||||
|
||||
---
|
||||
|
||||
## 8. 요약 체크리스트
|
||||
|
||||
- [ ] `brew install mariadb` 후 `brew services start mariadb`
|
||||
- [ ] `mariadb -u root` 로 접속해 `jongryangje_dev` DB·`jongryangje` 사용자 생성 (또는 `init_jongryangje_dev.sql` 실행)
|
||||
- [ ] 프로젝트 `.env` 에 `database.default.*` 설정
|
||||
- [ ] (선택) `php spark db:table` 또는 웹 접속으로 연결 확인
|
||||
|
||||
이후 Phase 1(로그인)·Phase 2(admin) 개발 시 이 DB를 사용하면 됩니다.
|
||||
161
docs/기본 개발계획/08-auth-login-flow-and-ci4-apply.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# Auth 로그인/로그아웃 플로우 정리 및 종량제(CI4) 적용 방안
|
||||
|
||||
slow-auth-application의 로그인/로그아웃이 어떻게 동작하는지 정리하고, 종량제 프로젝트(CI4)에 어떻게 적용할지 매핑한 문서입니다.
|
||||
|
||||
---
|
||||
|
||||
## 1. Auth 로그인 플로우 (현재 구조)
|
||||
|
||||
### 1.1 진입점
|
||||
|
||||
- **URL**: `GET /auth/login`
|
||||
- **컨트롤러**: `Auth::login()`
|
||||
- **전제**:
|
||||
- 이미 `logged_in` 세션이 있으면 → `/access` 로 리다이렉트 (재로그인 불필요)
|
||||
- `?is_logout=1` 이면 → `/auth/logout` 으로 보냄
|
||||
|
||||
### 1.2 폼 제출 (POST /auth/login)
|
||||
|
||||
1. **입력 검증**
|
||||
- `mb_id`(아이디): required
|
||||
- `mb_passwd`: required, min 4, max 20
|
||||
- 실패 시 → 로그인 뷰 다시 + `form_validation->error_array()` 로 에러 표시
|
||||
|
||||
2. **회원 조회**
|
||||
- `access_get_member_info($mb_id, $auth_data)` 호출
|
||||
- **auth는 3종 계정** 지원:
|
||||
- `@` 없음 → **member** (일반 회원): `member_m->login()` 으로 `member` 테이블 조회
|
||||
- `@` 있음 → **group** 또는 **entity**: `member_group_m`, `member_entity_m` 로 그룹/엔티티 로그인
|
||||
- 조회 실패 → `access_log($msg, false, $mb_id)` 로 실패 로그, 로그인 화면으로 alert 후 복귀
|
||||
|
||||
3. **추가 검사 (member일 때만 해당)**
|
||||
- 기간 설정 그룹: `gp_period_yn`, `gp_startdate`, `gp_enddate` 로 이용 기간 체크 → 밖이면 "unauthorized" 로그 + 실패
|
||||
- `member_type == "group"` 이면 임시 차단 메시지 + 실패
|
||||
- **비밀번호**: `password_verify($auth_data['mb_passwd'], $result->mb_passwd)` 로 검증
|
||||
- **상태**: `mb_state != 1` 이면 "탈퇴/정지" 메시지 + 실패, `access_log` 기록
|
||||
|
||||
4. **로그인 성공**
|
||||
- `access_login_success($result)` 호출:
|
||||
- `access_set_token()`: JWT 생성, `access_token` 테이블에 저장, **세션에 토큰 저장**
|
||||
- `access_log("You are logged in.", true, ...)` → `member_log` 테이블에 **로그인 성공 로그** (1시간 내 중복 로그인은 한 건만 저장)
|
||||
- 세션에 저장: `userinfo`, `depart`(mb_group), `access_token`, `lang`, `logged_in`, `last_activity`
|
||||
- `access_update_latest_data()`: member/group/entity 별로 `mb_latestdate` 등 최근 로그인 시간 업데이트
|
||||
- **응답**:
|
||||
- AJAX(`is_ajax=true`)면: JSON `{ result:1, redirect, token }` 반환, 클라이언트가 `localStorage`에 토큰 저장 후 `redirect` 로 이동
|
||||
- 일반 폼이면: `redirect('/access')`
|
||||
|
||||
5. **실패 시**
|
||||
- "Please check your email and password." 등 메시지 + `access_log(..., false)` → 로그인 화면으로
|
||||
|
||||
### 1.3 로그인 후 첫 화면 (Access)
|
||||
|
||||
- **기본 라우트**: `$route['default_controller'] = 'access'` → `Access::index()`
|
||||
- **동작**:
|
||||
- 세션에 `userinfo` 없으면 → `/auth/logout` 으로 보냄
|
||||
- `access_token` 과 DB의 `access_token` 테이블 비교해서 유효한 토큰인지 확인 (super admin은 별도 처리)
|
||||
- 유효하면 `Access::main()` → 접근 가능한 앱 목록(`access_list`)을 보여주는 **앱 선택 화면** (`_access_view("/access_v")`)
|
||||
- 앱이 1개면 해당 앱 URL로 바로 이동
|
||||
|
||||
### 1.4 로그아웃 (GET/POST /auth/logout)
|
||||
|
||||
1. 세션에서 `access_token` 취득
|
||||
2. **토큰이 있으면**:
|
||||
- `member_log_m->update_logout_item_by_token($token)` → 해당 로그인 로그에 **로그아웃 시각** 저장
|
||||
- `access_token_m->item_delete_by_token($token)` → DB에서 토큰 삭제
|
||||
3. `?is_logout=1` 이면 클라이언트에 `localStorage.clear()` 스크립트 출력 (자동 로그인 토큰 제거)
|
||||
4. `$this->session->sess_destroy()` 로 세션 파기
|
||||
5. `replace('/auth/login')` → 로그인 페이지로 이동
|
||||
|
||||
### 1.5 보호 구간 (로그인 필수)
|
||||
|
||||
- **SL_Controller** 상속 컨트롤러에서 `_setting_view()`, `_access_view()`, `_modal_view()` 등은 내부에서 `_require_login()` 호출
|
||||
- `_require_login()`: `logged_in` 세션이 없으면 "로그인화면으로 이동합니다." alert 후 `/auth/logout` 으로 보냄 (결국 로그인 페이지)
|
||||
|
||||
### 1.6 로그 저장 구조 (member_log)
|
||||
|
||||
- **저장 시점**: 로그인 시도(성공/실패), 로그인 성공 시 "You are logged in." 한 번, 로그아웃 시 `mll_logout_date` 업데이트
|
||||
- **필드 예**: `mll_ip`, `mll_useragent`, `mb_id`, `mb_idx`, `gp_idx`, `mll_success`, `mll_msg`, `mll_url`, `mll_country`, `at_token`, `mll_regdate`, `mll_logout_date` 등
|
||||
|
||||
---
|
||||
|
||||
## 2. 종량제(CI4)에 적용할 때 매핑
|
||||
|
||||
### 2.1 줄이기 / 빼기
|
||||
|
||||
| Auth 기능 | 종량제 적용 |
|
||||
|-----------|-------------|
|
||||
| 3종 계정 (member / group / entity) | **1종만**: 일반 사용자(member)만. group/entity 로그인 제거 |
|
||||
| JWT + access_token 테이블 (자동 로그인·다중 세션) | **Phase 1에서는 제거**: 세션만 사용. 필요 시 Phase 2 이후에 "Remember me" 단순 구현 |
|
||||
| Access 앱 선택 화면 | **대체**: 로그인 성공 시 `/dashboard`(또는 `/admin`)로 바로 이동. 앱 목록 불필요 |
|
||||
| access_get_country(), GeoIP | **제거** 또는 나중에: 로그에는 IP만 저장 |
|
||||
| 1시간 내 중복 로그인 로그 억제 | **선택**: Phase 1에서는 매 로그인마다 로그 저장해도 무방 |
|
||||
| 기간/그룹 차단 로직 | **Phase 1에서는 제거**. Phase 2에서 권한/상태만 적용 |
|
||||
|
||||
### 2.2 그대로 가져올 개념 (동작만 CI4로 구현)
|
||||
|
||||
| 항목 | auth | 종량제(CI4) |
|
||||
|------|------|-------------|
|
||||
| 로그인 폼 | `mb_id`, `mb_passwd`, return_url, token(CSRF) | 동일. `login_id`, `password`, CI4 CSRF |
|
||||
| 회원 조회 | `member_m->login()` → mb_id로 1건 | `UserModel::findByLoginId($loginId)` |
|
||||
| 비밀번호 검증 | `password_verify()` | 동일 |
|
||||
| 상태 체크 | `mb_state == 1` | `status` 활성만 허용 |
|
||||
| 성공 시 세션 | userinfo, logged_in, (access_token) | `user`(또는 userinfo), `logged_in` |
|
||||
| 로그인 로그 | `member_log` insert (성공/실패) | `login_attempts` 또는 `audit_logs` 에 INSERT |
|
||||
| 로그아웃 시 | member_log에 logout 시각 update, 세션 destroy | 로그아웃 로그 1건 INSERT + 세션 destroy |
|
||||
| 로그인 필수 체크 | `_require_login()` → 없으면 /auth/logout | **Filter** `auth`: 세션 없으면 redirect to `/login` |
|
||||
|
||||
### 2.3 CI4에서 구현할 흐름 (Phase 1)
|
||||
|
||||
1. **GET /login**
|
||||
- 이미 로그인됐으면 → `/dashboard` 리다이렉트
|
||||
- 아니면 로그인 뷰 표시 (auth의 login_v 참고해 레이아웃만 단순화)
|
||||
|
||||
2. **POST /login**
|
||||
- Validation: `login_id`, `password` 필수
|
||||
- `UserModel::findByLoginId(login_id)`
|
||||
- 없으면 → 실패 로그 저장, "아이디 또는 비밀번호를 확인해 주세요." → 로그인 화면
|
||||
- 있으면 → `password_verify(password, user->password_hash)`
|
||||
- 실패 → 실패 로그, 동일 메시지
|
||||
- 활성 상태 아님 → "중지된 계정입니다." 등
|
||||
- 성공 →
|
||||
- 세션에 `user`(id, login_id, name, role 등), `logged_in = true`
|
||||
- 로그인 성공 로그 INSERT (IP, user_agent, user_id, success)
|
||||
- (선택) `users.last_login_at` UPDATE
|
||||
- redirect to `/dashboard`
|
||||
|
||||
3. **POST /logout**
|
||||
- (선택) 로그아웃 로그 INSERT (user_id, action=LOGOUT)
|
||||
- `session()->destroy()`
|
||||
- redirect to `/login`
|
||||
|
||||
4. **Filter `auth`**
|
||||
- URI가 `login` 이면 통과
|
||||
- 그 외: 세션에 `logged_in` 없으면 redirect to `/login`
|
||||
- 필요한 라우트에만 `filter('auth')` 적용 (또는 전역 적용 후 login만 제외)
|
||||
|
||||
5. **대시보드**
|
||||
- `GET /dashboard` → Filter auth 통과 후, 단순 대시 뷰 (나중에 Phase 2에서 admin 메뉴로 교체)
|
||||
|
||||
---
|
||||
|
||||
## 3. 정리
|
||||
|
||||
- **Auth의 로그인/로그아웃 플로우**는 “폼 검증 → 회원 조회 → 비밀번호/상태 검사 → 세션 + 토큰 + 로그 기록 → 리다이렉트”이고, 로그아웃은 “토큰/로그 업데이트 + 세션 파기”입니다.
|
||||
- **종량제 Phase 1**에서는 위 플로우 중 **세션 기반 로그인/로그아웃 + 로그인(성공/실패) 로그**만 동일하게 구현하고,
|
||||
**JWT·access_token·3종 계정·Access 앱 선택 화면**은 쓰지 않습니다.
|
||||
- 이렇게 하면 auth와 **동작 느낌(로그인 → 대시로 이동, 로그인 필수 구간 보호)**은 맞추면서, CI4 구조에 맞게 단순하게 가져갈 수 있습니다.
|
||||
|
||||
---
|
||||
|
||||
## 4. 회원가입 / 계정 생성 정책 (요구사항 기준 초안)
|
||||
|
||||
- CSV와 현재 문서 기준으로 보면, **명시된 역할은 4가지**입니다.
|
||||
- `super admin` / `지자체관리자` / `지정판매소` / `일반 사용자(시민)`
|
||||
- 이 중에서 **업무용 계정(super admin, 지자체, 지정판매소)** 은
|
||||
- **관리자가 “사용자 관리(PWB-020201)” 화면에서 등록**하고,
|
||||
- 브라우저에서 자체 등록한 계정이 있다면 **권한 승인(PWB-020301)** 으로 승인하는 흐름을 사용합니다.
|
||||
- **일반 사용자(시민)** 는 현재 요구사항에서 **로그인 기반 기능이 “정품 바코드 확인” 정도** 뿐이고, “시민이 직접 회원가입해야 한다”는 명시는 없습니다.
|
||||
- 따라서 **지금 요구사항만 놓고 보면**:
|
||||
- **일반 사용자는 필수 회원가입 없이 앱을 쓸 수 있게 하고**,
|
||||
- **관리자·지자체·지정판매소 계정은 관리자 등록 + (옵션) 권한 승인** 구조로 가는 것이 자연스럽습니다.
|
||||
- 시민 회원가입/로그인(예: 마이페이지, 신고 이력 관리 등)이 실제로 필요해지는 시점에, 별도의 **시민 회원가입/인증 플로우를 설계**하는 쪽이 더 안전합니다.
|
||||
6
docs/기본 개발계획/09-high-level-requirements-architecture.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# 종량제봉투 웹 플랫폼 개발 (상위 설계 요약)
|
||||
|
||||
> 원본: Notion 문서 "종량제봉투 웹 플랫폼 개발"에서 발췌
|
||||
|
||||
(여기에 상위 설계 전문을 붙여넣었습니다. 이미 질문에 포함된 내용과 동일하므로, 요약은 06-development-plan.md 6장에 정리되어 있습니다.)
|
||||
|
||||
4
docs/기본 개발계획/10-business-notes-2025-11-24.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# [25.11.24] 종량제 봉투 물류 관리 시스템 미팅 메모
|
||||
|
||||
(질문에 제공된 회의 메모 전문을 이 파일에 보관합니다.)
|
||||
|
||||
164
docs/기본 개발계획/11-login-logout-development-guide.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# 로그인/로그아웃 개발 진행 가이드
|
||||
|
||||
기존 정리 문서(`06-development-plan.md`, `08-auth-login-flow-and-ci4-apply.md`)와 새로 추가된 요구사항(Notion 설계, 25.11.24 미팅, auth DB DDL)을 바탕으로 **로그인/로그아웃 기능을 어떤 순서로 어떻게 개발할지** 정리한 문서입니다.
|
||||
|
||||
---
|
||||
|
||||
## 1. 목적·범위
|
||||
|
||||
- **목적**: Phase 1 공통·인증의 핵심인 **로그인/로그아웃**을 구현하여, 이후 모든 화면에서 "로그인 필수" 체크와 권한 기반 메뉴(Phase 2)의 기반을 마련한다.
|
||||
- **범위**:
|
||||
- 로그인 화면(GET/POST), 로그아웃(POST), 세션 기반 인증
|
||||
- 로그인 성공/실패/로그아웃 **이력 저장**(각 기능별 로그 필수 요구 반영, 향후 블록체인/불변 원장 확장 고려)
|
||||
- 로그인하지 않으면 내부 페이지 접근 불가(Filter)
|
||||
- **제외(Phase 1)**:
|
||||
- 2차 인증, 5회 실패 시 계정 lock → Phase 2에서 검토
|
||||
- 회원가입 화면 → 관리자 사용자 관리(Phase 2)에서 계정 생성
|
||||
- JWT·자동 로그인
|
||||
|
||||
---
|
||||
|
||||
## 2. 참조 문서
|
||||
|
||||
| 문서 | 참고 내용 |
|
||||
|------|-----------|
|
||||
| `06-development-plan.md` | Phase 1 목표, Phase 2 이후 흐름, §7 운영 요구(로그 필수) |
|
||||
| `08-auth-login-flow-and-ci4-apply.md` | auth 로그인/로그아웃 플로우, CI4 적용 흐름(GET/POST login, logout, Filter), 회원가입 정책 |
|
||||
| `00-project-overview.md` | 4가지 권한(super admin, 지자체관리자, 지정판매소, 일반 사용자) |
|
||||
| auth DDL (회원 제공) | `member`, `member_log` 테이블 구조 — 종량제 DB와 **최대한 유사**하게 설계 |
|
||||
|
||||
---
|
||||
|
||||
## 3. DB 설계 (auth 유사)
|
||||
|
||||
### 3.1 테이블: `member`
|
||||
|
||||
auth의 `member` DDL을 기준으로, 종량제에서 **로그인/권한에 필요한 컬럼만** 우선 반영한다.
|
||||
|
||||
- **식별·계정**: `mb_idx`(PK), `mb_id`(UNIQUE), `mb_passwd`, `mb_type`(또는 `mb_level`/`mb_group`으로 역할 구분)
|
||||
- **기본 정보**: `mb_name`, `mb_email`, `mb_phone`, `mb_lang`
|
||||
- **권한**: `mb_level`, `mb_group` (또는 `mb_type` 하나로 super_admin / local_admin / shop / citizen 구분)
|
||||
- **상태·날짜**: `mb_state`(1 정상, 2 정지, 0 탈퇴), `mb_regdate`, `mb_latestdate`, `mb_leavedate`(NULL 가능)
|
||||
- **기타**: auth와 동일하게 두되, 유료회원/기간 제한 등은 Phase 1에서 미사용 가능
|
||||
|
||||
날짜 컬럼은 **VARCHAR → DATETIME** 로 통일해 두면 CI4에서 다루기 편하다.
|
||||
마이그레이션 작성 시 auth DDL(`member`)을 참고해 `CREATE TABLE member ( ... )` 형태로 작성한다.
|
||||
|
||||
### 3.2 테이블: `member_log`
|
||||
|
||||
auth의 `member_log` DDL을 참고해 **로그인/로그아웃 이력**을 저장한다.
|
||||
|
||||
- **필수 컬럼**: `mll_idx`(PK), `mll_success`, `mb_idx`, `mb_id`, `mll_regdate`, `mll_ip`, `mll_msg`, `mll_useragent`, `mll_logout_date`
|
||||
- **선택**: `mll_url`, `mll_referer`, `mll_country`, `at_token` — Phase 1에서는 비워두거나 NULL 허용
|
||||
- 엔진: **MyISAM → InnoDB** 로 생성해도 됨
|
||||
|
||||
로그인 시도(성공/실패) 시 1건 INSERT, 로그아웃 시 해당 세션의 마지막 로그인 로그에 `mll_logout_date` UPDATE 하거나, 로그아웃 시점에 새 로그 1건 INSERT 하는 방식 중 하나로 통일한다. (08 문서에서는 “로그아웃 로그 1건 INSERT”를 옵션으로 둠.)
|
||||
|
||||
---
|
||||
|
||||
### 3.3 로그 테이블 구분 정책
|
||||
|
||||
- **로그인/로그아웃 로그** → **전용 테이블 `member_log`** 에만 저장한다.
|
||||
- auth 호환·로그인 이력 조회(Phase 2의 "로그인 이력 조회")용으로 컬럼 구조(mb_idx, mll_success, mll_regdate, mll_logout_date 등)를 유지한다.
|
||||
- **그 외 기능에 대한 감사 로그**(입고·불출·판매·메뉴 접근·사용자 CRUD·권한 변경 등) → **별도 통합 테이블 한 개**에 저장한다.
|
||||
- 예: `audit_log` (또는 `action_log`) — 컬럼 예: `al_idx`, `mb_idx`, `action`(또는 `log_type`), `entity`, `entity_id`, `regdate`, `ip`, `user_agent`, `payload`(JSON) 등.
|
||||
- Phase 1에서는 `member_log`만 구현하고, `audit_log`는 Phase 2 이후 각 기능 개발 시점에 도입해도 된다.
|
||||
|
||||
즉, **로그인 로그만 `member_log`에 두고, 나머지 기능 로그는 같은 통합 테이블(`audit_log`)에 남기는 구조**로 한다.
|
||||
|
||||
---
|
||||
|
||||
## 4. 구현 순서
|
||||
|
||||
아래 순서대로 진행하면 의존 관계 없이 단계별로 검증할 수 있다.
|
||||
|
||||
1. **마이그레이션 작성 및 실행**
|
||||
- **Phase 1에서는 로그인 관련 테이블만** 생성: `member`, `member_log` (auth DDL 참고, charset/collate는 `utf8mb4`/`utf8mb4_unicode_ci` 권장). 그 외 테이블(menu, audit_log 등)은 해당 기능을 만들 때 마이그레이션으로 추가하면 된다.
|
||||
- `php spark migrate` 로 적용
|
||||
|
||||
2. **시더(Seeder) 작성**
|
||||
- 테스트용 **super admin** 계정 1건 (예: `mb_id` = admin, 비밀번호는 `password_hash` 로 저장)
|
||||
|
||||
3. **Config 설정**
|
||||
- `app/Config/Routes.php`: `get('login', ...)`, `post('login', ...)`, `post('logout', ...)`, `get('dashboard', ...)` 등
|
||||
- `app/Config/Filters.php`: `auth` 필터 정의 (세션 없으면 redirect to `/login`), `guest` 필터(로그인 상태면 `/dashboard`로)
|
||||
- `app/Config/Validation.php`: 로그인 폼 규칙 (`login_id` 필수, `password` 필수·최소 길이)
|
||||
|
||||
4. **모델**
|
||||
- `App\Models\MemberModel`: `findByLoginId($loginId)`, `updateLastLoginAt($id)` 등 (auth `Member_m` 참고)
|
||||
- `App\Models\MemberLogModel`: `insertItem($data)`, (로그아웃 시) `updateLogoutByToken($token)` 또는 로그아웃 전용 `insertLogout($userId)` 등
|
||||
|
||||
5. **컨트롤러**
|
||||
- `App\Controllers\AuthController`: `showLoginForm()`, `login()`, `logout()` (08 §2.3 흐름 그대로)
|
||||
- `App\Controllers\DashboardController`: `index()` — 로그인 후 첫 화면(임시 뷰)
|
||||
|
||||
6. **Filter 적용**
|
||||
- `auth`: 로그인 필요 라우트에 적용 (또는 전역 적용 후 `/login` 제외)
|
||||
- `guest`: `/login` 접근 시 이미 로그인돼 있으면 `/dashboard` 로 리다이렉트
|
||||
|
||||
7. **뷰**
|
||||
- **로그인 화면** (`app/Views/auth/login.php`): 레이아웃 없이 **단독 페이지**로 구성. 아이디·비밀번호 입력 필드, CSRF hidden, 제출 버튼, 검증 실패 시 `validation_list_errors()` 또는 컨트롤러에서 넘긴 `error` 메시지 출력. auth의 `login_v` 참고해 단순화. Phase 1에서는 스타일은 최소(또는 CI4 기본 스타일)로 두고, Phase 2에서 admin 테마 적용 시 로그인 페이지만 공통 헤더 없이 유지.
|
||||
- **대시보드** (`app/Views/dashboard/index.php`): 로그인 후 첫 화면. Phase 1에서는 **최소 구성** — 상단에 로그인 사용자 표시 + 로그아웃 링크(폼 POST `/logout` 또는 링크), 본문은 "대시보드" 문구만 있어도 됨. Phase 2에서 admin 레이아웃(header + sidebar + 본문)을 도입하면 이 뷰를 레이아웃 본문으로 넣고, sidebar 메뉴는 그때 추가.
|
||||
- **공통 레이아웃**: Phase 1에서는 대시보드용 레이아웃을 따로 두지 않고, 단순 HTML로 로그아웃만 넣어도 됨. Phase 2에서 `layout_main_v` 스타일(header + sidebar)을 만들 때 `layout/header.php`, `layout/sidebar.php` 등을 도입하면 됨.
|
||||
|
||||
8. **동작 확인**
|
||||
- 미로그인 시 `/dashboard` 접근 → `/login` 이동
|
||||
- 로그인 성공 → `/dashboard` 이동, 세션 유지
|
||||
- 로그아웃 → 세션 제거 후 `/login` 이동
|
||||
- `member_log` 에 성공/실패/로그아웃 기록 저장 여부 확인
|
||||
|
||||
---
|
||||
|
||||
## 5. 상세 스펙 요약
|
||||
|
||||
- **GET /login**
|
||||
- 이미 로그인(`logged_in`)이면 `/dashboard` 리다이렉트
|
||||
- 아니면 로그인 뷰 출력 (CSRF 토큰 포함)
|
||||
|
||||
- **POST /login**
|
||||
- 입력: `login_id`, `password`
|
||||
- 검증 실패 → 로그인 뷰 + 에러 메시지
|
||||
- `MemberModel::findByLoginId(login_id)` 없음 → 실패 로그 INSERT, "아이디 또는 비밀번호를 확인해 주세요."
|
||||
- `password_verify` 실패 → 실패 로그 INSERT, 동일 메시지
|
||||
- `mb_state != 1` → "중지된 계정입니다." 등
|
||||
- 성공 → 세션에 `user`(mb_idx, mb_id, mb_name, mb_level, mb_group 등), `logged_in = true` / 성공 로그 INSERT / `mb_latestdate` UPDATE / redirect to `/dashboard`
|
||||
|
||||
- **POST /logout**
|
||||
- (선택) 로그아웃 이력 저장 (`member_log` 에 1건 추가 또는 기존 로그에 `mll_logout_date` UPDATE)
|
||||
- `session()->destroy()` 후 redirect to `/login`
|
||||
|
||||
- **앱 첫 페이지**
|
||||
- 이 앱은 **공개 랜딩이 없고**, 비로그인 사용자가 보는 첫 화면은 **로그인 화면**만 둔다. 따라서 **루트 URL (`/`) 은 `/login`으로 리다이렉트**하거나, `/` 에서 바로 로그인 뷰를 출력하도록 한다. (현재 `Routes.php`의 `Home::index`는 구현 시 `/login` 리다이렉트로 교체.)
|
||||
- **Filter `auth`**
|
||||
- `logged_in` 없으면 redirect to `/login`
|
||||
- `login` URI는 통과(또는 `guest` 필터로 로그인 상태면 `/dashboard` 이동)
|
||||
|
||||
---
|
||||
|
||||
## 6. 역할(권한) 처리
|
||||
|
||||
- **Phase 1**에서는 `member` 테이블의 `mb_level`, `mb_group`(또는 `mb_type`)만 저장하고, **메뉴/기능 제어는 Phase 2(메뉴별 권한 설정)** 에서 구현한다.
|
||||
- 로그인 성공 시 세션에 `user.mb_level`, `user.mb_group` 등을 넣어 두어, Phase 2에서 sidebar·라우트 접근 제어에 사용하면 된다.
|
||||
- 4가지 역할은 `00-project-overview.md` 기준: super admin, 지자체관리자, 지정판매소, 일반 사용자 — DB에는 auth와 같이 `mb_level`/`mb_group` 코드로 구분하거나, `mb_type` enum 하나로 구분해도 됨.
|
||||
|
||||
---
|
||||
|
||||
## 7. 로그(감사 이력) 요구사항 반영
|
||||
|
||||
- 로그 테이블 구분은 **§3.3** 참고: 로그인/로그아웃 → `member_log` 전용, 그 외 기능 → `audit_log` 통합 테이블.
|
||||
- 25.11.24 미팅 및 06 §7에서 **각 기능별 로그 필요**가 명시되어 있으므로, 로그인/로그아웃에서도 **반드시 `member_log` 에 기록**한다.
|
||||
- 로그인 시도(성공/실패) 시 1건 INSERT, 로그아웃 시 1건 추가 또는 기존 로그에 로그아웃 시각 UPDATE.
|
||||
- 추후 블록체인/불변 원장 도입 시 이 로그가 기반 데이터가 될 수 있으므로, **INSERT 전용**으로 두고 UPDATE/DELETE는 하지 않는 정책을 권장한다. (로그아웃 시각만 UPDATE하는 방식은 예외로 둘 수 있음.)
|
||||
|
||||
---
|
||||
|
||||
## 8. 검증 체크리스트
|
||||
|
||||
- [ ] 미로그인 시 `/dashboard` 접근 시 `/login`으로 리다이렉트
|
||||
- [ ] 잘못된 아이디/비밀번호 시 에러 메시지 및 실패 로그 1건
|
||||
- [ ] 정상 로그인 시 세션 생성, `member_log` 성공 1건, `mb_latestdate` 갱신
|
||||
- [ ] 로그아웃 시 세션 삭제, `/login` 리다이렉트, (선택) 로그아웃 기록
|
||||
- [ ] 로그인 상태에서 `/login` 접근 시 `/dashboard`로 리다이렉트
|
||||
- [ ] CSRF 토큰으로 로그인 폼 제출 동작
|
||||
|
||||
이 순서와 스펙대로 구현하면, 기존 정리 문서와 새로 추가된 요구사항을 모두 반영한 로그인/로그아웃 개발이 가능하다.
|
||||
82
docs/기본 개발계획/12-technology-stack-rationale.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# 기술 스택 선정 이유 (회의용)
|
||||
|
||||
이 프로젝트의 기술 스택을 **CodeIgniter 4.7, PHP 8.4, MariaDB 11.7, Homebrew, Apache 2.4** 로 세팅한 이유를 회의에서 설명할 때 참고할 수 있도록 정리한 문서입니다.
|
||||
|
||||
**요약**: 위 항목은 모두 **최신이면서 안정(stable) 버전**으로 맞춰 두었다. 각 항목은 해당 라인(4.x, 8.x, 11.x, 2.4.x)에서 현재 제공되는 최신 안정 릴리스이다. 회의에서 “전부 최신 안정화 버전으로 설치했다”고 말해도 된다.
|
||||
|
||||
---
|
||||
|
||||
## 최신 안정화 버전 사용 시 장단점
|
||||
|
||||
### 장점
|
||||
|
||||
- **보안**: 최신 안정 버전은 알려진 보안 취약점에 대한 패치가 반영되어 있어, 공공·관공서 환경에서 유리하다.
|
||||
- **성능·기능**: 해당 라인에서의 성능 개선·버그 수정·새 기능을 바로 활용할 수 있다.
|
||||
- **지원 기간**: 구버전보다 보안·버그 수정 지원이 더 오래 이어질 가능성이 높다.
|
||||
- **문서·커뮤니티**: 최신 버전 기준 문서·질문·해결책이 많아 문제 해결이 수월하다.
|
||||
- **향후 유지보수**: 나중에 한 번에 대규모 업그레이드할 필요가 줄어든다.
|
||||
|
||||
### 단점
|
||||
|
||||
- **호환성**: 레거시 시스템·서드파티 라이브러리와의 호환 이슈가 가끔 생길 수 있다. (이 프로젝트는 새로 시작하므로 상대적으로 부담이 적음.)
|
||||
- **변경 사항**: 최신 버전에서 동작 변경·deprecation이 있을 수 있어, 마이너 업데이트 시 릴리스 노트 확인이 필요하다.
|
||||
- **운영 환경**: 실제 서버(지자체)가 구버전 PHP·DB·웹서버를 쓰는 경우, 배포 시 버전 맞춤이 필요할 수 있다.
|
||||
|
||||
**정리**: 이 프로젝트는 신규 개발이고 참조 프로젝트(auth)와의 이식만 고려하면 되므로, **최신 안정 버전 사용의 장점이 단점보다 크다**. 운영 서버 버전은 배포 전에 한 번 확인하는 것이 좋다.
|
||||
|
||||
---
|
||||
|
||||
## 1. CodeIgniter 4.7
|
||||
|
||||
- **참조 프로젝트(slow-auth-application)가 CodeIgniter 기반**이라, admin(메뉴·회원 관리) 구조·화면 흐름을 **이식하기 쉽다**. CI3 → CI4로 올리면서 코드를 그대로 복사하지 않고 **동작만 맞춰 가져오는** 방식으로 개발 계획을 세웠다.
|
||||
- **경량·PHP 네이티브**라 학습 곡선이 낮고, 지자체 내부 서버에 설치하는 **응용프로그램형 배포**에 적합하다. 무겁지 않아 레거시 환경에서도 운영 부담이 적다.
|
||||
- **PSR-4·네임스페이스·Filter·Validation** 등 현대 PHP 구조를 지원해, 유지보수와 테스트 작성이 수월하다.
|
||||
- 4.7은 LTS에 가까운 안정 라인으로, 장기 유지보수·보안 패치를 기대할 수 있다.
|
||||
|
||||
---
|
||||
|
||||
## 2. PHP 8.4
|
||||
|
||||
- **CI4 공식 요구사항이 PHP 8.2 이상**이므로, 8.4는 요구사항을 만족하면서 **최신 안정 버전**을 쓰는 선택이다.
|
||||
- PHP 8.x의 **타입·성능·JIT** 등 개선을 활용할 수 있고, 보안·버그 수정이 활발한 버전을 쓰기 위함이다.
|
||||
- 프로젝트가 새로 시작하는 시점이므로, 레거시 호환보다 **현재 권장 버전**을 선택했다.
|
||||
|
||||
---
|
||||
|
||||
## 3. MariaDB 11.7
|
||||
|
||||
- **MySQL과 호환**되며, 기존 레거시·문서에서 MySQL/ MariaDB를 전제로 한 설명이 많아 **마이그레이션·DDL 재사용**이 쉽다. 참조용 auth DB DDL(member, member_log 등)도 그대로 활용할 수 있다.
|
||||
- **PHP 8 + CI4**와의 호환성이 검증되어 있고, CI4 DB 드라이버(MySQLi/PDO)로 문제 없이 연동된다.
|
||||
- 11.7은 **최신 안정(stable)** 라인으로, 성능·기능 면에서 충분하며, 지자체 서버에 설치형으로 올리기에도 무리가 없다.
|
||||
- 오픈소스·라이선스 이슈가 없어 공공·관공서 환경에서도 선택하기 수월하다.
|
||||
|
||||
---
|
||||
|
||||
## 4. Homebrew
|
||||
|
||||
- **macOS 로컬 개발 환경**에서 패키지 설치·버전 관리가 쉽다. MariaDB, PHP(필요 시), Apache 등 **한 곳에서 의존성**을 관리할 수 있다.
|
||||
- 팀원이 macOS를 쓰는 경우 **동일한 환경**을 `brew install` 수준으로 맞추기 좋고, 문서화(예: `07-local-db-setup.md`)도 단순해진다.
|
||||
- 서버(운영) 환경과는 별개로, **로컬 개발용** 도구 체인을 Homebrew로 통일한 선택이다.
|
||||
|
||||
---
|
||||
|
||||
## 5. Apache 2.4
|
||||
|
||||
- **버전**: 2.4.x 라인이 현재 안정(stable) 브랜치이며, Homebrew 등에서 제공하는 최신 2.4를 사용하면 된다. (예: 2.4.62, 2.4.63 등 — 설치 시점의 `brew install httpd` 버전을 따른다.)
|
||||
- **PHP와의 연동**이 오래되고 문서·자료가 많아, 지자체·관공서에서 이미 쓰는 **기존 인프라**와 맞추기 쉽다.
|
||||
- **mod_rewrite**로 CI4 라우팅(index.php 제거, clean URL)을 적용하는 패턴이 널리 알려져 있어, 배포·설정이 단순하다.
|
||||
- 운영 측에서 nginx 등 다른 웹 서버를 쓰는 경우, 나중에 **리버스 프록시 뒤에 PHP-FPM + Apache** 또는 **nginx + PHP-FPM**으로 바꿀 수 있도록, CI4는 프레임워크 단에서 웹 서버에 종속되지 않게 구성해 두면 된다. 현재는 **로컬/테스트 환경**을 Apache 기준으로 세팅한 것이다.
|
||||
|
||||
---
|
||||
|
||||
## 요약 (회의에서 한 줄씩)
|
||||
|
||||
| 항목 | 선정 이유 (한 줄) |
|
||||
|------|-------------------|
|
||||
| **CodeIgniter 4.7** | 참조 프로젝트(auth)가 CI 기반이라 이식이 쉽고, 경량·PHP 네이티브로 지자체 설치형에 적합함. |
|
||||
| **PHP 8.4** | CI4 요구사항(PHP 8.2+) 충족 + 최신 안정 버전으로 성능·보안·유지보수 이점. |
|
||||
| **MariaDB 11.7** | MySQL 호환·auth DDL 재사용 용이, PHP 8·CI4와 호환, 오픈소스로 공공 환경에 적합. |
|
||||
| **Homebrew** | macOS 로컬 개발 시 패키지·환경 통일이 쉽고, 문서화·온보딩이 단순함. |
|
||||
| **Apache 2.4** | 2.4.x 안정 라인. PHP 연동·mod_rewrite 패턴이 익숙하고, 기존 인프라·문서와 맞추기 좋음. 로컬/테스트 기준. |
|
||||
|
||||
이 문서는 회의에서 “왜 이 스택인가?”를 설명할 때 참고용으로 사용하면 됩니다.
|
||||
50
docs/기본 개발계획/13-meeting-questions-to-clarify.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# 회의에서 명확히 할 질문 (확인용)
|
||||
|
||||
내일 회의에서 요구사항·범위를 확정하기 위해 물어볼 사항을 정리한 문서입니다.
|
||||
|
||||
---
|
||||
|
||||
## 1. 회원가입·일반 사용자
|
||||
|
||||
- **일반 사용자(시민)** 도 브라우저에서 **직접 회원가입(등록 요청)** 을 받을 예정인가요, 아니면 일반 사용자 계정은 **관리자만 등록**하고 시민 회원가입은 하지 않나요?
|
||||
- **브라우저에서 “사용자 등록” 후 권한 승인**이 필요한 대상은 **어떤 역할**인가요? (지정판매소만? 지자체 관계자? 일반 사용자도?)
|
||||
|
||||
---
|
||||
|
||||
## 2. 권한 승인 루틴
|
||||
|
||||
- 사용자가 브라우저에서 등록 요청을 했을 때 **승인은 누가** 하나요? (super admin만? 지자체 관리자도?)
|
||||
- 승인 **전**에는 **로그인 불가**인가요, 아니면 제한된 메뉴만 보이게 하나요?
|
||||
- 승인 요청 목록을 **어디서** 보고 승인/반려하나요? (관리자 화면 메뉴 하나로?)
|
||||
|
||||
---
|
||||
|
||||
## 3. 사용자 삭제·5년 유지
|
||||
|
||||
- **“삭제 상태로 5년 유지”** 가 법·감사 요구인가요? 5년 후에는 물리 삭제(또는 비식별화)를 해도 되나요?
|
||||
- 삭제된 사용자 **조회·복구** 기능이 필요한가요? (예: 실수 삭제 시 복구)
|
||||
|
||||
---
|
||||
|
||||
## 4. 로그인·보안 (Phase 1 vs 2)
|
||||
|
||||
- **Phase 1**에서는 로그인/로그아웃만 하고, **2차 인증·5회 실패 시 계정 잠금**은 **Phase 2**에서 진행해도 되는지 확인해 주세요.
|
||||
- 로그인 실패 **5회 잠금** 시 **해제 방법**은 어떻게 할 예정인가요? (관리자만? 시간 경과 후 자동 해제?)
|
||||
|
||||
---
|
||||
|
||||
## 5. 운영·배포 환경
|
||||
|
||||
- 실제 **지자체 서버**에 설치할 때 **PHP·MariaDB·Apache(또는 nginx) 버전**이 정해져 있나요? 우리가 쓰는 최신 안정 버전과 맞출 수 있는지요.
|
||||
- **지자체 내부 서버 설치형**만 우선인가요, **외부 서버/클라우드** 대응은 언제쯤 필요할까요?
|
||||
|
||||
---
|
||||
|
||||
## 6. 일정·우선순위
|
||||
|
||||
- **Phase 1(로그인/로그아웃)** 완료 후 **Phase 2(관리자·메뉴·사용자 관리·권한 승인)** 로 넘어가는 순서에 동의하시나요?
|
||||
- 기능 완료·테스트·오픈 목표 일정(예: 2026년 말~2027년 초)을 다시 한 번 확인해 주세요.
|
||||
|
||||
---
|
||||
|
||||
이 목록을 회의 전에 공유하거나, 회의 중 하나씩 짚어 가며 답을 정리해 두면 이후 개발·문서화할 때 혼선이 줄어듭니다.
|
||||
72
docs/기본 개발계획/14-expected-colleague-questions.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# 내일 발표 시 동료들이 할 만한 질문 정리
|
||||
|
||||
발표 후 Q&A에서 나올 수 있는 질문과, 간단한 답변/참고 위치를 정리한 문서입니다.
|
||||
|
||||
---
|
||||
|
||||
## 기술 스택
|
||||
|
||||
| 예상 질문 | 답변 포인트 / 참고 |
|
||||
|-----------|---------------------|
|
||||
| 왜 CodeIgniter 4인가? Laravel은? | 참조 프로젝트(auth)가 CI 기반이라 이식이 쉽고, 경량이라 지자체 설치형에 적합. `12-technology-stack-rationale.md` |
|
||||
| PHP 8.4는 필수인가? 8.2면 안 되나? | CI4 요구가 8.2 이상이라 8.2도 가능. 8.4는 최신 안정 버전으로 선택한 것. |
|
||||
| MariaDB 말고 MySQL 써도 되나? | 호환됨. auth DDL·기존 문서가 MySQL/MariaDB 전제라 MariaDB로 통일. |
|
||||
| Apache 말고 nginx는? | 로컬/테스트는 Apache. 운영 서버가 nginx면 나중에 PHP-FPM 등으로 전환 가능, CI4는 웹서버에 종속되지 않음. |
|
||||
| 전부 최신인데 위험하지 않나? | 최신 **안정(stable)** 버전만 사용. 베타/RC 아님. 보안·패치 측면에서 유리. `12-technology-stack-rationale.md` 장단점 |
|
||||
|
||||
---
|
||||
|
||||
## 로그인·인증
|
||||
|
||||
| 예상 질문 | 답변 포인트 / 참고 |
|
||||
|-----------|---------------------|
|
||||
| 로그인은 auth랑 똑같이 하나요? | 동작·흐름은 auth와 동일. 코드는 복사하지 않고 CI4/PHP 8로 재구현. `08-auth-login-flow-and-ci4-apply.md`, `11-login-logout-development-guide.md` |
|
||||
| 2차 인증(OTP 등)은 언제 넣나요? | Phase 1에서는 제외. Phase 2에서 검토. 웹 기능 목록(`01-web-features.md`) 로그인(PWB-010301-001) 요약에 "2차인증, 5회 실패 시 lock" 명시. |
|
||||
| 로그인 5회 실패 시 잠금은? | Phase 1 제외, Phase 2에서 구현 예정. 해제 방법(관리자/자동)은 회의에서 확인 예정. `13-meeting-questions-to-clarify.md` |
|
||||
| JWT·자동 로그인(Remember me)은? | Phase 1에서는 세션만. 필요 시 Phase 2 이후에 검토. |
|
||||
| 첫 화면이 로그인만 있나요? | 네. 공개 랜딩 없이, 비로그인 시 로그인 화면만. 루트(/)는 /login으로 리다이렉트. `11-login-logout-development-guide.md` |
|
||||
|
||||
---
|
||||
|
||||
## 사용자·권한·회원가입
|
||||
|
||||
| 예상 질문 | 답변 포인트 / 참고 |
|
||||
|-----------|---------------------|
|
||||
| 사용자 역할이 몇 가지인가요? | 4종: super admin, 지자체관리자, 지정판매소, 일반 사용자. `00-project-overview.md`, 웹 기능 CSV |
|
||||
| 일반 사용자도 회원가입 받나요? | 요구사항만으로는 불명확. 내일 회의에서 “일반 사용자 회원가입 여부” 확인 예정. `13-meeting-questions-to-clarify.md` |
|
||||
| 브라우저에서 사용자 등록 후 승인은 누가 하나요? | super admin / 지자체 등 구체는 회의에서 확인. 2-6 권한 승인 루틴. |
|
||||
| 삭제한 사용자 5년 유지가 법적 요구인가요? | 회의에서 확인 예정. soft delete로 상태만 삭제 처리, 5년 보관. |
|
||||
|
||||
---
|
||||
|
||||
## 범위·Phase·일정
|
||||
|
||||
| 예상 질문 | 답변 포인트 / 참고 |
|
||||
|-----------|---------------------|
|
||||
| Phase 1에 뭐가 들어가나요? | 로그인·로그아웃·세션·로그인 이력 저장. 2차인증·5회 잠금·회원가입 화면은 Phase 2. `01-web-features.md` 로그인 항목에 2차인증·5회 lock 명시됨. `06-development-plan.md` §3 Phase 1 |
|
||||
| Phase 2는 언제쯤 시작하나요? | Phase 1(로그인/로그아웃) 완료·검증 후. 일정은 회의에서 재확인. |
|
||||
| 전체 오픈 일정은? | 문서상 2026년 말 기능 완료·테스트, 2027년 초 오픈 목표. 회의에서 확정. |
|
||||
| auth admin을 그대로 가져오나요? | 기능(메뉴 관리, 회원 관리, 권한별 메뉴)과 화면 흐름을 auth 참고해 CI4로 이식. 코드 복사 아님. |
|
||||
|
||||
---
|
||||
|
||||
## 로그·보안·운영
|
||||
|
||||
| 예상 질문 | 답변 포인트 / 참고 |
|
||||
|-----------|---------------------|
|
||||
| 로그인 로그만 남기나요? | 로그인/로그아웃은 member_log 전용. 그 외 기능(입고·불출 등)은 audit_log 같은 통합 테이블에. `11-login-logout-development-guide.md` §3.3 |
|
||||
| 지자체 서버 버전은 우리랑 맞나요? | 미확정. 배포 전에 PHP/DB/웹서버 버전 확인 예정. `13-meeting-questions-to-clarify.md` |
|
||||
| 로컬만 지금 세팅한 건가요? | 네. 테스트·운영 서버는 협의 후. `06-development-plan.md` 0.2, `07-local-db-setup.md` |
|
||||
|
||||
---
|
||||
|
||||
## 문서·참고
|
||||
|
||||
| 예상 질문 | 답변 포인트 / 참고 |
|
||||
|-----------|---------------------|
|
||||
| 계획서·스펙은 어디 있나요? | `docs/` — 06 개발계획, 08 auth 적용, 11 로그인 개발 가이드, 12 기술 스택, 13 회의 확인 질문 등. |
|
||||
| auth 프로젝트 경로는? | slow-auth-application (동일 상위 폴더). CI3 기반. `06-development-plan.md` 0.1 |
|
||||
|
||||
---
|
||||
|
||||
회의 전에 위 표만 한 번씩 훑어 보시면, 질문 나왔을 때 빠르게 답하거나 “그건 오늘 회의에서 같이 정리할 예정입니다”로 넘기기 좋습니다.
|
||||
88
docs/기본 개발계획/15-naver-cloud-deployment-outline.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# 네이버 클라우드 서버 사용 시 구성 개요
|
||||
|
||||
실제 서비스 서버는 아직 미정이나, 회의에서 **클라우드(네이버 클라우드) 사용** 방향으로 논의했다는 전제로, 그때 **실제 어떤 식으로 구성하면 되는지** 정리한 문서입니다. (구체 제품·요금은 NCP 정책에 따라 확인 필요.)
|
||||
|
||||
---
|
||||
|
||||
## 1. 전체 구성 개요
|
||||
|
||||
애플리케이션 스택이 **CI4 + PHP 8.4 + MariaDB 11.7 + Apache 2.4** 이므로, 네이버 클라우드에서 아래처럼 나누어 두는 구성을 가정할 수 있습니다.
|
||||
|
||||
```
|
||||
[인터넷]
|
||||
│
|
||||
▼
|
||||
[로드밸런서] ← 선택. 단일 서버면 생략 가능
|
||||
│
|
||||
▼
|
||||
[웹·앱 서버] ← PHP + Apache + CI4 (소스 배포)
|
||||
│
|
||||
▼
|
||||
[DB 서버] ← MariaDB (NCP Managed DB 또는 별도 Server에 설치)
|
||||
```
|
||||
|
||||
- **웹·앱 서버**: PHP 8.4, Apache 2.4, CI4 프로젝트 배포. 세션·파일 업로드는 이 서버(또는 공유 스토리지)에 둠.
|
||||
- **DB 서버**: MariaDB 11.x. 네이버 클라우드 **DB for MySQL** (MariaDB 호환) 사용 시 관리·백업이 편함. 또는 **Server** 한 대에 MariaDB를 직접 설치해 운영할 수도 있음.
|
||||
- **로드밸런서**: 트래픽이 많거나 장애 대비로 웹 서버를 2대 이상 둘 때 사용. 초기에는 1대만 둔다면 생략 가능.
|
||||
|
||||
---
|
||||
|
||||
## 2. 네이버 클라우드(NCP)에서 쓸 수 있는 리소스
|
||||
|
||||
| 용도 | NCP 제품 예시 | 비고 |
|
||||
|------|----------------|------|
|
||||
| 웹·앱 서버 | **Server** (VPC, Linux) | Ubuntu/CentOS 등에 PHP 8.4, Apache 2.4 설치. CI4 소스 배포. |
|
||||
| DB | **DB for MySQL** (MariaDB 호환) 또는 **Server** 1대에 MariaDB 설치 | Managed DB면 패치·백업 자동화. 직접 설치면 비용·제어 유연. |
|
||||
| 로드밸런서 | **Load Balancer** | 웹 서버 다중화 시 사용. |
|
||||
| 스토리지 | **Object Storage** 또는 서버 내 디스크 | 첨부파일·로그 등. CI4 `writable/` 경로는 서버 로컬 또는 공유 볼륨. |
|
||||
| SSL/도메인 | **Certificate Manager** 또는 Let's Encrypt | HTTPS 적용 시. |
|
||||
| 백업 | **Server** 스냅샷, **DB for MySQL** 자동 백업 | 정책에 따라 보관 기간·복구 절차 정의. |
|
||||
|
||||
실제 제품명·요금은 [네이버 클라우드 플랫폼](https://www.ncloud.com/) 문서를 참고하면 됩니다.
|
||||
|
||||
---
|
||||
|
||||
## 3. 서버 1대 구성 예시 (최소 구성)
|
||||
|
||||
초기에 **웹 1대 + DB 1대** 또는 **웹+DB 한 대**로 시작할 때 예시입니다.
|
||||
|
||||
**옵션 A: 웹 서버 1대 + DB for MySQL(MariaDB) 1대**
|
||||
- **Server** 1대: OS(Ubuntu 22.04 등) + Apache 2.4 + PHP 8.4 + CI4 배포.
|
||||
- **DB for MySQL**: MariaDB 호환 엔진 선택, 전용 VPC/Subnet에서 웹 서버만 접속 허용.
|
||||
- CI4 `.env`: `database.hostname` 을 DB for MySQL 엔드포인트로 설정.
|
||||
|
||||
**옵션 B: 웹+DB 한 대 (소규모)**
|
||||
- **Server** 1대: Apache + PHP + CI4 + MariaDB 모두 설치.
|
||||
- 구성이 단순하고 비용 최소. 트래픽·데이터가 적을 때 적합. 백업·스냅샷으로 복구 대비.
|
||||
|
||||
공통으로 필요한 것:
|
||||
- **PHP 8.4**, **Apache 2.4**, **MariaDB 11.x** — 로컬 개발과 동일 버전 권장.
|
||||
- **CI4** `env` 를 `production` 으로, `baseURL`, `database.*`, `session.*` 등 운영값으로 설정.
|
||||
- **디렉터리 권한**: `writable/` 쓰기 가능, `app/Config/` 등은 읽기만.
|
||||
- **방화벽**: 80/443만 개방, 22(SSH)는 지정 IP만. DB 포트(3306)는 웹 서버에서만 접근 가능하도록.
|
||||
|
||||
---
|
||||
|
||||
## 4. 지자체별 “내부 서버 vs 클라우드” 공존
|
||||
|
||||
06 개발계획·25.11.24 메모에 따르면:
|
||||
- **지자체 내부 서버 설치형**을 우선 고려하면서,
|
||||
- **외부 서버/클라우드형**도 지원하는 **유연한 구조**가 영업상 유리하다는 의견이 있었습니다.
|
||||
|
||||
따라서 실제 구성은 다음처럼 나뉠 수 있습니다.
|
||||
|
||||
| 고객/지자체 | 구성 |
|
||||
|-------------|------|
|
||||
| **클라우드 사용** (우리 쪽 또는 지자체 NCP) | NCP Server + DB for MySQL(또는 Server에 MariaDB) 위에 CI4 배포. 위 2~3절 참고. |
|
||||
| **지자체 내부 서버** | 지자체가 제공한 물리/가상 서버에 Apache + PHP + MariaDB 직접 설치 후 동일 CI4 소스 배포. |
|
||||
|
||||
애플리케이션(CI4)은 **웹 서버 + DB 주소만 설정**하면 되므로, “실물 서버”이든 “네이버 클라우드”이든 **동일 소스로 배포**할 수 있게 두는 것이 좋습니다.
|
||||
즉, **실제 어떤 식으로 구성해야 하냐**는 “네이버 클라우드를 쓸 때”는 위와 같이 하고, “지자체 내부 서버를 쓸 때”는 그 서버에 맞춰 PHP/Apache/MariaDB만 설치해 같은 방식으로 구성하면 됩니다.
|
||||
|
||||
---
|
||||
|
||||
## 5. 정리
|
||||
|
||||
- **네이버 클라우드 사용 시**: 웹·앱은 **Server**에 PHP + Apache + CI4, DB는 **DB for MySQL(MariaDB)** 또는 Server 한 대에 MariaDB 설치. 필요 시 로드밸런서·Object Storage·SSL 추가.
|
||||
- **실제 서비스 서버가 아직 미정**이므로, 위 구성을 “클라우드 선택 시 참고용”으로 두고, 확정되면 **도메인·SSL·백업·모니터링**까지 구체 계획을 잡으면 됩니다.
|
||||
- 지자체별로 **내부 서버 / 클라우드**가 다를 수 있으므로, **동일 소스·환경 변수만 바꾸어 배포**할 수 있게 유지하는 것이 좋습니다.
|
||||
173
docs/기본 개발계획/16-web-development-duration-estimate.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# 종량제 웹 버전 개발 기간 산정
|
||||
|
||||
**웹 기능만** (Phase 1~10, 모바일앱 Phase 11 제외) 기준으로, **얼마나 걸릴지** 단계별·인원별로 계산한 개요입니다.
|
||||
실제 일정은 인력·요구 변경·테스트 기간에 따라 달라질 수 있으므로 참고용으로 사용합니다.
|
||||
|
||||
---
|
||||
|
||||
## 1. 범위 (웹만)
|
||||
|
||||
- **01-web-features.md** 기준 **63건** 기능.
|
||||
- **06-development-plan.md** Phase **1~10** (Phase 11 모바일앱 제외).
|
||||
- 공통·인증 → 관리자·메뉴 → 기본정보 → 발주/입고 → 불출 → 재고/실사 → 주문·판매 → 판매현황 → 수불 → 스캔 조회 순으로 의존 관계 있음.
|
||||
|
||||
---
|
||||
|
||||
## 2. Phase별 공수 가정 (1인 기준)
|
||||
|
||||
| Phase | 내용 | 예상 공수 (1인) | 비고 |
|
||||
|-------|------|-----------------|------|
|
||||
| **1** | 공통·인증 (로그인/로그아웃/로그/비식별화) | **2~3주** | auth 참고, CI4 재구현. 2차인증·5회 lock은 2단계에서 |
|
||||
| **2** | 관리자·메뉴 (메뉴·권한·사용자·로그인이력·승인) | **4~5주** | auth admin 이식, 레이아웃·권한별 메뉴 |
|
||||
| **3** | 기본정보 (코드·단가·포장단위·대행소·담당자·업체·무료대상자·지정판매소·비밀번호변경) | **6~8주** | CRUD 다수. 지정판매소(지도·바코드·엑셀) 비중 큼 |
|
||||
| **4** | 발주·입고 (발주 등록/변경/삭제, LOT·바코드, 스캐너 입고, 일괄입고, 현황) | **6~8주** | LOT·PDF417·암호화·스캐너 연동 등 복잡 |
|
||||
| **5** | 불출 (무료용 불출 현황·처리·취소) | **2~3주** | 재고·판매 연동 |
|
||||
| **6** | 재고·실사 (재고 조회, 실사 선별·조회) | **2~3주** | Phase 4·5 데이터 기반 |
|
||||
| **7** | 주문·판매 (전화접수·지정판매소 판매/취소/반품) | **5~6주** | 가상계좌·주문플로우. PG/Webhook은 고도화 시 별도 |
|
||||
| **8** | 판매 현황 (대장·일계표·기간별·년도별·판매소별·홈택스) | **4~5주** | 리포트·엑셀·인쇄 |
|
||||
| **9** | 봉투 수불 (기타 입출고·수불현황·반품파기·수급계획·LOT 수불) | **3~4주** | 수불 이력·조회 |
|
||||
| **10** | 봉투 스캔 (스캔 횟수/위치 조회) | **1~2주** | 앱 스캔 데이터 조회, 지도 옵션 |
|
||||
|
||||
**Phase 1~10 합계 (1인)**
|
||||
- 낙관: 2+4+6+6+2+2+5+4+3+1 = **35주**
|
||||
- 보수: 3+5+8+8+3+3+6+5+4+2 = **47주**
|
||||
- **중간값**: 약 **40~42주 (10~11개월)**.
|
||||
|
||||
---
|
||||
|
||||
## 3. 버퍼·통합·테스트
|
||||
|
||||
- **요구 확정·변경**: Phase 진행 중 스펙 정리·변경 반영 — **+10~15%**.
|
||||
- **통합 테스트·버그 수정**: Phase 7~8 완료 후 전체 플로우 검증 — **+2~3주**.
|
||||
- **검수·설치 테스트**: 06·25.11.24 기준 “약 1개월” 전제 — **+4주** (병행 가능).
|
||||
|
||||
반영 시 **1인 기준 순수 개발 40주 + 버퍼 4~6주 + 통합/검수 4~6주** → **약 48~52주 (12~13개월)**.
|
||||
|
||||
---
|
||||
|
||||
## 4. 인원별 예상 기간 (웹만, 달력 기준)
|
||||
|
||||
| 인원 | 순수 개발 (Phase 1~10) | 버퍼·통합·검수 포함 | 비고 |
|
||||
|------|------------------------|----------------------|------|
|
||||
| **1인** | 약 10~11개월 | **약 12~13개월** | Phase 순차 진행. 병목 없음. |
|
||||
| **2인** | 약 5~6개월 | **약 7~8개월** | Phase 1·2 후 역할 분담(예: 1명 기본정보·발주, 1명 판매·현황). 의존 관계상 완전 병렬은 어려움. |
|
||||
| **3인** | 약 4~5개월 | **약 6~7개월** | Phase 3 이후 모듈 분할. 통합·테스트 기간 필요. |
|
||||
|
||||
- **“웹 버전만 만드는데 얼마나 걸리나”** → **1인 기준 약 12~13개월**, **2인 기준 약 7~8개월** 정도로 보면 됩니다.
|
||||
- 이미 문서에 있던 “2026년 말 기능 완료·2027년 초 오픈”과 맞추려면 **2인 이상**이면 2026년 2~3월 전후 착수 시 가능한 구간에 들어갑니다.
|
||||
|
||||
---
|
||||
|
||||
## 5. 전제·가정
|
||||
|
||||
- **요구사항**: 01-web-features, 04-menu-structure, 03-basic-codes 등 현재 문서 기준. 대규모 추가/삭제 시 공수 재산정 필요.
|
||||
- **참조**: auth(메뉴·회원)·기존 레거시 동작 참고. 전부 신규 설계가 아님.
|
||||
- **복잡 기능**: LOT·바코드(PDF417)·스캐너 연동·가상계좌·홈택스는 “1차 수준” 구현 가정. API·외부 연동 고도화는 별도 기간.
|
||||
- **블록체인/불변 원장**: v1에서는 RDBMS 이력만. 블록체인 확장은 별도 Phase.
|
||||
- **PDA 동기화·오프라인**: 25.11.24 메모에 있으나, 웹 1차 범위에서 “동기화 로직” 수준만 반영 가능하다고 보면, 상세 설계에 따라 공수 추가 가능.
|
||||
|
||||
---
|
||||
|
||||
## 6. AI를 적극 사용한다고 가정할 때
|
||||
|
||||
**전제**: 개발자가 Cursor·GitHub Copilot·ChatGPT 등으로 **코드 생성·리팩터·문서 작성·단위 테스트 초안**을 꾸준히 활용하고, 생성 결과를 검토·수정하면서 진행한다고 가정.
|
||||
|
||||
**AI로 단축되기 쉬운 부분**
|
||||
- CRUD·폼·리스트·마이그레이션·시더: 템플릿·패턴이 명확해 **20~35%** 단축 가능.
|
||||
- auth 이식(로그인·메뉴·권한): 문서·기존 코드 참고 시 **초안 작성·보일러플레이트** 단축.
|
||||
- 공통 로직·헬퍼·검증 규칙: 반복 작업 감소.
|
||||
- 문서·주석·테스트 케이스 초안: 작성 시간 감소.
|
||||
|
||||
**AI로 단축되기 어려운 부분**
|
||||
- **요구사항 확정·의사결정**: 사람이 해야 함.
|
||||
- **복잡 비즈니스 로직**(LOT·바코드 규칙, 수불·재고 계산, 주문 플로우): 검증·디버깅은 개발자 부담.
|
||||
- **스캐너·하드웨어 연동**, **외부 API**(PG·홈택스): 연동·테스트는 그대로.
|
||||
- **통합 테스트·버그 수정·검수**: 자동화되지 않으면 공수 유사.
|
||||
|
||||
**공수 감소 가정**
|
||||
- **순수 개발(Phase 1~10)**: 위 구간에 한해 **약 25~30%** 단축 가능하다고 보면,
|
||||
- 1인: 40~42주 → **약 28~32주 (7~8개월)**
|
||||
- 2인: 20~24주 → **약 14~18주 (3.5~4.5개월)**
|
||||
- **버퍼·통합·검수**는 AI 영향이 제한적이라 **기존과 비슷**하게 둠 (+4~6주).
|
||||
- **AI 적극 사용 시 총 기간**
|
||||
- **1인**: 28~32주 + 4~6주 ≈ **32~38주 (약 8~10개월)**
|
||||
- **2인**: 14~18주 + 4~6주 ≈ **18~24주 (약 4.5~6개월)**
|
||||
|
||||
| 인원 | 기존 (AI 없음) | AI 적극 사용 시 |
|
||||
|------|----------------|-----------------|
|
||||
| **1인** | 약 12~13개월 | **약 8~10개월** |
|
||||
| **2인** | 약 7~8개월 | **약 4.5~6개월** |
|
||||
|
||||
**정리**: AI를 적극 쓰면 **1인 기준 약 3~4개월, 2인 기준 약 2~2.5개월** 정도 단축될 수 있다고 보는 수준. 실제는 툴 숙련도·요구 변경·검수 강도에 따라 달라짐.
|
||||
|
||||
---
|
||||
|
||||
## 7. Electron 데스크톱 추가 시 기간
|
||||
|
||||
**전제**: 웹(CI4) 완성 후 **Electron**으로 설치형 데스크톱을 만든다. (Electron이 로컬에서 PHP 서버를 띄우고, 창으로 CI4 웹을 띄우는 방식. `17-desktop-packaging-options.md` §2.3 참고.)
|
||||
|
||||
**Electron 추가 공수 (웹 완료 이후)**
|
||||
|
||||
| 작업 | 예상 (1인) | 비고 |
|
||||
|------|-------------|------|
|
||||
| Electron 프로젝트 구성, 메인 프로세스(PHP 서버 기동·종료, BrowserWindow) | 1~2주 | Node.js·child_process로 PHP 실행, localhost 대기 후 로드 |
|
||||
| PHP 런타임 + CI4 앱 번들링, (선택) MariaDB 포터블/SQLite | 1~2주 | 경로·환경변수·DB 연결 설정 |
|
||||
| 패키징(electron-builder 등)·설치 프로그램(NSIS 등) | 0.5~1주 | exe/설치형 산출물 |
|
||||
| 타깃 OS 테스트(Windows, 필요 시 Mac) | 1~2주 | 실제 PC에서 기동·종료·재설치 시나리오 |
|
||||
|
||||
**합계**: **약 3.5~7주 (약 1~1.5개월)**. 2인이면 2~4주로 단축 가능.
|
||||
웹 개발과 **일부 병렬** 가능(예: 웹 Phase 8~9 진행 중 1명이 Electron 셋업 착수)하면, **달력상 추가는 약 0.5~1개월** 정도로 볼 수 있음.
|
||||
|
||||
**웹 + Electron 총 기간**
|
||||
|
||||
| 인원 | 웹만 | 웹 + Electron (순차) | 웹 + Electron (병렬 시) |
|
||||
|------|------|----------------------|-------------------------|
|
||||
| **1인** | 12~13개월 | **약 13~14.5개월** | **약 12.5~14개월** |
|
||||
| **2인** | 7~8개월 | **약 7.5~9개월** | **약 7.5~8.5개월** |
|
||||
| **1인 (AI 사용)** | 8~10개월 | **약 9~11개월** | **약 8.5~10.5개월** |
|
||||
| **2인 (AI 사용)** | 4.5~6개월 | **약 5~6.5개월** | **약 5~6개월** |
|
||||
|
||||
Electron을 쓰기로 했으면 **웹 기간 + 약 1~1.5개월**(순차) 또는 **+0.5~1개월**(병렬) 정도로 보면 됨.
|
||||
|
||||
---
|
||||
|
||||
## 8. 공휴일·주말·휴가 제외 시 달력 기준 (착수 3월 3일 가정)
|
||||
|
||||
**전제**: 공휴일·주말·**월 1일 휴가**·**여름휴가 1주(5일)** 를 제외하고만 작업. 착수일 **2025년 3월 3일** 기준.
|
||||
|
||||
**가용 작업일**
|
||||
- 1년 기준: 365 − 104(주말) − 15(공휴일) − 12(월 1일 휴가) − 5(여름휴가) ≈ **229일**.
|
||||
- 월평균: **약 19일** (일반적인 20~21일/월 가정보다 적음).
|
||||
|
||||
**기간 환산**
|
||||
- 기존 "12개월" = 12 × 20 = 240 인·일 가정 시 → **달력상 240 ÷ 19 ≈ 12.6개월**.
|
||||
- 기존 "8개월"(AI 사용) = 8 × 20 = 160 인·일 → **달력상 160 ÷ 19 ≈ 8.4개월**.
|
||||
|
||||
**착수 3월 3일 기준 예상 완료 시점**
|
||||
|
||||
| 시나리오 | 기존 기간 | 공휴·휴가 제외 반영 | 완료 시점 (대략) |
|
||||
|----------|-----------|----------------------|-------------------|
|
||||
| 1인, 웹만 | 12~13개월 | **약 13~14개월** | **2026년 4월~5월** |
|
||||
| 1인, 웹만, AI 사용 | 8~10개월 | **약 8.5~10.5개월** | **2025년 11월~2026년 1월** |
|
||||
| 2인, 웹만 | 7~8개월 | **약 7.5~8.5개월** | **2025년 10월~11월** |
|
||||
| 2인, 웹만, AI 사용 | 4.5~6개월 | **약 5~6.5개월** | **2025년 8월~9월** |
|
||||
| 1인, 웹+Electron | 13~14.5개월 | **약 14~15개월** | **2026년 5월~6월** |
|
||||
| 1인, 웹+Electron, AI | 9~11개월 | **약 9.5~11.5개월** | **2025년 12월~2026년 2월** |
|
||||
|
||||
- 위 완료 시점은 **시작일 3월 3일**부터의 달력 일수로 환산한 것이며, 공휴일·휴가가 예상대로만 있을 때의 참고치입니다.
|
||||
- 여름휴가·공휴일이 더 많거나, 월 1일 휴가가 늘어나면 가용 일수가 줄어 **완료는 더 늦어질 수** 있습니다.
|
||||
|
||||
---
|
||||
|
||||
## 9. 요약
|
||||
|
||||
| 질문 | 답 |
|
||||
|------|----|
|
||||
| 웹만 만들면 얼마나 걸리나? | **1인 약 12~13개월, 2인 약 7~8개월** (버퍼·통합·검수 포함). |
|
||||
| AI 적극 사용하면? | **1인 약 8~10개월, 2인 약 4.5~6개월** (순수 개발 25~30% 단축 가정). |
|
||||
| Electron 데스크톱까지? | **웹 기간 + 약 1~1.5개월** (순차). 병렬 시 **+0.5~1개월**. |
|
||||
| 순수 개발만? | 1인 약 10~11개월, 2인 약 5~6개월. (AI 사용 시 1인 7~8개월, 2인 3.5~4.5개월) |
|
||||
| 2026년 말 완료 가능? | 2인 이상·2026년 초 착수 시 가능 구간. 1인만이면 2026년 말은 촉박. **AI 적극 사용 시 1인도 2026년 초 착수면 2026년 말 완료 가능 구간.** |
|
||||
| 3/3 착수, 공휴·주말·월1휴가·여름1주 제외 시? | 1인 웹만 **약 13~14개월** → 2026년 4~5월. 1인+AI **약 8.5~10.5개월** → 2025년 11월~2026년 1월. 2인+AI **약 5~6.5개월** → 2025년 8~9월. (§8 참고) |
|
||||
|
||||
이 문서는 회의·예산·일정 논의 시 참고용으로 사용하면 됩니다.
|
||||
81
docs/기본 개발계획/17-desktop-packaging-options.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# CI4 웹 버전 완성 후 설치형 데스크톱으로 만들 때 사용 기술
|
||||
|
||||
웹 버전(CI4 + PHP + MariaDB)이 완성된 뒤, **설치형 데스크톱**으로 제공할 때 고려할 수 있는 기술·방식입니다.
|
||||
|
||||
**선택**: **Electron 방식** 사용 예정. (로컬 PHP 서버 기동 + Electron 창에서 CI4 웹 로드. 기간 영향은 `16-web-development-duration-estimate.md` §7 참고.)
|
||||
|
||||
---
|
||||
|
||||
## 1. 전제
|
||||
|
||||
- **CI4 앱** = 서버에서 PHP가 HTML을 렌더링하는 **서버 사이드** 구조.
|
||||
- “설치형 데스크톱” = 사용자 PC에 **설치 파일(또는 포터블)** 로 제공하고, 실행하면 **창 하나로** 앱처럼 쓰는 형태.
|
||||
|
||||
이걸 만드는 방식은 크게 두 가지입니다.
|
||||
|
||||
1. **웹 앱을 그대로 두고, “데스크톱 껍데기”만 씌우기**
|
||||
→ 로컬에서 PHP + 웹 서버를 띄우고, 그걸 **내장 브라우저**로 보여 주는 방식.
|
||||
→ **사용 기술**: PHP Desktop(Chromium 임베드), ExeOutput for PHP, 또는 Electron + 로컬 PHP 서버 등.
|
||||
|
||||
2. **웹을 API 서버로 바꾸고, 데스크톱 전용 클라이언트를 새로 만들기**
|
||||
→ CI4는 REST API만 제공하고, 데스크톱 앱은 **Electron / Tauri / Qt** 등으로 **별도 클라이언트** 개발.
|
||||
→ 웹 UI를 대폭 수정하거나, 데스크톱만의 UI를 만드는 작업이 필요.
|
||||
|
||||
지자체 **내부 서버 설치형**이면 “웹을 브라우저로 접속”만 해도 되고,
|
||||
**진짜 PC 한 대에 단독 설치**해서 쓰는 “데스크톱 앱”이 필요할 때만 아래 기술을 쓰면 됩니다.
|
||||
|
||||
---
|
||||
|
||||
## 2. 웹 그대로 둔 상태에서 데스크톱 껍데기 (추천 후보)
|
||||
|
||||
CI4 소스를 거의 수정하지 않고, **로컬에서 PHP + DB를 돌리고 창으로 보여 주는** 방식입니다.
|
||||
|
||||
### 2.1 PHP Desktop (phpdesktop)
|
||||
|
||||
- **역할**: **Chromium(Chrome 엔진)** 을 내장한 창에서 **로컬 PHP 앱**을 실행.
|
||||
- **구성**: PHP 실행 파일 + Chromium + 프로젝트 폴더를 묶어서, 실행 시 **내장 웹 서버** 또는 **PHP 내장 서버**로 CI4를 띄우고, 그 주소를 Chromium 창에 띄움.
|
||||
- **특징**: 오픈소스, 무료. PHP 기반 웹 앱을 exe/설치형으로 감쌀 때 자주 쓰임.
|
||||
- **한계**: DB(MariaDB)는 별도 설치하거나, SQLite로 바꾸거나, 포터블 MariaDB를 번들해야 함.
|
||||
- **참고**: [phpdesktop](https://github.com/cztomczak/phpdesktop) (GitHub).
|
||||
|
||||
### 2.2 ExeOutput for PHP (상용)
|
||||
|
||||
- **역할**: PHP 스크립트를 **exe로 패키징**해 주는 상용 도구.
|
||||
- **특징**: 설치형/포터블 배포, 인스톨러 제작 등 지원. PHP Desktop과 개념적으로 비슷(로컬 PHP + 브라우저 창).
|
||||
- **참고**: ExeOutput for PHP 제품 문서.
|
||||
|
||||
### 2.3 Electron + 로컬 PHP 서버
|
||||
|
||||
- **역할**: **Electron** 앱이 사용자 PC에서 **PHP 내장 서버**(또는 소형 웹 서버)를 기동하고, Electron 창에서 `http://localhost:...` 로 CI4 웹을 띄움.
|
||||
- **특징**: Node.js 생태계 활용 가능. 다만 PHP 실행 파일·런타임을 함께 묶고, 기동/종료 스크립트를 직접 짜야 함.
|
||||
- **기술**: **Electron**, **Node.js**, (선택) **node-php** 또는 **child_process**로 PHP 프로세스 실행.
|
||||
|
||||
이 경우 **“사용하는 기술”**은
|
||||
**PHP Desktop** 이라면 **PHP + Chromium(CEF) + (선택) SQLite/포터블 MariaDB**,
|
||||
**Electron** 이라면 **Electron + Node.js + PHP 런타임 번들** 이라고 보면 됩니다.
|
||||
|
||||
---
|
||||
|
||||
## 3. API 분리 후 데스크톱 클라이언트만 새로 만들기
|
||||
|
||||
- **역할**: CI4는 **REST API 전용**으로 두고, 데스크톱 앱은 **전용 클라이언트**를 따로 만듦.
|
||||
- **데스크톱 쪽 기술 예**:
|
||||
- **Electron** (HTML/CSS/JS + Node) — 웹 기술 그대로 사용.
|
||||
- **Tauri** (Rust + 웹뷰) — 바이너리 크기·리소스가 Electron보다 작음.
|
||||
- **Qt + C++/Python** — 네이티브 UI.
|
||||
- **특징**: 웹 UI와 데스크톱 UI를 나눌 수 있지만, **CI4를 API 서버로 바꾸는 작업 + 클라이언트 개발**이 들어가서 공수가 큼. “웹 버전 완성 후 데스크톱만 추가”라기보다는 아키텍처 변경에 가깝습니다.
|
||||
|
||||
---
|
||||
|
||||
## 4. 정리 (질문에 대한 답)
|
||||
|
||||
**“CI4 웹 버전이 완성되면, 설치형 데스크톱으로 만들 때 사용하는 기술은 뭐냐?”**
|
||||
|
||||
- **웹 구조를 최대한 유지**하면서 데스크톱처럼 쓰게 하려면:
|
||||
**PHP Desktop(Chromium + PHP)** 또는 **Electron + 로컬 PHP 서버** 같은 **“로컬 PHP 웹 앱 + 내장 브라우저 창”** 조합을 쓰게 됩니다.
|
||||
DB는 **로컬 MariaDB 설치** 또는 **SQLite 전환** 등을 함께 결정해야 합니다.
|
||||
|
||||
- **데스크톱 전용 클라이언트**를 새로 만든다면:
|
||||
**Electron**, **Tauri**, **Qt** 등이 후보이고, 이때는 CI4는 **백엔드 API** 역할만 하게 됩니다.
|
||||
|
||||
현재 문서상으로는 “설치형”이 **지자체 내부 서버에 웹을 설치해 브라우저로 접속**하는 형태인지, **PC 한 대 단독 설치형 데스크톱 exe**를 원하는지가 명확하지 않으므로, 위 두 가지를 모두 후보로 두고 요구가 확정되면 하나를 골라 쓰면 됩니다.
|
||||
72
docs/기본 개발계획/18-mobile-app-technology-options.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# 모바일 앱 버전 개발 시 사용 기술 후보
|
||||
|
||||
웹(CI4)이 완성된 뒤 **모바일 앱**을 만들 때, 어떤 기술을 쓰면 좋을지 정리한 문서입니다.
|
||||
`02-mobile-features.md` 기준 **PDF417 카메라 스캔·상하 2분할 화면·바코드 연동**이 필요하므로, **카메라/바코드 API**를 안정적으로 쓸 수 있는 선택이 중요합니다.
|
||||
|
||||
---
|
||||
|
||||
## 1. 전제
|
||||
|
||||
- **백엔드**: CI4 웹과 동일. 모바일은 **REST API**로 CI4와 통신한다고 가정. (CI4에 모바일용 API 라우트·인증 추가 필요.)
|
||||
- **필요 기능**: 로그인, PDF417/바코드 스캔, 입고/불출/판매/반품 처리, 주문 조회, 정품 인증 등. (`02-mobile-features.md` 15건.)
|
||||
- **플랫폼**: iOS + Android 모두 대상이라면 **한 번 개발해 두 플랫폼에 배포**하는 크로스플랫폼이 유리.
|
||||
|
||||
---
|
||||
|
||||
## 2. 기술 후보 비교
|
||||
|
||||
| 기술 | 한 줄 설명 | 장점 | 단점 | 바코드/카메라 |
|
||||
|------|------------|------|------|----------------|
|
||||
| **React Native** | JS/React로 iOS·Android 앱 한 코드베이스 | 생태계·인력 많음, CI4 API 연동 쉬움, PDF417 등 라이브러리 풍부 | 네이티브 모듈 이슈 시 디버깅 난이도 있음 | ✅ 라이브러리 많음 |
|
||||
| **Expo (React Native)** | React Native + 빌드/배포 도구 | 설정 간단, OTA 업데이트, 카메라/바코드 Expo 모듈 제공 | 네이티브 코드 커스텀 시 EAS 등 필요 | ✅ expo-camera, 스캔 가능 |
|
||||
| **Flutter** | Dart, 구글 제안 크로스플랫폼 | 성능·UI 일관성 좋음, 한 코드베이스 | Dart 학습, PHP 팀과 스택 다름 | ✅ mobile_scanner 등 패키지 |
|
||||
| **Capacitor + Vue/React** | 웹(HTML/JS)을 네이티브 앱으로 감쌈 | 웹 기술 재사용, CI4 팀이 웹만 해도 진입 가능 | 성능·네이티브 느낌은 RN/Flutter보다 떨어질 수 있음 | ✅ 플러그인으로 카메라/바코드 |
|
||||
| **PWA** | 웹을 “앱처럼” 설치 | 추가 앱 빌드 없음, CI4 그대로 활용 | 카메라/바코드 제한, 앱스토어 배포 어려움, 오프라인 제한 | ⚠️ 제한적 |
|
||||
| **네이티브 (Swift + Kotlin)** | iOS·Android 각각 개발 | 성능·UX 최고 | 두 코드베이스, 인력·기간 2배 | ✅ 완전 제어 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 추천 방향
|
||||
|
||||
### 3.1 **1순위: React Native 또는 Expo**
|
||||
|
||||
- **이유**
|
||||
- CI4를 **REST API**로 두고, 앱은 **JS/React**로만 개발하면 됨. 백엔드(PHP) 팀과 프론트(JS) 역할 나누기 쉬움.
|
||||
- **PDF417·바코드 스캔**용 라이브러리(예: `react-native-camera`, `expo-barcode-scanner`)가 많고, 상하 2분할 레이아웃도 React로 구현 가능.
|
||||
- 인력 구하기 쉽고, Electron(웹 기술)과는 다르지만 “한 번 배우면 iOS·Android 동시”라 공수 절감.
|
||||
- **Expo**를 쓰면 초기 설정·카메라/바코드 연동이 더 빠르고, 나중에 네이티브 모듈이 필요하면 **EAS Build** 등으로 전환 가능.
|
||||
- **구성 예**: CI4 (API) + React Native 또는 Expo (앱) + JWT 또는 세션 기반 인증.
|
||||
|
||||
### 3.2 **2순위: Flutter**
|
||||
|
||||
- **이유**
|
||||
- 한 코드베이스로 iOS·Android, UI·성능이 좋고, `mobile_scanner` 등으로 바코드 스캔 지원.
|
||||
- **단점**
|
||||
- Dart 언어·Flutter 프레임워크를 새로 익혀야 함. PHP만 하던 팀이면 학습 부담이 React보다 클 수 있음.
|
||||
|
||||
### 3.3 **3순위: Capacitor + Vue/React**
|
||||
|
||||
- **이유**
|
||||
- 웹 개발자만 있어도 **Vue/React**로 화면 만들고, **Capacitor**로 감싸서 앱 배포 가능. CI4는 API 또는 기존 웹 화면을 iframe/웹뷰로 부를 수도 있음.
|
||||
- **단점**
|
||||
- PDF417 등 **고성능 연속 스캔**·복잡한 제스처에서는 네이티브나 React Native보다 손댈 부분이 많을 수 있음.
|
||||
|
||||
### 3.4 **PWA**
|
||||
|
||||
- **이유**
|
||||
- CI4 웹을 **반응형**으로 만들고, PWA로 “홈에 추가”만 해도 간단한 모바일 활용 가능.
|
||||
- **한계**
|
||||
- `02-mobile-features`의 **카메라 연속 스캔·바코드 중심** 플로우에는 제한이 있고, 앱스토어 배포·오프라인 동기화도 제약이 있음. **보조용** 또는 **스캔 없는 조회 전용**에 가깝게 보는 것이 좋음.
|
||||
|
||||
---
|
||||
|
||||
## 4. 정리 (질문에 대한 답)
|
||||
|
||||
**“모바일 앱 버전도 만들어야 하는데 어떤 기술을 사용하면 좋을까?”**
|
||||
|
||||
- **우선 추천**: **React Native** 또는 **Expo**.
|
||||
CI4를 API 서버로 두고, **한 코드베이스로 iOS·Android**를 만들 수 있고, **PDF417·바코드 스캔**과 **상하 2분할 UI** 구현에 적합하며, 인력·자료도 많음.
|
||||
- **대안**: **Flutter** (성능·UI 중시, Dart 학습 가능할 때), **Capacitor + Vue/React** (웹 인력만 있을 때).
|
||||
- **PWA**는 스캔·오프라인 요구가 적은 “조회 위주” 보조 수단으로만 고려하는 편이 좋음.
|
||||
|
||||
모바일 개발 공수·일정은 웹·Electron 완료 후, 선택한 기술과 API 설계가 정해진 뒤 **16번 문서 방식으로 별도 산정**하는 것이 좋습니다.
|
||||
88
docs/기본 개발계획/19-db-personal-data-encryption.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# DB 개인정보 보안·암호화 방안 (개발자도 알 수 없게)
|
||||
|
||||
“DB 보안을 중요시하고, **개발자도 사용자 개인정보를 알 수 없게** 꼼꼼히 암호화한다”는 요구에 맞춘 설계·구현 방향입니다.
|
||||
|
||||
---
|
||||
|
||||
## 1. 목표
|
||||
|
||||
- **DB에 저장되는 개인정보**를 **암호화**해, DB만 접근하는 사람(개발자, DBA, 백업 유출 시)이 **평문을 볼 수 없게** 한다.
|
||||
- **암호화 키**는 DB나 소스코드 저장소에 두지 않고, **환경 변수·시크릿 관리**에만 둔다.
|
||||
- 비밀번호는 **해시만** 저장(복호화 불가). 이름·휴대전화·이메일 등 **복구가 필요한 값**만 **대칭키 암호화**로 저장한다.
|
||||
|
||||
---
|
||||
|
||||
## 2. 무엇을 어떻게 다룰지
|
||||
|
||||
| 데이터 종류 | 처리 방식 | 이유 |
|
||||
|-------------|------------|------|
|
||||
| **비밀번호** | **해시만** (`password_hash` / bcrypt·argon2) | 복호화 불필요. 로그인 시 `password_verify`만 하면 됨. DB 유출돼도 평문 복원 불가. |
|
||||
| **이름, 휴대전화, 이메일** 등 | **저장 전 암호화**, 조회 시 **애플리케이션에서만 복호화** | DB에는 암호문만 저장. 키가 없으면 개발자도 평문을 알 수 없음. |
|
||||
| **로그·감사 이력** | 개인정보 필드는 **암호화 저장** 또는 **마스킹만 저장** | 로그에 평문 개인정보가 쌓이지 않게 함. |
|
||||
|
||||
---
|
||||
|
||||
## 3. 필드 단위 암호화 (이름·전화·이메일)
|
||||
|
||||
### 3.1 방식
|
||||
|
||||
- **대칭키 암호화**(예: **AES-256-GCM** 또는 AES-256-CBC + HMAC) 사용.
|
||||
- **키**는 PHP `openssl` 등으로 생성해, **애플리케이션만** 사용. DB에는 키를 저장하지 않음.
|
||||
- **IV(초기화 벡터)** 는 암호화할 때마다 랜덤 생성하고, **암호문과 함께 저장** (IV는 공개돼도 됨, 키만 비밀).
|
||||
|
||||
### 3.2 키 보관 (개발자도 알 수 없게)
|
||||
|
||||
- **로컬/개발**: `.env`에 `ENCRYPTION_KEY=...` 형태로 둠. **`.env`는 Git에 넣지 않고**, `.env.example`에는 키 없이 변수명만 예시로 둠.
|
||||
- **운영**: 서버 환경 변수 또는 **시크릿 관리**(AWS Secrets Manager, HashiCorp Vault, 네이버 클라우드 시크릿 등)에 넣고, 앱 기동 시에만 읽어 씀.
|
||||
- **규칙**: 키가 **소스코드·DB·백업 파일**에 들어가지 않도록 한다. 개발자에게 DB만 주면 **암호문만 보이고**, 키 없이는 복호화 불가.
|
||||
|
||||
### 3.3 적용 위치 (CI4 예시)
|
||||
|
||||
- **옵션 A**: **암호화 헬퍼/라이브러리**를 두고, **Model**에서 `member` 등 저장·조회 시:
|
||||
- **INSERT/UPDATE 전**: `mb_name`, `mb_phone`, `mb_email` 등을 암호화해 DB에 넣음.
|
||||
- **SELECT 후**: 화면·비즈니스 로직에 넘기기 직전에만 복호화. 로그에는 복호화된 값이나 평문을 남기지 않음.
|
||||
- **옵션 B**: **Entity**에서 `mb_name` 등 접근 시 자동 암·복호화(Getter/Setter에서 처리). Model은 Entity를 쓰므로, 저장·조회 시 일관되게 암호화된 값만 DB에 쌓이게 함.
|
||||
|
||||
이렇게 하면 **DB 덤프를 열어도** 이름·전화·이메일은 **암호문**으로만 보이고, **키를 모르는 개발자**는 평문을 알 수 없다.
|
||||
|
||||
### 3.4 키 로테이션(선택)
|
||||
|
||||
- 주기적으로 **새 키**로 다시 암호화하는 정책. 구현 시 **키 버전**을 필드에 두고, 복호화 시 버전별 키로 풀 수 있게 하면 된다. 초기에는 단일 키로 시작해도 됨.
|
||||
|
||||
---
|
||||
|
||||
## 4. 비밀번호는 암호화가 아니라 해시
|
||||
|
||||
- **저장**: `password_hash($password, PASSWORD_DEFAULT)` (bcrypt 등)로 **해시만** 저장.
|
||||
- **검증**: `password_verify($input, $storedHash)`.
|
||||
- **복호화하지 않음**. 따라서 “개발자가 DB만 보고 비밀번호를 알 수 없다”는 건 해시를 쓰는 것만으로 만족됨. 이미 11번 문서 등에서 `password_verify` 전제로 되어 있음.
|
||||
|
||||
---
|
||||
|
||||
## 5. 비식별화(마스킹)와의 관계
|
||||
|
||||
- **PWB-010201-001** “이름·휴대전화 가림”은 **화면·로그에 보여줄 때** 마스킹(홍*동, 010-****-5678)하는 **비식별화**이다.
|
||||
- **DB 보안**을 위해선 그에 **더해** 위처럼 **저장 단계에서 암호화**를 하는 것이 좋다.
|
||||
- 저장: 암호화 → DB에는 암호문만.
|
||||
- 표시: 필요한 경우에만 복호화 후, 권한에 따라 **마스킹**해서 보여줌 (관리자만 전체 보기 등 정책에 따라).
|
||||
|
||||
---
|
||||
|
||||
## 6. 접근 제어·운영
|
||||
|
||||
- **DB 계정**: 애플리케이션 전용 계정만 최소 권한(SELECT/INSERT/UPDATE/DELETE 등 필요한 것만) 부여. 개발·운영 DB는 역할별로 분리하고, **개인정보가 있는 테이블**에 대한 직접 조회를 제한할 수 있으면 좋음.
|
||||
- **백업**: 백업 파일도 **암호문**만 포함하므로, 키가 유출되지 않는 한 개인정보 평문이 노출되지 않음. 백업 파일 자체도 암호화 저장 권장.
|
||||
- **감사 로그**: 개인정보 조회/복호화 이벤트를 로그에 남기면, 나중에 “누가 언제 복호화했는지” 추적 가능. (구현 여부는 정책에 따라.)
|
||||
|
||||
---
|
||||
|
||||
## 7. 구현 시 체크리스트
|
||||
|
||||
- [ ] 개인정보 필드(mb_name, mb_phone, mb_email 등) **저장 전 AES-256 등으로 암호화**.
|
||||
- [ ] **암호화 키**는 `.env` 또는 시크릿 관리에만 두고, **Git/DB에 포함하지 않음**.
|
||||
- [ ] 비밀번호는 **해시만** 저장, 복호화 로직 없음.
|
||||
- [ ] 복호화는 **애플리케이션에서만**, 필요한 권한이 있을 때만 수행. 로그에는 평문·복호화 결과를 남기지 않음.
|
||||
- [ ] 화면·로그에는 필요 시 **마스킹(비식별화)** 적용.
|
||||
- [ ] (선택) 키 로테이션·감사 로그 설계.
|
||||
|
||||
이렇게 하면 “개발자도 사용자 개인정보를 알 수 없게” DB 보안을 꼼꼼히 맞추는 방향이 됩니다. 구현은 Phase 1 후반 또는 Phase 2에서 **암호화 라이브러리/헬퍼 도입**과 **member 등 개인정보 테이블 적용**부터 진행하면 됩니다.
|
||||
30
docs/기본 개발계획/20-지자체_운영_방식_정리.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# 지자체 운영 방식 정리
|
||||
|
||||
> 지자체 단위 데이터 분리 시 **단일 테넌트 vs 멀티테넌트** 결정 및 테이블 설계 참조.
|
||||
|
||||
---
|
||||
|
||||
## 1. 자료상 명시 여부
|
||||
|
||||
- **자료에는** "지자체 1개당 시스템 1개" vs "한 시스템에서 여러 지자체(멀티테넌트)" 중 **어떤 방식으로 개발해야 하는지 명시되어 있지 않음.**
|
||||
- 기능·역할 설명 문맥상 **"각 지자체에서 시스템에 접속"**, super admin(wixon/서진)이 전 영역 관리한다는 표현으로 보아, **한 시스템에 여러 지자체가 접속하는 구조(멀티테넌트)** 를 전제로 한 설명에 가깝다.
|
||||
- **최종 결정**은 발주처·실무와 확인하는 것이 좋다.
|
||||
|
||||
---
|
||||
|
||||
## 2. 방식별 요약
|
||||
|
||||
| 방식 | 설명 | 참고 |
|
||||
|------|------|------|
|
||||
| **지자체 1개당 시스템 1개** | 지자체별로 DB·앱 인스턴스를 분리. 지자체 FK·테넌트 필터 불필요. | 구현 단순, 운영·패치는 지자체 수만큼 필요. |
|
||||
| **멀티테넌트** | 한 시스템·한 DB에서 여러 지자체 데이터를 `lg_idx` 등으로 구분. | 배포·패치 일원화 가능. 모든 지자체별 쿼리에 테넌트 필터 필수. |
|
||||
|
||||
---
|
||||
|
||||
## 3. 테이블 설계 참조
|
||||
|
||||
- **지자체별로 유저·정보를 나누고, 해당 지자체 데이터만 보이게** 하려면 테이블 설계는 **`docs/기본 개발계획/테이블/`** 폴더 문서를 따른다.
|
||||
- **목록·ERD**: `00-테이블_목록_및_ERD.md`
|
||||
- **마스터 DDL**: `01-마스터_테이블_DDL.md` (지자체, member 확장, 지정판매소, 기본코드, 대행소, 담당자, 업체, 무료대상자)
|
||||
- **물류·판매 DDL**: `02-물류_판매_테이블_DDL.md` (품목, 단가, 포장단위, 발주, 입고, 주문, 수불)
|
||||
- **필터·권한**: `03-지자체_데이터_필터_및_권한.md` (조회 시 lg_idx 적용 방법)
|
||||
97
docs/기본 개발계획/21-super_admin_지자체_선택_흐름.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Super Admin 지자체 선택 흐름
|
||||
|
||||
> Super admin이 로그인 시 지자체를 하나 선택한 뒤, 해당 지자체 관리자와 동일한 화면/권한으로 사용하고, 필요 시 지자체를 전환하는 방식 정리.
|
||||
|
||||
---
|
||||
|
||||
## 1. 목적
|
||||
|
||||
- Super admin이 **전체 지자체 데이터를 한꺼번에** 보지 않고, **선택한 한 지자체** 기준으로만 화면이 보이게 한다.
|
||||
- 지자체 관리자와 **동일한 UX**로 사용해 테스트·지원·교육을 단순화한다.
|
||||
- 실수로 다른 지자체 데이터를 조회·수정하는 것을 줄인다.
|
||||
|
||||
---
|
||||
|
||||
## 2. 흐름 요약
|
||||
|
||||
| 단계 | Super Admin | 지자체 관리자 |
|
||||
|------|-------------|----------------|
|
||||
| 로그인 직후 | **지자체 선택 화면**으로 이동 → 목록에서 하나 선택 | **관리자 대시보드**로 바로 이동 |
|
||||
| 관리자 사용 중 | 선택한 지자체의 데이터만 조회·등록·수정 (지자체 관리자와 동일) | 소속 지자체(`mb_lg_idx`) 데이터만 조회·등록·수정 |
|
||||
| 지자체 전환 | 상단 **「지자체 전환」** 메뉴로 선택 화면 이동 → 다른 지자체 선택 가능 | 해당 없음 (소속 지자체 고정) |
|
||||
| 지자체 등록/목록 | **「지자체」** 메뉴로 전체 지자체 CRUD (시스템 설정 용도) | 메뉴 비노출 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 세션·권한 규칙
|
||||
|
||||
### 3-1. 세션 값
|
||||
|
||||
- **`admin_selected_lg_idx`** (int|null)
|
||||
- Super admin이 **선택한 지자체 PK**.
|
||||
- 지자체 선택 화면에서 선택 시 설정, 지자체 전환 시 변경.
|
||||
- **지자체 관리자**
|
||||
- `mb_lg_idx`만 사용하며 `admin_selected_lg_idx`는 사용하지 않음.
|
||||
|
||||
### 3-2. “효과 지자체”(effective lg)
|
||||
|
||||
관리자 페이지에서 **데이터 필터·등록 시 사용하는 지자체**는 다음 규칙으로 결정한다.
|
||||
|
||||
| mb_level | 효과 지자체 |
|
||||
|----------|-------------|
|
||||
| 4 (Super Admin) | `session('admin_selected_lg_idx')` |
|
||||
| 3 (지자체 관리자) | `session('mb_lg_idx')` |
|
||||
|
||||
- 컨트롤러·쿼리에서는 위 값을 **effective lg_idx**로 사용해 `WHERE lg_idx = ?` 등을 적용한다.
|
||||
- 구현 시 헬퍼 `admin_effective_lg_idx()`로 일괄 조회한다.
|
||||
|
||||
### 3-3. 접근 제어
|
||||
|
||||
- **Super admin**
|
||||
- `admin_selected_lg_idx`가 **없으면** 관리자 대시보드 등 다른 admin URL 접근 시 **지자체 선택 화면(`/admin/select-local-government`)** 으로 리다이렉트.
|
||||
- `admin/select-local-government` 자체는 `admin_selected_lg_idx` 없이 접근 가능.
|
||||
- **지자체 관리자**
|
||||
- 지자체 선택 화면으로 보내지 않으며, 항상 `mb_lg_idx`로 동작.
|
||||
|
||||
---
|
||||
|
||||
## 4. 화면·메뉴
|
||||
|
||||
### 4-1. 지자체 선택 화면 (`/admin/select-local-government`)
|
||||
|
||||
- **노출 대상**: Super admin만 (지자체 관리자는 이 URL로 유도되지 않음).
|
||||
- **내용**: 사용 가능한 지자체(`lg_state=1`) 목록. 하나 선택 후 제출하면 `admin_selected_lg_idx` 저장 후 `/admin`으로 이동.
|
||||
- **지자체 전환**: 관리자 레이아웃 상단의 「지자체 전환」 클릭 시 동일 화면으로 이동해 다른 지자체 선택 가능.
|
||||
|
||||
### 4-2. 관리자 레이아웃
|
||||
|
||||
- **Super admin**
|
||||
- **지자체 전환**: 상단 메뉴에 표시, 클릭 시 `/admin/select-local-government` 이동.
|
||||
- **현재 선택 지자체**: 상단에 현재 선택된 지자체명 표시(선택된 경우).
|
||||
- **지자체**: 기존처럼 전체 지자체 CRUD용 메뉴 유지 (지자체 등록/목록).
|
||||
- **지자체 관리자**
|
||||
- 지자체 전환 메뉴 비노출, 지자체 메뉴(전체 CRUD) 비노출.
|
||||
|
||||
---
|
||||
|
||||
## 5. 기능별 동작
|
||||
|
||||
- **지정판매소 목록/등록**
|
||||
- Super admin: `admin_selected_lg_idx` 기준으로 해당 지자체 지정판매소만 조회·등록.
|
||||
- 지자체 관리자: `mb_lg_idx` 기준 (기존과 동일).
|
||||
- **지자체 목록/등록** (지자체 메뉴)
|
||||
- Super admin만 접근, 전체 지자체 조회·등록·수정.
|
||||
- “지자체 선택”과 분리: 선택 = 작업 컨텍스트, 지자체 메뉴 = 시스템 설정.
|
||||
|
||||
---
|
||||
|
||||
## 6. 구현 참고
|
||||
|
||||
| 구분 | 경로 |
|
||||
|------|------|
|
||||
| 필터 | `app/Filters/AdminAuthFilter.php` — Super admin이고 `admin_selected_lg_idx` 미설정 시 `admin/select-local-government`이 아니면 선택 페이지로 리다이렉트 |
|
||||
| 헬퍼 | `app/Helpers/admin_helper.php` — `admin_effective_lg_idx()` |
|
||||
| 지자체 선택 | `app/Controllers/Admin/SelectLocalGovernment.php`, `app/Views/admin/select_local_government/index.php` |
|
||||
| 라우트 | `GET/POST admin/select-local-government` |
|
||||
|
||||
- **문서**: `docs/기본 개발계획/테이블/03-지자체_데이터_필터_및_권한.md`와 연계.
|
||||
102
docs/기본 개발계획/22-판매소번호_일련번호_결정.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# 판매소번호 일련번호 부여 방식 결정
|
||||
|
||||
> 지정판매소 등록 시 **판매소번호(ds_shop_no)** 에 들어가는 **일련번호**를 전역으로 둘지, 구·동별·지자체별로 둘지에 대한 자료 정리 및 결정.
|
||||
|
||||
---
|
||||
|
||||
## 1. 자료에서 나온 내용
|
||||
|
||||
### 1-1. 웹 기능목록 (원본)
|
||||
|
||||
- **파일**: `docs/종량제 관련 자료/종량제 개발목록/종량제_개발목록_20260127(웹 기능목록) (1).csv`
|
||||
- **내용**
|
||||
- "**판매소번호** : 판매소의 **주소를 바탕으로** **기본코드 B, C, D + 판매소 일련번호**로 생성"
|
||||
- "**구코드** : 판매소의 주소를 바탕으로 **기본코드 C** 할당"
|
||||
- **의미**
|
||||
- 판매소번호 = (주소에서 유도한) B·C·D 코드 + **판매소 일련번호**
|
||||
- 일련번호를 **전역으로 둘지**, **구·동별·지자체별**로 둘지는 기술되어 있지 않음.
|
||||
|
||||
### 1-2. 결정 필요 문서
|
||||
|
||||
- **파일**: `docs/결정_필요한_사항들/01-DB_및_도메인_구조.md`
|
||||
- **내용**
|
||||
- "**판매소번호** 규칙: '기본코드 B, C, D + 판매소 일련번호' — 기본코드 B/C/D는 어디서 오는지(기본코드 테이블? 지자체별?). **일련번호는 전역인지 지자체별인지.**"
|
||||
- **의미**
|
||||
- 원본 자료만으로는 **일련번호 범위(전역 vs 지자체별 등)** 가 정해져 있지 않아, **결정 필요** 항목으로 남겨 둔 상태.
|
||||
|
||||
### 1-3. 기본코드·형식 참고
|
||||
|
||||
- **파일**: `docs/기본 개발계획/03-basic-codes.md`, `종량제_개발목록_20260127(기본코드 종류).csv`
|
||||
- **내용**
|
||||
- 판매소번호 = 기본코드 B, C, D + 판매소 일련번호.
|
||||
- 코드 C = 구코드(B + 구 순번 2자리), 코드 D = 동코드(C + 동 순번 2자리).
|
||||
- 예: 북구 110209, 동 11020901~11020928.
|
||||
- **의미**
|
||||
- 형식은 **“(구/동 등) 코드 + 일련번호”** 이지만, **일련번호를 어느 단위로 001부터 다시 세는지**는 문서에 없음.
|
||||
|
||||
---
|
||||
|
||||
## 2. 결정 사항
|
||||
|
||||
- **일련번호는 지자체별로 부여한다.**
|
||||
|
||||
| 항목 | 결정 내용 |
|
||||
|------|------------|
|
||||
| **일련번호 범위** | **지자체(lg_idx) 단위**로 001, 002, 003… 을 부여한다. |
|
||||
| **의미** | 같은 지자체에 속한 지정판매소만 모아서, 그 지자체 안에서 1번째, 2번째… 순으로 번호를 붙인다. |
|
||||
| **전역** | 사용하지 않는다. (전체 시스템에서 하나의 일련번호 줄을 두지 않음.) |
|
||||
| **구·동별** | 현재는 적용하지 않는다. 동(코드 D) 테이블·선택이 갖춰지면, 필요 시 “지자체 내 구·동별” 등으로 확장 검토 가능. |
|
||||
|
||||
### 2-1. 구현 시 적용
|
||||
|
||||
- 지정판매소 등록 시 **해당 지자체(ds_lg_idx)** 에 한정해,
|
||||
기존 `ds_shop_no` 중 **같은 지자체**로 이미 사용 중인 번호의 **일련번호 부분** 최대값을 구한 뒤, **+1** 한 값을 3자리(001, 002, …)로 패딩하여 사용한다.
|
||||
- 판매소번호 전체 형식은 아래 §3 단순 방식으로 확정한다.
|
||||
|
||||
---
|
||||
|
||||
## 3. 판매소번호 전체 형식 — 단순 방식 (결정)
|
||||
|
||||
자료상 "기본코드 B, C, D + 일련번호"가 있으나, **접두사는 지자체 정보만 사용하는 단순한 형식**으로 먼저 적용하기로 함.
|
||||
|
||||
| 항목 | 결정 내용 |
|
||||
|------|------------|
|
||||
| **형식** | **지자체 코드(lg_code) + 일련번호 3자리** |
|
||||
| **접두사** | `local_government.lg_code` (등록 시 선택/결정된 지자체의 코드). 예: 110201(중구), 110209(북구) |
|
||||
| **일련번호** | 해당 지자체(`ds_lg_idx`) 내에서 001, 002, 003 … (3자리, 앞자리 0 패딩) |
|
||||
| **결과 예** | `110209001`, `110209002` (북구 제1호, 제2호) |
|
||||
|
||||
### 3-1. 구현 규칙
|
||||
|
||||
- **생성 시점**: 지정판매소 등록 처리 시, 사용자 입력이 아닌 **시스템 자동 생성**.
|
||||
- **계산 방법**
|
||||
1. 등록 대상 지자체 `ds_lg_idx` 확정 (폼에서 선택된 지자체 또는 효과 지자체).
|
||||
2. 해당 지자체의 `lg_code` 조회 (예: `110209`).
|
||||
3. 동일 `ds_lg_idx`인 기존 지정판매소의 `ds_shop_no` 중, 접미사 3자리(일련번호 부분)의 최대값을 구한 뒤 **+1**.
|
||||
4. `ds_shop_no = lg_code + sprintf('%03d', 다음_일련번호)` (예: `110209` + `001`).
|
||||
- **구코드(ds_gugun_code)**
|
||||
- 판매소번호 생성에는 **사용하지 않음** (접두사는 lg_code만 사용).
|
||||
- **등록 시 자동 설정**: 소속 지자체가 한 구·군 단위이므로, 해당 지자체의 `local_government.lg_code`를 그대로 `ds_gugun_code`에 저장. 사용자 입력 없음. → §3-3 참고.
|
||||
- **동코드**
|
||||
- 현재 미적용. 필요 시 추후 "접두사 확장(동코드 포함)" 검토.
|
||||
|
||||
### 3-2. 확장 가능성
|
||||
|
||||
- 추후 "주소 기반 구코드(C)·동코드(D) 반영"이 필요하면, 접두사를 `ds_gugun_code` 또는 동코드까지 포함하는 형식으로 변경 검토.
|
||||
- 당분간은 **lg_code + 3자리 일련번호**로 통일.
|
||||
|
||||
### 3-3. 구코드(ds_gugun_code) 자동 등록 (결정)
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **결정** | 구코드는 **등록 시 시스템이 자동으로 부여**한다. 사용자 입력란 없음. |
|
||||
| **근거** | 지정판매소는 소속 지자체(`ds_lg_idx`)가 한 구·군을 의미하고, `local_government` 1행 = 1구·군이며 `lg_code`가 기본코드 C(구코드)와 동일함. |
|
||||
| **구현** | 지정판매소 등록 처리 시, 선택/효과 지자체의 `lg_code`를 조회하여 `ds_gugun_code`에 그대로 저장. |
|
||||
| **자료** | 웹 기능목록: "구코드: 판매소 주소를 바탕으로 기본코드 C 할당" — 본 시스템에서는 "소속 지자체 = 구·군"이므로 지자체 코드로 자동 할당. |
|
||||
|
||||
---
|
||||
|
||||
## 4. 참고
|
||||
|
||||
- **결정 필요 문서**: `docs/결정_필요한_사항들/01-DB_및_도메인_구조.md` §2 (판매소번호 규칙)
|
||||
- **기본코드**: `docs/기본 개발계획/03-basic-codes.md`, `종량제_개발목록_20260127(기본코드 종류).csv`
|
||||
76
docs/기본 개발계획/23-지정판매소_수정_삭제_기능.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# 지정판매소 수정·삭제 기능
|
||||
|
||||
> 등록된 지정판매소의 **정보 수정**과 **삭제** 기능에 대한 요구사항 정리 및 구현 방침.
|
||||
|
||||
---
|
||||
|
||||
## 1. 자료 근거 (웹 기능목록)
|
||||
|
||||
**파일**: `docs/종량제 관련 자료/종량제 개발목록/종량제_개발목록_20260127(웹 기능목록) (1).csv`
|
||||
|
||||
- **지정판매소 등록 / 수정 / 삭제** (PWB-030901-001)
|
||||
지정판매소의 상호명, 우편번호, 사업자번호, 일반전화, 대표자명, 이메일, 도로명주소, 지번주소, 개인전화, **지정일자**, 업태, 구코드, 업종, 구역, 종사업장번호, 가상계좌, 계좌번호, **영업상태(정상, 폐업, 직권해지)**, 변경일자, 변경사유 **등록 / 수정 / 삭제** 기능 구현.
|
||||
|
||||
→ **수정·삭제**는 원래 요구사항에 포함됨.
|
||||
|
||||
---
|
||||
|
||||
## 2. 권한
|
||||
|
||||
| 역할 | 수정 | 삭제 |
|
||||
|------|------|------|
|
||||
| Super admin | 가능 (효과 지자체 내 지정판매소) | 가능 |
|
||||
| 지자체관리자 | 가능 (본인 지자체 내 지정판매소) | 가능 |
|
||||
| 지정판매소 / 일반 | 불가 | 불가 |
|
||||
|
||||
- 수정·삭제 대상은 **효과 지자체(`admin_effective_lg_idx()`)** 에 소속된 지정판매소만 허용. 타 지자체 소속은 404 또는 403 처리.
|
||||
|
||||
---
|
||||
|
||||
## 3. 수정 기능
|
||||
|
||||
### 3-1. 수정 가능 항목
|
||||
|
||||
- **수정 가능**: 상호명, 사업자번호, 대표자명, 가상계좌, 우편번호, 도로명주소, 지번주소, 일반전화, 대표 휴대전화, 이메일, 지정일자, **영업상태**(정상/폐업/직권해지).
|
||||
- **수정 불가(표시만)**: 지자체, 판매소번호, 구코드.
|
||||
- 판매소번호·구코드는 등록 시 자동 부여 규칙에 따라 변경하지 않음.
|
||||
- 지자체 변경은 별도 이관 요건이 있을 경우 추후 검토.
|
||||
|
||||
### 3-2. 흐름
|
||||
|
||||
1. 목록에서 「수정」 클릭 → `GET /admin/designated-shops/edit/{ds_idx}`
|
||||
2. 효과 지자체 소속 여부 확인 후, 수정 폼 표시 (기존 값 채움).
|
||||
3. 저장 → `POST /admin/designated-shops/update/{ds_idx}`
|
||||
4. 유효성 검사 후 `designated_shop` 업데이트, 목록으로 리다이렉트.
|
||||
|
||||
### 3-3. 영업상태 (ds_state)
|
||||
|
||||
- `1` = 정상, `2` = 폐업, `3` = 직권해지.
|
||||
- 수정 폼에서 선택 가능. (기능목록의 “영업상태(정상, 폐업, 직권해지)” 반영.)
|
||||
|
||||
---
|
||||
|
||||
## 4. 삭제 기능
|
||||
|
||||
### 4-1. 방식
|
||||
|
||||
- **현재**: **물리 삭제** (DB에서 해당 행 `DELETE`).
|
||||
- 연관 데이터(주문·결제 등)가 생기면, “삭제 시 검사” 또는 “상태만 폐업/직권해지로 변경(소프트 삭제)” 등으로 정책 재검토.
|
||||
|
||||
### 4-2. 흐름
|
||||
|
||||
1. 목록에서 「삭제」 클릭 → 확인 후 `POST /admin/designated-shops/delete/{ds_idx}` (또는 GET + 확인 페이지 후 POST).
|
||||
2. 효과 지자체 소속 여부 확인.
|
||||
3. 해당 행 삭제 후 목록으로 리다이렉트, 성공 메시지.
|
||||
|
||||
### 4-3. 확인
|
||||
|
||||
- 삭제 전 사용자 확인(confirm 또는 전용 확인 페이지) 권장.
|
||||
|
||||
---
|
||||
|
||||
## 5. 참고
|
||||
|
||||
- **등록·판매소번호·구코드**: `docs/기본 개발계획/22-판매소번호_일련번호_결정.md`
|
||||
- **테이블 DDL**: `docs/기본 개발계획/테이블/01-마스터_테이블_DDL.md` §3 designated_shop
|
||||
- **지자체 필터**: `docs/기본 개발계획/테이블/03-지자체_데이터_필터_및_권한.md`
|
||||
106
docs/기본 개발계획/24-관리자_메뉴_관리_기능.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# 관리자 메뉴 관리 기능
|
||||
|
||||
> 관리자가 **메뉴를 등록·수정·삭제·순서 변경**하고, **관리자 상단 네비게이션**에 DB 메뉴를 반영하는 기능 정리.
|
||||
|
||||
---
|
||||
|
||||
## 1. 목적
|
||||
|
||||
- **관리자 화면(admin)** 상단 메뉴를 **DB로 관리**하여, 코드 수정 없이 메뉴 추가·순서·노출 대상 변경 가능.
|
||||
- 참고: slow-auth-application의 메뉴 설정 방식과 유사하게 구현.
|
||||
|
||||
---
|
||||
|
||||
## 2. DB 구조
|
||||
|
||||
### 2-1. menu_type (메뉴 종류)
|
||||
|
||||
| 컬럼 | 설명 |
|
||||
|--------|------|
|
||||
| mt_idx | PK |
|
||||
| mt_code | 코드 (admin, site 등) |
|
||||
| mt_name | 표시명 |
|
||||
| mt_sort | 정렬 |
|
||||
|
||||
- 초기 데이터: `admin` (관리자 메뉴) 1건.
|
||||
|
||||
### 2-2. menu (메뉴 항목)
|
||||
|
||||
| 컬럼 | 설명 |
|
||||
|----------|------|
|
||||
| mm_idx | PK |
|
||||
| mt_idx | 메뉴 종류 FK |
|
||||
| mm_name | 메뉴명 |
|
||||
| mm_link | 링크 경로 (예: admin, admin/users) |
|
||||
| mm_pidx | 부모 메뉴 PK (0=최상위) |
|
||||
| mm_dep | 깊이 (0, 1, 2) |
|
||||
| mm_num | 형제 내 순서 |
|
||||
| mm_cnode | 자식 개수 |
|
||||
| mm_level | 노출 허용 mb_level, 쉼표 구분 (빈값=전체) |
|
||||
| mm_is_view | Y=노출, N=숨김 |
|
||||
|
||||
- **링크**: 상대 경로. 예: `admin`, `admin/users`, `admin/access/login-history`. 레이아웃에서 `base_url(mm_link)` 로 사용.
|
||||
- **노출 대상**: `mm_level`에 포함된 `mb_level` 사용자만 해당 메뉴 노출. 빈값이면 전체.
|
||||
|
||||
---
|
||||
|
||||
## 3. 권한
|
||||
|
||||
- 메뉴 **등록·수정·삭제·순서 변경**: **admin 로그인 사용자** (adminAuth 필터 통과 시). 역할별 제한은 없음 (추후 메뉴 관리 권한 분리 가능).
|
||||
|
||||
---
|
||||
|
||||
## 4. 기능 요약
|
||||
|
||||
| 기능 | 경로 | 설명 |
|
||||
|------|------|------|
|
||||
| 메뉴 관리 화면 | GET /admin/menus | 메뉴 종류 선택, 목록, 등록/수정 폼 |
|
||||
| 메뉴 목록 JSON | GET /admin/menus/list?mt_idx=1 | 트리 정렬된 목록 (추가 연동용) |
|
||||
| 메뉴 등록 | POST /admin/menus/store | 신규 메뉴 추가 |
|
||||
| 메뉴 수정 | POST /admin/menus/update/:id | 메뉴명, 링크, 노출대상, 사용여부 수정 |
|
||||
| 메뉴 삭제 | POST /admin/menus/delete/:id | 삭제 (하위 메뉴 있으면 불가) |
|
||||
| 순서 적용 | POST /admin/menus/move | mm_idx[] 순서대로 mm_num 반영 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 관리자 레이아웃 연동
|
||||
|
||||
- **app/Views/admin/layout.php**
|
||||
- `get_admin_nav_items()` (admin_helper)로 **admin** 타입 메뉴 조회, 현재 `mb_level` 기준 노출 항목만 사용.
|
||||
- **1건 이상**이면 해당 목록으로 상단 `<nav>` 렌더링.
|
||||
- **0건**이면 기존 **하드코딩 메뉴**로 폴백 (테이블 미구축·시드 미적용 환경 대비).
|
||||
|
||||
- **app/Helpers/admin_helper.php**
|
||||
- `get_admin_nav_items()`: menu_type.code='admin' 조회 후, MenuModel::getVisibleByLevel(mt_idx, mb_level) 반환.
|
||||
|
||||
---
|
||||
|
||||
## 6. 파일 위치
|
||||
|
||||
| 구분 | 경로 |
|
||||
|------|------|
|
||||
| DDL·시드 | writable/database/menu_tables.sql |
|
||||
| 모델 | app/Models/MenuTypeModel.php, app/Models/MenuModel.php |
|
||||
| 컨트롤러 | app/Controllers/Admin/Menu.php |
|
||||
| 뷰 | app/Views/admin/menu/index.php |
|
||||
| 헬퍼 | app/Helpers/admin_helper.php (get_admin_nav_items) |
|
||||
| 레이아웃 | app/Views/admin/layout.php |
|
||||
|
||||
---
|
||||
|
||||
## 7. 사용 방법
|
||||
|
||||
1. **테이블 생성**: `menu_tables.sql` 실행 (menu_type, menu 생성 + admin 타입 및 초기 메뉴 시드).
|
||||
2. **관리자 로그인** 후 **메뉴** 메뉴 이동.
|
||||
3. **메뉴 종류**에서 "관리자 메뉴" 선택.
|
||||
4. **메뉴 등록**: 우측 폼에서 메뉴명, 링크, 노출 대상(mm_level), 노출 여부 입력 후 등록.
|
||||
5. **수정**: 목록에서 해당 행 **수정** 클릭 후 폼에서 수정·**수정** 버튼.
|
||||
6. **삭제**: 목록에서 **삭제** (하위 메뉴가 있으면 불가).
|
||||
7. **순서**: 목록 순서를 바꾼 뒤 **순서 적용** 버튼 (현재는 목록 순서가 곧 mm_num 순서).
|
||||
|
||||
---
|
||||
|
||||
## 8. 참고
|
||||
|
||||
- **결정 필요 사항** (03-기능_명세_보완.md): 메뉴별 접근 제어를 DB로 할지 코드로 할지 → 본 기능으로 **DB 기반 메뉴 노출** 적용.
|
||||
- **auth 프로젝트**: slow-auth-application의 setting/Menu, Menu_m, tree_helper, menu_helper 참고.
|
||||
230
docs/기본 개발계획/25-메뉴_추가수정_개발_계획.md
Normal file
@@ -0,0 +1,230 @@
|
||||
## 메뉴 추가·수정 개발 계획
|
||||
|
||||
### 1. 목적 및 범위
|
||||
|
||||
- **목적**
|
||||
- 관리자 화면과 일반 사이트 화면의 상단 메뉴를 **지자체별·역할별로 DB에서 동적으로 관리**할 수 있도록 확장한다.
|
||||
- 1차 메뉴뿐 아니라 **2차/3차 하위 메뉴까지 등록·수정·삭제·순서 변경** 가능하게 하고, 상단 `<nav>`에 **드롭다운 구조**로 반영한다.
|
||||
- **범위**
|
||||
- 테이블: `menu_type`, `menu`
|
||||
- 모델: `MenuModel`, `MenuTypeModel`
|
||||
- 컨트롤러: `App\Controllers\Admin\Menu`
|
||||
- 뷰: `app/Views/admin/layout.php`, `app/Views/admin/menu/index.php`
|
||||
- 헬퍼: `app/Helpers/admin_helper.php`
|
||||
|
||||
---
|
||||
|
||||
### 2. 데이터 구조 및 기본 정책
|
||||
|
||||
#### 2.1 메뉴 종류 (`menu_type`)
|
||||
|
||||
- 컬럼
|
||||
- `mt_idx` : PK
|
||||
- `mt_code` : 코드 (`admin`, `site` 등)
|
||||
- `mt_name` : 표시명
|
||||
- `mt_sort` : 정렬 우선순위
|
||||
- 기본 데이터
|
||||
- `admin` : 관리자 상단 메뉴
|
||||
- `site` : 일반 사이트 상단 메뉴
|
||||
|
||||
#### 2.2 메뉴 항목 (`menu`)
|
||||
|
||||
- 컬럼
|
||||
- `mm_idx` : PK
|
||||
- `mt_idx` : 메뉴 종류 FK (`menu_type.mt_idx`)
|
||||
- `lg_idx` : 지자체 FK (지자체별 메뉴 분리)
|
||||
- `mm_name` : 메뉴명 (1차/2차/3차 공통)
|
||||
- `mm_link` : 링크 경로 (예: `admin`, `admin/users`, `site/inventory/list`)
|
||||
- `mm_pidx` : 부모 메뉴 PK (`0` = 최상위 1차 메뉴)
|
||||
- `mm_dep` : 깊이 (`0`=1차, `1`=2차, `2`=3차 …)
|
||||
- `mm_num` : 형제 내 정렬 순서
|
||||
- `mm_cnode` : 자식 개수
|
||||
- `mm_level` : 노출 허용 `mb_level` 쉼표 구분 (빈값=전체, super admin은 무시하고 항상 전체)
|
||||
- `mm_is_view` : `Y`=노출, `N`=숨김
|
||||
- 인덱스
|
||||
- `idx_mt_lg (mt_idx, lg_idx)` : 메뉴 종류·지자체별 조회용
|
||||
- `idx_mm_pidx (mm_pidx)` : 하위 메뉴 존재 여부 확인용
|
||||
- `idx_mm_dep_num (mm_dep, mm_num)` : 트리 정렬용
|
||||
|
||||
#### 2.3 기본 메뉴 정책
|
||||
|
||||
- **관리자 상단 메뉴 (`mt_code='admin'`)**
|
||||
- 각 지자체별로 다음과 같은 1차 메뉴가 기본 등록되어야 한다.
|
||||
- 대시보드 (`admin`)
|
||||
- 회원 관리 (`admin/users`)
|
||||
- 로그인 이력 (`admin/access/login-history`)
|
||||
- 승인 대기 (`admin/access/approvals`)
|
||||
- 역할 (`admin/roles`)
|
||||
- 메뉴 (`admin/menus`)
|
||||
- 지자체 전환 (`admin/select-local-government`, super admin 전용)
|
||||
- 지자체 (`admin/local-governments`, super admin 전용)
|
||||
- 지정판매소 (`admin/designated-shops`)
|
||||
- 각 1차 메뉴 아래에 2차/3차 하위 메뉴를 둘 수 있으며, 상단 `<nav>`에서 드롭다운으로 노출한다.
|
||||
|
||||
- **일반 사이트 상단 메뉴 (`mt_code='site'`)**
|
||||
- 각 지자체별로 다음과 같은 1차 메뉴 세트를 기본 등록한다.
|
||||
- 기본정보관리
|
||||
- 발주 입고 관리
|
||||
- 불출 관리
|
||||
- 재고 관리
|
||||
- 판매 관리
|
||||
- 판매 현황
|
||||
- 봉투 수불 관리
|
||||
- 통계 분석 관리
|
||||
- 창
|
||||
- 도움말
|
||||
- 각 1차 메뉴 아래의 2차/3차 메뉴 구성은 **CSV의 “1차 메뉴정리” 파일**을 기준으로 초기 등록한다.
|
||||
|
||||
- **역할·권한 정책**
|
||||
- `mm_level` 빈값: 모든 역할 노출 (일반 사용자, 지정판매소, 지자체관리자, super admin).
|
||||
- `mm_level`에 숫자(1,2,3) 지정: 해당 `mb_level` 사용자에게만 노출.
|
||||
- super admin(4): DB `mm_level` 값과 관계없이 해당 지자체의 모든 메뉴를 볼 수 있도록 모델에서 처리.
|
||||
|
||||
---
|
||||
|
||||
### 3. 기능 요구사항 (관리자 메뉴 관리)
|
||||
|
||||
#### 3.1 공통 동작
|
||||
|
||||
- **지자체 선택 필수**
|
||||
- `admin_effective_lg_idx()`를 사용해 현재 작업 지자체를 결정한다.
|
||||
- 값이 `null`이면 지자체 선택 화면(`/admin/select-local-government`)으로 리다이렉트하고,
|
||||
“메뉴를 관리하려면 먼저 지자체를 선택하세요.” 메시지를 표출한다.
|
||||
|
||||
- **메뉴 종류 선택**
|
||||
- `menu_type` 목록에서 `mt_code`(admin/site 등)를 선택하여 관리 대상 메뉴 종류를 바꾼다.
|
||||
- 선택된 `mt_idx` + 현재 `lg_idx` 기준으로 메뉴 목록과 등록/수정 폼을 동작시킨다.
|
||||
|
||||
#### 3.2 목록 영역 (트리 + 들여쓰기)
|
||||
|
||||
- 선택한 `mt_idx`, 현재 `lg_idx` 기준으로 **트리 구조를 평면 리스트로 렌더링**한다.
|
||||
- `mm_dep` 값에 따라 좌측 padding을 주어 1차/2차/3차 메뉴를 시각적으로 구분한다.
|
||||
- 각 행에 다음 정보를 표시한다.
|
||||
- 메뉴명 (`mm_name`)
|
||||
- 링크 (`mm_link`)
|
||||
- 노출 대상 (`mm_level` → 역할 이름으로 변환, 빈값이면 “전체”)
|
||||
- 노출 여부 (`mm_is_view` Y/N)
|
||||
- 삭제 버튼
|
||||
- 현재 지자체(`lg_idx`) 소속인지 검증 후 삭제 허용.
|
||||
- 하위 메뉴가 있으면 삭제 불가.
|
||||
|
||||
- **하위 메뉴 등록 버튼**
|
||||
- 각 행 우측에 “하위 메뉴 추가” 버튼을 배치한다.
|
||||
- 클릭 시:
|
||||
- 우측 폼의 hidden 값에 `mm_pidx=해당 행 mm_idx`, `mm_dep=해당 행 mm_dep+1`을 세팅한다.
|
||||
- 폼 타이틀을 “하위 메뉴 등록”으로 변경(표시용).
|
||||
- 이렇게 등록된 메뉴는 동일한 컨트롤러(`/admin/menus/store`)를 통해 2차/3차 메뉴로 저장된다.
|
||||
|
||||
- **순서 변경**
|
||||
- 현재 구현과 동일하게 리스트 순서를 조정한 뒤, “순서 적용” 버튼으로 `mm_idx[]` 순서를 서버로 보낸다.
|
||||
- 서버에서는 현재 지자체(`lg_idx`) 기준으로만 `mm_num`을 재부여하여 순서를 저장한다.
|
||||
|
||||
#### 3.3 등록/수정 폼
|
||||
|
||||
- hidden 필드
|
||||
- `mt_idx` : 현재 선택된 메뉴 종류
|
||||
- `mm_pidx` : 부모 메뉴 PK (기본값 `0`, “하위 메뉴 추가” 시 부모 ID로 변경)
|
||||
- `mm_dep` : 깊이 (기본값 `0`, “하위 메뉴 추가” 시 `부모+1`)
|
||||
- `mm_idx_edit` : 수정 대상 PK (수정 모드일 때만 값 설정)
|
||||
|
||||
- 입력 필드
|
||||
- `mm_name` : 필수, 메뉴명
|
||||
- `mm_link` : 링크 경로 (1차/하위 메뉴 모두 동일 규칙)
|
||||
- `mm_level` : 체크박스(전체 + 각 역할), super admin은 별도로 저장하지 않는다.
|
||||
- `mm_is_view` : 체크박스, 기본값 `Y` (노출)
|
||||
|
||||
- 동작 모드
|
||||
- **등록 모드**
|
||||
- `mm_idx_edit` 비어 있음.
|
||||
- `mm_pidx=0`, `mm_dep=0`이면 1차 메뉴 등록.
|
||||
- `하위 메뉴 추가`로 진입한 경우, `mm_pidx/mm_dep`에 부모 정보가 채워진 상태로 등록.
|
||||
- **수정 모드**
|
||||
- “수정” 버튼 클릭 시 해당 행의 정보를 폼에 로딩한다.
|
||||
- `mm_pidx`, `mm_dep`는 변경하지 않고, `mm_name/mm_link/mm_level/mm_is_view`만 수정.
|
||||
|
||||
---
|
||||
|
||||
### 4. 네비게이션 드롭다운 설계
|
||||
|
||||
#### 4.1 공통 트리 헬퍼/서비스
|
||||
|
||||
- 함수 예시: `get_menu_tree(string $typeCode, int $lgIdx, int $mbLevel): array`
|
||||
- `menu_type.mt_code`로 `mt_idx` 조회.
|
||||
- `MenuModel::getVisibleByLevel(mt_idx, mbLevel, lgIdx)`로 현재 지자체/역할 기준 메뉴 목록 조회.
|
||||
- 조회 결과(평면 배열)를 `mm_idx/mm_pidx` 기준으로 트리 구조로 변환:
|
||||
- 1차 메뉴: `mm_pidx=0`
|
||||
- children: `mm_pidx=부모 mm_idx`
|
||||
- 각 노드에 `children` 배열을 추가.
|
||||
|
||||
#### 4.2 관리자 레이아웃(nav)
|
||||
|
||||
- 파일: `app/Views/admin/layout.php`
|
||||
- 변경 내용
|
||||
- 기존 `get_admin_nav_items()`는 1차 메뉴 리스트만 반환하는 형태에서,
|
||||
**트리 형태를 반환하는 헬퍼**를 사용하도록 변경한다.
|
||||
- 상단 `<nav>`에서:
|
||||
- 1차 메뉴(트리 루트)를 루프 돌며 `<a>`를 렌더링.
|
||||
- 자식 메뉴가 있는 경우:
|
||||
- 1차 메뉴를 `<div class="relative group">`로 감싼 후,
|
||||
- `group-hover:block` 형태의 `<div>` 안에 children 메뉴들을 `<a>` 리스트로 렌더링.
|
||||
- 각 `<a>`의 `href`는 `base_url(mm_link)`로 풀 페이지 전환을 사용한다.
|
||||
|
||||
#### 4.3 일반 사이트 레이아웃(nav)
|
||||
|
||||
- (향후) 사이트용 레이아웃 파일에서:
|
||||
- `get_menu_tree('site', 현재 lg_idx, 현재 사용자 레벨)` 을 호출.
|
||||
- 관리자와 동일한 드롭다운 패턴으로 1차/하위 메뉴를 렌더링.
|
||||
- 링크 클릭 시 역시 풀 페이지 전환을 사용한다.
|
||||
|
||||
---
|
||||
|
||||
### 5. 지자체·권한 정책 정리
|
||||
|
||||
- **지자체별 메뉴 분리**
|
||||
- 모든 메뉴 조회·등록·수정·삭제·순서 변경은 `mt_idx + lg_idx`를 조건으로 수행한다.
|
||||
- 북구청에서 만든 메뉴(`lg_idx=북구청`)는 다른 구청(`lg_idx`가 다른 값)에서는 보이지 않고, 관리도 불가하다.
|
||||
|
||||
- **역할별 노출**
|
||||
- `mm_level`이 빈값인 메뉴는 **모든 역할**에 노출된다.
|
||||
- `mm_level`에 1,2,3이 포함된 경우, 해당 `mb_level`만 노출한다.
|
||||
- super admin(4)은 `mm_level`과 관계없이, 현재 지자체의 모든 `mm_is_view='Y'` 메뉴를 노출한다.
|
||||
|
||||
---
|
||||
|
||||
### 6. CSV 기반 초기 데이터 등록 계획
|
||||
|
||||
1. **CSV 구조 확인**
|
||||
- “1차 메뉴정리” 파일의 컬럼 구조를 확정한다.
|
||||
- 최소 필요 컬럼 예시:
|
||||
- 메뉴 종류(admin/site)
|
||||
- 1차 메뉴명 / 1차 메뉴 링크
|
||||
- 2차 메뉴명 / 2차 메뉴 링크 (선택)
|
||||
- 3차 메뉴명 / 3차 메뉴 링크 (선택)
|
||||
- 노출 대상 역할, 사용 여부 등
|
||||
2. **초기 시드/Import 스크립트 작성**
|
||||
- CSV 한 행당 `menu` 테이블 1개 또는 다수 행으로 변환.
|
||||
- 1차 메뉴는 `mm_pidx=0, mm_dep=0` 으로 insert.
|
||||
- 2차/3차 메뉴는 상위 메뉴의 `mm_idx`를 `mm_pidx`로 참조하여 insert.
|
||||
- 초기에는 특정 지자체(예: 대구 전체 or 테스트용 하나의 지자체) 기준으로만 시드하고,
|
||||
필요 시 “메뉴 복사” 기능으로 다른 지자체로 복제하는 방식을 고려.
|
||||
3. **개발/테스트 DB에 적용 및 검증**
|
||||
- 관리자 `/admin/menus`에서 트리 구조와 드롭다운 노출 상태를 확인한다.
|
||||
- 역할별 노출, 지자체별 분리가 기대대로 동작하는지 검증한다.
|
||||
4. **운영 반영 절차 문서화**
|
||||
- 운영 DB 초기 세팅 시, CSV → SQL/스크립트 실행 순서를 별도 문서에 정리한다.
|
||||
|
||||
---
|
||||
|
||||
### 7. 구현 순서 제안
|
||||
|
||||
1. `menu` 테이블에 `lg_idx` 컬럼 및 인덱스 추가, 시드 SQL 정리 (완료 기준 재확인).
|
||||
2. `MenuModel`에 `lg_idx`를 반영한 조회/정렬 메서드 정리 (`getAllByType`, `getVisibleByLevel`, `getNextNum`, `setOrder` 등).
|
||||
3. `Admin\Menu` 컨트롤러에서 지자체 필수 체크 및 지자체 소속 검증 로직 보완.
|
||||
4. `admin/menu/index` 뷰에서:
|
||||
- 하위 메뉴 등록 버튼 추가
|
||||
- `mm_pidx/mm_dep` 값을 활용한 2차/3차 메뉴 등록/표시 기능 구현.
|
||||
5. 트리 헬퍼(`get_menu_tree` 류) 구현 및 `admin_helper`에 연동.
|
||||
6. `admin/layout` 상단 네비게이션을 DB 트리 기반 드롭다운으로 교체.
|
||||
7. CSV 기반 초기 데이터 스크립트 작성 및 개발 환경에서 시범 적용.
|
||||
8. 통합 테스트 후 운영 반영 계획 수립.
|
||||
|
||||
30
docs/기본 개발계획/26-메뉴_드래그_정렬_기능.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# 메뉴 목록 드래그 정렬 기능
|
||||
|
||||
## 목적
|
||||
- 관리자 메뉴 관리 화면에서 상위/하위 메뉴 행을 마우스로 드래그해 순서를 쉽게 변경한다.
|
||||
- 변경된 순서를 기존 `순서 적용` 버튼으로 저장한다.
|
||||
|
||||
## 적용 범위
|
||||
- 화면: `admin/menus` (`app/Views/admin/menu/index.php`)
|
||||
- 서버 정렬 조회: `app/Models/MenuModel.php`
|
||||
|
||||
## 구현 내용
|
||||
- 메뉴 목록 테이블에 드래그 핸들(`↕`) 컬럼 추가.
|
||||
- 각 메뉴 행에 HTML5 DnD(`draggable="true"`) 적용.
|
||||
- 드래그 중 마우스 위치 기준으로 행을 실시간 재배치.
|
||||
- 행 순서가 바뀌면 화면의 순번(`#`)을 즉시 갱신.
|
||||
- 저장은 기존과 동일하게 `mm_idx[]` 순서로 `POST /admin/menus/move` 호출.
|
||||
- 목록 조회 정렬을 `mm_num ASC` 기준으로 변경하여 드래그 저장 결과가 그대로 반영되도록 수정.
|
||||
|
||||
## 사용 방법
|
||||
1. 메뉴 관리 화면에서 원하는 행을 드래그한다.
|
||||
2. 원하는 위치로 놓는다.
|
||||
3. `순서 적용` 버튼을 눌러 저장한다.
|
||||
|
||||
## 동작 규칙/제약
|
||||
- 드래그는 행 단위 정렬만 수행한다.
|
||||
- 부모/자식 관계(`mm_pidx`, `mm_dep`)는 변경하지 않는다.
|
||||
- 즉, 구조 변경이 아니라 표시/노출 순서(`mm_num`)만 변경한다.
|
||||
|
||||
## 참고
|
||||
- 하위 메뉴의 추가는 1차 메뉴에서만 가능하도록 기존 정책 유지.
|
||||
118
docs/기본 개발계획/27-회원가입_역할승인_요구사항.md
Normal file
@@ -0,0 +1,118 @@
|
||||
## 회원가입 역할 승인 요구사항
|
||||
|
||||
### 1) 배경
|
||||
|
||||
- 현재 `register`에서 사용자가 선택한 `mb_level`이 즉시 저장되어, 승인 절차 없이 해당 역할로 로그인 가능하다.
|
||||
- 목표는 **회원가입 시 선택한 역할을 승인 대기 상태로 저장**하고, `admin/access/approvals`에서 승인된 뒤에만 해당 역할이 활성화되도록 바꾸는 것이다.
|
||||
|
||||
---
|
||||
|
||||
### 2) 목표
|
||||
|
||||
- `super admin`은 공개 회원가입에서 선택할 수 없도록 제거한다.
|
||||
- 회원가입 시 선택 가능한 역할은 아래 3개로 제한한다.
|
||||
- `일반 사용자(1)`
|
||||
- `지정판매소(2)`
|
||||
- `지자체관리자(3)`
|
||||
- 회원가입 직후에는 승인 전 상태로 저장한다.
|
||||
- 관리자 승인 이후에만 사용자가 선택한 역할로 로그인 가능하게 한다.
|
||||
- 승인 전 로그인 시 명확한 안내 메시지를 노출한다.
|
||||
|
||||
---
|
||||
|
||||
### 3) AS-IS / TO-BE
|
||||
|
||||
#### AS-IS
|
||||
|
||||
- `register` 폼에서 `mb_level`이 `1,2,3,4` 선택 가능.
|
||||
- 저장 시 `member.mb_level`에 즉시 반영, `mb_state=1`로 바로 로그인 가능.
|
||||
- `admin/access/approvals`는 플레이스홀더(실제 승인 데이터 없음).
|
||||
|
||||
#### TO-BE
|
||||
|
||||
- `register` 폼에서 `4(super admin)` 제거.
|
||||
- 회원가입 시 승인 요청 레코드가 생성되고, 요청 상태는 `pending`.
|
||||
- 승인 전 로그인 시 차단되고, `"관리자 승인 후 로그인 가능합니다."` 메시지 노출.
|
||||
- `admin/access/approvals`에서 `pending` 목록 조회, 승인/반려 처리 가능.
|
||||
- 승인 시 사용자 역할이 최종 확정되어 로그인 허용.
|
||||
|
||||
---
|
||||
|
||||
### 4) 사용자 시나리오
|
||||
|
||||
#### 시나리오 A: 일반 회원가입
|
||||
|
||||
1. 사용자가 `register`에서 역할(1/2/3) 선택 후 가입
|
||||
2. 시스템은 계정을 승인 대기 상태로 저장
|
||||
3. 사용자가 로그인 시도
|
||||
4. 승인 전이면 로그인 실패 + 승인 필요 메시지
|
||||
5. 관리자 승인 후 재로그인 성공
|
||||
|
||||
#### 시나리오 B: 승인 처리
|
||||
|
||||
1. 관리자가 `admin/access/approvals` 접속
|
||||
2. 대기 목록에서 요청 확인
|
||||
3. 승인 또는 반려
|
||||
4. 승인 시 해당 회원은 선택 역할로 활성화
|
||||
5. 반려 시 회원에게 반려 상태 유지(필요 시 반려 사유 저장)
|
||||
|
||||
---
|
||||
|
||||
### 5) 정책(권한)
|
||||
|
||||
- 공개 회원가입 경로에서 `super admin` 요청은 허용하지 않는다.
|
||||
- 승인 처리 권한은 관리자만 가진다.
|
||||
- 승인 권한 상세:
|
||||
- `super admin`: 모든 승인 처리 가능
|
||||
- `지자체관리자`: 필요 시 정책에 따라 동일 지자체 범위 내 승인만 허용(최종 정책 확정 필요)
|
||||
|
||||
---
|
||||
|
||||
### 6) 로그인 정책
|
||||
|
||||
- 로그인 차단 조건:
|
||||
- 승인 상태가 `pending`인 계정
|
||||
- 승인 상태가 `rejected`인 계정(메시지 별도)
|
||||
- 메시지 예시:
|
||||
- `pending`: `관리자 승인 후 로그인 가능합니다.`
|
||||
- `rejected`: `승인이 반려되었습니다. 관리자에게 문의해 주세요.`
|
||||
|
||||
---
|
||||
|
||||
### 7) 승인 대기 목록 화면 요구사항
|
||||
|
||||
- 컬럼:
|
||||
- 요청일
|
||||
- 아이디
|
||||
- 이름
|
||||
- 지자체
|
||||
- 요청 역할
|
||||
- 요청 상태
|
||||
- 처리자/처리일
|
||||
- 관리(승인/반려)
|
||||
- 필터:
|
||||
- 상태(`pending/approved/rejected`)
|
||||
- 기간
|
||||
- 역할
|
||||
- 지자체
|
||||
|
||||
---
|
||||
|
||||
### 8) 데이터/이력 요구사항
|
||||
|
||||
- 승인 요청은 이력으로 남겨 감사 가능해야 한다.
|
||||
- 최소 이력 항목:
|
||||
- 요청자, 요청 역할, 요청일
|
||||
- 처리자, 처리 결과, 처리일
|
||||
- 반려 사유(선택)
|
||||
|
||||
---
|
||||
|
||||
### 9) 완료 기준(수용 기준)
|
||||
|
||||
- `register` 역할 드롭다운에 `super admin`이 보이지 않는다.
|
||||
- 회원가입 직후 계정은 승인 전 상태이며 로그인할 수 없다.
|
||||
- `admin/access/approvals`에서 대기 건이 조회된다.
|
||||
- 승인 처리 후 해당 사용자는 선택한 역할로 로그인 가능하다.
|
||||
- 승인 전 로그인 시 지정 메시지가 노출된다.
|
||||
|
||||
164
docs/기본 개발계획/28-회원가입_역할승인_개발계획.md
Normal file
@@ -0,0 +1,164 @@
|
||||
## 회원가입 역할 승인 개발 계획
|
||||
|
||||
### 1) 범위
|
||||
|
||||
- 회원가입(`register`) 역할 선택 정책 변경
|
||||
- 승인 대기/승인 처리 기능 구현
|
||||
- 로그인 차단/메시지 처리
|
||||
- 관리자 승인 화면(`admin/access/approvals`) 실데이터 연동
|
||||
|
||||
---
|
||||
|
||||
### 2) 구현 방향
|
||||
|
||||
승인 절차를 안정적으로 운영하기 위해 `member` 테이블만으로 처리하지 않고, 승인 이력을 분리 저장하는 전용 테이블을 도입한다.
|
||||
|
||||
- 회원 기본 정보: `member`
|
||||
- 역할 승인 워크플로: `member_approval_request`(신규)
|
||||
|
||||
---
|
||||
|
||||
### 3) 데이터 설계
|
||||
|
||||
#### 3.1 신규 테이블: `member_approval_request`
|
||||
|
||||
- `mar_idx` PK
|
||||
- `mb_idx` FK (`member.mb_idx`)
|
||||
- `requested_level` (요청 역할: 1,2,3)
|
||||
- `status` (`pending`, `approved`, `rejected`)
|
||||
- `request_note` (선택)
|
||||
- `reject_reason` (선택)
|
||||
- `requested_at`
|
||||
- `requested_by` (self 가입이면 본인)
|
||||
- `processed_at`
|
||||
- `processed_by`
|
||||
|
||||
인덱스 권장:
|
||||
- `(status, requested_at)`
|
||||
- `(mb_idx, status)`
|
||||
|
||||
#### 3.2 member 보조 컬럼(선택)
|
||||
|
||||
아래 두 가지 중 하나 선택:
|
||||
|
||||
- A안(권장): 승인 여부는 `member_approval_request` 최신 상태로 판단
|
||||
- B안: `member`에 캐시성 플래그(`mb_approval_state`) 추가
|
||||
|
||||
본 계획은 A안을 기준으로 진행한다.
|
||||
|
||||
---
|
||||
|
||||
### 4) 백엔드 변경 계획
|
||||
|
||||
#### 4.1 `Auth::register()`
|
||||
|
||||
- `mb_level` 검증을 `in_list[1,2,3]`로 제한
|
||||
- `mb_level=4` 입력 시 서버에서 거부
|
||||
- 회원 생성 후 `member_approval_request`에 `pending` 레코드 생성
|
||||
- 회원 레벨은 즉시 활성화하지 않도록 정책 적용
|
||||
- 방법 1: 임시 기본 레벨(예: 1) + 승인 전 로그인 차단
|
||||
- 방법 2: 요청 레벨 별도 저장 후 승인 시 반영
|
||||
|
||||
#### 4.2 `Auth::login()`
|
||||
|
||||
- 비밀번호 검증 성공 후 승인 상태 체크 추가
|
||||
- `pending`이면 로그인 차단 + 메시지
|
||||
- `rejected`이면 로그인 차단 + 메시지
|
||||
- `approved`일 때만 기존 로그인 흐름 진행
|
||||
|
||||
#### 4.3 `Admin\Access`
|
||||
|
||||
- `approvals()`:
|
||||
- `pending` 중심 목록 조회
|
||||
- 필터(상태/기간/역할/지자체) 지원
|
||||
- `approve($id)`:
|
||||
- 요청 상태 `pending` 검증
|
||||
- 사용자 역할 갱신(`member.mb_level = requested_level`)
|
||||
- 요청 상태 `approved`/처리자/처리일 기록
|
||||
- `reject($id)`:
|
||||
- 요청 상태 `rejected` + 반려 사유 기록
|
||||
|
||||
트랜잭션:
|
||||
- 승인/반려 처리 시 반드시 트랜잭션 사용
|
||||
|
||||
---
|
||||
|
||||
### 5) 프론트(뷰) 변경 계획
|
||||
|
||||
#### 5.1 `app/Views/auth/register.php`
|
||||
|
||||
- 역할 드롭다운에서 `super admin` 제거
|
||||
- 안내 문구 추가:
|
||||
- `가입 후 관리자 승인 완료 시 로그인 가능합니다.`
|
||||
|
||||
#### 5.2 `app/Views/admin/access/approvals.php`
|
||||
|
||||
- 플레이스홀더 제거
|
||||
- 실제 승인 대기 목록 렌더링
|
||||
- 승인/반려 버튼 및 반려 사유 입력 UI 제공
|
||||
|
||||
---
|
||||
|
||||
### 6) 권한/보안 규칙
|
||||
|
||||
- 공개 회원가입에서 `super admin` 요청 금지(서버 검증 필수)
|
||||
- 승인 API는 관리자 권한 필요
|
||||
- 중복 처리 방지:
|
||||
- 이미 처리된 요청 재승인/재반려 차단
|
||||
- 감사 로그:
|
||||
- 누가, 언제, 어떤 요청을 승인/반려했는지 기록
|
||||
|
||||
---
|
||||
|
||||
### 7) 단계별 작업 순서
|
||||
|
||||
1. SQL 추가 (`writable/database`): 승인 요청 테이블 DDL
|
||||
2. 모델 추가: `MemberApprovalRequestModel`
|
||||
3. `Auth::register` 변경 (역할 제한 + 승인요청 생성)
|
||||
4. `Auth::login` 변경 (승인 전 로그인 차단)
|
||||
5. `Admin\Access` 목록/승인/반려 로직 구현
|
||||
6. `approvals.php` UI 구현
|
||||
7. 메시지/문구 정리
|
||||
8. 테스트 및 회귀 점검
|
||||
|
||||
---
|
||||
|
||||
### 8) 테스트 계획
|
||||
|
||||
핵심 케이스:
|
||||
|
||||
- 회원가입 역할 선택
|
||||
- 1/2/3 저장 성공
|
||||
- 4 입력 시 거부
|
||||
- 로그인
|
||||
- 승인 전(`pending`) 로그인 실패 + 메시지 확인
|
||||
- 승인 후 로그인 성공 + 역할별 리다이렉트 확인
|
||||
- 승인 화면
|
||||
- 목록 조회/필터 동작
|
||||
- 승인 처리 후 사용자 역할 변경 확인
|
||||
- 반려 처리 후 로그인 차단 메시지 확인
|
||||
- 예외
|
||||
- 이미 처리된 요청 재처리 차단
|
||||
- 잘못된 요청 ID 처리
|
||||
|
||||
---
|
||||
|
||||
### 9) 파일 변경 예정(구현 단계)
|
||||
|
||||
- `app/Controllers/Auth.php`
|
||||
- `app/Controllers/Admin/Access.php`
|
||||
- `app/Views/auth/register.php`
|
||||
- `app/Views/admin/access/approvals.php`
|
||||
- `app/Models/MemberApprovalRequestModel.php` (신규)
|
||||
- `writable/database/*_member_approval_request.sql` (신규)
|
||||
|
||||
---
|
||||
|
||||
### 10) 오픈 이슈
|
||||
|
||||
- 승인 전 사용자의 `mb_level` 저장 전략 확정 필요
|
||||
- 임시 레벨 사용 vs 요청 테이블 단일 소스
|
||||
- 반려 후 재신청 UX
|
||||
- 기존 요청 재오픈 vs 신규 요청 생성
|
||||
- 지자체관리자 승인 범위 정책 확정
|
||||
|
||||
152
docs/기본 개발계획/29-비밀번호_및_개인정보_암호화_기술.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# 비밀번호 및 개인정보 암호화 기술 정리
|
||||
|
||||
본 문서는 **종량제(jongryangje) 프로젝트에 실제 적용된** 비밀번호 처리와 개인정보(PII) 저장 방식을, 사용 기술·동작 원리·설정·코드 위치 기준으로 정리한다.
|
||||
|
||||
관련 코드·설정:
|
||||
|
||||
- `app/Controllers/Auth.php` — 회원가입 시 비밀번호 해시, 로그인 시 검증
|
||||
- `app/Controllers/Admin/User.php` — 관리자 회원 등록·수정 시 비밀번호 해시
|
||||
- `app/Helpers/pii_encryption_helper.php` — 이메일·연락처 암·복호화
|
||||
- `app/Config/Encryption.php` — CodeIgniter 4 암호화 설정
|
||||
|
||||
---
|
||||
|
||||
## 1. 암호화와 해시의 구분 (이 프로젝트에서의 역할)
|
||||
|
||||
| 구분 | 대상 데이터 | 목적 | 복원 가능 여부 |
|
||||
|------|-------------|------|----------------|
|
||||
| **해시 (일방향)** | 로그인 비밀번호 | “같은 비밀번호인지”만 검증 | **불가** (설계상 원문 복구 불가) |
|
||||
| **대칭키 암호화** | 이메일, 연락처 등 | DB 유출 시 평문 노출 완화, 화면 표시 시 복호화 | **가능** (암호화 키 보유 시) |
|
||||
|
||||
비밀번호는 **암호화가 아니라 해시**로 저장하는 것이 표준이다. “복호화해서 비교”하지 않고, `password_verify`로만 비교한다.
|
||||
|
||||
---
|
||||
|
||||
## 2. 비밀번호: PHP `password_hash` / `password_verify`
|
||||
|
||||
### 2.1 사용 API
|
||||
|
||||
- **저장(회원가입·비밀번호 변경 시)**
|
||||
`password_hash(평문비밀번호, PASSWORD_DEFAULT)`
|
||||
|
||||
- **검증(로그인 시)**
|
||||
`password_verify(입력평문, DB에_저장된_해시문자열)`
|
||||
|
||||
### 2.2 `PASSWORD_DEFAULT`의 의미
|
||||
|
||||
- PHP 버전에 따라 **권장 알고리즘**이 달라질 수 있으나, 일반적으로 **bcrypt** 기반 해시를 사용한다.
|
||||
- 해시 문자열 내부에 **알고리즘 식별자·비용(cost)·salt** 등이 **한 문자열에 포함**되어 저장된다.
|
||||
- 따라서 같은 비밀번호로 여러 번 `password_hash`를 호출해도 **매번 다른 해시**가 나올 수 있으며, `password_verify`는 저장된 해시 문자열을 해석해 올바르게 비교한다.
|
||||
|
||||
### 2.3 보안 관점에서의 특징
|
||||
|
||||
- DB가 유출되어도, 공격자가 해시만 가지고 **원 비밀번호를 바로 읽어낼 수는 없다** (무차별 대입·레인보우 테이블 등 별도 공격에는 여전히 취약할 수 있으므로 비밀번호 정책·2FA 등은 별도 검토).
|
||||
- 애플리케이션은 **평문 비밀번호를 DB에 저장하지 않는다**.
|
||||
|
||||
### 2.4 프로젝트 내 호출 위치
|
||||
|
||||
| 위치 | 용도 |
|
||||
|------|------|
|
||||
| `Auth::register()` | 가입 시 `mb_passwd`에 해시 저장 |
|
||||
| `Auth::login()` | `password_verify`로 로그인 검증 |
|
||||
| `Admin\User::store()` | 관리자가 등록한 회원 비밀번호 해시 |
|
||||
| `Admin\User::update()` | 비밀번호 변경 시에만 새 해시 저장 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 개인정보(PII): CodeIgniter 4 Encrypter + 커스텀 헬퍼
|
||||
|
||||
### 3.1 적용 필드
|
||||
|
||||
`app/Helpers/pii_encryption_helper.php` 상수 `PII_ENCRYPTED_FIELDS` 기준:
|
||||
|
||||
- `member.mb_email`
|
||||
- `member.mb_phone`
|
||||
|
||||
`mb_id`, `mb_name` 등은 **현재 코드 경로상 평문 저장**이다. (추가 암호화는 별도 설계·마이그레이션 필요.)
|
||||
|
||||
### 3.2 설정: `app/Config/Encryption.php`
|
||||
|
||||
| 항목 | 값 | 설명 |
|
||||
|------|-----|------|
|
||||
| `driver` | `OpenSSL` | OpenSSL 확장 기반 암호화 핸들러 사용 |
|
||||
| `cipher` | `AES-256-CTR` | AES 블록암호, 256비트 키, **CTR** 모드 |
|
||||
| `digest` | `SHA512` | 프레임워크 내부에서 무결성·키 유도 등에 사용되는 다이제스트 설정 (OpenSSL 핸들러와 연동) |
|
||||
| `rawData` | `true` | 암호문을 raw 바이너리로 다룸 (이후 헬퍼에서 base64로 한 번 더 감쌈) |
|
||||
| `key` | `.env`의 `encryption.key` | **64자리 16진수(hex)** 문자열만 유효로 인식 후 `hex2bin`으로 바이너리 키로 변환. 형식이 맞지 않으면 **빈 문자열**이 되어 암호화가 비활성화된다. |
|
||||
|
||||
키 로드 로직 요약:
|
||||
|
||||
- `env('encryption.key')` → 길이 64이고 모두 16진수인 경우에만 `hex2bin` 적용.
|
||||
- 그 외는 `$key === ''` 로 간주되어 **암호화 미적용 분기**로 이어진다.
|
||||
|
||||
### 3.3 AES-256-CTR (개념)
|
||||
|
||||
- **AES**: 대칭키 블록암호. 같은 키로 암호화·복호화한다.
|
||||
- **256**: 키 길이(비트). 설정·키 생성 시 이 길이에 맞춰야 한다.
|
||||
- **CTR (Counter)**: 블록 모드의 하나. 스트림 암호에 가깝게 동작하며, **같은 키·같은 nonce/IV 재사용**만 피하면 안전하게 쓰는 패턴이 널리 쓰인다. (실제 IV/nonce 처리는 CodeIgniter Encrypter 구현에 따름.)
|
||||
|
||||
### 3.4 애플리케이션 레이어: `pii_encrypt` / `pii_decrypt`
|
||||
|
||||
동작 요약:
|
||||
|
||||
1. 값이 비어 있으면 빈 문자열 반환.
|
||||
2. `config('Encryption')->key`가 비어 있으면 **평문 그대로 반환** (키 미설정·개발 편의·기존 데이터 호환).
|
||||
3. 키가 있으면 `service('encrypter')->encrypt($value)` 호출 후, DB 저장용으로
|
||||
**`ENC:` + base64_encode(암호문 바이너리)** 형태로 만든다.
|
||||
4. 복호화 시 `ENC:` 접두사가 없으면 **레거시 평문**으로 간주해 그대로 반환.
|
||||
5. 예외 발생 시 안전하게 **원 입력값을 되돌리는** 폴백이 들어 있다 (운영에서는 로깅 정책 별도 검토 권장).
|
||||
|
||||
이렇게 하면:
|
||||
|
||||
- DB 덤프를 보더라도 `ENC:` 로 시작하는 필드는 **즉시 읽을 수 있는 평문이 아니다**.
|
||||
- 복호화에는 **애플리케이션이 읽는 동일한 `encryption.key`** 가 필요하다.
|
||||
|
||||
### 3.5 키 로테이션(설정상 지원)
|
||||
|
||||
`Encryption` 설정에 `previousKeys` 개념이 문서화되어 있다. 키 교체 시 구 데이터 복호화를 위해 **이전 키 목록**을 두는 용도이며, 실제 운영 적용 여부는 `.env` 및 CI4 버전 문서와 맞춰 설정해야 한다.
|
||||
|
||||
---
|
||||
|
||||
## 4. 데이터 흐름 요약
|
||||
|
||||
### 4.1 회원가입 (`Auth::register`)
|
||||
|
||||
1. 비밀번호 → `password_hash` → `member.mb_passwd`
|
||||
2. 이메일·연락처 → `pii_encrypt` → `member.mb_email`, `member.mb_phone` (키 있을 때만 암호문)
|
||||
|
||||
### 4.2 로그인 (`Auth::login`)
|
||||
|
||||
1. 아이디로 `member` 조회
|
||||
2. `password_verify(입력비밀번호, mb_passwd)`
|
||||
3. 승인 상태 등 추가 정책 후 세션 설정
|
||||
|
||||
### 4.3 관리자 회원 목록·수정 (`Admin\User`)
|
||||
|
||||
- 목록·수정 폼 표시 전 `pii_decrypt`로 이메일·연락처 복호화
|
||||
- 저장 시 다시 `pii_encrypt`
|
||||
|
||||
---
|
||||
|
||||
## 5. 운영·보안 체크리스트
|
||||
|
||||
- [ ] **`.env`에 `encryption.key` 설정**
|
||||
- 32바이트 난수의 hex 표현 = **64자리 hex** (프로젝트 주석 예: `php -r "echo bin2hex(random_bytes(32));"`)
|
||||
- [ ] `.env`는 **저장소에 커밋하지 않음** (`.env.example`에는 키 없이 변수명만)
|
||||
- [ ] 백업·로그에 **복호화된 PII**가 불필요하게 남지 않도록 주의
|
||||
- [ ] 비밀번호는 **절대 복호화·로그 출력하지 않음**
|
||||
- [ ] 키 분실 시: 기존 `ENC:` 데이터는 **복구 불가**에 가깝다 → 키 관리 절차 필요
|
||||
|
||||
---
|
||||
|
||||
## 6. 참고 문서
|
||||
|
||||
- 동일 레포 내 설계 방향: `docs/기본 개발계획/19-db-personal-data-encryption.md`
|
||||
- PHP: [password_hash](https://www.php.net/manual/en/function.password-hash.php), [password_verify](https://www.php.net/manual/en/function.password-verify.php)
|
||||
- CodeIgniter 4: [Encryption 서비스](https://codeigniter.com/user_guide/libraries/encryption.html)
|
||||
|
||||
---
|
||||
|
||||
## 7. 변경 이력
|
||||
|
||||
- 최초 작성: 프로젝트 코드(`Auth`, `User`, `pii_encryption_helper`, `Config\Encryption`) 기준 정리
|
||||
135
docs/기본 개발계획/테이블/00-테이블_목록_및_ERD.md
Normal 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`
|
||||
190
docs/기본 개발계획/테이블/01-마스터_테이블_DDL.md
Normal 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='무료용 대상자';
|
||||
```
|
||||
180
docs/기본 개발계획/테이블/02-물류_판매_테이블_DDL.md
Normal 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='수불 내역';
|
||||
```
|
||||
59
docs/기본 개발계획/테이블/03-지자체_데이터_필터_및_권한.md
Normal 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 | |
|
||||
215
docs/기본 개발계획/테이블/04-마스터_데이터_선행_정리.md
Normal 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`의 규칙을 따른다.
|
||||
|
||||
24
docs/기본 개발계획/테이블/README.md
Normal 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`
|
||||
241
docs/노션_업로드용_작업내역.md
Normal file
@@ -0,0 +1,241 @@
|
||||
# 종량제 쓰레기봉투 물류시스템 개발 - 작업내역
|
||||
|
||||
> 노션 업로드용 상세 작업내역 문서
|
||||
> 작성일: 2025년 기준
|
||||
|
||||
---
|
||||
|
||||
## 📋 프로젝트 개요
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| 프로젝트명 | 종량제 쓰레기봉투 물류시스템 |
|
||||
| 기술 스택 | CodeIgniter 4, PHP 8.2+, MariaDB |
|
||||
| 개발 환경 | jongryangje.local:8080 |
|
||||
|
||||
---
|
||||
|
||||
## ✅ 완료된 작업 목록
|
||||
|
||||
### 1. 로그인/로그아웃 기능 개발
|
||||
|
||||
#### 1.1 구현 내용
|
||||
|
||||
- **로그인 화면** (`/login`)
|
||||
- 아이디/비밀번호 입력 폼
|
||||
- CSRF 토큰 적용
|
||||
- 유효성 검증 (필수 입력, 최대 길이)
|
||||
- 에러/성공 메시지 표시
|
||||
|
||||
- **로그인 처리** (`POST /login`)
|
||||
- 아이디·비밀번호 검증
|
||||
- 계정 상태 체크 (정상/정지/탈퇴)
|
||||
- 로그인 성공 시 세션 저장 (`mb_idx`, `mb_id`, `mb_name`, `mb_level`, `logged_in`)
|
||||
- 최근 접속일(`mb_latestdate`) 업데이트
|
||||
|
||||
- **로그아웃 처리** (`/logout`)
|
||||
- 세션 파괴
|
||||
- 로그아웃 이력 기록
|
||||
- 로그인 페이지로 리다이렉트
|
||||
|
||||
#### 1.2 관련 파일
|
||||
|
||||
| 파일 경로 | 설명 |
|
||||
|-----------|------|
|
||||
| `app/Controllers/Auth.php` | 로그인/로그아웃/회원가입 컨트롤러 |
|
||||
| `app/Views/auth/login.php` | 로그인 화면 뷰 |
|
||||
| `app/Models/MemberModel.php` | 회원 조회 모델 |
|
||||
| `app/Models/MemberLogModel.php` | 로그 이력 모델 |
|
||||
|
||||
#### 1.3 로그 테이블
|
||||
|
||||
- **member_log** 테이블: 로그인 성공/실패 이력 저장
|
||||
- 기록 항목: 회원ID, 성공여부, IP, User-Agent, 메시지, 로그아웃 시각 등
|
||||
|
||||
---
|
||||
|
||||
### 2. 로그인 후 메인 화면 연동
|
||||
|
||||
#### 2.1 구현 내용
|
||||
|
||||
- 로그인 성공 시 **일일봉투 수불현황** 페이지로 자동 이동
|
||||
- 기존 대시보드(`home/dashboard`) 대신 `bag/daily_inventory` 뷰 표시
|
||||
|
||||
#### 2.2 수정 파일
|
||||
|
||||
| 파일 | 변경 내용 |
|
||||
|------|-----------|
|
||||
| `app/Controllers/Home.php` | `view('home/dashboard')` → `view('bag/daily_inventory')` |
|
||||
| `app/Controllers/Auth.php` | 리다이렉트 URL을 `site_url('/')`로 명시 |
|
||||
|
||||
---
|
||||
|
||||
### 3. 일일봉투 수불현황 페이지 개발
|
||||
|
||||
#### 3.1 페이지 구성
|
||||
|
||||
Google Stitch로 제작한 HTML을 CodeIgniter 뷰로 변환하여 구현
|
||||
|
||||
**레이아웃 구조**
|
||||
|
||||
1. **상단 헤더**
|
||||
- 로고 + 시스템명
|
||||
- 메뉴 네비게이션
|
||||
- 로그아웃(종료) 아이콘
|
||||
|
||||
2. **페이지 제목 바**
|
||||
- 화면 ID: `[w_gm804r]`
|
||||
- 제목: 일일 봉투 수불 현황
|
||||
|
||||
3. **컨트롤 패널 (검색/필터)**
|
||||
- 조회기간 (날짜 ~ 날짜)
|
||||
- 봉투구분 (드롭다운)
|
||||
- 봉투형식 (드롭다운)
|
||||
- 대행소 (드롭다운)
|
||||
- 액션 버튼: 조회, 엑셀저장, 인쇄, 종료
|
||||
|
||||
4. **데이터 테이블**
|
||||
- 일자 | 품 목 | 전일재고 | 입고(입고/반품/입고계) | 출고(판매/일반불출·무료불출/반품/기타/출고계) | 잔량
|
||||
|
||||
5. **푸터**
|
||||
- Ready..... | 북구 | Ver.. | 날짜/시간
|
||||
|
||||
#### 3.2 관련 파일
|
||||
|
||||
| 파일 경로 | 설명 |
|
||||
|-----------|------|
|
||||
| `app/Views/bag/daily_inventory.php` | 일일봉투 수불현황 뷰 (신규 생성) |
|
||||
| `app/Controllers/Home.php` | 로그인 시 해당 뷰 반환 |
|
||||
|
||||
---
|
||||
|
||||
### 4. 503 오류 및 리다이렉트 이슈 해결
|
||||
|
||||
#### 4.1 원인
|
||||
|
||||
- `jongryangje.local` 호스트가 `allowedHostnames`에 없어 URL 생성/리다이렉트 시 문제 발생 가능
|
||||
|
||||
#### 4.2 조치 내용
|
||||
|
||||
| 파일 | 변경 내용 |
|
||||
|------|-----------|
|
||||
| `app/Config/App.php` | `allowedHostnames`에 `jongryangje.local`, `localhost` 추가 |
|
||||
| `app/Controllers/Auth.php` | `redirect()->to('/')` → `redirect()->to(site_url('/'))` |
|
||||
|
||||
---
|
||||
|
||||
### 5. UI/UX 개선 (참조 이미지 반영)
|
||||
|
||||
일일봉투 수불현황 기준 이미지에 맞춰 UI 수정
|
||||
|
||||
#### 5.1 로고 변경
|
||||
|
||||
| 구분 | 변경 전 | 변경 후 |
|
||||
|------|---------|---------|
|
||||
| 형태 | 녹색 원형 + 새로고침 아이콘 | 파란색 사각형 + 흰색 사각형 2개 겹친 형태 |
|
||||
| 스타일 | 웹 스타일 | 데스크톱 앱 아이콘 스타일 |
|
||||
|
||||
#### 5.2 타이틀 변경
|
||||
|
||||
| 구분 | 변경 전 | 변경 후 |
|
||||
|------|---------|---------|
|
||||
| 시스템명 | 스마트 폐기물 관리 시스템 | 쓰레기봉투 물류시스템 |
|
||||
|
||||
#### 5.3 페이지 제목 바
|
||||
|
||||
| 항목 | 변경 내용 |
|
||||
|------|-----------|
|
||||
| 화면 ID | `[_gm804r]` → `[w_gm804r]` |
|
||||
| 제목 | 일별 봉투 수불황 → 일일 봉투 수불 현황 |
|
||||
|
||||
#### 5.4 메뉴 구성
|
||||
|
||||
| 변경 내용 |
|
||||
|-----------|
|
||||
| 발주/입고 관리 → 발주 입고 관리 |
|
||||
| 통계/분석 관리 → 통계 분석 관리 |
|
||||
| 봉투 수불 관리 메뉴 추가 |
|
||||
| 설정 → 창 메뉴로 변경 |
|
||||
|
||||
#### 5.5 버튼 및 아이콘
|
||||
|
||||
| 버튼 | 변경 전 | 변경 후 |
|
||||
|------|---------|---------|
|
||||
| 검색 | 검색 | 조회 |
|
||||
| 엑셀 | Excel 내보내기 | 엑셀저장 |
|
||||
| 종료 | 번개 아이콘 | 빨간색 X 아이콘 |
|
||||
| 우측 상단 | 로그아웃 아이콘 | 빨간색 X 아이콘 |
|
||||
|
||||
#### 5.6 테이블
|
||||
|
||||
| 항목 | 변경 내용 |
|
||||
|------|-----------|
|
||||
| 헤더 | 품목 → 품 목 |
|
||||
|
||||
---
|
||||
|
||||
## 📁 파일 구조 변경 요약
|
||||
|
||||
### 신규 생성
|
||||
|
||||
```
|
||||
app/Views/bag/daily_inventory.php # 일일봉투 수불현황 뷰
|
||||
```
|
||||
|
||||
### 수정된 파일
|
||||
|
||||
```
|
||||
app/Controllers/Auth.php # 로그인 리다이렉트, allowedHostnames 대응
|
||||
app/Controllers/Home.php # 로그인 후 표시 뷰 변경
|
||||
app/Config/App.php # allowedHostnames 추가
|
||||
app/Views/bag/daily_inventory.php # UI 수정 (로고, 메뉴, 버튼 등)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 설정 정보
|
||||
|
||||
### 환경 변수 (.env)
|
||||
|
||||
```
|
||||
CI_ENVIRONMENT = development
|
||||
app.baseURL = 'http://jongryangje.local:8080/'
|
||||
database.default.hostname = localhost
|
||||
database.default.database = jongryangje_dev
|
||||
database.default.username = jongryangje
|
||||
database.default.password = 'jongryangje_dev'
|
||||
```
|
||||
|
||||
### 라우트 (Routes.php)
|
||||
|
||||
| Method | URI | Controller::Method |
|
||||
|--------|-----|---------------------|
|
||||
| GET | / | Home::index |
|
||||
| GET | login | Auth::showLoginForm |
|
||||
| POST | login | Auth::login |
|
||||
| GET | logout | Auth::logout |
|
||||
| GET | register | Auth::showRegisterForm |
|
||||
| POST | register | Auth::register |
|
||||
|
||||
---
|
||||
|
||||
## 📊 진행 현황 요약
|
||||
|
||||
| 작업 항목 | 진행률 | 비고 |
|
||||
|-----------|--------|------|
|
||||
| 로그인/로그아웃 개발 | 100% | 완료 |
|
||||
| 로그인 후 메인 화면 연동 | 100% | 완료 |
|
||||
| 일일봉투 수불현황 페이지 | 100% | 완료 |
|
||||
| 503 오류 해결 | 100% | 완료 |
|
||||
| UI/UX 개선 (참조 이미지 반영) | 100% | 완료 |
|
||||
|
||||
---
|
||||
|
||||
## 📌 참고 자료
|
||||
|
||||
- 참조 이미지: `docs/종량제 관련 자료/쓰레기봉투 물류시스템_스크린샷/봉투수불관리/일일봉투 수불현황.png`
|
||||
- 기술 스택: CodeIgniter 4.7.0, PHP 8.2+, Tailwind CSS (CDN)
|
||||
|
||||
---
|
||||
|
||||
*본 문서는 노션 페이지 업로드용으로 작성되었습니다.*
|
||||
58
docs/보안관련/01-개인정보_보안_현황.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# 개인정보·보안 현황
|
||||
|
||||
> 현재 구현 기준. DB·세션·로그·화면 접근을 정리한 문서.
|
||||
|
||||
---
|
||||
|
||||
## 1. 비밀번호
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **저장** | DB에는 **해시만** 저장 (`password_hash(..., PASSWORD_DEFAULT)` → PHP bcrypt) |
|
||||
| **위치** | `Auth::register`, `Admin\User::store`, `Admin\User::update` |
|
||||
| **검증** | 로그인 시 `password_verify()` 사용. 평문 비밀번호는 저장·전달하지 않음 |
|
||||
|
||||
---
|
||||
|
||||
## 2. DB에 저장되는 개인정보(비밀번호 제외)
|
||||
|
||||
- **member 테이블**: `mb_id`, `mb_name`, `mb_email`, `mb_phone` 등은 **평문** 저장.
|
||||
- **암호화**: 애플리케이션 단에서 이 컬럼들에 대한 암호화·복호화는 **없음**.
|
||||
- **DB 연결**: `app/Config/Database.php` 에서 `'encrypt' => false`. DB 연결 구간 암호화(TLS)는 앱 설정에 없음(서버/DB 설정에 따름).
|
||||
|
||||
---
|
||||
|
||||
## 3. 세션
|
||||
|
||||
- **저장 항목**: `mb_idx`, `mb_id`, `mb_name`, `mb_level`, `logged_in`
|
||||
- **비밀번호·이메일·연락처는 세션에 넣지 않음.**
|
||||
|
||||
---
|
||||
|
||||
## 4. 로그(member_log)
|
||||
|
||||
- **저장 필드**: `mb_idx`, `mb_id`, `mll_regdate`, `mll_ip`, `mll_msg`, `mll_useragent`, `mll_url`, `mll_referer` 등
|
||||
- **비밀번호는 로그에 기록되지 않음.**
|
||||
- 로그인 시도 시 **아이디(mb_id)** 는 그대로 저장됨(실패/성공 구분용). 마스킹·축약 저장은 없음.
|
||||
|
||||
---
|
||||
|
||||
## 5. 화면·접근
|
||||
|
||||
- 뷰 출력 시 `esc()` 사용 → **XSS** 방지.
|
||||
- 회원 목록(이름·이메일·연락처 등)은 **관리자만** 조회 가능(`adminAuth` 필터).
|
||||
|
||||
---
|
||||
|
||||
## 6. 요약
|
||||
|
||||
| 구분 | 적용 여부 |
|
||||
|------|-----------|
|
||||
| 비밀번호 해시 저장·검증 | ✅ 적용 |
|
||||
| 세션에 비밀번호 미저장 | ✅ 적용 |
|
||||
| 로그에 비밀번호 미기록 | ✅ 적용 |
|
||||
| 출력 이스케이프(esc) | ✅ 적용 |
|
||||
| 관리자만 회원 목록 조회 | ✅ 적용 |
|
||||
| 이름·이메일·연락처 DB 암호화 | ⚠️ 선택 적용 (키 설정 시 `mb_phone`, `mb_email` 암호화. [03-개인정보_암호화.md](03-개인정보_암호화.md) 참고) |
|
||||
| 로그의 mb_id 마스킹 | ❌ 미적용 |
|
||||
| DB 연결 암호화(TLS) 설정 | ❌ 앱 설정 없음 |
|
||||
37
docs/보안관련/02-개선_검토_사항.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# 보안·개인정보 개선 검토 사항
|
||||
|
||||
> 개인정보보호법·내부 정책에 맞춰 추후 검토할 수 있는 항목.
|
||||
|
||||
---
|
||||
|
||||
## 1. DB 저장 암호화
|
||||
|
||||
- **대상**: `member.mb_name`, `mb_email`, `mb_phone` 등 개인정보 필드
|
||||
- **방식**: 필드 단위 암호화(예: CI4 Encryption, AES) 후 DB 저장, 조회 시 복호화
|
||||
- **참고**: `app/Config/Encryption.php` 에 키 설정 후 Encrypter 사용 가능
|
||||
|
||||
---
|
||||
|
||||
## 2. 로그 내 식별자 마스킹
|
||||
|
||||
- **대상**: `member_log.mb_id` (로그인 시도 아이디)
|
||||
- **방식**: 전체 저장 대신 앞뒤 일부만 저장하거나 마스킹(예: `ab***ef`) 후 저장
|
||||
- **목적**: 로그 유출 시 개인 식별 가능성 완화
|
||||
|
||||
---
|
||||
|
||||
## 3. DB 연결 암호화(TLS)
|
||||
|
||||
- **대상**: 애플리케이션 ↔ DB 서버 구간
|
||||
- **방식**: MySQL SSL/TLS 설정 후 `app/Config/Database.php` 에서 `encrypt`·DSN 옵션 설정
|
||||
- **참고**: DB 서버·호스팅 측에서 SSL 지원 여부 확인 필요
|
||||
|
||||
---
|
||||
|
||||
## 4. 기타 검토
|
||||
|
||||
- **세션**: 세션 고정·타임아웃·재로그인 정책
|
||||
- **관리자**: 관리자 계정 2단계 인증, 접근 로그
|
||||
- **비밀번호**: 최소 길이·복잡도·주기적 변경 정책(현재는 4자 이상, 해시 저장만 적용)
|
||||
|
||||
위 항목은 필요 시 단계적으로 도입을 검토하면 된다.
|
||||
73
docs/보안관련/03-개인정보_암호화.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# 개인정보 암호화 (전화번호·이메일 등)
|
||||
|
||||
> 비밀번호는 해시(일방향), 전화번호·이메일 등은 **암호화(양방향)** 로 저장해, 키가 없으면 개발자도 복호화할 수 없게 하는 방법.
|
||||
|
||||
---
|
||||
|
||||
## 1. 해시 vs 암호화
|
||||
|
||||
| 구분 | 비밀번호 | 전화번호·이메일 등 |
|
||||
|------|----------|---------------------|
|
||||
| **목적** | 로그인 시 “같은지”만 검사 | 화면·연락에 **다시 읽어서** 써야 함 |
|
||||
| **방식** | 해시(일방향) | 암호화(양방향) |
|
||||
| **저장** | 해시만 저장 | 암호문 저장, **키**로 복호화 |
|
||||
|
||||
그래서 개인정보는 **암호화**해서 저장하고, 읽을 때만 **복호화**합니다.
|
||||
|
||||
---
|
||||
|
||||
## 2. “개발자가 해독할 수 없게” 하려면
|
||||
|
||||
- 암호화/복호화는 **키(비밀키)** 로 합니다.
|
||||
- 키를 **앱/코드 밖**에 두면, 코드를 아는 개발자라도 키가 없으면 복호화할 수 없습니다.
|
||||
|
||||
**권장:**
|
||||
|
||||
- **암호화 키**를 `.env`(또는 환경 변수)에만 넣고, **저장소에는 올리지 않음** (`.env`는 `.gitignore`).
|
||||
- 운영 서버에서는 서버만 갖는 키를 두고, 개발 PC에는 키를 두지 않거나 테스트용 키만 둠.
|
||||
- 필요하면 AWS KMS, HashiCorp Vault 등 **키 관리 서비스**로 키를 분리할 수 있습니다.
|
||||
|
||||
이렇게 하면 “키가 없는 사람(예: 코드만 본 개발자)”은 DB에 저장된 암호문을 풀 수 없습니다.
|
||||
|
||||
---
|
||||
|
||||
## 3. 이 프로젝트에서의 구현 개요
|
||||
|
||||
- **대상 필드**: `member.mb_phone`, `member.mb_email` (선택: `mb_name`)
|
||||
- **방식**: 저장 전 암호화, 조회 후 복호화. CI4 `Encryption`(OpenSSL) 사용.
|
||||
- **키**: `app/Config/Encryption.php` → `.env`의 `encryption.key`. 키가 비어 있으면 암호화/복호화를 건너뛰어 기존 평문 데이터와 호환.
|
||||
- **저장 형식**: 암호문 앞에 `ENC:` 접두어를 붙여 “암호화된 값”인지 구분. 기존 평문 데이터는 그대로 두고, 새로 넣거나 수정할 때만 암호화해 저장.
|
||||
|
||||
---
|
||||
|
||||
## 4. 키 설정 방법
|
||||
|
||||
1. **키 생성** (32바이트):
|
||||
```bash
|
||||
php -r "echo bin2hex(random_bytes(32));"
|
||||
```
|
||||
2. **.env**에 추가 (저장소에 커밋하지 않음):
|
||||
```
|
||||
encryption.key = 위에서 나온 64자 hex 문자열
|
||||
```
|
||||
3. `app/Config/Encryption.php`에서 `$key`가 환경 변수에서 오도록 설정했는지 확인. (기본값은 빈 문자열이고, `.env`에서 덮어쓰면 됨.)
|
||||
|
||||
키를 넣지 않으면 암호화/복호화가 동작하지 않고, 값은 평문으로 저장·조회됩니다.
|
||||
|
||||
---
|
||||
|
||||
## 5. 구현 요약 (이 프로젝트)
|
||||
|
||||
- **헬퍼**: `app/Helpers/pii_encryption_helper.php` — `pii_encrypt($value)`, `pii_decrypt($value)`
|
||||
- **대상 필드**: `member.mb_phone`, `member.mb_email` (상수 `PII_ENCRYPTED_FIELDS`)
|
||||
- **저장 형식**: 암호화 시 `ENC:` + base64(암호문). 미암호화(키 없음) 또는 기존 평문은 그대로 저장·조회.
|
||||
- **사용처**: `Auth::register` 저장 전 암호화, `Admin\User::store` / `update` 저장 전 암호화, `Admin\User::index` / `edit` 조회 후 복호화.
|
||||
- **설정**: `app/Config/Encryption.php` — `.env`의 `encryption.key`(64자 hex)를 읽어 사용. 키가 없으면 암호화/복호화 생략.
|
||||
|
||||
---
|
||||
|
||||
## 6. 정리
|
||||
|
||||
- 전화번호·이메일 등은 **암호화**해서 저장하고, **키**로만 복호화합니다.
|
||||
- 키를 **코드/저장소 밖**(`.env`·키 관리 서비스)에 두면, **개발자가 해독할 수 없게** 할 수 있습니다.
|
||||
- 비밀번호는 계속 **해시만** 저장하고, 개인정보 필드만 암호화하는 방식이 적절합니다.
|
||||
13
docs/보안관련/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# 보안 관련 정리
|
||||
|
||||
> DB·앱에서의 사용자 개인정보 및 보안 처리 현황.
|
||||
|
||||
---
|
||||
|
||||
## 문서 목록
|
||||
|
||||
| 파일 | 내용 |
|
||||
|------|------|
|
||||
| [01-개인정보_보안_현황.md](01-개인정보_보안_현황.md) | 비밀번호·DB·세션·로그·화면 접근 등 종합 현황 |
|
||||
| [02-개선_검토_사항.md](02-개선_검토_사항.md) | 추후 검토 가능한 보안·개인정보 보강 항목 |
|
||||
| [03-개인정보_암호화.md](03-개인정보_암호화.md) | 전화번호·이메일 암호화 저장, 키 관리, 개발자 비해독 가능 |
|
||||
12
docs/완료된_개발_내역/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# 완료된 개발 내역
|
||||
|
||||
> 구현이 완료된 기능별 정리. 상세는 각 하위 폴더·파일 참고.
|
||||
|
||||
---
|
||||
|
||||
## 목록
|
||||
|
||||
| 구분 | 경로 | 요약 |
|
||||
|------|------|------|
|
||||
| **관리자단** | [관리자단/](관리자단/README.md) | AdminAuth 필터, 회원/접근/역할/메뉴, 뷰·라우트 |
|
||||
| **인증 및 홈** | [인증_및_홈/](인증_및_홈/README.md) | 로그인 후 리다이렉트(→ /), 루트(/) 표시 뷰(로그인 시 bag/daily_inventory, 비로그인 시 welcome_message) |
|
||||
16
docs/완료된_개발_내역/관리자단/01-필터.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# 관리자단 — 필터
|
||||
|
||||
## AdminAuthFilter
|
||||
|
||||
- **파일**: `app/Filters/AdminAuthFilter.php`
|
||||
- **등록**: `app/Config/Filters.php` → `'adminAuth' => \App\Filters\AdminAuthFilter::class`
|
||||
|
||||
### 동작
|
||||
|
||||
1. **로그인 여부**: `session()->get('logged_in')`이 없으면 → `site_url('login')`으로 리다이렉트, 플래시 `error` "로그인이 필요합니다."
|
||||
2. **권한**: `session()->get('mb_level')`이 **3**(`Roles::LEVEL_LOCAL_ADMIN`) 또는 **4**(`Roles::LEVEL_SUPER_ADMIN`)이 아니면 → `site_url('/')`로 리다이렉트, 플래시 `error` "관리자만 접근할 수 있습니다."
|
||||
3. 통과 시 `before()`는 `null` 반환하여 다음 처리 진행.
|
||||
|
||||
### 적용 범위
|
||||
|
||||
- `app/Config/Routes.php`의 `admin` 그룹 전체에 `'filter' => 'adminAuth'`로 적용됨.
|
||||
25
docs/완료된_개발_내역/관리자단/02-라우트.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# 관리자단 — 라우트
|
||||
|
||||
## 정의 위치
|
||||
|
||||
`app/Config/Routes.php` — `$routes->group('admin', ['filter' => 'adminAuth'], ...)`
|
||||
|
||||
## 목록
|
||||
|
||||
| Method | URI | Handler | 비고 |
|
||||
|--------|-----|---------|------|
|
||||
| GET | `/admin` | `Admin\Dashboard::index` | 대시보드 |
|
||||
| GET | `/admin/users` | `Admin\User::index` | 회원 목록 |
|
||||
| GET | `/admin/users/create` | `Admin\User::create` | 회원 등록 폼 |
|
||||
| POST | `/admin/users/store` | `Admin\User::store` | 회원 등록 처리 |
|
||||
| GET | `/admin/users/edit/(:num)` | `Admin\User::edit/$1` | 회원 수정 폼 |
|
||||
| POST | `/admin/users/update/(:num)` | `Admin\User::update/$1` | 회원 수정 처리 |
|
||||
| POST | `/admin/users/delete/(:num)` | `Admin\User::delete/$1` | 회원 탈퇴 처리 |
|
||||
| GET | `/admin/access/login-history` | `Admin\Access::loginHistory` | 로그인 이력(기간 조회) |
|
||||
| GET | `/admin/access/approvals` | `Admin\Access::approvals` | 권한 승인 대기 목록 |
|
||||
| POST | `/admin/access/approve/(:num)` | `Admin\Access::approve/$1` | 권한 승인(플레이스홀더) |
|
||||
| POST | `/admin/access/reject/(:num)` | `Admin\Access::reject/$1` | 권한 반려(플레이스홀더) |
|
||||
| GET | `/admin/roles` | `Admin\Role::index` | 역할 목록(Config\Roles) |
|
||||
| GET | `/admin/menus` | `Admin\Menu::index` | 메뉴 관리(플레이스홀더) |
|
||||
|
||||
모든 위 라우트에 `adminAuth` 필터가 before/after로 적용됨.
|
||||
59
docs/완료된_개발_내역/관리자단/03-컨트롤러.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# 관리자단 — 컨트롤러
|
||||
|
||||
## 공통
|
||||
|
||||
- 네임스페이스: `App\Controllers\Admin`
|
||||
- 모든 응답은 `admin/layout`으로 감싸서 `title`, `content` 전달. 본문은 하위 뷰에서 렌더.
|
||||
|
||||
---
|
||||
|
||||
## Dashboard
|
||||
|
||||
- **파일**: `app/Controllers/Admin/Dashboard.php`
|
||||
- **메서드**: `index()` — 대시보드 뷰만 표시.
|
||||
|
||||
---
|
||||
|
||||
## User (회원 관리)
|
||||
|
||||
- **파일**: `app/Controllers/Admin/User.php`
|
||||
- **의존**: `MemberModel`, `Config\Roles`
|
||||
|
||||
| 메서드 | 역할 |
|
||||
|--------|------|
|
||||
| `index()` | 회원 목록 (목록 뷰 + roles) |
|
||||
| `create()` | 회원 등록 폼 |
|
||||
| `store()` | 등록 처리: 유효성 검사 → 비밀번호 해시 → insert, redirect `admin/users` |
|
||||
| `edit($id)` | 수정 폼 (회원 없으면 redirect) |
|
||||
| `update($id)` | 수정 처리: 유효성(비밀번호 선택), mb_state 포함, redirect `admin/users` |
|
||||
| `delete($id)` | 탈퇴 처리: `mb_state=0`, `mb_leavedate` 설정 후 redirect (물리 삭제 없음) |
|
||||
|
||||
- 삭제는 **탈퇴 처리**만 수행. 5년 유지 정책은 별도 스케줄/정책으로 구현 예정.
|
||||
|
||||
---
|
||||
|
||||
## Access (접근 관리)
|
||||
|
||||
- **파일**: `app/Controllers/Admin/Access.php`
|
||||
- **의존**: `MemberLogModel`
|
||||
|
||||
| 메서드 | 역할 |
|
||||
|--------|------|
|
||||
| `loginHistory()` | GET `start`/`end` 기간으로 로그 이력 조회, 뷰에 list/start/end 전달 |
|
||||
| `approvals()` | 권한 승인 대기 목록 (현재 빈 목록, 추후 테이블 연동) |
|
||||
| `approve($id)` | 승인 처리 플레이스홀더 (redirect + success) |
|
||||
| `reject($id)` | 반려 처리 플레이스홀더 (redirect + success) |
|
||||
|
||||
---
|
||||
|
||||
## Role (역할)
|
||||
|
||||
- **파일**: `app/Controllers/Admin/Role.php`
|
||||
- **메서드**: `index()` — `Config\Roles`의 `levelNames` 목록만 뷰에 전달. (role 테이블 미사용, 추후 확장 가능)
|
||||
|
||||
---
|
||||
|
||||
## Menu (메뉴)
|
||||
|
||||
- **파일**: `app/Controllers/Admin/Menu.php`
|
||||
- **메서드**: `index()` — 메뉴 관리 안내 뷰만 표시. (menu·menu_permission 테이블 연동은 추후)
|
||||
29
docs/완료된_개발_내역/관리자단/04-뷰.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# 관리자단 — 뷰
|
||||
|
||||
## 공통 레이아웃
|
||||
|
||||
- **파일**: `app/Views/admin/layout.php`
|
||||
- **역할**: 공통 HTML·Tailwind, 좌측 사이드바(대시보드/회원/로그인이력/승인대기/역할/메뉴 링크), 플래시(success/error/errors) 표시, `<?= $content ?>`로 본문 출력.
|
||||
- **변수**: `$title`, `$content` (본문은 각 컨트롤러에서 `view('admin/...')`로 렌더 후 전달)
|
||||
|
||||
---
|
||||
|
||||
## 디렉터리·파일
|
||||
|
||||
| 경로 | 역할 |
|
||||
|------|------|
|
||||
| `admin/dashboard/index.php` | 대시보드 본문 |
|
||||
| `admin/user/index.php` | 회원 목록 테이블(수정/삭제 링크) |
|
||||
| `admin/user/create.php` | 회원 등록 폼 (mb_id, mb_passwd, mb_name, mb_email, mb_phone, mb_level) |
|
||||
| `admin/user/edit.php` | 회원 수정 폼 (비밀번호 변경 선택, mb_state 포함) |
|
||||
| `admin/access/login_history.php` | 기간(start/end) 조회 폼 + 로그인 이력 테이블 |
|
||||
| `admin/access/approvals.php` | 권한 승인 대기 안내·테이블(현재 빈 목록) |
|
||||
| `admin/role/index.php` | Config\Roles levelNames 테이블 |
|
||||
| `admin/menu/index.php` | 메뉴 관리 안내 문구 |
|
||||
|
||||
---
|
||||
|
||||
## 뷰 규칙 (개발 규칙 준수)
|
||||
|
||||
- 출력: `esc()`, 링크: `base_url()`, 폼: `csrf_field()`, 복원: `old()`
|
||||
- 플래시: layout에서 `success`, `error`, `errors` 표시
|
||||
19
docs/완료된_개발_내역/관리자단/05-사용방법_확장예정.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# 관리자단 — 사용 방법 및 확장 예정
|
||||
|
||||
## 사용 방법
|
||||
|
||||
1. **관리자 계정**: DB `member` 테이블에서 해당 회원의 `mb_level`을 **3**(지자체관리자) 또는 **4**(super admin)으로 설정.
|
||||
2. **접속**: 해당 계정으로 로그인 후 `/admin` 접속.
|
||||
3. **회원 관리**: 등록/수정/삭제(탈퇴 처리). 삭제는 물리 삭제 없이 `mb_state=0`, `mb_leavedate` 기록.
|
||||
4. **로그인 이력**: `/admin/access/login-history`에서 쿼리 파라미터 `start`, `end`(날짜)로 기간 조회.
|
||||
|
||||
---
|
||||
|
||||
## 확장 예정
|
||||
|
||||
| 항목 | 현재 | 추후 |
|
||||
|------|------|------|
|
||||
| **권한 승인** | 승인 대기·승인/반려 플레이스홀더 | 권한 승인 요청 테이블·플로우 연동 후 구현 |
|
||||
| **역할(Role)** | Config\Roles levelNames 목록만 표시 | role 테이블·CRUD 및 역할별 설명 등 |
|
||||
| **메뉴(Menu)** | 안내 문구만 표시 | menu, menu_permission 테이블 및 메뉴별 권한 설정 (설계서 5단계) |
|
||||
| **회원 삭제 정책** | 탈퇴 처리만 수행 | 5년 보관 후 물리 삭제 등 스케줄/정책 추가 가능 |
|
||||
38
docs/완료된_개발_내역/관리자단/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# 관리자단 구현 완료 내역
|
||||
|
||||
> 개발 규칙 및 `docs/ai용 개발계획/관리자단_개발_설계.md` 기준으로 구현된 관리자단(admin) 기능 요약.
|
||||
|
||||
---
|
||||
|
||||
## 접속 URL
|
||||
|
||||
| 구분 | URL |
|
||||
|------|-----|
|
||||
| 관리자 대시보드 | `/admin` |
|
||||
| 회원 관리 | `/admin/users` |
|
||||
| 회원 등록 | `/admin/users/create` |
|
||||
| 로그인 이력 | `/admin/access/login-history` |
|
||||
| 승인 대기 | `/admin/access/approvals` |
|
||||
| 역할 | `/admin/roles` |
|
||||
| 메뉴 | `/admin/menus` |
|
||||
|
||||
- 접속 조건: 로그인한 계정의 `mb_level`이 **3**(지자체관리자) 또는 **4**(super admin)이어야 함.
|
||||
|
||||
---
|
||||
|
||||
## 구현 목록
|
||||
|
||||
| 항목 | 경로 | 비고 |
|
||||
|------|------|------|
|
||||
| 필터 | `app/Filters/AdminAuthFilter.php` | 미로그인/비관리자 차단 |
|
||||
| 라우트 | `app/Config/Routes.php` | `admin` 그룹, `adminAuth` 적용 |
|
||||
| 컨트롤러 | `app/Controllers/Admin/*.php` | Dashboard, User, Access, Role, Menu |
|
||||
| 뷰 | `app/Views/admin/**/*.php` | layout, dashboard, user, access, role, menu |
|
||||
|
||||
상세는 아래 파일 참고.
|
||||
|
||||
- [01-필터.md](01-필터.md) — AdminAuth 필터
|
||||
- [02-라우트.md](02-라우트.md) — admin 라우트 목록
|
||||
- [03-컨트롤러.md](03-컨트롤러.md) — 컨트롤러·메서드 요약
|
||||
- [04-뷰.md](04-뷰.md) — 뷰 구조·역할
|
||||
- [05-사용방법_확장예정.md](05-사용방법_확장예정.md) — 사용 방법 및 추후 확장
|
||||
35
docs/완료된_개발_내역/인증_및_홈/README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# 인증 및 홈(루트) — 구현 완료 내역
|
||||
|
||||
> 로그인 후 이동 경로 및 루트(/) 표시 뷰 정리.
|
||||
|
||||
---
|
||||
|
||||
## 로그인 후 연결 페이지
|
||||
|
||||
- **URL**: `/` (루트)
|
||||
- **처리**: `app/Controllers/Auth.php` — 로그인 성공 시 `redirect()->to(site_url('/'))->with('success', '로그인되었습니다.');`
|
||||
|
||||
즉, 로그인 후에는 **홈(루트)** 로 이동한다.
|
||||
|
||||
---
|
||||
|
||||
## 루트(/)에서 표시되는 뷰
|
||||
|
||||
- **라우트**: `GET /` → `Home::index`
|
||||
- **컨트롤러**: `app/Controllers/Home.php` — `index()` 메서드
|
||||
|
||||
| 조건 | 뷰 이름 | 파일 경로 |
|
||||
|------|---------|-----------|
|
||||
| **로그인 O** | `bag/daily_inventory` | `app/Views/bag/daily_inventory.php` |
|
||||
| **로그인 X** | `welcome_message` | `app/Views/welcome_message.php` |
|
||||
|
||||
- 로그인한 사용자는 루트 접속 시 **일일 봉투 수불(또는 bag 관련)** 화면(`bag/daily_inventory`)이 보이고, 비로그인 사용자는 **환영 페이지**(`welcome_message`)가 보인다.
|
||||
|
||||
---
|
||||
|
||||
## 일일 봉투 수불 화면 — 관리자 이동 버튼
|
||||
|
||||
- **뷰**: `app/Views/bag/daily_inventory.php`
|
||||
- **동작**: 로그인한 사용자의 `mb_level`이 **3**(지자체관리자) 또는 **4**(super admin)일 때만, 상단 헤더 우측에 **「관리자」** 버튼을 표시한다.
|
||||
- **버튼**: 클릭 시 `/admin`(관리자 대시보드)으로 이동. 스타일은 디자인 규칙의 주 액션 버튼(`btn-search`)을 사용한다.
|
||||
- **판단**: `Config\Roles::LEVEL_LOCAL_ADMIN`, `LEVEL_SUPER_ADMIN` 상수로 비교.
|
||||
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-1.png
Normal file
|
After Width: | Height: | Size: 214 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-10.png
Normal file
|
After Width: | Height: | Size: 135 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-11_1.png
Normal file
|
After Width: | Height: | Size: 568 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-11_2.png
Normal file
|
After Width: | Height: | Size: 393 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-11_3.png
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-12.png
Normal file
|
After Width: | Height: | Size: 223 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-2.png
Normal file
|
After Width: | Height: | Size: 347 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-3.png
Normal file
|
After Width: | Height: | Size: 330 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-4.png
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-5.png
Normal file
|
After Width: | Height: | Size: 296 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-5_2.png
Normal file
|
After Width: | Height: | Size: 200 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-6.png
Normal file
|
After Width: | Height: | Size: 141 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-6_2.png
Normal file
|
After Width: | Height: | Size: 177 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-7.png
Normal file
|
After Width: | Height: | Size: 382 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-8_1.png
Normal file
|
After Width: | Height: | Size: 381 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-8_2.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-8_3.png
Normal file
|
After Width: | Height: | Size: 520 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-8_4.png
Normal file
|
After Width: | Height: | Size: 372 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/1-9.png
Normal file
|
After Width: | Height: | Size: 510 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/2-1.png
Normal file
|
After Width: | Height: | Size: 414 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/2-2.png
Normal file
|
After Width: | Height: | Size: 219 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/2-3.png
Normal file
|
After Width: | Height: | Size: 150 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/2-4.png
Normal file
|
After Width: | Height: | Size: 222 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/2-5.png
Normal file
|
After Width: | Height: | Size: 401 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/2-6.png
Normal file
|
After Width: | Height: | Size: 378 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/2-7.png
Normal file
|
After Width: | Height: | Size: 268 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/3-1.png
Normal file
|
After Width: | Height: | Size: 146 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/3-2.png
Normal file
|
After Width: | Height: | Size: 144 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/3-3.png
Normal file
|
After Width: | Height: | Size: 316 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/4-1.png
Normal file
|
After Width: | Height: | Size: 200 KiB |
BIN
docs/종량제 관련 자료/ss_gbms/ss_gbms/4-2-1.png
Normal file
|
After Width: | Height: | Size: 86 KiB |