Фотографии и документы выезда
Все операции. Авторизация. Запросы и повторы.
Все пути в этом файле дополняют /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'