From c16e071859731894deb90ac44c0184eb2b8ea7d2 Mon Sep 17 00:00:00 2001 From: Light1YT Date: Sun, 28 Jun 2026 22:10:44 +0500 Subject: [PATCH] test(supply_layers): assert inline DISTINCT ON physflat-dedup, not the view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Perf-батч #2 заменил _L1_OPEN_SQL view→inline DISTINCT ON. Тест из #1964 (test_sql_reads_physflat_view) ассертил наличие view + отсутствие FROM objective_lots — теперь инвертирован под inline. Новый инвариант сохраняет анти-регресс #1964 (требует physflat-дедуп через DISTINCT ON, иначе сырой objective_lots раздул бы units_available ~2.91×) и запрещает view (full-scan). --- .../site_finder/test_supply_layers.py | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/backend/tests/services/site_finder/test_supply_layers.py b/backend/tests/services/site_finder/test_supply_layers.py index 054db14f..e9e245fd 100644 --- a/backend/tests/services/site_finder/test_supply_layers.py +++ b/backend/tests/services/site_finder/test_supply_layers.py @@ -229,16 +229,22 @@ class TestLayer1Open: assert "CAST(:districts AS text[])" in sql _assert_no_double_colon_cast(sql) - def test_sql_reads_physflat_view(self) -> None: - # #1964: L1 открытое предложение читает physflat-дедуп view, НЕ сырой - # objective_lots (раздут ~2.91× мульти lot_id/физлот → units_available был - # завышен ~3-4.6× → дефицит-форсайт переоценивал L1). Регресс к - # `FROM objective_lots` → fail. + def test_sql_dedups_physflat_inline(self) -> None: + # Перф-батч #2 (#1953-followup): L1 дедупит INLINE через DISTINCT ON по + # physflat-ключу (последний снапшот), НЕ через v_objective_lots_latest + # (view = оптимизационный барьер → full-scan 1.76M, ~6с). Анти-регресс + # #1964 сохранён: чтение СЫРОГО objective_lots БЕЗ дедупа раздуло бы + # units_available ~2.91× (мульти lot_id/физлот) — поэтому требуем DISTINCT ON. db = _mock_db([]) compute_layer1_open(db, district="Автовокзал") sql = _executed_sql(db) - assert "v_objective_lots_latest" in sql, "L1 должен читать physflat-дедуп view" - assert "FROM objective_lots " not in sql, "L1 не должен читать сырой objective_lots" + norm = " ".join(sql.split()) + assert "DISTINCT ON" in norm, "L1 должен physflat-дедупить (анти-инфляция #1964)" + for col in ("project_name", "corpus_name", "section", "floor", "lot_number"): + assert col in norm, f"physflat-ключ DISTINCT ON должен включать {col}" + assert "snapshot_date DESC" in norm, "дедуп к последнему снапшоту физлота" + assert "FROM objective_lots" in norm, "L1 читает сырой objective_lots (inline-дедуп)" + assert "v_objective_lots_latest" not in sql, "view = full-scan, должен быть inline" def test_params(self) -> None: db = _mock_db([])