Files
sam-docs/guides/super-admin-protection.md
pro ec74d63120 docs:mng/claudedocs 가이드 문서들 guides 폴더로 이동
이동된 파일:
- 2025-12-02_file-attachment-feature.md
- ai-config-설정.md
- archive-restore-feature-analysis.md
- barobill-members-migration.md
- super-admin-protection.md
- 명함추출로직.md
- 모달창_생성시_유의사항.md
- 상품관리정보.md
- 수당지급.md
- 영업파트너구조.md
- 홈택스 매입매출 조회성공.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 16:29:16 +09:00

6.0 KiB

Super Admin Protection Feature

날짜: 2025-12-01 작업자: Claude Code 요청: 슈퍼관리자 보호 및 복원/영구삭제 권한 분리


1. 요구사항

1.1 슈퍼관리자 보호

  • 일반관리자는 슈퍼관리자를 볼 수 없음 (목록에서 숨김)
  • 일반관리자는 슈퍼관리자를 수정/삭제할 수 없음
  • 슈퍼관리자만 다른 슈퍼관리자를 관리 가능

1.2 복원/영구삭제 권한 분리

  • 복원 (Restore): 일반관리자도 가능
  • 영구삭제 (Force Delete): 슈퍼관리자 전용

2. 구현 내용

2.1 라우트 수정 (routes/api.php)

8개 엔티티의 restore 라우트를 super.admin 미들웨어 밖으로 이동:

엔티티 라인 복원 라우트 영구삭제 라우트
Tenants 42-48 POST /{id}/restore DELETE /{id}/force (super.admin)
Departments 76-82 POST /{id}/restore DELETE /{id}/force (super.admin)
Users 93-99 POST /{id}/restore DELETE /{id}/force (super.admin)
Menus 117-123 POST /{id}/restore DELETE /{id}/force (super.admin)
Boards 151-157 POST /{id}/restore DELETE /{id}/force (super.admin)
PM Projects 234-240 POST /{id}/restore DELETE /{id}/force (super.admin)
PM Tasks 260-266 POST /{id}/restore DELETE /{id}/force (super.admin)
PM Issues 292-298 POST /{id}/restore DELETE /{id}/force (super.admin)

패턴:

// 복원 (일반관리자 가능)
Route::post('/{id}/restore', [Controller::class, 'restore'])->name('restore');

// 슈퍼관리자 전용 액션 (영구삭제)
Route::middleware('super.admin')->group(function () {
    Route::delete('/{id}/force', [Controller::class, 'forceDestroy'])->name('forceDestroy');
});

2.2 서비스 레이어 수정

app/Services/UserService.php

public function canAccessUser(int $targetUserId): bool
{
    // withTrashed()를 사용하여 soft-deleted 사용자도 확인 (복원 시 필요)
    $targetUser = User::withTrashed()->find($targetUserId);
    $currentUser = auth()->user();

    // 대상 사용자가 슈퍼관리자이고 현재 사용자가 슈퍼관리자가 아니면 접근 불가
    if ($targetUser?->is_super_admin && ! $currentUser?->is_super_admin) {
        return false;
    }

    return true;
}

app/Services/UserPermissionService.php

public function canModifyUser(int $targetUserId): bool
{
    // withTrashed()를 사용하여 일관성 유지
    $targetUser = User::withTrashed()->find($targetUserId);
    $currentUser = auth()->user();

    if ($targetUser?->is_super_admin && ! $currentUser?->is_super_admin) {
        return false;
    }

    return true;
}

핵심 수정: User::find()User::withTrashed()->find()

  • Soft-deleted 사용자도 조회 가능하게 변경
  • 복원 작업 시 권한 체크가 정상 작동

2.3 뷰 레이어 수정

6개 테이블 뷰에 권한별 버튼 표시 로직 적용:

파일 복원 버튼 영구삭제 버튼
users/partials/table.blade.php $canModify 체크 is_super_admin 체크
users/partials/modal-info.blade.php 슈퍼관리자이거나 대상이 일반사용자 -
departments/partials/table.blade.php 항상 표시 is_super_admin 체크
menus/partials/table.blade.php 항상 표시 is_super_admin 체크
boards/partials/table.blade.php 항상 표시 is_super_admin 체크
tenants/partials/table.blade.php 항상 표시 is_super_admin 체크
project-management/projects/partials/table.blade.php 항상 표시 is_super_admin 체크

Blade 패턴:

@if($item->deleted_at)
    <!-- 삭제된 항목 - 복원은 일반관리자도 가능, 영구삭제는 슈퍼관리자만 -->
    <button onclick="confirmRestore({{ $item->id }}, '{{ $item->name }}')">
        복원
    </button>
    @if(auth()->user()?->is_super_admin)
    <button onclick="confirmForceDelete({{ $item->id }}, '{{ $item->name }}')">
        영구삭제
    </button>
    @endif
@endif

3. 수정된 파일 목록

라우트

  • routes/api.php - 8개 엔티티 restore 라우트 분리

서비스

  • app/Services/UserService.php - canAccessUser() withTrashed 적용
  • app/Services/UserPermissionService.php - canModifyUser() withTrashed 적용

뷰 (Blade)

  • resources/views/users/partials/table.blade.php
  • resources/views/users/partials/modal-info.blade.php
  • resources/views/departments/partials/table.blade.php
  • resources/views/menus/partials/table.blade.php
  • resources/views/boards/partials/table.blade.php
  • resources/views/tenants/partials/table.blade.php
  • resources/views/project-management/projects/partials/table.blade.php

4. 테스트 시나리오

4.1 일반관리자 테스트

  • 사용자 목록에서 슈퍼관리자가 보이지 않음
  • 삭제된 사용자 복원 가능
  • 삭제된 부서/메뉴/게시판/테넌트/프로젝트 복원 가능
  • 영구삭제 버튼이 보이지 않음
  • 슈퍼관리자 수정/삭제 불가 (API 레벨)

4.2 슈퍼관리자 테스트

  • 모든 사용자 조회 가능 (슈퍼관리자 포함)
  • 삭제된 항목 복원 가능
  • 영구삭제 가능
  • 다른 슈퍼관리자 관리 가능

5. 이슈 해결

5.1 302 Found 에러

문제: 일반관리자가 복원 API 호출 시 302 리다이렉트 발생 원인: restore 라우트가 super.admin 미들웨어 내부에 있었음 해결: restore 라우트를 미들웨어 밖으로 이동

5.2 Soft-deleted 사용자 권한 체크 실패

문제: User::find()가 soft-deleted 사용자를 조회하지 못함 원인: Eloquent 기본 동작으로 soft-deleted 레코드 제외 해결: User::withTrashed()->find() 사용


6. 관련 문서

  • claudedocs/archive-restore-feature-analysis.md - 아카이브/복원 기능 분석
  • CURRENT_WORKS.md - 작업 히스토리