fix: migration dedup and legacy reconcile gaps
- Removed double log line in runMigrations (migration name printed twice) - Added v0.54 (user_settings) and v0.55 (user_login_history device metadata) to reconcileLegacyMigrations - Both are idempotent, no data was ever lost, but legacy upgrades were re-running them unnecessarily
This commit is contained in:
parent
a1f679f7b0
commit
1b9518a5d7
|
|
@ -877,6 +877,50 @@ function reconcileLegacyMigrations() {
|
|||
console.log('[migration] user_login_history table created');
|
||||
}
|
||||
},
|
||||
{
|
||||
version: 'v0.54',
|
||||
description: 'user_settings: per-user display and billing preferences',
|
||||
check: function() {
|
||||
return !!db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='user_settings'").get();
|
||||
},
|
||||
run: function() {
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS user_settings (
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
key TEXT NOT NULL,
|
||||
value TEXT NOT NULL,
|
||||
updated_at TEXT DEFAULT (datetime('now')),
|
||||
PRIMARY KEY (user_id, key)
|
||||
)
|
||||
`);
|
||||
const userSettingKeys = ['currency', 'date_format', 'grace_period_days', 'notify_days_before'];
|
||||
const users = db.prepare('SELECT id FROM users').all();
|
||||
const getCurrent = db.prepare('SELECT value FROM settings WHERE key = ?');
|
||||
const insert = db.prepare('INSERT OR IGNORE INTO user_settings (user_id, key, value) VALUES (?, ?, ?)');
|
||||
for (const user of users) {
|
||||
for (const key of userSettingKeys) {
|
||||
const row = getCurrent.get(key);
|
||||
if (row) insert.run(user.id, key, row.value);
|
||||
}
|
||||
}
|
||||
console.log('[migration] user_settings table ensured');
|
||||
}
|
||||
},
|
||||
{
|
||||
version: 'v0.55',
|
||||
description: 'user_login_history: parsed device metadata and fingerprint',
|
||||
check: function() {
|
||||
const cols = db.prepare('PRAGMA table_info(user_login_history)').all().map(c => c.name);
|
||||
return ['browser', 'os', 'device_type', 'device_fingerprint'].every(c => cols.includes(c));
|
||||
},
|
||||
run: function() {
|
||||
const cols = db.prepare('PRAGMA table_info(user_login_history)').all().map(c => c.name);
|
||||
for (const col of ['browser', 'os', 'device_type', 'device_fingerprint']) {
|
||||
if (!cols.includes(col)) db.exec(`ALTER TABLE user_login_history ADD COLUMN ${col} TEXT`);
|
||||
}
|
||||
console.log('[migration] user_login_history device metadata columns ensured');
|
||||
}
|
||||
},
|
||||
{
|
||||
version: 'v0.56',
|
||||
description: 'bills/categories: soft-delete columns',
|
||||
|
|
@ -1895,8 +1939,6 @@ function runMigrations() {
|
|||
if (!hasMigrationBeenApplied(migration.version)) {
|
||||
// Validate dependencies before applying
|
||||
const depCheck = validateMigrationDependencies(migration, appliedVersions);
|
||||
console.log(`[migration] Applying ${migration.version}: ${migration.description}`);
|
||||
|
||||
if (!depCheck.valid) {
|
||||
console.error(`[migration-error] ${migration.version} depends on [${depCheck.missing.join(', ')}] which have not been applied. Skipping.`);
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "bill-tracker",
|
||||
"version": "0.30.1",
|
||||
"version": "0.30.2",
|
||||
"description": "Monthly bill tracking system",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
|
|
|
|||
Loading…
Reference in New Issue