186 lines
6.5 KiB
Python
186 lines
6.5 KiB
Python
"""
|
|
Custom Admin Dashboard with Key Metrics
|
|
"""
|
|
from django.contrib.admin.views.decorators import staff_member_required
|
|
from django.shortcuts import render
|
|
from django.db.models import Count, Sum, Q
|
|
from django.utils import timezone
|
|
from datetime import timedelta
|
|
|
|
|
|
@staff_member_required
|
|
def admin_dashboard(request):
|
|
"""Custom admin dashboard with operational metrics"""
|
|
|
|
# Date ranges
|
|
today = timezone.now().date()
|
|
week_ago = today - timedelta(days=7)
|
|
month_ago = today - timedelta(days=30)
|
|
|
|
# Account metrics
|
|
from igny8_core.auth.models import Account, Site
|
|
total_accounts = Account.objects.count()
|
|
active_accounts = Account.objects.filter(status='active').count()
|
|
low_credit_accounts = Account.objects.filter(
|
|
status='active',
|
|
credits__lt=100
|
|
).count()
|
|
critical_credit_accounts = Account.objects.filter(
|
|
status='active',
|
|
credits__lt=10
|
|
).count()
|
|
|
|
# Site metrics
|
|
total_sites = Site.objects.count()
|
|
active_sites = Site.objects.filter(is_active=True, status='active').count()
|
|
|
|
# Content metrics
|
|
from igny8_core.modules.writer.models import Content, Tasks
|
|
content_this_week = Content.objects.filter(created_at__gte=week_ago).count()
|
|
content_this_month = Content.objects.filter(created_at__gte=month_ago).count()
|
|
tasks_pending = Tasks.objects.filter(status='pending').count()
|
|
tasks_in_progress = Tasks.objects.filter(status='in_progress').count()
|
|
|
|
# Billing metrics
|
|
from igny8_core.business.billing.models import Payment, CreditTransaction
|
|
pending_payments = Payment.objects.filter(status='pending_approval').count()
|
|
payments_this_month = Payment.objects.filter(
|
|
created_at__gte=month_ago,
|
|
status='succeeded'
|
|
).aggregate(total=Sum('amount'))['total'] or 0
|
|
|
|
credit_usage_this_month = CreditTransaction.objects.filter(
|
|
created_at__gte=month_ago,
|
|
transaction_type='deduction'
|
|
).aggregate(total=Sum('amount'))['total'] or 0
|
|
|
|
# Automation metrics
|
|
from igny8_core.business.automation.models import AutomationRun
|
|
automation_running = AutomationRun.objects.filter(status='running').count()
|
|
automation_failed = AutomationRun.objects.filter(
|
|
status='failed',
|
|
started_at__gte=week_ago
|
|
).count()
|
|
|
|
# Calculate success rate
|
|
total_runs = AutomationRun.objects.filter(started_at__gte=week_ago).count()
|
|
if total_runs > 0:
|
|
success_runs = AutomationRun.objects.filter(
|
|
started_at__gte=week_ago,
|
|
status='completed'
|
|
).count()
|
|
automation_success_rate = round((success_runs / total_runs) * 100, 1)
|
|
else:
|
|
automation_success_rate = 0
|
|
|
|
# WordPress sync metrics
|
|
from igny8_core.business.integration.models import SyncEvent
|
|
sync_failed_today = SyncEvent.objects.filter(
|
|
success=False,
|
|
created_at__date=today
|
|
).count()
|
|
sync_success_today = SyncEvent.objects.filter(
|
|
success=True,
|
|
created_at__date=today
|
|
).count()
|
|
|
|
# Celery task metrics
|
|
try:
|
|
from django_celery_results.models import TaskResult
|
|
celery_failed = TaskResult.objects.filter(
|
|
status='FAILURE',
|
|
date_created__gte=week_ago
|
|
).count()
|
|
celery_pending = TaskResult.objects.filter(status='PENDING').count()
|
|
except:
|
|
celery_failed = 0
|
|
celery_pending = 0
|
|
|
|
# Generate alerts
|
|
alerts = []
|
|
|
|
if critical_credit_accounts > 0:
|
|
alerts.append({
|
|
'level': 'error',
|
|
'message': f'{critical_credit_accounts} account(s) have CRITICAL low credits (< 10)',
|
|
'action': 'Review Accounts',
|
|
'url': '/admin/igny8_core_auth/account/?credits__lt=10'
|
|
})
|
|
|
|
if low_credit_accounts > 0:
|
|
alerts.append({
|
|
'level': 'warning',
|
|
'message': f'{low_credit_accounts} account(s) have low credits (< 100)',
|
|
'action': 'Review Accounts',
|
|
'url': '/admin/igny8_core_auth/account/?credits__lt=100'
|
|
})
|
|
|
|
if pending_payments > 0:
|
|
alerts.append({
|
|
'level': 'warning',
|
|
'message': f'{pending_payments} payment(s) awaiting approval',
|
|
'action': 'Approve Payments',
|
|
'url': '/admin/billing/payment/?status__exact=pending_approval'
|
|
})
|
|
|
|
if automation_failed > 5:
|
|
alerts.append({
|
|
'level': 'error',
|
|
'message': f'{automation_failed} automation runs failed this week',
|
|
'action': 'View Failed Runs',
|
|
'url': '/admin/automation/automationrun/?status__exact=failed'
|
|
})
|
|
|
|
if sync_failed_today > 0:
|
|
alerts.append({
|
|
'level': 'warning',
|
|
'message': f'{sync_failed_today} WordPress sync failure(s) today',
|
|
'action': 'View Sync Events',
|
|
'url': '/admin/integration/syncevent/?success__exact=0'
|
|
})
|
|
|
|
if celery_failed > 10:
|
|
alerts.append({
|
|
'level': 'error',
|
|
'message': f'{celery_failed} Celery tasks failed this week',
|
|
'action': 'View Failed Tasks',
|
|
'url': '/admin/django_celery_results/taskresult/?status__exact=FAILURE'
|
|
})
|
|
|
|
context = {
|
|
'title': 'IGNY8 Dashboard',
|
|
'site_title': 'IGNY8 Admin',
|
|
'site_header': 'IGNY8 Administration',
|
|
# Account metrics
|
|
'total_accounts': total_accounts,
|
|
'active_accounts': active_accounts,
|
|
'low_credit_accounts': low_credit_accounts,
|
|
'critical_credit_accounts': critical_credit_accounts,
|
|
# Site metrics
|
|
'total_sites': total_sites,
|
|
'active_sites': active_sites,
|
|
# Content metrics
|
|
'content_this_week': content_this_week,
|
|
'content_this_month': content_this_month,
|
|
'tasks_pending': tasks_pending,
|
|
'tasks_in_progress': tasks_in_progress,
|
|
# Billing metrics
|
|
'pending_payments': pending_payments,
|
|
'payments_this_month': float(payments_this_month),
|
|
'credit_usage_this_month': abs(float(credit_usage_this_month)),
|
|
# Automation metrics
|
|
'automation_running': automation_running,
|
|
'automation_failed': automation_failed,
|
|
'automation_success_rate': automation_success_rate,
|
|
# Integration metrics
|
|
'sync_failed_today': sync_failed_today,
|
|
'sync_success_today': sync_success_today,
|
|
# Celery metrics
|
|
'celery_failed': celery_failed,
|
|
'celery_pending': celery_pending,
|
|
# Alerts
|
|
'alerts': alerts,
|
|
}
|
|
|
|
return render(request, 'admin/dashboard.html', context)
|