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>
This commit is contained in:
+29
-24
@@ -1082,33 +1082,33 @@ const MIGRATIONS = [
|
||||
-- ========================================
|
||||
-- CardDAV Accounts
|
||||
-- ========================================
|
||||
CREATE TABLE cardav_accounts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
cardav_url TEXT NOT NULL,
|
||||
username TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
|
||||
last_sync TEXT,
|
||||
UNIQUE(cardav_url, username)
|
||||
CREATE TABLE carddav_accounts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
carddav_url TEXT NOT NULL,
|
||||
username TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
|
||||
last_sync TEXT,
|
||||
UNIQUE(carddav_url, username)
|
||||
);
|
||||
|
||||
-- ========================================
|
||||
-- CardDAV Addressbook Selection
|
||||
-- ========================================
|
||||
CREATE TABLE cardav_addressbook_selection (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
account_id INTEGER NOT NULL,
|
||||
addressbook_url TEXT NOT NULL,
|
||||
CREATE TABLE carddav_addressbook_selection (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
account_id INTEGER NOT NULL,
|
||||
addressbook_url TEXT NOT NULL,
|
||||
addressbook_name TEXT NOT NULL,
|
||||
enabled INTEGER NOT NULL DEFAULT 1,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
|
||||
enabled INTEGER NOT NULL DEFAULT 1,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
|
||||
UNIQUE(account_id, addressbook_url),
|
||||
FOREIGN KEY(account_id) REFERENCES cardav_accounts(id) ON DELETE CASCADE
|
||||
FOREIGN KEY(account_id) REFERENCES carddav_accounts(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX idx_cardav_addressbook_account
|
||||
ON cardav_addressbook_selection(account_id, enabled);
|
||||
CREATE INDEX idx_carddav_addressbook_account
|
||||
ON carddav_addressbook_selection(account_id, enabled);
|
||||
|
||||
-- ========================================
|
||||
-- Extend Contacts Table for CardDAV
|
||||
@@ -1119,14 +1119,19 @@ const MIGRATIONS = [
|
||||
ALTER TABLE contacts ADD COLUMN website TEXT;
|
||||
ALTER TABLE contacts ADD COLUMN photo TEXT;
|
||||
ALTER TABLE contacts ADD COLUMN nickname TEXT;
|
||||
ALTER TABLE contacts ADD COLUMN cardav_account_id INTEGER
|
||||
REFERENCES cardav_accounts(id) ON DELETE SET NULL;
|
||||
ALTER TABLE contacts ADD COLUMN cardav_uid TEXT;
|
||||
ALTER TABLE contacts ADD COLUMN cardav_addressbook_url TEXT;
|
||||
ALTER TABLE contacts ADD COLUMN carddav_account_id INTEGER
|
||||
REFERENCES carddav_accounts(id) ON DELETE SET NULL;
|
||||
ALTER TABLE contacts ADD COLUMN carddav_uid TEXT;
|
||||
ALTER TABLE contacts ADD COLUMN carddav_addressbook_url TEXT;
|
||||
|
||||
CREATE INDEX idx_contacts_cardav_uid ON contacts(cardav_uid);
|
||||
CREATE INDEX idx_contacts_carddav_uid ON contacts(carddav_uid);
|
||||
CREATE INDEX idx_contacts_email ON contacts(email);
|
||||
|
||||
-- UNIQUE constraint for CardDAV UIDs (prevents duplicates per account+addressbook)
|
||||
CREATE UNIQUE INDEX idx_contacts_carddav_uid_unique
|
||||
ON contacts(carddav_account_id, carddav_addressbook_url, carddav_uid)
|
||||
WHERE carddav_uid IS NOT NULL;
|
||||
|
||||
-- ========================================
|
||||
-- Contact Phones (Multiple per Contact)
|
||||
-- ========================================
|
||||
@@ -1351,4 +1356,4 @@ function transaction(fn) {
|
||||
|
||||
init(); // auto-initialise when module is first imported
|
||||
|
||||
export { init, get, transaction, currentVersion, getPath, backupToFile, restoreFromFile };
|
||||
export { init, get, transaction, currentVersion, getPath, backupToFile, restoreFromFile, MIGRATIONS };
|
||||
|
||||
Reference in New Issue
Block a user