make_thumbnail: пропуск по факту существования → устаревшая миниатюра после перекачки оригинала #1642

Closed
opened 2026-06-16 18:46:29 +00:00 by bot-backend · 0 comments
Collaborator

Severity: low · Категория: data-staleness/correctness · Файл: backend/app/services/photos/thumbs.py:42-46

Файл: backend/app/services/photos/thumbs.py:42-46. Логика пропуска if dst.exists() and not overwrite: return dst сравнивает только существование, никогда — свежесть (mtime/контент src vs dst). Цепочка в scrapers/domrf_kn.py: при local.stat().st_size != expected_size (строка 1403) оригинал перекачивается и перезаписывается (local.write_bytes(data), 1408), но миниатюра обновляется только если её нет (1414-1418, ветка else), а существующий _thumb.webp переиспользуется без регенерации. overwrite=True не передаёт ни один вызывающий (photos.py:97,114; domrf_kn.py:1418). Импакт: обновлённое фото DOM.РФ продолжает показывать СТАРУЮ миниатюру в гриде; усугубляется иммутабельным кэшем на 7 дней (photos.py:88 Cache-Control: public, max-age=604800, immutable). Фикс: в scraper при ветке перекачки (size mismatch) удалять/перегенерировать тумбу — вызывать make_thumbnail(local, overwrite=True) после write_bytes, либо в make_thumbnail сравнивать dst.stat().st_mtime < src.stat().st_mtime и регенерировать при устаревании.

Почему баг: Existence is not a freshness check. After a content change under the same obj_file_id, the source PNG/JPG is rewritten but dst.exists() is True, so make_thumbnail returns the stale thumb path unchanged. The API (photos.py:88) serves it with Cache-Control: public, max-age=604800, immutable, so even a later regeneration wouldn't reach the browser for a week. The grid permanently shows a thumbnail that no longer matches the original.

Как чинить: In make_thumbnail, when dst exists and overwrite is False, also verify freshness: regenerate if dst.stat().st_mtime < src.stat().st_mtime. Alternatively have the re-download path in domrf_kn.py unlink the old thumb (thumb_path_for(local).unlink(missing_ok=True)) before calling make_thumbnail, or pass overwrite=True there.


deep-audit backend v2 (2-й проход, после PR #1543) · verify+harden, confidence 0.85 · unit B30

**Severity:** low · **Категория:** data-staleness/correctness · **Файл:** `backend/app/services/photos/thumbs.py:42-46` Файл: backend/app/services/photos/thumbs.py:42-46. Логика пропуска `if dst.exists() and not overwrite: return dst` сравнивает только существование, никогда — свежесть (mtime/контент src vs dst). Цепочка в scrapers/domrf_kn.py: при `local.stat().st_size != expected_size` (строка 1403) оригинал перекачивается и перезаписывается (`local.write_bytes(data)`, 1408), но миниатюра обновляется только если её нет (1414-1418, ветка else), а существующий `_thumb.webp` переиспользуется без регенерации. overwrite=True не передаёт ни один вызывающий (photos.py:97,114; domrf_kn.py:1418). Импакт: обновлённое фото DOM.РФ продолжает показывать СТАРУЮ миниатюру в гриде; усугубляется иммутабельным кэшем на 7 дней (photos.py:88 `Cache-Control: public, max-age=604800, immutable`). Фикс: в scraper при ветке перекачки (size mismatch) удалять/перегенерировать тумбу — вызывать `make_thumbnail(local, overwrite=True)` после write_bytes, либо в make_thumbnail сравнивать `dst.stat().st_mtime < src.stat().st_mtime` и регенерировать при устаревании. **Почему баг:** Existence is not a freshness check. After a content change under the same obj_file_id, the source PNG/JPG is rewritten but `dst.exists()` is True, so make_thumbnail returns the stale thumb path unchanged. The API (photos.py:88) serves it with `Cache-Control: public, max-age=604800, immutable`, so even a later regeneration wouldn't reach the browser for a week. The grid permanently shows a thumbnail that no longer matches the original. **Как чинить:** In make_thumbnail, when dst exists and overwrite is False, also verify freshness: regenerate if `dst.stat().st_mtime < src.stat().st_mtime`. Alternatively have the re-download path in domrf_kn.py unlink the old thumb (thumb_path_for(local).unlink(missing_ok=True)) before calling make_thumbnail, or pass overwrite=True there. --- <sub>deep-audit backend v2 (2-й проход, после PR #1543) · verify+harden, confidence 0.85 · unit B30</sub>
bot-backend added the
week ревью 1
label 2026-06-16 18:46:29 +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#1642
No description provided.