Files
jongryangje/writable/database/login_tables.sql
taekyoungc a3f92cd322 feat: TOTP 2차 인증, 관리자 메뉴/대시보드 및 의존성 반영
- robthree/twofactorauth, Auth 설정·TotpService·2FA 뷰·라우트
- member TOTP 컬럼 DDL(login_tables, member_add_totp.sql)
- 관리자 메뉴·레이아웃·필터·대시보드 등 연관 변경
- env 샘플에 auth.requireTotp 주석

Made-with: Cursor
2026-03-26 15:30:32 +09:00

125 lines
8.2 KiB
SQL

-- 로그인 기능용 테이블 (docs/11-login-logout-development-guide.md 기준)
-- 실행: mysql -h 127.0.0.1 -P 3306 -u jongryangje -p jongryangje_dev < writable/database/login_tables.sql
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ---------------------------------------------------------------------------
-- member: 로그인·권한용 회원 테이블
-- mb_state: 1=정상, 2=정지, 0=탈퇴
-- mb_level: app/Config/Roles.php 참고
-- 1=일반 사용자, 2=지정판매소, 3=지자체관리자, 4=super admin, 5=본부 관리자
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `member` (
`mb_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '회원 PK',
`mb_id` VARCHAR(50) NOT NULL COMMENT '로그인 아이디',
`mb_passwd` VARCHAR(255) NOT NULL COMMENT '비밀번호 해시(password_hash)',
`mb_totp_secret` TEXT NULL DEFAULT NULL COMMENT 'TOTP 시크릿(암호화 저장, pii_encrypt)',
`mb_totp_enabled` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '1=등록 완료·검증 대상',
`mb_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '이름',
`mb_email` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '이메일',
`mb_phone` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '연락처',
`mb_lang` VARCHAR(10) NOT NULL DEFAULT 'ko' COMMENT '언어',
`mb_level` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1=일반, 2=지정판매소, 3=지자체관리자, 4=super admin, 5=본부 관리자 (Roles.php)',
`mb_group` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '권한 그룹 코드(Phase 2)',
`mb_lg_idx` INT UNSIGNED NULL DEFAULT NULL COMMENT '소속 지자체 PK(지자체관리자만 사용)',
`mb_state` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1=정상, 2=정지, 0=탈퇴',
`mb_regdate` DATETIME NOT NULL COMMENT '가입일시',
`mb_latestdate` DATETIME NULL DEFAULT NULL COMMENT '최근 로그인 일시',
`mb_leavedate` DATETIME NULL DEFAULT NULL COMMENT '탈퇴일시',
PRIMARY KEY (`mb_idx`),
UNIQUE KEY `uk_mb_id` (`mb_id`),
KEY `idx_mb_state` (`mb_state`),
KEY `idx_mb_lg_idx` (`mb_lg_idx`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='회원(로그인·권한)';
-- ---------------------------------------------------------------------------
-- member_log: 로그인/로그아웃 이력 전용
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `member_log` (
`mll_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '로그 PK',
`mll_success` TINYINT(1) NOT NULL COMMENT '1=성공, 0=실패',
`mb_idx` INT UNSIGNED NULL DEFAULT NULL COMMENT '회원 PK(실패 시 NULL 가능)',
`mb_id` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '로그인 시도 아이디',
`mll_regdate` DATETIME NOT NULL COMMENT '로그 일시',
`mll_ip` VARCHAR(45) NOT NULL DEFAULT '' COMMENT 'IP',
`mll_msg` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '메시지(실패 사유 등)',
`mll_useragent` VARCHAR(500) NOT NULL DEFAULT '' COMMENT 'User-Agent',
`mll_logout_date` DATETIME NULL DEFAULT NULL COMMENT '로그아웃 일시',
`mll_url` VARCHAR(500) NULL DEFAULT NULL COMMENT '요청 URL(선택)',
`mll_referer` VARCHAR(500) NULL DEFAULT NULL COMMENT 'Referer(선택)',
`mll_country` VARCHAR(10) NULL DEFAULT NULL COMMENT '국가 코드(선택)',
`at_token` VARCHAR(100) NULL DEFAULT NULL COMMENT '세션/토큰 식별(선택)',
PRIMARY KEY (`mll_idx`),
KEY `idx_mll_mb_idx` (`mb_idx`),
KEY `idx_mll_regdate` (`mll_regdate`),
KEY `idx_mll_success` (`mll_success`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='로그인/로그아웃 이력';
-- ---------------------------------------------------------------------------
-- member_approval_request: 회원가입 역할 승인 요청 이력
-- 공개 회원가입 시 생성되며, 승인 후에만 requested_level이 member.mb_level로 반영됨
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `member_approval_request` (
`mar_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '승인요청 PK',
`mb_idx` INT UNSIGNED NOT NULL COMMENT '회원 FK(member.mb_idx)',
`mar_requested_level` TINYINT UNSIGNED NOT NULL COMMENT '요청 역할(1,2,3)',
`mar_status` VARCHAR(20) NOT NULL DEFAULT 'pending' COMMENT 'pending|approved|rejected',
`mar_request_note` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '요청 메모',
`mar_reject_reason` VARCHAR(255) NULL DEFAULT NULL COMMENT '반려 사유',
`mar_requested_at` DATETIME NOT NULL COMMENT '요청일시',
`mar_requested_by` INT UNSIGNED NULL DEFAULT NULL COMMENT '요청자 mb_idx',
`mar_processed_at` DATETIME NULL DEFAULT NULL COMMENT '처리일시',
`mar_processed_by` INT UNSIGNED NULL DEFAULT NULL COMMENT '처리자 mb_idx',
PRIMARY KEY (`mar_idx`),
KEY `idx_mar_mb_idx` (`mb_idx`),
KEY `idx_mar_status_requested` (`mar_status`, `mar_requested_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='회원가입 역할 승인 요청';
-- ---------------------------------------------------------------------------
-- local_government: 지자체 마스터 (테넌트 루트)
-- ---------------------------------------------------------------------------
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='지자체(테넌트 루트)';
-- ---------------------------------------------------------------------------
-- designated_shop: 지정판매소
-- ---------------------------------------------------------------------------
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='지정판매소';
SET FOREIGN_KEY_CHECKS = 1;