Вложения и ссылки для пользователя
Где доступны файлы
| Владелец | Загрузка | Вид (kind) |
Версия при загрузке |
|---|---|---|---|
| Акт | POST /acts/{act_id}/media |
attachment |
If-Resource-Version не требуется |
| Выезд | POST /visits/{visit_id}/media |
photo, attachment |
If-Resource-Version не требуется |
| Оборудование | POST /equipment/{equipment_id}/media |
photo, document |
Для photo обязательна версия оборудования; document не требует заголовка |
Для каждого семейства есть GET списка, JSON-карточки и /download, а также POST /{id}/delete. Для скачивания нужны действующий токен и текущий доступ к файлу. download_url не является публичной или подписанной ссылкой на хранилище.
Для загрузки используйте multipart/form-data с одним полем file и текстовым kind. Необязательное поле client_filename задаёт непустое имя до 255 символов без управляющих символов и разделителей пути. Если оно отсутствует, используется имя загружаемого файла. Допустимый размер — от 1 до 10 485 760 байт (10 МиБ) включительно. Несколько файлов, повторяющиеся текстовые части и неизвестные поля отклоняются. Не задавайте заголовок Content-Type вручную: curl сам добавляет разделитель частей.
Допустимые типы
Фото выезда и оборудования: JPEG, PNG, GIF, WebP. У остальных видов разные наборы форматов:
Владелец и kind |
Разрешённые форматы |
|---|---|
| Акт, attachment | Изображения, PDF, текст, Word, Excel, PowerPoint, ZIP/RAR/7z из MIME-таблицы ниже |
| Выезд, attachment | PDF, JPEG, PNG, WebP |
| Оборудование, document | PDF, Word, Excel, JPEG, PNG, GIF, WebP |
Точная MIME-таблица для вложений акта:
| Формат | MIME |
|---|---|
| JPEG, PNG, GIF, WebP | image/jpeg, image/png, image/gif, image/webp |
| PDF, текст | application/pdf, text/plain |
| Word | application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document |
| Excel | application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
| PowerPoint | application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation |
| ZIP, RAR, 7z | application/zip, application/x-rar-compressed, application/x-7z-compressed |
Сервер проверяет содержимое и формат, включая Office-контейнеры. Расширение и присланный MIME не заменяют проверку. SVG, HTML и исполняемые файлы не разрешены. Архивы принимаются только вложениями акта и сохраняются без распаковки. У оборудования не принимаются text/plain, PowerPoint и архивы; у выезда attachment не принимает Word/Excel, GIF, текст и архивы. URL, base64, путь на сервере и чужой ID вложения не заменяют file.
Пример загрузки и скачивания
Для примера нужны act_media:write, act_media:read, права на акт и доступный ACT_ID. Загрузка вложений акта и выезда дополнительно требует «Системные настройки → Загрузка вложений». Файлы examples/attachment.txt и examples/attachment.pdf входят в комплект; PDF подходит также для attachment выезда и document оборудования.
export UPLOAD_KEY='demo:act:attachment:001'
curl --fail-with-body --silent --show-error --request POST \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Idempotency-Key: $UPLOAD_KEY" \
--form 'kind=attachment' \
--form 'client_filename=Осмотр.txt' \
--form 'file=@./examples/attachment.txt;type=text/plain' \
--output media-response.json \
"$API/acts/$ACT_ID/media"
export MEDIA_ID="$(jq -r '.data.id' media-response.json)"
curl --fail-with-body --silent --show-error \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--output attachment-downloaded.txt \
"$API/acts/$ACT_ID/media/$MEDIA_ID/download"
Готовое вложение даёт 201 с карточкой. Принятая, но ещё не завершённая загрузка может дать 202; до завершения проверяйте журнал. При 202 не извлекайте media_id из формы ответа 201. Скачивание возвращает содержимое файла с кодом 200, Content-Type, Content-Disposition: attachment, X-Content-Type-Options: nosniff, Cache-Control: private, no-store; JSON-обёртки нет. Ошибка до передачи файла возвращается общим JSON-форматом.
Замена фото оборудования и удаление
kind=photo устанавливает единственное основное фото, включая первую установку. Передайте If-Resource-Version из GET оборудования. Старое фото остаётся доступным до готовности нового. После успеха ответ содержит ID нового вложения; старый ID не становится ID замены. При ошибке старое фото сохраняется. Два разных ключа в одну секунду могут последовательно заменить фото с одинаковой версией оборудования — это ограничение секундного updated_at.
Для удаления получите текущую JSON-карточку файла и передайте её data.version. Тело — {}, Content-Type — application/json, ключ новый для этого действия.
curl --fail-with-body --silent --show-error \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--output media-current.json \
"$API/acts/$ACT_ID/media/$MEDIA_ID"
export MEDIA_VERSION="$(jq -r '.data.version' media-current.json)"
curl --fail-with-body --silent --show-error --request POST \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: demo:act:attachment:delete:001' \
--header "If-Resource-Version: $MEDIA_VERSION" \
--data-binary '{}' \
"$API/acts/$ACT_ID/media/$MEDIA_ID/delete" | jq .
При повторной загрузке используйте прежний ключ, kind, имя и содержимое файла. Другой файл или имя с занятым ключом возвращают IDEMPOTENCY_CONFLICT. Повтор принятого удаления возвращает сохранённый результат; новая команда к отсутствующему файлу — 404. Если результат неизвестен, проверьте журнал операции. Новый ключ не восстанавливает пропавший файл. Ошибка MULTIPART_INPUT_UNAVAILABLE означает, что сервер не смог принять исходное тело загрузки; сообщите её и X-Request-Id администратору организации.
Полные схемы: act-media, visit-media, equipment-media.
links.edit, links.portal, links.public
Клиенты, акты, оборудование, индивидуальные планы и регламенты могут возвращать объект links с полями edit, portal, public. Значение — готовый абсолютный адрес или null. Передавайте готовый адрес; не собирайте адрес карточки из ID самостоятельно. У акта edit учитывает ремонт, монтаж или ТО. У плана и регламента выдаётся edit, а portal/public равны null.
editоткрывает панель и требует входа сотрудника.portalоткрывает клиентский кабинет с его обычной авторизацией. API не создаёт сессию, пароль или ссылку для входа без пароля. Отключённый раздел не получает недоступную ссылку.publicоткрывает доступную публичную страницу: короткую ссылку акта или существующий QR-паспорт оборудования. У клиента отдельной публичной карточки нет. У планаpublicтакже отсутствует. Ссылкуpublicможно передать клиенту с учётом назначенной видимости.
GET не публикует паспорт и не создаёт отсутствующий публичный токен. У оборудования без такого токена и у pending_install соответствующие ссылки могут быть null. Получение ссылки не регистрирует просмотр клиентом. Загрузка вложения не включает его показ в портале и не меняет настройки show_images / show_documents. Публичная ссылка карточки не превращает защищённый download_url в публичный файл.
При повторе запроса ссылки берутся из сохранённого ответа. Доступ к самой странице проверяется по текущим правилам. Для получения актуальных ссылок перечитайте карточку через GET.