(medium) scrape/all/page.tsx logs: при filter=all кнопка «логи» не задаёт scraper_type — смешивает логи разных скраперов по совпадающему run_id #1401

Closed
opened 2026-06-15 05:53:31 +00:00 by bot-backend · 1 comment
Collaborator

Severity: medium · Категория: logic · Файл: frontend/src/app/admin/scrape/all/page.tsx:85-96, 289-305

frontend/src/app/admin/scrape/all/page.tsx:289-305 (кнопка) + 85-96 (запрос). Кнопка onClick={() => setLogsRunId(r.run_id)} (стр.295) сохраняет только число run_id и не меняет filter и не запоминает scraper_type строки. Запрос логов (стр.88-90) добавляет scraper_type в query только при filter !== "all"; при filter=all формируется ?limit=100&run_id=<n> без scraper_type. Бэкенд /all/logs (backend/app/api/v1/admin_scrape.py:1138-1143) добавляет scraper_type в WHERE только если параметр передан, иначе фильтрует лишь run_id = :rid по объединённой v_scrape_log_unified. Подтверждено: v_scrape_log_unified (data/sql/77_nspd_geo_jobs.sql:140-149) объединяет kn_scrape_log, nspd_scrape_log и nspd_geo_log (job_id AS run_id); run_id/job_id — независимые BIGSERIAL PRIMARY KEY (50_schema_kn_extensions.sql:33, 63_schema_nspd_runs.sql:53, 77_nspd_geo_jobs.sql:23), поэтому один и тот же номер существует у нескольких источников. Кнопка «логи» рендерится для kn/nspd/nspd_geo (стр.290-292), которые видны и при filter=all. Импакт: на сводном дашборде при filter=all панель логов показывает вперемешку записи разных скраперов с одинаковым run_id — неверная диагностика. Это внутренний admin-дашборд, не клиентский, поэтому medium, не high. Чинить: при клике сохранять и scraper_type строки (например setFilter(r.scraper_type) либо отдельный logsScraperType-стейт) и всегда передавать scraper_type в /all/logs.

Почему баг: Подтверждено: run_id/job_id — per-table BIGSERIAL PRIMARY KEY (data/sql/50_schema_kn_extensions.sql:33, 63_schema_nspd_runs.sql:53, 68_schema_objective.sql:52, 77_nspd_geo_jobs.sql:23), значит коллизия номеров между скраперами гарантирована. Бэкенд (admin_scrape.py:1136-1143) добавляет scraper_type в WHERE только если параметр передан, а кнопка onClick={() => setLogsRunId(r.run_id)} (стр.295) scraper_type не сохраняет и filter не меняет. На объединённом дашборде (в отличие от scrape/page.tsx и ScrapeLogsPanel.tsx, которые scoped на один скрапер) это даёт неверную выборку.

Как чинить: Хранить logs-таргет как пару {scraper_type, run_id} (например setLogsTarget({scraper_type: r.scraper_type, run_id: r.run_id})) и всегда добавлять оба параметра в запрос логов, либо при клике «логи» одновременно делать setFilter(r.scraper_type), чтобы scraper_type попадал в WHERE.


deep-audit «армия ботов 2» · verify+harden, confidence 0.9 · unit U68

**Severity:** medium · **Категория:** logic · **Файл:** `frontend/src/app/admin/scrape/all/page.tsx:85-96, 289-305` frontend/src/app/admin/scrape/all/page.tsx:289-305 (кнопка) + 85-96 (запрос). Кнопка `onClick={() => setLogsRunId(r.run_id)}` (стр.295) сохраняет только число run_id и не меняет filter и не запоминает scraper_type строки. Запрос логов (стр.88-90) добавляет `scraper_type` в query только при `filter !== "all"`; при filter=all формируется `?limit=100&run_id=<n>` без scraper_type. Бэкенд /all/logs (backend/app/api/v1/admin_scrape.py:1138-1143) добавляет scraper_type в WHERE только если параметр передан, иначе фильтрует лишь `run_id = :rid` по объединённой v_scrape_log_unified. Подтверждено: v_scrape_log_unified (data/sql/77_nspd_geo_jobs.sql:140-149) объединяет kn_scrape_log, nspd_scrape_log и nspd_geo_log (job_id AS run_id); run_id/job_id — независимые BIGSERIAL PRIMARY KEY (50_schema_kn_extensions.sql:33, 63_schema_nspd_runs.sql:53, 77_nspd_geo_jobs.sql:23), поэтому один и тот же номер существует у нескольких источников. Кнопка «логи» рендерится для kn/nspd/nspd_geo (стр.290-292), которые видны и при filter=all. Импакт: на сводном дашборде при filter=all панель логов показывает вперемешку записи разных скраперов с одинаковым run_id — неверная диагностика. Это внутренний admin-дашборд, не клиентский, поэтому medium, не high. Чинить: при клике сохранять и scraper_type строки (например setFilter(r.scraper_type) либо отдельный logsScraperType-стейт) и всегда передавать scraper_type в /all/logs. **Почему баг:** Подтверждено: run_id/job_id — per-table BIGSERIAL PRIMARY KEY (data/sql/50_schema_kn_extensions.sql:33, 63_schema_nspd_runs.sql:53, 68_schema_objective.sql:52, 77_nspd_geo_jobs.sql:23), значит коллизия номеров между скраперами гарантирована. Бэкенд (admin_scrape.py:1136-1143) добавляет scraper_type в WHERE только если параметр передан, а кнопка `onClick={() => setLogsRunId(r.run_id)}` (стр.295) scraper_type не сохраняет и filter не меняет. На объединённом дашборде (в отличие от scrape/page.tsx и ScrapeLogsPanel.tsx, которые scoped на один скрапер) это даёт неверную выборку. **Как чинить:** Хранить logs-таргет как пару {scraper_type, run_id} (например setLogsTarget({scraper_type: r.scraper_type, run_id: r.run_id})) и всегда добавлять оба параметра в запрос логов, либо при клике «логи» одновременно делать setFilter(r.scraper_type), чтобы scraper_type попадал в WHERE. --- <sub>deep-audit «армия ботов 2» · verify+harden, confidence 0.9 · unit U68</sub>
bot-backend added the
week ревью 1
label 2026-06-15 05:53:31 +00:00
bot-backend added the
scope/frontend
label 2026-06-15 11:01:59 +00:00
Owner

🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)

Текущее состояние кода: frontend/src/app/admin/scrape/all/page.tsx:

  • Кнопка «логи» (289-305): onClick={() => setLogsRunId(r.run_id)} (295) — сохраняет только число run_id, не меняет filter и не запоминает scraper_type строки. Рендерится для kn/nspd/nspd_geo (290-292), все видны при filter=all.
  • Запрос логов (85-96): if (filter !== "all") params.set("scraper_type", filter) (89) — при filter=all scraper_type НЕ передаётся, формируется ?limit=100&run_id=<n>.

Бэкенд /all/logs добавляет scraper_type в WHERE только если параметр передан (как описано в issue) → при filter=all фильтрует лишь по run_id поверх объединённой v_scrape_log_unified, где run_id/job_id — независимые per-table BIGSERIAL → коллизия номеров между источниками.

Корень: При filter=all клик «логи» не задаёт scraper_type → панель логов показывает вперемешку записи разных скраперов с одинаковым run_id (неверная диагностика на сводном дашборде). Внутренний admin → medium.

Что править:

  • Хранить logs-таргет как пару, напр. setLogsTarget({scraper_type: r.scraper_type, run_id: r.run_id}), и всегда добавлять оба параметра в запрос (queryKey включить scraper_type). Либо при клике одновременно setFilter(r.scraper_type), чтобы scraper_type попал в WHERE.

Что посмотреть:

  • Код: frontend/src/app/admin/scrape/all/page.tsx:85-96 (запрос), 289-305 (кнопка). Бэкенд /all/logs WHERE-логика в backend/app/api/v1/admin_scrape.py. Сравнить со scoped ScrapeLogsPanel.tsx / scrape/page.tsx.
  • Vault: релевантных заметок не найдено.
**🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)** **Текущее состояние кода:** `frontend/src/app/admin/scrape/all/page.tsx`: - Кнопка «логи» (289-305): `onClick={() => setLogsRunId(r.run_id)}` (295) — сохраняет только число `run_id`, не меняет `filter` и не запоминает `scraper_type` строки. Рендерится для `kn`/`nspd`/`nspd_geo` (290-292), все видны при filter=all. - Запрос логов (85-96): `if (filter !== "all") params.set("scraper_type", filter)` (89) — при filter=all `scraper_type` НЕ передаётся, формируется `?limit=100&run_id=<n>`. Бэкенд `/all/logs` добавляет `scraper_type` в WHERE только если параметр передан (как описано в issue) → при filter=all фильтрует лишь по `run_id` поверх объединённой `v_scrape_log_unified`, где `run_id`/`job_id` — независимые per-table BIGSERIAL → коллизия номеров между источниками. **Корень:** При filter=all клик «логи» не задаёт scraper_type → панель логов показывает вперемешку записи разных скраперов с одинаковым run_id (неверная диагностика на сводном дашборде). Внутренний admin → medium. **Что править:** - Хранить logs-таргет как пару, напр. `setLogsTarget({scraper_type: r.scraper_type, run_id: r.run_id})`, и всегда добавлять оба параметра в запрос (queryKey включить scraper_type). Либо при клике одновременно `setFilter(r.scraper_type)`, чтобы scraper_type попал в WHERE. **Что посмотреть:** - Код: `frontend/src/app/admin/scrape/all/page.tsx:85-96` (запрос), 289-305 (кнопка). Бэкенд `/all/logs` WHERE-логика в `backend/app/api/v1/admin_scrape.py`. Сравнить со scoped `ScrapeLogsPanel.tsx` / `scrape/page.tsx`. - Vault: релевантных заметок не найдено.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1401
No description provided.