fix(admin): require host on any maintenance save; cancel-notify only delivered announcements

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat/portal-design
nexxo 2026-07-25 16:19:44 +02:00
parent 62b4d85ef7
commit 718e8568c1
2 changed files with 12 additions and 11 deletions

View File

@ -76,17 +76,17 @@ class Maintenance extends Component
return null;
}
if ($state === 'scheduled') {
if (empty($this->hostIds)) {
$this->addError('hostIds', __('maintenance.need_host'));
// A window always needs a host — otherwise a hostless draft can never be
// published (there is no edit-hosts action) and is stuck.
if (empty($this->hostIds)) {
$this->addError('hostIds', __('maintenance.need_host'));
return null;
}
if ($ends->isPast()) {
$this->addError('endsAt', __('maintenance.end_future'));
return null;
}
if ($state === 'scheduled' && $ends->isPast()) {
$this->addError('endsAt', __('maintenance.end_future'));
return null;
}
return null;
}
// Create the window and attach hosts atomically so a bad id can't leave
@ -163,6 +163,7 @@ class Maintenance extends Component
$notified = MaintenanceNotification::query()
->where('maintenance_window_id', $window->id)
->where('event', 'announcement')
->whereNotNull('sent_at') // only customers who actually received it
->pluck('customer_id');
foreach (Customer::query()->whereIn('id', $notified)->get() as $customer) {
$this->deliverOnce($window, $customer, 'cancelled', new MaintenanceCancelledMail($window, $customer));

View File

@ -54,9 +54,9 @@ it('emails a cancellation to customers who were announced', function () {
$customer = affectedCustomerOn($host);
$window = MaintenanceWindow::factory()->scheduled()->create();
$window->hosts()->attach($host->id);
// Simulate the customer having received the announcement.
// Simulate the customer having actually received the announcement.
\App\Models\MaintenanceNotification::create([
'maintenance_window_id' => $window->id, 'customer_id' => $customer->id, 'event' => 'announcement', 'email' => $customer->email,
'maintenance_window_id' => $window->id, 'customer_id' => $customer->id, 'event' => 'announcement', 'email' => $customer->email, 'sent_at' => now(),
]);
Livewire::actingAs(operator('Owner'))->test(Maintenance::class)->call('cancel', $window->uuid);