diff --git a/backend/igny8_core/modules/system/migrations/0007_add_module_enable_settings.py b/backend/igny8_core/modules/system/migrations/0007_add_module_enable_settings.py index 2a03b28d..ca1b8085 100644 --- a/backend/igny8_core/modules/system/migrations/0007_add_module_enable_settings.py +++ b/backend/igny8_core/modules/system/migrations/0007_add_module_enable_settings.py @@ -1,37 +1,39 @@ # Generated manually for Phase 0: Module Enable Settings +# Using RunSQL to create table directly to avoid model resolution issues with new unified API model -from django.db import migrations, models +from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('igny8_core_modules_system', '0006_alter_systemstatus_unique_together_and_more'), + ('system', '0006_alter_systemstatus_unique_together_and_more'), ('igny8_core_auth', '0008_passwordresettoken_alter_industry_options_and_more'), ] operations = [ - migrations.CreateModel( - name='ModuleEnableSettings', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('planner_enabled', models.BooleanField(default=True, help_text='Enable Planner module')), - ('writer_enabled', models.BooleanField(default=True, help_text='Enable Writer module')), - ('thinker_enabled', models.BooleanField(default=True, help_text='Enable Thinker module')), - ('automation_enabled', models.BooleanField(default=True, help_text='Enable Automation module')), - ('site_builder_enabled', models.BooleanField(default=True, help_text='Enable Site Builder module')), - ('linker_enabled', models.BooleanField(default=True, help_text='Enable Linker module')), - ('optimizer_enabled', models.BooleanField(default=True, help_text='Enable Optimizer module')), - ('publisher_enabled', models.BooleanField(default=True, help_text='Enable Publisher module')), - ('account', models.ForeignKey(on_delete=models.CASCADE, to='igny8_core_auth.account', db_column='tenant_id')), - ], - options={ - 'db_table': 'igny8_module_enable_settings', - }, - ), - migrations.AddConstraint( - model_name='moduleenablesettings', - constraint=models.UniqueConstraint(fields=('account',), name='unique_account_module_enable_settings'), + # Create table using raw SQL to avoid model resolution issues + # The model state is automatically discovered from models.py + migrations.RunSQL( + sql=""" + CREATE TABLE IF NOT EXISTS igny8_module_enable_settings ( + id BIGSERIAL PRIMARY KEY, + planner_enabled BOOLEAN NOT NULL DEFAULT TRUE, + writer_enabled BOOLEAN NOT NULL DEFAULT TRUE, + thinker_enabled BOOLEAN NOT NULL DEFAULT TRUE, + automation_enabled BOOLEAN NOT NULL DEFAULT TRUE, + site_builder_enabled BOOLEAN NOT NULL DEFAULT TRUE, + linker_enabled BOOLEAN NOT NULL DEFAULT TRUE, + optimizer_enabled BOOLEAN NOT NULL DEFAULT TRUE, + publisher_enabled BOOLEAN NOT NULL DEFAULT TRUE, + tenant_id BIGINT NOT NULL REFERENCES igny8_tenants(id) ON DELETE CASCADE, + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW() + ); + CREATE INDEX IF NOT EXISTS igny8_module_enable_settings_tenant_id_idx ON igny8_module_enable_settings(tenant_id); + CREATE INDEX IF NOT EXISTS igny8_module_enable_settings_account_created_idx ON igny8_module_enable_settings(tenant_id, created_at); + CREATE UNIQUE INDEX IF NOT EXISTS unique_account_module_enable_settings ON igny8_module_enable_settings(tenant_id); + """, + reverse_sql="DROP TABLE IF EXISTS igny8_module_enable_settings CASCADE;", ), ] - diff --git a/backend/igny8_core/modules/system/settings_views.py b/backend/igny8_core/modules/system/settings_views.py index 5ded65c1..57a0b0f0 100644 --- a/backend/igny8_core/modules/system/settings_views.py +++ b/backend/igny8_core/modules/system/settings_views.py @@ -354,15 +354,31 @@ class ModuleEnableSettingsViewSet(AccountModelViewSet): request=request ) - # Get or create settings for account (one per account) + # Check if table exists (migration might not have been run) try: - settings = ModuleEnableSettings.objects.get(account=account) - except ModuleEnableSettings.DoesNotExist: - # Create default settings for account - settings = ModuleEnableSettings.objects.create(account=account) - - serializer = self.get_serializer(settings) - return success_response(data=serializer.data, request=request) + # Get or create settings for account (one per account) + try: + settings = ModuleEnableSettings.objects.get(account=account) + except ModuleEnableSettings.DoesNotExist: + # Create default settings for account + settings = ModuleEnableSettings.objects.create(account=account) + + serializer = self.get_serializer(settings) + return success_response(data=serializer.data, request=request) + except Exception as db_error: + # Check if it's a "table does not exist" error + error_str = str(db_error) + if 'does not exist' in error_str.lower() or 'relation' in error_str.lower(): + import logging + logger = logging.getLogger(__name__) + logger.error(f"ModuleEnableSettings table does not exist. Migration 0007_add_module_enable_settings needs to be run: {error_str}") + return error_response( + error='Module enable settings table not found. Please run migration: python manage.py migrate igny8_core_modules_system 0007', + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + request=request + ) + # Re-raise other database errors + raise except Exception as e: import traceback error_trace = traceback.format_exc()