Phase 0: Foundation & Credit System - Initial implementation
- Updated CREDIT_COSTS constants to Phase 0 format with new operations - Enhanced CreditService with get_credit_cost() method and operation_type support - Created AccountModuleSettings model for module enable/disable functionality - Added AccountModuleSettingsSerializer and ViewSet - Registered module settings API endpoint: /api/v1/system/settings/account-modules/ - Maintained backward compatibility with existing credit system
This commit is contained in:
@@ -6,7 +6,7 @@ from igny8_core.auth.models import AccountBaseModel
|
||||
|
||||
# Import settings models
|
||||
from .settings_models import (
|
||||
SystemSettings, AccountSettings, UserSettings, ModuleSettings, AISettings
|
||||
SystemSettings, AccountSettings, UserSettings, ModuleSettings, AccountModuleSettings, AISettings
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -92,6 +92,61 @@ class ModuleSettings(BaseSettings):
|
||||
return f"ModuleSetting: {self.module_name} - {self.key}"
|
||||
|
||||
|
||||
class AccountModuleSettings(AccountBaseModel):
|
||||
"""
|
||||
Account-level module enable/disable settings.
|
||||
Phase 0: Credit System - Module Settings
|
||||
"""
|
||||
# Module enable/disable flags
|
||||
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")
|
||||
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
db_table = 'igny8_account_module_settings'
|
||||
verbose_name = 'Account Module Settings'
|
||||
verbose_name_plural = 'Account Module Settings'
|
||||
# One settings record per account
|
||||
constraints = [
|
||||
models.UniqueConstraint(fields=['account'], name='unique_account_module_settings')
|
||||
]
|
||||
indexes = [
|
||||
models.Index(fields=['account']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
account = getattr(self, 'account', None)
|
||||
return f"ModuleSettings: {account.name if account else 'No Account'}"
|
||||
|
||||
@classmethod
|
||||
def get_or_create_for_account(cls, account):
|
||||
"""Get or create module settings for an account"""
|
||||
settings, created = cls.objects.get_or_create(account=account)
|
||||
return settings
|
||||
|
||||
def is_module_enabled(self, module_name):
|
||||
"""Check if a module is enabled"""
|
||||
module_map = {
|
||||
'planner': self.planner_enabled,
|
||||
'writer': self.writer_enabled,
|
||||
'thinker': self.thinker_enabled,
|
||||
'automation': self.automation_enabled,
|
||||
'site_builder': self.site_builder_enabled,
|
||||
'linker': self.linker_enabled,
|
||||
'optimizer': self.optimizer_enabled,
|
||||
'publisher': self.publisher_enabled,
|
||||
}
|
||||
return module_map.get(module_name, True) # Default to enabled if module not found
|
||||
|
||||
|
||||
# AISettings extends IntegrationSettings (which already exists)
|
||||
# We'll create it as a separate model that can reference IntegrationSettings
|
||||
class AISettings(AccountBaseModel):
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Serializers for Settings Models
|
||||
"""
|
||||
from rest_framework import serializers
|
||||
from .settings_models import SystemSettings, AccountSettings, UserSettings, ModuleSettings, AISettings
|
||||
from .settings_models import SystemSettings, AccountSettings, UserSettings, ModuleSettings, AccountModuleSettings, AISettings
|
||||
from .validators import validate_settings_schema
|
||||
|
||||
|
||||
@@ -58,6 +58,18 @@ class ModuleSettingsSerializer(serializers.ModelSerializer):
|
||||
return value
|
||||
|
||||
|
||||
class AccountModuleSettingsSerializer(serializers.ModelSerializer):
|
||||
"""Serializer for Account Module Settings (Phase 0)"""
|
||||
class Meta:
|
||||
model = AccountModuleSettings
|
||||
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
|
||||
|
||||
@@ -13,10 +13,10 @@ from igny8_core.api.authentication import JWTAuthentication, CSRFExemptSessionAu
|
||||
from igny8_core.api.pagination import CustomPageNumberPagination
|
||||
from igny8_core.api.throttles import DebugScopedRateThrottle
|
||||
from igny8_core.api.permissions import IsAuthenticatedAndActive, HasTenantAccess, IsAdminOrOwner
|
||||
from .settings_models import SystemSettings, AccountSettings, UserSettings, ModuleSettings, AISettings
|
||||
from .settings_models import SystemSettings, AccountSettings, UserSettings, ModuleSettings, AccountModuleSettings, AISettings
|
||||
from .settings_serializers import (
|
||||
SystemSettingsSerializer, AccountSettingsSerializer, UserSettingsSerializer,
|
||||
ModuleSettingsSerializer, AISettingsSerializer
|
||||
ModuleSettingsSerializer, AccountModuleSettingsSerializer, AISettingsSerializer
|
||||
)
|
||||
|
||||
|
||||
@@ -276,6 +276,75 @@ 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 AccountModuleSettingsViewSet(AccountModelViewSet):
|
||||
"""
|
||||
ViewSet for managing account module enable/disable settings.
|
||||
Phase 0: Credit System - Module Settings
|
||||
One settings record per account (get_or_create pattern)
|
||||
"""
|
||||
queryset = AccountModuleSettings.objects.all()
|
||||
serializer_class = AccountModuleSettingsSerializer
|
||||
permission_classes = [IsAuthenticatedAndActive, HasTenantAccess]
|
||||
authentication_classes = [JWTAuthentication, CSRFExemptSessionAuthentication]
|
||||
pagination_class = CustomPageNumberPagination
|
||||
throttle_scope = 'system'
|
||||
throttle_classes = [DebugScopedRateThrottle]
|
||||
|
||||
def get_queryset(self):
|
||||
"""Get module settings for current account"""
|
||||
queryset = super().get_queryset()
|
||||
return queryset.filter(account=self.request.account)
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
"""Get or create module settings for account"""
|
||||
account = request.account
|
||||
settings = AccountModuleSettings.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 settings for account"""
|
||||
account = request.account
|
||||
try:
|
||||
settings = AccountModuleSettings.objects.get(account=account, pk=pk)
|
||||
except AccountModuleSettings.DoesNotExist:
|
||||
# Create if doesn't exist
|
||||
settings = AccountModuleSettings.get_or_create_for_account(account)
|
||||
serializer = self.get_serializer(settings)
|
||||
return success_response(data=serializer.data, request=request)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
"""Set account automatically"""
|
||||
account = getattr(self.request, 'account', None)
|
||||
if not account:
|
||||
user = getattr(self.request, 'user', None)
|
||||
if user:
|
||||
account = getattr(user, 'account', None)
|
||||
|
||||
if not account:
|
||||
from rest_framework.exceptions import ValidationError
|
||||
raise ValidationError("Account is required")
|
||||
|
||||
serializer.save(account=account)
|
||||
|
||||
@action(detail=False, methods=['get'], url_path='check/(?P<module_name>[^/.]+)', url_name='check_module')
|
||||
def check_module(self, request, module_name=None):
|
||||
"""Check if a specific module is enabled"""
|
||||
account = request.account
|
||||
settings = AccountModuleSettings.get_or_create_for_account(account)
|
||||
is_enabled = settings.is_module_enabled(module_name)
|
||||
return success_response(
|
||||
data={'module_name': module_name, 'enabled': is_enabled},
|
||||
request=request
|
||||
)
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
list=extend_schema(tags=['System']),
|
||||
create=extend_schema(tags=['System']),
|
||||
|
||||
@@ -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, AccountModuleSettingsViewSet, 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/account-modules', AccountModuleSettingsViewSet, basename='account-module-settings')
|
||||
router.register(r'settings/ai', AISettingsViewSet, basename='ai-settings')
|
||||
|
||||
# Custom URL patterns for integration settings - matching reference plugin structure
|
||||
|
||||
Reference in New Issue
Block a user