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');
|
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',
|
version: 'v0.56',
|
||||||
description: 'bills/categories: soft-delete columns',
|
description: 'bills/categories: soft-delete columns',
|
||||||
|
|
@ -1895,8 +1939,6 @@ function runMigrations() {
|
||||||
if (!hasMigrationBeenApplied(migration.version)) {
|
if (!hasMigrationBeenApplied(migration.version)) {
|
||||||
// Validate dependencies before applying
|
// Validate dependencies before applying
|
||||||
const depCheck = validateMigrationDependencies(migration, appliedVersions);
|
const depCheck = validateMigrationDependencies(migration, appliedVersions);
|
||||||
console.log(`[migration] Applying ${migration.version}: ${migration.description}`);
|
|
||||||
|
|
||||||
if (!depCheck.valid) {
|
if (!depCheck.valid) {
|
||||||
console.error(`[migration-error] ${migration.version} depends on [${depCheck.missing.join(', ')}] which have not been applied. Skipping.`);
|
console.error(`[migration-error] ${migration.version} depends on [${depCheck.missing.join(', ')}] which have not been applied. Skipping.`);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "bill-tracker",
|
"name": "bill-tracker",
|
||||||
"version": "0.30.1",
|
"version": "0.30.2",
|
||||||
"description": "Monthly bill tracking system",
|
"description": "Monthly bill tracking system",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue