Files
sam-manage/resources/views/trigger-audit/rollback-preview.blade.php
권혁성 0316c63d3c feat:DB 트리거 감사 로그 관리 화면 구현
- TriggerAuditLog 모델 (casts, accessors, scopes)
- TriggerAuditController (목록/상세/이력/롤백 미리보기/롤백 실행)
- index: 대시보드 통계 + 필터 + 목록 + 파티션 현황
- show: old/new diff 뷰 (변경 컬럼 하이라이트)
- history: 레코드별 변경 타임라인
- rollback-preview: SQL 미리보기 + 확인 후 실행
- 라우트 5개 등록, 메뉴 시더 (시스템 관리 > DB 변경 추적)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 08:55:18 +09:00

110 lines
4.6 KiB
PHP

@extends('layouts.app')
@section('title', '롤백 미리보기 #' . $log->id)
@section('content')
<div class="flex justify-between items-center mb-6">
<div>
<h1 class="text-2xl font-bold text-gray-800">롤백 미리보기</h1>
<p class="text-sm text-gray-500 mt-1">
감사 로그 #{{ $log->id }} /
<span class="font-medium">{{ $log->table_name }}</span> / Row
<span class="font-medium">{{ $log->row_id }}</span>
</p>
</div>
<div class="flex gap-2">
<a href="{{ route('trigger-audit.show', $log->id) }}"
class="bg-gray-200 hover:bg-gray-300 text-gray-700 px-4 py-2 rounded-lg text-sm">상세로 돌아가기</a>
<a href="{{ route('trigger-audit.index') }}"
class="bg-gray-200 hover:bg-gray-300 text-gray-700 px-4 py-2 rounded-lg text-sm">목록</a>
</div>
</div>
@if(session('error'))
<div class="bg-red-100 text-red-700 px-4 py-3 rounded-lg mb-6">{{ session('error') }}</div>
@endif
<!-- 변경 요약 -->
<div class="bg-white rounded-lg shadow-sm p-4 mb-6">
<h3 class="text-sm font-semibold text-gray-700 mb-3">변경 요약</h3>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
<div>
<span class="text-gray-500">DML 타입</span>
<div class="mt-1">
<span class="px-2 py-1 rounded text-xs font-medium
{{ $log->dml_type === 'INSERT' ? 'bg-green-100 text-green-700' : '' }}
{{ $log->dml_type === 'UPDATE' ? 'bg-yellow-100 text-yellow-700' : '' }}
{{ $log->dml_type === 'DELETE' ? 'bg-red-100 text-red-700' : '' }}">
{{ $log->dml_type }}
</span>
</div>
</div>
<div>
<span class="text-gray-500">롤백 동작</span>
<div class="mt-1 font-medium text-orange-600">
@if($log->dml_type === 'INSERT')
DELETE (삽입된 레코드 삭제)
@elseif($log->dml_type === 'UPDATE')
UPDATE (이전 값으로 복원)
@elseif($log->dml_type === 'DELETE')
INSERT (삭제된 레코드 복원)
@endif
</div>
</div>
<div>
<span class="text-gray-500">대상 테이블</span>
<div class="mt-1 font-medium">{{ $log->table_name }}</div>
</div>
<div>
<span class="text-gray-500">대상 Row ID</span>
<div class="mt-1 font-medium">{{ $log->row_id }}</div>
</div>
</div>
</div>
<!-- 실행할 SQL -->
<div class="bg-white rounded-lg shadow-sm p-4 mb-6">
<h3 class="text-sm font-semibold text-gray-700 mb-3">실행할 SQL</h3>
<div class="bg-gray-900 text-green-400 p-4 rounded-lg overflow-x-auto">
<pre class="text-sm font-mono whitespace-pre-wrap">{{ $sql }}</pre>
</div>
<p class="text-xs text-gray-500 mt-2">
* 감사 트리거를 비활성화한 상태에서 실행됩니다 (<code>@disable_audit_trigger = 1</code>)
</p>
</div>
<!-- 경고 -->
<div class="bg-orange-50 border border-orange-200 rounded-lg p-4 mb-6">
<div class="flex items-start gap-3">
<span class="text-orange-500 text-xl">&#9888;</span>
<div>
<h4 class="text-sm font-semibold text-orange-700">주의사항</h4>
<ul class="text-sm text-orange-600 mt-1 space-y-1">
<li> 작업은 실제 데이터를 변경합니다. 되돌릴 없습니다.</li>
<li>롤백 이후 추가 변경이 있었다면 데이터 충돌이 발생할 있습니다.</li>
<li>운영 환경에서는 반드시 백업 실행하세요.</li>
</ul>
</div>
</div>
</div>
<!-- 롤백 실행 -->
<div class="bg-white rounded-lg shadow-sm p-4">
<form method="POST" action="{{ route('trigger-audit.rollback-execute', $log->id) }}"
onsubmit="return confirm('정말로 롤백을 실행하시겠습니까? 이 작업은 되돌릴 수 없습니다.')">
@csrf
<div class="flex items-center gap-4">
<label class="flex items-center gap-2 text-sm">
<input type="checkbox" name="confirm" value="1" required
class="rounded border-gray-300 text-orange-600 focus:ring-orange-500">
<span class="text-gray-700"> SQL을 실행하여 데이터를 롤백합니다.</span>
</label>
<button type="submit"
class="bg-orange-500 hover:bg-orange-600 text-white px-6 py-2 rounded-lg text-sm font-medium">
롤백 실행
</button>
</div>
</form>
</div>
@endsection