using Ban.Sdaid.Notation.Documents;
namespace Ban.Sdaid.Icd.Epics.RecognitionStand.UseCases
{
/// <summary>Use-case: применение трафарета к скану и чтение зон (отметки офлайн + текст движком).</summary>
public class ApplyTemplateUseCase : IUseCaseDocument, IHasStructuralLinks
{
public static string _refName = "сценарий «Применение трафарета и чтение зон»";
public string Name => "Применение трафарета и чтение зон";
public string Description =>
@"Аналитик загружает трафарет и скан того же вида, выравнивает скан, читает отметки офлайн и текст выбранным движком; результат — JSON и читаемый список полей.";
public string Version => "0.1";
public string Status => "draft";
public string[] Comments => new[]
{
"2026-08-24. Первичная фиксация сценария применения трафарета.",
};
public string PrimaryActor => "Аналитик";
public SdaidLink[] Links => new[]
{
Rel.Realizes<EPIC_RecognitionStand>(),
};
public static string S1_Given = """
## Given
- Открыт экран применения (`editor/apply-template.html`) через локальный прокси.
- Есть трафарет нужного вида (JSON) и скан того же вида страницы.
- По умолчанию: нормализация выключена, deskew включён.
""";
public static string S2_When = """
## When
1. Аналитик загружает трафарет и скан; скан выравнивается по вертикали (deskew).
2. Клетки трафарета накладываются на скан по своим координатам (для «плывущих»
родственных сканов включается опциональная привязка по линиям сетки).
3. Аналитик жмёт «Читать зоны»:
- **отметки** считаются офлайн прототип-вычитанием (клетка темнее «пустого» прототипа
колонки = метка), чувствительность регулируется ползунком;
- **текст**: перед каждым полем — офлайн-проверка «есть чернила»; непустые уходят
в выбранный движок (Qwen-VL по клетке / Yandex OCR одним запросом на страницу).
4. Аналитик сверяет результат по подсветке зон и списку распознанных полей.
""";
public static string S3_Then = """
## Then
- Получен JSON: `marks[]` (отметка true/false + score) и `fields[]` (значение + путь/подпись).
- Пустые клетки помечены и не отправлялись в модель.
- Справа — читаемый список «поле → значение» для быстрой сверки.
""";
public static string S4_Alternatives = """
## Альтернативы и ошибки
| Ситуация | Поведение |
|---|---|
| Скан «плывёт» относительно эталона | Включается привязка по линиям (кусочная интерполяция, регуляризованная к аффинной): на «своём» скане вырождается в тождество и не вредит |
| Слабая рукописная метка | Разделение метка/пусто на пределе; крутится чувствительность, помогает более крупная съёмка |
| Крупный бокс Комментария с редким текстом | Не считается пустым по абсолютному числу тёмных пикселей, а не по доле |
| Лимит частоты облачного OCR | Yandex — один запрос на всю страницу, слова раскладываются по клеткам через геометрию |
""";
public static string S5_Trace = $"""
## Трассировка
| Шаг | Инструмент |
|---|---|
| Наложение трафарета, deskew, привязка, чтение зон | `editor/apply-template.html` |
| Отметки | офлайн прототип-вычитание (в странице) |
| Текст | Qwen-VL / Yandex OCR через `server/` |
Эпик — {nameof(EPIC_RecognitionStand)}. Продуктовая цель — {nameof(Ban.Sdaid.Icd.Epics.CardExtraction.EPIC_CardExtraction)}.
""";
}
}