삭제 요청 처리 기능 추가 및 오류 메시지 처리 강화

- 승인 요청 삭제 버튼 추가 및 확인 경고문 삽입
- 삭제 가능 여부 검증 로직 추가 및 네이티브 쿼리 대체 처리
- 오류 메시지 파싱 로직 및 상세 조회 실패 시 UI 처리 개선
This commit is contained in:
Rinjae
2026-08-24 13:16:39 +09:00
parent a6e88f2281
commit 0f36718534
3 changed files with 132 additions and 14 deletions
@@ -468,8 +468,40 @@ public class PortalApprovalManService extends BaseService {
* 임의 삭제 방지를 위해 실제로 삭제된 사용자/법인이 포함된 USER 유형 요청만 허용한다.
*/
public void deleteApprovalRequest(String id) {
Approval approval = approvalService.findById(id)
.orElseThrow(() -> new BizException("승인 정보를 찾을 수 없습니다. ID: " + id));
Approval approval = null;
try {
approval = approvalService.findById(id).orElse(null);
} catch (Exception e) {
// 요청자/승인자 row 가 사라진 건은 엔티티 hydration 자체가 실패한다. 네이티브 조회로 우회한다.
logger.warn("Approval {} 엔티티 로딩 실패. 네이티브 조회로 대체합니다. 원인: {}", id, e.getMessage());
}
if (approval != null) {
assertDeletable(approval);
} else {
// Approval.requester 는 @JoinColumn(nullable=false) + @NotFound(IGNORE) 조합이라
// 요청자(PTL_USER) row 가 삭제되면 findById 가 빈 결과를 반환한다(조회·승인·반려 모두 불가).
assertDeletableByNativeQuery(id);
}
entityManager.createNativeQuery("DELETE FROM PTL_APPROVER WHERE APPROVAL_ID = :id")
.setParameter("id", id)
.executeUpdate();
int affected = entityManager.createNativeQuery("DELETE FROM PTL_APPROVAL WHERE ID = :id")
.setParameter("id", id)
.executeUpdate();
if (affected == 0) {
throw new BizException("승인 정보를 찾을 수 없습니다. ID: " + id);
}
logger.info("Approval {} deleted (deleted requester/target user/org present)", id);
}
/** 엔티티 로딩이 가능한 건: 요청자 삭제이거나, 대상 사용자·법인이 삭제된 법인사용자 요청만 삭제 허용 */
private void assertDeletable(Approval approval) {
boolean requesterDeleted = approval.getRequester() == null;
if (requesterDeleted) {
return;
}
if (!approval.getApprovalType().equals(ApprovalType.USER)) {
throw new BizException("법인사용자 승인 요청만 삭제할 수 있습니다.");
}
@@ -486,19 +518,38 @@ public class PortalApprovalManService extends BaseService {
|| "삭제된법인".equals(org.getOrgName());
}
if (!(userDeleted || orgDeleted)) {
throw new BizException("삭제된 사용자 또는 법인이 포함된 요청만 삭제할 수 있습니다.");
throw new BizException("삭제된 요청자·사용자 또는 법인이 포함된 요청만 삭제할 수 있습니다.");
}
}
entityManager.createNativeQuery("DELETE FROM PTL_APPROVER WHERE APPROVAL_ID = :id")
/** 엔티티 로딩이 불가능한 건: PTL_APPROVAL 원본 row 를 직접 읽어 요청자/대상 사용자 삭제 여부를 확인한다. */
@SuppressWarnings("unchecked")
private void assertDeletableByNativeQuery(String id) {
List<Object[]> rows = entityManager.createNativeQuery(
"SELECT APPROVAL_TYPE, TARGET_ID, REQUESTER_ID FROM PTL_APPROVAL WHERE ID = :id")
.setParameter("id", id)
.executeUpdate();
int affected = entityManager.createNativeQuery("DELETE FROM PTL_APPROVAL WHERE ID = :id")
.setParameter("id", id)
.executeUpdate();
if (affected == 0) {
.getResultList();
if (rows.isEmpty()) {
throw new BizException("승인 정보를 찾을 수 없습니다. ID: " + id);
}
logger.info("Approval {} deleted (deleted target user/org present)", id);
Object[] row = rows.get(0);
String approvalType = row[0] == null ? null : String.valueOf(row[0]);
String targetId = row[1] == null ? null : String.valueOf(row[1]);
String requesterId = row[2] == null ? null : String.valueOf(row[2]);
boolean requesterDeleted = requesterId == null || !existsPortalUser(requesterId);
boolean targetUserDeleted = ApprovalType.USER.name().equals(approvalType)
&& (targetId == null || !existsPortalUser(targetId));
if (!(requesterDeleted || targetUserDeleted)) {
throw new BizException("삭제된 요청자·사용자가 포함된 요청만 삭제할 수 있습니다.");
}
}
private boolean existsPortalUser(String userId) {
Number count = (Number) entityManager.createNativeQuery("SELECT COUNT(*) FROM PTL_USER WHERE ID = :id")
.setParameter("id", userId)
.getSingleResult();
return count != null && count.intValue() > 0;
}
public void sendEvent(String id, ApprovalEvent event, Map<String, Object> options) {