fix(api): align contracts with frontend md
Some checks failed
CI/CD Pipeline / Code Quality Checks (pull_request) Failing after 3m20s
CI/CD Pipeline / Run Tests (pull_request) Successful in 13m45s
CI/CD Pipeline / Run API Inventory E2E Tests (pull_request) Successful in 22s
CI/CD Pipeline / Telegram Notify Success (pull_request) Has been skipped

This commit is contained in:
2026-03-23 13:12:10 +01:00
parent d030c705ac
commit 4ca6b75393
12 changed files with 215 additions and 215 deletions

View File

@@ -314,6 +314,13 @@ class FNSZipUploadSerializer(serializers.Serializer):
return value
class FNSFileUploadSuccessSerializer(serializers.Serializer):
"""Ответ одиночной загрузки FNS в формате frontend."""
success = serializers.BooleanField(read_only=True)
message = serializers.CharField(read_only=True)
class ParsingSettingsSerializer(serializers.ModelSerializer):
"""Настройки периодичности обновления источников парсинга."""
@@ -429,6 +436,15 @@ class ParserLoadLogListSerializer(serializers.Serializer):
updated_at = serializers.DateTimeField(read_only=True)
class ParserLoadLogPageSerializer(serializers.Serializer):
"""Пагинированный ответ списка логов для frontend."""
count = serializers.IntegerField(read_only=True)
next = serializers.CharField(read_only=True, allow_null=True)
previous = serializers.CharField(read_only=True, allow_null=True)
results = ParserLoadLogListSerializer(many=True, read_only=True)
class SourceCardRefreshParamSerializer(serializers.Serializer):
"""Описание параметра ручного обновления карточки источника."""
@@ -548,3 +564,36 @@ class SourceCardRefreshResponseSerializer(serializers.Serializer):
status = serializers.CharField(read_only=True)
requested_at = serializers.DateTimeField(read_only=True)
tasks = SourceCardRefreshTaskSerializer(many=True, read_only=True)
class FrontendApiResponseSerializer(serializers.Serializer):
"""Общая форма success/data/errors/meta для frontend sources API."""
success = serializers.BooleanField(read_only=True)
errors = serializers.JSONField(read_only=True, allow_null=True)
meta = serializers.JSONField(read_only=True, allow_null=True)
class SourceCardListResponseSerializer(FrontendApiResponseSerializer):
"""Envelope для списка карточек источников."""
data = SourceCardSerializer(many=True, read_only=True)
class SourceTaskStatusListResponseSerializer(FrontendApiResponseSerializer):
"""Envelope для списка статусов источников."""
data = SourceTaskStatusSerializer(many=True, read_only=True)
class SourceCardDetailResponseSerializer(FrontendApiResponseSerializer):
"""Envelope для детальной карточки источника."""
data = SourceCardDetailSerializer(read_only=True)
class SourceCardRefreshFrontendResponseSerializer(serializers.Serializer):
"""Минимальный ответ запуска обновления карточки по md."""
task_id = serializers.CharField(read_only=True, allow_null=True)
status = serializers.CharField(read_only=True)

View File

@@ -24,18 +24,24 @@ from apps.parsers.serializers import (
FinancialReportDetailSerializer,
FinancialReportSerializer,
FNSFileUploadSerializer,
FNSFileUploadSuccessSerializer,
IndustrialCertificateSerializer,
IndustrialProductSerializer,
InspectionSerializer,
ManufacturerSerializer,
ParserLoadLogListSerializer,
ParserLoadLogPageSerializer,
ParserLoadLogSerializer,
ParsingSettingsSerializer,
ProcurementSerializer,
SourceCardDetailResponseSerializer,
SourceCardDetailSerializer,
SourceCardListResponseSerializer,
SourceCardRefreshFrontendResponseSerializer,
SourceCardRefreshRequestSerializer,
SourceCardRefreshResponseSerializer,
SourceCardSerializer,
SourceTaskStatusListResponseSerializer,
SourceTaskStatusSerializer,
)
from apps.parsers.source_cards import SourceCardService
@@ -683,15 +689,16 @@ class FNSReportUploadView(APIView):
),
manual_parameters=[
openapi.Parameter(
name="files",
name="file",
in_=openapi.IN_FORM,
type=openapi.TYPE_FILE,
required=True,
description="Файл(ы) для загрузки (fin_*.xlsx)",
description="Файл для загрузки (fin_*.xlsx)",
),
],
consumes=["multipart/form-data"],
responses={
200: FNSFileUploadSuccessSerializer,
202: openapi.Response(
description="Файлы приняты в обработку",
schema=openapi.Schema(
@@ -809,7 +816,7 @@ class SourceCardListView(APIView):
"для фронтенда."
),
responses={
200: SourceCardSerializer(many=True),
200: SourceCardListResponseSerializer,
**ErrorResponses.AUTHENTICATED,
},
)
@@ -832,7 +839,7 @@ class SourceTaskStatusListView(APIView):
"мониторинга парсинга."
),
responses={
200: SourceTaskStatusSerializer(many=True),
200: SourceTaskStatusListResponseSerializer,
**ErrorResponses.AUTHENTICATED,
},
)
@@ -855,7 +862,7 @@ class SourceCardDetailView(APIView):
"включая подисточники, последние загрузки и активные задачи."
),
responses={
200: SourceCardDetailSerializer,
200: SourceCardDetailResponseSerializer,
**ErrorResponses.AUTHENTICATED_NOT_FOUND,
},
)
@@ -878,7 +885,7 @@ class SourceCardRefreshView(APIView):
),
request_body=SourceCardRefreshRequestSerializer,
responses={
202: SourceCardRefreshResponseSerializer,
202: SourceCardRefreshFrontendResponseSerializer,
400: CommonResponses.BAD_REQUEST,
**ErrorResponses.ADMIN_NOT_FOUND,
},
@@ -892,17 +899,9 @@ class SourceCardRefreshView(APIView):
requested_by_id=request.user.id if request.user.is_authenticated else None,
params=serializer.validated_data.get("params", {}),
)
output = SourceCardRefreshResponseSerializer(payload)
serialized_payload = output.data
tasks = serialized_payload.get("tasks", [])
task_id = tasks[0]["task_id"] if tasks else None
response_payload = {
"task_id": task_id,
"status": "accepted",
}
if len(tasks) > 1:
response_payload["tasks"] = tasks
response_payload["source_card"] = serialized_payload.get("source_card")
output = SourceCardRefreshResponseSerializer(payload).data
tasks = output.get("tasks", [])
response_payload = {"task_id": tasks[0]["task_id"] if tasks else None, "status": "accepted"}
return Response(
response_payload,
status=status.HTTP_202_ACCEPTED,
@@ -937,7 +936,7 @@ class ParserLoadLogViewSet(ReadOnlyModelViewSet):
"Возвращает историю загрузок данных парсерами.\n"
"Доступно только администраторам.\n"
"Поддерживает фильтрацию по: source, status, batch_id.\n"
"Поддерживает search по source, status, batch_id и error_message.\n"
"Поддерживает search по всем полям строки frontend-лога.\n"
"Поддерживает ordering по: id, batch_id, source, status, records_count, "
"created_at, updated_at."
),
@@ -947,7 +946,7 @@ class ParserLoadLogViewSet(ReadOnlyModelViewSet):
in_=openapi.IN_QUERY,
type=openapi.TYPE_STRING,
required=False,
description="Поиск по source, status, batch_id и error_message",
description="Поиск по всем полям строки frontend-лога",
),
openapi.Parameter(
name="ordering",
@@ -961,7 +960,7 @@ class ParserLoadLogViewSet(ReadOnlyModelViewSet):
),
],
responses={
200: ParserLoadLogSerializer(many=True),
200: ParserLoadLogPageSerializer,
**ErrorResponses.ADMIN,
},
)