feat(tui): add Diagnose Backup File option to interactive menu

- Added 'Diagnose Backup File' as menu option in TUI
- Archive browser now supports 'diagnose' mode
- Allows users to run deep diagnosis on backups before restore
- Helps identify truncation/corruption issues in large backups
This commit is contained in:
2026-01-06 09:44:22 +01:00
parent 4c171c0e44
commit 14bd1f848c
2 changed files with 34 additions and 15 deletions

View File

@@ -201,6 +201,12 @@ func (m ArchiveBrowserModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if len(m.archives) > 0 && m.cursor < len(m.archives) { if len(m.archives) > 0 && m.cursor < len(m.archives) {
selected := m.archives[m.cursor] selected := m.archives[m.cursor]
// Handle diagnose mode - go directly to diagnosis view
if m.mode == "diagnose" {
diagnoseView := NewDiagnoseView(m.config, m.logger, m.parent, m.ctx, selected)
return diagnoseView, diagnoseView.Init()
}
// Validate selection based on mode // Validate selection based on mode
if m.mode == "restore-cluster" && !selected.Format.IsClusterBackup() { if m.mode == "restore-cluster" && !selected.Format.IsClusterBackup() {
m.message = errorStyle.Render("❌ Please select a cluster backup (.tar.gz)") m.message = errorStyle.Render("❌ Please select a cluster backup (.tar.gz)")
@@ -250,6 +256,8 @@ func (m ArchiveBrowserModel) View() string {
title = "📦 Select Archive to Restore (Single Database)" title = "📦 Select Archive to Restore (Single Database)"
} else if m.mode == "restore-cluster" { } else if m.mode == "restore-cluster" {
title = "📦 Select Archive to Restore (Cluster)" title = "📦 Select Archive to Restore (Cluster)"
} else if m.mode == "diagnose" {
title = "🔍 Select Archive to Diagnose"
} }
s.WriteString(titleStyle.Render(title)) s.WriteString(titleStyle.Render(title))

View File

@@ -92,6 +92,7 @@ func NewMenuModel(cfg *config.Config, log logger.Logger) *MenuModel {
"────────────────────────────────", "────────────────────────────────",
"Restore Single Database", "Restore Single Database",
"Restore Cluster Backup", "Restore Cluster Backup",
"Diagnose Backup File",
"List & Manage Backups", "List & Manage Backups",
"────────────────────────────────", "────────────────────────────────",
"View Active Operations", "View Active Operations",
@@ -163,19 +164,21 @@ func (m *MenuModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m.handleRestoreSingle() return m.handleRestoreSingle()
case 5: // Restore Cluster Backup case 5: // Restore Cluster Backup
return m.handleRestoreCluster() return m.handleRestoreCluster()
case 6: // List & Manage Backups case 6: // Diagnose Backup File
return m.handleDiagnoseBackup()
case 7: // List & Manage Backups
return m.handleBackupManager() return m.handleBackupManager()
case 8: // View Active Operations case 9: // View Active Operations
return m.handleViewOperations() return m.handleViewOperations()
case 9: // Show Operation History case 10: // Show Operation History
return m.handleOperationHistory() return m.handleOperationHistory()
case 10: // Database Status case 11: // Database Status
return m.handleStatus() return m.handleStatus()
case 11: // Settings case 12: // Settings
return m.handleSettings() return m.handleSettings()
case 12: // Clear History case 13: // Clear History
m.message = "🗑️ History cleared" m.message = "🗑️ History cleared"
case 13: // Quit case 14: // Quit
if m.cancel != nil { if m.cancel != nil {
m.cancel() m.cancel()
} }
@@ -244,21 +247,23 @@ func (m *MenuModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m.handleRestoreSingle() return m.handleRestoreSingle()
case 5: // Restore Cluster Backup case 5: // Restore Cluster Backup
return m.handleRestoreCluster() return m.handleRestoreCluster()
case 6: // List & Manage Backups case 6: // Diagnose Backup File
return m.handleDiagnoseBackup()
case 7: // List & Manage Backups
return m.handleBackupManager() return m.handleBackupManager()
case 7: // Separator case 8: // Separator
// Do nothing // Do nothing
case 8: // View Active Operations case 9: // View Active Operations
return m.handleViewOperations() return m.handleViewOperations()
case 9: // Show Operation History case 10: // Show Operation History
return m.handleOperationHistory() return m.handleOperationHistory()
case 10: // Database Status case 11: // Database Status
return m.handleStatus() return m.handleStatus()
case 11: // Settings case 12: // Settings
return m.handleSettings() return m.handleSettings()
case 12: // Clear History case 13: // Clear History
m.message = "🗑️ History cleared" m.message = "🗑️ History cleared"
case 13: // Quit case 14: // Quit
if m.cancel != nil { if m.cancel != nil {
m.cancel() m.cancel()
} }
@@ -407,6 +412,12 @@ func (m *MenuModel) handleBackupManager() (tea.Model, tea.Cmd) {
return manager, manager.Init() return manager, manager.Init()
} }
// handleDiagnoseBackup opens archive browser for diagnosis
func (m *MenuModel) handleDiagnoseBackup() (tea.Model, tea.Cmd) {
browser := NewArchiveBrowser(m.config, m.logger, m, m.ctx, "diagnose")
return browser, browser.Init()
}
func (m *MenuModel) applyDatabaseSelection() { func (m *MenuModel) applyDatabaseSelection() {
if m == nil || len(m.dbTypes) == 0 { if m == nil || len(m.dbTypes) == 0 {
return return