*/ private array $collections = ['documents']; private int $contextLimit = 5; private float $temperature = 0.7; private int $maxTokens = 4096; private ?int $authorProfileId = null; private ?int $systemPromptId = null; private \DateTimeImmutable $createdAt; private \DateTimeImmutable $updatedAt; private \DateTimeImmutable $lastActivity; public function __construct() { $this->uuid = $this->generateUuid(); $this->createdAt = new \DateTimeImmutable(); $this->updatedAt = new \DateTimeImmutable(); $this->lastActivity = new \DateTimeImmutable(); } private function generateUuid(): string { $data = random_bytes(16); $data[6] = chr(ord($data[6]) & 0x0f | 0x40); $data[8] = chr(ord($data[8]) & 0x3f | 0x80); return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); } // Getters public function getId(): ?int { return $this->id; } public function getUuid(): string { return $this->uuid; } public function getSessionToken(): ?string { return $this->sessionToken; } public function getUserId(): ?int { return $this->userId; } public function getPersonaId(): ?int { return $this->personaId; } public function getTitle(): ?string { return $this->title; } public function getModel(): string { return $this->model; } /** * @return array */ public function getCollections(): array { return $this->collections; } public function getContextLimit(): int { return $this->contextLimit; } public function getTemperature(): float { return $this->temperature; } public function getMaxTokens(): int { return $this->maxTokens; } public function getAuthorProfileId(): ?int { return $this->authorProfileId; } public function getSystemPromptId(): ?int { return $this->systemPromptId; } public function getCreatedAt(): \DateTimeImmutable { return $this->createdAt; } public function getUpdatedAt(): \DateTimeImmutable { return $this->updatedAt; } public function getLastActivity(): \DateTimeImmutable { return $this->lastActivity; } // Setters with fluent interface public function setId(int $id): self { $this->id = $id; return $this; } public function setUuid(string $uuid): self { $this->uuid = $uuid; return $this; } public function setSessionToken(?string $sessionToken): self { $this->sessionToken = $sessionToken; return $this; } public function setUserId(?int $userId): self { $this->userId = $userId; return $this; } public function setPersonaId(?int $personaId): self { $this->personaId = $personaId; return $this; } public function setTitle(string $title): self { $this->title = $title; $this->touch(); return $this; } public function setModel(string $model): self { $this->model = $model; $this->touch(); return $this; } /** * @param array $collections */ public function setCollections(array $collections): self { $this->collections = $collections; $this->touch(); return $this; } public function setContextLimit(int $contextLimit): self { $this->contextLimit = $contextLimit; $this->touch(); return $this; } public function setTemperature(float $temperature): self { $this->temperature = $temperature; $this->touch(); return $this; } public function setMaxTokens(int $maxTokens): self { $this->maxTokens = $maxTokens; $this->touch(); return $this; } public function setAuthorProfileId(?int $authorProfileId): self { $this->authorProfileId = $authorProfileId; $this->touch(); return $this; } public function setSystemPromptId(?int $systemPromptId): self { $this->systemPromptId = $systemPromptId; $this->touch(); return $this; } public function setCreatedAt(\DateTimeImmutable $createdAt): self { $this->createdAt = $createdAt; return $this; } public function setUpdatedAt(\DateTimeImmutable $updatedAt): self { $this->updatedAt = $updatedAt; return $this; } public function setLastActivity(\DateTimeImmutable $lastActivity): self { $this->lastActivity = $lastActivity; return $this; } /** * Update timestamps on modification. */ private function touch(): void { $this->updatedAt = new \DateTimeImmutable(); $this->lastActivity = new \DateTimeImmutable(); } /** * Factory method for creating a new session. * * @param array $collections */ public static function create( string $uuid, string $model = 'claude-opus-4-5-20251101', array $collections = ['documents'], int $contextLimit = 5 ): self { $session = new self(); $session->uuid = $uuid; $session->model = $model; $session->collections = $collections; $session->contextLimit = $contextLimit; return $session; } /** * Create a copy with new ID (for post-save). */ public function withId(int $id): self { $clone = clone $this; $clone->id = $id; return $clone; } /** * Update settings in one call. */ public function updateSettings( string $model, array $collections, int $contextLimit, ?int $authorProfileId, float $temperature, int $maxTokens ): self { $this->model = $model; $this->collections = $collections; $this->contextLimit = $contextLimit; $this->authorProfileId = $authorProfileId; $this->temperature = $temperature; $this->maxTokens = $maxTokens; $this->touch(); return $this; } /** * Convert to array for persistence. * * @return array */ public function toArray(): array { return [ 'id' => $this->id, 'uuid' => $this->uuid, 'session_token' => $this->sessionToken, 'user_id' => $this->userId, 'persona_id' => $this->personaId, 'title' => $this->title, 'model' => $this->model, 'collections' => json_encode($this->collections), 'context_limit' => $this->contextLimit, 'temperature' => $this->temperature, 'max_tokens' => $this->maxTokens, 'author_profile_id' => $this->authorProfileId, 'system_prompt_id' => $this->systemPromptId, 'created_at' => $this->createdAt->format('Y-m-d H:i:s'), 'updated_at' => $this->updatedAt->format('Y-m-d H:i:s'), 'last_activity' => $this->lastActivity->format('Y-m-d H:i:s'), ]; } /** * Create from database row. * * @param array $data */ public static function fromArray(array $data): self { $session = new self(); if (isset($data['id'])) { $session->setId((int) $data['id']); } if (isset($data['uuid'])) { $session->setUuid($data['uuid']); } if (isset($data['session_token'])) { $session->setSessionToken($data['session_token']); } if (isset($data['user_id'])) { $session->setUserId((int) $data['user_id']); } if (isset($data['persona_id'])) { $session->setPersonaId((int) $data['persona_id']); } if (isset($data['title'])) { $session->title = $data['title']; } if (isset($data['model'])) { $session->model = $data['model']; } if (isset($data['collections'])) { $collections = is_string($data['collections']) ? json_decode($data['collections'], true) : $data['collections']; $session->collections = is_array($collections) ? $collections : ['documents']; } if (isset($data['context_limit'])) { $session->contextLimit = (int) $data['context_limit']; } if (isset($data['temperature'])) { $session->temperature = (float) $data['temperature']; } if (isset($data['max_tokens'])) { $session->maxTokens = (int) $data['max_tokens']; } if (isset($data['author_profile_id'])) { $session->authorProfileId = (int) $data['author_profile_id']; } if (isset($data['system_prompt_id'])) { $session->systemPromptId = (int) $data['system_prompt_id']; } if (isset($data['created_at'])) { $session->createdAt = new \DateTimeImmutable($data['created_at']); } if (isset($data['updated_at'])) { $session->updatedAt = new \DateTimeImmutable($data['updated_at']); } if (isset($data['last_activity'])) { $session->lastActivity = new \DateTimeImmutable($data['last_activity']); } return $session; } }