P0: GET /v1/events/:id/bookings отдаёт 500 — владелец не видит заявки #51
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?
Проблема
На stage
GET /v1/events/:id/bookingsвозвращает HTTP 500. В UI владелец события видит «Нет заявок» и не может подтвердить/отклонить pending-запись кнопками.Причина:
handler_bookings:list_bookings/1вызываетlogic_booking:list_event_bookings(UserId, EventId)(arity 2), тогда как вlogic_bookingэкспортирован толькоlist_event_bookings/1.Воспроизведение (browser QA, 2026-07-20/21):
pending.GET /v1/events/T75zm7qXFeISw9yREnJ0tA/bookings→ 500;PUT /v1/bookings/:idсaction=confirmот владельца при этом работает (200).Влияние
Владелец не может подтверждать записи через UI. Обход только через прямой API. Ломает сценарий «запись → подтверждение → отзыв».
Ожидаемый результат
Владелец получает список заявок события и может confirm/decline в карточке события.
Критерии приёмки
GET /v1/events/:id/bookingsдля владельца возвращает 200 и список заявок (в т.ч. pending)Файлы (подсказка)
src/handlers/handler_bookings.erl(вызовlist_event_bookings/2)src/logic/logic_booking.erl(list_event_bookings/1,list_bookings/2)Приоритет
P0
Беру задачу в работу из Cursor.
Сначала предложу варианты решения с trade-offs; код не меняю до вашего выбора варианта.
Анализ
Причина 500: handler_bookings:list_bookings/1 вызывает logic_booking:list_event_bookings(UserId, EventId) (arity 2), а в logic_booking экспортирована только list_event_bookings/1 (без проверки владельца). Существующая list_bookings/2 фильтрует заявки участника (свои), а не список владельца — для UI владельца не подходит.
Варианты решения
Вариант 1 (рекомендуемый)
Добавить list_event_bookings/2 (UserId, EventId):
Оставить list_event_bookings/1 для admin/internal. Handler уже готов к этому контракту. Добавить unit + API/CT тест на 200/403.
Плюсы: точечный фикс, правильный ACL, минимальный риск.
Минусы: появляется ещё одна функция рядом с list_bookings/2 (нужно ясно развести имена/доки).
Вариант 2
Проверку владельца сделать в handler, затем вызывать list_event_bookings/1.
Плюсы: меньше изменений в logic.
Минусы: ACL утекает в handler; хуже переиспользование и тестирование.
Вариант 3
Переиспользовать/переписать list_bookings/2 под семантику «владелец видит все заявки».
Плюсы: меньше экспортов.
Минусы: ломает текущую семантику (участник видит только свои); риск регрессий у других вызовов.
Жду выбор варианта перед правками кода.
Реализую утверждённый вариант 1: добавляю logic_booking:list_event_bookings/2 с проверкой владельца календаря (admin ok), возвращающий полный список заявок; list_event_bookings/1 оставляю для admin/internal; правлю вызов в handler; добавляю тесты 200 owner / 403 non-owner. list_bookings/2 не трогаю.
Сделано (вариант 1)
Добавлена logic_booking:list_event_bookings/2: проверка владельца календаря (или admin), полный список заявок. list_event_bookings/1 без изменений (admin/internal). list_bookings/2 не трогали. Handler уже вызывал /2 — теперь функция существует.
Файлы
Тесты
WSL: make eunit-module MODULE=logic_booking_tests — All 13 tests passed.
Issue оставляю открытой до подтверждения коммита/закрытия.
Зафиксировано в
5ac2321:list_event_bookings/2с ACL владельца + тесты. Задеплоено на remote master.