Перейти к основному содержимому

Архитектура ФО и оценки заданий — План реализации

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Формализовать двухуровневую архитектуру функциональных опций: добавить проектный флаг ФункциональностьОценки, удалить бесполезный ФункциональностьServiceDesk, добавить валидацию между глобальными ФО и проектными флагами.

Architecture: Трехуровневая цепочка: Редакция → Глобальная ФО → Проектный флаг → UI формы задания. Проектные флаги управляют видимостью динамических реквизитов и вкладок на форме задания через ЗаданияСервер.ИспользуемаяФункциональность().

Tech Stack::EDT, BSL, MCP EDT tools (для .bsl файлов), прямое редактирование .mdo/.form XML

Spec: docs/superpowers/specs/2026-04-07-functional-options-architecture-design.md


Порядок задач

Миграция данных (Task 5) должна выполняться ДО удаления ФункциональностьServiceDesk (Task 6-7), т.к. она читает старое значение.

Task 1: Добавить реквизит ФункциональностьОценки в Проекты.mdo
Task 2: Добавить элемент формы на вкладку "Функционал"
Task 3: Добавить обработчик и логику в модуль формы проекта (BSL)
Task 4: Добавить в API проекта (ManagerModule)
Task 5: Обработчик обновления ИБ (миграция данных)
Task 6: Добавить "Оценки" в ЗаданияСервер и форму задания (BSL)
Task 7: Удалить ФункциональностьServiceDesk из кода (BSL)
Task 8: Удалить ФункциональностьServiceDesk из метаданных (.mdo, .form)
Task 9: Добавить валидацию между глобальными ФО и проектными флагами
Task 10: Документация архитектуры ФО

Task 1: Добавить реквизит ФункциональностьОценки в Проекты.mdo

Files:

  • Modify: it/src/Catalogs/Проекты/Проекты.mdo:655 (вставить после ФункциональностьServiceDesk)

  • Step 1: Сгенерировать UUID

[guid]::NewGuid().ToString()

Запомнить результат — это UUID нового реквизита.

  • Step 2: Добавить реквизит в .mdo

Вставить после строки 655 (после закрывающего </attributes> реквизита ФункциональностьServiceDesk), перед ФункциональностьSLA:

  <attributes uuid="СГЕНЕРИРОВАННЫЙ-UUID">
<name>ФункциональностьОценки</name>
<synonym>
<key>ru</key>
<value>Функциональность оценки</value>
</synonym>
<type>
<types>Boolean</types>
</type>
<toolTip>
<key>ru</key>
<value>Отображать поле оценки выполнения в задачах проекта</value>
</toolTip>
<minValue xsi:type="core:UndefinedValue"/>
<maxValue xsi:type="core:UndefinedValue"/>
<fillValue xsi:type="core:BooleanValue"/>
<fullTextSearch>Use</fullTextSearch>
<dataHistory>Use</dataHistory>
</attributes>
  • Step 3: Проверить ошибки EDT

MCP: get_project_errors — убедиться что новый реквизит не вызвал ошибок.

  • Step 4: Commit
git add it/src/Catalogs/Проекты/Проекты.mdo
git commit -m "feat(T-XXXXX): Добавлен реквизит ФункциональностьОценки в справочник Проекты"

Task 2: Добавить элемент формы на вкладку "Функционал"

Files:

  • Modify: it/src/Catalogs/Проекты/Forms/ФормаЭлемента/Form.form:2048 (вставить после ФункциональностьServiceDesk)

  • Step 1: Определить id для новых элементов

Найти максимальный <id> в форме:

grep -oP '<id>\K[0-9]+' it/src/Catalogs/Проекты/Forms/ФормаЭлемента/Form.form | sort -n | tail -5

Новым элементам назначить id = max+1, max+2, max+3 (основной, контекстное меню, расширенная подсказка).

  • Step 2: Добавить элемент CheckBox в Form.form

Вставить после строки 2048 (после закрывающего </items> элемента ФункциональностьServiceDesk), перед элементом ФункциональностьТрудозатраты. Использовать как шаблон элемент ФункциональностьКлиенты (строки 2098-2144), заменив:

  • <name>ФункциональностьОценки
  • <id> → новые id (3 штуки: основной, контекстное меню, подсказка)
  • <dataPath>Объект.ФункциональностьОценки
  • <handlers>ФункциональностьОценкиПриИзменении
  • <title>Оценки
  • <toolTip>Отображать поле оценки выполнения в задачах проекта
  • checkBoxTypeSwitcher (как у остальных)

Структура элемента (3 XML-блока):

  1. Основной <items xsi:type="form:FormField"> с <type>CheckBoxField</type>
  2. Внутри: <contextMenu> с собственным <name> и <id>
  3. Внутри: <extendedTooltip> с собственным <name> и <id>
  • Step 3: Добавить поле СКД в ФормаВыбора проектов

В файле it/src/Catalogs/Проекты/Forms/ФормаВыбора/Form.form после строки с ФункциональностьServiceDesk (~784) добавить по аналогии:

          <field>ФункциональностьОценки</field>
<field>ФункциональностьОценки</field>
  • Step 4: Добавить поле СКД в ФормаСписка заданий

В файле it/src/Documents/Задание/Forms/ФормаСписка/Form.form после строки с ФункциональностьServiceDesk (~5131) добавить по аналогии:

          <field>ФункциональностьОценки</field>
<field>ФункциональностьОценки</field>
  • Step 5: Проверить ошибки EDT

MCP: get_project_errors — убедиться что форма корректна.

  • Step 6: Commit
git add it/src/Catalogs/Проекты/Forms/ФормаЭлемента/Form.form
git add it/src/Catalogs/Проекты/Forms/ФормаВыбора/Form.form
git add it/src/Documents/Задание/Forms/ФормаСписка/Form.form
git commit -m "feat(T-XXXXX): Элемент формы ФункциональностьОценки на вкладке Функционал"

Task 3: Добавить обработчик в модуль формы проекта

Files:

  • Modify: it/src/Catalogs/Проекты/Forms/ФормаЭлемента/Module.bsl

  • Step 1: Добавить обработчик ФункциональностьОценкиПриИзменении

Через MCP read_module_source прочитать модуль формы. Затем через write_module_source добавить после обработчика ФункциональностьServiceDeskПриИзменении (после строки 360):

&НаКлиенте
Процедура ФункциональностьОценкиПриИзменении(Элемент)
ФункциональностьПриИзменении(Элемент);
КонецПроцедуры

Шаблон идентичен остальным обработчикам (строки 342-379).

  • Step 2: Проверить ошибки EDT

MCP: get_project_errors

  • Step 3: Commit
git add it/src/Catalogs/Проекты/Forms/ФормаЭлемента/Module.bsl
git commit -m "feat(T-XXXXX): Обработчик ФункциональностьОценкиПриИзменении"

Task 4: Добавить в API проекта (ManagerModule)

Files:

  • Modify: it/src/Catalogs/Проекты/ManagerModule.bsl

Через MCP read_module_source прочитать модуль, затем write_module_source внести изменения.

  • Step 1: Словарь десериализации

После строки 72 (features_service_desk) добавить:

ДанныеAPI.СловарьДесериализации.Вставить("features_ratings", "ФункциональностьОценки");
  • Step 2: НовыйОбъектAPI

После строки 382 (ФункциональностьServiceDesk) добавить:

ОбъектAPI.Вставить("ФункциональностьОценки", Ложь);
  • Step 3: СериализаторПроекта

В инициализации ОбъектFeatures (после строки с service_desk, ~419) добавить:

ОбъектFeatures.Вставить("ratings", Ложь);

В блоке сериализации (после блока service_desk, ~446) добавить:

Если ОбъектAPI.Свойство("ФункциональностьОценки") Тогда
ОбъектFeatures.Вставить("ratings", ОбъектAPI.ФункциональностьОценки);
КонецЕсли;
  • Step 4: ДесериализаторПроекта

В блоке десериализации (после блока service_desk, ~512) добавить:

Если ОбъектFeatures.Свойство("ratings") Тогда
Результат.Вставить("ФункциональностьОценки", ОбъектFeatures.ratings);
КонецЕсли;
  • Step 5: SELECT-запросы

В обоих SELECT-запросах (после строк с ФункциональностьServiceDesk, ~1494 и ~1558) добавить:

ДанныеОбъекта.ФункциональностьОценки КАК ФункциональностьОценки,
  • Step 6: Проверить ошибки EDT

MCP: get_project_errors

  • Step 7: Commit
git add it/src/Catalogs/Проекты/ManagerModule.bsl
git commit -m "feat(T-XXXXX): API проекта - поле features_ratings"

Task 5: Обработчик обновления ИБ (миграция данных)

Files:

  • Modify: it/src/CommonModules/УправлениеITОтделом8УФОбновлениеИнформационнойБазыБСП/Module.bsl

Эта задача выполняется ДО удаления ФункциональностьServiceDesk.

  • Step 1: Найти процедуру регистрации обработчиков обновления

Через MCP read_module_source прочитать модуль. Найти процедуру ПриДобавленииОбработчиковОбновления и текущую версию конфигурации. Найти последний зарегистрированный обработчик, чтобы понять формат и версию.

  • Step 2: Зарегистрировать новый обработчик

В процедуре ПриДобавленииОбработчиковОбновления добавить регистрацию обработчика для текущей версии:

Обработчик = Обработчики.ДобавитьНовый();
Обработчик.Версия = "ТЕКУЩАЯ_ВЕРСИЯ";
Обработчик.Процедура = "УправлениеITОтделом8УФОбновлениеИнформационнойБазыБСП.ПеренестиФункциональностьОценкиИзServiceDesk";
  • Step 3: Написать процедуру миграции
Процедура ПеренестиФункциональностьОценкиИзServiceDesk() Экспорт

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Проекты.Ссылка КАК Ссылка
|ИЗ
| Справочник.Проекты КАК Проекты
|ГДЕ
| Проекты.ФункциональностьServiceDesk = ИСТИНА
| И Проекты.ФункциональностьОценки = ЛОЖЬ";

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл

ОбъектПроекта = Выборка.Ссылка.ПолучитьОбъект();
ОбъектПроекта.ФункциональностьОценки = Истина;
ОбъектПроекта.ОбменДанными.Загрузка = Истина;
ОбъектПроекта.Записать();

КонецЦикла;

КонецПроцедуры
  • Step 4: Проверить ошибки EDT

MCP: get_project_errors

  • Step 5: Commit
git add it/src/CommonModules/УправлениеITОтделом8УФОбновлениеИнформационнойБазыБСП/Module.bsl
git commit -m "feat(T-XXXXX): Обработчик обновления - миграция ФункциональностьОценки"

Task 6: Добавить "Оценки" в ЗаданияСервер и форму задания

Files:

  • Modify: it/src/CommonModules/ЗаданияСервер/Module.bsl

  • Modify: it/src/Documents/Задание/Forms/ФормаДокумента/Module.bsl

  • Step 1: ЗаданияСервер — добавить в запрос ИспользуемаяФункциональность

Через MCP read_module_source прочитать ЗаданияСервер. В запросе функции ИспользуемаяФункциональность (после строки 229 с ФункциональностьServiceDesk) добавить:

ЕСТЬNULL(МАКСИМУМ(Проекты.ФункциональностьОценки), ЛОЖЬ) КАК ФункциональностьОценки,
  • Step 2: ЗаданияСервер — добавить обработку результата

После блока ServiceDesk (после строки ~268) добавить:

Если Выборка.ФункциональностьОценки Тогда
Результат.Добавить("Оценки");
КонецЕсли;
  • Step 3: ФормаДокумента — добавить в ОтображатьРеквизитВсегда

Через MCP read_module_source прочитать Задание.ФормаДокумента. В функции ОтображатьРеквизитВсегда после блока "Service Desk" (после строки ~3868) добавить:

Набор = Новый Массив();
Набор.Добавить("ОценкаВыполнения");
ИспользуемыеРеквизиты.Вставить("Оценки", Набор);
  • Step 4: Проверить ошибки EDT

MCP: get_project_errors

  • Step 5: Commit
git add it/src/CommonModules/ЗаданияСервер/Module.bsl
git add it/src/Documents/Задание/Forms/ФормаДокумента/Module.bsl
git commit -m "feat(T-XXXXX): Оценки в ИспользуемаяФункциональность и динамических реквизитах"

Task 7: Удалить ФункциональностьServiceDesk из кода (BSL)

Files:

  • Modify: it/src/CommonModules/ЗаданияСервер/Module.bsl

  • Modify: it/src/Documents/Задание/Forms/ФормаДокумента/Module.bsl

  • Modify: it/src/Catalogs/Проекты/ManagerModule.bsl

  • Modify: it/src/Catalogs/Проекты/Forms/ФормаЭлемента/Module.bsl

  • Step 1: ЗаданияСервер — удалить из запроса

Через MCP read_module_source и write_module_source. Удалить строку из запроса ИспользуемаяФункциональность:

ЕСТЬNULL(МАКСИМУМ(Проекты.ФункциональностьServiceDesk), ЛОЖЬ) КАК ФункциональностьServiceDesk,

Удалить блок обработки результата (строки ~264-268):

Если Выборка.ФункциональностьServiceDesk Тогда
Результат.Добавить("Service Desk");
КонецЕсли;
  • Step 2: ФормаДокумента — удалить из ОбновитьВидимостьВкладок

Удалить строку ~3628:

ПоказатьРешения = Функциональность.Найти("Service Desk") <> Неопределено;

Изменить строку ~3631 — убрать ИЛИ ПоказатьРешения:

// Было:
Элементы.ГруппаВкладкаРешения.Видимость = Объект.Решения.Количество() <> 0 ИЛИ ПоказатьРешения;
// Стало:
Элементы.ГруппаВкладкаРешения.Видимость = Объект.Решения.Количество() <> 0;
  • Step 3: ФормаДокумента — удалить из ОтображатьРеквизитВсегда

Удалить блок (строки ~3867-3868):

Набор = Новый Массив();
ИспользуемыеРеквизиты.Вставить("Service Desk", Набор);
  • Step 4: ManagerModule — удалить из словаря десериализации

Удалить строку 72:

ДанныеAPI.СловарьДесериализации.Вставить("features_service_desk", "ФункциональностьServiceDesk");
  • Step 5: ManagerModule — удалить из НовыйОбъектAPI

Удалить строку 382:

ОбъектAPI.Вставить("ФункциональностьServiceDesk", Ложь);
  • Step 6: ManagerModule — удалить из сериализатора/десериализатора

Удалить из инициализации ОбъектFeatures:

ОбъектFeatures.Вставить("service_desk", Ложь);

Удалить блок сериализации:

Если ОбъектAPI.Свойство("ФункциональностьServiceDesk") Тогда
ОбъектFeatures.Вставить("service_desk", ОбъектAPI.ФункциональностьServiceDesk);
КонецЕсли;

Удалить блок десериализации:

Если ОбъектFeatures.Свойство("service_desk") Тогда
Результат.Вставить("ФункциональностьServiceDesk", ОбъектFeatures.service_desk);
КонецЕсли;
  • Step 7: ManagerModule — удалить из SELECT-запросов

В обоих запросах (~1494 и ~1558) удалить:

ДанныеОбъекта.ФункциональностьServiceDesk КАК ФункциональностьServiceDesk,
  • Step 8: Модуль формы проекта — удалить обработчик

Удалить строки 356-360:

&НаКлиенте
Процедура ФункциональностьServiceDeskПриИзменении(Элемент)
ФункциональностьПриИзменении(Элемент);
КонецПроцедуры
  • Step 9: Проверить ошибки EDT

MCP: get_project_errors — убедиться что нет ошибок после удаления.

  • Step 10: Commit
git add it/src/CommonModules/ЗаданияСервер/Module.bsl
git add it/src/Documents/Задание/Forms/ФормаДокумента/Module.bsl
git add it/src/Catalogs/Проекты/ManagerModule.bsl
git add it/src/Catalogs/Проекты/Forms/ФормаЭлемента/Module.bsl
git commit -m "refactor(T-XXXXX): Удален ФункциональностьServiceDesk из кода"

Task 8: Удалить ФункциональностьServiceDesk из метаданных

Files:

  • Modify: it/src/Catalogs/Проекты/Проекты.mdo:637-655

  • Modify: it/src/Catalogs/Проекты/Forms/ФормаЭлемента/Form.form:2002-2048

  • Modify: it/src/Catalogs/Проекты/Forms/ФормаВыбора/Form.form:783-784

  • Modify: it/src/Documents/Задание/Forms/ФормаСписка/Form.form:5130-5131

  • Step 1: Удалить реквизит из Проекты.mdo

Удалить строки 637-655 (блок <attributes> с ФункциональностьServiceDesk):

  <attributes uuid="ca69e938-fb5d-4116-9b8e-f6090bf4ab35">
<name>ФункциональностьServiceDesk</name>
...
</attributes>
  • Step 2: Удалить элемент из ФормаЭлемента/Form.form

Удалить строки 2002-2048 (блок <items> с ФункциональностьServiceDesk, включая контекстное меню и расширенную подсказку).

  • Step 3: Удалить поле из ФормаВыбора/Form.form

Удалить строки 783-784 (поле СКД ФункциональностьServiceDesk).

  • Step 4: Удалить поле из ФормаСписка/Form.form (Задание)

Удалить строки 5130-5131 (поле СКД ФункциональностьServiceDesk).

  • Step 5: Проверить ошибки EDT

MCP: get_project_errors — убедиться что удаление реквизита не вызвало ошибок в формах и модулях.

  • Step 6: Commit
git add it/src/Catalogs/Проекты/Проекты.mdo
git add it/src/Catalogs/Проекты/Forms/ФормаЭлемента/Form.form
git add it/src/Catalogs/Проекты/Forms/ФормаВыбора/Form.form
git add it/src/Documents/Задание/Forms/ФормаСписка/Form.form
git commit -m "refactor(T-XXXXX): Удален ФункциональностьServiceDesk из метаданных"

Task 9: Валидация между глобальными ФО и проектными флагами

Files:

  • Modify: it/src/Catalogs/Проекты/Forms/ФормаЭлемента/Module.bsl

  • Step 1: Добавить процедуру валидации

Через MCP read_module_source и write_module_source. Добавить новую процедуру УстановитьДоступностьФункциональности в область СлужебныеПроцедурыИФункции:

&НаСервере
Процедура УстановитьДоступностьФункциональности()

Элементы.ФункциональностьSLA.Доступность =
ПолучитьФункциональнуюОпцию("SLAСервисыРаботы");

Элементы.ФункциональностьСклад.Доступность =
ПолучитьФункциональнуюОпцию("ИспользоватьСкладскойУчет");

Элементы.ФункциональностьТрудозатраты.Доступность =
ПолучитьФункциональнуюОпцию("ИспользоватьУчетВремени");

КонецПроцедуры

Флаги ФункциональностьОценки, ФункциональностьКлиенты, ФункциональностьСинхронизацияСтатусаИРазделов — без ограничений (нет глобальной ФО-пары).

  • Step 2: Вызвать из ПриСозданииНаСервере

В процедуре ПриСозданииНаСервере (строки 5-42) добавить вызов перед КонецПроцедуры:

УстановитьДоступностьФункциональности();
  • Step 3: Вызвать из ПриЧтенииНаСервере

В процедуре ПриЧтенииНаСервере (~строка 58) добавить вызов:

УстановитьДоступностьФункциональности();
  • Step 4: Проверить ошибки EDT

MCP: get_project_errors

  • Step 5: Commit
git add it/src/Catalogs/Проекты/Forms/ФормаЭлемента/Module.bsl
git commit -m "feat(T-XXXXX): Валидация проектных флагов по глобальным ФО"

Task 10: Документация архитектуры ФО

Files:

  • Create: .claude/docs/functional-options-architecture.md

  • Modify: .claude/docs/navigation.md

  • Step 1: Создать документ архитектуры

Файл .claude/docs/functional-options-architecture.md:

# Архитектура функциональных опций

## Трехуровневая цепочка

Каждая бизнес-функция управляется через трехуровневую цепочку:

1. **Редакция** (лицензия) → определяет доступность глобальных ФО
- Механизм: `СЛС.УстановитьФункционал()`
2. **Глобальная ФО** (константа) → определяет доступность проектных флагов
- Механизм: `ПолучитьФункциональнуюОпцию()` в форме проекта
3. **Проектный флаг** (реквизит Проекты) → определяет UI формы задания
- Механизм: `ЗаданияСервер.ИспользуемаяФункциональность()`

Не каждый уровень обязателен:
- Функция без глобального рубильника — только проектный флаг (ФункциональностьКлиенты)
- Функция без проектной гранулярности — только глобальная ФО (ИспользоватьБизнесПроцессыИЗадачи)

## Таблица проектных флагов

| Проектный флаг | Глобальная ФО | Редакции | Эффект на форме задания |
|---|---|---|---|
| ФункциональностьSLA | SLAСервисыРаботы | ПРОФ, КОРП | Панель SLA, скрытие Приоритета, реквизиты Организация/Клиент/Дедлайн/Ответственный |
| ФункциональностьСклад | ИспользоватьСкладскойУчет | Все | Вкладка "Номенклатура", реквизит МестоХранения |
| ФункциональностьТрудозатраты | ИспользоватьУчетВремени | КОРП | Вкладка "Трудозатраты" |
| ФункциональностьОценки || Все | Реквизит ОценкаВыполнения |
| ФункциональностьКлиенты || Все | Реквизит Клиент + автозаполнение |
| ФункциональностьСинхронизацияСтатусаИРазделов || Все | Автоперемещение заданий при смене статуса |

## Глобальные ФО ServiceDesk

- `ИспользоватьServiceDesk` — базовый модуль заданий (все редакции)
- `SLAСервисыРаботы` — расширение ServiceDesk (ПРОФ/КОРП)
- `ИспользоватьServiceDesk` является пререквизитом для `SLAСервисыРаботы`

## Принцип добавления нового функционала

1. Определить: нужен ли глобальный рубильник? (если функция привязана к редакции — да)
2. Определить: нужна ли гранулярность по проектам? (если разные проекты могут иметь разное поведение — да)
3. Добавить проектный флаг `Функциональность<Имя>` в Проекты.mdo
4. Добавить в `ЗаданияСервер.ИспользуемаяФункциональность()`
5. Добавить набор реквизитов в `ОтображатьРеквизитВсегда` формы задания
6. Если есть глобальная ФО — добавить валидацию в `УстановитьДоступностьФункциональности()`
  • Step 2: Обновить navigation.md

Добавить ссылку в .claude/docs/navigation.md:

- `functional-options-architecture.md` — архитектура ФО: трехуровневая цепочка, проектные флаги, редакции
  • Step 3: Commit
git add .claude/docs/functional-options-architecture.md .claude/docs/navigation.md
git commit -m "docs(T-XXXXX): Документация архитектуры функциональных опций"