feat(sf): enumerate изъятия/резервирования с pravo.gov66 → land_reservation (#1062) #1145

Merged
bot-reviewer merged 1 commit from feat/reservation-pravo-enumerator into main 2026-06-07 13:56:30 +00:00
Owner

Что

Подключает подтверждённый источник к готовому парсеру land_reservation (#1091): автоэнумерация постановлений об изъятии/резервировании ЗУ с pravo.gov66.ru. Закрывает ИРД-5 #1062 (был needs-human — источник найден разведкой 2026-06-07).

Источник (подтверждён live)

  • GET pravo.gov66.ru/search/?q=<2-3 слова>&law_type=Постановление (server-rendered HTML, httpx) → ссылки /{NNNNN}/ → PDF /media/pravo/{NUM}-ПП_{hash}.pdf. ⚠️ движок q строгий (2-3 слова; 1/4+ → 0).

Состав

  • pravo_gov66_client.pysearch_documents(query, law_type, since) + get_document_pdf_url(doc_id) + fetch_pdf (verify=False, росс-CA #242).
  • reservation_ingest.py переписан: ingest_reservations() → enumerate по _RESERVATION_QUERIES=["изъятие земельных участков","резервирование земельных участков"] → фильтр заголовков (изъят/резерв + Екатеринбург/Свердлов) → fetch PDF → готовый extract_from_pdf → upsert. docs= override сохранён. Placeholder _SEED_DOCS удалён.
  • 28/28 тестов (mock search-HTML + doc-page + PDF).

После merge (прод)

  • ingest_reservations()SELECT count(*), reservation_kind FROM land_reservation GROUP BY 2. Проверить живой search (число хитов), regex PDF-путей если сайт сменил.

Closes #1062 (ingest). Часть #1067.

## Что Подключает подтверждённый источник к готовому парсеру `land_reservation` (#1091): автоэнумерация постановлений об изъятии/резервировании ЗУ с `pravo.gov66.ru`. Закрывает ИРД-5 #1062 (был needs-human — источник найден разведкой 2026-06-07). ## Источник (подтверждён live) - GET `pravo.gov66.ru/search/?q=<2-3 слова>&law_type=Постановление` (server-rendered HTML, httpx) → ссылки `/{NNNNN}/` → PDF `/media/pravo/{NUM}-ПП_{hash}.pdf`. ⚠️ движок `q` строгий (2-3 слова; 1/4+ → 0). ## Состав - `pravo_gov66_client.py` — `search_documents(query, law_type, since)` + `get_document_pdf_url(doc_id)` + `fetch_pdf` (verify=False, росс-CA #242). - `reservation_ingest.py` переписан: `ingest_reservations()` → enumerate по `_RESERVATION_QUERIES=["изъятие земельных участков","резервирование земельных участков"]` → фильтр заголовков (изъят/резерв + Екатеринбург/Свердлов) → fetch PDF → готовый `extract_from_pdf` → upsert. `docs=` override сохранён. Placeholder `_SEED_DOCS` удалён. - 28/28 тестов (mock search-HTML + doc-page + PDF). ## После merge (прод) - `ingest_reservations()` → `SELECT count(*), reservation_kind FROM land_reservation GROUP BY 2`. Проверить живой search (число хитов), regex PDF-путей если сайт сменил. Closes #1062 (ingest). Часть #1067.
lekss361 added 1 commit 2026-06-07 13:51:02 +00:00
feat(sf): enumerate изъятия/резервирования с pravo.gov66 → land_reservation (#1062)
All checks were successful
CI / changes (push) Successful in 7s
CI / frontend-tests (push) Has been skipped
CI / changes (pull_request) Successful in 9s
CI / frontend-tests (pull_request) Has been skipped
CI / backend-tests (push) Successful in 6m17s
CI / backend-tests (pull_request) Successful in 6m18s
23f04af80f
- Новый клиент pravo_gov66_client: search_documents (GET + BeautifulSoup, doc_id/title/url),
  get_document_pdf_url (предпочитает /media/pravo/, fallback ecp), fetch_pdf (verify=False).
- ingest_reservations переписан: enumerate по _RESERVATION_QUERIES 2-3 слова,
  фильтр заголовков (изъят|резерв + Екатеринбург|Свердлов), дедуп doc_id,
  SAVEPOINT per-row UPSERT в land_reservation; docs= override сохранён для back-compat.
- 28 тестов offline (mock search HTML, mock doc page, mock client в task).
lekss361 added the
GG-форсайт
scope/backend
site-finder
ИРД
labels 2026-06-07 13:51:08 +00:00
bot-reviewer approved these changes 2026-06-07 13:56:22 +00:00
bot-reviewer left a comment
Collaborator

APPROVE — pravo.gov66 enumerator → land_reservation (закрывает ingest #1062).

Verified:

  • verify=False присутствует везде в pravo_gov66_client.py (search/get_pdf_url/fetch_pdf) с #242-комментом → НЕ dead-on-arrival.
  • HTML-парсинг через bs4 (не regex); _RE_DOC_PATH/_RE_PDF_PATH — линейные (negative char-class, без catastrophic backtracking); graceful 0-хитов/malformed → []/None.
  • reservation_ingest rewrite чистый: enumerate (dedup by doc_id + title-filter изъят|резерв ∧ Екб|Свердл) + back-compat _ingest_explicit_docs; SAVEPOINT per-row; CAST psycopg v3; source='pravo_gov66'.
  • Нет миграции (land_reservation #1118 задеплоена, 0 строк). Нет beat → manual-run (dup-risk bounded). 28 тестов (search-HTML/doc-page/PDF/title-filter/dedup/graceful).
  • E501 проверил байт-в-байт (reviewer-subagent ложно зафлагал кириллицу): pravo_gov66_client.py и reservation_ingest.py0 строк >100 символов. ruff чист.

#1122 carry-over (tracked, НЕ ухудшено этим PR): parser _RE_ACT_NUMBER ReDoS (p2) + NULL-act_number дедуп (p2) — унаследовано из #1118, не регресс. ⚠️ Прод-запуск ingest_reservations держать до закрытия #1122 item 1 (ReDoS) — этот PR делает real-ingest возможным, но manual → последовательность контролируема.

Завершает #1062 end-to-end: parser #1118 + analyze-врезка #1127 + enumerator #1145. Хорошая работа.

Merging (squash).

<!-- gendesign-review-bot: sha=23f04af verdict=approve --> ✅ **APPROVE** — pravo.gov66 enumerator → land_reservation (закрывает ingest #1062). **Verified:** - **`verify=False` присутствует везде** в `pravo_gov66_client.py` (search/get_pdf_url/fetch_pdf) с #242-комментом → НЕ dead-on-arrival. - HTML-парсинг через bs4 (не regex); `_RE_DOC_PATH`/`_RE_PDF_PATH` — линейные (negative char-class, без catastrophic backtracking); graceful 0-хитов/malformed → []/None. - `reservation_ingest` rewrite чистый: enumerate (dedup by doc_id + title-filter изъят|резерв ∧ Екб|Свердл) + back-compat `_ingest_explicit_docs`; SAVEPOINT per-row; CAST psycopg v3; source='pravo_gov66'. - Нет миграции (land_reservation #1118 задеплоена, 0 строк). **Нет beat** → manual-run (dup-risk bounded). 28 тестов (search-HTML/doc-page/PDF/title-filter/dedup/graceful). - **E501 проверил байт-в-байт** (reviewer-subagent ложно зафлагал кириллицу): `pravo_gov66_client.py` и `reservation_ingest.py` — **0 строк >100 символов**. ruff чист. **#1122 carry-over (tracked, НЕ ухудшено этим PR):** parser `_RE_ACT_NUMBER` ReDoS (p2) + NULL-act_number дедуп (p2) — унаследовано из #1118, не регресс. ⚠️ **Прод-запуск `ingest_reservations` держать до закрытия #1122 item 1 (ReDoS)** — этот PR делает real-ingest возможным, но manual → последовательность контролируема. Завершает #1062 end-to-end: parser #1118 + analyze-врезка #1127 + enumerator #1145. Хорошая работа. Merging (squash).
bot-reviewer merged commit 396db20c48 into main 2026-06-07 13:56:30 +00:00
bot-reviewer deleted branch feat/reservation-pravo-enumerator 2026-06-07 13:56:30 +00:00
Sign in to join this conversation.
No reviewers
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#1145
No description provided.