Enhance API structure and documentation: Added new tags for Account, Integration, Automation, Linker, Optimizer, and Publisher; updated billing endpoints for admin and customer; improved API reference documentation; fixed endpoint paths in frontend services.
This commit is contained in:
@@ -10,6 +10,7 @@ from django.contrib.auth import get_user_model
|
||||
from django.db.models import Q, Count, Sum
|
||||
from django.utils import timezone
|
||||
from datetime import timedelta
|
||||
from drf_spectacular.utils import extend_schema, extend_schema_view
|
||||
|
||||
from igny8_core.auth.models import Account
|
||||
from igny8_core.business.billing.models import CreditTransaction
|
||||
@@ -17,6 +18,10 @@ from igny8_core.business.billing.models import CreditTransaction
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
retrieve=extend_schema(tags=['Account']),
|
||||
partial_update=extend_schema(tags=['Account']),
|
||||
)
|
||||
class AccountSettingsViewSet(viewsets.ViewSet):
|
||||
"""Account settings management"""
|
||||
permission_classes = [IsAuthenticated]
|
||||
@@ -77,6 +82,11 @@ class AccountSettingsViewSet(viewsets.ViewSet):
|
||||
})
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
list=extend_schema(tags=['Account']),
|
||||
create=extend_schema(tags=['Account']),
|
||||
destroy=extend_schema(tags=['Account']),
|
||||
)
|
||||
class TeamManagementViewSet(viewsets.ViewSet):
|
||||
"""Team members management"""
|
||||
permission_classes = [IsAuthenticated]
|
||||
@@ -166,6 +176,9 @@ class TeamManagementViewSet(viewsets.ViewSet):
|
||||
)
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
overview=extend_schema(tags=['Account']),
|
||||
)
|
||||
class UsageAnalyticsViewSet(viewsets.ViewSet):
|
||||
"""Usage analytics and statistics"""
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@@ -8,7 +8,20 @@ from drf_spectacular.utils import extend_schema, OpenApiResponse
|
||||
from rest_framework import status
|
||||
|
||||
# Explicit tags we want to keep (from SPECTACULAR_SETTINGS)
|
||||
EXPLICIT_TAGS = {'Authentication', 'Planner', 'Writer', 'System', 'Billing'}
|
||||
EXPLICIT_TAGS = {
|
||||
'Authentication',
|
||||
'Planner',
|
||||
'Writer',
|
||||
'System',
|
||||
'Billing',
|
||||
'Account',
|
||||
'Automation',
|
||||
'Linker',
|
||||
'Optimizer',
|
||||
'Publisher',
|
||||
'Integration',
|
||||
'Admin Billing',
|
||||
}
|
||||
|
||||
|
||||
def postprocess_schema_filter_tags(result, generator, request, public):
|
||||
@@ -41,6 +54,20 @@ def postprocess_schema_filter_tags(result, generator, request, public):
|
||||
filtered_tags = ['System']
|
||||
elif '/billing/' in path or '/api/v1/billing/' in path:
|
||||
filtered_tags = ['Billing']
|
||||
elif '/account/' in path or '/api/v1/account/' in path:
|
||||
filtered_tags = ['Account']
|
||||
elif '/automation/' in path or '/api/v1/automation/' in path:
|
||||
filtered_tags = ['Automation']
|
||||
elif '/linker/' in path or '/api/v1/linker/' in path:
|
||||
filtered_tags = ['Linker']
|
||||
elif '/optimizer/' in path or '/api/v1/optimizer/' in path:
|
||||
filtered_tags = ['Optimizer']
|
||||
elif '/publisher/' in path or '/api/v1/publisher/' in path:
|
||||
filtered_tags = ['Publisher']
|
||||
elif '/integration/' in path or '/api/v1/integration/' in path:
|
||||
filtered_tags = ['Integration']
|
||||
elif '/admin/' in path or '/api/v1/admin/' in path:
|
||||
filtered_tags = ['Admin Billing']
|
||||
|
||||
operation['tags'] = filtered_tags
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ from rest_framework.response import Response
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils import timezone
|
||||
from drf_spectacular.utils import extend_schema
|
||||
|
||||
from igny8_core.business.automation.models import AutomationConfig, AutomationRun
|
||||
from igny8_core.business.automation.services import AutomationService
|
||||
@@ -30,6 +31,7 @@ class AutomationViewSet(viewsets.ViewSet):
|
||||
site = get_object_or_404(Site, id=site_id, account=request.user.account)
|
||||
return site, None
|
||||
|
||||
@extend_schema(tags=['Automation'])
|
||||
@action(detail=False, methods=['get'])
|
||||
def config(self, request):
|
||||
"""
|
||||
@@ -68,6 +70,7 @@ class AutomationViewSet(viewsets.ViewSet):
|
||||
'next_run_at': config.next_run_at,
|
||||
})
|
||||
|
||||
@extend_schema(tags=['Automation'])
|
||||
@action(detail=False, methods=['put'])
|
||||
def update_config(self, request):
|
||||
"""
|
||||
@@ -142,6 +145,7 @@ class AutomationViewSet(viewsets.ViewSet):
|
||||
'next_run_at': config.next_run_at,
|
||||
})
|
||||
|
||||
@extend_schema(tags=['Automation'])
|
||||
@action(detail=False, methods=['post'])
|
||||
def run_now(self, request):
|
||||
"""
|
||||
@@ -175,6 +179,7 @@ class AutomationViewSet(viewsets.ViewSet):
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
)
|
||||
|
||||
@extend_schema(tags=['Automation'])
|
||||
@action(detail=False, methods=['get'])
|
||||
def current_run(self, request):
|
||||
"""
|
||||
@@ -211,6 +216,7 @@ class AutomationViewSet(viewsets.ViewSet):
|
||||
}
|
||||
})
|
||||
|
||||
@extend_schema(tags=['Automation'])
|
||||
@action(detail=False, methods=['post'])
|
||||
def pause(self, request):
|
||||
"""
|
||||
@@ -234,6 +240,7 @@ class AutomationViewSet(viewsets.ViewSet):
|
||||
status=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
|
||||
@extend_schema(tags=['Automation'])
|
||||
@action(detail=False, methods=['post'])
|
||||
def resume(self, request):
|
||||
"""
|
||||
@@ -262,6 +269,7 @@ class AutomationViewSet(viewsets.ViewSet):
|
||||
status=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
|
||||
@extend_schema(tags=['Automation'])
|
||||
@action(detail=False, methods=['get'])
|
||||
def history(self, request):
|
||||
"""
|
||||
@@ -291,6 +299,7 @@ class AutomationViewSet(viewsets.ViewSet):
|
||||
]
|
||||
})
|
||||
|
||||
@extend_schema(tags=['Automation'])
|
||||
@action(detail=False, methods=['get'])
|
||||
def logs(self, request):
|
||||
"""
|
||||
@@ -323,6 +332,7 @@ class AutomationViewSet(viewsets.ViewSet):
|
||||
status=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
|
||||
@extend_schema(tags=['Automation'])
|
||||
@action(detail=False, methods=['get'])
|
||||
def estimate(self, request):
|
||||
"""
|
||||
@@ -342,6 +352,7 @@ class AutomationViewSet(viewsets.ViewSet):
|
||||
'sufficient': site.account.credits >= (estimated_credits * 1.2)
|
||||
})
|
||||
|
||||
@extend_schema(tags=['Automation'])
|
||||
@action(detail=False, methods=['get'])
|
||||
def pipeline_overview(self, request):
|
||||
"""
|
||||
@@ -504,6 +515,7 @@ class AutomationViewSet(viewsets.ViewSet):
|
||||
]
|
||||
})
|
||||
|
||||
@extend_schema(tags=['Automation'])
|
||||
@action(detail=False, methods=['get'], url_path='current_processing')
|
||||
def current_processing(self, request):
|
||||
"""
|
||||
@@ -547,6 +559,7 @@ class AutomationViewSet(viewsets.ViewSet):
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
)
|
||||
|
||||
@extend_schema(tags=['Automation'])
|
||||
@action(detail=False, methods=['post'], url_path='pause')
|
||||
def pause_automation(self, request):
|
||||
"""
|
||||
@@ -596,6 +609,7 @@ class AutomationViewSet(viewsets.ViewSet):
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
)
|
||||
|
||||
@extend_schema(tags=['Automation'])
|
||||
@action(detail=False, methods=['post'], url_path='resume')
|
||||
def resume_automation(self, request):
|
||||
"""
|
||||
@@ -649,6 +663,7 @@ class AutomationViewSet(viewsets.ViewSet):
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
)
|
||||
|
||||
@extend_schema(tags=['Automation'])
|
||||
@action(detail=False, methods=['post'], url_path='cancel')
|
||||
def cancel_automation(self, request):
|
||||
"""
|
||||
|
||||
@@ -11,14 +11,21 @@ from .views import (
|
||||
AdminBillingViewSet,
|
||||
AccountPaymentMethodViewSet,
|
||||
)
|
||||
from igny8_core.modules.billing.views import (
|
||||
CreditBalanceViewSet,
|
||||
CreditUsageViewSet,
|
||||
)
|
||||
|
||||
router = DefaultRouter()
|
||||
router.register(r'invoices', InvoiceViewSet, basename='invoice')
|
||||
router.register(r'payments', PaymentViewSet, basename='payment')
|
||||
router.register(r'credit-packages', CreditPackageViewSet, basename='credit-package')
|
||||
router.register(r'transactions', CreditTransactionViewSet, basename='transaction')
|
||||
router.register(r'admin', AdminBillingViewSet, basename='admin-billing')
|
||||
router.register(r'payment-methods', AccountPaymentMethodViewSet, basename='payment-method')
|
||||
# Canonical credits endpoints (unified billing)
|
||||
router.register(r'credits/balance', CreditBalanceViewSet, basename='credit-balance')
|
||||
router.register(r'credits/usage', CreditUsageViewSet, basename='credit-usage')
|
||||
router.register(r'credits/transactions', CreditTransactionViewSet, basename='credit-transactions')
|
||||
|
||||
urlpatterns = [
|
||||
# Country/config-driven available methods (legacy alias)
|
||||
|
||||
@@ -9,6 +9,7 @@ from rest_framework.permissions import IsAuthenticated
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.db import models
|
||||
from drf_spectacular.utils import extend_schema, extend_schema_view
|
||||
|
||||
from .models import (
|
||||
Invoice,
|
||||
@@ -366,6 +367,14 @@ class CreditTransactionViewSet(viewsets.ViewSet):
|
||||
})
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
invoices=extend_schema(tags=['Admin Billing']),
|
||||
payments=extend_schema(tags=['Admin Billing']),
|
||||
pending_payments=extend_schema(tags=['Admin Billing']),
|
||||
approve_payment=extend_schema(tags=['Admin Billing']),
|
||||
reject_payment=extend_schema(tags=['Admin Billing']),
|
||||
stats=extend_schema(tags=['Admin Billing']),
|
||||
)
|
||||
class AdminBillingViewSet(viewsets.ViewSet):
|
||||
"""Admin billing management"""
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
from django.urls import path
|
||||
from rest_framework.routers import DefaultRouter
|
||||
|
||||
from .views import AdminBillingViewSet
|
||||
from igny8_core.business.billing.views import (
|
||||
AdminBillingViewSet as BillingAdminViewSet,
|
||||
)
|
||||
|
||||
router = DefaultRouter()
|
||||
|
||||
@@ -9,6 +13,12 @@ urlpatterns = [
|
||||
path('users/', AdminBillingViewSet.as_view({'get': 'list_users'}), name='admin-users-list'),
|
||||
path('users/<int:user_id>/adjust-credits/', AdminBillingViewSet.as_view({'post': 'adjust_credits'}), name='admin-adjust-credits'),
|
||||
path('credit-costs/', AdminBillingViewSet.as_view({'get': 'list_credit_costs', 'post': 'update_credit_costs'}), name='admin-credit-costs'),
|
||||
# Unified admin billing endpoints (alias legacy /billing/admin/* under /admin/billing/*)
|
||||
path('billing/invoices/', BillingAdminViewSet.as_view({'get': 'invoices'}), name='admin-billing-invoices'),
|
||||
path('billing/payments/', BillingAdminViewSet.as_view({'get': 'payments'}), name='admin-billing-payments'),
|
||||
path('billing/pending_payments/', BillingAdminViewSet.as_view({'get': 'pending_payments'}), name='admin-billing-pending-payments'),
|
||||
path('billing/<int:pk>/approve_payment/', BillingAdminViewSet.as_view({'post': 'approve_payment'}), name='admin-billing-approve-payment'),
|
||||
path('billing/<int:pk>/reject_payment/', BillingAdminViewSet.as_view({'post': 'reject_payment'}), name='admin-billing-reject-payment'),
|
||||
]
|
||||
|
||||
urlpatterns += router.urls
|
||||
|
||||
@@ -20,6 +20,9 @@ urlpatterns = [
|
||||
path('', include(router.urls)),
|
||||
# User-facing billing overview
|
||||
path('account_balance/', BillingOverviewViewSet.as_view({'get': 'account_balance'}), name='account-balance'),
|
||||
# Canonical credit balance endpoint
|
||||
path('credits/balance/', CreditBalanceViewSet.as_view({'get': 'list'}), name='credit-balance-canonical'),
|
||||
# Explicit list endpoints
|
||||
path('transactions/', CreditTransactionViewSet.as_view({'get': 'list'}), name='transactions'),
|
||||
path('usage/', CreditUsageViewSet.as_view({'get': 'list'}), name='usage'),
|
||||
# Admin billing endpoints
|
||||
|
||||
@@ -26,7 +26,7 @@ from .exceptions import InsufficientCreditsError
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
list=extend_schema(tags=['Billing']),
|
||||
list=extend_schema(tags=['Billing'], summary='Get credit balance'),
|
||||
)
|
||||
class CreditBalanceViewSet(viewsets.ViewSet):
|
||||
"""
|
||||
@@ -38,8 +38,7 @@ class CreditBalanceViewSet(viewsets.ViewSet):
|
||||
throttle_scope = 'billing'
|
||||
throttle_classes = [DebugScopedRateThrottle]
|
||||
|
||||
@action(detail=False, methods=['get'])
|
||||
def balance(self, request):
|
||||
def list(self, request):
|
||||
"""Get current credit balance and usage"""
|
||||
account = getattr(request, 'account', None)
|
||||
if not account:
|
||||
@@ -125,6 +124,7 @@ class CreditUsageViewSet(AccountModelViewSet):
|
||||
|
||||
return queryset.order_by('-created_at')
|
||||
|
||||
@extend_schema(tags=['Billing'], summary='Get usage summary')
|
||||
@action(detail=False, methods=['get'])
|
||||
def summary(self, request):
|
||||
"""Get usage summary for date range"""
|
||||
@@ -214,6 +214,7 @@ class CreditUsageViewSet(AccountModelViewSet):
|
||||
serializer = UsageSummarySerializer(data)
|
||||
return success_response(data=serializer.data, request=request)
|
||||
|
||||
@extend_schema(tags=['Billing'], summary='Get usage limits')
|
||||
@action(detail=False, methods=['get'], url_path='limits', url_name='limits')
|
||||
def limits(self, request):
|
||||
"""
|
||||
@@ -434,6 +435,13 @@ class BillingOverviewViewSet(viewsets.ViewSet):
|
||||
return Response(data)
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
stats=extend_schema(tags=['Admin Billing'], summary='Admin billing stats'),
|
||||
list_users=extend_schema(tags=['Admin Billing'], summary='List users with credit info'),
|
||||
adjust_credits=extend_schema(tags=['Admin Billing'], summary='Adjust user credits'),
|
||||
list_credit_costs=extend_schema(tags=['Admin Billing'], summary='List credit cost configurations'),
|
||||
update_credit_costs=extend_schema(tags=['Admin Billing'], summary='Update credit cost configurations'),
|
||||
)
|
||||
class AdminBillingViewSet(viewsets.ViewSet):
|
||||
"""Admin-only billing management API"""
|
||||
permission_classes = [IsAuthenticatedAndActive, permissions.IsAdminUser]
|
||||
|
||||
@@ -6,6 +6,7 @@ from rest_framework import status
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
from django.utils import timezone
|
||||
from drf_spectacular.utils import extend_schema, extend_schema_view
|
||||
|
||||
from igny8_core.api.base import SiteSectorModelViewSet
|
||||
from igny8_core.api.permissions import IsAuthenticatedAndActive, IsEditorOrAbove
|
||||
@@ -21,6 +22,14 @@ import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
list=extend_schema(tags=['Integration']),
|
||||
create=extend_schema(tags=['Integration']),
|
||||
retrieve=extend_schema(tags=['Integration']),
|
||||
update=extend_schema(tags=['Integration']),
|
||||
partial_update=extend_schema(tags=['Integration']),
|
||||
destroy=extend_schema(tags=['Integration']),
|
||||
)
|
||||
class IntegrationViewSet(SiteSectorModelViewSet):
|
||||
"""
|
||||
ViewSet for SiteIntegration model.
|
||||
@@ -88,6 +97,7 @@ class IntegrationViewSet(SiteSectorModelViewSet):
|
||||
|
||||
return SiteIntegrationSerializer
|
||||
|
||||
@extend_schema(tags=['Integration'])
|
||||
@action(detail=True, methods=['post'])
|
||||
def test_connection(self, request, pk=None):
|
||||
"""
|
||||
@@ -118,6 +128,7 @@ class IntegrationViewSet(SiteSectorModelViewSet):
|
||||
def allow_request(self, request, view):
|
||||
return True
|
||||
|
||||
@extend_schema(tags=['Integration'])
|
||||
@action(detail=False, methods=['post'], url_path='test-connection',
|
||||
permission_classes=[AllowAny], throttle_classes=[NoThrottle])
|
||||
def test_connection_collection(self, request):
|
||||
@@ -221,6 +232,7 @@ class IntegrationViewSet(SiteSectorModelViewSet):
|
||||
logger.info(f"[IntegrationViewSet] Deleted integration {integration.id} due to failed connection test")
|
||||
return error_response(result.get('message', 'Connection test failed'), None, status.HTTP_400_BAD_REQUEST, request)
|
||||
|
||||
@extend_schema(tags=['Integration'])
|
||||
@action(detail=True, methods=['post'])
|
||||
def sync(self, request, pk=None):
|
||||
"""
|
||||
@@ -252,6 +264,7 @@ class IntegrationViewSet(SiteSectorModelViewSet):
|
||||
response_status = status.HTTP_200_OK if result.get('success') else status.HTTP_400_BAD_REQUEST
|
||||
return success_response(result, request=request, status_code=response_status)
|
||||
|
||||
@extend_schema(tags=['Integration'])
|
||||
@action(detail=True, methods=['get'])
|
||||
def sync_status(self, request, pk=None):
|
||||
"""
|
||||
|
||||
@@ -11,6 +11,7 @@ from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.utils.decorators import method_decorator
|
||||
from drf_spectacular.utils import extend_schema, extend_schema_view
|
||||
|
||||
from igny8_core.api.base import SiteSectorModelViewSet
|
||||
from igny8_core.api.permissions import IsAuthenticatedAndActive, IsEditorOrAbove
|
||||
@@ -20,6 +21,14 @@ from igny8_core.business.publishing.models import PublishingRecord, DeploymentRe
|
||||
from igny8_core.business.publishing.services.publisher_service import PublisherService
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
list=extend_schema(tags=['Publisher']),
|
||||
create=extend_schema(tags=['Publisher']),
|
||||
retrieve=extend_schema(tags=['Publisher']),
|
||||
update=extend_schema(tags=['Publisher']),
|
||||
partial_update=extend_schema(tags=['Publisher']),
|
||||
destroy=extend_schema(tags=['Publisher']),
|
||||
)
|
||||
class PublishingRecordViewSet(SiteSectorModelViewSet):
|
||||
"""
|
||||
ViewSet for PublishingRecord model.
|
||||
@@ -41,6 +50,14 @@ class PublishingRecordViewSet(SiteSectorModelViewSet):
|
||||
return PublishingRecordSerializer
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
list=extend_schema(tags=['Publisher']),
|
||||
create=extend_schema(tags=['Publisher']),
|
||||
retrieve=extend_schema(tags=['Publisher']),
|
||||
update=extend_schema(tags=['Publisher']),
|
||||
partial_update=extend_schema(tags=['Publisher']),
|
||||
destroy=extend_schema(tags=['Publisher']),
|
||||
)
|
||||
class DeploymentRecordViewSet(SiteSectorModelViewSet):
|
||||
"""
|
||||
ViewSet for DeploymentRecord model.
|
||||
@@ -63,6 +80,7 @@ class DeploymentRecordViewSet(SiteSectorModelViewSet):
|
||||
return DeploymentRecordSerializer
|
||||
|
||||
|
||||
@extend_schema_view()
|
||||
class PublisherViewSet(viewsets.ViewSet):
|
||||
"""
|
||||
Publisher actions for publishing content.
|
||||
@@ -76,6 +94,7 @@ class PublisherViewSet(viewsets.ViewSet):
|
||||
super().__init__(**kwargs)
|
||||
self.publisher_service = PublisherService()
|
||||
|
||||
@extend_schema(tags=['Publisher'])
|
||||
@action(detail=False, methods=['post'], url_path='publish')
|
||||
def publish(self, request):
|
||||
"""
|
||||
|
||||
@@ -1580,12 +1580,12 @@ class ContentViewSet(SiteSectorModelViewSet):
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
list=extend_schema(tags=['Writer - Taxonomies']),
|
||||
create=extend_schema(tags=['Writer - Taxonomies']),
|
||||
retrieve=extend_schema(tags=['Writer - Taxonomies']),
|
||||
update=extend_schema(tags=['Writer - Taxonomies']),
|
||||
partial_update=extend_schema(tags=['Writer - Taxonomies']),
|
||||
destroy=extend_schema(tags=['Writer - Taxonomies']),
|
||||
list=extend_schema(tags=['Writer']),
|
||||
create=extend_schema(tags=['Writer']),
|
||||
retrieve=extend_schema(tags=['Writer']),
|
||||
update=extend_schema(tags=['Writer']),
|
||||
partial_update=extend_schema(tags=['Writer']),
|
||||
destroy=extend_schema(tags=['Writer']),
|
||||
)
|
||||
class ContentTaxonomyViewSet(SiteSectorModelViewSet):
|
||||
"""
|
||||
|
||||
@@ -352,12 +352,32 @@ SPECTACULAR_SETTINGS = {
|
||||
# Tag configuration - prevent auto-generation and use explicit tags
|
||||
'TAGS': [
|
||||
{'name': 'Authentication', 'description': 'User authentication and registration'},
|
||||
{'name': 'Account', 'description': 'Account settings, team, and usage analytics'},
|
||||
{'name': 'Integration', 'description': 'Site integrations and sync'},
|
||||
{'name': 'System', 'description': 'Settings, prompts, and integrations'},
|
||||
{'name': 'Admin Billing', 'description': 'Admin-only billing management'},
|
||||
{'name': 'Billing', 'description': 'Credits, usage, and transactions'},
|
||||
{'name': 'Planner', 'description': 'Keywords, clusters, and content ideas'},
|
||||
{'name': 'Writer', 'description': 'Tasks, content, and images'},
|
||||
{'name': 'System', 'description': 'Settings, prompts, and integrations'},
|
||||
{'name': 'Billing', 'description': 'Credits, usage, and transactions'},
|
||||
{'name': 'Automation', 'description': 'Automation configuration and runs'},
|
||||
{'name': 'Linker', 'description': 'Internal linking operations'},
|
||||
{'name': 'Optimizer', 'description': 'Content optimization operations'},
|
||||
{'name': 'Publisher', 'description': 'Publishing records and deployments'},
|
||||
],
|
||||
'TAGS_ORDER': [
|
||||
'Authentication',
|
||||
'Account',
|
||||
'Integration',
|
||||
'System',
|
||||
'Admin Billing',
|
||||
'Billing',
|
||||
'Planner',
|
||||
'Writer',
|
||||
'Automation',
|
||||
'Linker',
|
||||
'Optimizer',
|
||||
'Publisher',
|
||||
],
|
||||
'TAGS_ORDER': ['Authentication', 'Planner', 'Writer', 'System', 'Billing'],
|
||||
# Postprocessing hook to filter out auto-generated tags
|
||||
'POSTPROCESSING_HOOKS': ['igny8_core.api.schema_extensions.postprocess_schema_filter_tags'],
|
||||
|
||||
|
||||
Reference in New Issue
Block a user