Updater-Migration für Feature-Tabellen + README um neue Features erweitern

- updater/migrations/0001_feature_ui_tables.sql: legt voucher_templates und
  password_reset_tokens idempotent an (CREATE TABLE IF NOT EXISTS), damit
  bestehende Installationen die neuen Tabellen per System-Update erhalten
- Updater-UI: Button "Ausstehende Migrationen ausführen" + run_migrations-Action
  (CSRF-geschützt) im Migrations-Tab
- README: Features (Bulk, Templates, Dark Mode, i18n, Audit-Log, Passwort-Reset),
  zwei neue Screenshots (Bulk-Erstellung, Dashboard Dark Mode), Roadmap & Updater-
  Abschnitt aktualisiert
This commit is contained in:
Claude 2026-06-05 19:16:55 +00:00
parent 526c43e8ee
commit 51485810b4
No known key found for this signature in database
6 changed files with 105 additions and 6 deletions

View file

@ -34,6 +34,7 @@ class UpdateController
case 'progress': $this->actionProgress(); break;
case 'set_channel': $this->actionSetChannel(); break;
case 'migrations': $this->actionMigrations(); break;
case 'run_migrations': $this->actionRunMigrations(); break;
default: $this->renderPage();
}
}
@ -99,6 +100,28 @@ class UpdateController
}
}
private function actionRunMigrations(): void
{
if (!$this->auth->validateCsrfToken($_POST['csrf_token'] ?? '')) {
$this->json(['error' => 'Ungültiges Sicherheits-Token'], 403);
return;
}
try {
$runner = new MigrationRunner(
$this->db->getConnection(),
__DIR__ . '/migrations',
__DIR__ . '/storage'
);
$applied = $runner->runPending(true);
if ($this->audit) {
$this->audit->log('migrations_run', ['applied' => $applied], $_SESSION['user_id'] ?? null);
}
$this->json(['success' => true, 'applied' => $applied, 'migrations' => $runner->status()]);
} catch (\Throwable $e) {
$this->json(['error' => $e->getMessage()], 500);
}
}
// ------------------------------------------------------------------- Render
private function renderPage(): void