where('tenant_id', (int) $filters['tenant_id']); } if (! empty($filters['table_name'])) { $q->where('table_name', $filters['table_name']); } if (! empty($filters['row_id'])) { $q->where('row_id', $filters['row_id']); } if (! empty($filters['dml_type'])) { $q->where('dml_type', $filters['dml_type']); } if (! empty($filters['actor_id'])) { $q->where('actor_id', (int) $filters['actor_id']); } if (! empty($filters['db_user'])) { $q->where('db_user', 'like', "%{$filters['db_user']}%"); } if (! empty($filters['from'])) { $q->where('created_at', '>=', $filters['from']); } if (! empty($filters['to'])) { $q->where('created_at', '<=', $filters['to']); } return $q->orderBy($sort, $order)->paginate($size, ['*'], 'page', $page); } /** * 특정 레코드의 변경 이력 조회 */ public function recordHistory(string $tableName, string $rowId): \Illuminate\Support\Collection { return TriggerAuditLog::forRecord($tableName, $rowId) ->orderByDesc('created_at') ->get(); } /** * 테이블별 변경 통계 */ public function stats(?int $tenantId = null): array { $q = TriggerAuditLog::query(); if ($tenantId) { $q->where('tenant_id', $tenantId); } $total = (clone $q)->count(); $byDmlType = (clone $q) ->selectRaw('dml_type, COUNT(*) as count') ->groupBy('dml_type') ->pluck('count', 'dml_type') ->toArray(); $topTables = (clone $q) ->selectRaw('table_name, COUNT(*) as count') ->groupBy('table_name') ->orderByDesc('count') ->limit(10) ->pluck('count', 'table_name') ->toArray(); $today = (clone $q) ->whereDate('created_at', today()) ->count(); return [ 'total' => $total, 'today' => $today, 'by_dml_type' => $byDmlType, 'top_tables' => $topTables, ]; } }