From c99790a7107086ed8d7e188fd3c2c0e1ac60e7b0 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 1 Apr 2026 23:55:20 +0200 Subject: [PATCH] fix: expose migrations execute API route and preserve real migration errors in UI fallback --- app/settings/backend/router.py | 9 +++++++++ app/settings/frontend/migrations.html | 23 ++++++++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/app/settings/backend/router.py b/app/settings/backend/router.py index 4fee5a9..c617024 100644 --- a/app/settings/backend/router.py +++ b/app/settings/backend/router.py @@ -308,6 +308,15 @@ async def get_migration_statuses_api(): return migration_statuses() +@router.post("/settings/migrations/execute", tags=["Settings"]) +async def execute_migration_api(payload: dict): + """Expose migration execution via API router (served under /api/v1).""" + from app.settings.backend.views import execute_migration, MigrationExecution + + model = MigrationExecution(**payload) + return execute_migration(model) + + @router.post("/settings/sync-from-env", tags=["Settings"]) async def sync_settings_from_env(): """Sync settings from .env file into database (only updates empty values)""" diff --git a/app/settings/frontend/migrations.html b/app/settings/frontend/migrations.html index cc0df8d..f9eb1d5 100644 --- a/app/settings/frontend/migrations.html +++ b/app/settings/frontend/migrations.html @@ -184,6 +184,7 @@ const attempts = []; let data = null; let lastError = null; + let hardError = null; for (const url of urls) { try { @@ -202,7 +203,12 @@ break; } - lastError = payload.detail || payload.message || `HTTP ${response.status}`; + const errMsg = payload.detail || payload.message || `HTTP ${response.status}`; + if (response.status !== 404 && response.status !== 405) { + hardError = errMsg; + break; + } + lastError = errMsg; } catch (err) { attempts.push(`${url} -> ERR`); lastError = err.message || 'Netvaerksfejl'; @@ -210,11 +216,12 @@ } if (!data) { - throw new Error(`${lastError || 'Migration fejlede'} (forsøgt: ${attempts.join(' | ')})`); + throw new Error(`${hardError || lastError || 'Migration fejlede'} (forsøgt: ${attempts.join(' | ')})`); } feedback.className = 'alert alert-success mt-3'; - feedback.innerHTML = `Migration kørt
${data.output}
`; + const output = data.output || data.message || 'Migration executed successfully'; + feedback.innerHTML = `Migration kørt
${output}
`; } catch (error) { feedback.className = 'alert alert-danger mt-3'; feedback.innerHTML = `Fejl
${error.message}`; @@ -291,6 +298,7 @@ const urls = buildMigrationActionUrls('status'); let data = null; let lastError = null; + let hardError = null; const attempts = []; for (const url of urls) { @@ -302,7 +310,12 @@ data = payload; break; } - lastError = payload.detail || `HTTP ${response.status}`; + const errMsg = payload.detail || `HTTP ${response.status}`; + if (response.status !== 404 && response.status !== 405) { + hardError = errMsg; + break; + } + lastError = errMsg; } catch (err) { attempts.push(`${url} -> ERR`); lastError = err.message || 'Netvaerksfejl'; @@ -310,7 +323,7 @@ } if (!data) { - throw new Error(`${lastError || 'Status check fejlede'} (forsøgt: ${attempts.join(' | ')})`); + throw new Error(`${hardError || lastError || 'Status check fejlede'} (forsøgt: ${attempts.join(' | ')})`); } const statuses = data.statuses || [];