django admin Groups reorg, Frontend udpates for site settings, #Migration runs

This commit is contained in:
IGNY8 VPS (Salman)
2026-01-05 01:21:52 +00:00
parent 6e30d2d4e8
commit dc7a459ebb
39 changed files with 3142 additions and 1589 deletions

View File

@@ -0,0 +1,86 @@
# Generated by Django 5.2.9 on 2026-01-04 06:11
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('system', '0014_update_runware_models'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AlterField(
model_name='globalintegrationsettings',
name='anthropic_model',
field=models.CharField(choices=[('claude-3-5-sonnet-20241022', 'Claude 3.5 Sonnet - $3.00 / $15.00 per 1M tokens'), ('claude-3-5-haiku-20241022', 'Claude 3.5 Haiku - $1.00 / $5.00 per 1M tokens'), ('claude-3-opus-20240229', 'Claude 3 Opus - $15.00 / $75.00 per 1M tokens'), ('claude-3-sonnet-20240229', 'Claude 3 Sonnet - $3.00 / $15.00 per 1M tokens'), ('claude-3-haiku-20240307', 'Claude 3 Haiku - $0.25 / $1.25 per 1M tokens')], default='claude-3-5-sonnet-20241022', help_text='Default Claude model (accounts can override if plan allows)', max_length=100),
),
migrations.AlterField(
model_name='globalintegrationsettings',
name='default_image_service',
field=models.CharField(choices=[('openai', 'OpenAI DALL-E'), ('runware', 'Runware')], default='openai', help_text='Default image generation service for all accounts (openai=DALL-E, runware=Runware, bria=Bria)', max_length=20),
),
migrations.AlterField(
model_name='globalintegrationsettings',
name='image_style',
field=models.CharField(choices=[('photorealistic', 'Photorealistic'), ('illustration', 'Illustration'), ('3d_render', '3D Render'), ('minimal_flat', 'Minimal / Flat Design'), ('artistic', 'Artistic / Painterly'), ('cartoon', 'Cartoon / Stylized')], default='photorealistic', help_text='Default image style for all providers (accounts can override if plan allows)', max_length=30),
),
migrations.AlterField(
model_name='globalmodulesettings',
name='linker_enabled',
field=models.BooleanField(default=False, help_text='Enable Linker module platform-wide (Phase 2)'),
),
migrations.AlterField(
model_name='globalmodulesettings',
name='optimizer_enabled',
field=models.BooleanField(default=False, help_text='Enable Optimizer module platform-wide (Phase 2)'),
),
migrations.AlterField(
model_name='globalmodulesettings',
name='site_builder_enabled',
field=models.BooleanField(default=False, help_text='Enable Site Builder module platform-wide (DEPRECATED)'),
),
migrations.AlterField(
model_name='moduleenablesettings',
name='linker_enabled',
field=models.BooleanField(default=False, help_text='Enable Linker module (Phase 2)'),
),
migrations.AlterField(
model_name='moduleenablesettings',
name='optimizer_enabled',
field=models.BooleanField(default=False, help_text='Enable Optimizer module (Phase 2)'),
),
migrations.AlterField(
model_name='moduleenablesettings',
name='site_builder_enabled',
field=models.BooleanField(default=False, help_text='Enable Site Builder module (DEPRECATED)'),
),
migrations.CreateModel(
name='IntegrationProvider',
fields=[
('provider_id', models.CharField(help_text="Unique identifier (e.g., 'openai', 'stripe', 'resend')", max_length=50, primary_key=True, serialize=False, unique=True)),
('display_name', models.CharField(help_text='Human-readable name', max_length=100)),
('provider_type', models.CharField(choices=[('ai', 'AI Provider'), ('email', 'Email Service'), ('payment', 'Payment Gateway'), ('storage', 'Storage Service'), ('analytics', 'Analytics'), ('other', 'Other')], db_index=True, default='ai', max_length=20)),
('api_key', models.CharField(blank=True, help_text='Primary API key or token', max_length=500)),
('api_secret', models.CharField(blank=True, help_text='Secondary secret (for OAuth, Stripe secret key, etc.)', max_length=500)),
('webhook_secret', models.CharField(blank=True, help_text='Webhook signing secret (Stripe, PayPal)', max_length=500)),
('api_endpoint', models.URLField(blank=True, help_text='Custom API endpoint (if not default)')),
('webhook_url', models.URLField(blank=True, help_text='Webhook URL configured at provider')),
('config', models.JSONField(blank=True, default=dict, help_text='Provider-specific config: rate limits, regions, modes, etc.')),
('is_active', models.BooleanField(db_index=True, default=True)),
('is_sandbox', models.BooleanField(default=False, help_text='True if using sandbox/test mode (Stripe test keys, PayPal sandbox)')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('updated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='integration_provider_updates', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Integration Provider',
'verbose_name_plural': 'Integration Providers',
'db_table': 'igny8_integration_providers',
'ordering': ['provider_type', 'display_name'],
},
),
]

View File

@@ -0,0 +1,136 @@
# Generated manually for data migration
from django.db import migrations
def populate_integration_providers(apps, schema_editor):
"""
Populate IntegrationProvider with all 3rd party integrations.
API keys will need to be configured in Django admin after migration.
"""
IntegrationProvider = apps.get_model('system', 'IntegrationProvider')
providers = [
# AI Providers
{
'provider_id': 'openai',
'display_name': 'OpenAI',
'provider_type': 'ai',
'api_key': '', # To be configured in admin
'config': {
'default_model': 'gpt-5.1',
'models': ['gpt-4o-mini', 'gpt-4o', 'gpt-5.1', 'dall-e-3'],
},
'is_active': True,
},
{
'provider_id': 'runware',
'display_name': 'Runware',
'provider_type': 'ai',
'api_key': '', # To be configured in admin
'config': {
'default_model': 'runware:97@1',
'models': ['runware:97@1', 'google:4@2'],
},
'is_active': True,
},
{
'provider_id': 'anthropic',
'display_name': 'Anthropic (Claude)',
'provider_type': 'ai',
'api_key': '',
'config': {
'default_model': 'claude-3-5-sonnet-20241022',
},
'is_active': False, # Not currently used
},
{
'provider_id': 'google',
'display_name': 'Google Cloud',
'provider_type': 'ai',
'api_key': '',
'config': {},
'is_active': False, # Future: Gemini
},
# Payment Providers
{
'provider_id': 'stripe',
'display_name': 'Stripe',
'provider_type': 'payment',
'api_key': '', # Public key
'api_secret': '', # Secret key
'webhook_secret': '',
'config': {
'currency': 'usd',
},
'is_active': True,
'is_sandbox': True, # Start in test mode
},
{
'provider_id': 'paypal',
'display_name': 'PayPal',
'provider_type': 'payment',
'api_key': '', # Client ID
'api_secret': '', # Client Secret
'webhook_secret': '',
'api_endpoint': 'https://api-m.sandbox.paypal.com', # Sandbox endpoint
'config': {
'currency': 'usd',
},
'is_active': True,
'is_sandbox': True,
},
# Email Providers
{
'provider_id': 'resend',
'display_name': 'Resend',
'provider_type': 'email',
'api_key': '',
'config': {
'from_email': 'noreply@igny8.com',
'from_name': 'IGNY8',
},
'is_active': True,
},
# Storage Providers (Future)
{
'provider_id': 'cloudflare_r2',
'display_name': 'Cloudflare R2',
'provider_type': 'storage',
'api_key': '', # Access Key ID
'api_secret': '', # Secret Access Key
'config': {
'bucket': '',
'endpoint': '',
},
'is_active': False,
},
]
for provider_data in providers:
IntegrationProvider.objects.update_or_create(
provider_id=provider_data['provider_id'],
defaults=provider_data
)
def reverse_migration(apps, schema_editor):
"""Remove seeded providers"""
IntegrationProvider = apps.get_model('system', 'IntegrationProvider')
IntegrationProvider.objects.filter(
provider_id__in=['openai', 'runware', 'anthropic', 'google', 'stripe', 'paypal', 'resend', 'cloudflare_r2']
).delete()
class Migration(migrations.Migration):
dependencies = [
('system', '0015_add_integration_provider'),
]
operations = [
migrations.RunPython(populate_integration_providers, reverse_migration),
]

View File

@@ -0,0 +1,15 @@
# Generated by Django 5.2.9 on 2026-01-04 08:43
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('system', '0016_populate_integration_providers'),
]
operations = [
# AccountIntegrationOverride was already deleted in a previous migration
# Keeping this migration empty for now
]

View File

@@ -0,0 +1,35 @@
# Generated by Django 5.2.9 on 2026-01-04 08:43
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('system', '0017_create_ai_settings'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='SystemAISettings',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('temperature', models.FloatField(default=0.7, help_text='AI temperature (0.0-2.0). Higher = more creative.')),
('max_tokens', models.IntegerField(default=8192, help_text='Max response tokens')),
('image_style', models.CharField(choices=[('photorealistic', 'Photorealistic'), ('illustration', 'Illustration'), ('3d_render', '3D Render'), ('minimal_flat', 'Minimal / Flat Design'), ('artistic', 'Artistic / Painterly'), ('cartoon', 'Cartoon / Stylized')], default='photorealistic', help_text='Default image style', max_length=30)),
('image_quality', models.CharField(choices=[('standard', 'Standard'), ('hd', 'HD')], default='standard', help_text='Default image quality (standard/hd)', max_length=20)),
('max_images_per_article', models.IntegerField(default=4, help_text='Max in-article images (1-8)')),
('image_size', models.CharField(choices=[('1024x1024', '1024x1024 (Square)'), ('1792x1024', '1792x1024 (Landscape)'), ('1024x1792', '1024x1792 (Portrait)')], default='1024x1024', help_text='Default image dimensions', max_length=20)),
('updated_at', models.DateTimeField(auto_now=True)),
('updated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='system_ai_settings_updates', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'System AI Settings',
'verbose_name_plural': 'System AI Settings',
'db_table': 'igny8_system_ai_settings',
},
),
]

View File

@@ -0,0 +1,91 @@
# Generated by Django 5.2.9 on 2026-01-04 10:40
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('system', '0018_create_ai_settings_table'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.RemoveField(
model_name='accountsettings',
name='config',
),
migrations.RemoveField(
model_name='accountsettings',
name='is_active',
),
migrations.RemoveField(
model_name='integrationprovider',
name='webhook_url',
),
migrations.RemoveField(
model_name='modulesettings',
name='config',
),
migrations.AddField(
model_name='accountsettings',
name='value',
field=models.JSONField(default=dict, help_text='Setting value'),
),
migrations.AlterField(
model_name='accountsettings',
name='key',
field=models.CharField(db_index=True, help_text='Setting key', max_length=100),
),
migrations.AlterField(
model_name='integrationprovider',
name='api_endpoint',
field=models.URLField(blank=True, help_text='Custom endpoint (optional)'),
),
migrations.AlterField(
model_name='integrationprovider',
name='api_key',
field=models.CharField(blank=True, help_text='Primary API key', max_length=500),
),
migrations.AlterField(
model_name='integrationprovider',
name='api_secret',
field=models.CharField(blank=True, help_text='Secondary secret (Stripe, PayPal)', max_length=500),
),
migrations.AlterField(
model_name='integrationprovider',
name='config',
field=models.JSONField(blank=True, default=dict, help_text='Provider-specific config'),
),
migrations.AlterField(
model_name='integrationprovider',
name='is_active',
field=models.BooleanField(db_index=True, default=True, help_text='Enable/disable provider'),
),
migrations.AlterField(
model_name='integrationprovider',
name='is_sandbox',
field=models.BooleanField(default=False, help_text='Test mode flag'),
),
migrations.AlterField(
model_name='integrationprovider',
name='provider_type',
field=models.CharField(choices=[('ai', 'AI Provider'), ('payment', 'Payment Gateway'), ('email', 'Email Service'), ('storage', 'Storage Service')], db_index=True, default='ai', help_text='ai / payment / email / storage', max_length=20),
),
migrations.AlterField(
model_name='integrationprovider',
name='updated_by',
field=models.ForeignKey(blank=True, help_text='Audit trail', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='integration_provider_updates', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='integrationprovider',
name='webhook_secret',
field=models.CharField(blank=True, help_text='Webhook signing secret', max_length=500),
),
# AccountIntegrationOverride table doesn't exist in DB, so skip delete
# migrations.DeleteModel(
# name='AccountIntegrationOverride',
# ),
]