fix: harden browser file picker and remove legacy

This commit is contained in:
“Naeel”
2026-09-05 20:50:36 +03:00
parent f6b2f6d1b3
commit 017bd8c354
20 changed files with 499 additions and 216 deletions
@@ -0,0 +1,84 @@
# Ревью Gemini 3.8 Flash — 2026-09-05
## Контекст
Ревью ограничивалось проектом `upload-platform`. Проверены frontend-модули
универсального browser-only picker-а, Flask-обёртка, конфигурация и структура
проекта. Ниже зафиксированы findings ревью; исправления по этим пунктам в рамках
данной записи не выполнялись.
## Критические ошибки и логические баги (High)
1. **Не сбрасывается `fileInputEl.value` при выборе файлов.**
**Файл:** `upload/frontend/table/on_files_change.js`.
После удаления файла повторный выбор того же файла может не вызвать событие
`change`, если значение input не сброшено.
2. **Распаковка лишних файлов и преждевременный OOM в ZIP-фильтре.**
**Файл:** `upload/frontend/zip/list_zip_files.js`.
Callback `filter` проверяет размер и бюджет, но до декомпрессии не отбрасывает
записи с неразрешёнными расширениями. Бинарные файлы могут быть распакованы в
память, хотя затем будут отброшены.
3. **Синхронная блокировка UI при распаковке архивов.**
**Файл:** `upload/frontend/zip/list_zip_files.js`.
`unzipSync` выполняется в главном потоке браузера и может замораживать UI на
больших архивах. Предложенное направление: async unzip с чанками или Web Worker.
## Архитектурные недочёты и надёжность (Medium)
4. **Нарушается семантика `File.name` для файлов из папок и ZIP.**
**Файлы:** `upload/frontend/table/rebase_tree.js`,
`upload/frontend/zip/list_zip_files.js`.
При создании нового `File` полный логический путь может попасть в `file.name`,
хотя путь должен храниться отдельно в метаданных узла.
5. **Не выполняется слияние папок с одинаковыми путями.**
**Файл:** `upload/frontend/table/add_file_with_dedup.js`.
Повторное добавление корневого узла с тем же путём может создать два отдельных
узла вместо объединения их дочерних элементов.
6. **Потенциально небезопасная вставка HTML в статус.**
**Файл:** `upload/frontend/table/set_status.js`.
Прямое присваивание `innerHTML` требует гарантировать экранирование всех
передаваемых значений либо заменить его на безопасную работу с текстом.
7. **Молчаливый пропуск ошибок ZIP без `cfg.onError`.**
**Файлы:** `upload/frontend/table/on_files_change.js`,
`upload/frontend/table/on_folder_change.js`.
При отсутствии callback интегратор может не получить индикацию ошибки
повреждённого архива или превышения лимита.
8. **Падение `app.py` при отсутствии или повреждении `config.json`.**
**Файл:** `site/app.py`.
Чтение конфигурации выполняется на уровне импорта без обработки исключений;
при ошибке Flask-приложение не запускается.
## Мёртвый код и гигиена (Low)
9. **Дубликат `init_upload_table.js`.**
Файл выглядит неиспользуемым и дублирует логику текущего picker API.
Предложенное направление: удалить либо явно пометить как deprecated после
проверки всех импортов.
10. **Пустые служебные каталоги backend.**
Каталоги `session` и `upload_refs` содержат только старые `__pycache__`.
Требуется отдельное решение о сохранении или очистке структуры.
11. **Недостаточная обработка ошибок сборки в `build.mjs`.**
**Файл:** `build.mjs`.
Предложено добавить явную обработку ошибки сборки с `process.exit(1)` и
определить поведение каталога `dist/` перед сборкой.
## Итог
Gemini 3.8 Flash создал 4 задачи: три high/medium направления по ZIP и
событиям выбора, а также дополнительный набор архитектурных и гигиенических
проверок. Эта запись фиксирует результаты ревью как backlog. Код проекта и
рабочая реализация picker-а в рамках документирования не изменялись.
## Проверка записи
- Файл ревью создан в `HISTORY/`.
- Исходники проекта не изменялись.
- Findings сохранены в исходной классификации High, Medium и Low.