diff --git a/src/Purrse.Api/Program.cs b/src/Purrse.Api/Program.cs index e5fa423..a3fb05c 100644 --- a/src/Purrse.Api/Program.cs +++ b/src/Purrse.Api/Program.cs @@ -119,8 +119,25 @@ using (var scope = app.Services.CreateScope()) await db.Database.MigrateAsync(); } -// One-time data migration: split SimpleFIN connections by institution +// One-time data migrations await SimpleFinConnectionMigration.RunAsync(app.Services, app.Services.GetRequiredService>()); +using (var scope = app.Services.CreateScope()) +{ + var db = scope.ServiceProvider.GetRequiredService(); + await db.Database.ExecuteSqlRawAsync( + "CREATE TABLE IF NOT EXISTS data_migrations (name TEXT PRIMARY KEY, applied_at TIMESTAMP NOT NULL)"); + var applied = await db.Database.SqlQueryRaw( + "SELECT 1 AS \"Value\" FROM data_migrations WHERE name = 'ClearSyncedTransactions'").AnyAsync(); + if (!applied) + { + var count = await db.Database.ExecuteSqlRawAsync( + "UPDATE \"Transactions\" SET \"Status\" = 1 WHERE \"FitId\" IS NOT NULL AND \"Status\" = 0"); + if (count > 0) + app.Services.GetRequiredService>().LogInformation("Marked {Count} bank-synced transactions as Cleared", count); + await db.Database.ExecuteSqlRawAsync( + "INSERT INTO data_migrations (name, applied_at) VALUES ('ClearSyncedTransactions', NOW()) ON CONFLICT DO NOTHING"); + } +} // Initialize plugin system var pluginService = app.Services.GetRequiredService();