feat: Update audit log queries to improve clarity and accuracy in statistics
This commit is contained in:
@@ -280,7 +280,7 @@ export default function AuditLogViewer() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Statistics */}
|
{/* Statistics */}
|
||||||
{stats && (
|
{stats && stats.total > 0 && (
|
||||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
|
||||||
<div className="bg-white p-4 rounded-lg shadow">
|
<div className="bg-white p-4 rounded-lg shadow">
|
||||||
<h3 className="text-lg font-semibold">Total Events</h3>
|
<h3 className="text-lg font-semibold">Total Events</h3>
|
||||||
@@ -289,22 +289,22 @@ export default function AuditLogViewer() {
|
|||||||
<div className="bg-white p-4 rounded-lg shadow">
|
<div className="bg-white p-4 rounded-lg shadow">
|
||||||
<h3 className="text-lg font-semibold">Top Action</h3>
|
<h3 className="text-lg font-semibold">Top Action</h3>
|
||||||
<p className="text-sm font-medium">
|
<p className="text-sm font-medium">
|
||||||
{stats.actionBreakdown[0]?.action || "N/A"}
|
{stats.actionBreakdown && stats.actionBreakdown[0]?.action || "N/A"}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-lg font-bold text-green-600">
|
<p className="text-lg font-bold text-green-600">
|
||||||
{stats.actionBreakdown[0]?.count || 0}
|
{stats.actionBreakdown && stats.actionBreakdown[0]?.count || 0}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-white p-4 rounded-lg shadow">
|
<div className="bg-white p-4 rounded-lg shadow">
|
||||||
<h3 className="text-lg font-semibold">Active Users</h3>
|
<h3 className="text-lg font-semibold">Active Users</h3>
|
||||||
<p className="text-2xl font-bold text-purple-600">
|
<p className="text-2xl font-bold text-purple-600">
|
||||||
{stats.userBreakdown.length}
|
{stats.userBreakdown ? stats.userBreakdown.length : 0}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-white p-4 rounded-lg shadow">
|
<div className="bg-white p-4 rounded-lg shadow">
|
||||||
<h3 className="text-lg font-semibold">Resource Types</h3>
|
<h3 className="text-lg font-semibold">Resource Types</h3>
|
||||||
<p className="text-2xl font-bold text-orange-600">
|
<p className="text-2xl font-bold text-orange-600">
|
||||||
{stats.resourceBreakdown.length}
|
{stats.resourceBreakdown ? stats.resourceBreakdown.length : 0}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ export async function getAuditLogs({
|
|||||||
SELECT
|
SELECT
|
||||||
al.*,
|
al.*,
|
||||||
u.name as user_name,
|
u.name as user_name,
|
||||||
u.email as user_email
|
u.username as user_email
|
||||||
FROM audit_logs al
|
FROM audit_logs al
|
||||||
LEFT JOIN users u ON al.user_id = u.id
|
LEFT JOIN users u ON al.user_id = u.id
|
||||||
WHERE 1=1
|
WHERE 1=1
|
||||||
@@ -291,7 +291,7 @@ export async function getAuditLogStats({
|
|||||||
// Dynamic import to avoid Edge Runtime issues
|
// Dynamic import to avoid Edge Runtime issues
|
||||||
const { default: db } = await import("./db.js");
|
const { default: db } = await import("./db.js");
|
||||||
|
|
||||||
let baseQuery = "FROM audit_logs WHERE 1=1";
|
let baseQuery = "FROM audit_logs al WHERE 1=1";
|
||||||
const params = [];
|
const params = [];
|
||||||
|
|
||||||
if (startDate) {
|
if (startDate) {
|
||||||
@@ -310,34 +310,48 @@ export async function getAuditLogStats({
|
|||||||
|
|
||||||
// Actions breakdown
|
// Actions breakdown
|
||||||
const actionsStmt = db.prepare(`
|
const actionsStmt = db.prepare(`
|
||||||
SELECT action, COUNT(*) as count
|
SELECT al.action, COUNT(*) as count
|
||||||
${baseQuery}
|
${baseQuery}
|
||||||
GROUP BY action
|
GROUP BY al.action
|
||||||
ORDER BY count DESC
|
ORDER BY count DESC
|
||||||
`);
|
`);
|
||||||
const actionsResult = actionsStmt.all(...params);
|
const actionsResult = actionsStmt.all(...params);
|
||||||
|
|
||||||
// Users breakdown
|
// Users breakdown
|
||||||
const usersStmt = db.prepare(`
|
let usersQuery = `
|
||||||
SELECT
|
SELECT
|
||||||
al.user_id,
|
al.user_id,
|
||||||
u.name as user_name,
|
u.name as user_name,
|
||||||
u.email as user_email,
|
u.username as user_email,
|
||||||
COUNT(*) as count
|
COUNT(*) as count
|
||||||
${baseQuery}
|
FROM audit_logs al
|
||||||
LEFT JOIN users u ON al.user_id = u.id
|
LEFT JOIN users u ON al.user_id = u.id
|
||||||
GROUP BY al.user_id, u.name, u.email
|
WHERE 1=1
|
||||||
|
`;
|
||||||
|
|
||||||
|
if (startDate) {
|
||||||
|
usersQuery += " AND al.timestamp >= ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endDate) {
|
||||||
|
usersQuery += " AND al.timestamp <= ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
usersQuery += `
|
||||||
|
GROUP BY al.user_id, u.name, u.username
|
||||||
ORDER BY count DESC
|
ORDER BY count DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
`);
|
`;
|
||||||
|
|
||||||
|
const usersStmt = db.prepare(usersQuery);
|
||||||
const usersResult = usersStmt.all(...params);
|
const usersResult = usersStmt.all(...params);
|
||||||
|
|
||||||
// Resource types breakdown
|
// Resource types breakdown
|
||||||
const resourcesStmt = db.prepare(`
|
const resourcesStmt = db.prepare(`
|
||||||
SELECT resource_type, COUNT(*) as count
|
SELECT al.resource_type, COUNT(*) as count
|
||||||
${baseQuery}
|
${baseQuery}
|
||||||
WHERE resource_type IS NOT NULL
|
WHERE al.resource_type IS NOT NULL
|
||||||
GROUP BY resource_type
|
GROUP BY al.resource_type
|
||||||
ORDER BY count DESC
|
ORDER BY count DESC
|
||||||
`);
|
`);
|
||||||
const resourcesResult = resourcesStmt.all(...params);
|
const resourcesResult = resourcesStmt.all(...params);
|
||||||
|
|||||||
Reference in New Issue
Block a user