Fix admin API gaps for users, exchange checks, and parser logs
This commit is contained in:
@@ -29,6 +29,27 @@ class ExchangeConnectionService:
|
||||
"parsers.FinancialReportLine",
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def test_connection_payload(cls, **payload) -> dict[str, str]:
|
||||
"""Проверить подключение и структуру без сохранения в БД."""
|
||||
connection = ExchangeConnection(is_active=False, **payload)
|
||||
alias = cls.test_connection(connection)
|
||||
cls.validate_target_structure(
|
||||
connection=connection,
|
||||
alias=alias,
|
||||
schema_name=connection.schema_name,
|
||||
)
|
||||
|
||||
with suppress(Exception):
|
||||
connections[alias].close()
|
||||
with suppress(Exception):
|
||||
connections.databases.pop(alias, None)
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"message": "Подключение и структура целевой БД валидны.",
|
||||
}
|
||||
|
||||
@classmethod
|
||||
@transaction.atomic
|
||||
def create_active_connection_and_prepare(cls, **payload) -> ExchangeConnection:
|
||||
@@ -456,4 +477,7 @@ class ExchangeConnectionService:
|
||||
) -> None:
|
||||
connection.last_checked_at = timezone.now()
|
||||
connection.last_error = error_message
|
||||
connection.save(update_fields=["last_checked_at", "last_error", "updated_at"])
|
||||
if connection.pk:
|
||||
connection.save(
|
||||
update_fields=["last_checked_at", "last_error", "updated_at"]
|
||||
)
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
"""URL конфигурация приложения exchange."""
|
||||
|
||||
from apps.exchange.views import ExchangeConnectionListCreateView, ExchangeCopyDataView
|
||||
from apps.exchange.views import (
|
||||
ExchangeConnectionListCreateView,
|
||||
ExchangeConnectionTestView,
|
||||
ExchangeCopyDataView,
|
||||
)
|
||||
from django.urls import path
|
||||
|
||||
app_name = "exchange"
|
||||
@@ -9,6 +13,11 @@ exchange_urlpatterns = [
|
||||
path(
|
||||
"connections/", ExchangeConnectionListCreateView.as_view(), name="connections"
|
||||
),
|
||||
path(
|
||||
"connections/test/",
|
||||
ExchangeConnectionTestView.as_view(),
|
||||
name="connections-test",
|
||||
),
|
||||
path("copy/", ExchangeCopyDataView.as_view(), name="copy"),
|
||||
]
|
||||
|
||||
|
||||
@@ -78,6 +78,48 @@ class ExchangeConnectionListCreateView(APIView):
|
||||
return api_created_response(output.data)
|
||||
|
||||
|
||||
class ExchangeConnectionTestView(APIView):
|
||||
"""API проверки подключения к внешней БД без сохранения."""
|
||||
|
||||
permission_classes = [IsAdminUser]
|
||||
|
||||
@swagger_auto_schema(
|
||||
tags=[EXCHANGE_TAG],
|
||||
operation_summary="Проверить подключение",
|
||||
operation_description=(
|
||||
"Проверяет подключение и структуру целевой БД без сохранения "
|
||||
"настроек подключения."
|
||||
),
|
||||
request_body=ExchangeConnectionCreateSerializer,
|
||||
responses={
|
||||
200: openapi.Response(
|
||||
description="Проверка успешна",
|
||||
schema=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
"status": openapi.Schema(type=openapi.TYPE_STRING),
|
||||
"message": openapi.Schema(type=openapi.TYPE_STRING),
|
||||
},
|
||||
),
|
||||
),
|
||||
400: CommonResponses.BAD_REQUEST,
|
||||
**ErrorResponses.ADMIN,
|
||||
},
|
||||
)
|
||||
def post(self, request):
|
||||
serializer = ExchangeConnectionCreateSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
try:
|
||||
result = ExchangeConnectionService.test_connection_payload(
|
||||
**serializer.validated_data
|
||||
)
|
||||
except ExchangeServiceError as exc:
|
||||
raise ValidationError({"connection": str(exc)}) from exc
|
||||
|
||||
return api_response(result, status_code=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class ExchangeCopyDataView(APIView):
|
||||
"""API запуска копирования данных в целевую БД."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user