feat(22d): catalog scraper — skip-today filter + force flag #348
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#348
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/22d-catalog-skip-today-force"
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
_SELECT_TARGETS_SQL: вместо 30-day staleness теперь skip-today — пропускаем только то, чтоcatalog_scraped_at= сегодня. Новые (IS NULL) и вчерашние грузим всегда.force: bool = False.force=True→ кнопка "Загрузить все" — снимает skip и грузит все объекты последнего snapshot.Зачем
Full sweep на 1532 obj ≈ 50 мин/run. До этого фильтр был "не обновлялось ≥30 дней", поэтому повторный запуск после партиала всё равно гнал тот же batch. Теперь partial+resume даёт реальный инкремент. Force остаётся для случаев "обновился schema, нужно перезалить всё".
SQL diff
CAST(:force AS boolean)—:force::booleanне сработает в SQLAlchemy 2.0 + psycopg3 (см..claude/rules/backend.md).Test plan
ruff checkcleantests/workers/test_scrape_kn_catalog_objects.py)tests/services/scrapers/test_domrf_catalog_object.py)force=false→ грузит N obj, 2-й вызов сразу сforce=false→obj_ids_count=0, 3-й сforce=true→ грузит снова.force=Falseиobj_ids_countсоответствует объектам не-сегодня.Was: 30-day staleness window (catalog_scraped_at < NOW() - INTERVAL '30 days') Now: skip только если catalog_scraped_at = сегодня; новые (NULL) и вчерашние грузим всегда. Admin endpoint и beat task получили `force: bool = False` — True игнорирует skip и грузит все объекты последнего snapshot (кнопка "Загрузить все"). - SQL: WHERE (CAST(:force AS boolean) OR catalog_scraped_at IS NULL OR DATE(catalog_scraped_at) < CURRENT_DATE) - Task signature: scrape_kn_catalog_objects(region_code, max_objects, force) - Admin POST /admin/scrape/kn-catalog-objects payload: + force: bool - Tests: 5 новых (skip-today active, force passthrough, max_objects, rows processed, SQL contains skip-today predicate) Зачем: full sweep на 1532 obj — ~50 мин/run. До сих пор повторный запуск после партиала всё равно проходил тот же batch — нет признака "уже обновлено сегодня". Кнопка "Загрузить все" остаётся для force-pass всего региона (например после schema change).Deep Code Review — verdict ✅ APPROVE
Files: 3 (admin endpoint, task, tests) · +153/-15 · mergeable, no conflicts
Checks pass
CAST(:force AS boolean)correct (no:force::booleantrap). All other binds parameterised.IS NULL∨DATE(catalog_scraped_at) < CURRENT_DATE∨CAST(:force AS boolean)— short-circuit viaORкорректен. Race-condition guard (MAX(snapshot_date) WHERE region_cd = :region_code) сохранён из оригинала.forceидёт через Pydantic body →apply_async kwargs→ SQL bind → response echo + logger. Beat schedule не передаётforce→ defaults toFalse✅.logger.*с observableforce=%s.Edge case (acceptable)
Partial-failed run today не будет ретраиться до завтра без
force=True. Author documented это в PR body как accepted trade-off — кнопка "Загрузить все" покрывает recovery.Post-merge smoke (from PR test plan)
force=false→ грузит N objforce=false→obj_ids_count=0(skip-today active)force=true→ грузит сноваforce=FalseMerging via squash.