Сборщик получает ключ --platform {avito,cian}: платформо-зависимые куски
(URL коридора, счётчик, парс, потолок пагинации, целевая таблица) вынесены
в PlatformAdapter, общая часть — бисекция по цене, guard на блок, накопитель
и заливка — одна на обе площадки.
Скоуп Циан проверен живыми запросами 10.09, а не взят из документации:
- region=1 и region=4593 двумя параметрами НЕ объединяются, сервер берёт
последний. Прежний базовый URL собрал бы одну Московскую область и молча
потерял Москву целиком (92 817 объявлений). Правильный скоуп — region=-1.
- object_type[0]=1 обязателен: без него счётчик считает новостройки, которые
дальше не сохраняются, и расходится с числом карточек вдвое.
- Итоговый скоуп: 62 548 объявлений вторички по Москве и МО.
- Потолок пагинации 54 страницы подтверждён: страница 55 пуста.
Фильтра новостроек в адаптере нет, и это сознательное отличие от кита. Кит
считает новостройкой всё, у чего есть offer.newbuilding.id (serp.py:401-402),
потому что для ЕКБ выдача бралась без object_type. На московской странице из
28 карточек 16 имеют этот блок, и у всех шестнадцати isFromBuilder=false,
isFromLeadFactory=false — это вторичка в ЖК, а не лоты застройщика. С китовым
фильтром прогон терял бы 57 % корпуса безвозвратно. msk_raw — сырьё, payload
несёт listing_segment целиком, сегмент отделяется на импорте в listings.
Детект блока Циан. Капча приходит как HTTP 200 с обычной на вид страницей:
поймана живьём, 40 КБ, title «Captcha - база объявлений ЦИАН», без
window._cianConfig. По статусу её не отличить, поэтому маркер ищется в первых
4 КБ (в нормальной выдаче на 2,6 МБ там ни одного вхождения). Вторая сеть в
parse_page: счётчик None при нуле сырых карточек — тоже стоп. Без этого блок
засчитывался бы как пустая страница, коридор уходил в done, а --resume его
уже не перебрал бы.
Гвард empty_page считает карточки ДО фильтра: иначе штатный ноль после
фильтрации был бы неотличим от блока. У Авито атрибута нет, дефолт — длина
итогового списка, поведение прежнее.
Заливка. Целевая таблица берётся из адаптера, staging создаётся с
INCLUDING IDENTITY (без него identity-колонка не переносится, а NOT NULL
переносится всегда, и \copy падал бы на каждом батче). Наличие таблицы
проверяется на старте одним SELECT to_regclass — иначе прогон умирал бы
на первой заливке, после часов планирования.
Миграция 299 заводит cian_cards, domclick_cards, yandex_cards и три вью
по образцу avito_cards/avito_latest. id — bigserial, а не IDENTITY, ровно
по причине выше.
Заодно: _wt-mskcol/ выведен из индекса и закрыт в .gitignore. Копия-worktree
попала в репозиторий 09.09, и три фикса ушли в дубликат мимо канонического
collect.py — дефект нашёлся только при сверке размера страницы.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ8jqr4SFirX5tFLwdSrXh
118 lines
4.1 KiB
Text
118 lines
4.1 KiB
Text
# Memory graph (hardlink to C:\mcp\.aim\memory-gendesign.jsonl)
|
||
*.jsonl
|
||
!memory/memory-gendesign.jsonl
|
||
|
||
# Python / Node / venv
|
||
.venv/
|
||
__pycache__/
|
||
*.pyc
|
||
*.egg-info/
|
||
node_modules/
|
||
|
||
# Next.js build artifacts
|
||
.next/
|
||
frontend/.next/
|
||
out/
|
||
|
||
# Sentry CLI config (auto-generated, contains auth tokens)
|
||
.sentryclirc
|
||
frontend/.sentryclirc
|
||
# TypeScript incremental build info — must NOT be committed; locally-generated
|
||
# and changes on every build, which busts Docker build context cache.
|
||
*.tsbuildinfo
|
||
|
||
# Env / secrets
|
||
.env
|
||
.env.local
|
||
.env.*.local
|
||
.env.runtime
|
||
.mcp.json
|
||
# креды-заметки — НЕ коммитить (см. issue #391)
|
||
sshkey.txt
|
||
# Session cookies (browser-export) для local-sweep — НЕ коммитить (#770)
|
||
tradein-mvp/scripts/.cian-cookies.json
|
||
tradein-mvp/scripts/*.cookies.json
|
||
tradein-mvp/scripts/*cookies*.json
|
||
tradein-mvp/scripts/.*cookies*.json
|
||
|
||
# IDE
|
||
.vscode/
|
||
.idea/
|
||
*.swp
|
||
|
||
# Claude Code — local state only (cache, locks, sessions, schedules).
|
||
# Agents and rules ARE tracked: they are team-shared config.
|
||
# Explicit per-path list — `.claude/` + `!.claude/agents/` whitelist pattern
|
||
# does not work because git cannot re-include files under an ignored parent.
|
||
.claude/settings.local.json
|
||
.claude/cache/
|
||
.claude/sessions/
|
||
.claude/locks/
|
||
.claude/file-history/
|
||
.claude/shell-snapshots/
|
||
.claude/tasks/
|
||
.claude/plans/
|
||
.claude/telemetry/
|
||
.claude/projects/
|
||
.claude/worktrees/
|
||
.claude/daemon/
|
||
.claude/session-env/
|
||
.claude/stats-cache.json
|
||
.claude/history.jsonl
|
||
.claude/mcp-needs-auth-cache.json
|
||
.claude/paste-cache/
|
||
.claude/downloads/
|
||
.claude/backups/
|
||
.claude/plugins/
|
||
.claude/agent-memory*/
|
||
.claude/scheduled_tasks.lock
|
||
|
||
# Local data (raw CSVs from Rosreestr/etc — too large for git)
|
||
data/raw/
|
||
data/raw/prinzip_crm.sqlite
|
||
data/raw/domrf_photos/
|
||
# Objective API smoke dumps (ходят в backend/data/raw когда скрипт запускают из backend/)
|
||
backend/data/raw/
|
||
|
||
# Antonov SQLite snapshot для ETL (340 MB)
|
||
sf_anton_snapshot.db
|
||
sf_anton_snapshot.db-*
|
||
*.csv
|
||
*.csv.zip
|
||
!backend/db/init/*.sql
|
||
|
||
# OSRM routing graph build output (#39) — ~1.5GB .osrm* + intermediate .pbf.
|
||
# Строится offline на VPS через scripts/build_osrm.sh, монтируется в osrm-service.
|
||
# НЕ коммитим артефакты; .gitkeep держит каталог.
|
||
data/osrm/*
|
||
!data/osrm/.gitkeep
|
||
|
||
# Full PDF report bind-source (#2259 PR-D) — worker пишет PDF в ./reports:/app/reports.
|
||
# Артефакты рантайма, не коммитим (untracked и так выживает при deploy git reset --hard).
|
||
/reports/
|
||
|
||
# Log cruft at repo root
|
||
debug.log
|
||
.ds-sync/
|
||
ds-bundle/
|
||
.design-sync/.cache/
|
||
.design-sync/learnings/
|
||
.design-sync/node_modules
|
||
|
||
# Боевой конфиг Alertmanager собирается на хосте из .tmpl (deploy-metrics.yml):
|
||
# содержит токен бота и идентификатор чата, поэтому в репозиторий не попадает.
|
||
ops/metrics/alertmanager/alertmanager.yml
|
||
|
||
# Цели file_sd для Prometheus рендерит тот же деплой — по условию, которым
|
||
# включает профиль alerts. Отслеживаемая версия правилась руками и жила отдельно
|
||
# от включателя: 27.08 профиль включили, а файл так и остался плейсхолдером,
|
||
# и Prometheus не видел ни одного приёмника (#3155). Производный файл убирает
|
||
# сам зазор — правится только там же, где принимается решение о профиле.
|
||
ops/metrics/prometheus/alertmanager_targets.gen.yml
|
||
|
||
# Временные рабочие копии-worktree вида _wt-<тема>/ живут рядом с репозиторием
|
||
# и в него попадать не должны. 09.09 копия _wt-mskcol попала в индекс одним
|
||
# файлом сборщика, и три следующих фикса ушли в дубликат мимо канонического
|
||
# tradein-mvp/scripts/local-avito-msk/collect.py — дефект нашёлся только при
|
||
# сверке page size.
|
||
_wt-*/
|