-- ============================================================ -- 회원(member) 테이블 (MariaDB) -- 로컬(아이디/비밀번호) + 소셜(네이버 등) 로그인 확장을 고려한 설계 -- 실행: 애플리케이션 기동 시 연결된 DB(sbdb)에 자동 생성됨 -- ============================================================ CREATE TABLE IF NOT EXISTS member ( id BIGINT NOT NULL AUTO_INCREMENT, login_id VARCHAR(50) NULL COMMENT '로컬 로그인 아이디 (소셜 전용 계정은 NULL)', password VARCHAR(100) NULL COMMENT 'BCrypt 해시 (소셜 전용 계정은 NULL)', name VARCHAR(100) NOT NULL COMMENT '이름/닉네임', email VARCHAR(255) NULL, provider VARCHAR(20) NOT NULL DEFAULT 'LOCAL' COMMENT 'LOCAL / NAVER', provider_id VARCHAR(100) NULL COMMENT '소셜 제공자 측 고유 사용자 ID', role VARCHAR(20) NOT NULL DEFAULT 'USER' COMMENT 'USER / ADMIN', status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE' COMMENT 'ACTIVE / SUSPENDED / WITHDRAWN', created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_member_login_id (login_id), UNIQUE KEY uk_member_provider (provider, provider_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 구글 계정 연결: 기존 LOCAL 계정에 구글 sub 를 연결해 같은 이메일이면 한 계정으로 통합한다. -- (provider 는 LOCAL 로 유지 → 아이디/비밀번호 로그인·프로필 편집 그대로) MariaDB IF NOT EXISTS 로 멱등. ALTER TABLE member ADD COLUMN IF NOT EXISTS google_id VARCHAR(100) NULL COMMENT '구글 sub (계정 연결용)' AFTER provider_id; ALTER TABLE member ADD UNIQUE KEY IF NOT EXISTS uk_member_google_id (google_id); -- 기존 구글 계정(provider=GOOGLE)의 sub 를 google_id 로 백필(멱등 — 이미 채워졌으면 아무 것도 안 함). UPDATE member SET google_id = provider_id WHERE provider = 'GOOGLE' AND google_id IS NULL AND provider_id IS NOT NULL; -- ============================================================ -- 앱 전역 설정 (단일 행, id=1). 관리자 화면에서 변경. -- ============================================================ CREATE TABLE IF NOT EXISTS app_setting ( id BIGINT NOT NULL, signup_enabled TINYINT(1) NOT NULL DEFAULT 1 COMMENT '회원가입 허용 여부(0=제한)', updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; INSERT IGNORE INTO app_setting (id, signup_enabled) VALUES (1, 1); -- ============================================================ -- 세션 백업 (Redis 유실/재시작 대비 영속 저장). getSession 미스 시 DB에서 복원. -- ============================================================ CREATE TABLE IF NOT EXISTS auth_session ( token VARCHAR(64) NOT NULL COMMENT '세션 토큰', member_id BIGINT NOT NULL, login_id VARCHAR(50) NULL, name VARCHAR(100) NULL, role VARCHAR(20) NULL, provider VARCHAR(20) NULL, remember_me TINYINT(1) NOT NULL DEFAULT 0, expires_at DATETIME NOT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (token), KEY idx_auth_session_expires (expires_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;