P1: GET /v1/search без фильтров — отдавать топы календарей и событий #50

Closed
opened 2026-07-20 11:03:47 +03:00 by cursor-ai · 3 comments
Owner

Проблема

GET /v1/search без фильтров сейчас возвращает все доступные пользователю календари и события (полный скан Mnesia + пагинация). Для страницы «Найти» нужен осмысленный дефолт — топы из stats_tops, а не полный каталог.

На фронте (#7) при открытии /search планируется вызывать search без параметров; без изменения бэка пользователь либо получит слишком большой/случайный список, либо фронт вынужден держать отдельную логику.

Влияние

  • Пустая/бессмысленная выдача на главной точке discovery.
  • Лишняя нагрузка: полный match по всем active calendar/event вместо готовых ETS-топов.

Ожидаемый результат

При пустых query-параметрах поиска (q, tags, geo, from/to отсутствуют; typeundefined или явно задан) GET /v1/search возвращает топовые публичные календари и события из агрегатов stats_tops, с учётом прав доступа пользователя.

При непустых фильтрах поведение без изменений — текущий полнотекстовый поиск и фильтрация.

Контракт ответа тот же: { total, limit, offset, results } (events/calendars).

Критерии приёмки

  • Пустой GET /v1/search (только auth) → топ-календари + топ-события (лимит по limit, default 20).
  • Только type=calendar / type=event без q → топ соответствующего типа.
  • С q, тегами, датами или geo — старая логика search, не топы.
  • В топ не попадают недоступные сущности (приватные чужие календари и т.п.) — тот же can_access, что в logic_search.
  • Источник: core_calendar:get_top_calendars_by_rating/1 (или by_reviews — зафиксировать в PR) и core_event:get_top_events_by_rating/1; fallback при пустых tops — документировать (пустой список или текущий scan).
  • Unit-тесты в logic_search_tests.erl на ветку «empty params → tops» и на то, что q переключает на обычный search.
  • Swagger/handler_search описание обновлено (пустой search = discovery tops).
  • Связано с EventHub/EventHubFront#7; спека EventHubBackSpec.md § search после тестов.

Файлы (подсказка)

  • src/logic/logic_search.erl
  • src/handlers/handler_search.erl
  • src/core/core_calendar.erl, src/core/core_event.erl
  • src/infra/stats_tops.erl
  • test/unit/logic_search_tests.erl

Связанные задачи

Приоритет

P1

## Проблема `GET /v1/search` без фильтров сейчас возвращает **все** доступные пользователю календари и события (полный скан Mnesia + пагинация). Для страницы «Найти» нужен осмысленный дефолт — **топы** из `stats_tops`, а не полный каталог. На фронте (#7) при открытии `/search` планируется вызывать search без параметров; без изменения бэка пользователь либо получит слишком большой/случайный список, либо фронт вынужден держать отдельную логику. ## Влияние - Пустая/бессмысленная выдача на главной точке discovery. - Лишняя нагрузка: полный match по всем active calendar/event вместо готовых ETS-топов. ## Ожидаемый результат При **пустых** query-параметрах поиска (`q`, `tags`, geo, `from`/`to` отсутствуют; `type` — `undefined` или явно задан) `GET /v1/search` возвращает топовые публичные календари и события из агрегатов `stats_tops`, с учётом прав доступа пользователя. При **непустых** фильтрах поведение без изменений — текущий полнотекстовый поиск и фильтрация. Контракт ответа тот же: `{ total, limit, offset, results }` (events/calendars). ## Критерии приёмки - [ ] Пустой `GET /v1/search` (только auth) → топ-календари + топ-события (лимит по `limit`, default 20). - [ ] Только `type=calendar` / `type=event` без `q` → топ соответствующего типа. - [ ] С `q`, тегами, датами или geo — старая логика search, не топы. - [ ] В топ не попадают недоступные сущности (приватные чужие календари и т.п.) — тот же `can_access`, что в `logic_search`. - [ ] Источник: `core_calendar:get_top_calendars_by_rating/1` (или by_reviews — зафиксировать в PR) и `core_event:get_top_events_by_rating/1`; fallback при пустых tops — документировать (пустой список или текущий scan). - [ ] Unit-тесты в `logic_search_tests.erl` на ветку «empty params → tops» и на то, что `q` переключает на обычный search. - [ ] Swagger/handler_search описание обновлено (пустой search = discovery tops). - [ ] Связано с EventHub/EventHubFront#7; спека `EventHubBackSpec.md` § search после тестов. ## Файлы (подсказка) - `src/logic/logic_search.erl` - `src/handlers/handler_search.erl` - `src/core/core_calendar.erl`, `src/core/core_event.erl` - `src/infra/stats_tops.erl` - `test/unit/logic_search_tests.erl` ## Связанные задачи - EventHub/EventHubFront#7 — UI «Найти» при пустых фильтрах ## Приоритет P1
cursor-ai self-assigned this 2026-07-20 11:03:47 +03:00
Author
Owner

Беру в работу. Сначала предложу варианты реализации discovery-топов в GET /v1/search.

Беру в работу. Сначала предложу варианты реализации discovery-топов в GET /v1/search.
Author
Owner

Реализован вариант 1 + fallback (локально, без push): пустой GET /v1/search → tops by rating из stats_tops с can_access; при пустых tops — scan. q/tags/geo/from/to/sort → прежний поиск. Unit: logic_search_tests (+2 кейса), 13/13 ok.

Реализован вариант 1 + fallback (локально, без push): пустой GET /v1/search → tops by rating из stats_tops с can_access; при пустых tops — scan. q/tags/geo/from/to/sort → прежний поиск. Unit: logic_search_tests (+2 кейса), 13/13 ok.
Author
Owner

Готово. Коммит 6d52bc3: пустой GET /v1/search (без q, тегов, дат, geo, sort) отдаёт discovery tops из stats_tops с фильтром can_access и fallback на полный scan; при q/фильтрах — прежний поиск. Unit logic_search_tests (13/13).

CI run 366 — зелёный (IFT e2e, 39/39 API).

Спека обновлена: EventHubBackSpec.md §2.5, EventHubFrontSpec.md §5.3.

Готово. Коммит `6d52bc3`: пустой `GET /v1/search` (без `q`, тегов, дат, geo, sort) отдаёт discovery tops из `stats_tops` с фильтром `can_access` и fallback на полный scan; при `q`/фильтрах — прежний поиск. Unit `logic_search_tests` (13/13). CI run 366 — зелёный (IFT e2e, 39/39 API). Спека обновлена: `EventHubBackSpec.md` §2.5, `EventHubFrontSpec.md` §5.3.
Sign in to join this conversation.