Инициализировать репозиторий «Дейл»

Первый коммит: модульный монолит ядра (.NET 10) и gRPC-сервисы
ai/ml/telegram, фронтенд Vue 3/Vite/Tailwind, документация (ТЗ,
инструкция пользователя, техдокументация, код-стайл), бэклог,
скрипты развёртывания и архив прототипа LeadRadar.
This commit is contained in:
Rustam Khalimov
2026-09-11 02:50:17 +03:00
commit 9e07568ddd
1402 changed files with 177470 additions and 0 deletions
+60
View File
@@ -0,0 +1,60 @@
namespace Deal.Api.Http;
/// <summary>
/// Общие ответы ошибок минимальных API: HTTP-код + <c>{"detail":"…"}</c> (формат прототипа, Ruling 10).
/// </summary>
/// <remarks>
/// Единая точка для всех Endpoints-файлов (Auth/Settings/Ai-проверка): сообщения деталей —
/// фиксированные строки прототипа (FastAPI HTTPException), задаются вызывающим.
/// </remarks>
public static class EndpointResults
{
/// <summary>
/// 401-ответ: сессия не разрешена/учётные данные не приняты.
/// </summary>
/// <param name="detail">Текст ошибки (напр. <see cref="AuthHelpers.UnauthorizedDetail"/>).</param>
/// <returns>JSON-ответ {detail} со статусом 401.</returns>
public static IResult Unauthorized(string detail) =>
Results.Json(new { detail }, statusCode: StatusCodes.Status401Unauthorized);
/// <summary>
/// 400-ответ: некорректный запрос (тело/значения).
/// </summary>
/// <param name="detail">Текст ошибки.</param>
/// <returns>JSON-ответ {detail} со статусом 400.</returns>
public static IResult BadRequest(string detail) =>
Results.Json(new { detail }, statusCode: StatusCodes.Status400BadRequest);
/// <summary>
/// 404-ответ: ресурс не найден (формат прототипа, Ruling 10).
/// </summary>
/// <param name="detail">Текст ошибки.</param>
/// <returns>JSON-ответ {detail} со статусом 404.</returns>
public static IResult NotFound(string detail) =>
Results.Json(new { detail }, statusCode: StatusCodes.Status404NotFound);
/// <summary>
/// 403-ответ: запрос понятен, но доступ запрещён (приостановленный тенант, план Task 7/Ruling 10(5)).
/// </summary>
/// <param name="detail">Текст ошибки.</param>
/// <returns>JSON-ответ {detail} со статусом 403.</returns>
public static IResult Forbidden(string detail) =>
Results.Json(new { detail }, statusCode: StatusCodes.Status403Forbidden);
/// <summary>
/// 429-ответ: превышен лимит запросов/попыток входа (план Task 11, Ruling 5: LoginAttemptGuard).
/// </summary>
/// <param name="detail">Текст ошибки.</param>
/// <returns>JSON-ответ {detail} со статусом 429.</returns>
public static IResult TooManyRequests(string detail) =>
Results.Json(new { detail }, statusCode: StatusCodes.Status429TooManyRequests);
/// <summary>
/// 410-ответ: ресурс больше недоступен (Ruling 4: файл без objectKey — «Файл не сохранён
/// в объектном хранилище»; api-map §1: 410 в списке кодов ошибок прототипа).
/// </summary>
/// <param name="detail">Текст ошибки.</param>
/// <returns>JSON-ответ {detail} со статусом 410.</returns>
public static IResult Gone(string detail) =>
Results.Json(new { detail }, statusCode: StatusCodes.Status410Gone);
}