## Summary CLI commands, daemon/dashboard startup, packaged desktop startup, and live-data maintenance scripts now share the mandatory PostgreSQL lifecycle. Operators no longer risk a command silently reading or writing a disconnected SQLite shadow when PostgreSQL setup fails. ## Design decisions - Every startup owner retains and awaits its PostgreSQL shutdown callback, including partial-startup failure paths. - CLI project context and lock-retry flows resolve through asynchronous project stores. - Maintenance scripts use the shared backend helper; explicit database migration/inspection remains the only CLI surface allowed to read legacy SQLite sources. ## Validation - CLI and Desktop typechecks pass on the stacked branch. - `pnpm test:gate` passes all 478 gate tests. - This PR changes 54 files. ## Stack - Depends on #2109, which depends on #2108. - Bundled plugins and docs/release follow in later PRs. Related: #2105 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * PostgreSQL is now the authoritative store for structured project and task metadata. * Projects can be recognized and initialized using `.fusion/project.json`, without creating a legacy SQLite database. * CLI commands now retry transient PostgreSQL contention errors. * **Bug Fixes** * Improved cleanup when commands complete, fail, or run in the background, preventing lingering resources. * Improved desktop, server, and session shutdown reliability. * **Documentation** * Updated storage and standalone binary guidance to reflect PostgreSQL and legacy SQLite compatibility. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
36 lines
1.1 KiB
JavaScript
36 lines
1.1 KiB
JavaScript
import { existsSync, statSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
import { DatabaseSync } from "node:sqlite";
|
|
|
|
/**
|
|
* FNXC:LocalStartupPostgresMigration 2026-07-14-22:25:
|
|
* Local startup recognizes both the PostgreSQL-era identity marker and a valid legacy SQLite database. Legacy input must pass the canonical read-only SQLite probe so malformed paths do not suppress initialization; an intentional zero-byte bootstrap file remains valid migration input.
|
|
*/
|
|
export function hasLocalProjectMigrationInput(rootDir) {
|
|
return existsSync(resolve(rootDir, ".fusion/project.json"))
|
|
|| isValidLegacySqliteInput(resolve(rootDir, ".fusion/fusion.db"));
|
|
}
|
|
|
|
function isValidLegacySqliteInput(dbPath) {
|
|
if (!existsSync(dbPath)) return false;
|
|
|
|
try {
|
|
const stats = statSync(dbPath);
|
|
if (!stats.isFile()) return false;
|
|
if (stats.size === 0) return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
|
|
let db = null;
|
|
try {
|
|
db = new DatabaseSync(dbPath, { readOnly: true });
|
|
db.prepare("PRAGMA schema_version").get();
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
} finally {
|
|
db?.close();
|
|
}
|
|
}
|