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,98 @@
# Продолжение вопросов и ответов по ревью Gemini 3.8 Flash — 2026-09-05
## Контекст
Зафиксирован второй блок ответов Gemini на дополнительные вопросы по ревью
`upload-platform`. Ответы уточняют границы ответственности picker-а, приоритеты
и декомпозицию findings. Код приложения в рамках документирования не изменялся.
## Уточнения
### №4: `File.name` и логический путь
Рекомендация Gemini: сохранять в `file.name` только базовое имя файла, а полный
логический путь передавать через `node.path` и контракт `getFiles()`.
Основание: стандартный browser `File` использует `name` как имя файла без
каталогов. Полный путь в `file.name` может некорректно обрабатываться при
`FormData.append('files', file)` и сторонними upload-библиотеками. Передача пути
третьим аргументом `FormData.append(name, file, filename)` устраняет проблему,
но перекладывает внутреннюю особенность picker-а на интегратора.
### №8: fallback для `config.json`
Пункт признан защитной мерой demo-сервера, а не production-риском библиотеки.
В целевом сценарии распространяется JavaScript bundle из `dist/`, а `site/app.py`
служит demo-обёрткой и не участвует в интеграции picker-а с host-системой. Поэтому
пункт не входит в обязательный pre-release топ-3.
### №3: порог `unzipSync`
Оценочный порог заметного фриза заявлен как 15–25 MiB сжатых данных или сотни
мелких XML/DOCX entries с суммарной распаковкой свыше 50 MiB. Для архивов до
10 MiB задержка обычно несущественна. Для целевого профиля офисных документов и
текущих лимитов переход на Web Worker признан преждевременной оптимизацией.
Приоритетнее сначала фильтровать расширения до декомпрессии и сохранять жёсткие
лимиты. Worker остаётся backlog для архивов порядка 100 MiB и более.
### №7: поведение без `onError`
Рекомендованный default — выводить ошибку в общий статус picker-а, например в
`elements.statusEl` или `.fp-status`. Молчаливый `continue` создаёт плохой UX:
пользователь не понимает, почему содержимое архива не появилось. Создание
неотправляемого сломанного корневого узла в таблице также признано нежелательным.
### №10: состояние backend-каталогов
По заявленному результату проверки файловой системы в `upload/backend/` остаются
только каталоги `session/` и `upload_refs/`, внутри которых нет исходников; есть
лишь пустые каталоги `__pycache__` от удалённых модулей. Вердикт Gemini: чинить
нечего, это остатки, которые можно удалить отдельным разрешённым изменением.
## Декомпозиция 11 findings на 4 задачи
### Задача 1: pre-release hotfixes UI и ZIP
- №1: сброс `fileInputEl.value` после обработки выбора;
- №2: фильтрация расширения внутри ZIP `filter` до декомпрессии;
- №5: слияние корневых папок с одинаковым путём.
Результат: корректный повторный выбор, снижение риска OOM и отсутствие дубликатов
корневых папок.
### Задача 2: контракт данных и обработка ошибок
- №4: базовое имя в `file.name`, путь в метаданных;
- №7: fallback-вывод ошибок ZIP в общий статус;
- №8: безопасная загрузка `config.json` с fallback-конфигурацией.
Результат: предсказуемый контракт browser `File` и понятная обратная связь.
### Задача 3: очистка репозитория
- №6: удаление или отдельное решение по legacy `set_status.js`;
- №9: удаление или отдельное решение по legacy `init_upload_table.js`;
- №10: удаление пустого `backend/` с остатками `__pycache__`;
- №11: определение поведения `dist/` перед сборкой.
Результат: в репозитории остаются актуальные исходники и ясная структура сборки.
### Задача 4: производительность больших архивов
- №3: перевод тяжёлой ZIP-распаковки в async-поток или Web Worker.
Задача отнесена в backlog и актуальна при появлении сценариев с очень большими
архивами.
## Итоговый приоритет
До следующего release в первую очередь предлагаются пункты **№2, №1 и №5**.
Пункты №4, №7, №8 и очистка legacy-кода относятся ко второй очереди. №3
остаётся производительным backlog до подтверждения реальных сценариев больших
архивов.
## Статус документирования
- Ответ Gemini сохранён в `HISTORY/`.
- Исходный код picker-а не изменялся.
- Удаление `__pycache__` и любых каталогов не выполнялось.