Files
fusion/scripts/lib/start-local-project.mjs
gsxdsm 97172fdcf2 fix(FN-7952): require PostgreSQL in CLI and desktop (#2110)
## 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 -->
2026-07-14 23:18:55 -07:00

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();
}
}