From 7617c9f3718eab1746b9538af11789c8e9c49992 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 20 Jul 2026 19:37:30 +0900 Subject: [PATCH] fix: restrict deletion to cancelled requests --- frontend/src/pages/DashboardPage.tsx | 30 +++------------------ frontend/src/pages/VisitRequestListPage.tsx | 28 +++---------------- server/routes/business.ts | 1 + 3 files changed, 9 insertions(+), 50 deletions(-) diff --git a/frontend/src/pages/DashboardPage.tsx b/frontend/src/pages/DashboardPage.tsx index 36ce297..47a80ea 100644 --- a/frontend/src/pages/DashboardPage.tsx +++ b/frontend/src/pages/DashboardPage.tsx @@ -4,7 +4,6 @@ import { deleteVisitRequest, getStatsSummary, listInside, listTodayAccess, listV import { StatsSummary, VisitRequestView } from '../types'; import { STATUS_CLASS, STATUS_LABEL, formatDateTime } from '../status'; import { VisitRequestDetailDialog } from '../components/VisitRequestDetailDialog'; -import { Dialog } from '../components/Dialog'; import { useAuth } from '../auth/AuthContext'; export const DashboardPage: React.FC = () => { @@ -14,7 +13,6 @@ export const DashboardPage: React.FC = () => { const [exitedIds, setExitedIds] = useState>(new Set()); const [checkOutById, setCheckOutById] = useState>(new Map()); const [detailId, setDetailId] = useState(null); - const [deleting, setDeleting] = useState(null); const [error, setError] = useState(null); const [notice, setNotice] = useState(null); const [loading, setLoading] = useState(true); @@ -48,15 +46,8 @@ export const DashboardPage: React.FC = () => { loadDashboard(); }, []); - const confirmDelete = async (text?: string) => { - const target = deleting; - if (!target) return; - if (text !== '삭제') { - setDeleting(null); - setError('삭제하려면 확인 입력란에 "삭제"를 입력하세요.'); - return; - } - setDeleting(null); + const deleteCancelled = async (target: VisitRequestView) => { + if (target.status !== 'CANCELLED') return; setError(null); setNotice(null); try { @@ -128,12 +119,12 @@ export const DashboardPage: React.FC = () => { )} - {hasRole('ADMIN') && ( + {hasRole('ADMIN') && r.status === 'CANCELLED' && ( )} - {hasRole('ADMIN') && ( - + {hasRole('ADMIN') && r.status === 'CANCELLED' && ( + )} @@ -143,18 +135,6 @@ export const VisitRequestListPage: React.FC = () => { /> )} - {deleting != null && ( - setDeleting(null)} - /> - )} ); }; diff --git a/server/routes/business.ts b/server/routes/business.ts index 1557f50..a699afd 100644 --- a/server/routes/business.ts +++ b/server/routes/business.ts @@ -588,6 +588,7 @@ export function createBusinessRouter(deps: BusinessRouterDeps = { query }): Rout const id = Number(req.params.id); const visit = await visitById(dbQuery, id); if (!visit) throw new ApiError(404, '방문 신청을 찾을 수 없습니다.'); + if (visit.status !== 'CANCELLED') throw new ApiError(400, '취소 상태인 신청만 삭제할 수 있습니다.'); await dbQuery('DELETE FROM pass_deliveries WHERE visit_request_id = $1', [id]); await dbQuery('DELETE FROM approvals WHERE visit_request_id = $1', [id]);