feat(objective): diff-gated objective_lots_history writer trigger (#307 OBJ-6) #1719

Merged
lekss361 merged 2 commits from feat/objective-lots-history-writer-307-obj6 into main 2026-06-17 19:44:27 +00:00
Owner

Задача (#307 OBJ-6)

objective_lots_history имел 974k строк, но дельта-трекинга не было — python-парсер (70_parse_objective_raw.py) делал wholesale INSERT ... ON CONFLICT DO NOTHING (одна строка на лот в день, независимо от изменений; vault-заметка про «delta tracking ON» оказалась ложной).

Решение

Миграция 164_objective_lots_history_writer.sql: AFTER INSERT OR UPDATE триггер objective_lots_write_history, diff-gated по price_per_m2_rub/price_calculated_total_rub/price_offer_total_rub/status/is_sold (IS DISTINCT FROM, NULL-safe). Latest-snapshot lookup по индексу; price_delta_pct snapshot-over-snapshot; ON CONFLICT DO UPDATE (чинит drop intraday-изменений). Idempotent. Python sync НЕ тронут (правится параллельным воркером).

Verify (live DB, авто-rollback, 0 прод-мутаций)

price 167326→180000 → 1 строка, delta 7.57 ; no-tracked-change → 0 строк ; same-day → update in place ; new lot → 1 строка . Триггер enabled на проде.

Follow-up (не в PR)

Убрать прямой history-INSERT из 70_parse_objective_raw.py (тот файл правит OBJ-1-воркер) — тогда history станет полностью diff-gated. Сейчас безопасно сосуществуют (DO UPDATE, без дублей).

Closes #307 (OBJ-6)

## Задача (#307 OBJ-6) `objective_lots_history` имел 974k строк, но **дельта-трекинга не было** — python-парсер (`70_parse_objective_raw.py`) делал wholesale `INSERT ... ON CONFLICT DO NOTHING` (одна строка на лот в день, независимо от изменений; vault-заметка про «delta tracking ON» оказалась ложной). ## Решение Миграция `164_objective_lots_history_writer.sql`: `AFTER INSERT OR UPDATE` триггер `objective_lots_write_history`, diff-gated по `price_per_m2_rub`/`price_calculated_total_rub`/`price_offer_total_rub`/`status`/`is_sold` (`IS DISTINCT FROM`, NULL-safe). Latest-snapshot lookup по индексу; `price_delta_pct` snapshot-over-snapshot; `ON CONFLICT DO UPDATE` (чинит drop intraday-изменений). Idempotent. Python sync НЕ тронут (правится параллельным воркером). ## Verify (live DB, авто-rollback, 0 прод-мутаций) price 167326→180000 → 1 строка, delta 7.57 ✅; no-tracked-change → 0 строк ✅; same-day → update in place ✅; new lot → 1 строка ✅. Триггер enabled на проде. ## Follow-up (не в PR) Убрать прямой history-INSERT из `70_parse_objective_raw.py` (тот файл правит OBJ-1-воркер) — тогда history станет полностью diff-gated. Сейчас безопасно сосуществуют (DO UPDATE, без дублей). Closes #307 (OBJ-6)
lekss361 added 1 commit 2026-06-17 19:33:51 +00:00
feat(objective): diff-gated objective_lots_history writer trigger (#307 OBJ-6)
Some checks failed
CI / changes (pull_request) Successful in 9s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Failing after 2m24s
CI / backend-tests (pull_request) Failing after 9m11s
3a3f934bac
bot-backend added 1 commit 2026-06-17 19:44:05 +00:00
chore(sql): renumber objective history writer migration 164→166 (avoid collision)
Some checks failed
CI / changes (pull_request) Successful in 7s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Failing after 1m47s
CI / backend-tests (pull_request) Failing after 9m16s
e4cc2d9625
lekss361 merged commit 13db14c8c9 into main 2026-06-17 19:44:27 +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#1719
No description provided.