Перейти к содержимому
СервисАпп API
На этой странице

Фотографии и документы выезда

Все операции. Авторизация. Запросы и повторы.

Все пути в этом файле дополняют /api/v1 на домене организации.

Описание и ограничения

Назначение

Получение и загрузка фотографий и документов выезда.

Поля и назначение

Публичное поле Формат и смысл Доступ
id, visit_id, filename, mime_type, size метаданные файла; visit_id задаётся путём только чтение
file один проверяемый файл входное поле
kind явный вид вложения входное поле / только чтение
client_filename необязательный имя файла без пути до 255 символов входное поле
version строка Unix-секунд для If-Resource-Version удаления; текущее состояние владельца и доступ проверяются отдельно под блокировкой только чтение
download_url, created_at относительный путь скачивание, дата и время UTC только чтение

Обязательность и null указаны в схемах каждой операции ниже.

Доступ и выборка

Чтение требует visit_media:read и «Акты приёма оборудования → Просмотр» в текущем контексте выезда. Запись требует visit_media:write и «Акты приёма оборудования → Изменение»; загрузка дополнительно требует «Системные настройки → Загрузка вложений». Дополнительные visits:read/write для этих методов не нужны. Авторизация проверяется также при скачивании, а не только в списке.

kind=photo обозначает фотографию, kind=attachment — вложение. Список поддерживает filter[kind]=photo или attachment, сортировку id или -id и общую пагинацию. Другие виды файлов через этот ресурс недоступны.

Правила и связи

  • Фотографии: JPEG, PNG, WebP и GIF. Вложения: PDF, JPEG, PNG и WebP. Допустим один непустой файл размером до 10 МиБ. Тип проверяется по содержимому, а не только расширению.
  • При повторе сравниваются содержимое файла, имя и поля запроса.
  • Повтор POST с прежним ключом возвращает тот же идентификатор файла и не создаёт вторую загрузку.
  • После сбоя файла/БД незавершённые загрузки очищаются или возобновляются, а не становятся вторым файлом.
  • Ссылка на другой файл и путь к файлу на сервере не заменяют загрузку содержимого.

Незавершённая загрузка не появляется в списке готовых файлов. Ответ 202 содержит идентификатор операции; проверяйте её состояние в журнале. Повтор с прежним ключом продолжает ту же загрузку. Перед завершением заново проверяются права, исходный акт и текущий владелец выезда. После переноса выезда нужны права на исходные и текущие записи; утрата доступа к исходному акту закрывает прежний сохранённый ответ.

Запрос и ответ

Загрузка принимает обязательные file и kind, а также необязательный client_filename. Если имя не задано, используется имя загружаемого файла без пути и управляющих символов, до 255 символов. Явно переданное client_filename с путём или управляющими символами возвращает 422. If-Resource-Version не нужен: это добавление независимого вложения. Успех — 201 с полями id, kind, filename, mime_type, size, version, created_at и download_url. Ссылка скачивания имеет вид /api/v1/visits/{visit_id}/media/{id}/download. Повтор возвращает прежние данные. Версия выезда обновляется вместе с вложением; обе записи перечислены в meta.affected_resources.

GET скачивание требует Bearer и текущего доступа, возвращает байты, Content-Type фактического MIME, Content-Disposition: attachment и Cache-Control: private, no-store; ошибка остаётся JSON по общим правилам. Redirect на публичный постоянный URL или ссылка, обходящая последующий отзыв прав, не допускаются. Удаление принимает {} и If-Resource-Version со значением data.version из GET метаданных, возвращает 200 tombstone. Скачивание не нужно для получения версии удаления.

Операции

Метод Путь Назначение
GET /visits/{visit_id}/media Метаданные доступных файлов
POST /visits/{visit_id}/media Загрузка multipart/form-data
GET /visits/{visit_id}/media/{id} Метаданные одного файла и версия для удаления
GET /visits/{visit_id}/media/{id}/download Защищённое получение содержимого
POST /visits/{visit_id}/media/{id}/delete Удаление разрешённого вложения

GET /visits/{visit_id}/media

Метаданные доступных файлов.

Доступ. Разрешения подключения: visit_media:read. Права сотрудника: «Акты приёма оборудования → Просмотр». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.

Параметры

Имя Где Тип Обязательно null Ограничения
Authorization заголовок строка да нет Bearer <SERVICEAPP_TOKEN>
visit_id путь строка да нет Шаблон: ^(?:[0-9]+)$
filter[kind] параметр запроса строка нет нет Допустимо: "photo", "attachment"
sort параметр запроса строка нет нет Допустимо: "id", "-id"
page[size] параметр запроса целое число нет нет ≥ 1; ≤ 100
page[cursor] параметр запроса строка нет нет не более 8192 символов

Ответы

HTTP Назначение и схема
200 Успех. Полная схема и пример
401 Требуется действующий Bearer. Коды и формат ошибки
403 Недостаточно допуска. Коды и формат ошибки
404 Не найдено или недоступно. Коды и формат ошибки
422 Ошибка входных данных. Коды и формат ошибки
429 Лимит запросов, Retry-After. Коды и формат ошибки
503 Временно недоступно. Коды и формат ошибки

Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.

Пример запроса

Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.

curl --silent --show-error --globoff \
  "$API/visits/101/media" \
  --header "Authorization: Bearer $SERVICEAPP_TOKEN" \
  --header "Accept: application/json"

POST /visits/{visit_id}/media

Загрузка multipart/form-data.

Доступ. Разрешения подключения: visit_media:write. Права сотрудника: «Акты приёма оборудования → Изменение», «Системные настройки → Загрузка вложений». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.

Параметры

Имя Где Тип Обязательно null Ограничения
Authorization заголовок строка да нет Bearer <SERVICEAPP_TOKEN>
visit_id путь строка да нет Шаблон: ^(?:[0-9]+)$
Idempotency-Key заголовок строка да нет не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._:-]+$

Тело запроса

Content-Type: multipart/form-data. Тело обязательно.

Поле Тип Обязательно null Ограничения и смысл
kind строка да нет Допустимо: "photo", "attachment"
file строка (двоичные данные) да нет Файл от 1 до 10 МиБ включительно; MIME проверяется по содержимому.
client_filename строка нет нет не более 255 символов

Ответы

HTTP Назначение и схема
201 Создано. Полная схема и пример
202 Принято, итог в журнале. Полная схема и пример
401 Требуется действующий Bearer. Коды и формат ошибки
403 Недостаточно допуска. Коды и формат ошибки
404 Не найдено или недоступно. Коды и формат ошибки
409 Конфликт состояния или повтора. Коды и формат ошибки
413 Превышен размер. Коды и формат ошибки
415 Неподдерживаемый Content-Type. Коды и формат ошибки
422 Ошибка входных данных. Коды и формат ошибки
429 Лимит запросов, Retry-After. Коды и формат ошибки
503 Временно недоступно. Коды и формат ошибки
HTTP Заголовок ответа Тип Описание
201 Location строка
202 Location строка

Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.

У принятого POST Location и meta.operation_id указывают на журнал операции; ETag отсутствует. При повторе запроса сохраняются исходные data/meta, добавляется Idempotency-Replayed: true. Версии передавайте по назначению, указанному в описании ресурса.

Пример запроса

Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.

curl --silent --show-error --globoff --request POST \
  "$API/visits/101/media" \
  --header "Authorization: Bearer $SERVICEAPP_TOKEN" \
  --header "Accept: application/json" \
  --header "Idempotency-Key: example:v1-visit-media-store:001" \
  --form 'kind=attachment' \
  --form 'file=@./examples/attachment.pdf;type=application/pdf'

GET /visits/{visit_id}/media/{id}

Метаданные одного файла и версия для удаления.

Доступ. Разрешения подключения: visit_media:read. Права сотрудника: «Акты приёма оборудования → Просмотр». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.

Параметры

Имя Где Тип Обязательно null Ограничения
Authorization заголовок строка да нет Bearer <SERVICEAPP_TOKEN>
visit_id путь строка да нет Шаблон: ^(?:[0-9]+)$
id путь строка да нет Шаблон: ^(?:[0-9]+)$
If-None-Match заголовок строка нет нет —

Ответы

HTTP Назначение и схема
200 Успех. Полная схема и пример
304 Представление не изменилось, без тела. Условный GET
401 Требуется действующий Bearer. Коды и формат ошибки
403 Недостаточно допуска. Коды и формат ошибки
404 Не найдено или недоступно. Коды и формат ошибки
422 Ошибка входных данных. Коды и формат ошибки
429 Лимит запросов, Retry-After. Коды и формат ошибки
503 Временно недоступно. Коды и формат ошибки
HTTP Заголовок ответа Тип Описание
200 ETag строка
304 ETag строка

Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.

Пример запроса

Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.

curl --silent --show-error --globoff \
  "$API/visits/101/media/101" \
  --header "Authorization: Bearer $SERVICEAPP_TOKEN" \
  --header "Accept: application/json"

GET /visits/{visit_id}/media/{id}/download

Защищённое получение содержимого.

Доступ. Разрешения подключения: visit_media:read. Права сотрудника: «Акты приёма оборудования → Просмотр». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.

Параметры

Имя Где Тип Обязательно null Ограничения
Authorization заголовок строка да нет Bearer <SERVICEAPP_TOKEN>
visit_id путь строка да нет Шаблон: ^(?:[0-9]+)$
id путь строка да нет Шаблон: ^(?:[0-9]+)$

Ответы

HTTP Назначение и схема
200 Успех. Бинарный файл без JSON-обёртки; вложения
401 Требуется действующий Bearer. Коды и формат ошибки
403 Недостаточно допуска. Коды и формат ошибки
404 Не найдено или недоступно. Коды и формат ошибки
422 Ошибка входных данных. Коды и формат ошибки
429 Лимит запросов, Retry-After. Коды и формат ошибки
503 Временно недоступно. Коды и формат ошибки
HTTP Заголовок ответа Тип Описание
200 Content-Disposition строка
200 X-Content-Type-Options строка
200 Cache-Control строка
401 Cache-Control строка
403 Cache-Control строка
404 Cache-Control строка
422 Cache-Control строка
429 Cache-Control строка
503 Cache-Control строка

Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.

Пример запроса

Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.

curl --silent --show-error --globoff \
  "$API/visits/101/media/101/download" \
  --header "Authorization: Bearer $SERVICEAPP_TOKEN" \
  --header "Accept: application/json"

POST /visits/{visit_id}/media/{id}/delete

Удаление разрешённого вложения.

Доступ. Разрешения подключения: visit_media:write. Права сотрудника: «Акты приёма оборудования → Изменение». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.

Параметры

Имя Где Тип Обязательно null Ограничения
Authorization заголовок строка да нет Bearer <SERVICEAPP_TOKEN>
visit_id путь строка да нет Шаблон: ^(?:[0-9]+)$
id путь строка да нет Шаблон: ^(?:[0-9]+)$
Idempotency-Key заголовок строка да нет не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._:-]+$
If-Resource-Version заголовок строка да нет не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._~-]+$

Тело запроса

Content-Type: application/json. Тело обязательно.

Тело — пустой JSON-объект {}. Другие ключи не принимаются.

Ответы

HTTP Назначение и схема
200 Успех. Полная схема и пример
401 Требуется действующий Bearer. Коды и формат ошибки
403 Недостаточно допуска. Коды и формат ошибки
404 Не найдено или недоступно. Коды и формат ошибки
409 Конфликт состояния или повтора. Коды и формат ошибки
412 Версия устарела. Коды и формат ошибки
422 Ошибка входных данных. Коды и формат ошибки
428 Нужно предусловие версии. Коды и формат ошибки
429 Лимит запросов, Retry-After. Коды и формат ошибки
503 Временно недоступно. Коды и формат ошибки
HTTP Заголовок ответа Тип Описание
200 Location строка

Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.

У принятого POST Location и meta.operation_id указывают на журнал операции; ETag отсутствует. При повторе запроса сохраняются исходные data/meta, добавляется Idempotency-Replayed: true. Версии передавайте по назначению, указанному в описании ресурса.

Пример запроса

Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.

curl --silent --show-error --globoff --request POST \
  "$API/visits/101/media/101/delete" \
  --header "Authorization: Bearer $SERVICEAPP_TOKEN" \
  --header "Accept: application/json" \
  --header "Idempotency-Key: example:v1-visit-media-destroy:001" \
  --header "If-Resource-Version: $RESOURCE_VERSION" \
  --header "Content-Type: application/json" \
  --data-binary '@examples/requests/v1.visit-media.destroy.json'