Расчёт площади ВОК для четырёхскатных крыш

Запрос на изменение Версия: 0.1 draft

Реализовать расчёт площади верхних ограждающих конструкций для типов крыши «Четырёхскатная вальмовая» и «Четырёхскатная шатровая» при прямоугольной форме здания. Формулы зафиксированы в методике; для вальмовой крыши требуется новый исходный параметр «Длина конька», которого нет ни в домене, ни в БД, ни на интерфейсе.

⟨/⟩ Исходник

1. Источник (как есть)

Одна из задач второго этапа: доработка методики расчёта: реализация расчёта площади верхних ограждающих конструкций для типов крыши: Односкатная, Четырехскатная вальмовая, Четырехскатная шатровая для прямоугольной форрмы здания.

Задача разбита на две: A — односкатная и B — четырёхскатные (вальмовая и шатровая, этот CR).

2. Разбор

Формулы для обоих типов крыши уже есть в методике — они были вписаны заранее и перенесены в SDAID вместе с остальным текстом. Реализации нет: MapRoofType в CalcInputModelFactory на этих типах кидает исключение, а диспетчеры секций te.attic_wall_area и te.roof_cover_area знают только плоскую, двускатную и односкатную крышу.

2.1. Что считаем

Площадь стен чердака по методике для обоих типов равна нулю: у вальмовой и шатровой крыши скаты сходятся со всех сторон, вертикальных фронтонов нет.

Тип \(A_{НП.Черд}\) \(A_{ПК}\)
Четырёхскатная вальмовая (hipped_rect) 0 \((L_A + L_{конька})·h_{трап} + L_B·h_{треуг}\)
Четырёхскатная шатровая (pyramidal_rect) 0 \(L_A·h^A_{треуг} + L_B·h^B_{треуг}\)

где \(h_{трап} = \sqrt{(H-z_{ВП})^2 + (L_B/2)^2}\), \(h_{треуг} = \sqrt{(H-z_{ВП})^2 + ((L_A-L_{конька})/2)^2}\), \(h^A_{треуг} = \sqrt{(H-z_{ВП})^2 + (L_B/2)^2}\), \(h^B_{треуг} = \sqrt{(H-z_{ВП})^2 + (L_A/2)^2}\).

Шатровая — вырожденный случай вальмовой при \(L_{конька} = 0\): подставив ноль в формулу вальмовой, получаем формулу шатровой. Отдельными ветками расчёта они остаются — тип задан справочником, — но это объясняет, почему незаполненный конёк у вальмовой крыши опасен: расчёт молча даст площадь шатровой — отсюда правило обязательности ниже.

2.2. Как различаются вальмовая и шатровая

В загруженном из АИС ОИА ПЭО справочнике типов крыш для них заведены отдельные записи: hipped — четырёхскатная вальмовая, pyramidal — четырёхскатная шатровая. Тип расчёта определяется кодом записи напрямую, как для плоской, двускатной и односкатной крыши. Длина конька — исходный параметр формулы вальмовой крыши, а не способ определить тип.

2.3. Новый параметр «Длина конька»

Параметр не ведёся в АИС ОИА ПЭО. Его надо добавить в характеристики верхних ограждающих конструкций, в сущность ВОК:

/// <summary>Длина конька, м</summary>
[DomainField(
    Alias = "ridge_length_m",
    RequiredForCalc = "Да, если Тип крыши.Код = \"hipped\"",
    Unit = "м",
    Range = "вещественное, 0 < L_конька < Размер по габариту A"
)]
public decimal RidgeLengthM { get; set; }

Он будет заполняться пользователем в Сервисе, импорт из АИС его не должен затирать.

Атрибут добавлен в спецификацию сущности этим CR. Как он ложится на структуру БД, read-модель и контракты — в разделе Blast radius.

2.4. Правило валидации длины конька

Правило одно, внесено в методику — раздел «Правила валидации» секции te.roof_cover_area: для вальмовой крыши \(0 < L_{конька} < L_A\). Место выбрано по использованию: длина конька входит только в эту секцию, смежная te.attic_wall_area для четырёхскатных крыш даёт ноль.

Обоснование границ: верхняя — из наклонной высоты торцевого ската \(h_{треуг}=\sqrt{(H-z_{ВП})^2 + ((L_A-L_{конька})/2)^2}\), при \(L_{конька} = L_A\) торцевые скаты вырождаются в линию. Сторона сравнения — \(L_A\), а не \(\max(L_A, L_B)\): конёк входит в формулу как слагаемое и вычитаемое именно к \(L_A\). Нижняя граница строгая, поэтому незаполненное значение нельзя подставлять нулём: при нулевом коньке формула вальмовой крыши вырождается в формулу шатровой и вернула бы площадь крыши другого типа.

2.5. Открытые вопросы

Прежняя запись справочника «Четырехскатная» (tr300), если она осталась и на неё ссылаются модели, остаётся типом крыши, не поддержанным методикой, — как и tr400 «Двускатная без нижнего перекрытия». Ни то, ни другое в объём этого CR не входит.

3. Blast radius

В отличие от CR по односкатной крыше, здесь появляется новый исходный параметр, поэтому правка сквозная — от структуры БД до формы ввода. Ниже — фактическая цепочка, прослеженная по коду на примере соседнего атрибута «Уровень верхнего перекрытия» (UpperFloorLevelM), который проходит ровно те же слои.

3.1. Спецификация

Документ Правка
ВОК новый атрибут «Длина конька, м» в классе сущности — таблица свойств и диаграмма связей строятся по нему
te.roof_cover_area правила валидации длины конька — внесены; источник данных для \(L_{конька}\) — атрибут сущности ВОК
te.attic_wall_area правила валидации: перечень типов крыши
Модель расчёта CalcModel блок roof модели входных данных: новое поле ridgeLengthM — без него параметр не доедет до расчёта
Маппинг домен → InputModel (ТЭ) соответствие Roof.RidgeLength ← «ВОК. Длина конька, м» в секции TeInputSection.Roof
Тип крыши состав справочника: записи hipped и pyramidal загружены из АИС; правок не требует, фиксируется как факт
Вкладка "Верхние ограждающие конструкции поле «Длина конька, м» в описании полей вкладки и в макете экрана — видимое только для вальмовой крыши

3.2. База данных

3.3. API и контракты

3.4. Расчёт

Цепочка передачи параметра до формулы: атрибут сущности ВОК → колонка БД → DTO ответа и команды → InputModel.roof.ridgeLengthM → RoofTeInput.RidgeLength → калькулятор секции te.roof_cover_area. Разрыв в любом звене оставит расчёт с пустым коньком, то есть с ошибкой валидации.

3.5. Интерфейс

3.6. Тесты

4. План

  1. Правки спецификации по таблице blast radius; в изменённых секциях проставить Status и Comments со ссылкой на этот CR.
  2. Домен и БД: атрибут, конфигурация, миграция, read-модель.
  3. API: контракты, обработчики команд и запросов; перегенерация клиента.
  4. UI: поле на форме и в карточке модели.
  5. Расчёт: типы крыши, ветки калькуляторов, валидаторы, сопоставление кода справочника.
  6. Контрольные примеры (значения предоставляет заказчик).
  7. Зафиксировать «Итог».

Шаги 2–5 разумно вести снизу вверх (домен → API → UI), чтобы контракт менялся один раз.

5. Acceptance criteria

6. Итог

—

Связанные артефакты

Документы