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

@@ -40,3 +40,29 @@ export function shouldRetryWithCredits(authKey: string, creditsEnabled: boolean)
export function handleCreditsFailure(authKey: string): boolean {
return recordCreditsFailure(authKey);
}
/**
* Read the ANTIGRAVITY_CREDITS env var to determine the credits injection strategy.
*
* - "off" — never inject credits (default if env var is missing)
* - "retry" — inject credits only as a 429 fallback
* - "always" — inject credits on every request (skip normal quota path)
*/
export type CreditsMode = "off" | "retry" | "always";
export function getCreditsMode(): CreditsMode {
const raw = (process.env.ANTIGRAVITY_CREDITS || "").trim().toLowerCase();
if (raw === "always" || raw === "retry") return raw;
return "off";
}
/**
* Determine if the executor should inject credits on the *first* request
* (credits-first mode). Returns true only when creditsMode === "always"
* and the auth key hasn't been disabled by repeated failures.
*/
export function shouldUseCreditsFirst(authKey: string, creditsMode: CreditsMode | string): boolean {
if (creditsMode !== "always") return false;
if (isCreditsDisabled(authKey)) return false;
return true;
}

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 &&