260706_1_계정, 로그인, 보안 초안 작성
This commit is contained in:
@@ -35,6 +35,13 @@ CREATE TABLE IF NOT EXISTS users (
|
||||
department VARCHAR(100), -- 부서명 (설계팀, 영업팀)
|
||||
phone VARCHAR(20), -- 연락처 (010-1234-5678)
|
||||
company_id INT, -- 소속 회사 (FK는 later)
|
||||
role ENUM('SYSTEM_ADMIN', 'MASTER', 'MEMBER') NOT NULL DEFAULT 'MEMBER',
|
||||
is_master BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
status ENUM('PENDING_EMAIL', 'PENDING', 'ACTIVE', 'INACTIVE', 'REJECTED') NOT NULL DEFAULT 'PENDING_EMAIL',
|
||||
last_email_verified_at TIMESTAMP NULL,
|
||||
login_failures INT NOT NULL DEFAULT 0,
|
||||
last_failed_at TIMESTAMP NULL,
|
||||
account_locked_until TIMESTAMP NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL DEFAULT NULL -- 소프트 삭제
|
||||
@@ -49,11 +56,120 @@ CREATE TABLE IF NOT EXISTS companies (
|
||||
business_owner VARCHAR(100), -- 사업주 이름
|
||||
business_status VARCHAR(50), -- 기업 상태 (활동중, 폐업, 휴업)
|
||||
created_by INT, -- 생성자 (FK는 later)
|
||||
company_code VARCHAR(20) NOT NULL UNIQUE,
|
||||
phone_number VARCHAR(20),
|
||||
representative_name VARCHAR(100),
|
||||
master_user_id INT NULL,
|
||||
status ENUM('ACTIVE', 'INACTIVE', 'SUSPENDED') NOT NULL DEFAULT 'ACTIVE',
|
||||
subscription_status ENUM('FREE', 'TRIAL', 'PAID', 'EXPIRED') NOT NULL DEFAULT 'FREE',
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- sessions: Secure HttpOnly 쿠키의 서버 측 세션 저장소
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
id VARCHAR(255) PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
user_agent_hash CHAR(64) NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
last_activity_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_sessions_user_id (user_id),
|
||||
INDEX idx_sessions_expires_at (expires_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- email_otps: 목적별 일회용 이메일 인증 코드
|
||||
CREATE TABLE IF NOT EXISTS email_otps (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
purpose ENUM('REGISTER', 'LOGIN', 'REVERIFY', 'PASSWORD_CHANGE') NOT NULL,
|
||||
otp_hash VARCHAR(255) NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
consumed_at TIMESTAMP NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_email_otps_user_purpose (user_id, purpose, created_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS trusted_devices (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
user_agent_hash CHAR(64) NOT NULL,
|
||||
verified_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
last_used_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uq_trusted_devices_user_agent (user_id, user_agent_hash)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS join_requests (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
company_id INT NOT NULL,
|
||||
status ENUM('PENDING', 'APPROVED', 'REJECTED') NOT NULL DEFAULT 'PENDING',
|
||||
requested_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
reviewed_at TIMESTAMP NULL,
|
||||
reviewed_by INT NULL,
|
||||
review_comment TEXT,
|
||||
INDEX idx_join_requests_company_status (company_id, status)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS login_logs (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NULL,
|
||||
email VARCHAR(255) NOT NULL,
|
||||
status ENUM('SUCCESS', 'FAILURE') NOT NULL,
|
||||
failure_reason VARCHAR(100),
|
||||
user_agent TEXT,
|
||||
login_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_login_logs_user_id (user_id),
|
||||
INDEX idx_login_logs_login_at (login_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS activity_logs (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
action_type VARCHAR(100) NOT NULL,
|
||||
action_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
resource_id VARCHAR(255),
|
||||
status ENUM('SUCCESS', 'FAILURE') NOT NULL DEFAULT 'SUCCESS',
|
||||
details JSON,
|
||||
INDEX idx_activity_logs_user_at (user_id, action_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS system_admin_logs (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
admin_user_id INT NOT NULL,
|
||||
action_type VARCHAR(100) NOT NULL,
|
||||
target_id VARCHAR(255),
|
||||
action_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
details JSON,
|
||||
INDEX idx_system_admin_logs_admin_at (admin_user_id, action_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS support_requests (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
company_id INT NULL,
|
||||
user_email VARCHAR(255) NOT NULL,
|
||||
subject VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
status ENUM('NEW', 'REVIEWED', 'RESOLVED', 'DELETED') NOT NULL DEFAULT 'NEW',
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
reviewed_at TIMESTAMP NULL,
|
||||
reviewed_by INT NULL,
|
||||
review_notes TEXT,
|
||||
INDEX idx_support_requests_status_at (status, created_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_consents (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
terms_version VARCHAR(20) NOT NULL,
|
||||
terms_agreed BOOLEAN NOT NULL,
|
||||
privacy_agreed BOOLEAN NOT NULL,
|
||||
marketing_agreed BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
agreed_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uq_user_consents_version (user_id, terms_version)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
|
||||
/* --------- 1-2. 프로젝트 그룹 --------- */
|
||||
|
||||
@@ -342,7 +458,39 @@ ALTER TABLE users
|
||||
|
||||
ALTER TABLE companies
|
||||
ADD CONSTRAINT fk_companies_created_by
|
||||
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL;
|
||||
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_companies_master_user_id
|
||||
FOREIGN KEY (master_user_id) REFERENCES users(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE sessions
|
||||
ADD CONSTRAINT fk_sessions_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE email_otps
|
||||
ADD CONSTRAINT fk_email_otps_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE trusted_devices
|
||||
ADD CONSTRAINT fk_trusted_devices_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE join_requests
|
||||
ADD CONSTRAINT fk_join_requests_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
ADD CONSTRAINT fk_join_requests_company_id FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
|
||||
ADD CONSTRAINT fk_join_requests_reviewed_by FOREIGN KEY (reviewed_by) REFERENCES users(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE login_logs
|
||||
ADD CONSTRAINT fk_login_logs_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE activity_logs
|
||||
ADD CONSTRAINT fk_activity_logs_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE system_admin_logs
|
||||
ADD CONSTRAINT fk_system_admin_logs_admin_user_id FOREIGN KEY (admin_user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE support_requests
|
||||
ADD CONSTRAINT fk_support_requests_company_id FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_support_requests_reviewed_by FOREIGN KEY (reviewed_by) REFERENCES users(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE user_consents
|
||||
ADD CONSTRAINT fk_user_consents_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE projects
|
||||
ADD CONSTRAINT fk_projects_user_id
|
||||
|
||||
Reference in New Issue
Block a user