Initial commit: igny8 project

This commit is contained in:
igny8
2025-11-09 10:27:02 +00:00
commit 60b8188111
27265 changed files with 4360521 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
# Management module

View File

@@ -0,0 +1,2 @@
# Management commands module

View File

@@ -0,0 +1,297 @@
"""
Django management command to delete accounts and reassign their data to AWS Admin account
Usage: python manage.py cleanup_accounts
"""
from django.core.management.base import BaseCommand
from django.db import transaction
from django.db.models import Q
from igny8_core.auth.models import Account, User, Site, Sector
from igny8_core.modules.planner.models import Keywords, Clusters, ContentIdeas
from igny8_core.modules.writer.models import Tasks, Images, Content
from igny8_core.modules.billing.models import CreditTransaction, CreditUsageLog
from igny8_core.modules.system.models import AIPrompt, IntegrationSettings, AuthorProfile, Strategy
from igny8_core.modules.system.settings_models import AccountSettings, UserSettings, ModuleSettings, AISettings
class Command(BaseCommand):
help = 'Delete specified accounts and reassign all their data to AWS Admin account'
def add_arguments(self, parser):
parser.add_argument(
'--dry-run',
action='store_true',
help='Show what would be done without actually doing it',
)
def handle(self, *args, **options):
dry_run = options['dry_run']
if dry_run:
self.stdout.write(self.style.WARNING('DRY RUN MODE - No changes will be made'))
# Get AWS Admin account
try:
aws_admin_account = Account.objects.get(slug='aws-admin')
self.stdout.write(self.style.SUCCESS(f'✅ Found AWS Admin account: {aws_admin_account.name} (ID: {aws_admin_account.id})'))
except Account.DoesNotExist:
self.stdout.write(self.style.ERROR('❌ AWS Admin account not found. Please create it first.'))
return
# Get AWS Admin user (developer role)
aws_admin_user = User.objects.filter(
account=aws_admin_account,
role='developer'
).first()
if not aws_admin_user:
# Try to get any user in aws-admin account
aws_admin_user = User.objects.filter(account=aws_admin_account).first()
if not aws_admin_user:
self.stdout.write(self.style.ERROR('❌ No user found in AWS Admin account. Please create a user first.'))
return
self.stdout.write(self.style.SUCCESS(f'✅ Using AWS Admin user: {aws_admin_user.email} (ID: {aws_admin_user.id})'))
# Accounts to delete (from the image)
accounts_to_delete = [
'test-user',
'test-account-test-user',
'default',
'salman-sadiq',
]
accounts_found = []
accounts_not_found = []
for slug in accounts_to_delete:
try:
account = Account.objects.get(slug=slug)
accounts_found.append(account)
self.stdout.write(f' - Found account: {account.name} (slug: {slug}, ID: {account.id})')
except Account.DoesNotExist:
accounts_not_found.append(slug)
self.stdout.write(self.style.WARNING(f' - Account not found: {slug}'))
if accounts_not_found:
self.stdout.write(self.style.WARNING(f'\n⚠️ {len(accounts_not_found)} account(s) not found: {", ".join(accounts_not_found)}'))
if not accounts_found:
self.stdout.write(self.style.ERROR('❌ No accounts found to delete.'))
return
self.stdout.write(f'\n📊 Summary:')
self.stdout.write(f' - AWS Admin account: {aws_admin_account.name} (ID: {aws_admin_account.id})')
self.stdout.write(f' - Accounts to delete: {len(accounts_found)}')
if dry_run:
self.stdout.write(self.style.WARNING('\n🔍 DRY RUN - Counting items to reassign:'))
else:
self.stdout.write(self.style.WARNING('\n⚠️ Starting reassignment and deletion...'))
with transaction.atomic():
total_reassigned = 0
for account in accounts_found:
self.stdout.write(f'\n📦 Processing account: {account.name} (ID: {account.id})')
# Count and reassign Sites
sites_count = Site.objects.filter(account=account).count()
if sites_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {sites_count} site(s)')
else:
Site.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {sites_count} site(s)'))
total_reassigned += sites_count
# Count and reassign Sectors
sectors_count = Sector.objects.filter(account=account).count()
if sectors_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {sectors_count} sector(s)')
else:
Sector.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {sectors_count} sector(s)'))
total_reassigned += sectors_count
# Count and reassign Keywords
keywords_count = Keywords.objects.filter(account=account).count()
if keywords_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {keywords_count} keyword(s)')
else:
Keywords.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {keywords_count} keyword(s)'))
total_reassigned += keywords_count
# Count and reassign Clusters
clusters_count = Clusters.objects.filter(account=account).count()
if clusters_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {clusters_count} cluster(s)')
else:
Clusters.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {clusters_count} cluster(s)'))
total_reassigned += clusters_count
# Count and reassign ContentIdeas
ideas_count = ContentIdeas.objects.filter(account=account).count()
if ideas_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {ideas_count} content idea(s)')
else:
ContentIdeas.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {ideas_count} content idea(s)'))
total_reassigned += ideas_count
# Count and reassign Tasks
tasks_count = Tasks.objects.filter(account=account).count()
if tasks_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {tasks_count} task(s)')
else:
Tasks.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {tasks_count} task(s)'))
total_reassigned += tasks_count
# Count and reassign Images
images_count = Images.objects.filter(account=account).count()
if images_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {images_count} image(s)')
else:
Images.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {images_count} image(s)'))
total_reassigned += images_count
# Count and reassign Content
content_count = Content.objects.filter(account=account).count()
if content_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {content_count} content record(s)')
else:
Content.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {content_count} content record(s)'))
total_reassigned += content_count
# Count and reassign CreditTransactions
transactions_count = CreditTransaction.objects.filter(account=account).count()
if transactions_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {transactions_count} credit transaction(s)')
else:
CreditTransaction.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {transactions_count} credit transaction(s)'))
total_reassigned += transactions_count
# Count and reassign CreditUsageLog
usage_logs_count = CreditUsageLog.objects.filter(account=account).count()
if usage_logs_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {usage_logs_count} usage log(s)')
else:
CreditUsageLog.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {usage_logs_count} usage log(s)'))
total_reassigned += usage_logs_count
# Count and reassign AIPrompt
prompts_count = AIPrompt.objects.filter(account=account).count()
if prompts_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {prompts_count} AI prompt(s)')
else:
AIPrompt.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {prompts_count} AI prompt(s)'))
total_reassigned += prompts_count
# Count and reassign IntegrationSettings
integrations_count = IntegrationSettings.objects.filter(account=account).count()
if integrations_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {integrations_count} integration setting(s)')
else:
IntegrationSettings.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {integrations_count} integration setting(s)'))
total_reassigned += integrations_count
# Count and reassign AuthorProfile
profiles_count = AuthorProfile.objects.filter(account=account).count()
if profiles_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {profiles_count} author profile(s)')
else:
AuthorProfile.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {profiles_count} author profile(s)'))
total_reassigned += profiles_count
# Count and reassign Strategy
strategies_count = Strategy.objects.filter(account=account).count()
if strategies_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {strategies_count} strategy(ies)')
else:
Strategy.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {strategies_count} strategy(ies)'))
total_reassigned += strategies_count
# Count and reassign AccountSettings
account_settings_count = AccountSettings.objects.filter(account=account).count()
if account_settings_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {account_settings_count} account setting(s)')
else:
AccountSettings.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {account_settings_count} account setting(s)'))
total_reassigned += account_settings_count
# Count and reassign ModuleSettings
module_settings_count = ModuleSettings.objects.filter(account=account).count()
if module_settings_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {module_settings_count} module setting(s)')
else:
ModuleSettings.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {module_settings_count} module setting(s)'))
total_reassigned += module_settings_count
# Count and reassign AISettings
ai_settings_count = AISettings.objects.filter(account=account).count()
if ai_settings_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {ai_settings_count} AI setting(s)')
else:
AISettings.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {ai_settings_count} AI setting(s)'))
total_reassigned += ai_settings_count
# Reassign Users to AWS Admin account
users_count = User.objects.filter(account=account).count()
if users_count > 0:
if dry_run:
self.stdout.write(f' - Would reassign {users_count} user(s) to AWS Admin account')
else:
User.objects.filter(account=account).update(account=aws_admin_account)
self.stdout.write(self.style.SUCCESS(f' ✅ Reassigned {users_count} user(s) to AWS Admin account'))
total_reassigned += users_count
# Delete the account
if not dry_run:
account_name = account.name
account_id = account.id
account.delete()
self.stdout.write(self.style.SUCCESS(f' ✅ Deleted account: {account_name} (ID: {account_id})'))
else:
self.stdout.write(f' - Would delete account: {account.name} (ID: {account.id})')
if dry_run:
self.stdout.write(self.style.WARNING(f'\n🔍 DRY RUN COMPLETE'))
self.stdout.write(f' - Total items that would be reassigned: {total_reassigned}')
self.stdout.write(f' - Accounts that would be deleted: {len(accounts_found)}')
self.stdout.write(self.style.WARNING('\n⚠️ Run without --dry-run to actually perform the operation'))
else:
self.stdout.write(self.style.SUCCESS(f'\n✅ CLEANUP COMPLETE'))
self.stdout.write(f' - Total items reassigned: {total_reassigned}')
self.stdout.write(f' - Accounts deleted: {len(accounts_found)}')
self.stdout.write(self.style.SUCCESS(f'\n✅ All data has been reassigned to AWS Admin account: {aws_admin_account.name}'))

View File

@@ -0,0 +1,134 @@
"""
Django management command to create aws-admin account and move developer/super admin users to it
Usage: python manage.py create_aws_admin_account
"""
from django.core.management.base import BaseCommand
from django.db import transaction
from django.db.models import Q
from django.utils.text import slugify
from igny8_core.auth.models import Account, User, Plan
class Command(BaseCommand):
help = 'Create aws-admin account and move developer/super admin users to it'
def handle(self, *args, **options):
with transaction.atomic():
# Step 1: Get or create an Enterprise plan for the aws-admin account
# System accounts should have unlimited access via Enterprise plan
plan, created = Plan.objects.get_or_create(
slug='enterprise',
defaults={
'name': 'Enterprise Plan',
'price': 0.00,
'billing_cycle': 'monthly',
'max_users': 999999,
'max_sites': 999999,
'max_keywords': 999999,
'max_clusters': 999999,
'max_content_ideas': 999999,
'monthly_word_count_limit': 999999999,
'daily_content_tasks': 999999,
'daily_ai_requests': 999999,
'daily_ai_request_limit': 999999,
'monthly_ai_credit_limit': 999999,
'monthly_image_count': 999999,
'daily_image_generation_limit': 999999,
'monthly_cluster_ai_credits': 999999,
'monthly_content_ai_credits': 999999,
'monthly_image_ai_credits': 999999,
'included_credits': 999999,
'is_active': True,
'features': ['ai_writer', 'image_gen', 'auto_publish', 'custom_prompts', 'unlimited'],
}
)
if created:
self.stdout.write(self.style.SUCCESS(f'✅ Created Enterprise plan: {plan.name}'))
else:
self.stdout.write(f'Using existing Enterprise plan: {plan.name}')
# Step 2: Get the first superuser or developer to be the owner
# If no superuser exists, we'll need to create one or use the first user
owner = User.objects.filter(
Q(is_superuser=True) | Q(role='developer')
).first()
if not owner:
# Try to get any user
owner = User.objects.first()
if not owner:
self.stdout.write(self.style.ERROR('No users found. Please create a user first.'))
return
self.stdout.write(self.style.WARNING(f'No superuser/developer found. Using first user as owner: {owner.username}'))
else:
self.stdout.write(f'Using owner: {owner.username} (ID: {owner.id})')
# Step 3: Create or get aws-admin account
account, created = Account.objects.get_or_create(
slug='aws-admin',
defaults={
'name': 'AWS Admin',
'owner': owner,
'plan': plan,
'credits': 999999,
'status': 'active',
}
)
# Always ensure aws-admin account uses Enterprise plan (update if needed)
if account.plan != plan:
old_plan_name = account.plan.name if account.plan else 'None'
account.plan = plan
account.save()
self.stdout.write(self.style.SUCCESS(f'✅ Updated account plan from "{old_plan_name}" to "{plan.name}"'))
if created:
self.stdout.write(self.style.SUCCESS(f'✅ Created account: {account.name} (slug: {account.slug})'))
else:
self.stdout.write(f'Account "{account.name}" already exists, using existing one.')
# Step 4: Find all developer and super admin users
developer_users = User.objects.filter(
Q(role='developer') | Q(is_superuser=True)
).distinct()
moved_count = 0
skipped_count = 0
for user in developer_users:
if user.account == account:
skipped_count += 1
self.stdout.write(f' - User {user.username} ({user.email}) already in aws-admin account, skipping...')
continue
old_account = user.account
user.account = account
user.save()
moved_count += 1
old_account_name = old_account.name if old_account else 'None'
self.stdout.write(
self.style.SUCCESS(
f' ✅ Moved user {user.username} ({user.email}) from "{old_account_name}" to "{account.name}"'
)
)
# Summary
self.stdout.write('')
self.stdout.write(self.style.SUCCESS('=' * 60))
self.stdout.write(self.style.SUCCESS('Summary:'))
self.stdout.write(f' - Account: {account.name} (slug: {account.slug})')
self.stdout.write(f' - Users moved: {moved_count}')
self.stdout.write(f' - Users already in account: {skipped_count}')
self.stdout.write(f' - Total developer/super admin users: {developer_users.count()}')
self.stdout.write(self.style.SUCCESS('=' * 60))
self.stdout.write('')
self.stdout.write(
self.style.SUCCESS(
'✅ All developer and super admin users have been moved to the aws-admin account.'
)
)
self.stdout.write(
' These users now have access to all data across all accounts without filtering.'
)