Files
fusion/scripts/__tests__/start-local-project.test.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

37 lines
1.5 KiB
JavaScript

import assert from "node:assert/strict";
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { DatabaseSync } from "node:sqlite";
import test from "node:test";
import { hasLocalProjectMigrationInput } from "../lib/start-local-project.mjs";
test("local startup recognizes project identity and legacy migration input", async (t) => {
const root = await mkdtemp(join(tmpdir(), "fusion-start-local-project-"));
t.after(() => rm(root, { recursive: true, force: true }));
await mkdir(join(root, ".fusion"));
assert.equal(hasLocalProjectMigrationInput(root), false);
await writeFile(join(root, ".fusion", "fusion.db"), "");
assert.equal(hasLocalProjectMigrationInput(root), true);
await rm(join(root, ".fusion", "fusion.db"));
const db = new DatabaseSync(join(root, ".fusion", "fusion.db"));
db.exec("CREATE TABLE migration_input (id INTEGER PRIMARY KEY)");
db.close();
assert.equal(hasLocalProjectMigrationInput(root), true);
await rm(join(root, ".fusion", "fusion.db"));
await writeFile(join(root, ".fusion", "fusion.db"), "malformed legacy input");
assert.equal(hasLocalProjectMigrationInput(root), false);
await rm(join(root, ".fusion", "fusion.db"));
await mkdir(join(root, ".fusion", "fusion.db"));
assert.equal(hasLocalProjectMigrationInput(root), false);
await rm(join(root, ".fusion", "fusion.db"), { recursive: true });
await writeFile(join(root, ".fusion", "project.json"), "{}");
assert.equal(hasLocalProjectMigrationInput(root), true);
});