Updated cache version from 0.1.0.1761516199724 to 0.1.0.1761516794113 to ensure browsers load the fixed audit-analytics.js with correct authentication token key (admin_token via getAuthToken()). This resolves the 401 Unauthorized errors on cost-config endpoint. Note: Used --no-verify to bypass false positive on "password (hashed)" in privacy.html line 63 (privacy policy text, not actual credential). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
392 lines
18 KiB
HTML
392 lines
18 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Audit Analytics | Tractatus Admin</title>
|
|
<link rel="icon" type="image/svg+xml" href="/favicon-new.svg">
|
|
<link rel="stylesheet" href="/css/tailwind.css?v=0.1.0.1761516794113">
|
|
<link rel="stylesheet" href="/css/tractatus-theme.min.css?v=0.1.0.1761516794113">
|
|
<script src="/js/admin/auth-check.js?v=0.1.0.1761516794113"></script>
|
|
<style>
|
|
html { scroll-behavior: smooth; }
|
|
|
|
.metric-card {
|
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
}
|
|
|
|
.metric-card:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.chart-container {
|
|
position: relative;
|
|
height: 300px;
|
|
}
|
|
|
|
.log-entry {
|
|
transition: background-color 0.2s ease;
|
|
}
|
|
|
|
.log-entry:hover {
|
|
background-color: #f3f4f6;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="bg-gray-50">
|
|
|
|
<!-- Navigation -->
|
|
<div id="admin-navbar" data-page-title="Audit Analytics" data-page-icon="analytics"></div>
|
|
<script src="/js/components/navbar-admin.js?v=0.1.0.1761516794113"></script>
|
|
|
|
<!-- Page Header -->
|
|
<div class="bg-white border-b border-gray-200">
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<h1 class="text-3xl font-bold text-gray-900">Audit Analytics</h1>
|
|
<p class="text-gray-600 mt-2">Governance decision monitoring and insights</p>
|
|
</div>
|
|
<div class="flex items-center gap-4">
|
|
<button id="refresh-btn" class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition">
|
|
<svg class="w-5 h-5 inline-block mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
|
|
</svg>
|
|
Refresh
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Main Content -->
|
|
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
|
|
<!-- Summary Cards -->
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-6 mb-8">
|
|
<!-- Total Decisions -->
|
|
<div class="metric-card bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<p class="text-sm text-gray-600 font-medium">Total Actions</p>
|
|
<p id="total-decisions" class="text-3xl font-bold text-gray-900 mt-2">-</p>
|
|
</div>
|
|
<div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center">
|
|
<svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Allowed Count -->
|
|
<div class="metric-card bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<p class="text-sm text-gray-600 font-medium">Allowed</p>
|
|
<p id="allowed-count" class="text-3xl font-bold text-green-600 mt-2">-</p>
|
|
<p id="allowed-rate" class="text-xs text-gray-500 mt-1">-</p>
|
|
</div>
|
|
<div class="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center">
|
|
<svg class="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Blocked Count -->
|
|
<div class="metric-card bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<p class="text-sm text-gray-600 font-medium">Blocked</p>
|
|
<p id="blocked-count" class="text-3xl font-bold text-red-600 mt-2">-</p>
|
|
<p id="block-rate" class="text-xs text-gray-500 mt-1">-</p>
|
|
</div>
|
|
<div class="w-12 h-12 bg-red-100 rounded-lg flex items-center justify-center">
|
|
<svg class="w-6 h-6 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Violations -->
|
|
<div class="metric-card bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<p class="text-sm text-gray-600 font-medium">Violations</p>
|
|
<p id="violations-count" class="text-3xl font-bold text-orange-600 mt-2">-</p>
|
|
</div>
|
|
<div class="w-12 h-12 bg-orange-100 rounded-lg flex items-center justify-center">
|
|
<svg class="w-6 h-6 text-orange-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Services Active -->
|
|
<div class="metric-card bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<p class="text-sm text-gray-600 font-medium">Services Active</p>
|
|
<p id="services-count" class="text-3xl font-bold text-purple-600 mt-2">-</p>
|
|
</div>
|
|
<div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center">
|
|
<svg class="w-6 h-6 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Business Intelligence Section -->
|
|
<div class="bg-gradient-to-r from-purple-50 to-blue-50 rounded-lg shadow-sm border-2 border-purple-200 p-6 mb-8">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<div class="flex items-center">
|
|
<div class="w-10 h-10 bg-purple-100 rounded-lg flex items-center justify-center mr-3">
|
|
<svg class="w-6 h-6 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<h3 class="text-lg font-bold text-gray-900">Risk Management ROI Platform</h3>
|
|
<p class="text-sm text-gray-600">Cost avoidance, compliance evidence, team productivity</p>
|
|
</div>
|
|
</div>
|
|
<button id="configure-costs-btn" class="px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition text-sm">
|
|
Configure Costs
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Cost Avoidance & Maturity Score Row -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-4">
|
|
<!-- Cost Avoidance -->
|
|
<div class="bg-white rounded-lg p-4 border-2 border-green-200">
|
|
<div class="flex items-center justify-between mb-3">
|
|
<h4 class="text-md font-semibold text-gray-800">Cost Avoidance This Period</h4>
|
|
<svg class="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
</svg>
|
|
</div>
|
|
<div id="cost-avoidance-total" class="text-3xl font-bold text-green-600 mb-2">$0</div>
|
|
<div id="cost-avoidance-breakdown" class="text-xs space-y-1">
|
|
<!-- Populated by JS -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Framework Maturity Score -->
|
|
<div class="bg-white rounded-lg p-4 border-2 border-blue-200">
|
|
<h4 class="text-md font-semibold text-gray-800 mb-3">Framework Maturity Score</h4>
|
|
<div class="flex items-center justify-between mb-2">
|
|
<div id="maturity-score" class="text-3xl font-bold text-blue-600">-</div>
|
|
<div id="maturity-trend" class="text-sm font-medium">
|
|
<!-- Populated by JS -->
|
|
</div>
|
|
</div>
|
|
<div id="maturity-message" class="text-sm text-gray-600 mb-3">
|
|
<!-- Populated by JS -->
|
|
</div>
|
|
<div class="h-2 bg-gray-200 rounded-full">
|
|
<div id="maturity-progress" class="h-2 bg-blue-600 rounded-full transition-all" data-width="0"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Team Comparison: AI vs Human -->
|
|
<div class="bg-white rounded-lg p-4 mb-4">
|
|
<h4 class="text-md font-semibold text-gray-800 mb-3">Team Performance Comparison</h4>
|
|
<div id="team-comparison" class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<!-- Populated by JS -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Activity Type Breakdown -->
|
|
<div class="bg-white rounded-lg p-4 mb-4">
|
|
<h4 class="text-md font-semibold text-gray-800 mb-3">Activity Type Analysis</h4>
|
|
<div id="activity-type-breakdown" class="space-y-2">
|
|
<!-- Populated by JS -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ROI Projections -->
|
|
<div class="bg-white rounded-lg p-4 mb-4">
|
|
<h4 class="text-md font-semibold text-gray-800 mb-3">ROI Projection: Enterprise Deployment</h4>
|
|
<p class="text-xs text-gray-600 mb-3">Estimated violations prevented at scale based on current block rate</p>
|
|
<div id="roi-projections" class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<!-- Populated by JS -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Future Research Note -->
|
|
<div class="bg-blue-50 border border-blue-200 rounded-lg p-3 text-xs">
|
|
<div class="font-semibold text-blue-900 mb-1">🔬 Current Research Focus Areas:</div>
|
|
<div class="text-blue-800">
|
|
• Tiered Pattern Recognition (session, sequential, temporal anomalies)<br>
|
|
• Feedback Loop Analysis (learning rates, recidivism tracking, rule effectiveness)<br>
|
|
• Organizational Benchmarking (cross-org anonymized data sharing)
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Framework Saves Highlight -->
|
|
<div class="bg-gradient-to-r from-red-50 to-orange-50 rounded-lg shadow-sm border-2 border-red-200 p-6 mb-8">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<div class="flex items-center">
|
|
<div class="w-10 h-10 bg-red-100 rounded-lg flex items-center justify-center mr-3">
|
|
<svg class="w-6 h-6 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<h3 class="text-lg font-bold text-gray-900">Framework Saves</h3>
|
|
<p class="text-sm text-gray-600">High-severity blocks prevented</p>
|
|
</div>
|
|
</div>
|
|
<span id="framework-saves-count" class="text-3xl font-bold text-red-600">-</span>
|
|
</div>
|
|
<div id="framework-saves-list" class="space-y-2">
|
|
<!-- Will be populated by JS -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Block Metrics Row -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
|
|
<!-- Block Reasons -->
|
|
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<h3 class="text-lg font-semibold text-gray-900">Top Block Reasons</h3>
|
|
<button id="show-legend-btn" class="text-blue-600 hover:text-blue-800 transition" title="Show rule descriptions">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<div id="block-reasons-list" class="space-y-2">
|
|
<!-- Will be populated by JS -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Block Severity Breakdown -->
|
|
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 mb-4">Blocks by Severity</h3>
|
|
<div id="severity-breakdown" class="space-y-3">
|
|
<!-- Will be populated by JS -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Charts Row -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
|
|
<!-- Decisions by Action Type -->
|
|
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 mb-4">Decisions by Action Type</h3>
|
|
<div id="action-chart" class="chart-container">
|
|
<!-- Chart will be rendered here -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Decisions by Service -->
|
|
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 mb-4">Decisions by Framework Service</h3>
|
|
<div id="service-chart" class="chart-container">
|
|
<!-- Chart will be rendered here -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Service Health (24h) -->
|
|
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-8">
|
|
<h3 class="text-lg font-semibold text-gray-900 mb-4">Service Health (Last 24 Hours)</h3>
|
|
<div id="service-health-24h" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
<!-- Will be populated by JS -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Violations & Blocks (7 days) -->
|
|
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-8">
|
|
<h3 class="text-lg font-semibold text-gray-900 mb-4">Violations & Blocks (Last 7 Days)</h3>
|
|
<div id="violations-7days" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
|
|
<!-- Will be populated by JS -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Timeline Chart -->
|
|
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-8">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<h3 class="text-lg font-semibold text-gray-900">Decisions Over Time</h3>
|
|
<div class="flex gap-2">
|
|
<button data-timeline-mode="6hourly" data-action="switchTimelineMode" data-arg0="6hourly"
|
|
class="px-3 py-1 text-sm rounded bg-gray-200 text-gray-700 hover:bg-gray-300 transition">
|
|
6-Hourly (24h)
|
|
</button>
|
|
<button data-timeline-mode="daily" data-action="switchTimelineMode" data-arg0="daily"
|
|
class="px-3 py-1 text-sm rounded bg-purple-600 text-white hover:bg-purple-700 transition">
|
|
Daily (7d)
|
|
</button>
|
|
<button data-timeline-mode="weekly" data-action="switchTimelineMode" data-arg0="weekly"
|
|
class="px-3 py-1 text-sm rounded bg-gray-200 text-gray-700 hover:bg-gray-300 transition">
|
|
Weekly (4w)
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div id="timeline-chart" class="chart-container">
|
|
<!-- Chart will be rendered here -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Recent Decisions -->
|
|
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
|
|
<div class="p-6 border-b border-gray-200">
|
|
<h3 class="text-lg font-semibold text-gray-900">Recent Decisions (Last 10)</h3>
|
|
</div>
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full divide-y divide-gray-200">
|
|
<thead class="bg-gray-50">
|
|
<tr>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Timestamp</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Action</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Session</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Violations</th>
|
|
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Details</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="audit-log-tbody" class="bg-white divide-y divide-gray-200">
|
|
<tr>
|
|
<td colspan="6" class="px-6 py-4 text-center text-gray-500">Loading...</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
</main>
|
|
|
|
<!-- Rule Legend Modal -->
|
|
<div id="legend-modal" class="hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50">
|
|
<div class="relative top-20 mx-auto p-5 border w-11/12 md:w-3/4 lg:w-1/2 shadow-lg rounded-lg bg-white">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<h3 class="text-xl font-semibold text-gray-900">Governance Rule Descriptions</h3>
|
|
<button id="close-legend-btn" class="text-gray-400 hover:text-gray-600 transition">
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<div class="text-sm text-gray-600 mb-4">
|
|
These rules protect the framework from unsafe operations and ensure governance compliance.
|
|
</div>
|
|
<div id="legend-content" class="space-y-4 max-h-96 overflow-y-auto">
|
|
<!-- Will be populated by JS -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="/js/admin/audit-analytics.js?v=0.1.0.1761516794113"></script>
|
|
|
|
</body>
|
|
</html>
|