-- TK-MP-Project 인증 시스템을 위한 사용자 및 로그인 테이블 생성 -- TK-FB-Project 인증 시스템을 참고하여 구현 -- 1. 사용자 테이블 생성 CREATE TABLE IF NOT EXISTS users ( user_id SERIAL PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, name VARCHAR(100) NOT NULL, email VARCHAR(100), -- 권한 관리 role VARCHAR(20) DEFAULT 'user' CHECK (role IN ('admin', 'system', 'leader', 'support', 'user')), access_level VARCHAR(20) DEFAULT 'worker' CHECK (access_level IN ('admin', 'system', 'group_leader', 'support_team', 'worker')), -- 계정 상태 관리 is_active BOOLEAN DEFAULT true, failed_login_attempts INT DEFAULT 0, locked_until TIMESTAMP NULL, -- 추가 정보 department VARCHAR(50), position VARCHAR(50), phone VARCHAR(20), -- 타임스탬프 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_login_at TIMESTAMP NULL ); -- 2. 로그인 이력 테이블 생성 CREATE TABLE IF NOT EXISTS login_logs ( log_id SERIAL PRIMARY KEY, user_id INT REFERENCES users(user_id) ON DELETE CASCADE, login_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, ip_address VARCHAR(45), user_agent TEXT, login_status VARCHAR(20) CHECK (login_status IN ('success', 'failed')), failure_reason VARCHAR(100), session_duration INT, -- 세션 지속 시간 (초) -- 인덱스를 위한 컬럼 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 3. 사용자 세션 테이블 (JWT Refresh Token 관리) CREATE TABLE IF NOT EXISTS user_sessions ( session_id SERIAL PRIMARY KEY, user_id INT REFERENCES users(user_id) ON DELETE CASCADE, refresh_token VARCHAR(500) NOT NULL, expires_at TIMESTAMP NOT NULL, ip_address VARCHAR(45), user_agent TEXT, is_active BOOLEAN DEFAULT true, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 4. 권한 테이블 (확장 가능한 권한 시스템) CREATE TABLE IF NOT EXISTS permissions ( permission_id SERIAL PRIMARY KEY, permission_name VARCHAR(50) UNIQUE NOT NULL, description TEXT, module VARCHAR(30), -- 모듈별 권한 관리 (bom, project, purchase 등) created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 5. 역할-권한 매핑 테이블 CREATE TABLE IF NOT EXISTS role_permissions ( role_permission_id SERIAL PRIMARY KEY, role VARCHAR(20) NOT NULL, permission_id INT REFERENCES permissions(permission_id) ON DELETE CASCADE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(role, permission_id) ); -- 6. 인덱스 생성 (성능 최적화) CREATE INDEX IF NOT EXISTS idx_users_username ON users(username); CREATE INDEX IF NOT EXISTS idx_users_email ON users(email); CREATE INDEX IF NOT EXISTS idx_users_role ON users(role); CREATE INDEX IF NOT EXISTS idx_users_is_active ON users(is_active); CREATE INDEX IF NOT EXISTS idx_users_created_at ON users(created_at); CREATE INDEX IF NOT EXISTS idx_login_logs_user_id ON login_logs(user_id); CREATE INDEX IF NOT EXISTS idx_login_logs_login_time ON login_logs(login_time); CREATE INDEX IF NOT EXISTS idx_login_logs_ip_address ON login_logs(ip_address); CREATE INDEX IF NOT EXISTS idx_login_logs_status ON login_logs(login_status); CREATE INDEX IF NOT EXISTS idx_user_sessions_user_id ON user_sessions(user_id); CREATE INDEX IF NOT EXISTS idx_user_sessions_refresh_token ON user_sessions(refresh_token); CREATE INDEX IF NOT EXISTS idx_user_sessions_expires_at ON user_sessions(expires_at); CREATE INDEX IF NOT EXISTS idx_user_sessions_is_active ON user_sessions(is_active); CREATE INDEX IF NOT EXISTS idx_permissions_module ON permissions(module); CREATE INDEX IF NOT EXISTS idx_role_permissions_role ON role_permissions(role); -- 7. 기본 권한 데이터 삽입 INSERT INTO permissions (permission_name, description, module) VALUES -- BOM 관리 권한 ('bom.view', 'BOM 조회 권한', 'bom'), ('bom.create', 'BOM 생성 권한', 'bom'), ('bom.edit', 'BOM 수정 권한', 'bom'), ('bom.delete', 'BOM 삭제 권한', 'bom'), ('bom.approve', 'BOM 승인 권한', 'bom'), -- 프로젝트 관리 권한 ('project.view', '프로젝트 조회 권한', 'project'), ('project.create', '프로젝트 생성 권한', 'project'), ('project.edit', '프로젝트 수정 권한', 'project'), ('project.delete', '프로젝트 삭제 권한', 'project'), ('project.manage', '프로젝트 관리 권한', 'project'), -- 파일 관리 권한 ('file.upload', '파일 업로드 권한', 'file'), ('file.download', '파일 다운로드 권한', 'file'), ('file.delete', '파일 삭제 권한', 'file'), -- 사용자 관리 권한 ('user.view', '사용자 조회 권한', 'user'), ('user.create', '사용자 생성 권한', 'user'), ('user.edit', '사용자 수정 권한', 'user'), ('user.delete', '사용자 삭제 권한', 'user'), -- 시스템 관리 권한 ('system.admin', '시스템 관리 권한', 'system'), ('system.logs', '로그 조회 권한', 'system'), ('system.settings', '시스템 설정 권한', 'system') ON CONFLICT (permission_name) DO NOTHING; -- 8. 역할별 기본 권한 할당 INSERT INTO role_permissions (role, permission_id) SELECT 'admin', permission_id FROM permissions ON CONFLICT (role, permission_id) DO NOTHING; INSERT INTO role_permissions (role, permission_id) SELECT 'system', permission_id FROM permissions ON CONFLICT (role, permission_id) DO NOTHING; INSERT INTO role_permissions (role, permission_id) SELECT 'leader', permission_id FROM permissions WHERE permission_name IN ( 'bom.view', 'bom.create', 'bom.edit', 'bom.approve', 'project.view', 'project.create', 'project.edit', 'project.manage', 'file.upload', 'file.download', 'file.delete', 'user.view' ) ON CONFLICT (role, permission_id) DO NOTHING; INSERT INTO role_permissions (role, permission_id) SELECT 'support', permission_id FROM permissions WHERE permission_name IN ( 'bom.view', 'bom.create', 'bom.edit', 'project.view', 'project.create', 'project.edit', 'file.upload', 'file.download' ) ON CONFLICT (role, permission_id) DO NOTHING; INSERT INTO role_permissions (role, permission_id) SELECT 'user', permission_id FROM permissions WHERE permission_name IN ( 'bom.view', 'project.view', 'file.upload', 'file.download' ) ON CONFLICT (role, permission_id) DO NOTHING; -- 9. 기본 관리자 계정 생성 (비밀번호: admin123) -- bcrypt 해시: $2b$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi INSERT INTO users (username, password, name, email, role, access_level, department, position) VALUES ('admin', '$2b$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', '시스템 관리자', 'admin@tkmp.com', 'admin', 'admin', 'IT', '시스템 관리자'), ('system', '$2b$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', '시스템 계정', 'system@tkmp.com', 'system', 'system', 'IT', '시스템 계정') ON CONFLICT (username) DO NOTHING; -- 10. 트리거 함수 생성 (updated_at 자동 업데이트) CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END; $$ language 'plpgsql'; -- 11. 트리거 적용 CREATE TRIGGER update_users_updated_at BEFORE UPDATE ON users FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); CREATE TRIGGER update_user_sessions_updated_at BEFORE UPDATE ON user_sessions FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- 12. 뷰 생성 (사용자 정보 조회용) CREATE OR REPLACE VIEW user_info_view AS SELECT u.user_id, u.username, u.name, u.email, u.role, u.access_level, u.department, u.position, u.is_active, u.created_at, u.last_login_at, COUNT(ll.log_id) as login_count, MAX(ll.login_time) as last_successful_login FROM users u LEFT JOIN login_logs ll ON u.user_id = ll.user_id AND ll.login_status = 'success' GROUP BY u.user_id, u.username, u.name, u.email, u.role, u.access_level, u.department, u.position, u.is_active, u.created_at, u.last_login_at; -- 완료 메시지 DO $$ BEGIN RAISE NOTICE '✅ TK-MP-Project 인증 시스템 데이터베이스 스키마가 성공적으로 생성되었습니다!'; RAISE NOTICE '📋 생성된 테이블: users, login_logs, user_sessions, permissions, role_permissions'; RAISE NOTICE '👤 기본 계정: admin/admin123, system/admin123'; RAISE NOTICE '🔐 권한 시스템: 5단계 역할 + 모듈별 세분화된 권한'; END $$;