diff --git a/app/modules/vacation/db.py b/app/modules/vacation/db.py
index cdd7eca..1f812dd 100644
--- a/app/modules/vacation/db.py
+++ b/app/modules/vacation/db.py
@@ -352,15 +352,20 @@ class VacationDBStore:
return self._req_serialize(row)
def hard_delete(self, *, request_id: str, user_email: str, is_admin: bool) -> None:
- """완전 삭제. 승인 전(작성중/제출/반려)만 허용. owner 또는 admin."""
+ """완전 삭제.
+
+ - 관리자(is_admin): 모든 상태 삭제 가능.
+ - 일반 사용자: 본인 + 승인 전(작성중/제출/반려)만. 승인/취소 건은 불가.
+ """
user_email = user_email.lower().strip()
current = self.get_request(request_id=request_id)
if not current:
raise KeyError(request_id)
- if not is_admin and current["owner"] != user_email:
- raise PermissionError("본인 신청만 삭제할 수 있습니다.")
- if current["status"] == "승인":
- raise ValueError("승인된 휴가는 삭제할 수 없습니다. 취소 처리하세요.")
+ if not is_admin:
+ if current["owner"] != user_email:
+ raise PermissionError("본인 신청만 삭제할 수 있습니다.")
+ if current["status"] not in ("작성중", "제출", "반려"):
+ raise ValueError("승인/취소된 휴가는 삭제할 수 없습니다. (관리자 문의)")
with self._pool.connection() as conn:
cur = conn.execute(
"DELETE FROM vacation_requests WHERE id = %s", (request_id,)
diff --git a/app/modules/vacation/templates/vacation/detail.html b/app/modules/vacation/templates/vacation/detail.html
index 72f13c1..1dbc25e 100644
--- a/app/modules/vacation/templates/vacation/detail.html
+++ b/app/modules/vacation/templates/vacation/detail.html
@@ -1,6 +1,6 @@
{% extends "erp_base.html" %}
-{% block head_extra %}{% endblock %}
+{% block head_extra %}{% endblock %}
{% block content %}
@@ -65,18 +65,26 @@
{% endif %}
- {% if (is_owner or is_admin) %}
- {% if req.status == '승인' %}
-
- {% elif req.status in ('작성중', '제출', '반려') %}
-
- {% endif %}
+ {# 승인 건: 취소처리(owner/admin). 미승인: 삭제(owner/admin). 관리자는 모든 상태 삭제 가능. #}
+ {% if req.status == '승인' and (is_owner or is_admin) %}
+
+ {% endif %}
+
+ {% if req.status in ('작성중', '제출', '반려') and (is_owner or is_admin) %}
+
+ {% endif %}
+
+ {% if is_admin and req.status in ('승인', '취소') %}
+
{% endif %}
{% if can_edit %}