using Ban.Sdaid.Notation.Documents;
using Ban.Sdaid.Icd;
namespace Ban.Sdaid.Icd.Subsystems.Backend
{
/// <summary>
/// Карта кода backend (src-api): проекты, где какой артефакт, стек, соответствие spec→code
/// и как запускать. Онбординг — чтобы не грепать дерево кода каждую сессию.
/// Сейчас backend — каркас (bootstrap) с единственной сквозной операцией; карта отражает
/// текущее состояние и целевую раскладку, куда лягут артефакты по мере реализации.
/// </summary>
public class BackendCodeMap : IApplicationDocument, IFolder<SubsystemsFolder>
{
public string Name => "Backend (src-api) — карта кода";
public string Description =>
@"Навигатор по реализации backend в src-api: какой проект за что отвечает, где физически лежит
каждый тип артефакта, каков стек и как запускать сервис. Backend в ранней стадии: реализован первый
реальный read-срез (справочники ввода) по CQRS-контракту с единой обёрткой ответа; БД/EF, command-ветка
и аутентификация ещё не введены. Прочитать ПЕРЕД реализацией backend — заменяет разведку по коду.";
public string Version => "0.2";
public string Status => "draft";
public string[] Comments => new[]
{
"2026-08-11. Заведено после разворачивания каркаса backend (src-api) — сквозной hello через слои.",
"2026-08-12. Проверочный hello удалён; реализован первый read-срез «справочники ввода» и единая обёртка ответа (ADR-SRV-001).",
};
public static string Projects = """
## Проекты (src-api)
| Проект | Роль |
|---|---|
| `Ban.Icd.Api` | Веб-хост ASP.NET Core (net10): `Program.cs` (DI, OpenAPI, контроллеры, enum-как-строка, CORS, HttpClient), `Controllers/`, прикладной слой `Application/`. Сейчас `Application/InputPackets/` (сдача `SubmitInputPacketCommand` — произвольный набор кадров без плана/ролей/идентификаторов, ADR-007; чтение очереди `GetInputQueueQuery`, удаление `DeleteInputPacketCommand`/`ForceDeleteInputPacketCommand`, обработка `NormalizePacketCommand`; `InputPacketController` = POST multipart, GET список, GET содержимое кадра (оригинал/обработанное), POST обработка кадра/пакета, DELETE мягкое/жёсткое); русские подписи идентификаторов — `Application/CaptureLabels`; общая обёртка `Application/CommonModels/` (`IcdBaseRequestResult`, `ErrorDetails`, `ErrorCode`). |
| `Ban.Icd.Cqrs` | Инфраструктура CQRS: `Queries/` и `Commands/` (`IIcdQuery`/`IIcdCommand` + Handler/Result/Processor), процессоры, `IcdCqrsDiExtension` (`Register{Query,Command}Processor`/`Handlers`). Pipeline-шаги ещё не введены. |
| `Ban.Icd.Domain` | Доменные сущности и типы. Модуль `Capture/`: enum'ы и сущности пакета `InputPacket`/`ImageFrame`/`PacketIdentifier` (по спеке `50_Domain/Capture`; планы съёмки убраны — ADR-007). |
| `Ban.Icd.Infrastructure` | Инфраструктура: `IClock`, **доступ к данным** (`Persistence/`: `IcdDbContext` + EF-конфигурации + миграции, EF Core/PostgreSQL), **файловое хранилище** (`Storage/IFileStorage` + `FileSystemFileStorage`) и **нормализация изображений** (`ImageProcessing/IImageNormalizer` + `OrthocoverImageNormalizer` — HTTP-клиент orthocover, multipart, ADR-SRV-005); `AddIcdInfrastructure`. |
""";
public static string Stack = """
## Стек и текущее состояние
- **net10**, ASP.NET Core: контроллеры + OpenAPI (`Microsoft.AspNetCore.OpenApi`, эндпоинт `/openapi/v1.json`). Enum сериализуются строкой (`JsonStringEnumConverter`, ADR-SRV-002).
- **Самописный CQRS** (без MediatR): query- и command-ветки, авто-регистрация обработчиков, без pipeline-шагов. Контроллер зависит от процессора (`IIcdQueryProcessor`/`IIcdCommandProcessor`).
- **Единая обёртка ответа** — `IcdBaseRequestResult { RequestId?, IsSuccess, StatusCode, Message?, Errors[] }`, полезная нагрузка в `Payload` наследника (ADR-SRV-001).
- **Персистентность** — EF Core + **PostgreSQL** (`IcdDbContext`, миграции в `Infrastructure/Persistence/Migrations`, строка подключения `ConnectionStrings:IcdDb`). Сущности — по ADR-SRV-003 (enum строкой, FK-каскад).
- **Файловое хранилище** — `IFileStorage` (диск, `Storage:RootPath`); на стенде заменяется S3/MinIO той же абстракцией.
- **Нормализация изображений** — `IImageNormalizer` (`OrthocoverImageNormalizer` — HTTP-клиент внешнего orthocover: multipart-запрос, разбор multipart/mixed; ADR-SRV-005). Конфиг `Orthocover:Url`/`ApiKey` (секрет — в `appsettings.Local.json`/env, вне git).
- **Срезы**: сдача `POST /api/InputPacket` (multipart: произвольный набор кадров без плана/ролей/идентификаторов — ADR-007 → номер `П-ГГГГММДД-NNN` от максимального суффикса за день, ключи хранения `<номер>/<NN>.<ext>` по ADR-002, файлы в хранилище, пакет в БД, состояние `Queued`); чтение очереди `GET /api/InputPacket` (список с составом из БД, мягко удалённые исключены); содержимое кадра `GET /api/InputPacket/{id}/frames/{order}/content` (поток из хранилища; `variant=normalized` — обработанное); обработка `POST /api/InputPacket/{id}/frames/{order}/normalize` (нормализация кадра через orthocover, хранит обработанный PNG; есть и пакетный `.../normalize`); удаление `DELETE /api/InputPacket/{id}` (мягкое — флаг `Deleted`) и `.../force` (жёсткое — запись каскадом + файлы кадров). Русские подписи идентификаторов — `Application/CaptureLabels`. Аутентификация, read/write-split, pipeline, автозапуск обработки (очередь), определение вида ИК/ролей и извлечение полей — **ещё не введены**.
- **Конфигурация по средам** — `appsettings.json` (`IConfiguration`); CORS-origins фронта из `Cors:AllowedOrigins` (пусто = разрешить любой, локально); Swagger UI только в Development. Конфиги сред генерятся `devops/configs-generator` (ADR-SRV-004).
- **Централизованные версии пакетов** — `src-api/Directory.Packages.props`.
- **Solution** — `Ban.Icd.slnx` на корне репозитория; ведётся отдельно от спеки (`sdaid/Ban.Sdaid.sln`), у которой свой процесс сборки-рендера.
""";
public static string SpecToCode = """
## Соответствие spec → code
Раскладка спеки (sdaid) и кода (src-api) различаются — целевой маппинг:
| sdaid (спека) | src-api (код) |
|---|---|
| `50_Domain/<Module>/<Entity>` | `Ban.Icd.Domain/<Module>/<Entity>.cs` |
| `45_Api/Endpoints/<Area>/<Name>` (endpoint + Command/Query + Result) | `Ban.Icd.Api/Application/<Area>/...` + `Ban.Icd.Api/Controllers/<Area>Controller.cs` |
| `55_Backend/Handlers/<Area>/<Name>Handler` (canonical narrative) | `Ban.Icd.Api/Application/<Area>/<Name>Handler.cs` |
| `55_Backend/Services/<Area>/<Name>` | `Ban.Icd.Infrastructure/...` или прикладной сервис в `Ban.Icd.Api` |
| CQRS-контракты (`IIcdQuery`/`IIcdQueryHandler`, процессор) | `Ban.Icd.Cqrs` |
| ADR бэкенда (`40_Arch/Tech/CSharp/ADR_SRV_001..003`) | конвенции CQRS/обёртки/grid/EF, которым следует код |
Каждый код-файл реализации несёт XML-`<remarks>` со ссылкой на артефакт спеки sdaid (правило в `CLAUDE.md`). Операции ввода/очереди описаны контрактом в спеке: `45_Api/Endpoints/InputPackets/{SubmitInputPacket, GetInputQueue, DeleteInputPacket, GetFrameContent, NormalizePacket}` (endpoint + команда/запрос + результат), парные `55_Backend/Handlers/...` (сценарии; у GetFrameContent handler-а нет — прямая отдача файла из хранилища); базовые типы — `45_Api/Based`. Внешние интеграции — под своим ADR (нормализация изображений — ADR-SRV-005).
""";
public static string Run = """
## Сборка и запуск
```bash
dotnet build Ban.Icd.slnx
# БД: PostgreSQL по строке ConnectionStrings:IcdDb; применить миграции:
dotnet ef database update --project src-api/Ban.Icd.Infrastructure --startup-project src-api/Ban.Icd.Api
dotnet run --project src-api/Ban.Icd.Api --urls http://localhost:5080
# сдача: POST http://localhost:5080/api/InputPacket (multipart)
# очередь: GET http://localhost:5080/api/InputPacket
# контракт/UI: /openapi/v1.json, /swagger (Development)
```
Особенности окружения (расположение dotnet SDK, `DOTNET_ROOT` для `dotnet ef`, доступ к PostgreSQL) относятся к конкретной машине разработчика и в спеке не фиксируются.
""";
public static string RelatedDocuments = $"""
## Связанные документы
- {nameof(Ban.Sdaid.Icd.Subsystems.Frontend.FrontendCodeMap)} — карта кода фронта; фронт потребляет контракт этого backend.
- {nameof(Ban.Sdaid.Icd.Arch.Tech.CSharp.ADR_SRV_001_Cqrs)} — CQRS и обёртка ответа, которым следует код.
- {nameof(Ban.Sdaid.Icd.Arch.Tech.CSharp.ADR_SRV_002_GridQueryContract)} — контракт списочных запросов (для будущих гридов).
- {nameof(Ban.Sdaid.Icd.Arch.Tech.CSharp.ADR_SRV_003_EntityAndEfMapping)} — правила сущностей и EF (для write-ветки с БД).
- {nameof(Ban.Sdaid.Icd.Arch.Tech.CSharp.ADR_SRV_004_AppConfigAndCors)} — конфигурация по средам и CORS.
- {nameof(Ban.Sdaid.Icd.Arch.Tech.CSharp.ADR_SRV_005_ImageNormalizationOrthocover)} — нормализация изображений (orthocover).
""";
}
}