Recht: Kuendigungsbutton nach Par. 312k BGB - Backend + Admin-Queue

Oeffentliche Bestaetigungsseite /de/kuendigung ohne Login: Art der
Kuendigung (Grund nur bei ausserordentlich), Zuordnungsdaten,
Beendigungszeitpunkt; Honeypot + Rate-Limit wie beim Widerruf.
Sofortige automatische Zugangsbestaetigung per E-Mail (Par. 312k
Abs. 4 BGB) + Betreiber-Mail. Kuendigungen laufen in der
Recht-&-Compliance-Queue unter den Widerrufen auf (K-Vorgaenge,
eigener Filter, Erledigt/Wieder-oeffnen, vierte KPI-Karte).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-03 11:32:43 +00:00
parent 239ec571bc
commit 1c3a52ae3c
12 changed files with 826 additions and 2 deletions

View file

@ -0,0 +1,77 @@
<?php
use App\Models\TerminationRequest;
use App\Models\User;
use Database\Seeders\RolesAndPermissionsSeeder;
use Livewire\Volt\Volt;
use Tests\TestCase;
beforeEach(function () {
/** @var TestCase $this */
$this->seed(RolesAndPermissionsSeeder::class);
});
function terminationAdmin(): User
{
$admin = User::factory()->create(['is_active' => true]);
$admin->assignRole('admin');
return $admin;
}
test('the legal queue lists open termination requests', function () {
$termination = TerminationRequest::factory()->extraordinary()->create([
'name' => 'Paula Presse',
'email' => 'paula@example.test',
'contract_reference' => 'STR-2026-0042',
'reason' => 'Wiederholte Störung der Leistung.',
]);
Volt::actingAs(terminationAdmin())
->test('admin.legal-requests.index')
->assertOk()
->assertSee('Kündigungen')
->assertSee('K-'.$termination->id)
->assertSee('Paula Presse')
->assertSee('paula@example.test')
->assertSee('STR-2026-0042')
->assertSee('Außerordentlich');
});
test('an admin can resolve a termination request', function () {
$termination = TerminationRequest::factory()->create();
Volt::actingAs(terminationAdmin())
->test('admin.legal-requests.index')
->call('resolveTermination', $termination->id)
->assertOk();
$termination->refresh();
expect($termination->status)->toBe('resolved');
expect($termination->resolved_at)->not->toBeNull();
});
test('an admin can reopen a resolved termination request', function () {
$termination = TerminationRequest::factory()->resolved()->create();
Volt::actingAs(terminationAdmin())
->test('admin.legal-requests.index')
->set('terminationStatusFilter', 'all')
->call('reopenTermination', $termination->id)
->assertOk();
$termination->refresh();
expect($termination->status)->toBe('open');
expect($termination->resolved_at)->toBeNull();
});
test('resolved terminations are hidden from the default open view', function () {
TerminationRequest::factory()->resolved()->create(['name' => 'Erledigte Kündigung']);
Volt::actingAs(terminationAdmin())
->test('admin.legal-requests.index')
->assertOk()
->assertDontSee('Erledigte Kündigung');
});