diff --git a/src/backend/database/db/index.ts b/src/backend/database/db/index.ts index 1d2205ab..47512e3e 100644 --- a/src/backend/database/db/index.ts +++ b/src/backend/database/db/index.ts @@ -588,25 +588,22 @@ async function handlePostInitFileEncryption() { } } -// Export a promise that resolves when database is fully initialized -export const databaseReady = initializeCompleteDatabase() - .then(async () => { - await handlePostInitFileEncryption(); +// Database initialization function - called explicitly, not at module import time +async function initializeDatabase(): Promise { + await initializeCompleteDatabase(); + await handlePostInitFileEncryption(); - databaseLogger.success("Database connection established", { - operation: "db_init", - path: actualDbPath, - hasEncryptedBackup: - enableFileEncryption && - DatabaseFileEncryption.isEncryptedDatabaseFile(encryptedDbPath), - }); - }) - .catch((error) => { - databaseLogger.error("Failed to initialize database", error, { - operation: "db_init", - }); - process.exit(1); + databaseLogger.success("Database connection established", { + operation: "db_init", + path: actualDbPath, + hasEncryptedBackup: + enableFileEncryption && + DatabaseFileEncryption.isEncryptedDatabaseFile(encryptedDbPath), }); +} + +// Export the initialization function instead of auto-starting +export { initializeDatabase }; // Cleanup function for database and temporary files async function cleanupDatabase() { @@ -693,7 +690,7 @@ let db: ReturnType>; // Export database connection getter function to avoid undefined access export function getDb(): ReturnType> { if (!db) { - throw new Error("Database not initialized. Ensure databaseReady promise is awaited before accessing db."); + throw new Error("Database not initialized. Ensure initializeDatabase() is called before accessing db."); } return db; } @@ -701,7 +698,7 @@ export function getDb(): ReturnType> { // Export raw SQLite instance for migrations export function getSqlite(): Database.Database { if (!sqlite) { - throw new Error("SQLite not initialized. Ensure databaseReady promise is awaited before accessing sqlite."); + throw new Error("SQLite not initialized. Ensure initializeDatabase() is called before accessing sqlite."); } return sqlite; } diff --git a/src/backend/starter.ts b/src/backend/starter.ts index 5da0ed37..2a5441ab 100644 --- a/src/backend/starter.ts +++ b/src/backend/starter.ts @@ -61,7 +61,7 @@ import { systemLogger, versionLogger } from "./utils/logger.js"; operation: "database_init" }); const dbModule = await import("./database/db/index.js"); - await dbModule.databaseReady; + await dbModule.initializeDatabase(); systemLogger.success("Database initialized successfully", { operation: "database_init_complete" }); diff --git a/src/backend/utils/auth-manager.ts b/src/backend/utils/auth-manager.ts index a0daddb9..e235fed8 100644 --- a/src/backend/utils/auth-manager.ts +++ b/src/backend/utils/auth-manager.ts @@ -97,10 +97,9 @@ class AuthManager { } // Import database connection - need to access raw SQLite for migration - const { getSqlite, saveMemoryDatabaseToFile, databaseReady } = await import("../database/db/index.js"); + const { getSqlite, saveMemoryDatabaseToFile } = await import("../database/db/index.js"); - // Ensure database is fully initialized before accessing SQLite - await databaseReady; + // Database should already be initialized by starter.ts, but ensure we can access it const sqlite = getSqlite(); // Perform the migration diff --git a/src/ui/Desktop/Homepage/HomepageAuth.tsx b/src/ui/Desktop/Homepage/HomepageAuth.tsx index da1bf487..fb256ea0 100644 --- a/src/ui/Desktop/Homepage/HomepageAuth.tsx +++ b/src/ui/Desktop/Homepage/HomepageAuth.tsx @@ -80,6 +80,7 @@ export function HomepageAuth({ const [error, setError] = useState(null); const [internalLoggedIn, setInternalLoggedIn] = useState(false); const [firstUser, setFirstUser] = useState(false); + const [firstUserToastShown, setFirstUserToastShown] = useState(false); const [registrationAllowed, setRegistrationAllowed] = useState(true); const [oidcConfigured, setOidcConfigured] = useState(false); @@ -143,7 +144,10 @@ export function HomepageAuth({ if (res.setup_required) { setFirstUser(true); setTab("signup"); - toast.info(t("auth.firstUserMessage")); + if (!firstUserToastShown) { + toast.info(t("auth.firstUserMessage")); + setFirstUserToastShown(true); + } } else { setFirstUser(false); } @@ -156,7 +160,7 @@ export function HomepageAuth({ .finally(() => { setDbHealthChecking(false); }); - }, [setDbError, t]); + }, [setDbError, firstUserToastShown]); useEffect(() => { if (!registrationAllowed && !internalLoggedIn) { diff --git a/src/ui/Mobile/Homepage/HomepageAuth.tsx b/src/ui/Mobile/Homepage/HomepageAuth.tsx index 98081237..a5f6f3d6 100644 --- a/src/ui/Mobile/Homepage/HomepageAuth.tsx +++ b/src/ui/Mobile/Homepage/HomepageAuth.tsx @@ -65,6 +65,7 @@ export function HomepageAuth({ const [error, setError] = useState(null); const [internalLoggedIn, setInternalLoggedIn] = useState(false); const [firstUser, setFirstUser] = useState(false); + const [firstUserToastShown, setFirstUserToastShown] = useState(false); const [registrationAllowed, setRegistrationAllowed] = useState(true); const [oidcConfigured, setOidcConfigured] = useState(false); @@ -123,7 +124,10 @@ export function HomepageAuth({ if (res.setup_required) { setFirstUser(true); setTab("signup"); - toast.info(t("auth.firstUserMessage")); + if (!firstUserToastShown) { + toast.info(t("auth.firstUserMessage")); + setFirstUserToastShown(true); + } } else { setFirstUser(false); } @@ -132,7 +136,7 @@ export function HomepageAuth({ .catch(() => { setDbError(t("errors.databaseConnection")); }); - }, [setDbError, t]); + }, [setDbError, firstUserToastShown]); async function handleSubmit(e: React.FormEvent) { e.preventDefault();