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>
- 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>
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>
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>
Null/undefined items in the Google Calendar API response caused a
TypeError on `item.status` access, silently aborting the sync while
the OAuth callback had already redirected to the success page.
- Filter null items in `upsertGoogleEvents` with an early `continue`
- Await `sync()` in the OAuth callback so errors surface as
`sync_error=google` redirects instead of false success
Resolves#92
Co-authored-by: Ulas Kalayci <ulas.kalayci@googlemail.com>
- router.js: route-announcer used bare `path` variable which is not in scope
inside renderPage(); replaced with `route.path`
- dashboard.js: shoppingLists query used `HAVING open_count > 0` without GROUP BY;
SQLite rejects this — replaced with a WHERE subquery
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When OPENWEATHER_UNITS=imperial, OpenWeatherMap returns wind speed in
mph directly — the server was incorrectly multiplying by 3.6 (m/s→km/h)
on top of that. All locale strings also hardcoded the unit label instead
of using a {{windUnit}} placeholder, so the label always read km/h.
Resolves#79
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
effectiveDue() and sortTasks() added — same logic on client (tasks.js)
and server (dashboard.js urgentTasks moved from SQL to JS sort).
Applies in list-group, Kanban, and dashboard widget views.
SQLite DATE('now') replaced with new Date() for timezone-safe due_time.
Google and Apple sync services now fetch calendar metadata and persist it via
upsertExternalCalendar(). The /calendar and /upcoming endpoints JOIN on
external_calendars to return cal_name and cal_color with every event.
- Implemented new recipes page with UI for managing recipes.
- Added REST API routes for recipes including create, read, update, and delete operations.
- Introduced database schema for recipes and recipe ingredients.
- Updated meals to link with recipes, allowing meals to reference specific recipes.
- Enhanced validation for recipe-related fields in meals.
- Added styles for the recipes page and components.