feat: state, window and quiet rules
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BCrwHHnGCB5XH968Nxokqw
This commit is contained in:
36
core/app/Scheduling/QuietRule.php
Normal file
36
core/app/Scheduling/QuietRule.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Scheduling;
|
||||
|
||||
use App\Enums\EventState;
|
||||
use App\Models\Event;
|
||||
use App\Models\User;
|
||||
use Carbon\CarbonImmutable;
|
||||
|
||||
/** «Помню»: до какого момента молчать, по текущему состоянию. */
|
||||
final class QuietRule
|
||||
{
|
||||
public function __construct(private readonly DueResolver $due) {}
|
||||
|
||||
public function afterAck(Event $event, User $user, EventState $state, Due $due, CarbonImmutable $now): CarbonImmutable
|
||||
{
|
||||
return match ($state) {
|
||||
EventState::Preparing => $this->nextCascadePoint($event, $user, $due, $now),
|
||||
EventState::Today => $now->startOfHour()->addHours(2),
|
||||
EventState::Overdue => $now->startOfDay()->addDays(2),
|
||||
default => $now,
|
||||
};
|
||||
}
|
||||
|
||||
private function nextCascadePoint(Event $event, User $user, Due $due, CarbonImmutable $now): CarbonImmutable
|
||||
{
|
||||
$today = $now->startOfDay();
|
||||
foreach (Cascade::points($this->due->fireStart($event, $user), $due->day) as $point) {
|
||||
if ($point->gt($today)) {
|
||||
return $point;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->due->todayStart($due, $user);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user