feat: production-wire Calendar sync via first-class CalDAV accounts #272

Merged
KofTwentyTwo merged 7 commits from story/m6.5-caldav-account into dev 2026-07-31 17:41:25 +00:00
7 Commits
Author SHA1 Message Date
James Maes 886e1c293a test(daemon): add collection_url to account test fixtures
Fill in the new AccountConfig.collection_url field in the orchestrator
and send test fixtures so they construct the mail account model.

Refs #254 #178
2026-07-31 12:38:10 -05:00
James Maes 1bad767faf test(daemon): prove the production CalDAV sync path offline
Add a full-daemon E2E that configures a CalDAV account over the real
Accounts API and drives Calendar/Sync with NO injected backend, so the
daemon builds a real CalDavClient against a WireMock CalDAV server and
persists the fetched events, immediately visible via ListEvents. Also
asserts the honest error for an unconfigured account and that Calendar
stays behind its BearerAuthInterceptor. Fully offline: WireMock + mock
keyring, no live network.

Refs #254 #178
2026-07-31 12:37:03 -05:00
James Maes 6bbe4b415e feat(cli): create and list CalDAV accounts
account add gains --protocol (imap-smtp/jmap/caldav) and --collection-url;
a caldav account is rejected before dialing the daemon if the collection
URL is missing, and prompts for a password like a mail account. account
list renders CalDAV accounts with their collection URL.

Refs #254 #178
2026-07-31 12:36:12 -05:00
James Maes 80bd7da176 feat(daemon): wire the production CalDAV sync path
Calendar/Sync with no injected backend now resolves configured CalDAV
accounts (filtered by protocol, honoring a targeted account_id), reads
each credential from the keyring vault, builds a real CalDavClient from
the persisted collection_url, and syncs events via
calendar_sync::sync_caldav_account. The honest error now fires only when
no CalDAV account is configured. AddAccount validates CalDAV accounts
(http(s) collection_url + password) via the protocol-aware core
validation. The mail sync/outbox paths skip DAV accounts, which have no
mail backend. The CalendarEngineOverrides seam is retained for tests.

Refs #254 #178
2026-07-31 12:35:23 -05:00
James Maes b763987caa feat(store): persist account collection_url with backfill-safe migration
Add a nullable collection_url column to the accounts table via an
ensure_accounts_dav_columns migration that mirrors the SMTP/TLS-mode
column backfills, and round-trip it through save_account/list_accounts/
get_account. Salvage preserves collection_url alongside the TLS modes.

Refs #254 #178
2026-07-31 12:34:32 -05:00
James Maes 8399f3eeb4 feat(core): model CalDAV accounts with a generic collection URL
Add AccountProtocol::CalDav and AccountConfig.collection_url, plus an
is_dav() helper. Validation is now protocol-aware: a DAV account requires
a non-empty http(s) collection_url and skips the IMAP/SMTP endpoint
checks, while mail accounts are unchanged.

Refs #254 #178
2026-07-31 12:33:43 -05:00
James Maes 0f15442072 feat(proto): add CALDAV account protocol and collection_url
Add ACCOUNT_PROTOCOL_CALDAV = 3 and a generic AccountConfig.collection_url
(field 14) so a CalDAV account can be a first-class account entry. The
field is deliberately generic (DAV collection URL) for CardDAV reuse.
Regenerated the committed descriptor golden; additive within nuncio.v1.

Refs #254 #178
2026-07-31 12:32:45 -05:00