Files
hado/core/app/Http/Requests/UpsertEventsRequest.php
2026-09-04 08:25:00 -03:00

75 lines
2.9 KiB
PHP

<?php
namespace App\Http\Requests;
use App\Ingest\DueAtParser;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;
use InvalidArgumentException;
class UpsertEventsRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'events' => ['required', 'array', 'min:1', 'max:500'],
'events.*.user' => ['required', 'string', 'max:255'],
'events.*.source_ref' => ['required', 'string', 'max:255'],
'events.*.topic' => ['sometimes', 'nullable', 'string', 'max:255'],
'events.*.due_at' => ['required', 'string'],
'events.*.fire_at' => ['required', 'date_format:Y-m-d'],
'events.*.after_due' => ['required', 'in:keep,expire'],
'events.*.payload' => ['required', 'array'],
'events.*.payload.title' => ['required', 'string'],
'events.*.payload.subtitle' => ['sometimes', 'nullable', 'string'],
'events.*.payload.deep_link' => ['sometimes', 'nullable', 'string', 'max:2048', 'regex:#^(/|https?://)#'],
'events.*.payload.done_label' => ['sometimes', 'nullable', 'string', 'max:64'],
];
}
public function messages(): array
{
return [
'events.*.payload.deep_link.regex' => 'deep_link должен быть относительным путём или http(s)-ссылкой',
];
}
public function after(): array
{
return [function (Validator $v) {
foreach ((array) $this->input('events', []) as $i => $item) {
if (! is_array($item) || ! isset($item['due_at'], $item['fire_at']) || ! is_string($item['due_at'])) {
continue;
}
try {
$due = DueAtParser::parse($item['due_at']);
} catch (InvalidArgumentException $e) {
$v->errors()->add("events.$i.due_at", $e->getMessage());
continue;
}
// Проверка fire_at <= день срока — по поясу по умолчанию; для fixed это
// приближение, точный день пользователя известен только при upsert.
if ($v->errors()->missing("events.$i.fire_at") && $item['fire_at'] > $due->dayFor(config('hado.default_tz'))) {
$v->errors()->add("events.$i.fire_at", 'fire_at не может быть позже дня срока');
}
}
}];
}
/** @return list<array<string,mixed>> */
public function items(): array
{
return array_map(function (array $item) {
$item['topic'] = (string) ($item['topic'] ?? '');
return $item;
}, $this->validated()['events']);
}
}