Руководство прикладника по разработке

Документ для тех, кто пишет прикладную логику на платформе: модули, события, формы, справочники, меню, HTTP/SQL и обновления приложений.

Цель руководства: чтобы можно было без захода в исходники Win32 начать и довести до рабочего флоу изменения в приложении.

Быстрый вход для новых приложений

  1. Выгрузить текущее приложение в архив:
python3 docs/downloads/tma_app_archive.py export-db \
  --database suvr_new \
  --output suvr_new.tma-source.zip
  1. Распаковать архив:
python3 docs/downloads/tma_app_archive.py unpack \
  --input suvr_new.tma-source.zip \
  --output suvr_new-source
  1. Редактировать файлы module.xml, form.xml, program.pas, триггеры.

  2. Проверить структуру:

python3 docs/downloads/tma_app_archive.py verify --input suvr_new-source
  1. Собрать XML обновления:
python3 docs/downloads/tma_app_archive.py pack \
  --input suvr_new-source \
  --output suvr_new-update.xml
  1. Загрузить в приложение через меню.

Где учиться дальше

Быстрые правила для прикладника

  • Не смешивайте режимы кодировок: XML и cp1251 — это legacy кодовая база, но для удобства редактирования берите UTF-8 в скриптах и репозитории (конвертируется через tma_app_archive.py).
  • Имена обработчиков всегда привязаны к объектам из module.xml:
  • Name="SaveBtn" у кнопки → OnSaveBtnClick
  • Name="Refresh", OnClick уже не нужен, движок добавляет OnRefreshClick
  • Для пунктов меню используйте Command:
  • Command="OnOpenCardClick" или Command="OpenCard"
  • если без Command, платформа строит On<name>Click сама
  • Любой изменённый модуль должен проходить проверку через verify и только потом через pack.
  • Критично: если в XML-структуре меню вы потеряли корневой элемент, приложение перестаёт определять обработчики и падает на инициализации.

Что важно понимать о runtime и отладке

  • Временный баг в логике (непойманное исключение) обычно останавливает сценарий целиком и показывает popup/trace из движка.
  • Для HTTP/внешних вызовов всегда проверяйте статусный код, не только текст тела ответа.
  • В SQL и скриптах для отладки полезны:
  • запись в лог через Warning/Raise (проверьте, какие системные функции доступны в вашем окружении; для плагинных сборок это может отличаться),
  • временные таблицы для проверки промежуточных значений.

Карта задач по задачнику прикладника

  1. Добавить новый справочник:
  2. создать Table (метаданные), Form и Reference.
  3. проставить PrimaryKeyField, DescriptionField, Parent для справочника.
  4. завести события и триггеры по нуждам.

  5. Добавить новый пункт меню:

  6. править MainMenu, указывая Command.
  7. либо Name, либо Command должны совпадать с обработчиком.

  8. Изменить бизнес-логику существующего процесса:

  9. править Program модуля или модульные скрипты,
  10. собрать частичный архив для конкретных модулей,
  11. собрать и загрузить через pack-db.

  12. Перенос на headless/web:

  13. использовать тот же XML-модельный контракт,
  14. запускать сервер и прогонять smoke по формам/справочникам.

Набор источников, которые нужно держать под рукой

  • docs/development/source-archive.md — как экспортировать и собирать архив.
  • docs/development/application-model.md — что внутри module.xml и form.xml.
  • docs/development/runtime-api.md — все практичные функции для скриптов.
  • docs/development/sidemenu-component.md — объектная модель SideMenu.
  • docs/development/forms-references.md — формы, таблицы, справочники.

Полный рабочий конвейер изменений

1) Подготовка исходников

  1. Определи задачу и минимальный список модулей, которые меняются.
  2. Проверь, какие модули реально участвуют (например, Table, Reference, Form, иногда триггеры before_*, after_* и Stored).
  3. Если меняются только отдельные модули — делай выборочную выгрузку, а не полный export для ускорения.

Рекомендуемый порядок:

# Полная выгрузка
python3 docs/downloads/tma_app_archive.py export-db --database my1 --output app.tma-source.zip
# Выборочная выгрузка только нужных модулей
python3 docs/downloads/tma_app_archive.py export-db --database my1 --module task --module taskForm --module taskReference --output task-pack.tma-source.zip

2) Редактирование и единообразие

  • Не трогай одновременно один и тот же объект в двух модулях (например Reference и связанный с ним Table) без необходимости.
  • Если редактируешь MainMenu — поддерживай один источник истины: Item Command, Name, Caption, иерархию. Дублирование веток в нескольких файлах почти всегда приводит к «схлопыванию» и некорректным обработчикам.
  • Для больших изменений делай правки в порядке: module.xml → program.pas → form.xml.

3) Проверки перед сборкой

python3 docs/downloads/tma_app_archive.py verify --input unpacked-dir

Что проверять до pack:

  • Module уникальность имён по типу.
  • Корректность Parent для Reference/Form.
  • Наличие и валидность Name у элементов интерфейса.
  • Отсутствие невалидных ссылок на таблицы и поля (DataType="*Table").
  • Формат команд: OnXClick для кнопок и меню, если событие в Pascal используется.

4) Сборка и нагрузка в тестовую БД

  • Для частичных изменений делай pack-db, чтобы не потерять общие секции приложения:
python3 docs/downloads/tma_app_archive.py pack-db --database my1 --input task-pack --output task-update.xml
  • Загрузи обновление в тестовый стенд/БД и только после проверки — в прод.

5) Приёмка после изменения

Минимальный smoke:

  1. Открыть главное меню.
  2. Открыть измененный справочник/форму.
  3. Проверить создание/изменение/сохранение записи.
  4. Проверить закрытие формы и перезапуск окна после ошибки.
  5. Проверить сетевые/HTTP сценарии с явной проверкой StatusCode.

Чек-лист для форм и справочников

Для Form и Reference держи этот список как обязательный:

  • Parent указывает на корректную Table.
  • У таблицы есть PrimaryKeyField и DescriptionField.
  • Permissions (Select/Insert/Update/Delete) разрешены роли пользователя.
  • Имена контролов уникальны.
  • Ключевые lookup-поля (DataType="*Table") указывают на существующие таблицы.
  • Обработчики событий объявлены в program.pas с точной сигнатурой (Procedure).
  • Проверены Filter/ExtFilter/ResultFilter на конфликты.
  • Для действий по кнопкам: On<Имя>Click реально существует.

Частые ошибки и быстрые причины

  • SideMenu.Command: ... не найден:
  • Command не указан или опечатка.
  • Обработчик не объявлен как Procedure OnXClick.
  • Command и Name не согласованы с тем, что реально ожидает скрипт.
  • Неверный тип поля / пустая форма:
  • неправильный Parent или расхождение DataType.
  • Форма открывается, но не сохраняется:
  • используется transaction/SQL сценарий с исключением в Try/Except;
  • отсутствует фактический Apply.
  • Ошибки при импорте/выгрузке:
  • есть конфликт кодировок при ручном редактировании legacy-пакета;
  • невалидный XML или битая структура module.xml.

Типовые шаблоны кода (Pascal)

1) Проверить создание и применить запись

Procedure OnSaveClick;
Begin
  If Trim(Form.Item('Header').Text) = '' Then
    Raise('Тема должна быть заполнена');
  Form.Apply;
  Form.Close;
End;

2) Безопасный HTTP вызов

Procedure SendDoc;
Var r : Record;
Begin
  r = HttpPostEx('https://api.internal.local/send', payload, headers);
  If Not r.Ok Then
    Raise('HTTP_' + r.StatusCode);
End;

3) Защищенный SQL-сценарий

Procedure OnCreate;
Var sqlText : String;
Begin
  sqlText = 'Select * From task Where project_id = ' + SqlArg_i(projectId);
  Query(sqlText);
End;

Протоколирование и диагностика

  • Используй Warning(...) для трассировки шагов в UI-трассах.
  • Для критичных ошибок — Raise с коротким кодом и контекстом:
  • Raise('ERR_SAVE_FAILED: ' + GetExceptionText()).
  • Для отладки больших ветвей лучше добавлять минимальные маркеры в начале ветвления и фиксировать вход/выход.

Рекомендации по подготовке релизного архива

  • Для изменений, которые затрагивают только одну бизнес-секцию, используй pack-db, чтобы исключить риск перезаписать нецелевые модули.
  • Перед финальной загрузкой:
  • снять дамп/экспорт текущего состояния;
  • проверить pack и размер итогового файла;
  • зафиксировать ticket/задачу и список изменённых модулей.

Что читать после этого