*/ public const LEVELS = ['warning', 'error']; public function authorize(): bool { return true; } /** * @return array|string> */ public function rules(): array { return [ 'appVersion' => ['nullable', 'string', 'max:40'], 'sessionId' => ['nullable', 'string', 'max:64'], 'userAgent' => ['nullable', 'string', 'max:400'], 'entries' => ['required', 'array', 'min:1', 'max:50'], 'entries.*.level' => ['required', 'string', 'in:'.implode(',', self::LEVELS)], 'entries.*.scope' => ['required', 'string', 'max:60'], 'entries.*.message' => ['required', 'string', 'max:1000'], 'entries.*.url' => ['nullable', 'string', 'max:500'], 'entries.*.occurredAt' => ['required', 'date'], 'entries.*.context' => ['nullable', 'array', 'max:20'], // Context values are flat: a status code, a path, a message. Nested // structures are stringified by the client before sending. 'entries.*.context.*' => ['nullable', new ScalarSetting(500)], ]; } }