Files
TK-BOM-Project/backend/scripts/18_create_auth_tables.sql
Hyungi Ahn 83b90ef05c
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled
feat: 자재 관리 페이지 대규모 개선
- 파이프 수량 계산 로직 수정 (단관 개수가 아닌 실제 길이 기반 계산)
- UI 전면 개편 (DevonThink 스타일의 간결하고 세련된 디자인)
- 자재별 그룹핑 로직 개선:
  * 플랜지: 동일 사양별 그룹핑, WN 스케줄 표시, ORIFICE 풀네임 표시
  * 피팅: 상세 타입 표시 (니플 길이, 엘보 각도/연결, 티 타입, 리듀서 타입 등)
  * 밸브: 동일 사양별 그룹핑, 타입/연결방식/압력 표시
  * 볼트: 크기/재질/길이별 그룹핑 (8SET → 개별 집계)
  * 가스켓: 동일 사양별 그룹핑, 재질/상세내역/두께 분리 표시
  * UNKNOWN: 원본 설명 전체 표시, 동일 항목 그룹핑
- 전체 카테고리 버튼 제거 (표시 복잡도 감소)
- 카테고리별 동적 컬럼 헤더 및 레이아웃 적용
2025-09-09 09:24:45 +09:00

237 lines
8.5 KiB
PL/PgSQL

-- 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 $$;