From 6c93e1971faf5a187f4579424e1676a359f9a41b Mon Sep 17 00:00:00 2001 From: Mikhail Kuznetsov Date: Thu, 16 Jul 2026 15:00:17 +1000 Subject: [PATCH] =?UTF-8?q?fix(templateMatcher):=20=D0=98=D1=81=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=B1=D0=B0=D0=B3=20?= =?UTF-8?q?=D0=B2=20AutoControlResolver=20=D0=B8=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=B2=D0=BB=D0=B5=D0=BD=20Include=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20AutoControl=20=D0=B3=D1=80=D1=83=D0=BF=D0=BF?= =?UTF-8?q?=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Добавлены строгие проверки на null для `GroupType`, `jobGroup.AutoControl` и `job.AutoControl` с генерацией исключений. - В запрос загрузки данных добавлен `.Include(j => j.Group).ThenInclude(g => g.AutoControl)`, исправивший падение в дефолтные состояния. --- .../Implementations/AutoControlResolver.cs | 51 ++++++++++++++----- .../Services/SimpleSync/LoadJobStage.cs | 2 +- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/PARR.TemplateMatcher/Services/Implementations/AutoControlResolver.cs b/PARR.TemplateMatcher/Services/Implementations/AutoControlResolver.cs index 4ca82b79..1c117157 100644 --- a/PARR.TemplateMatcher/Services/Implementations/AutoControlResolver.cs +++ b/PARR.TemplateMatcher/Services/Implementations/AutoControlResolver.cs @@ -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) - { - return ( - job.AutoControl.InitUsedTemplateState, - job.AutoControl.InitUsedScheduleState - ); - } + // 3. Сценарий: Управление на уровне конкретной Работы + if (job.AutoControl == null) + throw new InvalidOperationException( + $"В типе группы '{jobGroup.GroupType.Id}' указано управление " + + $"на уровне РАБОТЫ, но у работы '{job.Name}' (ID: {job.Id}) " + + $"отсутствуют настройки автоконтроля (Job.AutoControl равен null)!"); - return (defaultTemplateState, defaultScheduleState); + return ( + job.AutoControl.InitUsedTemplateState, + job.AutoControl.InitUsedScheduleState + ); } + } } diff --git a/PARR.TemplateMatcher/Services/SimpleSync/LoadJobStage.cs b/PARR.TemplateMatcher/Services/SimpleSync/LoadJobStage.cs index d4849ddf..6692c7fe 100644 --- a/PARR.TemplateMatcher/Services/SimpleSync/LoadJobStage.cs +++ b/PARR.TemplateMatcher/Services/SimpleSync/LoadJobStage.cs @@ -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);