7.4 KiB
7.4 KiB
2026-09-06: Архитектурные решения Слоя 2 и границы независимых API слоёв
1. Контекст и цели
Зафиксированы ключевые проектные и архитектурные решения по разработке Слоя 2 в репозитории upload-platform перед началом реализации:
- Полная автономность и независимость каждого слоя как отдельного API.
- Легкость интеграции обоих слоёв (Слой 1 + Слой 2) в целевые сервисы (
drhider,contractor) без переделки исходного кода ядра. - Составлено подробное ТЗ и резюме в файле
LAYER2-RESUME.md.
2. Архитектурные границы слоёв и API-контракты
Слой 1: File Picker (v0.1.13 — готов и протестирован)
- Зона ответственности: выбор отдельных файлов, выбор папок (
webkitdirectory), клиентская рекурсивная распаковка ZIP-архивов с помощьюfflate, дедупликация, фильтрация по расширениям, проверка лимитов, отрисовка древовидного UI. - API-контракт: метод
picker.getFiles()возвращает плоский массив стандартных объектовFile. Слой полностью изолирован от транспорта и бэкенда.
Слой 2: Транзитная доставка через ВМ-буфер в RAM бэкенда (текущая задача)
- Причина существования: Ingress-контроллер k8s-кластера (
pythonk8s) обрывает входящие запросы с телом более 64 КБ. ПрямойPOSTбольших файлов в кластер невозможен; исходящий трафик (egress) из кластера не ограничен. - Принципиальные решения:
- Пофайловый транзит (Per-File Transit) вместо накопления всей пачки в буфере:
- Файл
kотправляется браузером черезPUTв буфер на ВМ. - Браузер сразу отправляет
POST /api/upload_refsбэкенду во Flask для одного файлаk. - Бэкенд забирает файл исходящим потоковым
GETпрямо в RAM сессии (upload/backend/session/state.py). - Бэкенд немедленно отправляет
DELETEна ВМ. - Файл на ВМ удалён, буфер чист. Браузер переходит к файлу
k+1. - В любой момент времени в буфере на ВМ находится максимум один файл.
- Файл
- RAM-only (хранение строго в памяти):
- Никакой записи на диск ни на бэкенде, ни на ВМ в постоянном режиме.
- Zero Hardcode:
- Полная параметризация через конфигурацию (
vmUploadUrlна фронтенде,vmUploadPrefixна бэкенде для обязательной SSRF-валидации).
- Полная параметризация через конфигурацию (
- Автономный mock-буфер:
- In-memory mock WebDAV (
PUT,GET,DELETE) внутри тестового стендаsite/app.pyдля автономного прогона pytest и Playwright без внешней сети.
- In-memory mock WebDAV (
- Пофайловый транзит (Per-File Transit) вместо накопления всей пачки в буфере:
- API-контракт фронтенда: функция
uploadFilesViaVm(files, options)с колбэками прогресса по файлу/пачке, завершения файла и поддержкой отмены (AbortController). - API-контракт бэкенда: Blueprint
upload_refsи менеджер сессийsession(создание сессии, потоковое вытягивание, хранение в RAM, TTL, мягкая отмена).
Слой 3: Бизнес-логика потребителей (не входит в текущую задачу)
- Сервисы
drhider(обфускация, LLM) иcontractor(парсинг, diff договоров) забирают файлы из оперативной памяти сессии черезsession.get_files(session_id). - В
upload-platformСлой 3 эмулируется тестовым callback/эндпоинтом, фиксирующим успешный приём файла из сессии для дальнейшей обработки.
3. Файловая структура Слоя 2 в upload-platform
upload-platform/
├── upload/
│ ├── frontend/
│ │ ├── index.js # Слой 1 (initFilePicker)
│ │ ├── table/ # UI Слоя 1
│ │ ├── zip/ # fflate
│ │ └── upload/ # Слой 2 (Фронтенд):
│ │ ├── put_to_vm.js # XHR PUT одного файла на буфер с прогрессом и abort
│ │ └── upload_via_vm.js # Пофайловый транзит (PUT -> upload_refs -> repeat)
│ └── backend/ # Слой 2 (Бэкенд):
│ ├── __init__.py
│ ├── upload_refs/
│ │ ├── __init__.py
│ │ ├── blueprint.py # Flask Blueprint (POST /api/upload_refs)
│ │ ├── pull_file.py # Исходящий потоковый GET с ретраями (httpx)
│ │ ├── safe_name.py # Санитизация имен файлов
│ │ └── config.py # Конфигурация по умолчанию
│ └── session/
│ ├── __init__.py
│ ├── state.py # In-memory хранилище сессий
│ ├── create_session.py
│ ├── add_file.py
│ ├── get_files.py
│ ├── store_result.py
│ ├── store_csv.py
│ ├── ttl.py
│ ├── cancel.py
│ └── cleanup.py
├── site/
│ ├── app.py # Flask demo + local RAM mock buffer
│ └── templates/index.html
├── tests/ # pytest + browser smoke
├── LAYER2-RESUME.md # Техническое задание и сводка
├── build.mjs
├── package.json
└── requirements.txt
4. Зафиксированные факты инфраструктуры
- ВМ
5.172.178.213: Nginx WebDAV настроен на сброс на диск (/var/www/drhider-upload/,/var/www/contracts-upload/) с cron-очисткой каждые 5 мин (find ... -mmin +30 -delete). Для целевого прода требуется перевод в RAM/in-memory буфер. - Кластер k8s: неймспейсы
20a75175-a58c-49cb-b8fa-e86367b1a8dc(drhider),b4523aba-b5e6-40f1-be56-bb4d2509357c(contractor),0e108526-5bb2-4757-9499-3f0bac4f0e83(uploader-dev).