fix: resolve migration abort on fresh database #1328 and missing getCreditsMode export

This commit is contained in:
diegosouzapw
2026-04-16 13:48:37 -03:00
parent adf59ddce7
commit a0654b4643
3 changed files with 41 additions and 7 deletions

View File

@@ -791,7 +791,9 @@ export function getDbInstance(): SqliteDatabase {
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='key_value'")
.get();
if (hasKv) {
const rowCount = (kvProbe.prepare("SELECT COUNT(*) AS c FROM key_value").get() as { c: number }).c;
const rowCount = (
kvProbe.prepare("SELECT COUNT(*) AS c FROM key_value").get() as { c: number }
).c;
if (rowCount > KEY_VALUE_PRESERVE_LIMIT) {
console.warn(
`[DB] key_value has ${rowCount} rows (limit ${KEY_VALUE_PRESERVE_LIMIT}), skipping preservation`
@@ -819,6 +821,12 @@ export function getDbInstance(): SqliteDatabase {
}
}
// Track whether the DB file is brand new (fresh DATA_DIR / Docker volume).
// This is needed so the migration runner skips the mass-migration safety abort
// that would otherwise trigger because heuristic seeding marks some migrations
// as applied, making the fresh DB look like a wiped existing DB (#1328).
const isNewDb = !fs.existsSync(sqliteFile);
// Detect and handle old schema format — preserve data when possible (#146)
// Uses a single probe connection that becomes the real connection when possible.
if (fs.existsSync(sqliteFile)) {
@@ -983,7 +991,7 @@ export function getDbInstance(): SqliteDatabase {
"call_logs_summary_storage"
);
}
runMigrations(db);
runMigrations(db, { isNewDb });
offloadLegacyCallLogDetails(db);
// Auto-migrate from db.json if exists

View File

@@ -150,12 +150,10 @@ function reconcileRenumberedMigrations(
for (const compatibility of RENAMED_MIGRATION_COMPATIBILITY) {
const hasTargetFile = files.some(
(file) =>
file.version === compatibility.toVersion && file.name === compatibility.toName
(file) => file.version === compatibility.toVersion && file.name === compatibility.toName
);
const hasSourceFile = files.some(
(file) =>
file.version === compatibility.fromVersion && file.name !== compatibility.fromName
(file) => file.version === compatibility.fromVersion && file.name !== compatibility.fromName
);
if (!hasTargetFile || !hasSourceFile) {
@@ -241,7 +239,8 @@ function createPreMigrationBackup(db: Database.Database): string | null {
* 2. Aborts if too many pending migrations on an existing DB (likely wipe)
* 3. Creates automatic backup before running any migrations
*/
export function runMigrations(db: Database.Database): number {
export function runMigrations(db: Database.Database, options?: { isNewDb?: boolean }): number {
const isNewDb = options?.isNewDb === true;
ensureMigrationsTable(db);
const files = getMigrationFiles();
@@ -284,6 +283,7 @@ export function runMigrations(db: Database.Database): number {
if (
!isTestEnvironment &&
!isNewDb &&
process.env.DISABLE_SQLITE_AUTO_BACKUP !== "true" &&
MAX_PENDING_MIGRATIONS_ON_EXISTING_DB > 0 &&
applied.size > 0 &&