@page "/diagnostics" @implements IDisposable Database Configuration & Migrations - Chrono DB

Database Settings & Migrations

Configure database providers, update connection strings, inspect EF Core migrations, and run maintenance tasks.

@if (!string.IsNullOrEmpty(alertMessage)) { }
Database Provider & Connection
@if (selectedProvider == DatabaseProviderType.PostgreSQL) {
Standard Npgsql connection string format used by Cloud.AppDbContext.
} else {
In-memory EF Core provider creates an isolated database in RAM for instant testing.
}
Database Health & Entity Counts
@(health?.IsConnected == true ? "ONLINE" : "OFFLINE")
@if (health != null) {
Connection Status @(health.IsConnected ? "Connected" : "Disconnected")
Query Latency @(health.ResponseTimeMs) ms
CardNotes Table Rows @health.CardNotesCount
UserDecks Table Rows @health.UserDecksCount
PasskeyCredentials Table Rows @health.PasskeysCount
@if (!health.IsConnected && !string.IsNullOrEmpty(health.ErrorMessage)) {
@health.ErrorMessage
} }
EF Core Migrations Status
@if (migrationReport?.SupportsMigrations == true && migrationReport.PendingMigrations.Any()) { }
@if (migrationReport == null) {
Loading migration report...
} else if (!migrationReport.SupportsMigrations) {
Migrations are managed via relational schema (PostgreSQL). The active in-memory provider does not use relational migration tables.
} else {
APPLIED MIGRATIONS (@migrationReport.AppliedMigrations.Count)
@if (!migrationReport.AppliedMigrations.Any()) {
No migrations have been applied to this database yet.
} else {
@foreach (var m in migrationReport.AppliedMigrations) {
@m Applied
}
}
PENDING MIGRATIONS (@migrationReport.PendingMigrations.Count)
@if (!migrationReport.PendingMigrations.Any()) {
All migrations are applied. Schema is in sync with AppDbContext.
} else {
@foreach (var m in migrationReport.PendingMigrations) {
@m Pending
}
}
}
Database Maintenance & Tools
@code { private DatabaseHealthStatus? health; private MigrationReport? migrationReport; private DatabaseProviderType selectedProvider; private string connectionStringInput = ""; private string inMemoryNameInput = ""; private bool isSaving; private bool isActionBusy; private string? alertMessage; private bool alertIsSuccess; protected override async Task OnInitializedAsync() { ConfigService.OnConfigurationChanged += HandleConfigChanged; selectedProvider = ConfigService.ProviderType; connectionStringInput = ConfigService.ConnectionString; inMemoryNameInput = ConfigService.InMemoryDbName; await RefreshAsync(); } private void HandleConfigChanged() { selectedProvider = ConfigService.ProviderType; connectionStringInput = ConfigService.ConnectionString; inMemoryNameInput = ConfigService.InMemoryDbName; _ = RefreshAsync(); } private async Task RefreshAsync() { health = await DbService.CheckHealthAsync(); migrationReport = await DbService.GetMigrationStatusAsync(); } private void SelectProvider(DatabaseProviderType provider) { selectedProvider = provider; } private void SetPreset(string conn) { connectionStringInput = conn; } private async Task SaveConfigurationAsync() { isSaving = true; ConfigService.SetConnectionString(connectionStringInput); ConfigService.SetInMemoryDbName(inMemoryNameInput); ConfigService.SetProvider(selectedProvider); if (selectedProvider == DatabaseProviderType.InMemory) { await DbService.EnsureDatabaseCreatedAsync(); } await RefreshAsync(); isSaving = false; alertIsSuccess = health?.IsConnected == true; alertMessage = health?.IsConnected == true ? "Configuration updated successfully and connection verified." : $"Configuration updated, but connection failed: {health?.ErrorMessage}"; } private async Task ApplyMigrationsAsync() { isActionBusy = true; var result = await DbService.ApplyMigrationsAsync(); isActionBusy = false; alertIsSuccess = result.Success; alertMessage = result.Message; await RefreshAsync(); } private async Task SeedDataAsync() { isActionBusy = true; var result = await DbService.SeedSampleDataAsync(); isActionBusy = false; alertIsSuccess = result.Success; alertMessage = result.Message; await RefreshAsync(); } private async Task ResetDatabaseAsync() { isActionBusy = true; var result = await DbService.ResetDatabaseAsync(); isActionBusy = false; alertIsSuccess = result.Success; alertMessage = result.Message; await RefreshAsync(); } public void Dispose() { ConfigService.OnConfigurationChanged -= HandleConfigChanged; } }