using Rugrid.Sdaid.Notation.Documents;
using Rugrid.Sdaid.Epas.Ntr.Backend.Calc;
namespace Rugrid.Sdaid.Epas.Ntr.ChangeRequests
{
/// <summary>
/// Доработка методики второго этапа: расчёт площади верхних ограждающих конструкций
/// для односкатной крыши при прямоугольной форме здания.
/// </summary>
public class DOC_CR_2026_08_19_UpperEnclosuresShedRoof : IChangeRequestDocument, IHasStructuralLinks, IFolder<NtrChangeRequestsFolder>
{
public SdaidLink[] Links => new[]
{
Rel.Uses<DOC_TtrCalc>(),
Rel.Uses<Rugrid.Sdaid.Epas.Ntr.Domain.ConsumptionModel.DOC_RoofModel>(),
Rel.Uses<Rugrid.Sdaid.Epas.Ntr.Domain.Reference.DOC_RoofType>(),
};
public static string _refName = "CR 2026-08-19: ВОК для односкатной крыши";
public string Name => "Расчёт площади ВОК для односкатной крыши";
public string Description =>
@"Реализовать расчёт площади верхних ограждающих конструкций для типа крыши «Односкатная» при прямоугольной форме здания. Формулы уже зафиксированы в методике теплотехнического расчёта (вариант `shed_rect`); в реализации `Ntr.Calc` ветки не было, и модели с такой крышей расчёт не проходили.";
public string Version => "1.0";
public string Status => "done";
public string[] Comments => new string[0];
public static string Source = """"
## Источник (как есть)
Одна из задач второго этапа: доработка методики расчёта: реализация расчёта площади верхних
ограждающих конструкций для типов крыши: Односкатная, Четырехскатная вальмовая,
Четырехскатная шатровая для прямоугольной форрмы здания.
Задача разбита на две: **A — односкатная** (этот CR) и **B — четырёхскатные**
(вальмовая и шатровая).
"""";
public static string Analysis = $$""""
## Разбор
Справочник типов крыши уже содержит запись для односкатной крыши, и в системе есть модели
потребления с этим типом. Но расчёт по ним не выполнялся: сопоставление кода справочника
с типом расчёта (`MapRoofType` в `CalcInputModelFactory`) знало только плоскую и двускатную
крышу и на остальных кидало исключение, а секции методики
{{SdaidAnchors.RefTo<TeAtticWallArea>("te.attic_wall_area")}} и
{{SdaidAnchors.RefTo<TeRoofCoverArea>("te.roof_cover_area")}} были реализованы только для этих
двух типов. При этом сами формулы для односкатной крыши в методике **есть** — они были
вписаны в неё заранее и перенесены в SDAID вместе с остальным текстом.
### Что в объёме
- Ветка `shed_rect` в расчёте площади наружной поверхности стен чердака:
$A_{НП.Черд} = (L_A + L_B)·(H − z_{ВП})$.
- Ветка `shed_rect` в расчёте площади покрытия крыши:
$A_{ПК} = L_{max}·\sqrt{L_{min}^2 + (H − z_{ВП})^2}$.
- Снятие ограничения «тип крыши ∈ {Плоская, Двускатная}» в валидаторах обеих секций.
- Сопоставление кода справочника с типом расчёта.
- Контрольный пример в `src/Ntr.Calc.Tests`.
### Что вне объёма
- **Четырёхскатные крыши** (вальмовая, шатровая) — отдельный CR: они требуют нового
атрибута «Длина конька» в домене, миграции БД, поля на UI и правок контракта InputModel.
- **Формы здания, кроме прямоугольной.** Методика даёт формулы односкатной крыши только
для прямоугольной формы.
- **Массовый пересчёт** уже посчитанных моделей после доработки.
### Принятые решения
- **Только прямоугольная форма.** Для остальных форм с односкатной крышей поведение не меняется.
- **Запись справочника не заводим** — она уже есть, и модели с этим типом крыши существуют.
- **Изменений в БД, read-модели, API и UI не требуется.** Тип крыши выбирается из справочника,
новых атрибутов у ВОК не появляется, поэтому доработка укладывается в `Ntr.Calc` плюс одна
строка сопоставления кода в `CalcInputModelFactory`.
- **Код односкатной крыши в справочнике — `tr500`.** Состав справочника типов крыш из
АИС ОИА ПЭО: `tr100` — Плоская, `tr200` — Двускатная, `tr300` — Четырехскатная,
`tr400` — Двускатная без нижнего перекрытия, `tr500` — Односкатная.
### Смежные находки (вне объёма)
Состав справочника типов крыш расходится с методикой — обнаружено при уточнении кода
односкатной крыши:
- **`tr300` «Четырехскатная» — одна запись, а методика описывает два типа:** четырёхскатную
вальмовую и четырёхскатную шатровую, с разными формулами площади покрытия. Как их
различать при одном коде справочника — вопрос CR по четырёхскатным крышам.
*Закрыто 2026-08-31: в справочнике из АИС заведены отдельные записи `hipped`
и `pyramidal`.*
- **`tr400` «Двускатная без нижнего перекрытия»** в методике не описана вовсе. Расчёт
моделей с этим типом крыши падает так же, как падал с односкатной.
"""";
public static string BlastRadius = $$""""
## Blast radius
**Спецификация:**
| Документ | Правка |
|---|---|
| {{SdaidAnchors.RefTo<TeAtticWallArea>("te.attic_wall_area")}} | правило валидации «`Тип крыши`: ∈[Плоская, Двускатная]» устарело: тот же раздел уже описывает односкатную, вальмовую и шатровую крышу. Перечень расширен до фактически описанных вариантов. |
Правка отмечена в самой секции (`Status`, `Comments`) со ссылкой на этот CR — чтобы
отличать её от дефекта переноса первого этапа.
**Реализация:** `AtticWallAreaCalculator`, `RoofCoverAreaCalculator`, валидаторы обеих
секций, `RoofType`, `CalcInputModelFactory.MapRoofType`.
**Чего доработка не касается:** БД, read-модель, контракты API, swagger, UI.
"""";
public static string Plan = """"
## План
1. ✔ Ветки `shed_rect` в обоих калькуляторах.
2. ✔ Снятие ограничения по типу крыши в валидаторах.
3. ✔ Сопоставление кода `tr500` с типом расчёта.
4. Контрольный пример `CalcControlExample4GarageShedRoofTests` — ожидает контрольных
значений: расчёт контрольных чисел тем же алгоритмом, который проверяется, ничего
не доказывает.
"""";
public static string Acceptance = """"
## Acceptance criteria
- **AC-1.** Контрольный пример `CalcControlExample4GarageShedRoofTests` в `src/Ntr.Calc.Tests`
проходит: расчёт модели с односкатной крышей завершается со статусом `Success`, а значения
$A_{НП.Черд}$, $A_{ПК}$ и $A_{ВОК}$ совпадают с контрольными.
- **AC-2.** Модель потребления с типом крыши «Односкатная» рассчитывается из интерфейса
и не падает с ошибкой «Необрабатываемый тип крыши».
- **AC-3.** В журнале расчёта у такой модели виден выбранный вариант методики `shed_rect`.
- **AC-4.** Поведение моделей с плоской и двускатной крышей не изменилось: контрольные
примеры 1–3 продолжают проходить.
"""";
public static string Result = """"
## Итог
| Пункт | Статус |
|---|---|
| Расчёт площади стен чердака и покрытия крыши для односкатной крыши | выполнено |
| Сопоставление кода справочника `tr500` | выполнено |
| Правка методики (перечень типов крыши в правилах валидации) | выполнено |
| Контрольный пример | ожидает контрольных значений |
"""";
}
}