- TriggerManagementService: 테이블별 트리거 상태 조회/재생성/삭제 - PartitionManagementService: 파티션 현황 조회/추가/삭제 (보관기간 검증) - triggers.blade.php: 트리거 상태 대시보드 + 개별/전체 재생성·삭제 - partitions.blade.php: 파티션 통계 + 추가/삭제 (초과분만) - sub-nav: 감사 로그 목록/트리거 관리/파티션 관리 탭 내비게이션 - 라우트 6개 추가, 컨트롤러 6개 메서드 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
136 lines
6.5 KiB
PHP
136 lines
6.5 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('title', '파티션 관리')
|
|
|
|
@section('content')
|
|
<!-- 페이지 헤더 -->
|
|
<div class="flex justify-between items-center mb-6">
|
|
<h1 class="text-2xl font-bold text-gray-800">파티션 관리</h1>
|
|
</div>
|
|
|
|
@include('trigger-audit.partials.sub-nav')
|
|
|
|
<!-- 플래시 메시지 -->
|
|
@if(session('success'))
|
|
<div class="mb-4 p-4 bg-green-50 border border-green-200 text-green-700 rounded-lg">{{ session('success') }}</div>
|
|
@endif
|
|
@if(session('error'))
|
|
<div class="mb-4 p-4 bg-red-50 border border-red-200 text-red-700 rounded-lg">{{ session('error') }}</div>
|
|
@endif
|
|
|
|
<!-- 통계 카드 -->
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
|
|
<div class="bg-white rounded-lg shadow-sm p-4">
|
|
<div class="text-sm text-gray-500">파티션 수</div>
|
|
<div class="text-2xl font-bold text-gray-800">{{ $data['total_partitions'] }}</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-sm p-4">
|
|
<div class="text-sm text-gray-500">전체 행 수</div>
|
|
<div class="text-2xl font-bold text-blue-600">{{ number_format($data['total_rows']) }}</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-sm p-4">
|
|
<div class="text-sm text-gray-500">저장소 크기</div>
|
|
<div class="text-2xl font-bold text-purple-600">{{ $data['storage_mb'] }} MB</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-sm p-4">
|
|
<div class="text-sm text-gray-500">보관 정책</div>
|
|
<div class="text-2xl font-bold text-gray-800">{{ $data['retention_days'] }}일</div>
|
|
<div class="text-xs text-gray-400 mt-1">{{ round($data['retention_days'] / 30, 1) }}개월</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 액션 폼 -->
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
|
|
<!-- 파티션 추가 -->
|
|
<div class="bg-white rounded-lg shadow-sm p-4">
|
|
<h3 class="text-sm font-semibold text-gray-700 mb-3">미래 파티션 추가</h3>
|
|
<form method="POST" action="{{ route('trigger-audit.partitions.add') }}"
|
|
onsubmit="return confirm('파티션을 추가합니다. 계속하시겠습니까?')"
|
|
class="flex items-end gap-3">
|
|
@csrf
|
|
<div class="flex-1">
|
|
<label class="block text-xs text-gray-500 mb-1">추가 개월 수</label>
|
|
<input type="number" name="months" value="3" min="1" max="12"
|
|
class="w-full border rounded-lg px-3 py-2 text-sm">
|
|
</div>
|
|
<button type="submit" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg text-sm whitespace-nowrap">
|
|
추가
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- 보관 정책 안내 -->
|
|
<div class="bg-white rounded-lg shadow-sm p-4">
|
|
<h3 class="text-sm font-semibold text-gray-700 mb-3">보관 정책 설정</h3>
|
|
<div class="text-sm text-gray-600">
|
|
<p>현재 보관기간: <strong>{{ $data['retention_days'] }}일</strong> ({{ round($data['retention_days'] / 30, 1) }}개월)</p>
|
|
<p class="mt-2 text-xs text-gray-400">
|
|
변경하려면 <code class="bg-gray-100 px-1 py-0.5 rounded">.env</code> 파일에서
|
|
<code class="bg-gray-100 px-1 py-0.5 rounded">AUDIT_RETENTION_DAYS</code> 값을 수정하세요.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 파티션 테이블 -->
|
|
<div class="bg-white rounded-lg shadow-sm overflow-hidden">
|
|
<table class="w-full text-sm">
|
|
<thead class="bg-gray-50 text-gray-600">
|
|
<tr>
|
|
<th class="px-4 py-3 text-left">파티션명</th>
|
|
<th class="px-4 py-3 text-left">날짜 범위</th>
|
|
<th class="px-4 py-3 text-right">행 수</th>
|
|
<th class="px-4 py-3 text-center">상태</th>
|
|
<th class="px-4 py-3 text-center">액션</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-gray-100">
|
|
@foreach($data['partitions'] as $p)
|
|
<tr class="hover:bg-gray-50">
|
|
<td class="px-4 py-3 font-mono text-xs">{{ $p['name'] }}</td>
|
|
<td class="px-4 py-3 text-xs text-gray-600">
|
|
@if($p['bound_date'])
|
|
~ {{ $p['bound_date'] }}
|
|
@else
|
|
MAXVALUE (캐치올)
|
|
@endif
|
|
</td>
|
|
<td class="px-4 py-3 text-right text-xs text-gray-600">{{ number_format($p['rows']) }}</td>
|
|
<td class="px-4 py-3 text-center">
|
|
@switch($p['status'])
|
|
@case('current')
|
|
<span class="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-blue-100 text-blue-700">현재</span>
|
|
@break
|
|
@case('archived')
|
|
<span class="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-gray-100 text-gray-600">보관중</span>
|
|
@break
|
|
@case('expired')
|
|
<span class="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-red-100 text-red-700">초과</span>
|
|
@break
|
|
@case('upcoming')
|
|
<span class="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-green-100 text-green-700">예정</span>
|
|
@break
|
|
@case('future')
|
|
<span class="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-yellow-100 text-yellow-700">미래</span>
|
|
@break
|
|
@endswitch
|
|
</td>
|
|
<td class="px-4 py-3 text-center">
|
|
@if($p['can_drop'])
|
|
<form method="POST" action="{{ route('trigger-audit.partitions.drop') }}" class="inline"
|
|
onsubmit="return confirm('⚠️ 파티션 {{ $p['name'] }}을 삭제합니다. {{ number_format($p['rows']) }}행의 데이터가 영구 삭제됩니다. 계속하시겠습니까?')">
|
|
@csrf
|
|
<input type="hidden" name="partition_name" value="{{ $p['name'] }}">
|
|
<button type="submit" class="text-red-600 hover:text-red-800 text-xs px-2 py-1 rounded hover:bg-red-50">삭제</button>
|
|
</form>
|
|
@else
|
|
<span class="text-gray-300 text-xs">-</span>
|
|
@endif
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@endsection
|