feat(tradein-ui): Cian scraper admin page + global request delay control #486
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#486
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/tradein-cian-admin-page"
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
Replace
tradein-mvp/frontend/src/app/scrapers/cian/page.tsxstub (24 lines) с full admin UI mirroring Avito conventions. Adds Global Request Delay slider/input on the same page (calls new endpoints from sibling PR #485).Files
tradein-mvp/frontend/src/app/scrapers/cian/page.tsx— replaced stub, +435 lines / −8 lines (451 lines total)Branch cleanup
⚠️ Initial push had worktree pollution (backend files from sibling worker leaked into this branch). Cleaned via
git resetк forgejo/main + replay только frontend file +--force-with-leaseto remote. Final diff vs main: 1 file only.Cards implemented
/trade-in/scrapers/cian-cookies+ live auth badge fromGET /api/v1/admin/scrape/cian/test-authPOST /api/v1/admin/scrapebody{lat, lon, radius_m, sources: ["cian"]}+ multi-room checkboxcian-detailnot yet wired through admin API)cian-newbuildingnot yet wired through admin API)cian-valuationnot yet wired through admin API)/api/v1/admin/scraper-settings; read-only per-source list для contextGlobal delay control flow
Effect: next scrape request waits
max(per_source, global)seconds.TS strict
ScraperSetting,UploadResponse, etc.)anyPatterns reused
apiFetchfrom@/lib/api(relative paths, basePath=/trade-in applies)Topbar active="cian"(Topbar already has tab from PR #481)Auth
No
X-Admin-Token— tradein admin endpoints auth через Caddy basic_auth (matches Avito page conventions + cian-cookies page).Backend endpoints NOT yet existing (UI displays static notice)
POST /api/v1/admin/scrape/cian-detail(Stage 5 backend exists, admin trigger pending)POST /api/v1/admin/scrape/cian-newbuilding(Stage 6 backend exists, admin trigger pending)POST /api/v1/admin/scrape/cian-valuation(Stage 7 backend exists через estimator, standalone endpoint pending)UI shows "Endpoint не реализован" notice — easy follow-up PRs to wire them.
Push verify
LOCAL == REMOTE =
4eaa4050Companion PR
PR #485 —
feat/tradein-global-scraper-delay— backendGET/PUT /api/v1/admin/scraper-settingsendpoints + SQL migration 054. Must merge first для UI to work.URL
https://gendsgn.ru/trade-in/scrapers/cian(Cian tab в Topbar)Test plan
Merged via deep-code-reviewer — verdict APPROVE with 2 medium follow-ups.
Verdict summary
ebfd29a0)b21d7c7c(PR #484), no worktree pollution residueBackend schema compat check (vs main HEAD)
POST /api/v1/admin/scrapeaccepts{lat, lon, radius_m, sources: ["cian"], multi_room_cian: bool}— UI body matches exactlyGET /api/v1/admin/scraper-settingsreturns sortedlist[ScraperSetting]— UI shape matchesPUT /api/v1/admin/scraper-settings/{source}UPSERT,sourceisstr(no enum), acceptsglobal— worksGET /api/v1/admin/scrape/cian/test-authreturns{authenticated, userId, reason}— matchesTestAuthRespinterfaceany)apiFetch-> basePath=/trade-in-> Caddyhandle_path /trade-in/api/*-> tradein-backend (correct)Medium follow-ups (NON-blocking)
1. Slider min=0 vs backend ge=1.0 mismatch
Backend
ScraperSettingUpdate.request_delay_sec: float = Field(ge=1.0, le=60.0).UI slider/input
min={0}max={30}step={0.5}+ hint says "0 = только per-source defaults".Edge case: user moves slider to 0 or 0.5 -> PUT body
{request_delay_sec: 0}-> backend returns 422. UI rendersupdateSettingMut.errorso no crash, but UX misleading (hint promises 0 works, backend rejects).Recommend follow-up:
min={1}and update hint, ORge=0.0(matches UI semantics)2. "Global" delay not consumed by scrapers
tradein-mvp/backend/app/services/scraper_settings.py::get_scraper_delay()only reads the specific source key (with_KEY_ALIASESmapping). There is nomax(per_source, global)logic.UI hint claims: "Глобальный делэй применяется ко всем scrapers (max с per-source defaults). Изменение вступает в силу немедленно".
Actual behavior: PUT succeeds (row stored), but
get_scraper_delay("cian")readscianrow only, neverglobal. Cosmetic write.Recommend follow-up: extend
get_scraper_delay()to read both keys and returnmax(source_delay, global_delay).Minor
parseFloat(e.target.value)on number/range inputs -> NaN on empty input -> serialized asnull-> backend 422. Graceful (no crash). Could guard withNumber.isFinitebefore mutate.code/modules/tradein/Cian_Admin_Page.mdnot yet present — recommend creating post-deploy.Verify steps post-deploy
tradein-mvp/frontend/**)https://gendsgn.ru/trade-in/scrapers/cian-> 6 cards render, Topbarciantab active/admin/scrape/cian/test-auth