Each rule now has one owning contract; others point to it: validation and multi-step rules live in forms-validation (modal-workflows references them), pagination metadata lives in go-api (table-management references it), the async task flow lives in go-background-tasks (go-api references it), backup git-safety checks live in backup-management (go-database references it). Remove the leftover Vapor/Aqua baseline mention and stale kit/patterns paths, compress the batch-file-upload ADR narrative, and drop content-free pattern READMEs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
76 lines
3.4 KiB
Markdown
76 lines
3.4 KiB
Markdown
# Contract: Batch File Upload
|
||
|
||
Version: 1.1
|
||
|
||
## Purpose
|
||
|
||
Загрузка большого числа файлов одним multipart-запросом упирается в скрытые лимиты:
|
||
количество parts, размер тела запроса (413), таймауты соединения. Поэтому клиент делит
|
||
список файлов на батчи фиксированного размера и отправляет каждый батч отдельным
|
||
multipart-запросом. Цена решения — больше round-trips и, без агрегации, несколько
|
||
выходных файлов.
|
||
|
||
## Решение
|
||
|
||
- Размер батча определяется константой `MAX_FILES_PER_BATCH` (выбирается проектом).
|
||
- Батчи считаются по **числу файлов**, не только по байтам.
|
||
- Обработка батчей **последовательная** по умолчанию.
|
||
Параллельная обработка допускается только если явно оговорена и задокументирована.
|
||
- Каждый батч производит отдельный downloadable артефакт,
|
||
либо агрегируется на финальном шаге — решение принимается на уровне проекта.
|
||
|
||
---
|
||
|
||
## Правила реализации
|
||
|
||
### Константа батча
|
||
|
||
```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` — именование и доставка артефактов
|