# Процесс загрузки

> Трехэтапный протокол загрузки файлов, составная передача, ожидание готовности и скачивание.

Загрузка и скачивание данных через REST API выполняются по строгому протоколу для обеспечения целостности каждого байта.

## Общая схема загрузки

Процесс передачи файла в облако разделен на три последовательных шага:

1. Шаг 1: клиент отправляет запрос на получение тикета загрузки `POST /files/upload-ticket` с метаданными и хэшем SHA-256.
2. Шаг 2: бинарное содержимое файла передается методом PUT по полученной ссылке загрузки. Для больших файлов передача выполняется по отдельным ссылкам для каждой части.
3. Шаг 3: клиент вызывает `POST /files/complete` для фиксации загрузки и ожидает статус `ready` через периодический опрос `GET /files/{file_id}`.

## Шаг 1: Запрос тикета (POST /files/upload-ticket)

Запрос создает запись в хранилище и возвращает временные ссылки для передачи данных:

```http
POST /files/upload-ticket HTTP/1.1
Host: api.mmwcloud.tech
Authorization: Bearer mmwc_<prefix>_<secret>
Content-Type: application/json

{
  "name": "backup-archive.tar.gz",
  "size_bytes": 15728640,
  "sha256": "4b68e210ac124b868e826b5278c5208fe3b0c44298fc1c149afbf4c8996fb924",
  "kind": "tar.gz"
}
```

Требуемое право: `files:write`.

### Параметры тела запроса

- `name` (обязательно): имя файла, не содержащее управляющих символов (`\r`, `\n`, `\0`).
- `size_bytes` (обязательно): точный размер файла в байтах.
- `sha256` (обязательно): контрольная сумма SHA-256 всего файла в шестнадцатеричном формате.
- `kind` (опционально): строковое обозначение расширения или типа файла (до 64 символов).
- `is_media` (опционально): логический признак медиафайла.
- `taken_at` (опционально): дата и время создания медиафайла (до 64 символов).
- `agent_sync_enabled`: через Developer API передавать запрещено (значение должно быть false или отсутствовать, иначе возвращается 400).

### Ответ для небольшого файла (до 8 МиБ)

Сервер возвращает единую прямую ссылку `upload_url`:

```json
{
  "id": "file_01h8upload123",
  "upload_url": "https://storage.mmwcloud.tech/v1/upload/file_01h8upload123?capability=token123"
}
```

### Ответ для составного файла (от 8 МиБ)

Сервер возвращает массив частей `parts` с отдельными ссылками:

```json
{
  "id": "file_01h8upload456",
  "parts": [
    {
      "part_number": 1,
      "upload_url": "https://storage.mmwcloud.tech/v1/upload-part/file_01h8upload456/1?capability=tokenPart1"
    },
    {
      "part_number": 2,
      "upload_url": "https://storage.mmwcloud.tech/v1/upload-part/file_01h8upload456/2?capability=tokenPart2"
    }
  ]
}
```

## Шаг 2: Бинарная передача данных

- Для небольшого файла: отправьте бинарное содержимое методом PUT по полученной ссылке `upload_url` с заголовком `Content-Type: application/octet-stream`.
- Для составного файла: отправьте каждый фрагмент методом PUT по соответствующей ссылке `upload_url` из списка частей. В ответе на загрузку части сервер возвращает JSON с полем `etag`. Сохраните полученное значение `etag` для каждого номера части `part_number`.

## Шаг 3: Завершение загрузки (POST /files/complete)

После передачи всех данных отправьте запрос на завершение:

```http
POST /files/complete HTTP/1.1
Host: api.mmwcloud.tech
Authorization: Bearer mmwc_<prefix>_<secret>
Content-Type: application/json

{
  "id": "file_01h8upload456",
  "parts": [
    { "part_number": 1, "etag": "\"etag-part-1\"" },
    { "part_number": 2, "etag": "\"etag-part-2\"" }
  ]
}
```

Требуемое право: `files:write`.

Для небольшого файла массив `parts` можно опустить или передать пустым. Сервер возвращает HTTP 202 Accepted.

## Ожидание готовности (Ready)

После подтверждения завершения сервер выполняет сборку и проверку целостности данных. Клиент периодически опрашивает статус файла через запрос `GET /files/{file_id}`. Когда поле `status` принимает значение `ready`, файл готов к скачиванию.

## Скачивание файла

Скачивание выполняется в два шага:

1. Запрос ссылки на скачивание: выполните `GET /files/{file_id}/download` с правом `files:read`. Сервер вернет JSON с адресом `download_url`:

```json
{
  "download_url": "https://storage.mmwcloud.tech/v1/download/file_01h8upload456?capability=tokenDownload"
}
```

2. Получение содержимого: выполните стандартный GET-запрос по полученному адресу `download_url`. Временная ссылка действует ограниченное время и сгорает автоматически.
