Чек-лист для ревью кода в GlobalFramework#

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


1. Метаописания и Структура Классов#

  • [ ] Именование: Классы (<Модуль>_<Имя>, CamelCase) и атрибуты (camelCase) — уникальны, осознанны, без транслита.

  • [ ] Типы и связи: GSF-типы (NLong, NNumber, NString, NDate, NBigDecimal, NGid и т.п.) корректны и соответствуют БД. Поля с Reference, VariableReference, GID настроены и отражают связи в метаданных.

  • [ ] JSON/Jsonb-поля: При использовании динамического расширения (JSONB) проверена настройка контейнера (тип Json), схема ключ–значение и необходимость индексов.

  • [ ] Чистота метаданных: Отсутствуют дублирующие или неиспользуемые поля и неактуальные связи.


2. Конфигурация Модулей GSF#

  • [ ] project.yaml: Проверены секции конфигурации проекта (версии Scala/Java, параметры сборки, список модулей). Указаны все нужные модули (calculation, source, target, custom при наличии) и их настройки (ветки, isPublish).

  • [ ] Структура и зависимости: Соответствие шаблонам проекта (src, resources, тесты). Зависимости между модулями описаны явно, циклические зависимости отсутствуют.

  • [ ] Сборка и публикация: Конфигурации сборки (например, sbt) и плагины корректны. Названия модулей и подпроектов соответствуют соглашениям.


3. Использование стандартных компонентов GSF#

  • [ ] Встроенные сервисы: По возможности используются готовые сервисы фреймворка (аудит, автонумерация, группировка, поиск по шаблону, прикреплённые файлы).

  • [ ] Кэширование: Для часто запрашиваемых сущностей настроены cache-index в ORM, используется .unique() и tryCacheQueryResults(). Проверены стратегии инвалидирования кэша.

  • [ ] Логирование: Для записи логов используется LogTransaction. При большом количестве записей применяется commitByInterval().


4. Обработка Ошибок и Зависимости#

  • [ ] Исключения: Обрабатываются только AppException. Системные исключения выбрасываются дальше. Свои исключения создаются как подклассы AppException с фабрикой. Логирование ошибок — в отдельной транзакции.

  • [ ] Транзакции: Избегаются длинные транзакции. Большие операции разбиты на блоки с session.commitWorkAuto(). Неожиданные коммиты внутри server-side методов отсутствуют.


5. Особенности SQL в GSF#

  • [ ] Оптимизация и безопасность: Проверен план выполнения (EXPLAIN). Все запросы параметризованы. Используется NOT EXISTS вместо NOT IN.

  • [ ] ASQL vs ATSQL: ASQL — только для чтения; ATSQL — для DML и блокировок.

  • [ ] JOIN и типы: Выполняются по совместимым типам. Избегаются неявные преобразования.

  • [ ] Рекурсивные CTE: Имеют условие выхода и защиту от зацикливания.

  • [ ] Массовые операции: Реализованы через COPY или батчи. Долгие транзакции избегаются.

  • [ ] Функции GSF: getattribute, getmnemocode, getheadline и т.п. не используются в больших выборках без кэширования.


6. Требования к Структуре Scala-Кода#

  • [ ] D/A-паттерн: Бизнес-логика в ClassApi/ClassAvi. Генерируемые ClassDpi/ClassDvi не изменяются.

  • [ ] Null-типы GSF: Используются NLong, NNumber, NBigDecimal (для финансов), ===, .isNotNull.

  • [ ] Стиль и читаемость: Соблюдается CamelCase/camelCase, нет подчёркиваний. Методы короткие, используются view, pattern matching, trait для повторного использования.

  • [ ] Производительность: Избегаются лишние коллекции, используется ArrayBuffer. Циклы имеют верхний предел. Для больших наборов — стриминг.

  • [ ] Безопасность: null исключён. Используются headOption/getOption, а не head/get. Ветка else и case _ => обязательны.


7. Производительность#

  • [ ] .view: Используется при нескольких комбинаторах подряд.

  • [ ] Большие реестры: Запросы выполняются с максимальным количеством условий и session.flush().

  • [ ] Циклы: Максимальное число итераций проверено.

  • [ ] Мониторинг: Для массовых операций предусмотрен мониторинг и точки прерывания.


8. Работа с API и ROP#

  • [ ] HTTP/файлы: Используются btk_httppkg и btk_fileapi.

  • [ ] Загрузка/поиск: Btk_Pkg.loadByGid, findByMnemoCode(""). Объекты API объявлены через lazy val.

  • [ ] getVar: Используется get, а не asNLong.

  • [ ] Source-generated конструкции: Для доступа к атрибутам используется rop.get(_.attr).


9. Работа с Базой Данных и SQL (Дополнения)#

  • [ ] checkworkAbility: Не содержит запросов к БД.

  • [ ] Вложенные циклы: Запросы вне вложенных циклов.

  • [ ] onRefresh: Используется refreshByKey(parent).

  • [ ] @FlushBefore: Отключён в детализации документа.

  • [ ] OQuery: Используется итерация по списку или получение элемента в конце. Условия обрабатываются корректно (flush, filter, транз. индекс).

  • [ ] Параметры: Используется Symbol("param"), а не символьные литералы.


10. Архитектура и Дизайн#

  • [ ] lazy: Используется при объявлении переменных и в dataInstall.

  • [ ] API-методы: Типы параметров не меняются. Новые необязательные параметры добавляются в конец.

  • [ ] AVI: Сложная логика вынесена в API/PKG. AVI-операция сводится к вызову метода из API/PKG.

  • [ ] Scala-классы: Используется решение, позволяющее проектное переопределение.


11. Работа с Атрибутами и Полями (Дополнения)#

  • [ ] Source-generated доступ: Используется rop.get(_.attr) вместо getByAttrName.

  • [ ] getSelfVar: Используется A.idPerson.name вместо строкового имени.

  • [ ] Хранимые поля в AVI: Получаются через объект А.

  • [ ] var в case class: Атрибуты в case class в onRefresh — мутабельны.


12. Строки и JSON#

  • [ ] Интерполяция: Используется s"text${value}otherText" или многострочный вариант.

  • [ ] .stripMargin: Применяется для многострочных строк.

  • [ ] StringBuilder: Используется при сборке очень больших строк.

  • [ ] JSON: Не используется scala.util.parsing.json. Использование Btk_JsonPkg избегается.


13. Специфика UI: AVI и Списочные Отображения#

  • [ ] getVar / getSelfVar / A: В checkWorkAbility значения получаются через getVar, getSelfVar или A.

  • [ ] Большие поля: Не выводятся в списочные отображения.

  • [ ] @FlushBefore: В LookUp-отображениях для onRefresh добавлена аннотация @FlushBefore(mode = Disabled).

  • [ ] DefaultRep#deactivateOper: Используется для деактивации операций.

  • [ ] prepareSelectStatement: Сортировка по умолчанию и макросы фильтрации указаны в prepareSelectStatement.


14. Специфика UI: Кэширование, Логика и Настройки#

  • [ ] Переходы состояний: Определяются сравнением nOrder (условие из двух частей).

  • [ ] @Setter(refreshAfter = true): Выполняет selection.refreshItem() в конце сеттера.

  • [ ] Кастомные выборки: Реализованы объектным запросом, результат содержит id.

  • [ ] AdditionalInfo: Используется осторожно. Предпочтительнее onRefreshExt. Не создается AdditionalInfo2 для новых атрибутов.


15. Отражение (Reflection)#

  • [ ] Обоснование: Использование reflection оправдано; в общем случае запрещено.

  • [ ] scala.reflect.io._: Не используется, предпочтительнее Java-классы.


16. Специфика Модулей и Проектов#

  • [ ] Модуль STK: Для остатков — getRemainsMulti, для цены — getnPrCostConsSum.

  • [ ] Модуль ACT: Запрос оборотов выполняется с учётом логовой таблицы через union all.

  • [ ] Проектные модули: При открытии MR указывается соответствующая ветка (например, gs для sng-internal-dev).


17. Безопасность и Целостность Данных#

  • [ ] SQL-инъекции: Исключены за счёт параметризации.

  • [ ] Целостность: Ограничения (foreign key, unique) соответствуют метаданным. Валидации на уровне приложения дублируют БД-ограничения.

  • [ ] Чувствительные данные: Маскируются в логах и сообщениях об ошибках.


18. Соответствие Best Practices#

  • [ ] Scaladoc: Пишется scaladoc к методам, классам и переменным.

  • [ ] Комментарии: Код сопровождается понятными комментариями.

  • [ ] Форматирование: sql и scala код отформатированы и не превращаются в «кашу».

  • [ ] Именование: Переменным и атрибутам даются осознанные имена, транслит избегается. Следуются scala-конвенции наименования сущностей.

  • [ ] Чистота кода: Код читабельный, без дублирования. Имена ясно отражают назначение. Не используются служебные символы в идентификаторах.


19. Красные Флаги (Блокирующие)#

  • [ ] DML через ASQL: DML (INSERT/UPDATE/DELETE) выполняется через ASQL. — Блокирующее

  • [ ] Долгая транзакция: Долгая транзакция, захватывающая большое число строк без разбивки. — Блокирующее

  • [ ] Функции GSF в массовых выборках: Массовое использование getattribute/getmnemocode/getheadline в больших выборках/отчётах. — Блокирующее

  • [ ] Арифметика с N-типами: Арифметика с N-типами без проверки nullable (.isNotNull). — Блокирующее

  • [ ] Конкатенация строк SQL: SQL-строки формируются конкатенацией с пользовательскими данными. — Блокирующее

  • [ ] Дублирование логики: Необъяснимое и несогласованное дублирование логики в разных модулях. — Блокирующее