diff --git a/app/Models/Instance.php b/app/Models/Instance.php index 5254b26..2b999ea 100644 --- a/app/Models/Instance.php +++ b/app/Models/Instance.php @@ -22,6 +22,7 @@ class Instance extends Model 'ram_mb', 'cores', 'restart_required_since', 'subdomain', 'custom_domain', 'nc_admin_ref', 'admin_password', 'credentials_acknowledged_at', 'route_written', 'routed_hostnames', 'routed_backend', 'cert_ok', 'status', 'suspended_at', 'cancel_requested_at', 'service_ends_at', + 'export_wish', 'export_reminded_at', 'domain_token', 'domain_verified_at', 'domain_cert_ok', 'domain_checked_at', 'domain_error', 'domain_failures', 'security_log_offset', ]; @@ -56,6 +57,11 @@ class Instance extends Model 'cores' => 'integer', 'cancel_requested_at' => 'datetime', 'service_ends_at' => 'datetime', + // export_wish fuehrt DREI Zustaende: null (nicht gefragt), true, false. + // Laravels boolean-Cast laesst null als null durch (kein (bool)null), + // deshalb unterstellt eine Bestandsinstanz ohne Antwort kein "nein". + 'export_wish' => 'boolean', + 'export_reminded_at' => 'datetime', 'restart_required_since' => 'datetime', ]; } diff --git a/database/migrations/2026_08_04_140000_der_kunde_sagt_ob_er_einen_export_will.php b/database/migrations/2026_08_04_140000_der_kunde_sagt_ob_er_einen_export_will.php new file mode 100644 index 0000000..86647f5 --- /dev/null +++ b/database/migrations/2026_08_04_140000_der_kunde_sagt_ob_er_einen_export_will.php @@ -0,0 +1,37 @@ +boolean('export_wish')->nullable()->after('service_ends_at'); + $table->timestamp('export_reminded_at')->nullable()->after('export_wish'); + }); + } + + public function down(): void + { + Schema::table('instances', function (Blueprint $table) { + $table->dropColumn(['export_wish', 'export_reminded_at']); + }); + } +}; diff --git a/tests/Feature/Cancellation/ExportWishTest.php b/tests/Feature/Cancellation/ExportWishTest.php new file mode 100644 index 0000000..3601734 --- /dev/null +++ b/tests/Feature/Cancellation/ExportWishTest.php @@ -0,0 +1,22 @@ +create()->export_wish)->toBeNull(); +}); + +it('haelt ein Ja und ein Nein auseinander', function () { + expect(Instance::factory()->create(['export_wish' => true])->export_wish)->toBeTrue() + ->and(Instance::factory()->create(['export_wish' => false])->export_wish)->toBeFalse(); +}); + +it('merkt sich, wann erinnert wurde, damit es nicht zweimal geschieht', function () { + $instance = Instance::factory()->create(['export_reminded_at' => now()]); + + expect($instance->fresh()->export_reminded_at)->not->toBeNull(); +});