Доступность сотрудников
Все операции. Авторизация. Запросы и повторы.
Все пути в этом файле дополняют /api/v1 на домене организации.
Описание и ограничения
Назначение
Недельные рабочие окна и отдельные выходные, необходимые для расписания и бригадных назначений.
Поля и назначение
| Публичное поле | Формат и смысл | Доступ |
|---|---|---|
windows[].weekday |
1=понедельник … 7=воскресенье | чтение и запись |
windows[].starts_at, windows[].ends_at |
HH:mm в зоне организации | чтение и запись |
days_off[].id, days_off[].date, days_off[].reason |
ID для удаления, календарная дата, причина/null | только чтение |
date, reason |
выходной день и причина/null | входное поле |
timezone, version |
IANA timezone; непрозрачная версия всего графика пользователя |
только чтение |
Обязательность и null указаны в схемах каждой операции ниже.
Доступ и выборка
user_availability:read требует «Акты приёма оборудования → Просмотр» и видимость сотрудника в разрешённых мастерских. Запись требует user_availability:write, существующее право «Системные настройки → Пользователи» и видимость сотрудника; дополнительное разрешение подключения users:read не нужно. Обычного visits:write недостаточно для изменения чужого рабочего графика. Роль владельца сохраняет полный доступ в пределах ограничений подключения.
Запросы
GET принимает filter[from]/filter[to] как DATE; без границ — сегодня и следующие 29 дней по timezone организации. Недельный шаблон возвращается полностью, days_off — за период, meta.period фиксирует границы. Версия относится ко всему графику, не к странице/периоду.
У ответов за разные периоды при том же состоянии графика совпадает data.version; ETag относится к конкретному полному ответу с выбранным периодом и доступом и может отличаться. Для команд используется data.version из любого разрешённого периода, не ETag этого ответа.
POST availability принимает обязательный windows (максимум 100): { "windows": [{"weekday": 1, "starts_at": "09:00", "ends_at": "18:00"}] }. Окна одного дня не пересекаются, starts_at < ends_at, переход через полночь разбивается на дни. windows=[] означает отсутствие недельных ограничений, не полную недоступность; выходные продолжают действовать. Все POST графика передают data.version из GET availability в If-Resource-Version.
POST days-off принимает обязательную date и необязательную reason (до 1000/null). Уникальность — user_id/date независимо от Idempotency-Key. Повтор той же даты/причины возвращает существующую запись 200; другая причина для уже существующего дня — 409 DAY_OFF_EXISTS. Новая запись — 201 с id/date/reason. Удаление принимает {}, возвращает 200 запись с признаком удаления и новую версию графика в meta.affected_resources. Замена windows возвращает 200 с агрегатом.
Правила и связи
- Запись массива
windowsзаменяет именно недельный шаблон выбранного пользователя и проверяется по версии. - Выходной перекрывает недельное окно; календарная дата не переводится между часовыми поясами.
- Результат не изменяет автоматически уже назначенные выезды.
Версия относится ко всему графику сотрудника и имеет секундную точность. Изменение рабочих интервалов, выходных или сведений о сотруднике может изменить её. Если две записи изменились в одну секунду, версия может остаться прежней; это ограничение описано в правилах проверки версии.
Операции
| Метод | Путь | Назначение |
|---|---|---|
| GET | /users/{user_id}/availability |
Недельные окна и исключения выбранного периода |
| POST | /users/{user_id}/availability |
Сохранение явного набора недельных окон |
| POST | /users/{user_id}/days-off |
Добавление выходного |
| POST | /users/{user_id}/days-off/{id}/delete |
Удаление конкретного выходного |
GET /users/{user_id}/availability
Недельные окна и исключения выбранного периода.
Доступ. Разрешения подключения: user_availability:read. Права сотрудника: «Акты приёма оборудования → Просмотр». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.
Параметры
| Имя | Где | Тип | Обязательно | null | Ограничения |
|---|---|---|---|---|---|
Authorization |
заголовок | строка | да | нет | Bearer <SERVICEAPP_TOKEN> |
user_id |
путь | строка | да | нет | Шаблон: ^(?:[0-9]+)$ |
If-None-Match |
заголовок | строка | нет | нет | — |
filter[from] |
параметр запроса | строка (дата) | нет | нет | — |
filter[to] |
параметр запроса | строка (дата) | нет | нет | — |
Ответы
| 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/users/101/availability" \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Accept: application/json"
POST /users/{user_id}/availability
Сохранение явного набора недельных окон.
Доступ. Разрешения подключения: user_availability:write. Права сотрудника: «Системные настройки → Пользователи». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.
Параметры
| Имя | Где | Тип | Обязательно | null | Ограничения |
|---|---|---|---|---|---|
Authorization |
заголовок | строка | да | нет | Bearer <SERVICEAPP_TOKEN> |
user_id |
путь | строка | да | нет | Шаблон: ^(?:[0-9]+)$ |
Idempotency-Key |
заголовок | строка | да | нет | не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._:-]+$ |
If-Resource-Version |
заголовок | строка | да | нет | не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._~-]+$ |
Тело запроса
Content-Type: application/json. Тело обязательно.
| Поле | Тип | Обязательно | null | Ограничения и смысл |
|---|---|---|---|---|
windows |
массив | да | нет | не более 100 элементов |
windows[] |
объект | да | нет | Только перечисленные ключи |
windows[].weekday |
целое число | да | нет | ≥ 1.0; ≤ 7.0 |
windows[].starts_at |
строка | да | нет | Шаблон: ^(?:[01]\d|2[0-3]):[0-5]\d$ |
windows[].ends_at |
строка | да | нет | Шаблон: ^(?:[01]\d|2[0-3]):[0-5]\d$ |
Ответы
| 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/users/101/availability" \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Accept: application/json" \
--header "Idempotency-Key: example:v1-user-availability-save:001" \
--header "If-Resource-Version: $RESOURCE_VERSION" \
--header "Content-Type: application/json" \
--data-binary '@examples/requests/v1.user-availability.save.json'
POST /users/{user_id}/days-off
Добавление выходного.
Доступ. Разрешения подключения: user_availability:write. Права сотрудника: «Системные настройки → Пользователи». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.
Параметры
| Имя | Где | Тип | Обязательно | null | Ограничения |
|---|---|---|---|---|---|
Authorization |
заголовок | строка | да | нет | Bearer <SERVICEAPP_TOKEN> |
user_id |
путь | строка | да | нет | Шаблон: ^(?:[0-9]+)$ |
Idempotency-Key |
заголовок | строка | да | нет | не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._:-]+$ |
If-Resource-Version |
заголовок | строка | да | нет | не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._~-]+$ |
Тело запроса
Content-Type: application/json. Тело обязательно.
| Поле | Тип | Обязательно | null | Ограничения и смысл |
|---|---|---|---|---|
date |
строка (дата) | да | нет | — |
reason |
строка / null | нет | да | не более 1000 символов |
Ответы
| HTTP | Назначение и схема |
|---|---|
| 201 | Создано. Полная схема и пример |
| 401 | Требуется действующий Bearer. Коды и формат ошибки |
| 403 | Недостаточно допуска. Коды и формат ошибки |
| 404 | Не найдено или недоступно. Коды и формат ошибки |
| 409 | Конфликт состояния или повтора. Коды и формат ошибки |
| 412 | Версия устарела. Коды и формат ошибки |
| 422 | Ошибка входных данных. Коды и формат ошибки |
| 428 | Нужно предусловие версии. Коды и формат ошибки |
| 429 | Лимит запросов, Retry-After. Коды и формат ошибки |
| 503 | Временно недоступно. Коды и формат ошибки |
| HTTP | Заголовок ответа | Тип | Описание |
|---|---|---|---|
| 201 | Location |
строка | |
| 401 | Location |
строка | |
| 403 | Location |
строка | |
| 404 | Location |
строка | |
| 409 | Location |
строка | |
| 412 | Location |
строка | |
| 422 | Location |
строка | |
| 428 | Location |
строка | |
| 429 | Location |
строка | |
| 503 | 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/users/101/days-off" \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Accept: application/json" \
--header "Idempotency-Key: example:v1-user-availability-day-off-store:001" \
--header "If-Resource-Version: $RESOURCE_VERSION" \
--header "Content-Type: application/json" \
--data-binary '@examples/requests/v1.user-availability.day-off.store.json'
POST /users/{user_id}/days-off/{id}/delete
Удаление конкретного выходного.
Доступ. Разрешения подключения: user_availability:write. Права сотрудника: «Системные настройки → Пользователи». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.
Параметры
| Имя | Где | Тип | Обязательно | null | Ограничения |
|---|---|---|---|---|---|
Authorization |
заголовок | строка | да | нет | Bearer <SERVICEAPP_TOKEN> |
user_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/users/101/days-off/101/delete" \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Accept: application/json" \
--header "Idempotency-Key: example:v1-user-availability-day-off-delete:001" \
--header "If-Resource-Version: $RESOURCE_VERSION" \
--header "Content-Type: application/json" \
--data-binary '@examples/requests/v1.user-availability.day-off.delete.json'