$data */ public function __construct( private array $data = [], private ?string $userId = null, private ?string $environment = null, private ?UserAgent $userAgent = null, private ?IpAddress $ipAddress = null ) { } public function getValue(string $key): mixed { return match($key) { 'user_id' => $this->userId, 'environment' => $this->environment, 'user_agent' => $this->userAgent?->value, 'ip_address' => $this->ipAddress?->value, default => $this->data[$key] ?? null, }; } public function getUserId(): ?string { return $this->userId; } public function getEnvironment(): ?string { return $this->environment; } public function getUserAgent(): ?UserAgent { return $this->userAgent; } public function getIpAddress(): ?IpAddress { return $this->ipAddress; } public function withUserId(string $userId): self { return new self( $this->data, $userId, $this->environment, $this->userAgent, $this->ipAddress ); } public function withEnvironment(string $environment): self { return new self( $this->data, $this->userId, $environment, $this->userAgent, $this->ipAddress ); } public function withUserAgent(UserAgent $userAgent): self { return new self( $this->data, $this->userId, $this->environment, $userAgent, $this->ipAddress ); } public function withIpAddress(IpAddress $ipAddress): self { return new self( $this->data, $this->userId, $this->environment, $this->userAgent, $ipAddress ); } public function withData(array $data): self { return new self( array_merge($this->data, $data), $this->userId, $this->environment, $this->userAgent, $this->ipAddress ); } public function with(string $key, mixed $value): self { return $this->withData([$key => $value]); } }