Files
email-assistant/openspec/changes/contacts-caldav-server/proposal.md
T

4.4 KiB
Raw Blame History

Proposal: CardDAV-сервер для синхронизации контактов

Why

Сейчас контакты, извлечённые LLM из подписей писем, лежат только в файлах /opt/hermes/email/contacts/{contacts.json, contacts.vcf, index.json} и никуда не синхронизируются. Чтобы пользоваться ими на телефоне (Android) и в других клиентах, нужен CardDAV-сервер с адресными книгами, куда контакты пишутся сразу при извлечении.

Почему CardDAV, а не просто наличие .vcf: нативный Android (DAVx5) и большинство клиентов умеют только CardDAV-протокол. Отдельный файл .vcf на диске никто не читает.

What Changes

  1. Radicale расширяется на CardDAV — это тот же сервис Radicale (:5232), который уже развёрнут для CalDAV (календарь). Radicale из коробки умеет CardDAV (addressbook collections). Нужно только:
    • создать адресную книгу (например Контакты) в коллекциях Radicale
    • проверить CardDAV-endpoint (/estorozhenko/Контакты/)
  2. Контакты пишутся сразу в карточки — contacts_extractor.py после извлечения и дедупликации пишет/обновляет vCard в Radicale через CardDAV PUT, а не только в локальные файлы:
    • на каждый контакт — один .vcf в адресной книге
    • при обновлении контакта — PUT с новым ETag
    • удаление контакта, которого больше нет в базе — DELETE (опционально, см. design)
  3. Остаётся локальная база contacts.json — она продолжает быть источником истины (дедупликация, трекинг processed_uids), а Radicale — цель синка.

Capabilities

New Capabilities

  • contacts/carddav-sync: Синхронизация извлечённых из почты контактов в CardDAV-сервер (Radicale) — создание/обновление/удаление vCard-карточек, доступных клиентам (DAVx5 на Android и др.)

Modified Capabilities

Impact

  • Сервис: Radicale (:5232) — уже работает, добавляется CardDAV-часть (адресная книга). Новых портов нет.
  • Скрипт: scripts/contacts_extractor.py — добавляется синк в Radicale (PUT/DELETE vCard), появляется зависимость от CardDAV-клиента/HTTP.
  • Данные: контакты синхронизируются на сервер; конфликты при параллельном редактировании на телефоне решаются по ETag (см. design).
  • Документация: обновить README/STATUS (как подключить адресную книгу на Android, порты).
  • Риски: двусторонняя синхронизация (правка на телефоне → обратно в базу) — НЕ в скоупе этого change (односторонний синк: почта → сервер). Односторонний синк без конфликтов: только PUT новых/обновлённых, DELETE только явно помеченных.

Rollback

  1. Отключить синк: убрать шаг синка в contacts_extractor.py (флаг --no-caldav / откат коммита) — локальные файлы и база не затрагиваются.
  2. Удалить адресную книгу из Radicale: rm -rf /opt/hermes/email-assistant/radicale/data/collections/collection-root/estorozhenko/Контакты (или через DAVx5).
  3. Radicale сам не откатывается — он как был, так и остаётся (CalDAV календарь продолжает работать).
  4. Данные локально не теряются: contacts.json/contacts.vcf остаются.