2026-05-31 15:43:09 +09:00
|
|
|
-- ============================================================
|
|
|
|
|
-- 회원(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;
|
2026-06-06 00:15:57 +09:00
|
|
|
|
2026-06-27 19:01:57 +09:00
|
|
|
-- 구글 계정 연결: 기존 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;
|
|
|
|
|
|
2026-06-28 11:02:19 +09:00
|
|
|
-- 멤버십 플랜 (무료/유료). 기존 회원은 FREE 로 시작 (멱등).
|
|
|
|
|
ALTER TABLE member ADD COLUMN IF NOT EXISTS plan VARCHAR(20) NOT NULL DEFAULT 'FREE' COMMENT 'FREE / PREMIUM' AFTER role;
|
|
|
|
|
|
2026-06-28 11:39:35 +09:00
|
|
|
-- 프로필 사진. google_picture 는 구글 로그인 시 동기화되는 구글 아바타 URL,
|
|
|
|
|
-- profile_image 는 사용자가 직접 올린 커스텀 이미지(data URL). 표시 우선순위: profile_image > google_picture > 이니셜.
|
|
|
|
|
ALTER TABLE member ADD COLUMN IF NOT EXISTS google_picture VARCHAR(500) NULL COMMENT '구글 아바타 URL (로그인 시 동기화)' AFTER google_id;
|
|
|
|
|
ALTER TABLE member ADD COLUMN IF NOT EXISTS profile_image MEDIUMTEXT NULL COMMENT '사용자 지정 프로필 이미지(data URL)' AFTER google_picture;
|
|
|
|
|
|
2026-06-28 12:27:35 +09:00
|
|
|
-- 포인트(게시판 글/댓글 작성 보상). 기존 회원은 0 으로 시작 (멱등).
|
|
|
|
|
ALTER TABLE member ADD COLUMN IF NOT EXISTS points BIGINT NOT NULL DEFAULT 0 COMMENT '활동 포인트' AFTER plan;
|
|
|
|
|
|
2026-06-28 15:12:45 +09:00
|
|
|
-- 멤버십 만료일 (유료 구독). NULL = 만료 없음(관리자 영구 부여) 또는 무료. 만료 지나면 스케줄러가 FREE 로 강등.
|
|
|
|
|
ALTER TABLE member ADD COLUMN IF NOT EXISTS plan_expires_at DATETIME NULL COMMENT '유료 멤버십 만료일시' AFTER plan;
|
|
|
|
|
|
2026-06-28 16:04:20 +09:00
|
|
|
-- 구독 상품(premium_monthly 등) + 자동 갱신 여부 (정기결제 관리)
|
|
|
|
|
ALTER TABLE member ADD COLUMN IF NOT EXISTS plan_product VARCHAR(100) NULL COMMENT '구독 상품 ID' AFTER plan_expires_at;
|
|
|
|
|
ALTER TABLE member ADD COLUMN IF NOT EXISTS plan_auto_renew TINYINT(1) NOT NULL DEFAULT 0 COMMENT '자동 갱신(해지 시 0)' AFTER plan_product;
|
|
|
|
|
|
2026-06-28 15:12:45 +09:00
|
|
|
-- 인앱 결제 기록 (영수증 검증·중복 방지·감사)
|
|
|
|
|
CREATE TABLE IF NOT EXISTS iap_purchase (
|
|
|
|
|
id BIGINT NOT NULL AUTO_INCREMENT,
|
|
|
|
|
member_id BIGINT NOT NULL,
|
|
|
|
|
platform VARCHAR(20) NOT NULL COMMENT 'GOOGLE_PLAY / TEST',
|
|
|
|
|
product_id VARCHAR(100) NOT NULL COMMENT '상품 ID(premium_monthly 등)',
|
|
|
|
|
purchase_token VARCHAR(512) NOT NULL COMMENT 'Play 구매 토큰(또는 테스트 토큰)',
|
|
|
|
|
order_id VARCHAR(120) NULL,
|
|
|
|
|
status VARCHAR(20) NOT NULL COMMENT 'VERIFIED / FAILED',
|
|
|
|
|
expires_at DATETIME NULL COMMENT '이 결제로 부여된 만료일',
|
|
|
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
|
PRIMARY KEY (id),
|
|
|
|
|
UNIQUE KEY uk_iap_token (purchase_token),
|
|
|
|
|
KEY idx_iap_member (member_id)
|
|
|
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
|
|
2026-06-28 12:27:35 +09:00
|
|
|
-- 포인트 적립/차감 이력 (감사 + 일일 지급 한도 계산용).
|
|
|
|
|
CREATE TABLE IF NOT EXISTS point_history (
|
|
|
|
|
id BIGINT NOT NULL AUTO_INCREMENT,
|
|
|
|
|
member_id BIGINT NOT NULL,
|
|
|
|
|
amount INT NOT NULL COMMENT '증감 포인트(+/-)',
|
|
|
|
|
reason VARCHAR(30) NOT NULL COMMENT 'BOARD_WRITE 등',
|
|
|
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
|
PRIMARY KEY (id),
|
|
|
|
|
KEY idx_point_history_member_date (member_id, reason, created_at)
|
|
|
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
|
|
2026-06-06 00:15:57 +09:00
|
|
|
-- ============================================================
|
|
|
|
|
-- 앱 전역 설정 (단일 행, 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);
|
2026-06-06 08:12:57 +09:00
|
|
|
|
|
|
|
|
-- ============================================================
|
|
|
|
|
-- 세션 백업 (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,
|
2026-06-28 11:02:19 +09:00
|
|
|
plan VARCHAR(20) NULL,
|
2026-06-06 08:12:57 +09:00
|
|
|
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;
|
2026-06-28 11:02:19 +09:00
|
|
|
-- 멤버십 플랜 백업 (기존 세션 테이블에도 멱등 추가).
|
|
|
|
|
ALTER TABLE auth_session ADD COLUMN IF NOT EXISTS plan VARCHAR(20) NULL AFTER role;
|