⟨/⟩ 45_Api/Based/BasedTypes.cs

104 строк · в начало

using System;
using Ban.Sdaid.Notation.Documents;
using Ban.Sdaid.Icd;

namespace Ban.Sdaid.Icd.Api.Based
{
    /// <summary>
    /// Обзор базовых типов API: маркеры команд/запросов и единая обёртка результата с ошибками.
    /// Все endpoint-документы наследуют от этих типов или используют их в полях.
    /// </summary>
    public class DOC_BasedTypes : ISdaidDocument, IFolder<ApiFolder>
    {
        public static string _refName = "Базовые типы API";

        public string Name => "Базовые типы API";

        public string Description =>
            @"Маркерные базовые классы команд/запросов и единая обёртка результата (payload / успех / ошибки), общая для всех ручек. Соответствует коду `IcdBaseRequestResult` (ADR-SRV-001).";

        public string Version => "0.1";
        public string Status => "draft";
        public string[] Comments => new string[0];

        public static string Body = $"""
            ## Единая обёртка ответа

            Все ручки возвращают один контракт: успех — это отсутствие ошибок; полезная нагрузка кладётся
            в поле `Payload` конкретного результата-наследника. Соответствие в коде — `IcdBaseRequestResult`
            (см. {SdaidAnchors.RefTo<Ban.Sdaid.Icd.Arch.Tech.CSharp.ADR_SRV_001_Cqrs>()}).

            ## BasedCommand

            {SdaidCode.OfClass<BasedCommand>()}

            ## BasedQuery

            {SdaidCode.OfClass<BasedQuery>()}

            ## BasedResult

            {SdaidCode.OfClass<BasedResult>()}

            ## ErrorDetail

            {SdaidCode.OfClass<ErrorDetail>()}

            ## ErrorCode

            {SdaidCode.OfClass<ErrorCode>()}
            """;
    }

    /// <summary>Маркер команды (write-сторона).</summary>
    public class BasedCommand
    {
    }

    /// <summary>Маркер запроса (read-сторона).</summary>
    public class BasedQuery
    {
    }

    /// <summary>Единая обёртка результата: полезная нагрузка — в поле `Payload` наследника.</summary>
    public class BasedResult
    {
        /// <summary>Идентификатор запроса для трассировки (резерв).</summary>
        public Guid? RequestId { get; init; }

        /// <summary>HTTP-код операции.</summary>
        public int StatusCode { get; init; } = 200;

        /// <summary>Сопроводительное сообщение.</summary>
        public string? Message { get; init; }

        /// <summary>Детализация ошибок; пусто — успех.</summary>
        public ErrorDetail[] Errors { get; init; } = new ErrorDetail[0];

        /// <summary>Успех операции: ошибок нет.</summary>
        public bool IsSuccess => Errors.Length == 0;
    }

    /// <summary>Одна ошибка ответа. Текст формирует бэкенд (по-русски); UI его не переводит.</summary>
    public class ErrorDetail
    {
        /// <summary>Поле или контекст ошибки.</summary>
        public string? ErrorData { get; init; }

        /// <summary>Код ошибки.</summary>
        public ErrorCode ErrorCode { get; init; }

        /// <summary>Человекочитаемый текст.</summary>
        public string? ErrorMessage { get; init; }
    }

    /// <summary>Код ошибки операции.</summary>
    public enum ErrorCode
    {
        Unknown,
        Validation,
        NotFound,
        Conflict,
    }
}