fix(templateMatcher): Исправлен баг в AutoControlResolver и добавивлен Include для AutoControl группы

- Добавлены строгие проверки на null для `GroupType`, `jobGroup.AutoControl` и `job.AutoControl` с генерацией исключений.
- В запрос загрузки данных добавлен `.Include(j => j.Group).ThenInclude(g => g.AutoControl)`, исправивший падение в дефолтные состояния.
This commit is contained in:
Mikhail Kuznetsov
2026-07-16 15:00:17 +10:00
parent 6ca6bfbc2e
commit 6c93e1971f
2 changed files with 40 additions and 13 deletions

View File

@@ -16,26 +16,53 @@ namespace PARR.TemplateMatcher.Services.Implementations
bool defaultTemplateState = false,
bool defaultScheduleState = false)
{
// Тип группы определяет источник настроек
var isGroupLevel = jobGroup?.GroupType?.IsJobGroupAutoControl == true;
if (isGroupLevel && jobGroup!.AutoControl != null)
// Защита от оптимизации: если группу забыли подгрузить, метод честно падает,
// потому что без GroupType бизнес-логика не может определить уровень управления
if (jobGroup == null)
{
throw new InvalidOperationException(
$"Критическая ошибка бизнес-логики: Для работы '{job.Name}' (ID: {job.Id}) " +
$"не передана группа (null). Нужно добавить '.Include(j => j.Group)'.");
}
// 1. Проверяем, что разработчики подгрузили GroupType из базы данных
if (jobGroup.GroupType == null)
{
throw new InvalidOperationException(
$"Для работы '{job.Name}' (ID: {job.Id}) передана группа, " +
$"но её GroupType = null. Нужно добавить '.ThenInclude(g => g.GroupType)' в запрос.");
}
// Теперь компилятор знает, что jobGroup и GroupType гарантированно не null
var isGroupLevel = jobGroup.GroupType.IsJobGroupAutoControl;
// 2. Сценарий: Управление на уровне Группы Работ
if (isGroupLevel)
{
if (jobGroup.AutoControl == null)
throw new InvalidOperationException(
$"В типе группы '{jobGroup.GroupType.Id}' указано управление " +
$"на уровне ГРУППЫ, но у группы '{jobGroup.GroupName}' (ID: {jobGroup.Id}) " +
$"отсутствуют настройки автоконтроля (JobGroup.AutoControl равен null)!");
return (
jobGroup.AutoControl.InitUsedTemplateState,
jobGroup.AutoControl.InitUsedScheduleState
);
}
if (!isGroupLevel && job.AutoControl != null)
{
// 3. Сценарий: Управление на уровне конкретной Работы
if (job.AutoControl == null)
throw new InvalidOperationException(
$"В типе группы '{jobGroup.GroupType.Id}' указано управление " +
$"на уровне РАБОТЫ, но у работы '{job.Name}' (ID: {job.Id}) " +
$"отсутствуют настройки автоконтроля (Job.AutoControl равен null)!");
return (
job.AutoControl.InitUsedTemplateState,
job.AutoControl.InitUsedScheduleState
);
}
return (defaultTemplateState, defaultScheduleState);
}
}
}

View File

@@ -26,7 +26,7 @@ internal class LoadJobStage : ISimpleSyncStage
.Include(j => j.AutoControl)
.Include(j => j.Tnk)
.Include(j => j.Group).ThenInclude(g => g!.GroupType)
.Include(j => j.AutoControl)
.Include(j => j.Group).ThenInclude(g => g!.AutoControl)
.Include(j => j.UnitFilters).ThenInclude(uf => uf.RelationshipFilters)
.FirstOrDefaultAsync(j => j.Id == context.JobId, ct);