feat(db): quarter_price_index FDW foreign table + monthly refresh (Refs #762) #797
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
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#797
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/762-quarter-index-refresh"
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?
Что (P0, #647-2)
Делает
mv_quarter_price_index(#760, merged) читаемым estimator'ом за O(1) + периодический refresh. Инфра — клиентскую цену НЕ меняет (integration = #647-3, за гейтом #763).Решение (#647-1 decided: MV в main + FDW-чтение)
085_quarter_price_index_fdw.sql:FOREIGN TABLE quarter_price_indexнад mainpublic.mv_quarter_price_indexчерез существующий servergendesign_remote(паттерн060_postgres_fdw_extension.sql, per-table). Колонки 1:1 (varchar(30)/float8/bigint/text/timestamptz).DROP IF EXISTSидемпот.99b_grant_quarter_price_index_fdw.sql:GRANT SELECTна MV ролиtradein_fdw_reader(иначе foreign table падает на runtime; зеркало122_grant_rosreestr_to_fdw_reader.sql). Сортируется после99a_(MV создаётся там).quarter_price_index_refresh.py— chainedREFRESH mv_quarter_price_per_m2 → mv_quarter_price_index CONCURRENTLY; taskrefresh_quarter_price_index.py; beat-entryrefresh-quarter-price-indexcron0 2 5 * *(05:00 MSK 5-го, послеrefresh-ekb-districts-medians).Lookup-индекс
MV уже несёт
UNIQUE mv_quarter_price_index_uq(O(1) remote, FDW push-downWHERE quarter_cad_number=$1); локальный индекс на foreign table не нужен/невозможен.Валидация (postgres-gendesign)
MV 1972 строки, 0 NULL,
indisunique=true,REFRESH CONCURRENTLYвалиден. Column mapping сверен 1:1 с live MV.NB
quarter_price_refresh.py(standalone для source-MV) оставлен для ручного вызова; в beat — только chained task (избегаем double-refresh).Разблокирует #647-3. Refs #762
✅ APPROVE
FDW foreign table + chained monthly refresh для
quarter_price_index(P0 #647-2).Correctness
CREATE FOREIGN TABLEнад main MV черезgendesign_remote; колонки 1:1 (сверено с live MV);DROP IF EXISTSидемпот, BEGIN/COMMIT, per-table паттерн (как 060). NOT NULL — informational для postgres_fdw (MV гарантирует non-null per #792), безвредно.GRANT SELECT … TO tradein_fdw_reader, зеркало 122. Ordering reasoned:99b_после99a_(MV create,a<b); роль из100_(сортируется перед99_через1<9) — обе зависимости до grant. Идемпот.mv_quarter_price_per_m2→mv_quarter_price_index(верный порядок — derived читает source), CONCURRENTLY с safe-fallback на non-concurrent при "cannot refresh"-edge; commit per step; возвращает row count. У обоих MV unique index → CONCURRENTLY валиден.0 2 5 * *(05:00 MSK 5-го, после refresh-ekb-districts-medians 04:00),max_retries=2, SessionLocal+close. Имя task совпадает с beat-entry.Scope/security — чистая инфра (FDW read + refresh); estimator-интеграция = #647-3 (за гейтом #763) → нулевой риск клиентской цены. Новые файлы + beat-entry; нет secrets, нет self-extending триггера. Live-validated (MV 1972 строки, indisunique=true, CONCURRENTLY валиден, mapping 1:1).
Verdict: ✅ APPROVE (P0 #762). FDW read + refresh → qa.