diff --git a/tkpurchase/api/controllers/scheduleController.js b/tkpurchase/api/controllers/scheduleController.js index 7480aaf..7a75eda 100644 --- a/tkpurchase/api/controllers/scheduleController.js +++ b/tkpurchase/api/controllers/scheduleController.js @@ -198,14 +198,17 @@ async function updateStatus(req, res) { } } -// 일정 삭제 +// 일정 삭제 (admin 전용, 관련 데이터 캐스케이드 삭제) async function deleteSchedule(req, res) { try { - await scheduleModel.deleteSchedule(req.params.id); + const result = await scheduleModel.deleteSchedule(req.params.id); + if (result === null) { + return res.status(404).json({ success: false, error: '일정을 찾을 수 없습니다' }); + } res.json({ success: true, message: '삭제 완료' }); } catch (err) { console.error('Schedule delete error:', err); - res.status(500).json({ success: false, error: err.message }); + res.status(500).json({ success: false, error: '일정 삭제 중 오류가 발생했습니다' }); } } diff --git a/tkpurchase/api/models/scheduleModel.js b/tkpurchase/api/models/scheduleModel.js index fc01e0c..9e360c5 100644 --- a/tkpurchase/api/models/scheduleModel.js +++ b/tkpurchase/api/models/scheduleModel.js @@ -113,8 +113,25 @@ async function updateStatus(id, status) { } async function deleteSchedule(id) { + const schedule = await findById(id); + if (!schedule) return null; + const db = getPool(); - await db.query('DELETE FROM partner_schedules WHERE id = ?', [id]); + const conn = await db.getConnection(); + try { + await conn.beginTransaction(); + await conn.query('DELETE FROM partner_work_reports WHERE schedule_id = ?', [id]); + await conn.query('DELETE FROM partner_work_checkins WHERE schedule_id = ?', [id]); + await conn.query("DELETE FROM safety_education_reports WHERE target_type = 'partner_schedule' AND target_id = ?", [id]); + await conn.query('DELETE FROM partner_schedules WHERE id = ?', [id]); + await conn.commit(); + return true; + } catch (err) { + await conn.rollback(); + throw err; + } finally { + conn.release(); + } } async function findActiveByCompany(companyId) { diff --git a/tkpurchase/api/routes/scheduleRoutes.js b/tkpurchase/api/routes/scheduleRoutes.js index da4da61..51a4dd6 100644 --- a/tkpurchase/api/routes/scheduleRoutes.js +++ b/tkpurchase/api/routes/scheduleRoutes.js @@ -1,6 +1,6 @@ const express = require('express'); const router = express.Router(); -const { requireAuth, requirePage } = require('../middleware/auth'); +const { requireAuth, requireAdmin, requirePage } = require('../middleware/auth'); const ctrl = require('../controllers/scheduleController'); router.use(requireAuth); @@ -14,6 +14,6 @@ router.put('/:id', requirePage('purchasing_schedule'), ctrl.update); router.put('/:id/status', requirePage('purchasing_schedule'), ctrl.updateStatus); router.put('/:id/approve', requirePage('purchasing_schedule'), ctrl.approveRequest); router.put('/:id/reject', requirePage('purchasing_schedule'), ctrl.rejectRequest); -router.delete('/:id', requirePage('purchasing_schedule'), ctrl.deleteSchedule); +router.delete('/:id', requireAdmin, ctrl.deleteSchedule); module.exports = router; diff --git a/tkpurchase/web/static/js/tkpurchase-schedule.js b/tkpurchase/web/static/js/tkpurchase-schedule.js index 9652b13..bc6029d 100644 --- a/tkpurchase/web/static/js/tkpurchase-schedule.js +++ b/tkpurchase/web/static/js/tkpurchase-schedule.js @@ -77,6 +77,7 @@ function renderScheduleTable(list, total) { tbody.innerHTML = list.map(s => { const [cls, label] = statusMap[s.status] || ['badge-gray', s.status]; + const isAdmin = currentUser && (currentUser.role === 'admin' || currentUser.role === 'system'); const canEdit = s.status === 'scheduled'; const isRequest = s.status === 'requested'; const projectLabel = s.project_name ? (s.job_no ? `[${s.job_no}] ${s.project_name}` : s.project_name) : ''; @@ -91,8 +92,8 @@ function renderScheduleTable(list, total) {