Кратко

  • Живая ContactCard в RFC 9610 принадлежит как минимум одной AddressBook, но может входить в несколько; удаление одной связи не равно уничтожению карточки.
  • Группа хранит UID участников. При временной потере доступа соответствующий контакт исчезает из представления, однако неразрешимый UID сохраняется и после возврата доступа снова разрешается.
  • Обоснованный вывод об удалении требует Account, серверного ID, UID, прежнего набора книг, точных аргументов /set, ответа и последующей авторитетной проверки.

Исчезла строка, а не обязательно объект

После завершения проекта оператор удаляет общую адресную книгу. Экран пуст, и отчёт фиксирует «контакты удалены». Через несколько месяцев поставщик остаётся в книге аварийных контактов. Это не обязательно восстановление из резервной копии: первоначальная операция могла удалить только одну связь.

RFC 9610 определяет AddressBook как именованную коллекцию. Одна ContactCard может одновременно находиться в книгах проекта, дежурства и продления. При уничтожении проектной книги с onDestroyRemoveContents:true сервер убирает эту книгу из членства карточек. Сама карточка уничтожается, только если больше не относится ни к одной книге.

Поэтому успешная команда, пустой экран и сохранившийся объект совместимы. Интерфейс сообщает о выбранной коллекции; он не получает права выдавать глобальный сертификат стирания.

Коллекция группирует, но не владеет исключительно

Account с поддержкой контактов содержит AddressBook, а addressBookIds каждой карточки перечисляет её коллекции. Пока карточка существует, множество не может быть пустым. Один объект может обслуживать несколько рабочих процессов без расходящихся копий.

Исключение из «Продлений» меняет одно отношение, не отменяя «Закупки» и «Инциденты». Протокол задаёт минимальную общую модель для синхронизации. Продукт может рисовать папки и пространства, но визуальная метафора не расширяет последствия операции.

Узкое правило совместимости оставляет хранение, юридическое стирание и внешние системы локальным решениям. У каждого такого решения должен быть собственный уполномоченный субъект и отдельная квитанция.

Каскад зависит от предыдущего состояния

По умолчанию onDestroyRemoveContents равен false. Уничтожение непустой книги отклоняется ошибкой addressBookHasContents. Ошибка доказывает отказ этой попытки, но не вечное сохранение каждой карточки.

При true сервер удаляет книгу из всех её карточек. Карточка уничтожается лишь тогда, когда после этого не остаётся другого членства. Один вызов может уничтожить книгу, сохранить многократно включённые карточки и уничтожить осиротевшие.

Запись «каскад включён» теряет решающее условие. Нужны прежние addressBookIds, а также destroyed, notDestroyed, updated и ошибки ответа. Название опции — свидетельство намерения; состояние и ответ — свидетельство результата.

Серверный id и uid поддерживают разные линии идентичности

ContactCard имеет неизменяемый серверный id и uid из JSContact. RFC 9610 прямо разрешает им различаться и запрещает более одной карточки с одинаковым UID внутри одного Account.

Серверный ID выбирает объект для методов JMAP. UID выражает идентичность карточки и хранится в членстве групп. Один экранный заголовок не сохраняет ни того, ни другого. Только UID не показывает, какой объект какого Account изменился. Только ID теряет непрерывность, выраженную группой.

Оба идентификатора всё равно не являются человеком. Уничтожение карточки не стирает сообщения, экспорты, устройства, CRM, резервные копии и независимые записи.

Группа хранит ссылку во время невидимости

ContactCard группы содержит множество UID. Клиент ищет совпадающие карточки во всех доступных аккаунтах с JMAP Contacts. Если UID не найден, его следует не показывать, но сохранять.

RFC приводит точный пример: пользователь добавляет в личную группу контакты из общей книги, затем временно теряет к ней доступ. Участники исчезают, потому что UID не разрешаются. Когда разрешение возвращается, сохранённые UID снова находят карточки, и участники появляются.

Восстановления могло не быть. Непрерывность оставалась в ссылке. Снимок экрана во время перерыва доказывает только невозможность разрешения для этого субъекта в данный момент, а не уничтожение объекта, удаление UID или невидимость для всех.

Отсутствие в запросе остаётся ограниченным наблюдением

Фильтр inAddressBook выбирает карточки конкретной книги. Непопавшая карточка может существовать в другой книге или за пределами доступной поверхности. Запрос отвечает на поставленный вопрос, а не на универсальный вопрос существования.

Состояния JMAP и /changes позволяют проследить переход, если клиент сохранил старое состояние, проверил созданные, обновлённые и уничтоженные ID и устранил сомнения через /get в правильном Account. Исчезновение строки не заменяет эту цепочку.

Даже подтверждённое уничтожение ограничено: ContactCard больше нет в данном JMAP-аккаунте. Оно не говорит об иных аккаунтах, копиях, резервных хранилищах, почтовой истории или внешних системах.

Запрос книги по умолчанию показывает ту же границу

onSuccessSetIsDefault просит назначить книгу по умолчанию после успеха остальных изменений. Если ID не найден или политика сервера запрещает действие, просьба игнорируется без ошибки, а прежняя книга остаётся.

Отправленное намерение не равно наблюдаемому результату. Клиент должен прочитать возвращённые свойства или запросить текущее состояние. Кнопка и payload подтверждают попытку; ответ и readback подтверждают эффект.

Квитанция удаления должна образовывать цепочку

Сначала фиксируются Account, серверный id и UID. Затем сохраняются все прежние addressBookIds и связанные UID в группах. Запись различает уничтожение AddressBook и прямое уничтожение ContactCard и содержит точное значение onDestroyRemoveContents.

Далее нужны ответ метода, новое состояние и последующая проверка. Вывод ограничивается одной формулировкой: исключён из этой книги; сейчас неразрешим для данного субъекта; ContactCard уничтожена в этом Account; либо результат не установлен. RFC 9610 не может заявить, что человек стёрт отовсюду.

Разделение интерфейса, отношения, объекта и внешнего мира не ослабляет аудит. Оно не даёт одному слою присвоить полномочия другого без доказательств.

Источники