fix(freshness): repoint nspd source to live nspd_quarter_dumps (data-table mode) #1908

Merged
bot-backend merged 1 commit from fix/freshness-nspd-repoint into main 2026-06-26 06:51:01 +00:00
Collaborator

Расследование (по твоему запросу «разобраться почему умер»)

Монитор заалертил nspd [failed, нет успешных прогонов]. Копнул — и оказалось, что NSPD не умер:

  • nspd_scrape_runs (куда смотрел монитор) — это defunct-ledger заброшенного ручного bulk-region harvest: 3 прогона, все triggered_by=manual, все failed 2026-04-30 с «WAF banned after 5 retries». Никогда не шедулился, заброшен после WAF-бана в апреле.
  • Живой NSPD-harvest — это tasks.nspd_sync.harvest_stale_quarters (в beat) + /analyze resolver write-back (#1891), оба пишут nspd_quarter_dumps напрямую, минуя ledger. Эта таблица свежая: 370 строк, 56 за 7 дней, последний fetch 2026-06-22.

Итог: не мёртвый источник, а монитор смотрел не на ту таблицу. Ретайрить было бы ошибкой (потеряли бы реальный сигнал) — правильно репойнтнуть на живую таблицу.

Фикс

  • FreshnessSource.timestamp_col — новый режим «data-table»: свежесть = MAX(timestamp_col) вместо run-ledger status-семантики (у nspd_quarter_dumps нет status/started/finished, только fetched_at_utc).
  • nspd репойнт → nspd_quarter_dumps.fetched_at_utc, пороги fresh<14d / stale<30d (медленный кадастровый + lazy-refresh источник). Текущий age ~4d → fresh (ложный алерт снят).
  • Run-ledger источники (kn/objective/nspd_geo/cadastre) не тронуты (timestamp_col=None → старая ветка).

SQL psycopg-v3 безопасен (CAST(:d1 AS interval), f-string только на trusted registry-именах). Без schema/codegen.

Тесты

+2 (nspd data-table fresh→ok; stale 40d→critical), существующие репойнтнуты. 12 passed, ruff clean.

⚠️ Наблюдение: живой harvest_stale_quarters вообще не пишет run-ledger — у scheduled-джобы нет observability своих прогонов (видим только косвенно через nspd_quarter_dumps). Можно отдельно добавить ledger-запись в таск (out of scope этого PR).

Refs #73

## Расследование (по твоему запросу «разобраться почему умер») Монитор заалертил `nspd [failed, нет успешных прогонов]`. Копнул — и оказалось, что **NSPD не умер**: - `nspd_scrape_runs` (куда смотрел монитор) — это **defunct-ledger** заброшенного ручного bulk-region harvest: 3 прогона, все `triggered_by=manual`, все `failed` 2026-04-30 с «WAF banned after 5 retries». Никогда не шедулился, заброшен после WAF-бана в апреле. - **Живой NSPD-harvest** — это `tasks.nspd_sync.harvest_stale_quarters` (в beat) + /analyze resolver write-back (#1891), оба пишут **`nspd_quarter_dumps` напрямую**, минуя ledger. Эта таблица **свежая: 370 строк, 56 за 7 дней, последний fetch 2026-06-22.** Итог: не мёртвый источник, а **монитор смотрел не на ту таблицу.** Ретайрить было бы ошибкой (потеряли бы реальный сигнал) — правильно репойнтнуть на живую таблицу. ## Фикс - `FreshnessSource.timestamp_col` — новый режим «data-table»: свежесть = `MAX(timestamp_col)` вместо run-ledger `status`-семантики (у `nspd_quarter_dumps` нет status/started/finished, только `fetched_at_utc`). - `nspd` репойнт → `nspd_quarter_dumps.fetched_at_utc`, пороги `fresh<14d / stale<30d` (медленный кадастровый + lazy-refresh источник). Текущий age ~4d → **fresh** (ложный алерт снят). - Run-ledger источники (kn/objective/nspd_geo/cadastre) не тронуты (timestamp_col=None → старая ветка). SQL psycopg-v3 безопасен (`CAST(:d1 AS interval)`, f-string только на trusted registry-именах). Без schema/codegen. ## Тесты +2 (nspd data-table fresh→ok; stale 40d→critical), существующие репойнтнуты. **12 passed**, ruff clean. ⚠️ **Наблюдение:** живой `harvest_stale_quarters` вообще не пишет run-ledger — у scheduled-джобы нет observability своих прогонов (видим только косвенно через `nspd_quarter_dumps`). Можно отдельно добавить ledger-запись в таск (out of scope этого PR). Refs #73
bot-backend added 1 commit 2026-06-26 06:39:11 +00:00
fix(freshness): repoint nspd source to live nspd_quarter_dumps (data-table mode)
All checks were successful
CI / changes (pull_request) Successful in 6s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 1m48s
CI / backend-tests (pull_request) Successful in 11m3s
5b2b8e1958
The freshness monitor watched defunct nspd_scrape_runs (3 WAF-banned manual
runs 2026-04-30, triggered_by=manual, never scheduled) → false "no successful
runs" alert. Investigation (surfaced by the monitor's first prod run) showed
NSPD is healthy: the live harvest (tasks.nspd_sync.harvest_stale_quarters +
the #1891 /analyze resolver write-back) writes nspd_quarter_dumps directly —
370 rows, 56 in the last 7 days, last fetched 2026-06-22 — but never writes
nspd_scrape_runs.

Add a data-table freshness mode (FreshnessSource.timestamp_col): when set, the
source uses MAX(timestamp_col) instead of run-ledger status semantics. Repoint
nspd → nspd_quarter_dumps.fetched_at_utc (fresh<14d, stale<30d). Run-ledger
sources (kn/objective/nspd_geo/cadastre) untouched. No schema/codegen change.

Refs #73
bot-backend merged commit 67d41df880 into main 2026-06-26 06:51:01 +00:00
bot-backend deleted branch fix/freshness-nspd-repoint 2026-06-26 06:51:01 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
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#1908
No description provided.