Контракт
Продукт-источник сообщает о своём факте, Календарь отвечает за его расписание. Между ними узкий интерфейс, который не растёт вместе с числом интеграций.
Идентичность события это тройка
Продукт, тип сущности и её идентификатор. Внутренний идентификатор Календаря продукту хранить не нужно: он адресует событие тем, чем уже владеет.
(product_id, entity_type, entity_id)- Повторный upsert по той же тройке обновляет запись, а не создаёт вторую
- Повторный remove после удаления это не ошибка, а пустая операция
- Удалить событие может только продукт, создавший его своим ключом
- Токены отвязки не нужны: у события ровно один продукт-владелец
Точки контракта
| Метод | Назначение |
|---|---|
POST /Calendar/upsert | Создать или обновить событие продукта |
POST /Calendar/remove | Удалить событие по идентификационной тройке |
GET /Calendar/listByEntity | События конкретной сущности продукта |
GET /Calendar/events | Выборка для личного и командного представления |
GET /Calendar/freebusy | Занятость сотрудников и ресурсов без деталей |
GET /Calendar/expand | Разворот повторения в конкретные вхождения |
POST /Calendar/findSlots | Подбор общего свободного окна |
POST /Calendar/attachConference | Создание комнаты A3.Meet для события |
POST /Calendar/invite, /Calendar/rsvp | Приглашение участника и его ответ |
GET /Calendar/ics/{token} | Подписка внешнего клиента только на чтение |
Транспортные конвенции
Заголовки
API_KEY, A3Session, AccountId, ProductId и Language-Code. Продуктовый вызов авторизуется ключом продукта, пользовательский сессией A3.ID.
Конверт ответа
Единый конверт со статусом, кодом, текстом ошибки и полезной нагрузкой. Ошибки приходят в нём же и уже локализованы по Language-Code.
Списки
Списки возвращаются вместе с общим числом записей, фильтрация и постраничность идут через фильтры запроса.
Документация
Scalar и Swagger на шести языках. CalDAV описан отдельно: это не JSON-контракт, а протокол поверх WebDAV.
Версия события решает конфликты
Каждое обновление передаёт версию, которую вызывающая сторона видела последней. Если она разошлась с текущей, сервер отвечает кодом 409 и актуальным состоянием. Конфликт решает вызывающая сторона, а не сервер.
409 Conflict- Продукту типовая обработка это повтор с новой версией: он владеет полем целиком
- Человеку показывается диалог сравнения версий с выбором, какую оставить
- Та же версия служит ETag протокола CalDAV, второго механизма нет
- Это не CRDT и не блокировки на запись: модель соразмерна реальной нагрузке
Не только REST
CalDAV
Отдельный путь по RFC 4791 с методами обнаружения календарей, выборки по диапазону, записи и удаления. Событие продукта видно, но запись в него отклоняется.
Живой канал
Журнал изменений с монотонным курсором плюс хаб реального времени. Открытая вкладка обновляется сразу, офлайн-клиент догоняет по тому же курсору.
Виджет
Встраиваемый кадр поверх выборки событий и занятости для продукта, которому нужна сетка внутри своего интерфейса. Кадр открывается по короткоживущему токену от сервера продукта.
Ограничения
Ограничение частоты на запись по продукту и журнал запросов недефолтных ключей для разбора инцидентов.
Права интеграции
Интеграция не получает доступ ко всему календарю компании без явного разрешения владельца аккаунта.
ReadПолучать событияPushСоздавать и обновлять свои событияFreeBusyЗапрашивать занятость без деталей событияShareУправлять общим доступом к календарям