feat: due_at parser and event upserter
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BCrwHHnGCB5XH968Nxokqw
This commit is contained in:
60
core/app/Ingest/ParsedDue.php
Normal file
60
core/app/Ingest/ParsedDue.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Ingest;
|
||||
|
||||
use App\Enums\DueMode;
|
||||
use App\Models\Event;
|
||||
use Carbon\CarbonImmutable;
|
||||
|
||||
/** Разобранный due_at: tagged union по mode. */
|
||||
final class ParsedDue
|
||||
{
|
||||
private function __construct(
|
||||
public readonly DueMode $mode,
|
||||
public readonly ?string $date,
|
||||
public readonly ?string $time,
|
||||
public readonly ?CarbonImmutable $instant,
|
||||
) {}
|
||||
|
||||
public static function local(string $date, string $time): self
|
||||
{
|
||||
return new self(DueMode::Local, $date, $time, null);
|
||||
}
|
||||
|
||||
public static function fixed(CarbonImmutable $instant): self
|
||||
{
|
||||
return new self(DueMode::Fixed, null, null, $instant->utc());
|
||||
}
|
||||
|
||||
/** Календарный день срока в данном поясе, Y-m-d. */
|
||||
public function dayFor(string $tz): string
|
||||
{
|
||||
return match ($this->mode) {
|
||||
DueMode::Local => $this->date,
|
||||
DueMode::Fixed => $this->instant->setTimezone($tz)->format('Y-m-d'),
|
||||
};
|
||||
}
|
||||
|
||||
public function equals(Event $event): bool
|
||||
{
|
||||
if ($event->due_mode !== $this->mode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return match ($this->mode) {
|
||||
DueMode::Local => $event->due_date->format('Y-m-d') === $this->date && $event->due_time === $this->time,
|
||||
DueMode::Fixed => $event->due_instant->eq($this->instant),
|
||||
};
|
||||
}
|
||||
|
||||
/** @return array<string, mixed> колонки events */
|
||||
public function columns(): array
|
||||
{
|
||||
return [
|
||||
'due_mode' => $this->mode,
|
||||
'due_date' => $this->date,
|
||||
'due_time' => $this->time,
|
||||
'due_instant' => $this->instant,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user