feat(tradein): /scrapers/avito — 5-я секция City sweep (auto + cancel + runs list) #478
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
вторичка
ИРД
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#478
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/tradein-frontend-city-sweep"
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?
Summary
UI для backend city sweep (parallel PR
feat/tradein-avito-city-sweep) — добавляет 5-ю секцию на/trade-in/scrapers/avitoс формой запуска, polling списка runs, и кнопкой отмены.LOC: 2 files (1 modify page.tsx + 1 append CSS).
Changes
app/scrapers/avito/page.tsxuseStartCitySweep,useCitySweepRuns,useCancelCitySweep):/admin/scrape/avito-city-sweep(returns run_id, invalidates runs query)/admin/scrape/avito-city-sweep/runs?limit=10, auto-poll каждые 5 sec, staleTime=0/admin/scrape/avito-city-sweep/{run_id}/cancelCitySweepInput,CitySweepStartResp,CitySweepCounters,ScrapeRunRowtranslateStatus(RU labels: выполняется/готово/ошибка/отменено/...),formatTime(ru-RU локаль)trade-in.css.scraper-section--highlight— синий border + accent-soft background для city sweep.city-sweep-runs— секция с recent runs.runs-table— tabular-nums, sticky header, compact layout.run-badge--{running|done|failed|cancelled|zombie}— цветные status badges.cancel-btn— danger color, hoverVerify
tsc --noEmitcleannext buildpass —/scrapers/avito4.86 kB, all 9 routes generatedTest plan
/trade-in/scrapers/avito→ fill sweep form → submit → verify run_id returned + runs table показывает новый row с status=runningBehavior
Refs
feat/tradein-avito-city-sweep(3 endpoints + scrape_runs tracking)- City sweep form: pages_per_anchor (1-10), detail_top_n (0-30), request_delay_sec (3-15), radius_m, enrich_houses checkbox -> POST /admin/scrape/avito-city-sweep - 'Запустить sweep' button -> returns run_id (background task) - Recent runs table (auto-poll 5s): status badge, started/heartbeat, counters (anchors_done/total, lots, houses_enriched/unique, detail_enriched/attempted, errors) - 'Отменить' button per running run -> POST /scrape/avito-city-sweep/{run_id}/cancel - Status badges с цветами (running/done/failed/cancelled/zombie) - translateStatus helper (RU labels), formatTime helper (ru-RU locale) - CSS: .scraper-section--highlight (синий border для city-sweep section), .city-sweep-runs, .runs-table с tabular-nums, .run-badge variants, .cancel-btn Backend контракт: 3 endpoints из parallel PR (avito-city-sweep start/runs/cancel). TS strict + next build pass.Deep code review — verdict APPROVE.
Files: 2 (page.tsx +303/-1, trade-in.css +106). TS strict clean, no
any/@ts-ignore. Local TS interfaces match backend Pydantic shapes из PR #477 1-в-1 (URL/api/v1/admin/scrape/avito-city-sweep[/runs|/{id}/cancel], payload fields, response keys, status enum).apiFetchкорректно prefixes черезAPI_BASE_URL = BASE_PATH ?? ""(basePath-aware). Existing scraper hooks в этом же файле уже используют/api/v1/admin/scrape/*path style — consistency сохранена.Backend contract dependency: hooks call 3 endpoints из parallel PR #477. Если #478 merged без #477 —
useCitySweepRunsвернёт 404 → красная панель "Ошибка загрузки runs", остальные 4 секции работают. Graceful degradation OK, но рекомендую merge order #477 → #478 чтобы users не видели transient 404.Polling load:
refetchInterval: 5_000,staleTime: 0→ 12 req/min на admin user. Endpointlist_recent(limit=10)— single indexed SELECT, negligible. TanStack Query v5 default пауза приdocument.hidden. Не оптимизировано: продолжает poll даже когда все runs в terminal state (done/failed/cancelled). Minor — admin tool, low concurrent users.Minor nits (non-blocking, post-merge polish):
parseInt(sweepPages, 10)безNumber.isNaNguard → "abc" в input даётNaN→ JSON.stringify → null → backend 422. Admin-only UI, acceptable.formatTime— absolute timestamp ru-RU, без "5 мин назад". Achievable для long-running 1h+ runs..cancel-btn:disabledbackground--border-strong+ white text → low contrast.(q) => q.state.data?.some(r => r.status === 'running') ? 5000 : 30000— экономит requests когда idle.overflow-x: autowrapper — 10 cols на mobile узко (admin desktop OK).Status enum coverage:
translateStatusмаппит все 7 значений из 051 миграции CHECK constraint (running/done/failed/cancelled/zombie/skipped/banned) +default: return sfallback на новые backend статусы.Risk: Low. Reversibility: Easy revert (2 файла, append-only, no migration). Deploy trigger
tradein-mvp/frontend/**в deploy-tradein.yml сработает.Merging via deep-code-reviewer.