$row */ public static function fromDatabaseRow(array $row): self { return new self( id: (int) $row['id'], orderId: (int) $row['order_id'], versionNumber: (int) $row['version_number'], content: (string) $row['content'], model: (string) ($row['model'] ?? 'unknown'), tokensInput: (int) ($row['tokens_input'] ?? 0), tokensOutput: (int) ($row['tokens_output'] ?? 0), costUsd: (float) ($row['cost_usd'] ?? 0.0), durationMs: (int) ($row['duration_ms'] ?? 0), createdAt: new \DateTimeImmutable($row['created_at'] ?? 'now'), title: $row['title'] ?? null, ); } /** * Get total tokens used. */ public function totalTokens(): int { return $this->tokensInput + $this->tokensOutput; } /** * Get content preview (first N characters). */ public function preview(int $length = 200): string { if (mb_strlen($this->content) <= $length) { return $this->content; } return mb_substr($this->content, 0, $length) . '...'; } }