[Feature] Add CardDAV address-book connector #7

Open
opened 2026-07-13 00:53:46 +02:00 by zemion · 4 comments
Owner

Goal

Implement the first standards-based sync connector.

Scope

  • CardDAV account/address-book discovery
  • vCard resource sync into scoped address books
  • read-only and writable CardDAV books where supported by the server
  • ETag changes, deletes, and conflict detection
  • connection test and diagnostics

Acceptance Criteria

  • A CardDAV source can be connected, synced, inspected, and disconnected.
  • Refreshing a source does not duplicate contacts.
  • Conflict and permission states are visible to the user.

See govoplan-addresses/docs/ADDRESS_MODULE_ARCHITECTURE.md and govoplan-addresses/docs/IMPLEMENTATION_PLAN.md.

## Goal Implement the first standards-based sync connector. ## Scope - CardDAV account/address-book discovery - vCard resource sync into scoped address books - read-only and writable CardDAV books where supported by the server - ETag changes, deletes, and conflict detection - connection test and diagnostics ## Acceptance Criteria - A CardDAV source can be connected, synced, inspected, and disconnected. - Refreshing a source does not duplicate contacts. - Conflict and permission states are visible to the user. See `govoplan-addresses/docs/ADDRESS_MODULE_ARCHITECTURE.md` and `govoplan-addresses/docs/IMPLEMENTATION_PLAN.md`.
Author
Owner

Codex State: progress

Summary

  • Implemented first CardDAV path: discovery, source binding, full/sync-token inbound vCard sync, dry-run preview, tombstones, diagnostics, and conflict persistence.
  • Deferred outbound CardDAV PUT/DELETE and field-level merge UI; writable/two-way currently means local writable plus inbound sync.

Changed Files

  • src/govoplan_addresses/backend/carddav.py
  • src/govoplan_addresses/backend/service.py
  • src/govoplan_addresses/backend/router.py
  • tests/test_addresses_service.py
  • docs/IMPLEMENTATION_PLAN.md

Verification

  • python -m unittest tests.test_addresses_service -> OK
  • npm run build in govoplan-core/webui -> OK

Next / Blocked

  • Implement CardDAV disconnect/delete UI and outbound writes with conflict policy.

Suggested status label: status/in-progress

## Codex State: progress ### Summary - Implemented first CardDAV path: discovery, source binding, full/sync-token inbound vCard sync, dry-run preview, tombstones, diagnostics, and conflict persistence. - Deferred outbound CardDAV PUT/DELETE and field-level merge UI; writable/two-way currently means local writable plus inbound sync. ### Changed Files - `src/govoplan_addresses/backend/carddav.py` - `src/govoplan_addresses/backend/service.py` - `src/govoplan_addresses/backend/router.py` - `tests/test_addresses_service.py` - `docs/IMPLEMENTATION_PLAN.md` ### Verification - `python -m unittest tests.test_addresses_service -> OK` - `npm run build in govoplan-core/webui -> OK` ### Next / Blocked - Implement CardDAV disconnect/delete UI and outbound writes with conflict policy. Suggested status label: `status/in-progress`
Author
Owner

Codex State: progress

Summary

  • Implemented first two-way CardDAV write path: local creates, updates, and deletes are planned and applied to writable two-way/export sources.
  • Outbound CardDAV writes use If-None-Match/If-Match preconditions; stale remote state is persisted as a sync conflict instead of overwritten.

Changed Files

  • src/govoplan_addresses/backend/carddav.py
  • src/govoplan_addresses/backend/service.py
  • src/govoplan_addresses/backend/schemas.py
  • tests/test_addresses_service.py
  • webui/src/api/addresses.ts
  • webui/src/features/addressbook/AddressBookPage.tsx
  • docs/IMPLEMENTATION_PLAN.md
  • docs/ADDRESS_MODULE_ARCHITECTURE.md

Verification

  • PYTHONPATH=/mnt/DATA/git/govoplan-addresses/src:/mnt/DATA/git/govoplan-core/src /mnt/DATA/git/govoplan/.venv/bin/python -m unittest tests.test_addresses_service -> 9 tests OK
  • PYTHONPATH=/mnt/DATA/git/govoplan-addresses/src:/mnt/DATA/git/govoplan-core/src /mnt/DATA/git/govoplan/.venv/bin/python -m py_compile src/govoplan_addresses/backend/carddav.py src/govoplan_addresses/backend/service.py src/govoplan_addresses/backend/schemas.py -> OK
  • cd /mnt/DATA/git/govoplan-core/webui && npm run build -> OK, existing npm tmp and Vite chunk-size warnings remain

Next / Blocked

  • Still open: CardDAV source disconnect/delete UI and field-level conflict merge UX.

Suggested status label: status/in-progress

## Codex State: progress ### Summary - Implemented first two-way CardDAV write path: local creates, updates, and deletes are planned and applied to writable two-way/export sources. - Outbound CardDAV writes use If-None-Match/If-Match preconditions; stale remote state is persisted as a sync conflict instead of overwritten. ### Changed Files - `src/govoplan_addresses/backend/carddav.py` - `src/govoplan_addresses/backend/service.py` - `src/govoplan_addresses/backend/schemas.py` - `tests/test_addresses_service.py` - `webui/src/api/addresses.ts` - `webui/src/features/addressbook/AddressBookPage.tsx` - `docs/IMPLEMENTATION_PLAN.md` - `docs/ADDRESS_MODULE_ARCHITECTURE.md` ### Verification - `PYTHONPATH=/mnt/DATA/git/govoplan-addresses/src:/mnt/DATA/git/govoplan-core/src /mnt/DATA/git/govoplan/.venv/bin/python -m unittest tests.test_addresses_service -> 9 tests OK` - `PYTHONPATH=/mnt/DATA/git/govoplan-addresses/src:/mnt/DATA/git/govoplan-core/src /mnt/DATA/git/govoplan/.venv/bin/python -m py_compile src/govoplan_addresses/backend/carddav.py src/govoplan_addresses/backend/service.py src/govoplan_addresses/backend/schemas.py -> OK` - `cd /mnt/DATA/git/govoplan-core/webui && npm run build -> OK, existing npm tmp and Vite chunk-size warnings remain` ### Next / Blocked - Still open: CardDAV source disconnect/delete UI and field-level conflict merge UX. Suggested status label: `status/in-progress`
Author
Owner

Codex State: progress

Summary

  • Added CardDAV sync source lifecycle UX: enable/disable in the sync inspector and disconnect/delete with local contacts kept.
  • Added conflict review UI with local/remote field comparison, Keep local / Use remote / Ignore actions, and backend support to apply stored remote vCard payloads.
  • New vCard conflicts now persist structured local and remote payloads so the review dialog can show field-level differences and apply remote values.

Changed Files

  • src/govoplan_addresses/backend/service.py
  • src/govoplan_addresses/backend/router.py
  • tests/test_addresses_service.py
  • webui/src/api/addresses.ts
  • webui/src/features/addressbook/AddressBookPage.tsx
  • webui/src/styles/addresses.css
  • README.md
  • docs/IMPLEMENTATION_PLAN.md
  • docs/ADDRESS_MODULE_ARCHITECTURE.md

Verification

  • PYTHONPATH=/mnt/DATA/git/govoplan-addresses/src:/mnt/DATA/git/govoplan-core/src /mnt/DATA/git/govoplan/.venv/bin/python -m unittest tests.test_addresses_service -> 10 tests OK
  • PYTHONPATH=/mnt/DATA/git/govoplan-addresses/src:/mnt/DATA/git/govoplan-core/src /mnt/DATA/git/govoplan/.venv/bin/python -m py_compile src/govoplan_addresses/backend/router.py src/govoplan_addresses/backend/service.py src/govoplan_addresses/backend/schemas.py -> OK
  • cd /mnt/DATA/git/govoplan-core/webui && npm run build -> OK, existing npm tmp and Vite chunk-size warnings remain

Next / Blocked

  • Remaining follow-up: manual per-field merge editing beyond Keep local / Use remote / Ignore.

Suggested status label: status/in-progress

## Codex State: progress ### Summary - Added CardDAV sync source lifecycle UX: enable/disable in the sync inspector and disconnect/delete with local contacts kept. - Added conflict review UI with local/remote field comparison, Keep local / Use remote / Ignore actions, and backend support to apply stored remote vCard payloads. - New vCard conflicts now persist structured local and remote payloads so the review dialog can show field-level differences and apply remote values. ### Changed Files - `src/govoplan_addresses/backend/service.py` - `src/govoplan_addresses/backend/router.py` - `tests/test_addresses_service.py` - `webui/src/api/addresses.ts` - `webui/src/features/addressbook/AddressBookPage.tsx` - `webui/src/styles/addresses.css` - `README.md` - `docs/IMPLEMENTATION_PLAN.md` - `docs/ADDRESS_MODULE_ARCHITECTURE.md` ### Verification - `PYTHONPATH=/mnt/DATA/git/govoplan-addresses/src:/mnt/DATA/git/govoplan-core/src /mnt/DATA/git/govoplan/.venv/bin/python -m unittest tests.test_addresses_service -> 10 tests OK` - `PYTHONPATH=/mnt/DATA/git/govoplan-addresses/src:/mnt/DATA/git/govoplan-core/src /mnt/DATA/git/govoplan/.venv/bin/python -m py_compile src/govoplan_addresses/backend/router.py src/govoplan_addresses/backend/service.py src/govoplan_addresses/backend/schemas.py -> OK` - `cd /mnt/DATA/git/govoplan-core/webui && npm run build -> OK, existing npm tmp and Vite chunk-size warnings remain` ### Next / Blocked - Remaining follow-up: manual per-field merge editing beyond Keep local / Use remote / Ignore. Suggested status label: `status/in-progress`
Author
Owner

Codex State: done

Summary

  • Completed the field-level merge path: the conflict review dialog now lets users choose Local or Remote per stored vCard field and applies the merged payload with resolution=merge.
  • CardDAV source disconnect/delete UX and backend deletion are implemented; disconnect keeps local contacts and removes source sync records.

Changed Files

  • src/govoplan_addresses/backend/schemas.py
  • src/govoplan_addresses/backend/service.py
  • src/govoplan_addresses/backend/router.py
  • tests/test_addresses_service.py
  • webui/src/api/addresses.ts
  • webui/src/features/addressbook/AddressBookPage.tsx
  • webui/src/styles/addresses.css
  • README.md
  • docs/IMPLEMENTATION_PLAN.md
  • docs/ADDRESS_MODULE_ARCHITECTURE.md

Verification

  • PYTHONPATH=/mnt/DATA/git/govoplan-addresses/src:/mnt/DATA/git/govoplan-core/src /mnt/DATA/git/govoplan/.venv/bin/python -m unittest tests.test_addresses_service -> 11 tests OK
  • cd /mnt/DATA/git/govoplan-core/webui && npm run build -> OK, existing npm tmp and Vite chunk-size warnings remain
## Codex State: done ### Summary - Completed the field-level merge path: the conflict review dialog now lets users choose Local or Remote per stored vCard field and applies the merged payload with resolution=merge. - CardDAV source disconnect/delete UX and backend deletion are implemented; disconnect keeps local contacts and removes source sync records. ### Changed Files - `src/govoplan_addresses/backend/schemas.py` - `src/govoplan_addresses/backend/service.py` - `src/govoplan_addresses/backend/router.py` - `tests/test_addresses_service.py` - `webui/src/api/addresses.ts` - `webui/src/features/addressbook/AddressBookPage.tsx` - `webui/src/styles/addresses.css` - `README.md` - `docs/IMPLEMENTATION_PLAN.md` - `docs/ADDRESS_MODULE_ARCHITECTURE.md` ### Verification - `PYTHONPATH=/mnt/DATA/git/govoplan-addresses/src:/mnt/DATA/git/govoplan-core/src /mnt/DATA/git/govoplan/.venv/bin/python -m unittest tests.test_addresses_service -> 11 tests OK` - `cd /mnt/DATA/git/govoplan-core/webui && npm run build -> OK, existing npm tmp and Vite chunk-size warnings remain`
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: add-ideas/govoplan-addresses#7
No description provided.