Add batch file upload ADR contract
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
101
rules/patterns/batch-file-upload/contract.md
Normal file
101
rules/patterns/batch-file-upload/contract.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# Contract: Batch File Upload
|
||||
|
||||
Version: 1.0
|
||||
|
||||
## Purpose
|
||||
|
||||
ADR: стратегия загрузки большого числа файлов через multipart-запросы
|
||||
без переработки серверного pipeline и без скрытых лимитов.
|
||||
|
||||
---
|
||||
|
||||
## ADR
|
||||
|
||||
**Дата:** 2026-03-01
|
||||
**Статус:** Accepted
|
||||
|
||||
### Контекст
|
||||
|
||||
Клиент должен загрузить список файлов на сервер для обработки.
|
||||
Загрузка всех файлов одним multipart-запросом упирается в скрытые лимиты:
|
||||
количество parts, размер тела запроса (413), таймауты соединения.
|
||||
Переработка серверного pipeline под стриминговую загрузку — отдельная дорогостоящая задача.
|
||||
|
||||
### Решение
|
||||
|
||||
Клиент делит список файлов на батчи фиксированного размера и отправляет каждый батч
|
||||
отдельным multipart-запросом.
|
||||
|
||||
- Размер батча определяется константой `MAX_FILES_PER_BATCH` (выбирается проектом).
|
||||
- Батчи считаются по **числу файлов**, не только по байтам.
|
||||
- Обработка батчей **последовательная** по умолчанию.
|
||||
Параллельная обработка допускается только если явно оговорена и задокументирована.
|
||||
- Каждый батч производит отдельный downloadable артефакт,
|
||||
либо агрегируется на финальном шаге — решение принимается на уровне проекта.
|
||||
|
||||
### Последствия
|
||||
|
||||
**Плюсы:**
|
||||
- Избегаем скрытых лимитов на количество multipart parts
|
||||
- Снижаем риск таймаутов и ошибок 413
|
||||
- Не требует немедленной переработки серверного parser pipeline
|
||||
|
||||
**Минусы:**
|
||||
- Больше round-trips (N батчей = N запросов)
|
||||
- Несколько выходных файлов если артефакты не агрегируются
|
||||
- Более долгий end-to-end UX для пользователя
|
||||
|
||||
---
|
||||
|
||||
## Правила реализации
|
||||
|
||||
### Константа батча
|
||||
|
||||
```go
|
||||
const MaxFilesPerBatch = 1000 // выбирается проектом
|
||||
```
|
||||
|
||||
Константа объявляется явно — не хардкодится inline.
|
||||
|
||||
### Именование артефактов
|
||||
|
||||
Результаты батчей именуются с суффиксом `_partN`:
|
||||
|
||||
```
|
||||
report_part1.csv
|
||||
report_part2.csv
|
||||
report_part3.csv
|
||||
```
|
||||
|
||||
Или агрегируются в единый файл на финальном шаге — тогда суффикс не нужен.
|
||||
|
||||
### Обработка ошибок
|
||||
|
||||
- Ошибку превышения лимита parts (`multipart: too many parts`) **не маскировать** под ошибку размера.
|
||||
- Логировать первичную причину с явным указанием типа лимита.
|
||||
- Клиент при получении ошибки лимита должен уменьшить батч и повторить, либо сообщить пользователю.
|
||||
|
||||
```go
|
||||
// Правильно
|
||||
log.Error("batch upload failed: multipart parts limit exceeded", "batch", batchNum, "files", len(batch))
|
||||
|
||||
// Неправильно
|
||||
log.Error("batch upload failed: file too large") // маскирует причину
|
||||
```
|
||||
|
||||
### UI
|
||||
|
||||
UI обязан показывать пользователю:
|
||||
|
||||
- Общее количество батчей (проходов): `Шаг 2 из 5`
|
||||
- Прогресс текущего батча: прогресс-бар или процент
|
||||
- Финальный статус каждого батча до начала следующего
|
||||
|
||||
Пользователь не должен видеть технический термин "батч" — использовать "шаг" или "проход".
|
||||
|
||||
---
|
||||
|
||||
## Связанные контракты
|
||||
|
||||
- `go-background-tasks` — каждый батч запускается как фоновая задача
|
||||
- `import-export` — именование и доставка артефактов
|
||||
Reference in New Issue
Block a user