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:
@@ -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'),
|
||||
),
|
||||
]
|
||||
@@ -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),
|
||||
),
|
||||
]
|
||||
Reference in New Issue
Block a user