Files
octopus/myproject/integrations/models/base.py
Andrey Smakotin 4450e34497 feat(integrations): добавлен фундамент для интеграций с внешними сервисами
- Создано приложение integrations с базовой архитектурой
- BaseIntegration (абстрактная модель) для всех интеграций
- BaseIntegrationService (абстрактный сервисный класс)
- IntegrationConfig модель для тумблеров в system_settings
- Добавлена вкладка "Интеграции" в системные настройки
- Заготовка UI с тумблерами для включения интеграций

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 23:02:42 +03:00

94 lines
2.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from django.db import models
from django.core.exceptions import ValidationError
from abc import ABC, abstractmethod
class IntegrationType(models.TextChoices):
MARKETPLACE = 'marketplace', 'Маркетплейс'
PAYMENT = 'payment', 'Платёжная система'
SHIPPING = 'shipping', 'Служба доставки'
class BaseIntegration(models.Model):
"""
Абстрактный базовый класс для всех интеграций.
Содержит общие поля и логику валидации.
"""
integration_type = models.CharField(
max_length=20,
choices=IntegrationType.choices,
editable=False,
verbose_name="Тип интеграции"
)
is_active = models.BooleanField(
default=True,
verbose_name="Активна",
db_index=True,
help_text="Интеграция используется только если включена здесь и в системных настройках"
)
name = models.CharField(
max_length=100,
verbose_name="Название",
help_text="Произвольное название для удобства"
)
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name="Дата создания"
)
updated_at = models.DateTimeField(
auto_now=True,
verbose_name="Дата обновления"
)
# Общие credential поля (можно переопределить в наследниках)
api_key = models.CharField(
max_length=255,
blank=True,
verbose_name="API ключ",
help_text="Будет зашифрован при сохранении"
)
api_secret = models.CharField(
max_length=255,
blank=True,
verbose_name="API секрет",
help_text="Будет зашифрован при сохранении"
)
# Дополнительные настройки в JSON для гибкости
extra_config = models.JSONField(
default=dict,
blank=True,
verbose_name="Доп. настройки"
)
class Meta:
abstract = True
ordering = ['-is_active', 'name']
indexes = [
models.Index(fields=['is_active', 'integration_type']),
]
def __str__(self):
return f"{self.get_integration_type_display()}: {self.name}"
@property
def is_configured(self) -> bool:
"""
Проверить, есть ли необходимые credentials.
Можно переопределить в наследниках.
"""
return bool(self.api_key)
def clean(self):
"""Валидацияcredentials"""
if self.is_active and not self.is_configured:
raise ValidationError({
'api_key': 'API ключ обязателен для активной интеграции'
})