Align frontend API contracts

This commit is contained in:
2026-03-22 13:21:02 +01:00
parent 0da5b4abe2
commit e639b3c792
35 changed files with 1362 additions and 205 deletions

View File

@@ -61,10 +61,6 @@ class ExchangeConnectionSerializer(serializers.ModelSerializer):
"database_name",
"schema_name",
"is_active",
"last_checked_at",
"last_error",
"created_at",
"updated_at",
]
read_only_fields = fields
@@ -119,19 +115,12 @@ class ExchangePeriodicTaskSerializer(serializers.ModelSerializer):
crontab_day_of_week = serializers.SerializerMethodField()
crontab_day_of_month = serializers.SerializerMethodField()
crontab_month_of_year = serializers.SerializerMethodField()
crontab_timezone = serializers.SerializerMethodField()
mode = serializers.SerializerMethodField()
table = serializers.SerializerMethodField()
tables = serializers.SerializerMethodField()
truncate_before_copy = serializers.SerializerMethodField()
notify_on_error = serializers.SerializerMethodField()
class Meta:
model = PeriodicTask
fields = [
"id",
"name",
"description",
"enabled",
"schedule_type",
"interval_every",
"interval_period",
@@ -140,14 +129,7 @@ class ExchangePeriodicTaskSerializer(serializers.ModelSerializer):
"crontab_day_of_week",
"crontab_day_of_month",
"crontab_month_of_year",
"crontab_timezone",
"mode",
"table",
"tables",
"truncate_before_copy",
"last_run_at",
"total_run_count",
"date_changed",
"notify_on_error",
]
read_only_fields = fields
@@ -179,23 +161,8 @@ class ExchangePeriodicTaskSerializer(serializers.ModelSerializer):
def get_crontab_month_of_year(self, obj: PeriodicTask) -> str | None:
return obj.crontab.month_of_year if obj.crontab_id else None
def get_crontab_timezone(self, obj: PeriodicTask) -> str | None:
if not obj.crontab_id:
return None
timezone = obj.crontab.timezone
return str(timezone) if timezone is not None else None
def get_mode(self, obj: PeriodicTask) -> str | None:
return get_periodic_task_payload(obj).get("mode")
def get_table(self, obj: PeriodicTask) -> str | None:
return get_periodic_task_payload(obj).get("table")
def get_tables(self, obj: PeriodicTask) -> list[str] | None:
return get_periodic_task_payload(obj).get("tables")
def get_truncate_before_copy(self, obj: PeriodicTask) -> bool | None:
return get_periodic_task_payload(obj).get("truncate_before_copy")
def get_notify_on_error(self, obj: PeriodicTask) -> bool:
return bool(get_periodic_task_payload(obj).get("notify_on_error", False))
class ExchangePeriodicTaskUpsertSerializer(serializers.Serializer):
@@ -231,6 +198,7 @@ class ExchangePeriodicTaskUpsertSerializer(serializers.Serializer):
allow_empty=False,
)
truncate_before_copy = serializers.BooleanField(required=False)
notify_on_error = serializers.BooleanField(required=False)
def validate(self, attrs: dict[str, Any]) -> dict[str, Any]:
if not self.instance and "name" not in attrs:
@@ -270,6 +238,10 @@ class ExchangePeriodicTaskUpsertSerializer(serializers.Serializer):
"truncate_before_copy",
current_payload.get("truncate_before_copy", True),
)
notify_on_error = attrs.get(
"notify_on_error",
current_payload.get("notify_on_error", False),
)
if "mode" in attrs and attrs["mode"] != "single" and "table" not in attrs:
table = None
@@ -286,6 +258,7 @@ class ExchangePeriodicTaskUpsertSerializer(serializers.Serializer):
"table": table,
"tables": tables,
"truncate_before_copy": truncate_before_copy,
"notify_on_error": notify_on_error,
}
def _build_schedule(

View File

@@ -51,7 +51,7 @@ class ExchangeConnectionService:
return {
"status": "success",
"message": "Подключение и структура целевой БД валидны.",
"message": "Подключение проверено. Соединение и структура БД валидны.",
}
@classmethod

View File

@@ -3,7 +3,7 @@
from contextlib import suppress
from apps.core.openapi import CommonResponses, ErrorResponses, swagger_tag
from apps.core.response import api_created_response, api_response
from apps.core.response import api_response
from apps.core.services import BackgroundJobService
from apps.exchange.models import ExchangeConnection
from apps.exchange.serializers import (
@@ -26,6 +26,7 @@ from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.exceptions import ValidationError
from rest_framework.permissions import IsAdminUser
from rest_framework.response import Response
from rest_framework.views import APIView
EXCHANGE_TAG = swagger_tag("Обмен данными", "exchange")
@@ -53,7 +54,7 @@ class ExchangeConnectionListCreateView(APIView):
"-is_active", "-created_at"
)
serializer = ExchangeConnectionSerializer(queryset, many=True)
return api_response(serializer.data, status_code=status.HTTP_200_OK)
return Response({"results": serializer.data}, status=status.HTTP_200_OK)
@swagger_auto_schema(
tags=[EXCHANGE_TAG],
@@ -82,7 +83,7 @@ class ExchangeConnectionListCreateView(APIView):
raise ValidationError({"connection": str(exc)}) from exc
output = ExchangeConnectionSerializer(connection)
return api_created_response(output.data)
return Response(output.data, status=status.HTTP_201_CREATED)
class ExchangeConnectionTestView(APIView):
@@ -124,7 +125,13 @@ class ExchangeConnectionTestView(APIView):
except ExchangeServiceError as exc:
raise ValidationError({"connection": str(exc)}) from exc
return api_response(result, status_code=status.HTTP_200_OK)
return Response(
{
"success": result.get("status") == "success",
"message": result["message"],
},
status=status.HTTP_200_OK,
)
class ExchangeCopyDataView(APIView):
@@ -232,7 +239,7 @@ class ExchangePeriodicTaskListCreateView(APIView):
def get(self, request):
queryset = ExchangePeriodicTaskService.get_queryset()
serializer = ExchangePeriodicTaskSerializer(queryset, many=True)
return api_response(serializer.data, status_code=status.HTTP_200_OK)
return Response({"results": serializer.data}, status=status.HTTP_200_OK)
@swagger_auto_schema(
tags=[EXCHANGE_TAG],
@@ -265,7 +272,7 @@ class ExchangePeriodicTaskListCreateView(APIView):
raise ValidationError({"periodic_task": str(exc)}) from exc
output = ExchangePeriodicTaskSerializer(task)
return api_created_response(output.data)
return Response(output.data, status=status.HTTP_201_CREATED)
class ExchangePeriodicTaskDetailView(APIView):
@@ -288,7 +295,7 @@ class ExchangePeriodicTaskDetailView(APIView):
id=task_id,
)
output = ExchangePeriodicTaskSerializer(task)
return api_response(output.data, status_code=status.HTTP_200_OK)
return Response(output.data, status=status.HTTP_200_OK)
@swagger_auto_schema(
tags=[EXCHANGE_TAG],
@@ -330,4 +337,4 @@ class ExchangePeriodicTaskDetailView(APIView):
raise ValidationError({"periodic_task": str(exc)}) from exc
output = ExchangePeriodicTaskSerializer(task)
return api_response(output.data, status_code=status.HTTP_200_OK)
return Response(output.data, status=status.HTTP_200_OK)