Files
upload-platform/HISTORY/2026-09-05-file-picker.md
T

7.3 KiB
Raw Blame History

2026-09-05 — browser file-picker и иерархическое дерево

Исходная задача

  • Требовался браузерный выбор документов в upload-platform.
  • После уточнения требований сервис должен работать только как file-picker.
  • Загрузка файлов на VM, pull-фаза, backend sessions и upload API не требовались.
  • Интерфейс должен поддерживать выбор отдельных файлов, папок и ZIP.
  • Выбранные данные должны отображаться в виде сворачиваемого иерархического дерева.
  • Должна быть возможность удалить отдельный файл или целую группу.
  • Последующий сервисный слой должен получать leaf-файлы и их полные пути.
  • Разрешены только расширения .pdf, .doc, .docx, .txt, .md.
  • Ограничения по размеру и количеству файлов не добавлялись.
  • Должны поддерживаться вложенные структуры: folder -> ZIP -> subfolder -> ZIP -> file.

Реализовано

  • Удалён VM upload layer: PUT на внешний VM endpoint, pull, backend sessions и upload API.
  • Удалены старые backend/API части upload-platform по явному запросу:
    • upload/backend/;
    • site/routes/;
    • upload/frontend/upload/.
  • Flask-приложение оставлено только для отдачи страницы и frontend-модулей:
    • /;
    • /health;
    • /upload-frontend/<path:filename>.
  • Реализован интерфейс выбора файлов, выбора папки и очистки.
  • Добавлена конфигурация разрешённых расширений.
  • Реализована рекурсивная модель дерева с типами file, folder, zip.
  • Для ZIP реализованы чтение через локальный fflate, сохранение полных путей, раскрытие вложенных ZIP и фильтрация расширений.
  • Для выбранной папки реализованы чтение webkitRelativePath, построение вложенных каталогов, раскрытие ZIP внутри папки и удаление пустых групп.
  • Добавлена дедупликация по path + size.
  • Реализовано рекурсивное удаление дублей и пустых групп.
  • В таблице реализованы рендер дерева, сворачивание/разворачивание групп, удаление leaf-файлов и удаление групп вместе со всем поддеревом.
  • Счётчики количества файлов и общего размера пересчитываются после изменений.
  • Состояние таблицы хранит исходные browser File objects и метаданные для последующего сервисного слоя.
  • Версия приложения повышена до 0.1.6.

Исправления по ходу работы

  • Первоначальная реализация отправляла файлы на VM; она заменена на picker-only архитектуру.
  • Убраны устаревшие фрагменты VM upload и API.
  • Исправлены дублированные фрагменты кода, обнаруженные синтаксической проверкой после первоначального патча.
  • Исправлено построение полных путей для файлов в ZIP и вложенных ZIP.
  • Исправлено построение путей корневых папок и обычных файлов при выборе директории.
  • Исправлено удаление пустых групп после дедупликации.
  • Исправлен показ запрещённых файлов при обработке ZIP: ZIP без разрешённых leaf-файлов больше не отображается как группа.
  • Исправлен fallback для ошибочно раскрывающихся ZIP: нераскрытый ZIP не показывается пользователю как содержимое.
  • Добавлен HTML-фильтр accept для системного диалога выбора: показываются только разрешённые документы и .zip, а не Все файлы (*.*).

Проверки

  • Синтаксис JavaScript проверен через Node.js для frontend-модулей.
  • Синтетический тест вложенного ZIP подтвердил пути archive.zip/root.pdf и archive.zip/docs/inner.zip/deep.txt, а .png был исключён.
  • Повторная загрузка одинакового дерева не добавляет дубликаты.
  • Удаление корневого дерева удаляет все leaf-файлы.
  • Flask smoke test подтвердил страницу, /health и frontend-маршруты.
  • git diff --check прошёл.
  • Реальный браузерный тест подтвердил:
    • отображение обычного plain.md;
    • ZIP с вложенным ZIP;
    • фильтрацию .png и .jpg;
    • три сохранённых leaf-файла и общий размер 16 B;
    • сворачивание archive.zip через aria-expanded=false;
    • удаление группы archive.zip вместе со всем поддеревом;
    • удаление leaf-файла до состояния 0 файлов · 0 B;
    • выбор папки и фильтрацию запрещённых main.py и image.png.
  • Несколько автоматических кликов через browser tool не сработали из-за нестабильности Playwright locator; точные accessibility-селекторы и DOM-события подтвердили те же операции без дефектов приложения.
  • Дополнительный браузерный тест подтвердил, что ZIP только с image.jpg оставляет таблицу пустой: 0 файлов · 0 B.
  • Проверено наличие accept=".pdf,.doc,.docx,.txt,.md,.zip" у обоих file input.

Git

  • c0b8788 Implement reusable upload platform — первоначальный reusable upload platform.
  • 85605fe Remove VM upload layer; keep file picker only — удаление VM upload и переход к picker-only.
  • a965f18 Add hierarchical file picker — иерархическое дерево, вложенные ZIP, удаление групп и файлов.
  • До добавления этой записи master был синхронизирован с origin/master.
  • Текущая запись добавляется отдельным коммитом и отправляется в origin/master.