diff --git a/backend/igny8_core/modules/system/settings_serializers.py b/backend/igny8_core/modules/system/settings_serializers.py index 6233b893..414f9cc7 100644 --- a/backend/igny8_core/modules/system/settings_serializers.py +++ b/backend/igny8_core/modules/system/settings_serializers.py @@ -58,6 +58,17 @@ class ModuleSettingsSerializer(serializers.ModelSerializer): return value +class ModuleEnableSettingsSerializer(serializers.ModelSerializer): + class Meta: + model = ModuleEnableSettings + fields = [ + 'id', 'planner_enabled', 'writer_enabled', 'thinker_enabled', + 'automation_enabled', 'site_builder_enabled', 'linker_enabled', + 'optimizer_enabled', 'publisher_enabled', 'created_at', 'updated_at' + ] + read_only_fields = ['created_at', 'updated_at', 'account'] + + class AISettingsSerializer(serializers.ModelSerializer): class Meta: model = AISettings diff --git a/backend/igny8_core/modules/system/settings_views.py b/backend/igny8_core/modules/system/settings_views.py index 67863ed4..a423f193 100644 --- a/backend/igny8_core/modules/system/settings_views.py +++ b/backend/igny8_core/modules/system/settings_views.py @@ -16,7 +16,7 @@ from igny8_core.api.permissions import IsAuthenticatedAndActive, HasTenantAccess from .settings_models import SystemSettings, AccountSettings, UserSettings, ModuleSettings, ModuleEnableSettings, AISettings from .settings_serializers import ( SystemSettingsSerializer, AccountSettingsSerializer, UserSettingsSerializer, - ModuleSettingsSerializer, AISettingsSerializer + ModuleSettingsSerializer, ModuleEnableSettingsSerializer, AISettingsSerializer ) @@ -276,6 +276,105 @@ class ModuleSettingsViewSet(AccountModelViewSet): serializer.save(account=account) +@extend_schema_view( + list=extend_schema(tags=['System']), + retrieve=extend_schema(tags=['System']), + update=extend_schema(tags=['System']), + partial_update=extend_schema(tags=['System']), +) +class ModuleEnableSettingsViewSet(AccountModelViewSet): + """ + ViewSet for managing module enable/disable settings + Unified API Standard v1.0 compliant + One record per account + """ + queryset = ModuleEnableSettings.objects.all() + serializer_class = ModuleEnableSettingsSerializer + permission_classes = [IsAuthenticatedAndActive, HasTenantAccess, IsAdminOrOwner] + authentication_classes = [JWTAuthentication, CSRFExemptSessionAuthentication] + throttle_scope = 'system' + throttle_classes = [DebugScopedRateThrottle] + + def get_queryset(self): + """Get module enable settings for current account""" + queryset = super().get_queryset() + return queryset + + def list(self, request): + """Get or create module enable settings for current account""" + account = getattr(request, 'account', None) + if not account: + user = getattr(request, 'user', None) + if user: + account = getattr(user, 'account', None) + + if not account: + return error_response( + error='Account not found', + status_code=status.HTTP_400_BAD_REQUEST, + request=request + ) + + # Get or create settings for account + settings = ModuleEnableSettings.get_or_create_for_account(account) + serializer = self.get_serializer(settings) + return success_response(data=serializer.data, request=request) + + def retrieve(self, request, pk=None): + """Get module enable settings for current account""" + account = getattr(request, 'account', None) + if not account: + user = getattr(request, 'user', None) + if user: + account = getattr(user, 'account', None) + + if not account: + return error_response( + error='Account not found', + status_code=status.HTTP_400_BAD_REQUEST, + request=request + ) + + # Get or create settings for account + settings = ModuleEnableSettings.get_or_create_for_account(account) + serializer = self.get_serializer(settings) + return success_response(data=serializer.data, request=request) + + def update(self, request, pk=None): + """Update module enable settings for current account""" + account = getattr(request, 'account', None) + if not account: + user = getattr(request, 'user', None) + if user: + account = getattr(user, 'account', None) + + if not account: + return error_response( + error='Account not found', + status_code=status.HTTP_400_BAD_REQUEST, + request=request + ) + + # Get or create settings for account + settings = ModuleEnableSettings.get_or_create_for_account(account) + serializer = self.get_serializer(settings, data=request.data, partial=True) + + if serializer.is_valid(): + serializer.save() + return success_response(data=serializer.data, request=request) + + return error_response( + error='Validation failed', + errors=serializer.errors, + status_code=status.HTTP_400_BAD_REQUEST, + request=request + ) + + def partial_update(self, request, pk=None): + """Partial update module enable settings""" + return self.update(request, pk) + + @extend_schema_view( list=extend_schema(tags=['System']), create=extend_schema(tags=['System']), diff --git a/backend/igny8_core/modules/system/urls.py b/backend/igny8_core/modules/system/urls.py index 5e19b49c..c03c49b3 100644 --- a/backend/igny8_core/modules/system/urls.py +++ b/backend/igny8_core/modules/system/urls.py @@ -7,7 +7,7 @@ from .views import AIPromptViewSet, AuthorProfileViewSet, StrategyViewSet, syste from .integration_views import IntegrationSettingsViewSet from .settings_views import ( SystemSettingsViewSet, AccountSettingsViewSet, UserSettingsViewSet, - ModuleSettingsViewSet, AISettingsViewSet + ModuleSettingsViewSet, ModuleEnableSettingsViewSet, AISettingsViewSet ) router = DefaultRouter() router.register(r'prompts', AIPromptViewSet, basename='prompts') @@ -17,6 +17,7 @@ router.register(r'settings/system', SystemSettingsViewSet, basename='system-sett router.register(r'settings/account', AccountSettingsViewSet, basename='account-settings') router.register(r'settings/user', UserSettingsViewSet, basename='user-settings') router.register(r'settings/modules', ModuleSettingsViewSet, basename='module-settings') +router.register(r'settings/modules/enable', ModuleEnableSettingsViewSet, basename='module-enable-settings') router.register(r'settings/ai', AISettingsViewSet, basename='ai-settings') # Custom URL patterns for integration settings - matching reference plugin structure