Рефакторинг обработчиков #21
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📊 Анализ обработчиков и выявленные проблемы
Анализ более чем 50 файлов в директориях src/handlers/admin и src/handlers выявил несколько сквозных проблем, которые и будет решать наш план:
Отсутствие документации: Почти все обработчики не экспортируют trails/0, поэтому Swagger не знает об их существовании.
Дублирование кода: Вспомогательные функции, такие как send_json/3, send_error/3, auth_admin/1, parse_datetime/1 и review_to_json/1, многократно копируются из модуля в модуль.
Неполная сериализация: Многие функции *_to_json/1 не учитывают новые поля, добавленные в записи records.hrl (например, social_links у пользователя, edit_history у события, likes/dislikes у отзыва и т.д.).
Нет пагинации: Критически важные для производительности эндпоинты, возвращающие списки, не поддерживают пагинацию, фильтрацию и сортировку (например, admin_handler_users, admin_handler_reports, admin_handler_tickets).
📝 План рефакторинга (6 этапов)
Этот план нацелен на системное решение всех найденных проблем.
Этап 1: Создание фундамента — модуль handler_utils
Первый и самый важный шаг — устранить дублирование кода. Мы создадим модуль handler_utils, который станет «библиотекой» для всех обработчиков. Сюда будут вынесены:
Аутентификация: auth_admin(Req) и auth_user(Req).
HTTP-ответы: send_json(Req, Status, Data), send_error(Req, Status, Message).
Парсинг параметров: parse_int_qs/2, parse_datetime/1, parse_pagination_params(Req).
Сериализация: Полные и актуальные функции event_to_json/1, user_to_json/1, review_to_json/1, report_to_json/1, ticket_to_json/1 и т.д., в которых будут учтены все поля из records.hrl.
Swagger-помощники: Функция trails_for_crud(Path, Resource, Schema, UpdateSchema), которая будет генерировать стандартный набор трейлов для типовых CRUD-эндпоинтов.
Этап 2: Актуализация сериализации
После создания handler_utils мы проверим и дополним все функции *_to_json/1. Сверяясь с records.hrl, мы добавим в JSON-представление все новые поля, которые сейчас отсутствуют, но должны быть доступны клиенту. Пример для admin_handler_reviews: сейчас функция review_to_json не включает поля likes и dislikes. В рамках этого этапа мы добавим их наряду с reason.
erlang
%% Фрагмент review_to_json/1 после актуализации
review_to_json(R) -> #{
id => R#review.id,
user_id => R#review.user_id,
target_type => R#review.target_type,
target_id => R#review.target_id,
rating => R#review.rating,
comment => R#review.comment,
status => R#review.status,
reason => R#review.reason, % <-- Добавлено
likes => R#review.likes, % <-- Добавлено
dislikes => R#review.dislikes, % <-- Добавлено
created_at => datetime_to_iso8601(R#review.created_at),
updated_at => datetime_to_iso8601(R#review.updated_at)
}.
Этап 3: Внедрение пагинации, фильтрации и сортировки
Это ключевой этап для производительности. Мы возьмем за образец отлично реализованный admin_handler_events и logic_event:search_events/1 и внедрим аналогичный подход во все эндпоинты, возвращающие списки. Это коснется:
admin_handler_users
admin_handler_reports
admin_handler_tickets
admin_handler_subscriptions
admin_handler_audit
handler_events
handler_calendars
И других.
Каждый такой эндпоинт получит поддержку параметров limit, offset, sort, order и специфичные для сущности фильтры.
Этап 4: Документирование через @doc, -spec и trails/0
На этом этапе мы приведем код к единому стандарту документирования:
Добавим аннотации @doc ко всем публичным функциям в каждом обработчике.
Добавим спецификации типов (-spec). В первую очередь для всех функций в logic_* и handler_utils, а затем и для ключевых функций в обработчиках.
Добавим экспорт trails/0 в каждый обработчик. Для типовых CRUD-эндпоинтов будем использовать handler_utils:trails_for_crud/4, а для нестандартных — описывать трейлы вручную.
Этап 5: Обновление реестра trails.erl
После того как все обработчики будут готовы, мы обновим модуль trails.erl, чтобы он знал о них всех. Списки admin() и client() будут наполнены актуальными модулями, и Swagger начнет отображать полную документацию по API.
Этап 6: Финальное тестирование
Завершающий этап — расширение тестового модуля api_admin_tests.erl. Мы добавим новые тесты для проверки:
Работоспособности пагинации.
Корректности фильтрации.
Успешного получения Swagger-спецификации для всех эндпоинтов.