Improved content flow by showing screenshots (Preview section) before the Features section, giving visitors a visual first impression before diving into the feature list.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replace old screenshots with new ones showing updated dashboard design and weather widget. Update README to display mobile + desktop side-by-side, regenerate social preview images with new dashboard screenshot.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Root cause: loadCalDAVAccounts and loadCardDAVAccounts were defined
inside the render function but called from bindIcsEvents (outside render),
causing ReferenceError when accessing Settings page.
Changes:
- Move loadCalDAVAccounts and loadCardDAVAccounts to top-level functions
- Add user parameter to both functions (no longer in render scope)
- Update all recursive calls to pass user parameter
- Move initial load code from bindIcsEvents to render function
Fixes the "loadCalDAVAccounts is not defined" error in v0.47.0.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add support for customizable birthday reminders with preset offsets
(none, at time, 15min, 1h, 1d, 2d, 1w, 2w) and custom intervals.
Users can now configure when to be reminded of upcoming birthdays.
- Add migration 31: reminder_offset, reminder_custom_amount, reminder_custom_unit to birthdays table
- Update POST/PUT /birthdays routes to accept reminder fields
- Add getOffsetMinutes() helper in birthday service
- Update birthdayReminderAt() to calculate reminder time with offset
- Modify syncBirthdayReminder() to handle empty offset (no reminder)
- Add renderBirthdayReminderSection() UI component
- Move reminder-custom CSS from calendar.css to reminders.css
- Add protocol check to service worker (non-http protocol guard)
All translations already present in de.json.
Tests: 109 passing, 0 failing.
Co-Authored-By: Rafael Foster <rafaelfoster@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Remove CardDAV v0.45.0 session tracking document. Information is
preserved in git history, CHANGELOG.md, and archived design docs.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Design document for comprehensive repository and documentation
maintenance after v0.45.0 release. Covers archiving strategy for
implemented plans/specs, BACKLOG/CHANGELOG updates, and README
improvements.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Import and mount cardavRouter with requireAuth middleware. All
CardDAV management routes now accessible under /api/v1/contacts/cardav.
Router mounted BEFORE contacts router to ensure /api/v1/contacts/cardav
paths match before /api/v1/contacts.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Extend PUT /contacts/:id route to support updating phones, emails, and
addresses arrays with replacement semantics. Uses atomic transactions
to DELETE all existing multi-values then INSERT new ones. Validates
all multi-value fields before updating. Response includes full contact
with multi-value fields via loadMultiValueFields() helper.
Backward compatible: multi-value fields only replaced when present in
request body. Scalar fields (name, category, etc.) continue to work
independently.
Tests added:
- Update with multi-value fields (replacement semantics verified)
- Validation error on invalid phone data (400)
- Backward compatibility: update without multi-values preserves them
All 109 tests pass.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements Task 12: Extend POST /contacts to accept and persist phones,
emails, and addresses arrays. Uses atomic transactions to ensure all
related records are created together or rolled back on error.
- Validation: validatePhones/Emails/Addresses before insert
- Transaction: db.transaction() for atomic Contact + Multi-Values
- Backward compatible: Multi-value fields are optional
- Refactoring: Extracted loadMultiValueFields() helper (DRY)
- Response includes all multi-value fields with generated IDs
Tests: 3 new tests (create with multi-values, validation, backward compat)
TDD workflow: RED → GREEN → REFACTOR → Commit
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements Task 11: Extend GET /contacts/:id to include phones, emails,
and addresses arrays. Each multi-value field is queried from its respective
table (contact_phones, contact_emails, contact_addresses) and mapped to
camelCase response format with isPrimary boolean conversion.
Tests: 2 new tests (contact with multi-values, empty arrays)
TDD workflow: RED → GREEN → Commit
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add boolean field validator for use in CardDAV addressbook toggle
route and other boolean validation needs.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add addressbook refresh route. Loads account from DB, delegates to
CardDAVSync.discoverAddressbooks() to run PROPFIND, then returns
updated addressbook list from DB.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add addressbook listing route. Queries carddav_addressbook_selection
table directly, ordered by name. Returns empty array if account has
no addressbooks.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add connection test route. Loads account from DB and delegates to
CardDAVSync.testConnection() to verify credentials and discover
addressbooks without saving.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add account deletion route with ID validation. Delegates to
CardDAVSync.deleteAccount() which cascades to addressbooks and
contacts via foreign key constraints.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add account creation route with validation. Delegates to
CardDAVSync.addAccount() which creates account and discovers
addressbooks. Returns 201 with account + addressbooks array.
Add _mockTestConnection() helper for testing CardDAV routes without
real server connections.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add CardDAV API router with GET /accounts endpoint. Returns all
CardDAV accounts from database via cardav-sync service. Added test
infrastructure with _setTestDatabase helper for isolated API testing.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add validatePhones, validateEmails, validateAddresses for CardDAV
multi-value contact fields. Validates array structure, required
fields, type checks, and max lengths.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
All 4 previously interdependent tests now use shared aliceContact from
before() hook. 54/54 tests passing with full isolation.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>