diff --git a/backend/igny8_core/admin/site_backup.py b/backend/igny8_core/admin/site_backup.py
new file mode 100644
index 00000000..713d8e7f
--- /dev/null
+++ b/backend/igny8_core/admin/site_backup.py
@@ -0,0 +1,179 @@
+"""
+Custom AdminSite for IGNY8 to organize models into proper groups using Unfold
+"""
+from django.contrib import admin
+from django.contrib.admin.apps import AdminConfig
+from django.apps import apps
+from django.urls import path, reverse_lazy
+from django.shortcuts import redirect
+from unfold.admin import ModelAdmin as UnfoldModelAdmin
+from unfold.sites import UnfoldAdminSite
+
+
+class Igny8AdminSite(UnfoldAdminSite):
+ """
+ Custom AdminSite based on Unfold that organizes models into the planned groups
+ """
+ site_header = 'IGNY8 Administration'
+ site_title = 'IGNY8 Admin'
+ index_title = 'IGNY8 Administration'
+
+ def get_urls(self):
+ """Get admin URLs without custom dashboard"""
+ urls = super().get_urls()
+ return urls
+
+ def get_app_list(self, request):
+ """
+ Customize the app list to organize models into logical groups
+ """
+ # Get the default app list
+ app_dict = self._build_app_dict(request)
+
+ # Define our custom groups with their models (using object_name)
+ # Organized by business function with emoji icons for visual recognition
+ custom_groups = {
+ '💰 Billing & Accounts': {
+ 'models': [
+ ('igny8_core_auth', 'Plan'),
+ ('billing', 'PlanLimitUsage'),
+ ('igny8_core_auth', 'Account'),
+ ('igny8_core_auth', 'Subscription'),
+ ('billing', 'Invoice'),
+ ('billing', 'Payment'),
+ ('billing', 'CreditTransaction'),
+ ('billing', 'CreditUsageLog'),
+ ('billing', 'CreditPackage'),
+ ('billing', 'PaymentMethodConfig'),
+ ('billing', 'AccountPaymentMethod'),
+ ('billing', 'CreditCostConfig'),
+ ],
+ },
+ '👥 Sites & Users': {
+ 'models': [
+ ('igny8_core_auth', 'Site'),
+ ('igny8_core_auth', 'Sector'),
+ ('igny8_core_auth', 'User'),
+ ('igny8_core_auth', 'SiteUserAccess'),
+ ('igny8_core_auth', 'PasswordResetToken'),
+ ],
+ },
+ '📚 Content Management': {
+ 'models': [
+ ('writer', 'Content'),
+ ('writer', 'Tasks'),
+ ('writer', 'Images'),
+ ('writer', 'ContentTaxonomy'),
+ ('writer', 'ContentAttribute'),
+ ('writer', 'ContentTaxonomyRelation'),
+ ('writer', 'ContentClusterMap'),
+ ],
+ },
+ '🎯 Planning & Strategy': {
+ 'models': [
+ ('planner', 'Clusters'),
+ ('planner', 'Keywords'),
+ ('planner', 'ContentIdeas'),
+ ('system', 'Strategy'),
+ ],
+ },
+ '🔗 Integrations & Publishing': {
+ 'models': [
+ ('integration', 'SiteIntegration'),
+ ('integration', 'SyncEvent'),
+ ('publishing', 'PublishingRecord'),
+ ('publishing', 'DeploymentRecord'),
+ ],
+ },
+ '🤖 AI & Automation': {
+ 'models': [
+ ('ai', 'AITaskLog'),
+ ('system', 'AIPrompt'),
+ ('automation', 'AutomationConfig'),
+ ('automation', 'AutomationRun'),
+ ('optimization', 'OptimizationTask'),
+ ],
+ },
+ '🌍 Global Reference Data': {
+ 'models': [
+ ('igny8_core_auth', 'Industry'),
+ ('igny8_core_auth', 'IndustrySector'),
+ ('igny8_core_auth', 'SeedKeyword'),
+ ],
+ },
+ '⚙️ System Configuration': {
+ 'models': [
+ ('system', 'IntegrationSettings'),
+ ('system', 'AuthorProfile'),
+ ('system', 'SystemSettings'),
+ ('system', 'AccountSettings'),
+ ('system', 'UserSettings'),
+ ('system', 'ModuleSettings'),
+ ('system', 'AISettings'),
+ ('system', 'ModuleEnableSettings'),
+ ('system', 'SystemLog'),
+ ('system', 'SystemStatus'),
+ ],
+ },
+ '� Monitoring & Tasks': {
+ 'models': [
+ ('django_celery_results', 'TaskResult'),
+ ('django_celery_results', 'GroupResult'),
+ ],
+ },
+ '�🔧 Django System': {
+ 'models': [
+ ('admin', 'LogEntry'),
+ ('auth', 'Group'),
+ ('auth', 'Permission'),
+ ('contenttypes', 'ContentType'),
+ ('sessions', 'Session'),
+ ],
+ },
+ }
+
+ # Build the custom app list
+ app_list = []
+
+ for group_name, group_config in custom_groups.items():
+ group_models = []
+
+ for app_label, model_name in group_config['models']:
+ # Find the model in app_dict
+ if app_label in app_dict:
+ app_data = app_dict[app_label]
+ # Look for the model in the app's models
+ for model in app_data.get('models', []):
+ if model['object_name'] == model_name:
+ group_models.append(model)
+ break
+
+ # Only add the group if it has models
+ if group_models:
+ app_list.append({
+ 'name': group_name,
+ 'app_label': group_name.lower().replace(' ', '_').replace('&', '').replace('emoji', ''),
+ 'app_url': None,
+ 'has_module_perms': True,
+ 'models': group_models,
+ })
+
+ # Sort the app list by our custom order
+ order = [
+ '💰 Billing & Accounts',
+ '👥 Sites & Users',
+ '📚 Content Management',
+ '🎯 Planning & Strategy',
+ '🔗 Integrations & Publishing',
+ '🤖 AI & Automation',
+ '🌍 Global Reference Data',
+ '⚙️ System Configuration',
+ '🔧 Django System',
+ ]
+
+ app_list.sort(key=lambda x: order.index(x['name']) if x['name'] in order else 999)
+
+ return app_list
+
+
+
diff --git a/backend/igny8_core/auth/admin.py b/backend/igny8_core/auth/admin.py
index 756014fa..ea306f01 100644
--- a/backend/igny8_core/auth/admin.py
+++ b/backend/igny8_core/auth/admin.py
@@ -178,15 +178,12 @@ class AccountAdmin(AccountAdminMixin, ModelAdmin):
# Check credits
if obj.credits < 10:
status = 'critical'
- icon = '🔴'
message = 'Critical: Very low credits'
elif obj.credits < 100:
status = 'warning'
- icon = '⚠️'
message = 'Warning: Low credits'
else:
status = 'good'
- icon = '✅'
message = 'Good'
# Check for recent failed automations
@@ -201,12 +198,10 @@ class AccountAdmin(AccountAdminMixin, ModelAdmin):
if failed_runs > 5:
status = 'critical'
- icon = '🔴'
message = f'Critical: {failed_runs} automation failures'
elif failed_runs > 0:
if status == 'good':
status = 'warning'
- icon = '⚠️'
message = f'Warning: {failed_runs} automation failures'
except:
pass
@@ -214,7 +209,6 @@ class AccountAdmin(AccountAdminMixin, ModelAdmin):
# Check account status
if obj.status != 'active':
status = 'critical'
- icon = '🔴'
message = f'Critical: Account {obj.status}'
colors = {
@@ -224,8 +218,8 @@ class AccountAdmin(AccountAdminMixin, ModelAdmin):
}
return format_html(
- '{} {}',
- icon, colors[status], message
+ '{}',
+ colors[status], message
)
health_indicator.short_description = 'Health'
@@ -238,12 +232,18 @@ class AccountAdmin(AccountAdminMixin, ModelAdmin):
details = []
# Credits status
+ colors = {
+ 'critical': '#ef4444',
+ 'warning': '#ff7a00',
+ 'good': '#0bbf87'
+ }
+
if obj.credits < 10:
- details.append(f'🔴 Critical: Only {obj.credits} credits remaining')
+ details.append(f'Critical: Only {obj.credits} credits remaining')
elif obj.credits < 100:
- details.append(f'⚠️ Warning: Only {obj.credits} credits remaining')
+ details.append(f'Warning: Only {obj.credits} credits remaining')
else:
- details.append(f'✅ Credits: {obj.credits} available')
+ details.append(f'Credits: {obj.credits} available')
# Recent activity
try: