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
This commit is contained in:
IGNY8 VPS (Salman)
2025-12-20 12:55:05 +00:00
parent eb6cba7920
commit 3283a83b42
51 changed files with 3578 additions and 5434 deletions

View File

@@ -0,0 +1,186 @@
# Generated migration for global settings models
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('system', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('igny8_core_auth', '0001_initial'),
]
operations = [
# Create GlobalIntegrationSettings
migrations.CreateModel(
name='GlobalIntegrationSettings',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('openai_api_key', models.CharField(blank=True, help_text='Global OpenAI API key used by all accounts (unless overridden)', max_length=500)),
('openai_model', models.CharField(default='gpt-4-turbo-preview', help_text='Default OpenAI model for text generation', max_length=100)),
('openai_temperature', models.FloatField(default=0.7, help_text='Temperature for OpenAI text generation (0.0 to 2.0)')),
('openai_max_tokens', models.IntegerField(default=4000, help_text='Maximum tokens for OpenAI responses')),
('dalle_api_key', models.CharField(blank=True, help_text='Global DALL-E API key (can be same as OpenAI key)', max_length=500)),
('dalle_model', models.CharField(default='dall-e-3', help_text='DALL-E model version', max_length=100)),
('dalle_size', models.CharField(default='1024x1024', help_text='Default image size for DALL-E', max_length=20)),
('dalle_quality', models.CharField(choices=[('standard', 'Standard'), ('hd', 'HD')], default='standard', help_text='Image quality for DALL-E 3', max_length=20)),
('dalle_style', models.CharField(choices=[('vivid', 'Vivid'), ('natural', 'Natural')], default='vivid', help_text='Image style for DALL-E 3', max_length=20)),
('anthropic_api_key', models.CharField(blank=True, help_text='Global Anthropic Claude API key', max_length=500)),
('anthropic_model', models.CharField(default='claude-3-sonnet-20240229', help_text='Default Anthropic Claude model', max_length=100)),
('runware_api_key', models.CharField(blank=True, help_text='Global Runware API key for image generation', max_length=500)),
('is_active', models.BooleanField(default=True)),
('last_updated', models.DateTimeField(auto_now=True)),
('updated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='global_settings_updates', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Global Integration Settings',
'verbose_name_plural': 'Global Integration Settings',
'db_table': 'igny8_global_integration_settings',
},
),
# Create AccountIntegrationOverride
migrations.CreateModel(
name='AccountIntegrationOverride',
fields=[
('account', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='integration_override', serialize=False, to='igny8_core_auth.account')),
('use_own_keys', models.BooleanField(default=False, help_text="Use account's own API keys instead of global settings")),
('openai_api_key', models.CharField(blank=True, max_length=500, null=True)),
('openai_model', models.CharField(blank=True, max_length=100, null=True)),
('openai_temperature', models.FloatField(blank=True, null=True)),
('openai_max_tokens', models.IntegerField(blank=True, null=True)),
('dalle_api_key', models.CharField(blank=True, max_length=500, null=True)),
('dalle_model', models.CharField(blank=True, max_length=100, null=True)),
('dalle_size', models.CharField(blank=True, max_length=20, null=True)),
('dalle_quality', models.CharField(blank=True, max_length=20, null=True)),
('dalle_style', models.CharField(blank=True, max_length=20, null=True)),
('anthropic_api_key', models.CharField(blank=True, max_length=500, null=True)),
('anthropic_model', models.CharField(blank=True, max_length=100, null=True)),
('runware_api_key', models.CharField(blank=True, max_length=500, null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Account Integration Override',
'verbose_name_plural': 'Account Integration Overrides',
'db_table': 'igny8_account_integration_override',
},
),
# Create GlobalAIPrompt
migrations.CreateModel(
name='GlobalAIPrompt',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('prompt_type', models.CharField(choices=[('clustering', 'Clustering'), ('ideas', 'Ideas Generation'), ('content_generation', 'Content Generation'), ('image_prompt_extraction', 'Image Prompt Extraction'), ('image_prompt_template', 'Image Prompt Template'), ('negative_prompt', 'Negative Prompt'), ('site_structure_generation', 'Site Structure Generation'), ('product_generation', 'Product Content Generation'), ('service_generation', 'Service Page Generation'), ('taxonomy_generation', 'Taxonomy Generation')], help_text='Type of AI operation this prompt is for', max_length=50, unique=True)),
('prompt_value', models.TextField(help_text='Default prompt template')),
('description', models.TextField(blank=True, help_text='Description of what this prompt does')),
('variables', models.JSONField(default=list, help_text='List of variables used in the prompt (e.g., {keyword}, {industry})')),
('is_active', models.BooleanField(db_index=True, default=True)),
('version', models.IntegerField(default=1, help_text='Prompt version for tracking changes')),
('last_updated', models.DateTimeField(auto_now=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
],
options={
'verbose_name': 'Global AI Prompt',
'verbose_name_plural': 'Global AI Prompts',
'db_table': 'igny8_global_ai_prompts',
'ordering': ['prompt_type'],
},
),
# Create GlobalAuthorProfile
migrations.CreateModel(
name='GlobalAuthorProfile',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(help_text="Profile name (e.g., 'SaaS B2B Professional')", max_length=255, unique=True)),
('description', models.TextField(help_text='Description of the writing style')),
('tone', models.CharField(help_text="Writing tone (e.g., 'Professional', 'Casual', 'Technical')", max_length=100)),
('language', models.CharField(default='en', help_text='Language code', max_length=50)),
('structure_template', models.JSONField(default=dict, help_text='Structure template defining content sections')),
('category', models.CharField(choices=[('saas', 'SaaS/B2B'), ('ecommerce', 'E-commerce'), ('blog', 'Blog/Publishing'), ('technical', 'Technical'), ('creative', 'Creative'), ('news', 'News/Media'), ('academic', 'Academic')], help_text='Profile category', max_length=50)),
('is_active', models.BooleanField(db_index=True, default=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Global Author Profile',
'verbose_name_plural': 'Global Author Profiles',
'db_table': 'igny8_global_author_profiles',
'ordering': ['category', 'name'],
},
),
# Create GlobalStrategy
migrations.CreateModel(
name='GlobalStrategy',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(help_text='Strategy name', max_length=255, unique=True)),
('description', models.TextField(help_text='Description of the content strategy')),
('prompt_types', models.JSONField(default=list, help_text='List of prompt types to use')),
('section_logic', models.JSONField(default=dict, help_text='Section logic configuration')),
('category', models.CharField(choices=[('blog', 'Blog Content'), ('ecommerce', 'E-commerce'), ('saas', 'SaaS/B2B'), ('news', 'News/Media'), ('technical', 'Technical Documentation'), ('marketing', 'Marketing Content')], help_text='Strategy category', max_length=50)),
('is_active', models.BooleanField(db_index=True, default=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Global Strategy',
'verbose_name_plural': 'Global Strategies',
'db_table': 'igny8_global_strategies',
'ordering': ['category', 'name'],
},
),
# Update AIPrompt model - remove default_prompt, add is_customized
migrations.RemoveField(
model_name='aiprompt',
name='default_prompt',
),
migrations.AddField(
model_name='aiprompt',
name='is_customized',
field=models.BooleanField(default=False, help_text='True if account customized the prompt, False if using global default'),
),
migrations.AddIndex(
model_name='aiprompt',
index=models.Index(fields=['is_customized'], name='igny8_ai_pr_is_cust_idx'),
),
# Update AuthorProfile - add is_custom and cloned_from
migrations.AddField(
model_name='authorprofile',
name='is_custom',
field=models.BooleanField(default=False, help_text='True if created by account, False if cloned from global template'),
),
migrations.AddField(
model_name='authorprofile',
name='cloned_from',
field=models.ForeignKey(blank=True, help_text='Reference to the global template this was cloned from', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='cloned_instances', to='system.globalauthorprofile'),
),
migrations.AddIndex(
model_name='authorprofile',
index=models.Index(fields=['is_custom'], name='igny8_autho_is_cust_idx'),
),
# Update Strategy - add is_custom and cloned_from
migrations.AddField(
model_name='strategy',
name='is_custom',
field=models.BooleanField(default=False, help_text='True if created by account, False if cloned from global template'),
),
migrations.AddField(
model_name='strategy',
name='cloned_from',
field=models.ForeignKey(blank=True, help_text='Reference to the global template this was cloned from', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='cloned_instances', to='system.globalstrategy'),
),
migrations.AddIndex(
model_name='strategy',
index=models.Index(fields=['is_custom'], name='igny8_strat_is_cust_idx'),
),
]

View File

@@ -0,0 +1,108 @@
# Generated by Django 5.2.9 on 2025-12-20 12:29
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('system', '0003_fix_global_settings_architecture'),
]
operations = [
migrations.RenameIndex(
model_name='aiprompt',
new_name='igny8_ai_pr_is_cust_5d7a72_idx',
old_name='igny8_ai_pr_is_cust_idx',
),
migrations.RenameIndex(
model_name='authorprofile',
new_name='igny8_autho_is_cust_d163e6_idx',
old_name='igny8_autho_is_cust_idx',
),
migrations.RenameIndex(
model_name='strategy',
new_name='igny8_strat_is_cust_4b3c4b_idx',
old_name='igny8_strat_is_cust_idx',
),
migrations.AlterField(
model_name='aiprompt',
name='default_prompt',
field=models.TextField(blank=True, help_text='Global default prompt - used for reset to default'),
),
migrations.AlterField(
model_name='aiprompt',
name='prompt_value',
field=models.TextField(help_text='Current prompt text (customized or default)'),
),
migrations.AlterField(
model_name='globalintegrationsettings',
name='anthropic_api_key',
field=models.CharField(blank=True, help_text='Platform Anthropic API key - used by ALL accounts', max_length=500),
),
migrations.AlterField(
model_name='globalintegrationsettings',
name='anthropic_model',
field=models.CharField(default='claude-3-sonnet-20240229', help_text='Default Anthropic model (accounts can override if plan allows)', max_length=100),
),
migrations.AlterField(
model_name='globalintegrationsettings',
name='dalle_api_key',
field=models.CharField(blank=True, help_text='Platform DALL-E API key - used by ALL accounts (can be same as OpenAI)', max_length=500),
),
migrations.AlterField(
model_name='globalintegrationsettings',
name='dalle_model',
field=models.CharField(default='dall-e-3', help_text='Default DALL-E model (accounts can override if plan allows)', max_length=100),
),
migrations.AlterField(
model_name='globalintegrationsettings',
name='dalle_quality',
field=models.CharField(choices=[('standard', 'Standard'), ('hd', 'HD')], default='standard', help_text='Default image quality (accounts can override if plan allows)', max_length=20),
),
migrations.AlterField(
model_name='globalintegrationsettings',
name='dalle_size',
field=models.CharField(default='1024x1024', help_text='Default image size (accounts can override if plan allows)', max_length=20),
),
migrations.AlterField(
model_name='globalintegrationsettings',
name='dalle_style',
field=models.CharField(choices=[('vivid', 'Vivid'), ('natural', 'Natural')], default='vivid', help_text='Default image style (accounts can override if plan allows)', max_length=20),
),
migrations.AlterField(
model_name='globalintegrationsettings',
name='openai_api_key',
field=models.CharField(blank=True, help_text='Platform OpenAI API key - used by ALL accounts', max_length=500),
),
migrations.AlterField(
model_name='globalintegrationsettings',
name='openai_max_tokens',
field=models.IntegerField(default=8192, help_text='Default max tokens for responses (accounts can override if plan allows)'),
),
migrations.AlterField(
model_name='globalintegrationsettings',
name='openai_model',
field=models.CharField(default='gpt-4-turbo-preview', help_text='Default text generation model (accounts can override if plan allows)', max_length=100),
),
migrations.AlterField(
model_name='globalintegrationsettings',
name='openai_temperature',
field=models.FloatField(default=0.7, help_text='Default temperature 0.0-2.0 (accounts can override if plan allows)'),
),
migrations.AlterField(
model_name='globalintegrationsettings',
name='runware_api_key',
field=models.CharField(blank=True, help_text='Platform Runware API key - used by ALL accounts', max_length=500),
),
migrations.AlterField(
model_name='integrationsettings',
name='config',
field=models.JSONField(default=dict, help_text='Model and parameter overrides only. Fields: model, temperature, max_tokens, image_size, image_quality, etc. NULL = use global default. NEVER store API keys here.'),
),
migrations.AlterField(
model_name='integrationsettings',
name='integration_type',
field=models.CharField(choices=[('openai', 'OpenAI'), ('dalle', 'DALL-E'), ('anthropic', 'Anthropic'), ('runware', 'Runware')], db_index=True, max_length=50),
),
]