- Enviado
- 15 de novembro de 2026 às 10:00 UTC
- Autor
- Kamo
- Confirmação
- 3b85588
Configurações › Email › CalDAV/CardDAV salvou conexões externas e mostrou "Últimas synced" para uma sincronização que não buscou nada (os trabalhos do DaemonService atingiram contadores e marcou tudo como IDLE; as classes de provedor eram TODO's) sincroniza-os de verdade (groupware/sync): - CalDAV/CardDAV: descoberta (endereço → principal → home set → coleções, com /.falha bem conhecida, um endereço de calendário único colado funciona), CTag/sync-token check, calendar-query ETag listagem (últimos 366 dias), multiget do que mudou, PUT/DELETE com If-Match/If-None-Match. iCloud define seus endereços por padrão. - Google Calendar + Pessoas, Microsoft Gráfico de calendários + contatos na concessão /oauth armazena o fluxo; tokens atualizados (e tokens de atualização rotativos mantidos) com um escreve que substitui apenas o blob exato que ele atualizou. - Eventos aterram através de IcsImportService.upsert (séries, exceções, EXDATEs) e contatos através de ContactService + ContactDetailStore — sem convites, sem lembretes, nenhuma tabela bruta escreve. - Contabilidade por coleção / item (novas tabelas groupware_sync_*) dá atualizações, exclusões e duas vias: puxe primeiro (cópia externa ganha um empate), então empurre Kamo edita/cria/deleta quando a integração é bidirecional e a coleção Guards: nada removido em uma listagem falhada ou suspeita de estar vazia, nada Kamo não importava, nada que apenas envelhecesse fora da janela; uma passagem que apagaria a maior parte de uma coleção lá fora é recusada. - Status é honesto: SYNCING enquanto estiver em execução, IDLE + lastSyncedAt somente após um período completo fetch, ERROR + plain-words errorMessage caso contrário; escrito coluna-a-coluna assim A edição de um membro no meio da passagem sobrevive o payload de configurações (syncSupported, calendarsSynced, eventsSynced, addressBooksSynced, contactsSynced, coleções[]). - Agendamento: **************** (relógio do DaemonService) e /integrations/{id} (Sincronizar agora via daemon.sync.trigger, fallback local sem NATS); lease SingletonTaskRunner por integração para que os pods nunca sejam executados duas vezes. - Conexão de teste agora faz login e lista; linhas de membros registram sua organização; excluir uma integração separa (mantém) o que foi sincronizado; endereços externos deve ser https para um host público (sem alcance de cluster/SSRF); credenciais nunca registradas. - Removido os esboços de provedores TODO mortos e seus atualizadores não usados.
