// controllers/userController.js - 사용자 관리 컨트롤러 const bcrypt = require('bcrypt'); const { ApiError, asyncHandler } = require('../utils/errorHandler'); const db = require('../db'); /** * 모든 사용자 조회 */ const getAllUsers = asyncHandler(async (req, res) => { console.log('👥 모든 사용자 조회 요청'); const query = ` SELECT user_id, username, name, email, phone, role, access_level, is_active, created_at, updated_at, last_login FROM users ORDER BY created_at DESC `; const [users] = await db.execute(query); console.log(`✅ 사용자 ${users.length}명 조회 완료`); res.success(users, '사용자 목록 조회 성공'); }); /** * 특정 사용자 조회 */ const getUserById = asyncHandler(async (req, res) => { const { id } = req.params; console.log(`👤 사용자 조회: ID ${id}`); const query = ` SELECT user_id, username, name, email, phone, role, access_level, is_active, created_at, updated_at, last_login FROM users WHERE user_id = ? `; const [users] = await db.execute(query, [id]); if (users.length === 0) { throw new ApiError('사용자를 찾을 수 없습니다.', 404); } console.log(`✅ 사용자 조회 완료: ${users[0].name}`); res.success(users[0], '사용자 조회 성공'); }); /** * 새 사용자 생성 */ const createUser = asyncHandler(async (req, res) => { const { username, name, email, phone, role, password } = req.body; console.log(`👤 새 사용자 생성: ${name} (${username})`); // 필수 필드 검증 if (!username || !name || !role || !password) { throw new ApiError('필수 필드가 누락되었습니다.', 400); } // 사용자명 중복 확인 const checkQuery = 'SELECT user_id FROM users WHERE username = ?'; const [existing] = await db.execute(checkQuery, [username]); if (existing.length > 0) { throw new ApiError('이미 존재하는 사용자명입니다.', 400); } // 비밀번호 해시화 const hashedPassword = await bcrypt.hash(password, 10); // 사용자 생성 const insertQuery = ` INSERT INTO users (username, name, email, phone, role, access_level, password_hash, is_active, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, 1, NOW()) `; const [result] = await db.execute(insertQuery, [ username, name, email || null, phone || null, role, role, // access_level을 role과 동일하게 설정 hashedPassword ]); console.log(`✅ 사용자 생성 완료: ID ${result.insertId}`); res.created({ user_id: result.insertId }, '사용자가 성공적으로 생성되었습니다.'); }); /** * 사용자 정보 수정 */ const updateUser = asyncHandler(async (req, res) => { const { id } = req.params; const { username, name, email, phone, role, password } = req.body; console.log(`👤 사용자 수정: ID ${id}`); // 사용자 존재 확인 const checkQuery = 'SELECT user_id FROM users WHERE user_id = ?'; const [existing] = await db.execute(checkQuery, [id]); if (existing.length === 0) { throw new ApiError('사용자를 찾을 수 없습니다.', 404); } // 업데이트할 필드들 const updates = []; const values = []; if (username) { // 사용자명 중복 확인 (자신 제외) const dupQuery = 'SELECT user_id FROM users WHERE username = ? AND user_id != ?'; const [duplicate] = await db.execute(dupQuery, [username, id]); if (duplicate.length > 0) { throw new ApiError('이미 존재하는 사용자명입니다.', 400); } updates.push('username = ?'); values.push(username); } if (name) { updates.push('name = ?'); values.push(name); } if (email !== undefined) { updates.push('email = ?'); values.push(email || null); } if (phone !== undefined) { updates.push('phone = ?'); values.push(phone || null); } if (role) { updates.push('role = ?, access_level = ?'); values.push(role, role); } if (password) { const hashedPassword = await bcrypt.hash(password, 10); updates.push('password_hash = ?'); values.push(hashedPassword); } if (updates.length === 0) { throw new ApiError('수정할 내용이 없습니다.', 400); } updates.push('updated_at = NOW()'); values.push(id); const updateQuery = `UPDATE users SET ${updates.join(', ')} WHERE user_id = ?`; await db.execute(updateQuery, values); console.log(`✅ 사용자 수정 완료: ID ${id}`); res.success({ user_id: id }, '사용자 정보가 성공적으로 수정되었습니다.'); }); /** * 사용자 상태 변경 (활성화/비활성화) */ const updateUserStatus = asyncHandler(async (req, res) => { const { id } = req.params; const { is_active } = req.body; console.log(`👤 사용자 상태 변경: ID ${id}, 활성화: ${is_active}`); const query = 'UPDATE users SET is_active = ?, updated_at = NOW() WHERE user_id = ?'; const [result] = await db.execute(query, [is_active ? 1 : 0, id]); if (result.affectedRows === 0) { throw new ApiError('사용자를 찾을 수 없습니다.', 404); } console.log(`✅ 사용자 상태 변경 완료: ID ${id}`); res.success({ user_id: id, is_active }, '사용자 상태가 성공적으로 변경되었습니다.'); }); /** * 사용자 삭제 */ const deleteUser = asyncHandler(async (req, res) => { const { id } = req.params; console.log(`👤 사용자 삭제: ID ${id}`); // 자기 자신 삭제 방지 if (req.user && req.user.user_id == id) { throw new ApiError('자기 자신은 삭제할 수 없습니다.', 400); } const query = 'DELETE FROM users WHERE user_id = ?'; const [result] = await db.execute(query, [id]); if (result.affectedRows === 0) { throw new ApiError('사용자를 찾을 수 없습니다.', 404); } console.log(`✅ 사용자 삭제 완료: ID ${id}`); res.success({ user_id: id }, '사용자가 성공적으로 삭제되었습니다.'); }); module.exports = { getAllUsers, getUserById, createUser, updateUser, updateUserStatus, deleteUser };