tractatus/public/admin/dashboard.html
TheFlow c96ad31046 feat: implement Rule Manager and Project Manager admin systems
Major Features:
- Multi-project governance with Rule Manager web UI
- Project Manager for organizing governance across projects
- Variable substitution system (${VAR_NAME} in rules)
- Claude.md analyzer for instruction extraction
- Rule quality scoring and optimization

Admin UI Components:
- /admin/rule-manager.html - Full-featured rule management interface
- /admin/project-manager.html - Multi-project administration
- /admin/claude-md-migrator.html - Import rules from Claude.md files
- Dashboard enhancements for governance analytics

Backend Implementation:
- Controllers: projects, rules, variables
- Models: Project, VariableValue, enhanced GovernanceRule
- Routes: /api/projects, /api/rules with full CRUD
- Services: ClaudeMdAnalyzer, RuleOptimizer, VariableSubstitution
- Utilities: mongoose helpers

Documentation:
- User guides for Rule Manager and Projects
- Complete API documentation (PROJECTS_API, RULES_API)
- Phase 3 planning and architecture diagrams
- Test results and error analysis
- Coding best practices summary

Testing & Scripts:
- Integration tests for projects API
- Unit tests for variable substitution
- Database migration scripts
- Seed data generation
- Test token generator

Key Capabilities:
 UNIVERSAL scope rules apply across all projects
 PROJECT_SPECIFIC rules override for individual projects
 Variable substitution per-project (e.g., ${DB_PORT} → 27017)
 Real-time validation and quality scoring
 Advanced filtering and search
 Import from existing Claude.md files

Technical Details:
- MongoDB-backed governance persistence
- RESTful API with Express
- JWT authentication for admin endpoints
- CSP-compliant frontend (no inline handlers)
- Responsive Tailwind UI

This implements Phase 3 architecture as documented in planning docs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 17:16:51 +13:00

189 lines
8.6 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Dashboard | Tractatus Framework</title>
<link rel="stylesheet" href="/css/tailwind.css?v=1759833751">
</head>
<body class="bg-gray-50">
<!-- Navigation -->
<nav class="bg-white border-b border-gray-200">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-16">
<div class="flex items-center">
<div class="flex-shrink-0 flex items-center">
<div class="h-8 w-8 bg-blue-600 rounded-lg flex items-center justify-center">
<svg aria-hidden="true" class="h-5 w-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
</svg>
</div>
<span class="ml-3 text-xl font-bold text-gray-900">Admin Dashboard</span>
</div>
<div class="ml-10 flex items-baseline space-x-4">
<a href="#overview" class="nav-link active px-3 py-2 rounded-md text-sm font-medium">Overview</a>
<a href="#moderation" class="nav-link px-3 py-2 rounded-md text-sm font-medium">Moderation Queue</a>
<a href="#users" class="nav-link px-3 py-2 rounded-md text-sm font-medium">Users</a>
<a href="#documents" class="nav-link px-3 py-2 rounded-md text-sm font-medium">Documents</a>
<a href="/admin/rule-manager.html" class="nav-link px-3 py-2 rounded-md text-sm font-medium bg-indigo-50 text-indigo-700 hover:bg-indigo-100">🔧 Rule Manager</a>
<a href="/admin/blog-curation.html" class="nav-link px-3 py-2 rounded-md text-sm font-medium">Blog Curation</a>
<a href="/admin/audit-analytics.html" class="nav-link px-3 py-2 rounded-md text-sm font-medium bg-purple-50 text-purple-700 hover:bg-purple-100">📊 Audit Analytics</a>
</div>
</div>
<div class="flex items-center">
<span id="admin-name" class="text-sm text-gray-600 mr-4"></span>
<button id="logout-btn" class="text-sm font-medium text-gray-700 hover:text-gray-900">
Logout
</button>
</div>
</div>
</div>
</nav>
<!-- Main Content -->
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<!-- Overview Section -->
<div id="overview-section">
<h2 class="text-2xl font-bold text-gray-900 mb-6">Dashboard Overview</h2>
<!-- Statistics Cards -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="flex-shrink-0 bg-blue-100 rounded-md p-3">
<svg aria-hidden="true" class="h-6 w-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 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Total Documents</p>
<p id="stat-documents" class="text-2xl font-semibold text-gray-900">-</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="flex-shrink-0 bg-yellow-100 rounded-md p-3">
<svg aria-hidden="true" class="h-6 w-6 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Pending Review</p>
<p id="stat-pending" class="text-2xl font-semibold text-gray-900">-</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="flex-shrink-0 bg-green-100 rounded-md p-3">
<svg aria-hidden="true" class="h-6 w-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 class="ml-4">
<p class="text-sm font-medium text-gray-500">Published Posts</p>
<p id="stat-approved" class="text-2xl font-semibold text-gray-900">-</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="flex-shrink-0 bg-purple-100 rounded-md p-3">
<svg aria-hidden="true" class="h-6 w-6 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"/>
</svg>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Total Users</p>
<p id="stat-users" class="text-2xl font-semibold text-gray-900">-</p>
</div>
</div>
</div>
</div>
<!-- Recent Activity -->
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-medium text-gray-900">Recent Activity</h3>
</div>
<div id="recent-activity" class="px-6 py-4">
<div class="text-center py-12 text-gray-500">Loading activity...</div>
</div>
</div>
</div>
<!-- Moderation Queue Section -->
<div id="moderation-section" class="hidden">
<h2 class="text-2xl font-bold text-gray-900 mb-6">Moderation Queue</h2>
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<div class="flex justify-between items-center">
<h3 class="text-lg font-medium text-gray-900">Pending Items</h3>
<select id="queue-filter" class="text-sm border-gray-300 rounded-md">
<option value="all">All Types</option>
<option value="document">Documents</option>
<option value="blog">Blog Posts</option>
<option value="case">Case Studies</option>
</select>
</div>
</div>
<div id="moderation-queue" class="divide-y divide-gray-200">
<div class="px-6 py-8 text-center text-gray-500">Loading queue...</div>
</div>
</div>
</div>
<!-- Users Section -->
<div id="users-section" class="hidden">
<h2 class="text-2xl font-bold text-gray-900 mb-6">User Management</h2>
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<div class="flex justify-between items-center">
<h3 class="text-lg font-medium text-gray-900">Users</h3>
<button id="add-user-btn" class="bg-blue-600 text-white px-4 py-2 rounded-md text-sm font-medium hover:bg-blue-700">
Add User
</button>
</div>
</div>
<div id="users-list" class="divide-y divide-gray-200">
<div class="px-6 py-8 text-center text-gray-500">Loading users...</div>
</div>
</div>
</div>
<!-- Documents Section -->
<div id="documents-section" class="hidden">
<h2 class="text-2xl font-bold text-gray-900 mb-6">Document Management</h2>
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<div class="flex justify-between items-center">
<h3 class="text-lg font-medium text-gray-900">All Documents</h3>
<button id="upload-doc-btn" class="bg-blue-600 text-white px-4 py-2 rounded-md text-sm font-medium hover:bg-blue-700">
Upload Document
</button>
</div>
</div>
<div id="documents-list" class="divide-y divide-gray-200">
<div class="px-6 py-8 text-center text-gray-500">Loading documents...</div>
</div>
</div>
</div>
</div>
<!-- Modals -->
<div id="modal-container"></div>
<script src="/js/admin/dashboard.js?v=1759833751"></script>
</body>
</html>