- Make all tests independent by creating their own test data
- Remove duplicate Account Management Operations suite (lines 744-801)
- Each test now creates its own accounts instead of relying on previous tests
- Fix unique constraint violations by using distinct account URLs
- All 54 tests now pass independently
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add test coverage for CardDAV account management, addressbook discovery UPSERT logic, and contact merge scenarios. Tests verify plain-text password storage, duplicate prevention, CASCADE SET NULL on account deletion, addressbook toggle functionality, and NULL-only field updates during sync.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Issue #1: Wrapped DELETE + INSERT operations in updateContactMultiValues in transaction to prevent inconsistent state if INSERT fails after DELETE.
Issue #2: Replaced N+1 query pattern with batch INSERT statements using VALUES list for phones, emails, and addresses. Also optimized primary entry check queries to use SELECT 1 instead of COUNT(*).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add server/services/cardav-sync.js with full CardDAV functionality
- Implement account management (add, delete, list, test connection)
- Implement addressbook discovery and selection toggle
- Add vCard parser with support for all standard fields (FN, N, TEL, EMAIL, ADR, ORG, TITLE, URL, BDAY, PHOTO, NICKNAME, NOTE, CATEGORIES)
- Implement smart merge logic for contact deduplication (UID match, email/phone match)
- Handle multi-value fields (phones, emails, addresses) with primary flag preservation
- Add comprehensive tests for vCard parsing and database operations
- All 46 tests passing
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add comprehensive database schema for CardDAV multi-account contacts sync:
New tables:
- cardav_accounts: Store CardDAV server credentials
- cardav_addressbook_selection: Per-account addressbook enable/disable
- contact_phones: Multiple phone numbers per contact with labels
- contact_emails: Multiple email addresses per contact with labels
- contact_addresses: Multiple postal addresses per contact with labels
Extended contacts table with 9 new columns:
- organization, job_title, birthday, website, photo, nickname
- cardav_account_id (FK to cardav_accounts, ON DELETE SET NULL)
- cardav_uid (vCard UID from server)
- cardav_addressbook_url (source addressbook URL)
Features:
- UNIQUE constraints on (cardav_url, username) and (account_id, addressbook_url)
- CASCADE delete for addressbook selection and contact sub-tables
- Performance indices for cardav_uid and email lookups
- Support for manual contacts (NULL cardav_account_id)
- is_primary flag for phone/email/address selection
Test coverage:
- 23 comprehensive tests verify all tables, constraints, indices
- FK CASCADE delete behavior validated
- UNIQUE constraints enforced
- Data integrity scenarios tested
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replaces single Apple CalDAV with generic multi-account CalDAV integration.
Features:
- Multiple CalDAV accounts (iCloud, Nextcloud, Radicale, Baikal)
- Per-account calendar selection via checkboxes
- Bidirectional sync (CalDAV ↔ Oikos)
- Optional outbound target selection per event
- Migration of existing Apple CalDAV data
Technical:
- New tables: caldav_accounts, caldav_calendar_selection
- New service: server/services/caldav-sync.js
- New API routes: /calendar/caldav/*
- Enhanced UI in Settings and Calendar event modal
- 7 new tests, all passing
Closes#90
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add CalDAV accounts card to Settings page with:
* List of configured accounts showing URL and last sync
* Expandable calendar list with enable/disable checkboxes
* Sync Now, Refresh Calendars, and Delete actions per account
* Add Account modal with name, URL, username, password fields
- Add CalDAV target selector to event modal:
* Dropdown showing local and all enabled CalDAV calendars
* Grouped by account using optgroups
* Pre-selects current target when editing events
* Includes target_caldav_account_id and target_caldav_calendar_url in save
- Add CalDAV component styles to settings.css:
* Account cards with header, meta, and action sections
* Expandable calendar details with checkboxes and color dots
* Empty state for no accounts
- Add missing i18n keys for calendar enable/disable, refresh, delete confirm
- Load CalDAV targets async when modal opens
- Admin-only access to account management
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add getCalendars() and updateCalendarSelection() to caldav-sync.js
- Add sync() function for bidirectional CalDAV synchronization
- Add getStatus() to report on all accounts and enabled calendars
- Add 8 new API routes to calendar.js for CalDAV account and calendar management
- All routes require admin role for security
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add createAccount, updateAccount, deleteAccount functions with validation, error handling, and logging. Implements Task 3 from the CalDAV multi-account spec.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Remove buildICS, escapeICS, unescapeICS imports - these will be
needed in Task 5 (Sync Functions), not in Task 2. Keep only the
4 functions specified in the Task 2 spec: parseICS, formatICSDate,
tzLocalToUTC, applyDuration.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- caldav_accounts table for account credentials
- caldav_calendar_selection table for calendar selection
- Migrate Apple CalDAV data to caldav tables
- Add target_caldav_* columns to calendar_events
- Update external_source CHECK to include 'caldav'
- Update external_calendars.source CHECK to include 'caldav'
- Enhance migration runner to support function-based migrations
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Resolve sv.json conflict: take Swedish subcategory translations from
main and loan keys from PR branch.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The PR changed dmy from dots to slashes, breaking existing users.
Revert dmy to dots (backward compat), add dmy_slash for DD/MM/YYYY.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Translates remaining English strings in sv.json and fills missing keys
(calendar/notes colors, emptyHint texts, shortcuts, navLabelOverdue,
photoOptional) across all 14 locale files.
Co-Authored-By: Andreas Olsson <olsson82@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Translates remaining English strings in sv.json (attachment, API tokens,
budget categories, backup, onboarding, offline banner).
Also adds missing keys (calendar/notes color names, emptyHint texts,
shortcut labels, tasks.navLabelOverdue, birthdays.photoOptional) to all
13 other locale files so every language is now complete against de.json.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Also translate server error message to English and remove stale
comment from calendar.js catch block.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>