using System;
using Ban.Sdaid.Notation.Documents;
using Ban.Sdaid.Icd;
using Ban.Sdaid.Icd.Api.Based;
using Ban.Sdaid.Icd.Domain.Capture;
namespace Ban.Sdaid.Icd.Api.Endpoints.InputPackets.SubmitInputPacket
{
/// <summary>Документ-обёртка над endpoint постановки пакета ввода в очередь.</summary>
public class DOC_SubmitInputPacket : IApiContractDocument, IFolder<ApiFolder>, IHasStructuralLinks
{
public SdaidLink[] Links => new[]
{
Rel.Uses<Ban.Sdaid.Icd.Backend.Handlers.InputPackets.SubmitInputPacketHandler>(),
};
public static string _refName = "Endpoint SubmitInputPacket";
public string Name => "Endpoint: SubmitInputPacket";
public string Description =>
@"Постановка собранного пакета ввода в очередь: произвольный набор кадров одной ИК, без плана. Поведение — SubmitInputPacketHandler.";
public string Version => "0.1";
public string Status => "draft";
public string[] Comments => new string[0];
public static string Transport = """
## Транспорт
`POST /api/InputPacket`, **multipart/form-data**:
- часть `payload` — JSON метаданных пакета (форма `SubmitInputPacketCommand` ниже);
- части `files` — бинарное содержимое кадров; кадр ссылается на свой файл по `FileIndex`.
Кадр-ссылка (`Source = Url`) содержимого не несёт — сервер скачивает изображение по `Url` сам.
""";
public static string Body = $"""
## Endpoint
{SdaidCode.OfClass<SubmitInputPacketEndpoint>()}
## Command (часть `payload`)
{SdaidCode.OfClass<SubmitInputPacketCommand>()}
## FrameItem
{SdaidCode.OfClass<SubmitFrameItem>()}
## Result
{SdaidCode.OfClass<SubmitInputPacketResult>()}
## Payload
{SdaidCode.OfClass<SubmittedPacketPayload>()}
""";
}
/// <summary>Endpoint постановки пакета в очередь.</summary>
public class SubmitInputPacketEndpoint
{
public SubmitInputPacketCommand? Input { get; set; }
public SubmitInputPacketResult? Output { get; set; }
}
/// <summary>Метаданные сдаваемого пакета (JSON-часть multipart).</summary>
public class SubmitInputPacketCommand : BasedCommand
{
/// <summary>Кадры пакета (минимум один — пакет не может быть пустым). Роль на вводе не задаётся.</summary>
public SubmitFrameItem[] Frames { get; init; } = new SubmitFrameItem[0];
}
/// <summary>Описание одного кадра: метаданные + привязка к содержимому (файл или URL).</summary>
public class SubmitFrameItem
{
/// <summary>Способ получения: камера, диск, ссылка.</summary>
[Relation]
public ImageSource Source { get; init; }
/// <summary>Порядок кадра в пакете.</summary>
public int Order { get; init; }
/// <summary>Исходное имя файла (для диска/ссылки).</summary>
public string? OriginalFileName { get; init; }
/// <summary>Момент получения кадра.</summary>
public DateTime CapturedAt { get; init; }
/// <summary>Индекс файла в части `files` (для источников камера/диск).</summary>
public int? FileIndex { get; init; }
/// <summary>URL изображения (для источника «ссылка»); сервер скачивает содержимое.</summary>
public string? Url { get; init; }
}
/// <summary>Результат постановки в очередь.</summary>
public class SubmitInputPacketResult : BasedResult
{
/// <summary>Сведения о сданном пакете; null при ошибке.</summary>
public SubmittedPacketPayload? Payload { get; init; }
}
/// <summary>Сданный пакет — номер, время и состав (для списка «сдано за смену»).</summary>
public class SubmittedPacketPayload
{
public Guid Id { get; init; }
/// <summary>Присвоенный сервером номер вида П-ГГГГММДД-NNN.</summary>
public string Number { get; init; } = "";
public DateTime QueuedAt { get; init; }
public int FramesCount { get; init; }
}
}