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

78 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`.