fix: [users] 슈퍼관리자 보호 기능 복원 라우트 수정

- routes/api.php: 8개 엔티티의 restore 라우트를 super.admin 미들웨어 밖으로 이동
  - tenants, departments, users, menus, boards
  - pm/projects, pm/tasks, pm/issues
- UserService.canAccessUser(): withTrashed() 적용하여 soft-deleted 사용자 권한 체크 가능
- UserPermissionService.canModifyUser(): withTrashed() 적용 (일관성 유지)

권한 정책:
- 복원 (Restore): 일반관리자 가능
- 영구삭제 (Force Delete): 슈퍼관리자 전용

버그 수정:
- 302 Found 에러 해결 (미들웨어 블로킹)
- soft-deleted 사용자 복원 시 권한 체크 실패 해결

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-01 00:13:12 +09:00
parent bbf34e9f3f
commit b39e8b5f2c
14 changed files with 376 additions and 53 deletions

View File

@@ -39,9 +39,11 @@
Route::put('/{id}', [TenantController::class, 'update'])->name('update');
Route::delete('/{id}', [TenantController::class, 'destroy'])->name('destroy');
// 슈퍼관리자 전용 액션
// 복원 (일반관리자 가능)
Route::post('/{id}/restore', [TenantController::class, 'restore'])->name('restore');
// 슈퍼관리자 전용 액션 (영구삭제)
Route::middleware('super.admin')->group(function () {
Route::post('/{id}/restore', [TenantController::class, 'restore'])->name('restore');
Route::delete('/{id}/force', [TenantController::class, 'forceDestroy'])->name('forceDestroy');
});
@@ -71,9 +73,11 @@
Route::put('/{id}', [DepartmentController::class, 'update'])->name('update');
Route::delete('/{id}', [DepartmentController::class, 'destroy'])->name('destroy');
// 슈퍼관리자 전용 액션
// 복원 (일반관리자 가능)
Route::post('/{id}/restore', [DepartmentController::class, 'restore'])->name('restore');
// 슈퍼관리자 전용 액션 (영구삭제)
Route::middleware('super.admin')->group(function () {
Route::post('/{id}/restore', [DepartmentController::class, 'restore'])->name('restore');
Route::delete('/{id}/force', [DepartmentController::class, 'forceDelete'])->name('forceDelete');
});
});
@@ -86,9 +90,11 @@
Route::put('/{id}', [UserController::class, 'update'])->name('update');
Route::delete('/{id}', [UserController::class, 'destroy'])->name('destroy');
// 슈퍼관리자 전용 액션
// 복원 (일반관리자 가능 - 슈퍼관리자 복원은 컨트롤러에서 차단)
Route::post('/{id}/restore', [UserController::class, 'restore'])->name('restore');
// 슈퍼관리자 전용 액션 (영구삭제)
Route::middleware('super.admin')->group(function () {
Route::post('/{id}/restore', [UserController::class, 'restore'])->name('restore');
Route::delete('/{id}/force', [UserController::class, 'forceDestroy'])->name('forceDestroy');
});
@@ -108,9 +114,11 @@
Route::put('/{id}', [MenuController::class, 'update'])->name('update');
Route::delete('/{id}', [MenuController::class, 'destroy'])->name('destroy');
// 슈퍼관리자 전용 액션
// 복원 (일반관리자 가능)
Route::post('/{id}/restore', [MenuController::class, 'restore'])->name('restore');
// 슈퍼관리자 전용 액션 (영구삭제)
Route::middleware('super.admin')->group(function () {
Route::post('/{id}/restore', [MenuController::class, 'restore'])->name('restore');
Route::delete('/{id}/force', [MenuController::class, 'forceDestroy'])->name('forceDestroy');
});
@@ -140,9 +148,11 @@
Route::put('/{id}', [BoardController::class, 'update'])->name('update');
Route::delete('/{id}', [BoardController::class, 'destroy'])->name('destroy');
// 슈퍼관리자 전용 액션
// 복원 (일반관리자 가능)
Route::post('/{id}/restore', [BoardController::class, 'restore'])->name('restore');
// 슈퍼관리자 전용 액션 (영구삭제)
Route::middleware('super.admin')->group(function () {
Route::post('/{id}/restore', [BoardController::class, 'restore'])->name('restore');
Route::delete('/{id}/force', [BoardController::class, 'forceDestroy'])->name('forceDestroy');
});
@@ -221,9 +231,11 @@
Route::put('/{id}', [PmProjectController::class, 'update'])->name('update');
Route::delete('/{id}', [PmProjectController::class, 'destroy'])->name('destroy');
// 슈퍼관리자 전용 액션
// 복원 (일반관리자 가능)
Route::post('/{id}/restore', [PmProjectController::class, 'restore'])->name('restore');
// 슈퍼관리자 전용 액션 (영구삭제)
Route::middleware('super.admin')->group(function () {
Route::post('/{id}/restore', [PmProjectController::class, 'restore'])->name('restore');
Route::delete('/{id}/force', [PmProjectController::class, 'forceDestroy'])->name('forceDestroy');
});
@@ -245,9 +257,11 @@
Route::put('/{id}', [PmTaskController::class, 'update'])->name('update');
Route::delete('/{id}', [PmTaskController::class, 'destroy'])->name('destroy');
// 슈퍼관리자 전용 액션
// 복원 (일반관리자 가능)
Route::post('/{id}/restore', [PmTaskController::class, 'restore'])->name('restore');
// 슈퍼관리자 전용 액션 (영구삭제)
Route::middleware('super.admin')->group(function () {
Route::post('/{id}/restore', [PmTaskController::class, 'restore'])->name('restore');
Route::delete('/{id}/force', [PmTaskController::class, 'forceDestroy'])->name('forceDestroy');
});
@@ -275,9 +289,11 @@
Route::put('/{id}', [PmIssueController::class, 'update'])->name('update');
Route::delete('/{id}', [PmIssueController::class, 'destroy'])->name('destroy');
// 슈퍼관리자 전용 액션
// 복원 (일반관리자 가능)
Route::post('/{id}/restore', [PmIssueController::class, 'restore'])->name('restore');
// 슈퍼관리자 전용 액션 (영구삭제)
Route::middleware('super.admin')->group(function () {
Route::post('/{id}/restore', [PmIssueController::class, 'restore'])->name('restore');
Route::delete('/{id}/force', [PmIssueController::class, 'forceDestroy'])->name('forceDestroy');
});