Give the installation a test mode and a live mode

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
feature/betriebsmodus
nexxo 2026-07-30 10:41:23 +02:00
parent 88d6dc620b
commit 3cf17e5cb0
2 changed files with 75 additions and 0 deletions

View File

@ -0,0 +1,41 @@
<?php
namespace App\Support;
/**
* Test oder Live welcher Satz Zugangsdaten gilt.
*
* In `Settings` und nicht in der `.env`, weil `Settings` seinen Zwischenspeicher
* beim Schreiben verwirft: ein Umlegen wirkt sofort, auch in den
* Warteschlangen-Prozessen, die seit Stunden laufen. Eine `.env`-Variable
* bräuchte einen Containerneustart genau die Falle, die am 2026-07-30 eine
* korrigierte DNS-Zone acht Stunden lang wirkungslos gelassen hat.
*
* Live ist die Vorgabe. Eine Installation, die nichts gespeichert hat, soll
* nicht in einem Modus stehen, der stillschweigend andere Zugangsdaten benutzt.
*/
enum OperatingMode: string
{
case Test = 'test';
case Live = 'live';
public const SETTING = 'platform.mode';
public static function current(): self
{
// tryFrom, nicht from: ein unbekannter Wert in der Zeile ist ein
// Datenfehler und darf nicht jede Anfrage in eine Ausnahme werfen.
return self::tryFrom((string) Settings::get(self::SETTING, self::Live->value))
?? self::Live;
}
public static function set(self $mode): void
{
Settings::set(self::SETTING, $mode->value);
}
public function isTest(): bool
{
return $this === self::Test;
}
}

View File

@ -0,0 +1,34 @@
<?php
use App\Support\OperatingMode;
use App\Support\Settings;
/**
* Der Modus entscheidet, welche Zugangsdaten gelten. Er wird an genau einer
* Stelle gelesen, damit nirgends sonst ein String verglichen wird ein
* Tippfehler in einem Vergleich wäre sonst ein stiller Wechsel auf Live.
*/
it('is live when nothing has been stored', function () {
expect(OperatingMode::current())->toBe(OperatingMode::Live);
});
it('reads the stored mode', function () {
Settings::set('platform.mode', 'test');
expect(OperatingMode::current())->toBe(OperatingMode::Test);
});
it('falls back to live when the stored value is not a mode', function () {
// Eine Zeile, die von Hand oder von einer alten Fassung geschrieben wurde.
// Live ist die sichere Richtung: eine echte Zahlung wird korrekt behandelt,
// ein Testereignis scheitert laut.
Settings::set('platform.mode', 'staging');
expect(OperatingMode::current())->toBe(OperatingMode::Live);
});
it('writes the mode and takes effect immediately', function () {
OperatingMode::set(OperatingMode::Test);
expect(OperatingMode::current())->toBe(OperatingMode::Test);
});