'required|integer', 'school_year' => 'required|regex_match[/^\d{4}-\d{4}$/]|max_length[9]', 'accepted_at' => 'required|valid_date[Y-m-d H:i:s]', 'source' => 'required|max_length[40]', 'ip_address' => 'permit_empty|max_length[45]', 'user_agent' => 'permit_empty|max_length[255]', ]; public function hasAccepted(int $parentId, string $schoolYear): bool { return $this->where('parent_id', $parentId) ->where('school_year', $schoolYear) ->first() !== null; } public function recordAcceptance( int $parentId, string $schoolYear, string $source, ?string $ipAddress = null, ?string $userAgent = null ): bool { $payload = [ 'parent_id' => $parentId, 'school_year' => $schoolYear, 'accepted_at' => utc_now(), 'source' => $source, 'ip_address' => $ipAddress, 'user_agent' => $userAgent !== null ? substr($userAgent, 0, 255) : null, ]; $existing = $this->where('parent_id', $parentId) ->where('school_year', $schoolYear) ->first(); if ($existing !== null) { return $this->update((int) $existing[$this->primaryKey], $payload) !== false; } return $this->insert($payload) !== false; } }