fix: resolve data directory persistence between Electron and Web modes

This commit fixes bidirectional data synchronization between Electron and Web
modes by addressing multiple interconnected issues:

**Core Fixes:**

1. **Electron userData Path (main.ts)**
   - Explicitly set userData path in development using app.setPath()
   - Navigate from __dirname to project root instead of relying on process.cwd()
   - Ensures Electron reads from /data instead of ~/.config/Automaker

2. **Server DataDir Path (main.ts, start-automaker.sh)**
   - Fixed startServer() to use __dirname for reliable path calculation
   - Export DATA_DIR environment variable in start-automaker.sh
   - Server now consistently uses shared /data directory

3. **Settings Sync Protection (settings-service.ts)**
   - Modified wipe protection to distinguish legitimate removals from accidents
   - Allow empty projects array if trashedProjects has items
   - Prevent false-positive wipe detection when removing projects

4. **Diagnostics & Logging**
   - Enhanced cache loading logging in use-settings-migration.ts
   - Detailed migration decision logs for troubleshooting
   - Track project counts from both cache and server

**Impact:**
- Projects created in Electron now appear in Web mode after restart
- Projects removed in Web mode stay removed in Electron after restart
- Settings changes sync bidirectionally across mode switches
- No more data loss or project duplication issues

**Testing:**
- Verified Electron uses /home/dhanush/Projects/automaker/data
- Confirmed server startup logs show correct DATA_DIR
- Tested project persistence across mode restarts
- Validated no writes to ~/.config/Automaker in dev mode

Fixes: Data persistence between Electron and Web modes

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
DhanushSantosh
2026-01-18 18:21:14 +05:30
parent 484d4c65d5
commit f37812247d
8 changed files with 142 additions and 35 deletions

View File

@@ -120,11 +120,14 @@ export function parseLocalStorageSettings(): Partial<GlobalSettings> | null {
if (settingsCache) {
try {
const cached = JSON.parse(settingsCache) as GlobalSettings;
logger.debug('Using fresh settings cache from localStorage');
const cacheProjectCount = cached?.projects?.length ?? 0;
logger.info(`[CACHE_LOADED] projects=${cacheProjectCount}, theme=${cached?.theme}`);
return cached;
} catch (e) {
logger.warn('Failed to parse settings cache, falling back to old storage');
}
} else {
logger.info('[CACHE_EMPTY] No settings cache found in localStorage');
}
// Fall back to old Zustand persisted storage
@@ -313,12 +316,19 @@ export async function performSettingsMigration(
): Promise<{ settings: GlobalSettings; migrated: boolean }> {
// Get localStorage data
const localSettings = parseLocalStorageSettings();
logger.info(`localStorage has ${localSettings?.projects?.length ?? 0} projects`);
logger.info(`Server has ${serverSettings.projects?.length ?? 0} projects`);
const localProjects = localSettings?.projects?.length ?? 0;
const serverProjects = serverSettings.projects?.length ?? 0;
logger.info('[MIGRATION_CHECK]', {
localStorageProjects: localProjects,
serverProjects: serverProjects,
localStorageMigrated: serverSettings.localStorageMigrated,
dataSourceMismatch: localProjects !== serverProjects,
});
// Check if migration has already been completed
if (serverSettings.localStorageMigrated) {
logger.info('localStorage migration already completed, using server settings only');
logger.info('[MIGRATION_SKIP] Using server settings only (migration already completed)');
return { settings: serverSettings, migrated: false };
}