diff --git a/apps/browser-extension/src/utils/dist/core/vault/index.d.mts b/apps/browser-extension/src/utils/dist/core/vault/index.d.mts index 1b864c15d..332197028 100644 --- a/apps/browser-extension/src/utils/dist/core/vault/index.d.mts +++ b/apps/browser-extension/src/utils/dist/core/vault/index.d.mts @@ -122,7 +122,7 @@ declare const VAULT_VERSIONS: VaultVersion[]; * Complete database schema SQL (latest version) * Auto-generated from EF Core migrations */ -declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nCOMMIT;\n\nPRAGMA foreign_keys = OFF;\n\nBEGIN TRANSACTION;\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"DeletedAt\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId\n LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.notes' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = ON;\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20260130221620_2.0.0-MajorVersionBump', '9.0.4');\n\nCOMMIT;\n"; +declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nCOMMIT;\n\nPRAGMA foreign_keys = OFF;\n\nBEGIN TRANSACTION;\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"DeletedAt\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId\n LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'notes.content' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = ON;\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20260130221620_2.0.0-MajorVersionBump', '9.0.4');\n\nCOMMIT;\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/browser-extension/src/utils/dist/core/vault/index.d.ts b/apps/browser-extension/src/utils/dist/core/vault/index.d.ts index 1b864c15d..332197028 100644 --- a/apps/browser-extension/src/utils/dist/core/vault/index.d.ts +++ b/apps/browser-extension/src/utils/dist/core/vault/index.d.ts @@ -122,7 +122,7 @@ declare const VAULT_VERSIONS: VaultVersion[]; * Complete database schema SQL (latest version) * Auto-generated from EF Core migrations */ -declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nCOMMIT;\n\nPRAGMA foreign_keys = OFF;\n\nBEGIN TRANSACTION;\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"DeletedAt\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId\n LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.notes' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = ON;\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20260130221620_2.0.0-MajorVersionBump', '9.0.4');\n\nCOMMIT;\n"; +declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nCOMMIT;\n\nPRAGMA foreign_keys = OFF;\n\nBEGIN TRANSACTION;\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"DeletedAt\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId\n LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'notes.content' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = ON;\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20260130221620_2.0.0-MajorVersionBump', '9.0.4');\n\nCOMMIT;\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/browser-extension/src/utils/dist/core/vault/index.js b/apps/browser-extension/src/utils/dist/core/vault/index.js index 9b555efbc..539078573 100644 --- a/apps/browser-extension/src/utils/dist/core/vault/index.js +++ b/apps/browser-extension/src/utils/dist/core/vault/index.js @@ -1068,7 +1068,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, @@ -2278,7 +2278,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, diff --git a/apps/browser-extension/src/utils/dist/core/vault/index.mjs b/apps/browser-extension/src/utils/dist/core/vault/index.mjs index 23ffd0001..52104736d 100644 --- a/apps/browser-extension/src/utils/dist/core/vault/index.mjs +++ b/apps/browser-extension/src/utils/dist/core/vault/index.mjs @@ -1036,7 +1036,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, @@ -2246,7 +2246,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, diff --git a/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/vaultstore/models/VaultSql.kt b/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/vaultstore/models/VaultSql.kt index e4b30ef0f..be8b79731 100644 --- a/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/vaultstore/models/VaultSql.kt +++ b/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/vaultstore/models/VaultSql.kt @@ -1045,7 +1045,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, @@ -2281,7 +2281,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, diff --git a/apps/mobile-app/ios/VaultModels/VaultSql.swift b/apps/mobile-app/ios/VaultModels/VaultSql.swift index 4a856c230..6809fe70e 100644 --- a/apps/mobile-app/ios/VaultModels/VaultSql.swift +++ b/apps/mobile-app/ios/VaultModels/VaultSql.swift @@ -1041,7 +1041,7 @@ public struct VaultSql { SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, @@ -2275,7 +2275,7 @@ public struct VaultSql { SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, diff --git a/apps/mobile-app/utils/dist/core/vault/index.d.mts b/apps/mobile-app/utils/dist/core/vault/index.d.mts index 1b864c15d..332197028 100644 --- a/apps/mobile-app/utils/dist/core/vault/index.d.mts +++ b/apps/mobile-app/utils/dist/core/vault/index.d.mts @@ -122,7 +122,7 @@ declare const VAULT_VERSIONS: VaultVersion[]; * Complete database schema SQL (latest version) * Auto-generated from EF Core migrations */ -declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nCOMMIT;\n\nPRAGMA foreign_keys = OFF;\n\nBEGIN TRANSACTION;\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"DeletedAt\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId\n LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.notes' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = ON;\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20260130221620_2.0.0-MajorVersionBump', '9.0.4');\n\nCOMMIT;\n"; +declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nCOMMIT;\n\nPRAGMA foreign_keys = OFF;\n\nBEGIN TRANSACTION;\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"DeletedAt\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId\n LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'notes.content' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = ON;\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20260130221620_2.0.0-MajorVersionBump', '9.0.4');\n\nCOMMIT;\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/mobile-app/utils/dist/core/vault/index.d.ts b/apps/mobile-app/utils/dist/core/vault/index.d.ts index 1b864c15d..332197028 100644 --- a/apps/mobile-app/utils/dist/core/vault/index.d.ts +++ b/apps/mobile-app/utils/dist/core/vault/index.d.ts @@ -122,7 +122,7 @@ declare const VAULT_VERSIONS: VaultVersion[]; * Complete database schema SQL (latest version) * Auto-generated from EF Core migrations */ -declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nCOMMIT;\n\nPRAGMA foreign_keys = OFF;\n\nBEGIN TRANSACTION;\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"DeletedAt\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId\n LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.notes' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = ON;\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20260130221620_2.0.0-MajorVersionBump', '9.0.4');\n\nCOMMIT;\n"; +declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nCOMMIT;\n\nPRAGMA foreign_keys = OFF;\n\nBEGIN TRANSACTION;\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"DeletedAt\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId\n LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'notes.content' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = ON;\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20260130221620_2.0.0-MajorVersionBump', '9.0.4');\n\nCOMMIT;\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/mobile-app/utils/dist/core/vault/index.js b/apps/mobile-app/utils/dist/core/vault/index.js index 9b555efbc..539078573 100644 --- a/apps/mobile-app/utils/dist/core/vault/index.js +++ b/apps/mobile-app/utils/dist/core/vault/index.js @@ -1068,7 +1068,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, @@ -2278,7 +2278,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, diff --git a/apps/mobile-app/utils/dist/core/vault/index.mjs b/apps/mobile-app/utils/dist/core/vault/index.mjs index 23ffd0001..52104736d 100644 --- a/apps/mobile-app/utils/dist/core/vault/index.mjs +++ b/apps/mobile-app/utils/dist/core/vault/index.mjs @@ -1036,7 +1036,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, @@ -2246,7 +2246,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, diff --git a/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.d.mts b/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.d.mts index 1b864c15d..332197028 100644 --- a/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.d.mts +++ b/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.d.mts @@ -122,7 +122,7 @@ declare const VAULT_VERSIONS: VaultVersion[]; * Complete database schema SQL (latest version) * Auto-generated from EF Core migrations */ -declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nCOMMIT;\n\nPRAGMA foreign_keys = OFF;\n\nBEGIN TRANSACTION;\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"DeletedAt\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId\n LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.notes' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = ON;\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20260130221620_2.0.0-MajorVersionBump', '9.0.4');\n\nCOMMIT;\n"; +declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nCOMMIT;\n\nPRAGMA foreign_keys = OFF;\n\nBEGIN TRANSACTION;\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"DeletedAt\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId\n LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'notes.content' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = ON;\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20260130221620_2.0.0-MajorVersionBump', '9.0.4');\n\nCOMMIT;\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.d.ts b/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.d.ts index 1b864c15d..332197028 100644 --- a/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.d.ts +++ b/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.d.ts @@ -122,7 +122,7 @@ declare const VAULT_VERSIONS: VaultVersion[]; * Complete database schema SQL (latest version) * Auto-generated from EF Core migrations */ -declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nCOMMIT;\n\nPRAGMA foreign_keys = OFF;\n\nBEGIN TRANSACTION;\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"DeletedAt\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId\n LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.notes' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = ON;\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20260130221620_2.0.0-MajorVersionBump', '9.0.4');\n\nCOMMIT;\n"; +declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nCOMMIT;\n\nPRAGMA foreign_keys = OFF;\n\nBEGIN TRANSACTION;\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"DeletedAt\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId\n LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'notes.content' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = ON;\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20260130221620_2.0.0-MajorVersionBump', '9.0.4');\n\nCOMMIT;\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.js b/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.js index 9b555efbc..539078573 100644 --- a/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.js +++ b/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.js @@ -1068,7 +1068,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, @@ -2278,7 +2278,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, diff --git a/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.mjs b/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.mjs index 23ffd0001..52104736d 100644 --- a/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.mjs +++ b/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/index.mjs @@ -1036,7 +1036,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, @@ -2246,7 +2246,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, diff --git a/apps/server/Databases/AliasClientDb/Migrations/20251213111207_1.7.0-FieldBasedDataModelUpdate.cs b/apps/server/Databases/AliasClientDb/Migrations/20251213111207_1.7.0-FieldBasedDataModelUpdate.cs index d42f5cf1a..f5625c8bf 100644 --- a/apps/server/Databases/AliasClientDb/Migrations/20251213111207_1.7.0-FieldBasedDataModelUpdate.cs +++ b/apps/server/Databases/AliasClientDb/Migrations/20251213111207_1.7.0-FieldBasedDataModelUpdate.cs @@ -572,7 +572,7 @@ namespace AliasClientDb.Migrations WHERE c.Username IS NOT NULL AND c.Username != ''; "); - // Migrate login.notes field (system field using FieldKey) + // Migrate notes.content field (system field using FieldKey) // Note: GUID format must be uppercase with dashes (8-4-4-4-12) to match C# Guid.Parse expectations migrationBuilder.Sql(@" INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) @@ -584,7 +584,7 @@ namespace AliasClientDb.Migrations SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, diff --git a/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/000_FullSchema.sql b/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/000_FullSchema.sql index 6f5dcbbef..e03a279f7 100644 --- a/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/000_FullSchema.sql +++ b/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/000_FullSchema.sql @@ -1030,7 +1030,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, diff --git a/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/011_20251014122838_1.6.0-AddPasskeys_to_20251213111207_1.7.0-FieldBasedDataModelUpdate.sql b/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/011_20251014122838_1.6.0-AddPasskeys_to_20251213111207_1.7.0-FieldBasedDataModelUpdate.sql index 9e32d81c1..f11f0b509 100644 --- a/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/011_20251014122838_1.6.0-AddPasskeys_to_20251213111207_1.7.0-FieldBasedDataModelUpdate.sql +++ b/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/011_20251014122838_1.6.0-AddPasskeys_to_20251213111207_1.7.0-FieldBasedDataModelUpdate.sql @@ -356,7 +356,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, diff --git a/core/vault/src/sql/SqlConstants.ts b/core/vault/src/sql/SqlConstants.ts index 72ff24fd9..2b331d09a 100644 --- a/core/vault/src/sql/SqlConstants.ts +++ b/core/vault/src/sql/SqlConstants.ts @@ -1037,7 +1037,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt, @@ -2251,7 +2251,7 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, - 'login.notes' AS FieldKey, + 'notes.content' AS FieldKey, c.Notes AS Value, 0 AS Weight, c.UpdatedAt AS CreatedAt,