Files
igny8/02_COMPREHENSIVE_REFACTORING_PLAN.md
IGNY8 VPS (Salman) 3283a83b42 feat(migrations): Rename indexes and update global integration settings fields for improved clarity and functionality
feat(admin): Add API monitoring, debug console, and system health templates for enhanced admin interface

docs: Add AI system cleanup summary and audit report detailing architecture, token management, and recommendations

docs: Introduce credits and tokens system guide outlining configuration, data flow, and monitoring strategies
2025-12-20 12:55:05 +00:00

52 KiB

COMPREHENSIVE REFACTORING PLAN: Frontend Admin Removal & Global Settings Architecture

Date: December 20, 2025
Status: Detailed Implementation Plan
Priority: HIGH - Architecture Refactoring


PART 1: FRONTEND PAGES - COMPLETE INVENTORY & MIGRATION PLAN

1.1 ADMIN PAGES TO REMOVE (Frontend → Django Admin)

Page 1: System Dashboard

  • File: frontend/src/pages/admin/AdminSystemDashboard.tsx
  • Current Route: /admin/dashboard
  • APIs Called:
    • /v1/admin/billing/stats/ - System-wide billing statistics
  • Data Displayed:
    • Total users, active users
    • Credits issued vs used (30-day)
    • Top accounts by credits
    • Quick links to: Marketing site, App, Django admin, PgAdmin, FileManager, Portainer, Swagger, ReDoc, Gitea
  • Actions: Read-only dashboard
  • Django Admin Equivalent: YES - Custom dashboard already exists at /admin/dashboard/
  • Migration Strategy: REMOVE FRONTEND - Django admin dashboard already has similar functionality
  • Status: Ready to remove

Page 2: All Accounts Management

  • File: frontend/src/pages/admin/AdminAllAccountsPage.tsx
  • Current Route: /admin/accounts
  • APIs Called:
    • /v1/admin/accounts/ - List all accounts with search/filter
  • Data Displayed:
    • Account name, owner, plan, status, credits
    • Search by name/owner
    • Filter by status, plan
  • Actions: View accounts, search, filter
  • Django Admin Equivalent: YES - /admin/igny8_core_auth/account/
  • Django Admin Features:
    • List display with all fields
    • Search by name, owner email
    • Filter by status, plan, created date
    • Bulk actions (activate, suspend, soft delete, credit adjustment)
    • 180+ bulk actions just implemented
  • Migration Strategy: REMOVE FRONTEND - Django admin is MORE powerful
  • Status: Ready to remove

Page 3: Subscriptions Management

  • File: frontend/src/pages/admin/AdminSubscriptionsPage.tsx
  • Current Route: /admin/subscriptions
  • APIs Called:
    • /v1/admin/subscriptions/ - List all subscriptions
    • /v1/admin/subscriptions/{id}/activate/ - Activate subscription
    • /v1/admin/subscriptions/{id}/cancel/ - Cancel subscription
  • Data Displayed:
    • Account name, plan, status, start/end date
    • Filter by status, plan
  • Actions: Activate, cancel subscriptions
  • Django Admin Equivalent: YES - /admin/igny8_core_auth/subscription/
  • Django Admin Features:
    • List with all fields
    • Filter by status, plan, account
    • Bulk actions: activate, cancel, renew, upgrade plan
    • Change history tracking
  • Migration Strategy: REMOVE FRONTEND - Django admin has same + more features
  • Status: Ready to remove

Page 4: Account Limits Configuration

  • File: frontend/src/pages/admin/AdminAccountLimitsPage.tsx
  • Current Route: /admin/account-limits
  • APIs Called: NONE - Using mock data
  • Data Displayed: Mock list of accounts with limit overrides
  • Actions: None (placeholder UI)
  • Django Admin Equivalent: ⚠️ PARTIAL - Plan limits exist in Plan model, usage tracking in PlanLimitUsage
  • Migration Strategy:
    • REMOVE FRONTEND - Non-functional placeholder
    • ⚠️ ADD TO DJANGO ADMIN if needed: Create inline for account-specific limit overrides
  • Status: Remove (no functionality to preserve)

Page 5: Admin Billing Overview

  • File: frontend/src/pages/Admin/AdminBilling.tsx
  • Current Route: /admin/billing
  • APIs Called:
    • /v1/admin/billing/stats/ - Billing statistics
    • /v1/admin/users/ - All users with credits
    • /v1/admin/credit-costs/ - Credit cost configurations
    • /v1/admin/users/{id}/adjust-credits/ - Adjust user credits
  • Data Displayed:
    • Billing stats (credits issued, used, revenue)
    • User list with credit balances
    • Credit cost configurations
  • Actions:
    • Adjust credits for any user (with reason)
    • View/edit credit costs
  • Django Admin Equivalent: YES - Multiple models
    • /admin/igny8_core_auth/account/ - Account with credit adjustment actions
    • /admin/billing/credittransaction/ - All transactions
    • /admin/billing/creditcostconfig/ - Cost configurations
  • Django Admin Features:
    • Bulk credit adjustment on Account admin
    • Full transaction history
    • Edit credit costs directly
  • Migration Strategy: REMOVE FRONTEND - Django admin has all functionality
  • Status: Ready to remove

Page 6: All Invoices

  • File: frontend/src/pages/admin/AdminAllInvoicesPage.tsx
  • Current Route: /admin/invoices
  • APIs Called:
    • /v1/admin/invoices/ - List all invoices across accounts
  • Data Displayed:
    • Invoice number, account, amount, status, date
    • Search by account, invoice number
    • Filter by status
  • Actions: View invoices, search, filter
  • Django Admin Equivalent: YES - /admin/billing/invoice/
  • Django Admin Features:
    • List with all fields
    • Search by number, account
    • Filter by status, date range
    • Bulk actions: mark as paid/pending/cancelled, send reminders, apply late fees
  • Migration Strategy: REMOVE FRONTEND - Django admin superior
  • Status: Ready to remove

Page 7: All Payments

  • File: frontend/src/pages/admin/AdminAllPaymentsPage.tsx
  • Current Route: /admin/payments
  • APIs Called:
    • /v1/admin/payments/ - List all payments
    • /v1/admin/payments/{id}/ - Payment details
  • Data Displayed:
    • Payment ID, account, amount, method, status, date
    • Search by account, transaction ID
    • Filter by status, method
  • Actions: View payments, search, filter
  • Django Admin Equivalent: YES - /admin/billing/payment/
  • Django Admin Features:
    • List with all fields
    • Search capabilities
    • Filter by status, method, date
    • Bulk actions: verify, mark failed, refund
  • Migration Strategy: REMOVE FRONTEND - Django admin has it
  • Status: Ready to remove

Page 8: Payment Approval (Manual Payments)

  • File: frontend/src/pages/admin/PaymentApprovalPage.tsx
  • Current Route: /admin/payments/approvals
  • APIs Called:
    • /v1/admin/payments/pending/ - Pending manual payments
    • /v1/admin/payments/{id}/approve/ - Approve payment
    • /v1/admin/payments/{id}/reject/ - Reject payment
  • Data Displayed:
    • Pending manual payments awaiting approval
    • Payment details, account info
  • Actions: Approve or reject manual payments
  • Django Admin Equivalent: ⚠️ PARTIAL - Payment model exists, but no specific approval workflow
  • Migration Strategy:
    • REMOVE FRONTEND
    • ⚠️ ADD TO DJANGO ADMIN: Add list filter for pending status + approve/reject actions
  • Status: Remove, add actions to Django admin Payment model

Page 9: Credit Packages

  • File: frontend/src/pages/admin/AdminCreditPackagesPage.tsx
  • Current Route: /admin/credit-packages
  • APIs Called:
    • /v1/admin/credit-packages/ - CRUD operations
  • Data Displayed:
    • Package name, credits, price, active status
  • Actions: Create, edit, delete, activate/deactivate packages
  • Django Admin Equivalent: YES - /admin/billing/creditpackage/
  • Django Admin Features:
    • Full CRUD
    • Import/export
    • Bulk activate/deactivate
  • Migration Strategy: REMOVE FRONTEND - Django admin sufficient
  • Status: Ready to remove

Page 10: Credit Costs Configuration

  • File: frontend/src/pages/Admin/AdminCreditCostsPage.tsx
  • Current Route: /admin/credit-costs
  • APIs Called:
    • /v1/admin/credit-costs/ - CRUD for credit costs
  • Data Displayed:
    • Operation type, cost in credits
    • All operations (keyword research, clustering, content gen, images, etc.)
  • Actions: Create, edit, delete cost configurations
  • Django Admin Equivalent: YES - /admin/billing/creditcostconfig/
  • Django Admin Features:
    • Full CRUD on cost configs
    • Organized by operation type
    • Bulk operations
  • Migration Strategy: REMOVE FRONTEND - Django admin has it
  • Status: Ready to remove

Page 11: All Users

  • File: frontend/src/pages/admin/AdminAllUsersPage.tsx
  • Current Route: /admin/users
  • APIs Called:
    • /v1/admin/users/ - List all users across accounts
  • Data Displayed:
    • Username, email, account, role, status
    • Search by name, email
    • Filter by role, account
  • Actions: View users, search, filter
  • Django Admin Equivalent: YES - /admin/igny8_core_auth/user/
  • Django Admin Features:
    • Comprehensive user management
    • Search by username, email, account
    • Filter by role, status, account
    • Bulk actions: activate, deactivate, assign groups, reset password, verify email
  • Migration Strategy: REMOVE FRONTEND - Django admin superior
  • Status: Ready to remove

Page 12: Roles & Permissions

  • File: frontend/src/pages/admin/AdminRolesPermissionsPage.tsx
  • Current Route: /admin/roles
  • APIs Called: NONE - Mock data
  • Data Displayed: Mock list of roles with permissions
  • Actions: None (placeholder)
  • Django Admin Equivalent: YES - /admin/auth/group/ and /admin/auth/permission/
  • Django Admin Features:
    • Full group (role) management
    • Permission assignment per group
    • User group assignments
  • Migration Strategy: REMOVE FRONTEND - Non-functional placeholder
  • Status: Remove (Django admin already handles this)

Page 13: Activity Logs (Audit Trail)

  • File: frontend/src/pages/admin/AdminActivityLogsPage.tsx
  • Current Route: /admin/activity-logs
  • APIs Called: NONE - Mock data
  • Data Displayed: Mock audit logs
  • Actions: None (placeholder)
  • Django Admin Equivalent: YES - /admin/admin/logentry/
  • Django Admin Features:
    • Complete audit trail of all admin actions
    • Filter by user, action type, date
    • Search by object
  • Migration Strategy: REMOVE FRONTEND - Django admin has complete audit trail
  • Status: Remove (Django admin LogEntry is production-ready)

Page 14: System Settings (Global Config)

  • File: frontend/src/pages/admin/AdminSystemSettingsPage.tsx
  • Current Route: /admin/system-settings
  • APIs Called: NONE - Mock data
  • Data Displayed: Mock system-wide settings
  • Actions: None (placeholder)
  • Django Admin Equivalent: ⚠️ PARTIAL - SystemSettings model exists
  • Migration Strategy:
    • REMOVE FRONTEND - Non-functional
    • USE DJANGO ADMIN - /admin/system/systemsettings/
  • Status: Remove, use Django admin

Page 15: System Health Monitor

  • File: frontend/src/pages/admin/AdminSystemHealthPage.tsx
  • Current Route: /settings/status (also /admin/system-health)
  • APIs Called: NONE - Mock data
  • Data Displayed: Mock infrastructure health (DB, Redis, Celery, API)
  • Actions: None (placeholder)
  • Django Admin Equivalent: NO - Needs to be created
  • Migration Strategy:
    • REMOVE FRONTEND
    • ⚠️ CREATE IN DJANGO ADMIN: New monitoring page at /admin/monitoring/system-health/
    • What to build: Real health checks for database, Redis, Celery workers, API response times
  • Status: Remove, create new Django admin page

Page 16: API Monitor

  • File: frontend/src/pages/admin/AdminAPIMonitorPage.tsx AND frontend/src/pages/Settings/ApiMonitor.tsx
  • Current Route: /settings/api-monitor
  • APIs Called: NONE - Frontend runs endpoint checks directly
  • Data Displayed:
    • 100+ API endpoint health checks
    • Response times, error rates
    • Status per endpoint group
  • Actions: Manual endpoint testing, real-time monitoring
  • Django Admin Equivalent: NO - Needs to be created
  • Migration Strategy:
    • REMOVE FRONTEND
    • ⚠️ CREATE IN DJANGO ADMIN: /admin/monitoring/api-monitor/
    • What to build:
      • Backend service to check API endpoints
      • Store results in database
      • Display status dashboard
      • Alert on failures
  • Status: Remove, create new Django admin page (complex - worth building)

1.2 SETTINGS PAGES ANALYSIS

Page 17: Module Settings (Enable/Disable Modules)

  • File: frontend/src/pages/Settings/Modules.tsx
  • Current Route: /settings/modules
  • APIs Called:
    • /v1/system/settings/modules/ - GET/PUT module enable settings
  • Data Displayed: Toggle switches for each module (Planner, Writer, Automation, etc.)
  • Actions: Enable/disable modules per account
  • Who Needs This: ACCOUNT OWNERS - This is account-specific configuration
  • Django Admin Equivalent: YES - /admin/system/moduleenablesettings/
  • Migration Strategy: ⚠️ KEEP IN FRONTEND - Normal users need this
  • Status: Keep (user-facing feature, not admin-only)

Page 18: AI Settings

  • File: frontend/src/pages/Settings/AI.tsx
  • Current Route: /settings/ai
  • APIs Called:
    • /v1/system/settings/ai/ - GET/PUT AI settings (models, prompts, etc.)
  • Data Displayed:
    • AI model selection (text, image)
    • Prompt customization
    • Temperature, tokens, etc.
  • Actions: Configure AI behavior per account
  • Who Needs This: ⚠️ POWER USERS - Account-specific AI config
  • Current Issue: Using aws-admin fallback for settings
  • Migration Strategy:
    • ⚠️ REFACTOR - Implement global + account override pattern
    • Keep in frontend but connect to proper global settings
  • Status: Keep, refactor backend

Page 19: System Settings (Account-Level)

  • File: frontend/src/pages/Settings/System.tsx
  • Current Route: /settings/system
  • APIs Called: TBD - Check file
  • Migration Strategy: AUDIT NEEDED - Unclear if account-level or global

Page 20: Debug Status

  • File: frontend/src/pages/Settings/DebugStatus.tsx
  • Current Route: /settings/debug-status
  • APIs Called:
    • Various debug endpoints (environment, config, cache status)
  • Data Displayed: System debug information, environment variables (masked), active settings
  • Actions: View debug info, clear caches
  • Who Needs This: ⚠️ DEVELOPERS ONLY
  • Migration Strategy:
    • REMOVE FROM FRONTEND
    • ⚠️ CREATE IN DJANGO ADMIN: /admin/monitoring/debug-console/
  • Status: Remove, move to Django admin

Page 21-37: Other Settings Pages (Keep - User-Facing)

  • /settings/account - Keep (account info, team management)
  • /settings/billing - Keep (view own invoices, add payment methods)
  • /settings/credits - Keep (view credit balance, usage, buy more)
  • /settings/integration - Keep (WordPress site connections)
  • /settings/users - Keep (manage team members)
  • /settings/sites - Keep (manage sites/domains)
  • /settings/publishing - Keep (publishing settings per site)
  • /settings/subscriptions - Keep (view/manage own subscription)
  • /settings/plans - Keep (view available plans, upgrade)
  • /settings/industries - Keep (select industry for account)
  • /settings/profile - Keep (user profile settings)
  • /settings/import-export - Keep (data export for account)
  • /settings/general - Keep (general account preferences)

Status: All KEEP - Normal user features


1.3 UI ELEMENTS PAGES (23 Pages)

Directory: frontend/src/pages/Settings/UiElements/

Pages:

  1. Alerts
  2. Avatars
  3. Badges
  4. Breadcrumb
  5. Buttons
  6. ButtonsGroup
  7. Cards
  8. Carousel
  9. Dropdowns
  10. Images
  11. Links
  12. List
  13. Modals
  14. Notifications
  15. Pagination
  16. Popovers
  17. PricingTable
  18. Progressbar
  19. Ribbons
  20. Spinners
  21. Tabs
  22. Tooltips
  23. Videos

Purpose: Design system showcase / component library documentation

Who Needs This:

  • Not needed in production app
  • Useful for developers
  • Could be useful for marketing (show UI quality)

Migration Strategy:

  • REMOVE FROM MAIN APP
  • ⚠️ OPTIONAL: Move to marketing site at https://igny8.com/design-system with noindex meta tag
  • Alternative: Create separate Storybook instance for component documentation

Status: Remove from production app


PART 2: SETTINGS ARCHITECTURE - DETAILED ANALYSIS

2.1 CURRENT DATABASE MODELS

Integration Settings Model

File: backend/igny8_core/modules/system/models.py

class IntegrationSettings(AccountBaseModel):
    integration_type = models.CharField(max_length=50)  # openai, runware, gsc, image_generation
    config = models.JSONField(default=dict)  # Stores API keys, settings
    is_active = models.BooleanField(default=True)
    
    # Foreign key to Account (inherited from AccountBaseModel)
    # account = models.ForeignKey(Account)

Current Config Structure:

{
  "openai_api_key": "sk-...",
  "openai_model": "gpt-4",
  "openai_temperature": 0.7,
  "openai_max_tokens": 4000,
  "dalle_api_key": "sk-...",
  "dalle_model": "dall-e-3",
  "dalle_size": "1024x1024",
  "dalle_quality": "standard",
  "dalle_style": "vivid",
  "anthropic_api_key": "sk-...",
  "anthropic_model": "claude-3-sonnet-20240229"
}

Issue: Account-based, using aws-admin as fallback (confusing pattern)


AI Prompts Model

File: backend/igny8_core/modules/system/models.py

class AIPrompt(AccountBaseModel):
    prompt_type = models.CharField(max_length=50)  # clustering, ideas, content_generation, etc.
    prompt_value = models.TextField()  # Current prompt
    default_prompt = models.TextField()  # Default (for reset)
    is_active = models.BooleanField(default=True)
    
    # unique_together = [['account', 'prompt_type']]

Current Behavior:

  • Has default_prompt field - Good!
  • ⚠️ Account-specific prompts
  • No global prompt library

Issue: Need global library + account customization


Author Profiles Model

class AuthorProfile(AccountBaseModel):
    name = models.CharField(max_length=255)
    description = models.TextField()
    tone = models.CharField(max_length=100)
    language = models.CharField(max_length=50, default='en')
    structure_template = models.JSONField(default=dict)
    is_active = models.BooleanField(default=True)

Issue: Account-based, no global library


Content Strategies Model

class Strategy(AccountBaseModel):
    name = models.CharField(max_length=255)
    description = models.TextField()
    sector = models.ForeignKey(Sector)  # Optional
    prompt_types = models.JSONField(default=list)
    section_logic = models.JSONField(default=dict)
    is_active = models.BooleanField(default=True)

Issue: Account-based, no global templates


2.2 PROPOSED SETTINGS ARCHITECTURE

Category 1: TRULY GLOBAL (No Account Override Needed)

Setting Current Proposed Reasoning
Credit Cost Config Global Keep Global System-wide pricing, no per-account override
Rate Limiting Rules Global (code) Keep Global System-wide throttling
Publishing Channels Global Keep Global Available platforms (WordPress, Ghost, etc.)
System Feature Flags Global Keep Global Enable/disable features platform-wide

Implementation: Already correct, no changes needed


Category 2: GLOBAL DEFAULT + ACCOUNT OVERRIDE (Complex Pattern)

2.2.1 AI Integration Settings (OpenAI, DALL-E, Anthropic)

Current:

IntegrationSettings(AccountBaseModel):
    account = FK(Account)  # Per-account, fallback to aws-admin
    integration_type = 'openai'
    config = {openai_api_key, openai_model, ...}

Proposed - Two Models:

# NEW: Global defaults (no account FK)
class GlobalIntegrationSettings(models.Model):
    """Platform-wide default API keys and settings"""
    
    # OpenAI
    openai_api_key = EncryptedCharField(max_length=500)
    openai_model = models.CharField(max_length=100, default='gpt-4-turbo-preview')
    openai_temperature = models.FloatField(default=0.7)
    openai_max_tokens = models.IntegerField(default=4000)
    
    # DALL-E
    dalle_api_key = EncryptedCharField(max_length=500)
    dalle_model = models.CharField(max_length=100, default='dall-e-3')
    dalle_size = models.CharField(max_length=20, default='1024x1024')
    dalle_quality = models.CharField(max_length=20, default='standard')
    dalle_style = models.CharField(max_length=20, default='vivid')
    
    # Anthropic
    anthropic_api_key = EncryptedCharField(max_length=500)
    anthropic_model = models.CharField(max_length=100, default='claude-3-sonnet-20240229')
    
    # Metadata
    is_active = models.BooleanField(default=True)
    last_updated = models.DateTimeField(auto_now=True)
    updated_by = models.ForeignKey(User, null=True)
    
    class Meta:
        verbose_name = "Global Integration Settings"
        # Singleton pattern - only one row
    
    def save(self, *args, **kwargs):
        # Enforce singleton
        self.pk = 1
        super().save(*args, **kwargs)
    
    @classmethod
    def get_instance(cls):
        obj, created = cls.objects.get_or_create(pk=1)
        return obj


# MODIFIED: Account overrides (optional)
class AccountIntegrationOverride(models.Model):
    """Optional per-account API key overrides"""
    account = models.OneToOneField(Account, on_delete=models.CASCADE, related_name='integration_override')
    
    use_own_keys = models.BooleanField(default=False, help_text="Use account's own API keys instead of global")
    
    # OpenAI overrides (null = use global)
    openai_api_key = EncryptedCharField(max_length=500, null=True, blank=True)
    openai_model = models.CharField(max_length=100, null=True, blank=True)
    openai_temperature = models.FloatField(null=True, blank=True)
    openai_max_tokens = models.IntegerField(null=True, blank=True)
    
    # DALL-E overrides
    dalle_api_key = EncryptedCharField(max_length=500, null=True, blank=True)
    dalle_model = models.CharField(max_length=100, null=True, blank=True)
    dalle_size = models.CharField(max_length=20, null=True, blank=True)
    dalle_quality = models.CharField(max_length=20, null=True, blank=True)
    dalle_style = models.CharField(max_length=20, null=True, blank=True)
    
    # Anthropic overrides
    anthropic_api_key = EncryptedCharField(max_length=500, null=True, blank=True)
    anthropic_model = models.CharField(max_length=100, null=True, blank=True)
    
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    def get_effective_openai_settings(self):
        """Get effective OpenAI settings (own or global)"""
        if self.use_own_keys and self.openai_api_key:
            return {
                'api_key': self.openai_api_key,
                'model': self.openai_model or GlobalIntegrationSettings.get_instance().openai_model,
                'temperature': self.openai_temperature if self.openai_temperature is not None else GlobalIntegrationSettings.get_instance().openai_temperature,
                'max_tokens': self.openai_max_tokens or GlobalIntegrationSettings.get_instance().openai_max_tokens,
            }
        else:
            # Use global
            global_settings = GlobalIntegrationSettings.get_instance()
            return {
                'api_key': global_settings.openai_api_key,
                'model': global_settings.openai_model,
                'temperature': global_settings.openai_temperature,
                'max_tokens': global_settings.openai_max_tokens,
            }
    
    def get_effective_dalle_settings(self):
        """Get effective DALL-E settings"""
        if self.use_own_keys and self.dalle_api_key:
            global_settings = GlobalIntegrationSettings.get_instance()
            return {
                'api_key': self.dalle_api_key,
                'model': self.dalle_model or global_settings.dalle_model,
                'size': self.dalle_size or global_settings.dalle_size,
                'quality': self.dalle_quality or global_settings.dalle_quality,
                'style': self.dalle_style or global_settings.dalle_style,
            }
        else:
            global_settings = GlobalIntegrationSettings.get_instance()
            return {
                'api_key': global_settings.dalle_api_key,
                'model': global_settings.dalle_model,
                'size': global_settings.dalle_size,
                'quality': global_settings.dalle_quality,
                'style': global_settings.dalle_style,
            }

Updated Lookup Logic:

# backend/igny8_core/ai/settings.py

def get_openai_settings(account):
    """Get effective OpenAI settings for account"""
    try:
        override = AccountIntegrationOverride.objects.get(account=account)
        if override.use_own_keys:
            return override.get_effective_openai_settings()
    except AccountIntegrationOverride.DoesNotExist:
        pass
    
    # Use global settings
    global_settings = GlobalIntegrationSettings.get_instance()
    return {
        'api_key': global_settings.openai_api_key,
        'model': global_settings.openai_model,
        'temperature': global_settings.openai_temperature,
        'max_tokens': global_settings.openai_max_tokens,
    }

def get_dalle_settings(account):
    """Get effective DALL-E settings for account"""
    try:
        override = AccountIntegrationOverride.objects.get(account=account)
        if override.use_own_keys:
            return override.get_effective_dalle_settings()
    except AccountIntegrationOverride.DoesNotExist:
        pass
    
    # Use global
    global_settings = GlobalIntegrationSettings.get_instance()
    return {
        'api_key': global_settings.dalle_api_key,
        'model': global_settings.dalle_model,
        'size': global_settings.dalle_size,
        'quality': global_settings.dalle_quality,
        'style': global_settings.dalle_style,
    }

Frontend Display:

// For regular users in /settings/ai
{
  "Using global AI settings": true,
  "Current model": "gpt-4-turbo-preview (global)",
  "Want to use your own API keys?": "Contact support" // Enterprise feature
}

// For enterprise accounts with override
{
  "Using own API keys": true,
  "OpenAI API Key": "sk-...****",
  "Model": "gpt-4" (dropdown with all available models),
  "Temperature": 0.7 (slider),
  "Reset to global settings": (button)
}

2.2.2 AI Prompts

Current:

class AIPrompt(AccountBaseModel):
    account = FK(Account)  # Per-account
    prompt_type = 'clustering'
    prompt_value = "Current prompt..."
    default_prompt = "Default prompt..."  # ✅ Has this!

Proposed - Add Global Library:

# NEW: Global prompt library (no account)
class GlobalAIPrompt(models.Model):
    """Platform-wide default prompts"""
    prompt_type = models.CharField(max_length=50, unique=True)
    prompt_value = models.TextField(help_text="Default prompt template")
    description = models.TextField(blank=True)
    variables = models.JSONField(default=list, help_text="List of variables like {keyword}, {industry}, etc.")
    is_active = models.BooleanField(default=True)
    version = models.IntegerField(default=1)
    last_updated = models.DateTimeField(auto_now=True)
    
    class Meta:
        verbose_name = "Global AI Prompt"
        ordering = ['prompt_type']


# KEEP: Account-specific customization
class AIPrompt(AccountBaseModel):
    """Account-specific prompt customizations"""
    account = FK(Account)
    prompt_type = models.CharField(max_length=50)
    prompt_value = models.TextField()  # Customized prompt
    is_customized = models.BooleanField(default=False, help_text="True if modified from global")
    
    # Remove default_prompt field (use global instead)
    # default_prompt = REMOVED
    
    def reset_to_global(self):
        """Reset prompt to global default"""
        global_prompt = GlobalAIPrompt.objects.get(prompt_type=self.prompt_type)
        self.prompt_value = global_prompt.prompt_value
        self.is_customized = False
        self.save()
    
    def get_effective_prompt(self):
        """Get the prompt to use (customized or global)"""
        if self.is_customized and self.prompt_value:
            return self.prompt_value
        else:
            # Use global
            try:
                global_prompt = GlobalAIPrompt.objects.get(prompt_type=self.prompt_type, is_active=True)
                return global_prompt.prompt_value
            except GlobalAIPrompt.DoesNotExist:
                return self.prompt_value  # Fallback to stored value

Lookup Logic:

def get_prompt(account, prompt_type):
    """Get effective prompt for account"""
    try:
        account_prompt = AIPrompt.objects.get(account=account, prompt_type=prompt_type)
        if account_prompt.is_customized:
            return account_prompt.prompt_value
    except AIPrompt.DoesNotExist:
        pass
    
    # Use global
    global_prompt = GlobalAIPrompt.objects.get(prompt_type=prompt_type, is_active=True)
    return global_prompt.prompt_value

User Experience:

[Prompt Editor - Clustering]

Default (Global):
  "Analyze the following keywords and group them into semantic clusters..."
  [Using global prompt] [Customize]

OR (if customized):

Your Custom Prompt:
  [Textarea with custom prompt]
  [Save] [Reset to Global Default]

2.2.3 Author Profiles

Proposed:

# NEW: Global author profile library
class GlobalAuthorProfile(models.Model):
    """Platform-wide author persona templates"""
    name = models.CharField(max_length=255, unique=True)
    description = models.TextField()
    tone = models.CharField(max_length=100)
    language = models.CharField(max_length=50, default='en')
    structure_template = models.JSONField(default=dict)
    is_active = models.BooleanField(default=True)
    category = models.CharField(max_length=50, choices=[
        ('saas', 'SaaS/B2B'),
        ('ecommerce', 'E-commerce'),
        ('blog', 'Blog/Publishing'),
        ('technical', 'Technical'),
        ('creative', 'Creative'),
    ])


# KEEP: Account customization
class AuthorProfile(AccountBaseModel):
    account = FK(Account)
    name = models.CharField(max_length=255)
    description = models.TextField()
    tone = models.CharField(max_length=100)
    language = models.CharField(max_length=50, default='en')
    structure_template = models.JSONField(default=dict)
    is_active = models.BooleanField(default=True)
    is_custom = models.BooleanField(default=False, help_text="True if created by user, not cloned from global")
    cloned_from = models.ForeignKey(GlobalAuthorProfile, null=True, blank=True, on_delete=models.SET_NULL)

User Experience:

[Author Profiles]

Global Library (Available to All Accounts):
  - SaaS B2B Professional (tone: professional, formal)
  - E-commerce Product Descriptions (tone: persuasive, benefit-focused)
  - Blog Conversational (tone: casual, friendly)
  [Clone to My Account]

My Custom Profiles:
  - Tech Startup Informal (cloned from SaaS B2B, customized)
    [Edit] [Delete]
  - Product Launch Hype (created from scratch)
    [Edit] [Delete]
  
[Create New Profile]

2.2.4 Content Strategies

Similar to Author Profiles:

# NEW: Global strategy templates
class GlobalStrategy(models.Model):
    name = models.CharField(max_length=255, unique=True)
    description = models.TextField()
    prompt_types = models.JSONField(default=list)
    section_logic = models.JSONField(default=dict)
    is_active = models.BooleanField(default=True)
    category = models.CharField(max_length=50)  # blog, ecommerce, saas, etc.


# KEEP: Account strategies
class Strategy(AccountBaseModel):
    account = FK(Account)
    name = models.CharField(max_length=255)
    description = models.TextField()
    sector = models.ForeignKey(Sector, null=True)
    prompt_types = models.JSONField(default=list)
    section_logic = models.JSONField(default=dict)
    is_active = models.BooleanField(default=True)
    is_custom = models.BooleanField(default=False)
    cloned_from = models.ForeignKey(GlobalStrategy, null=True)

2.3 SETTINGS MIGRATION SUMMARY

Setting Type Current Model Proposed Change Pattern
OpenAI API Key IntegrationSettings(account) with aws-admin fallback GlobalIntegrationSettings + AccountIntegrationOverride Global + Optional Override
DALL-E Settings IntegrationSettings(account) with fallback Same as OpenAI Global + Optional Override
AI Model Selection IntegrationSettings.config['openai_model'] Multiple fields: text models, image models, embedding models Global + Override per model type
Image Generation Settings IntegrationSettings.config Separate fields for size, quality, style, steps, guidance Global + Override
AI Prompts AIPrompt(account) with default_prompt field GlobalAIPrompt + AIPrompt(account) with is_customized flag Global Library + Account Custom
Author Profiles AuthorProfile(account) only GlobalAuthorProfile + AuthorProfile(account) with cloned_from Global Library + Account Clone/Custom
Content Strategies Strategy(account) only GlobalStrategy + Strategy(account) with cloned_from Global Library + Account Clone/Custom
Module Enable/Disable ModuleEnableSettings(account) Keep as is Per-Account Only
WordPress Integrations SiteIntegration(account, site) Keep as is Per-Account Only
Publishing Channels Global (correct) Keep as is Truly Global
Credit Costs Global (correct) Keep as is Truly Global

PART 3: FRONTEND CODE CLEANUP - COMPLETE AUDIT

3.1 FILES TO DELETE

Admin Pages (16 files)

frontend/src/pages/admin/AdminSystemDashboard.tsx
frontend/src/pages/admin/AdminAllAccountsPage.tsx
frontend/src/pages/admin/AdminSubscriptionsPage.tsx
frontend/src/pages/admin/AdminAccountLimitsPage.tsx
frontend/src/pages/Admin/AdminBilling.tsx
frontend/src/pages/admin/AdminAllInvoicesPage.tsx
frontend/src/pages/admin/AdminAllPaymentsPage.tsx
frontend/src/pages/admin/PaymentApprovalPage.tsx
frontend/src/pages/admin/AdminCreditPackagesPage.tsx
frontend/src/pages/Admin/AdminCreditCostsPage.tsx
frontend/src/pages/admin/AdminAllUsersPage.tsx
frontend/src/pages/admin/AdminRolesPermissionsPage.tsx
frontend/src/pages/admin/AdminActivityLogsPage.tsx
frontend/src/pages/admin/AdminSystemSettingsPage.tsx
frontend/src/pages/admin/AdminSystemHealthPage.tsx
frontend/src/pages/admin/AdminAPIMonitorPage.tsx

Settings Pages to Remove (3 files)

frontend/src/pages/Settings/ApiMonitor.tsx
frontend/src/pages/Settings/DebugStatus.tsx
frontend/src/pages/Settings/MasterStatus.tsx (if exists)

UI Elements Pages (23 files)

frontend/src/pages/Settings/UiElements/Alerts.tsx
frontend/src/pages/Settings/UiElements/Avatars.tsx
... (all 23 files)

Components to Delete

frontend/src/components/auth/AdminGuard.tsx
frontend/src/components/sidebar/ApiStatusIndicator.tsx (move logic to Django)
frontend/src/components/debug/ResourceDebugOverlay.tsx
frontend/src/components/debug/ResourceDebugToggle.tsx

Total Files to Delete: ~45 files


3.2 CODE TO MODIFY

File: frontend/src/layout/AppSidebar.tsx

Remove:

// Line 46-52: Remove isAwsAdminAccount check
const isAwsAdminAccount = Boolean(
  user?.account?.slug === 'aws-admin' ||
  user?.account?.slug === 'default-account' ||
  user?.account?.slug === 'default' ||
  user?.role === 'developer'
);

// Lines 258-355: Remove entire adminSection
const adminSection: MenuSection = useMemo(() => ({
  label: "ADMIN",
  items: [...]
}), []);

// Line 360: Remove admin section from allSections
const allSections = useMemo(() => {
  const baseSections = menuSections.map(...);
  if (isAwsAdminAccount) {  // ← REMOVE THIS CHECK
    return [...baseSections, adminSection];
  }
  return baseSections;
}, [menuSections, isAwsAdminAccount, adminSection]);

Result: Sidebar becomes pure user interface


File: frontend/src/components/auth/ProtectedRoute.tsx

Remove:

// Line 127: Remove isPrivileged check
const isPrivileged = user?.role === 'developer' || user?.is_superuser;

// Any code using isPrivileged variable

File: frontend/src/services/api.ts

Remove:

// Lines 640-641, 788-789, 1011-1012, 1169-1170
// Remove comments about admin/developer overrides
// Always add site_id if there's an active site (even for admin/developer)
// The backend will respect it appropriately - admin/developer can still see all sites

// Remove any conditional logic that checks for admin/developer

File: frontend/src/routes.tsx

Remove Routes:

// Remove all /admin/* routes
{ path: '/admin/dashboard', element: <AdminSystemDashboard /> },
{ path: '/admin/accounts', element: <AdminAllAccountsPage /> },
// ... all admin routes

// Remove /ui-elements/* routes
{ path: '/ui-elements/alerts', element: <Alerts /> },
// ... all 23 UI element routes

// Remove some /settings routes
{ path: '/settings/api-monitor', element: <ApiMonitor /> },
{ path: '/settings/debug-status', element: <DebugStatus /> },

3.3 BACKEND CODE TO MODIFY

Remove API Endpoints (No Longer Needed)

File: backend/igny8_core/api/urls.py or similar

Remove:

# Admin endpoints that duplicate Django admin
path('admin/accounts/', views.admin_accounts),  # Django admin has this
path('admin/subscriptions/', views.admin_subscriptions),
path('admin/users/', views.admin_users),
path('admin/billing/stats/', views.admin_billing_stats),
# etc.

Keep:

# User-facing endpoints
path('billing/credits/balance/', ...),  # Users need this
path('system/settings/modules/', ...),  # Users need this
# etc.

Remove Permission Class

File: backend/igny8_core/api/permissions.py

Remove:

class IsSystemAccountOrDeveloper(permissions.BasePermission):
    """No longer needed - no admin-only frontend endpoints"""
    pass

Update Settings Lookup Logic

File: backend/igny8_core/ai/settings.py

Replace:

# BEFORE
def get_openai_settings(account):
    settings = IntegrationSettings.objects.filter(account=account).first()
    if not settings:
        # Fallback to aws-admin (WRONG!)
        aws = Account.objects.filter(slug='aws-admin').first()
        settings = IntegrationSettings.objects.filter(account=aws).first()
    return settings

# AFTER
def get_openai_settings(account):
    # Check for account override
    try:
        override = AccountIntegrationOverride.objects.get(account=account)
        if override.use_own_keys:
            return override.get_effective_openai_settings()
    except AccountIntegrationOverride.DoesNotExist:
        pass
    
    # Use global settings
    return GlobalIntegrationSettings.get_instance().get_openai_settings()

PART 4: DJANGO ADMIN ENHANCEMENTS

4.1 NEW PAGES TO CREATE

Page 1: System Health Monitor

File: backend/igny8_core/admin/monitoring.py

from django.contrib.admin.views.decorators import staff_member_required
from django.shortcuts import render
from django.db import connection
import redis
from celery import Celery

@staff_member_required
def system_health_dashboard(request):
    """
    System infrastructure health monitoring
    """
    context = {}
    
    # Database Check
    try:
        with connection.cursor() as cursor:
            cursor.execute("SELECT 1")
        context['database'] = {
            'status': 'healthy',
            'message': 'Database connection OK'
        }
    except Exception as e:
        context['database'] = {
            'status': 'error',
            'message': str(e)
        }
    
    # Redis Check
    try:
        r = redis.Redis(host='redis', port=6379, db=0)
        r.ping()
        context['redis'] = {
            'status': 'healthy',
            'message': 'Redis connection OK'
        }
    except Exception as e:
        context['redis'] = {
            'status': 'error',
            'message': str(e)
        }
    
    # Celery Workers Check
    try:
        app = Celery('igny8_core')
        inspect = app.control.inspect()
        active = inspect.active()
        context['celery'] = {
            'status': 'healthy' if active else 'warning',
            'workers': len(active) if active else 0,
            'message': f'{len(active)} workers active' if active else 'No workers'
        }
    except Exception as e:
        context['celery'] = {
            'status': 'error',
            'message': str(e)
        }
    
    return render(request, 'admin/monitoring/system_health.html', context)

Template: backend/igny8_core/templates/admin/monitoring/system_health.html


Page 2: API Monitor

File: backend/igny8_core/admin/monitoring.py

@staff_member_required
def api_monitor_dashboard(request):
    """
    API endpoint health monitoring
    """
    # Define endpoint groups to check
    endpoint_groups = [
        {
            'name': 'Authentication',
            'endpoints': [
                {'path': '/v1/auth/login/', 'method': 'POST'},
                {'path': '/v1/auth/me/', 'method': 'GET'},
            ]
        },
        {
            'name': 'Planner Module',
            'endpoints': [
                {'path': '/v1/planner/keywords/', 'method': 'GET'},
                {'path': '/v1/planner/clusters/', 'method': 'GET'},
            ]
        },
        # ... more groups
    ]
    
    # Check each endpoint
    results = []
    for group in endpoint_groups:
        group_results = []
        for endpoint in group['endpoints']:
            # Make internal API call
            status = check_endpoint(endpoint['path'], endpoint['method'])
            group_results.append({
                'path': endpoint['path'],
                'method': endpoint['method'],
                'status': status['status'],
                'response_time': status['response_time'],
            })
        results.append({
            'name': group['name'],
            'endpoints': group_results
        })
    
    context = {'results': results}
    return render(request, 'admin/monitoring/api_monitor.html', context)


def check_endpoint(path, method):
    """Check endpoint health"""
    import requests
    import time
    
    start = time.time()
    try:
        if method == 'GET':
            response = requests.get(f'http://localhost:8010{path}', timeout=5)
        else:
            response = requests.post(f'http://localhost:8010{path}', timeout=5)
        
        elapsed = (time.time() - start) * 1000  # ms
        
        return {
            'status': 'healthy' if response.status_code < 400 else 'error',
            'response_time': round(elapsed, 2),
            'status_code': response.status_code,
        }
    except Exception as e:
        return {
            'status': 'error',
            'response_time': None,
            'error': str(e),
        }

Page 3: Debug Console

File: backend/igny8_core/admin/monitoring.py

@staff_member_required
def debug_console(request):
    """
    System debug information
    """
    from django.conf import settings
    import os
    
    context = {
        'environment': {
            'DEBUG': settings.DEBUG,
            'ENVIRONMENT': os.getenv('ENVIRONMENT', 'unknown'),
            'DJANGO_SETTINGS_MODULE': os.getenv('DJANGO_SETTINGS_MODULE'),
        },
        'database': {
            'ENGINE': settings.DATABASES['default']['ENGINE'],
            'NAME': settings.DATABASES['default']['NAME'],
            'HOST': settings.DATABASES['default']['HOST'],
        },
        'cache': {
            'BACKEND': settings.CACHES['default']['BACKEND'],
            'LOCATION': settings.CACHES['default']['LOCATION'],
        },
        'celery': {
            'BROKER_URL': settings.CELERY_BROKER_URL,
            'RESULT_BACKEND': settings.CELERY_RESULT_BACKEND,
        },
    }
    
    return render(request, 'admin/monitoring/debug_console.html', context)

4.2 UPDATE DJANGO ADMIN SITE

File: backend/igny8_core/admin/site.py

def get_urls(self):
    """Add custom monitoring URLs"""
    from django.urls import path
    from .monitoring import (
        system_health_dashboard,
        api_monitor_dashboard,
        debug_console
    )
    
    urls = super().get_urls()
    custom_urls = [
        # Existing
        path('dashboard/', self.admin_view(admin_dashboard), name='dashboard'),
        
        # NEW: Monitoring
        path('monitoring/system-health/', 
             self.admin_view(system_health_dashboard), 
             name='monitoring_system_health'),
        path('monitoring/api-monitor/', 
             self.admin_view(api_monitor_dashboard), 
             name='monitoring_api_monitor'),
        path('monitoring/debug-console/', 
             self.admin_view(debug_console), 
             name='monitoring_debug_console'),
    ]
    return custom_urls + urls

4.3 ADD PAYMENT APPROVAL ACTIONS

File: backend/igny8_core/modules/billing/admin.py

class PaymentAdmin(ExportMixin, Igny8ModelAdmin):
    list_display = ['id', 'account', 'amount', 'status', 'method', 'created_at']
    list_filter = ['status', 'method', 'created_at']
    search_fields = ['account__name', 'transaction_id']
    
    actions = [
        'bulk_approve_payments',
        'bulk_reject_payments',
        # ... existing actions
    ]
    
    def bulk_approve_payments(self, request, queryset):
        """Approve pending manual payments"""
        pending = queryset.filter(status='pending', method='manual')
        count = 0
        for payment in pending:
            payment.status = 'completed'
            payment.approved_by = request.user
            payment.approved_at = timezone.now()
            payment.save()
            count += 1
            
            # Credit the account
            payment.account.credits += payment.amount_credits
            payment.account.save()
            
            # Create credit transaction
            CreditTransaction.objects.create(
                account=payment.account,
                amount=payment.amount_credits,
                transaction_type='purchase',
                description=f'Manual payment approved: {payment.transaction_id}',
                created_by=request.user
            )
        
        self.message_user(request, f'{count} payment(s) approved.')
    bulk_approve_payments.short_description = "Approve selected pending payments"
    
    def bulk_reject_payments(self, request, queryset):
        """Reject pending manual payments"""
        pending = queryset.filter(status='pending', method='manual')
        count = pending.update(status='failed')
        self.message_user(request, f'{count} payment(s) rejected.')
    bulk_reject_payments.short_description = "Reject selected pending payments"

PART 5: IMPLEMENTATION PHASES

Phase 1: Backend Settings Refactor (Week 1-2)

Tasks:

  1. Create GlobalIntegrationSettings model
  2. Create AccountIntegrationOverride model
  3. Create GlobalAIPrompt model
  4. Update AIPrompt model (add is_customized)
  5. Create GlobalAuthorProfile model
  6. Update AuthorProfile (add cloned_from)
  7. Create GlobalStrategy model
  8. Update Strategy (add cloned_from)
  9. Create migrations
  10. Create data migration to move aws-admin settings to global
  11. Update ai/settings.py lookup logic
  12. Update all API views using settings
  13. Test thoroughly

Deliverables:

  • New models in production
  • Settings lookup working correctly
  • All existing functionality preserved

Phase 2: Django Admin Enhancements (Week 2-3)

Tasks:

  1. Create admin/monitoring.py
  2. Build system health dashboard
  3. Build API monitor dashboard
  4. Build debug console
  5. Add monitoring URLs to admin site
  6. Create templates for monitoring pages
  7. Add payment approval actions to Payment admin
  8. Test all new Django admin features

Deliverables:

  • 3 new monitoring pages in Django admin
  • Payment approval workflow functional

Phase 3: Frontend Cleanup (Week 3-4)

Tasks:

  1. Delete 16 admin page files
  2. Delete 3 settings page files (api-monitor, debug-status)
  3. Delete 23 UI elements page files
  4. Delete AdminGuard component
  5. Delete ApiStatusIndicator component
  6. Remove admin section from AppSidebar
  7. Remove isAwsAdminAccount checks
  8. Remove isPrivileged checks from ProtectedRoute
  9. Clean up api.ts comments
  10. Remove admin routes from routes.tsx
  11. Test all user-facing features still work
  12. Verify no broken links

Deliverables:

  • ~45 files deleted
  • Frontend code cleaned
  • All user features functional

Phase 4: Backend API Cleanup (Week 4)

Tasks:

  1. Remove admin-only API endpoints (duplicating Django admin)
  2. Remove IsSystemAccountOrDeveloper permission class
  3. Update settings API to use global + override pattern
  4. Remove aws-admin fallback logic everywhere
  5. Test all remaining API endpoints
  6. Update API documentation

Deliverables:

  • Cleaner API codebase
  • No frontend admin dependencies

Phase 5: Testing & Documentation (Week 4)

Tasks:

  1. End-to-end testing of all user features
  2. Test Django admin monitoring pages
  3. Test global + override settings pattern
  4. Verify no regressions
  5. Update documentation
  6. Train team on new architecture

Deliverables:

  • All tests passing
  • Documentation updated
  • Team trained

PART 6: VERIFICATION CHECKLIST

6.1 Settings Verification

  • Global OpenAI settings work for all accounts
  • Account can override OpenAI with own key
  • Global DALL-E settings work
  • Account can override DALL-E settings
  • Global prompts accessible to all accounts
  • Account can customize prompts
  • Account can reset prompts to global default
  • Global author profiles clonable by accounts
  • Global strategies clonable by accounts

6.2 Frontend Verification

  • No admin routes accessible in frontend
  • Sidebar has no admin section
  • All user settings pages still work
  • Module enable/disable works
  • WordPress integrations work
  • No broken links
  • No console errors about missing routes

6.3 Django Admin Verification

  • System health monitor functional
  • API monitor functional
  • Debug console functional
  • Payment approval actions work
  • All existing admin models still work
  • Bulk actions still work

6.4 Backend Verification

  • AI operations use correct settings (global or override)
  • No aws-admin fallback logic remaining
  • Settings API returns global + override info
  • All endpoints functional
  • No permission errors

PART 7: ROLLBACK PLAN

If issues occur during migration:

  1. Phase 1 Rollback:

    • Keep new models but don't use them
    • Restore old settings lookup logic
  2. Phase 2 Rollback:

    • Remove monitoring pages from Django admin URLs
  3. Phase 3 Rollback:

    • Git revert frontend file deletions
    • Restore admin routes
  4. Phase 4 Rollback:

    • Restore API endpoints
    • Restore permission classes

SUMMARY

Pages Being Removed from Frontend: 42 Pages

Admin Pages: 16 Monitoring Pages: 3 UI Elements Pages: 23

Pages Being Created in Django Admin: 3 Pages

Monitoring Pages: System Health, API Monitor, Debug Console

Settings Being Refactored: 7 Categories

  1. OpenAI API settings (global + override)
  2. DALL-E/image settings (global + override)
  3. Anthropic settings (global + override)
  4. AI Prompts (global library + account custom)
  5. Author Profiles (global library + account clone)
  6. Content Strategies (global library + account clone)
  7. Module enable settings (keep as account-specific)

Code Cleanup: 5 Areas

  1. Frontend admin components (delete)
  2. Frontend admin routes (delete)
  3. Backend admin-only APIs (delete)
  4. Permission classes (simplify)
  5. Settings fallback logic (replace with global)

Status: COMPREHENSIVE PLAN COMPLETE
Timeline: 4 weeks for full implementation
Risk: LOW - Well-defined changes
Benefit: HIGH - Cleaner, more secure, easier to maintain


End of Comprehensive Plan