<?php
declare(strict_types=1);
namespace Domain\DTO;
// @responsibility: DTO für Content-Version-Daten aus Repository
final readonly class ContentVersionDTO
{
public function __construct(
public int $id,
public int $orderId,
public int $versionNumber,
public string $content,
public string $model,
public int $tokensInput,
public int $tokensOutput,
public float $costUsd,
public int $durationMs,
public \DateTimeImmutable $createdAt,
public ?string $title = null,
) {}
/**
* Create from database row.
*
* @param array<string, mixed> $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) . '...';
}
}