feat(integrations): архитектура включения/выключения интеграций

- Удалена лишняя модель IntegrationConfig из system_settings
- Singleton-паттерн: одна запись на интеграцию с is_active тумблером
- Добавлено шифрование токенов (EncryptedCharField с Fernet AES-128)
- UI: тумблеры слева, форма настроек справа
- API endpoints: toggle, settings, form_data
- Модель Recommerce: store_url + api_token (x-auth-token)
- Модель WooCommerce: store_url + consumer_key/secret

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-12 00:29:04 +03:00
parent 4629369823
commit 37394121e1
14 changed files with 804 additions and 200 deletions

View File

@@ -1,44 +1,32 @@
from django.contrib import admin
from system_settings.models import IntegrationConfig
from .models import RecommerceIntegration, WooCommerceIntegration
@admin.register(IntegrationConfig)
class IntegrationConfigAdmin(admin.ModelAdmin):
"""Админка для настроек интеграций (тумблеров)"""
list_display = ['get_integration_id_display', 'is_enabled', 'last_sync_at', 'updated_at']
list_filter = ['is_enabled', 'integration_id']
search_fields = ['integration_id']
list_editable = ['is_enabled']
@admin.register(RecommerceIntegration)
class RecommerceIntegrationAdmin(admin.ModelAdmin):
"""Админка для Recommerce интеграции"""
list_display = ['__str__', 'is_active', 'is_configured', 'updated_at']
list_filter = ['is_active']
readonly_fields = ['created_at', 'updated_at']
def has_add_permission(self, request):
"""Запретить добавление новых интеграций вручную"""
return False
def has_delete_permission(self, request, obj=None):
"""Запретить удаление интеграций"""
return False
fieldsets = (
('Основное', {'fields': ('name', 'is_active')}),
('API настройки', {'fields': ('store_url', 'api_token')}),
('Синхронизация', {'fields': ('auto_sync_products', 'import_orders')}),
('Служебное', {'fields': ('created_at', 'updated_at'), 'classes': ('collapse',)}),
)
# Регистрация конкретных интеграций (когда будут готовы):
#
# @admin.register(WooCommerceIntegration)
# class WooCommerceIntegrationAdmin(admin.ModelAdmin):
# list_display = ['name', 'store_url', 'is_active', 'is_configured', 'updated_at']
# list_filter = ['is_active', 'auto_sync_products']
# fieldsets = (
# ('Основное', {'fields': ('name', 'is_active')}),
# ('API настройки', {'fields': ('store_url', 'consumer_key', 'consumer_secret')}),
# ('Синхронизация', {'fields': ('auto_sync_products', 'import_orders')}),
# )
#
#
# @admin.register(RecommerceIntegration)
# class RecommerceIntegrationAdmin(admin.ModelAdmin):
# list_display = ['name', 'merchant_id', 'is_active', 'is_configured', 'updated_at']
# list_filter = ['is_active', 'sync_prices', 'sync_stock']
# fieldsets = (
# ('Основное', {'fields': ('name', 'is_active')}),
# ('API настройки', {'fields': ('store_url', 'api_endpoint', 'api_token', 'merchant_id')}),
# ('Синхронизация', {'fields': ('auto_sync_products', 'import_orders', 'sync_prices', 'sync_stock')}),
# )
@admin.register(WooCommerceIntegration)
class WooCommerceIntegrationAdmin(admin.ModelAdmin):
"""Админка для WooCommerce интеграции"""
list_display = ['__str__', 'is_active', 'is_configured', 'updated_at']
list_filter = ['is_active']
readonly_fields = ['created_at', 'updated_at']
fieldsets = (
('Основное', {'fields': ('name', 'is_active')}),
('API настройки', {'fields': ('store_url', 'consumer_key', 'consumer_secret', 'api_version')}),
('Синхронизация', {'fields': ('auto_sync_products', 'import_orders')}),
('Служебное', {'fields': ('created_at', 'updated_at'), 'classes': ('collapse',)}),
)