Commit Graph

156 Commits

Author SHA1 Message Date
Ulas Kalayci f7eb73b835 feat(cardav): implement POST /accounts endpoint
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>
2026-05-04 16:54:52 +02:00
Ulas Kalayci 930800eed9 fix(cardav): improve router security and test coverage
- Remove error message leakage (return generic 'Interner Fehler')
- Remove unused imports (str, collectErrors, MAX_TITLE, MAX_URL)
- Add _resetTestDatabase() for proper test cleanup
- Add test for populated accounts case with shape validation
- Import 'after' from node:test for proper teardown

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-04 16:51:21 +02:00
Ulas Kalayci cf68bff25f feat(cardav): create cardav router with GET /accounts
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>
2026-05-04 16:47:24 +02:00
Ulas Kalayci a71547562e feat(contacts): add multi-value array validators
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>
2026-05-04 13:01:22 +02:00
Ulas Kalayci c4b8b76221 Fix critical database issues in CardDAV sync service
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>
2026-05-04 11:45:07 +02:00
Ulas Kalayci 689b479b2d Implement CardDAV sync service with account and contact management
- 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>
2026-05-04 11:34:25 +02:00
Ulas Kalayci 3f77fdb11d Fix Migration 30 code quality issues
C1 (CRITICAL): Refactor test-carddav.js to import migrations
- Import MIGRATIONS from server/db.js instead of duplicating SQL
- Export MIGRATIONS array from server/db.js
- Use better-sqlite3 to apply Migration 30 dynamically
- Ensures future changes to Migration 30 are reflected in tests

I1 (IMPORTANT): Add UNIQUE index on carddav_uid
- Create idx_contacts_carddav_uid_unique partial index
- Prevents duplicate CardDAV contacts per account+addressbook
- WHERE clause excludes NULL values (manual contacts allowed)
- Add test to verify unique constraint enforcement

I3 (IMPORTANT): Rename cardav → carddav (RFC 6352 compliance)
- Table: cardav_accounts → carddav_accounts
- Table: cardav_addressbook_selection → carddav_addressbook_selection
- Column: contacts.cardav_* → contacts.carddav_*
- Index: idx_cardav_* → idx_carddav_*
- Test file: test-cardav.js → test-carddav.js
- Package.json: test:cardav → test:carddav
- All test assertions updated

All 25 tests pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-04 10:55:30 +02:00
Ulas Kalayci 18310dbfe5 feat(cardav): add Migration 30 for CardDAV contacts schema
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>
2026-05-04 10:47:16 +02:00
Ulas Kalayci c5a9799983 feat(caldav): add calendar selection, sync, and API routes
- 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>
2026-05-04 08:32:46 +02:00
Ulas Kalayci 01ccf715e5 feat(caldav): add account management functions (add, list, update, delete) 2026-05-04 08:20:17 +02:00
Ulas Kalayci 59773bd797 feat(caldav): implement account CRUD operations
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>
2026-05-04 08:00:49 +02:00
Ulas Kalayci 7b91fa5136 Fix caldav-sync.js imports to match Task 2 spec
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>
2026-05-04 07:56:57 +02:00
Ulas Kalayci a159a57e9c feat(caldav): add caldav-sync service base structure with helpers
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-04 07:53:39 +02:00
Ulas Kalayci 4eb7e852fd feat: add DB migration for CalDAV multi-account support
- 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>
2026-05-04 07:42:57 +02:00
Ulas Kalayci 9b29d1847c feat: automatische geplante Backups mit Rotation
Phase 1.3 - Automatische Backups:
- Cron-basierter Scheduler (Standard: täglich 2 Uhr)
- Konfigurierbar über .env (Zeitplan, Verzeichnis, Anzahl)
- Automatische Rotation: behält nur letzte N Backups (Standard: 7)
- UI in Settings → Backup: Status-Anzeige und manueller Trigger
- Tests: 7 erfolgreiche Tests für Scheduler-Funktionalität

Neue Umgebungsvariablen:
- BACKUP_ENABLED (Standard: true)
- BACKUP_SCHEDULE (Standard: 0 2 * * *)
- BACKUP_DIR (Standard: ./backups)
- BACKUP_KEEP (Standard: 7)
- TZ (für Zeitzone)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-04 07:02:38 +02:00
Ulas Kalayci 99a2280c02 chore: release v0.42.0
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-04 06:52:35 +02:00
Ulas Kalayci f3dbbb37d7 fix: preserve dmy=DD.MM.YYYY, add dmy_slash for DD/MM/YYYY
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>
2026-05-01 15:28:18 +02:00
Rafael Foster f5377bd2f1 Improve dashboard widget sizing controls 2026-05-01 09:05:20 -03:00
Rafael Foster 9c5f8c9a99 Add dashboard widget customization 2026-05-01 08:53:25 -03:00
Rafael Foster e34ba33f9b Refine loan tab filtering and date formats 2026-05-01 08:24:39 -03:00
Rafael Foster 79f55cbfbc Improve loan dashboard interactions 2026-05-01 08:09:12 -03:00
Rafael Foster 977bee8a3a Separate budget and loan views 2026-05-01 07:52:43 -03:00
Rafael Foster ce107c80a4 Add budget loan tracking 2026-04-30 23:12:38 -03:00
Ulas Kalayci e59a9818a9 fix(i18n): add time format translations to all 13 missing locales
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>
2026-04-30 19:54:12 +02:00
Rafael Foster 8c9a5c6aa2 feat(settings): add time format preference 2026-04-30 13:48:35 -03:00
Ulas Kalayci 4a050e92a8 chore: release v0.38.2
Fix recurring events with FREQ=WEEKLY;INTERVAL=N;BYDAY ignoring the
interval when crossing a week boundary (e.g. Friday → Monday).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 10:51:01 +02:00
Rafael Foster 4aa9bc2a48 fix(calendar): tighten modal and attachment rendering 2026-04-29 22:44:25 -03:00
Rafael Foster 6e177bb8c4 docs(api): document family documents endpoints 2026-04-29 18:07:18 -03:00
Rafael Foster 0cbd93e4e0 feat(settings): add database backup management 2026-04-29 14:04:04 -03:00
Rafael Foster d9218a4941 feat(calendar): add overlapping layout and event attachments 2026-04-29 08:53:07 -03:00
Rafael Foster 72fca92066 feat(documents): add family document management 2026-04-29 06:14:29 -03:00
Rafael Foster 9759f5e267 feat(tasks): add archived status support in API and schema 2026-04-29 05:33:06 -03:00
Rafael Foster 4d3c2688fe Prevent deletion of family members from contact list 2026-04-28 22:17:21 -03:00
Rafael Foster 5062e1e61f Improve account profile and sidebar details 2026-04-28 21:11:49 -03:00
Rafael Foster 69897666fb Refine family settings and calendar dentist icon 2026-04-28 20:28:50 -03:00
Rafael Foster 7b85db9b07 Sync family members with contacts and birthdays 2026-04-28 20:04:13 -03:00
Ulas Kalayci 6f8cc712a7 chore: release v0.30.3 2026-04-28 22:40:36 +02:00
Rafael Foster b4d74f239b Expand calendar event icon options 2026-04-27 22:22:30 -03:00
Rafael Foster 1d1d2291e5 Add calendar event icons and flexible date inputs 2026-04-27 21:38:06 -03:00
Ulas Kalayci 74dca56850 fix(google-sync): db.transaction → db.get().transaction in upsertGoogleEvents 2026-04-27 22:34:23 +02:00
ulsklyc 19e6569281 fix(google-sync): skip null items and await initial sync (#93)
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>
2026-04-27 17:24:37 +02:00
Rafael Foster 7e4db48a9f Merge branch 'main' of github.com:rafaelfoster/oikos 2026-04-27 08:52:18 -03:00
Rafael Foster 6e410cb671 Add member editing and profile pictures 2026-04-27 08:09:00 -03:00
Rafael Foster b82a86c4b3 Add family roles to member management 2026-04-27 07:53:43 -03:00
Ulas Kalayci 6a575520aa chore: release v0.26.5 2026-04-27 12:51:10 +02:00
Ulas Kalayci 1821b7147a fix: path is not defined in renderPage and HAVING clause SQL error
- 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>
2026-04-27 12:24:39 +02:00
Rafael Foster 08199495b6 A lot of change in this commit. Changing the dashboard to get more data and the new features added 2026-04-26 21:18:59 -03:00
Rafael Foster 3c5a8c7eb3 Adding option for allowing users to define the Application visible name 2026-04-26 19:32:19 -03:00
Rafael Foster b0c1b8b6f9 Merge branch 'main' of github.com:rafaelfoster/oikos 2026-04-26 07:50:59 -03:00
Rafael Foster 394b4ea84e Adding Birthday tracking feature - to compete with FamilyWall 2026-04-26 07:36:53 -03:00