# 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. **Двусторонний синк** — правки, сделанные с телефона (DAVx5) в адресной книге, синхронизируются обратно в `contacts.json`: - изменённые карточки → обновление контакта - новые карточки → новые контакты - удалённые карточки → soft-delete (`deleted: true`) в базе - конфликт (изменено и в почте, и на телефоне) → приоритет телефону, локальная версия сохраняется в лог, данные не теряются 4. **Локальная база contacts.json** остаётся источником истины (дедупликация, трекинг processed_uids) и хранит состояние синка (ETag карточки). ## 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 — приоритет телефону + лог локальной версии, см. REQ-011). ## 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 остаются.