refactor: worker_id 잔재 제거 - user_id 기반으로 완전 전환
- workerModel: remove()를 user_id 기반 cascading delete로 전환 - workerController: 계정 생성/해제를 workers.user_id 연결 방식으로 변경 - userController: JOIN 방향 전환 (u.worker_id→w.worker_id 에서 w.user_id→u.user_id) - authController, systemController, authRoutes: 모든 CRUD에서 worker_id 참조 제거 - DB: UNIQUE KEY 5개 교체, FK 7개 삭제, daily_worker_summary user_id 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -161,11 +161,10 @@ router.post('/refresh-token', async (req, res) => {
|
||||
|
||||
// 새 토큰 발급
|
||||
const newToken = jwt.sign(
|
||||
{
|
||||
{
|
||||
user_id: user.user_id,
|
||||
username: user.username,
|
||||
access_level: user.access_level,
|
||||
worker_id: user.worker_id,
|
||||
name: user.name || user.username
|
||||
},
|
||||
process.env.JWT_SECRET || 'your-secret-key',
|
||||
@@ -456,10 +455,10 @@ router.get('/me', verifyToken, async (req, res) => {
|
||||
|
||||
connection = await mysql.createConnection(dbConfig);
|
||||
const [rows] = await connection.execute(
|
||||
'SELECT user_id, username, name, email, access_level, worker_id, last_login_at, created_at FROM users WHERE user_id = ?',
|
||||
'SELECT user_id, username, name, email, access_level, last_login_at, created_at FROM users WHERE user_id = ?',
|
||||
[userId]
|
||||
);
|
||||
|
||||
|
||||
if (rows.length === 0) {
|
||||
return res.status(404).json({ error: '사용자를 찾을 수 없습니다.' });
|
||||
}
|
||||
@@ -471,7 +470,6 @@ router.get('/me', verifyToken, async (req, res) => {
|
||||
name: user.name || user.username,
|
||||
email: user.email,
|
||||
access_level: user.access_level,
|
||||
worker_id: user.worker_id,
|
||||
last_login_at: user.last_login_at,
|
||||
created_at: user.created_at
|
||||
});
|
||||
@@ -493,43 +491,43 @@ router.post('/register', verifyToken, async (req, res) => {
|
||||
let connection;
|
||||
|
||||
try {
|
||||
const { username, password, name, email, access_level, worker_id } = req.body;
|
||||
const { username, password, name, email, access_level } = req.body;
|
||||
|
||||
// 권한 확인 (admin 이상만 사용자 등록 가능)
|
||||
if (!['admin', 'system'].includes(req.user.access_level)) {
|
||||
return res.status(403).json({
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
error: '사용자 등록 권한이 없습니다.'
|
||||
error: '사용자 등록 권한이 없습니다.'
|
||||
});
|
||||
}
|
||||
|
||||
if (!username || !password || !name || !access_level) {
|
||||
return res.status(400).json({
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: '필수 항목을 모두 입력해주세요.'
|
||||
error: '필수 항목을 모두 입력해주세요.'
|
||||
});
|
||||
}
|
||||
|
||||
// 비밀번호 강도 검증
|
||||
if (password.length < 6) {
|
||||
return res.status(400).json({
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: '비밀번호는 최소 6자 이상이어야 합니다.'
|
||||
error: '비밀번호는 최소 6자 이상이어야 합니다.'
|
||||
});
|
||||
}
|
||||
|
||||
connection = await mysql.createConnection(dbConfig);
|
||||
|
||||
|
||||
// 사용자명 중복 체크
|
||||
const [existing] = await connection.execute(
|
||||
'SELECT user_id FROM users WHERE username = ?',
|
||||
[username]
|
||||
);
|
||||
|
||||
|
||||
if (existing.length > 0) {
|
||||
return res.status(409).json({
|
||||
return res.status(409).json({
|
||||
success: false,
|
||||
error: '이미 존재하는 사용자명입니다.'
|
||||
error: '이미 존재하는 사용자명입니다.'
|
||||
});
|
||||
}
|
||||
|
||||
@@ -539,11 +537,11 @@ router.post('/register', verifyToken, async (req, res) => {
|
||||
'SELECT user_id FROM users WHERE email = ?',
|
||||
[email]
|
||||
);
|
||||
|
||||
|
||||
if (existingEmail.length > 0) {
|
||||
return res.status(409).json({
|
||||
return res.status(409).json({
|
||||
success: false,
|
||||
error: '이미 사용 중인 이메일입니다.'
|
||||
error: '이미 사용 중인 이메일입니다.'
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -553,9 +551,9 @@ router.post('/register', verifyToken, async (req, res) => {
|
||||
|
||||
// 사용자 추가
|
||||
const [result] = await connection.execute(
|
||||
`INSERT INTO Users (username, password, name, email, access_level, worker_id, is_active, created_at, password_changed_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, TRUE, NOW(), NOW())`,
|
||||
[username, hashedPassword, name, email || null, access_level, worker_id || null]
|
||||
`INSERT INTO Users (username, password, name, email, access_level, is_active, created_at, password_changed_at)
|
||||
VALUES (?, ?, ?, ?, ?, TRUE, NOW(), NOW())`,
|
||||
[username, hashedPassword, name, email || null, access_level]
|
||||
);
|
||||
|
||||
// 비밀번호 변경 로그 기록 (초기 설정)
|
||||
@@ -578,8 +576,7 @@ router.post('/register', verifyToken, async (req, res) => {
|
||||
username,
|
||||
name,
|
||||
email: email || null,
|
||||
access_level,
|
||||
worker_id: worker_id || null
|
||||
access_level
|
||||
}
|
||||
});
|
||||
|
||||
@@ -615,7 +612,6 @@ router.get('/users', verifyToken, async (req, res) => {
|
||||
u.role_id,
|
||||
r.name as role_name,
|
||||
u._access_level_old as access_level,
|
||||
u.worker_id,
|
||||
u.is_active,
|
||||
u.last_login_at,
|
||||
u.created_at
|
||||
@@ -649,8 +645,7 @@ router.get('/users', verifyToken, async (req, res) => {
|
||||
email: user.email,
|
||||
role_id: user.role_id,
|
||||
role_name: user.role_name,
|
||||
access_level: user.access_level || user.role_name?.toLowerCase(), // 하위 호환성
|
||||
worker_id: user.worker_id,
|
||||
access_level: user.access_level || user.role_name?.toLowerCase(),
|
||||
is_active: user.is_active,
|
||||
last_login_at: user.last_login_at,
|
||||
created_at: user.created_at
|
||||
@@ -676,22 +671,22 @@ router.put('/users/:id', verifyToken, async (req, res) => {
|
||||
|
||||
try {
|
||||
const userId = parseInt(req.params.id);
|
||||
const { name, email, access_level, worker_id, password, is_active } = req.body;
|
||||
const { name, email, access_level, password, is_active } = req.body;
|
||||
|
||||
// 권한 확인
|
||||
if (!['admin', 'system'].includes(req.user.access_level)) {
|
||||
// 일반 사용자는 자신의 정보만 수정 가능 (이름, 이메일만)
|
||||
if (userId !== req.user.user_id) {
|
||||
return res.status(403).json({
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
error: '다른 사용자의 정보를 수정할 권한이 없습니다.'
|
||||
error: '다른 사용자의 정보를 수정할 권한이 없습니다.'
|
||||
});
|
||||
}
|
||||
|
||||
if (access_level || worker_id || is_active !== undefined) {
|
||||
return res.status(403).json({
|
||||
|
||||
if (access_level || is_active !== undefined) {
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
error: '권한, 작업자 ID, 활성화 상태는 관리자만 수정할 수 있습니다.'
|
||||
error: '권한, 활성화 상태는 관리자만 수정할 수 있습니다.'
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -744,11 +739,6 @@ router.put('/users/:id', verifyToken, async (req, res) => {
|
||||
updateValues.push(access_level);
|
||||
}
|
||||
|
||||
if (worker_id !== undefined && ['admin', 'system'].includes(req.user.access_level)) {
|
||||
updateFields.push('worker_id = ?');
|
||||
updateValues.push(worker_id || null);
|
||||
}
|
||||
|
||||
if (is_active !== undefined && ['admin', 'system'].includes(req.user.access_level)) {
|
||||
updateFields.push('is_active = ?');
|
||||
updateValues.push(is_active);
|
||||
@@ -794,7 +784,7 @@ router.put('/users/:id', verifyToken, async (req, res) => {
|
||||
|
||||
// 업데이트된 사용자 정보 조회
|
||||
const [updated] = await connection.execute(
|
||||
'SELECT user_id, username, name, email, access_level, worker_id, is_active FROM users WHERE user_id = ?',
|
||||
'SELECT user_id, username, name, email, access_level, is_active FROM users WHERE user_id = ?',
|
||||
[userId]
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user