Resumo

  • Um ContactCard ativo no RFC 9610 pertence a pelo menos um AddressBook, mas pode pertencer a vários; retirar um vínculo não é destruir o cartão.
  • Grupos armazenam UIDs. Quando o acesso ao cartão correspondente se perde temporariamente, o membro some da visão, mas o UID não resolvido é preservado e pode voltar a resolver.
  • Uma alegação de exclusão exige Account, ID do objeto, UID, conjunto anterior de agendas, argumentos de /set, resposta e leitura autoritativa posterior.

A agenda terminou; o objeto talvez não

No encerramento de um contrato, uma equipe apaga a agenda do projeto. A tela fica vazia e o relatório de conformidade diz “contatos excluídos”. Mais tarde, um dos fornecedores reaparece na agenda de continuidade. Antes de concluir que houve restauração indevida, é preciso perguntar que camada o primeiro recibo realmente cobria.

No RFC 9610, AddressBook é uma coleção nomeada. Um ContactCard pode pertencer ao mesmo tempo às agendas de projeto, plantão e renovação. Ao destruir a primeira com onDestroyRemoveContents:true, o servidor remove esse vínculo. O cartão só é destruído se não pertencer a nenhuma outra agenda.

Logo, pedido bem-sucedido, tela vazia e objeto sobrevivente podem coexistir. A interface descreve a coleção consultada; não recebe, por isso, autoridade para certificar o ciclo de vida global do contato.

Coleção não significa propriedade exclusiva

Um Account com JMAP Contacts contém AddressBooks, e cada cartão mantém em addressBookIds o conjunto de coleções às quais pertence. Enquanto existir, esse conjunto não pode ficar vazio. O modelo evita cópias divergentes: o mesmo registro pode servir a vários fluxos operacionais.

Remover “Renovações” muda uma relação. Não altera automaticamente “Incidentes” nem “Compras”. Essa separação é a especificação mínima que implementações distintas conseguem executar. O produto pode desenhar pastas ou espaços, mas a metáfora visual não amplia a operação.

O princípio é simples: o protocolo deve dizer com precisão o que o código em execução precisa compartilhar. Política de retenção, abrangência jurídica e dados em outros sistemas permanecem decisões locais, cada qual com sua própria autoridade.

A cascata tem uma condição que o botão costuma esconder

onDestroyRemoveContents é falso por padrão. Se a agenda contiver cartões, sua destruição é recusada com addressBookHasContents. O erro prova que aquela tentativa não destruiu a coleção; não prova preservação universal dos cartões.

Com o valor verdadeiro, o servidor remove a agenda de cada cartão. Só destrói o cartão que, após essa remoção, não tiver outra agenda. Uma única chamada pode destruir a coleção, preservar cartões com múltiplos vínculos e destruir cartões órfãos.

Registrar apenas “cascata ativada” perde o predicado decisivo. O recibo precisa dos addressBookIds anteriores e dos campos destroyed, notDestroyed, updated e de erro da resposta. O nome da opção expressa intenção; o estado e a resposta expressam efeito.

id e uid não são intercambiáveis

O ContactCard possui id imutável definido pelo servidor e também o uid do JSContact. O RFC permite que sejam diferentes e proíbe mais de um cartão com o mesmo UID dentro do mesmo Account.

O ID do servidor localiza o objeto manipulado pelos métodos JMAP. O UID sustenta a identidade do cartão na representação de contatos e é o valor usado pelos membros de grupos. Guardar só o nome exibido perde ambos. Guardar só o UID não identifica qual objeto de qual conta mudou. Guardar só o ID não preserva a continuidade que grupos e outras contas acessíveis expressam pelo UID.

Mesmo os dois juntos não são a pessoa. Destruir um cartão em uma conta não apaga mensagens, exportações, aparelhos, CRM, backups nem registros independentes.

O grupo guarda a referência durante a falta de acesso

Um ContactCard de grupo contém um conjunto de UIDs. O cliente procura cartões correspondentes em contas acessíveis com suporte a JMAP Contacts. Se um UID não puder ser localizado, ele deve ser omitido da apresentação atual, mas preservado.

O próprio RFC descreve o caso: o usuário adiciona contatos de uma agenda compartilhada a um grupo privado e depois perde temporariamente o acesso à agenda. Os membros desaparecem porque os UIDs deixam de resolver. Quando o acesso retorna, as referências preservadas encontram os cartões e os membros reaparecem.

Não houve necessariamente restauração. A continuidade permaneceu no grupo. Uma captura durante a interrupção prova apenas que aquele principal não resolvia o membro naquele instante; não prova destruição do cartão, remoção do UID ou invisibilidade para todos.

Ausência em consulta continua sendo um fato escopado

O filtro inAddressBook seleciona cartões de uma agenda específica. Um cartão fora do resultado pode existir em outra agenda ou fora da superfície acessível ao solicitante. A consulta respondeu à pergunta feita, não a uma pergunta universal sobre existência.

Estados JMAP e /changes permitem acompanhar transições, desde que o cliente retenha o estado anterior, examine IDs criados, atualizados e destruídos e resolva incerteza com /get no Account correto. O sumiço de uma linha não substitui essa cadeia.

Até uma destruição confirmada tem limite: aquele ContactCard não existe mais naquela conta JMAP. Nada se conclui, por isso só, sobre outras contas, cópias, backups, histórico de mensagens ou sistemas externos.

O pedido de agenda padrão confirma a regra probatória

onSuccessSetIsDefault pede que uma agenda se torne padrão após o sucesso das demais mudanças. Se o ID não existir ou a política do servidor não permitir, essa parte é ignorada sem erro e o padrão anterior continua.

Enviar a intenção é diferente de observar o resultado. O cliente precisa ler propriedades retornadas ou buscar o estado atual antes de declarar sucesso. A mesma disciplina vale para exclusão: botão e payload provam tentativa; resposta e leitura provam estado.

Um recibo de exclusão precisa sobreviver à reaparição

O registro começa com Account, id e UID. Preserva todos os addressBookIds anteriores e referências do UID em grupos. Distingue destruição de AddressBook de destruição direta de ContactCard e guarda o valor exato de onDestroyRemoveContents.

Depois conserva resposta, novo estado e consulta posterior. A conclusão deve ser limitada: removido desta agenda; atualmente não resolvido para este principal; ContactCard destruído nesta conta; ou fato não estabelecido. “A pessoa foi apagada de todo lugar” não é uma sentença que o RFC 9610 possa emitir.

Separar visão, relação, objeto e mundo externo é o que permite uma auditoria honesta. Cada camada recebe apenas o poder que seu recibo sustenta.

Fontes