persist_analysis_run коммитит result ДО дописывания forecast/ird/developer_attribution — сохранённый ран расходится с live-ответом #1561

Closed
opened 2026-06-16 17:05:31 +00:00 by bot-backend · 0 comments
Collaborator

Severity: low · Категория: data-consistency · Файл: backend/app/api/v1/parcels.py:2871-2945

Файл /Users/anton/Птица/gendesign/backend/app/api/v1/parcels.py:2871-2945. persist_analysis_run(db, result=result_payload, ...) (2871) сериализует result_payload в jsonb и делает явный db.commit() (repository.py:140) — снимок фиксируется в этот момент. Уже ПОСЛЕ persist в result_payload дописываются ключи: forecast (2899/2909), ird (2917, под флагом enable_ird_analyze) и developer_attribution (2937). Поскольку _jsonb_param(result) сериализует dict в JSON-строку во время execute (до возврата управления в 2887), последующие мутации в DB не попадают. Эти ключи есть в live-ответе POST /analyze (return на 2945), но НЕ в строке analysis_runs. GET /runs/{run_id} (1061-1077) возвращает run.result как есть → при re-open сохранённого анализа пользователь видит отчёт БЕЗ блока атрибуции застройщика и ИРД-слоя, бывших в первичном ответе. Импакт: вторичная (advisory) потеря содержимого в истории для developer_attribution/ird; для forecast это лишь pending-заглушка (не потеря). Фикс: вызвать persist_analysis_run ПОСЛЕ дописывания всех additive-блоков, либо отдельным UPDATE дополнить result после сборки forecast/ird/developer_attribution.

Почему баг: GET /runs/{run_id} и re-open истории возвращают run.result как есть (см. get_analysis_run, 1061-1077). Пользователь, открывший сохранённый анализ, увидит отчёт БЕЗ блока атрибуции застройщика и ИРД-слоя, которые были в первичном ответе — то есть данные «исчезают» при повторном открытии того же рана. Для developer_attribution/ird это реальная (хоть и вторичная, advisory) потеря содержимого в истории; для forecast это лишь pending-заглушка.

Как чинить: Если эти блоки должны жить в истории — собирать forecast/ird/developer_attribution в result_payload ДО вызова persist_analysis_run (developer_attribution и ird — синхронные DB-резолверы, их можно посчитать раньше). Либо явно задокументировать, что история не включает advisory-блоки, и не вводить пользователя в заблуждение на UI re-open.


deep-audit backend v2 (после PR #1543) · verify+harden, confidence 0.85 · unit B02

**Severity:** low · **Категория:** data-consistency · **Файл:** `backend/app/api/v1/parcels.py:2871-2945` Файл /Users/anton/Птица/gendesign/backend/app/api/v1/parcels.py:2871-2945. `persist_analysis_run(db, result=result_payload, ...)` (2871) сериализует `result_payload` в jsonb и делает явный `db.commit()` (repository.py:140) — снимок фиксируется в этот момент. Уже ПОСЛЕ persist в `result_payload` дописываются ключи: `forecast` (2899/2909), `ird` (2917, под флагом enable_ird_analyze) и `developer_attribution` (2937). Поскольку `_jsonb_param(result)` сериализует dict в JSON-строку во время execute (до возврата управления в 2887), последующие мутации в DB не попадают. Эти ключи есть в live-ответе POST /analyze (return на 2945), но НЕ в строке analysis_runs. GET /runs/{run_id} (1061-1077) возвращает `run.result` как есть → при re-open сохранённого анализа пользователь видит отчёт БЕЗ блока атрибуции застройщика и ИРД-слоя, бывших в первичном ответе. Импакт: вторичная (advisory) потеря содержимого в истории для developer_attribution/ird; для forecast это лишь pending-заглушка (не потеря). Фикс: вызвать persist_analysis_run ПОСЛЕ дописывания всех additive-блоков, либо отдельным UPDATE дополнить result после сборки forecast/ird/developer_attribution. **Почему баг:** `GET /runs/{run_id}` и re-open истории возвращают `run.result` как есть (см. get_analysis_run, 1061-1077). Пользователь, открывший сохранённый анализ, увидит отчёт БЕЗ блока атрибуции застройщика и ИРД-слоя, которые были в первичном ответе — то есть данные «исчезают» при повторном открытии того же рана. Для `developer_attribution`/`ird` это реальная (хоть и вторичная, advisory) потеря содержимого в истории; для `forecast` это лишь pending-заглушка. **Как чинить:** Если эти блоки должны жить в истории — собирать forecast/ird/developer_attribution в result_payload ДО вызова persist_analysis_run (developer_attribution и ird — синхронные DB-резолверы, их можно посчитать раньше). Либо явно задокументировать, что история не включает advisory-блоки, и не вводить пользователя в заблуждение на UI re-open. --- <sub>deep-audit backend v2 (после PR #1543) · verify+harden, confidence 0.85 · unit B02</sub>
bot-backend added the
week ревью 1
label 2026-06-16 17:05:31 +00:00
Sign in to join this conversation.
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#1561
No description provided.