Backup #1226

ID1226
Dateipfad/var/www/dev.campus.systemische-tools.de/src/Domain/DTO/SessionStatsDTO.php
Version2
Typ modified
Größe3.9 KB
Hash976694e4771e3a9d4e09308ee9c6b8b34a29dd880af277d3cbc0130108692f7c
Datum2025-12-25 10:50:43
Geändert vonclaude-code-hook
GrundClaude Code Pre-Hook Backup vor Edit-Operation
Datei existiert Ja

Dateiinhalt

<?php

declare(strict_types=1);

namespace Domain\DTO;

// @responsibility: DTO für Chat-Session-Statistiken

final readonly class SessionStatsDTO
{
    /**
     * @param array<string> $collections
     */
    public function __construct(
        public int $id,
        public string $uuid,
        public ?string $title,
        public string $model,
        public array $collections,
        public int $contextLimit,
        public int $messageCount,
        public int $totalTokensInput,
        public int $totalTokensOutput,
        public float $totalCostUsd,
        public \DateTimeImmutable $createdAt,
        public \DateTimeImmutable $lastActivity,
        public ?int $authorProfileId = null,
    ) {}

    /**
     * Create from database row with aggregated stats.
     *
     * @param array<string, mixed> $row
     */
    public static function fromDatabaseRow(array $row): self
    {
        $id = isset($row['id']) ? (int) $row['id'] : 0;
        $uuid = isset($row['uuid']) ? (string) $row['uuid'] : '';
        $title = isset($row['title']) ? (string) $row['title'] : null;
        $model = isset($row['model']) ? (string) $row['model'] : 'unknown';
        $collections = self::parseCollections($row['collections'] ?? '');
        $contextLimit = isset($row['context_limit']) ? (int) $row['context_limit'] : 3;
        $messageCount = isset($row['message_count']) ? (int) $row['message_count'] : 0;
        $totalTokensInput = isset($row['total_tokens_input']) ? (int) $row['total_tokens_input'] : 0;
        $totalTokensOutput = isset($row['total_tokens_output']) ? (int) $row['total_tokens_output'] : 0;
        $totalCostUsd = isset($row['total_cost_usd']) ? (float) $row['total_cost_usd'] : 0.0;

        $createdAtStr = isset($row['created_at']) ? (string) $row['created_at'] : 'now';
        $lastActivityStr = isset($row['last_activity'])
            ? (string) $row['last_activity']
            : (isset($row['created_at']) ? (string) $row['created_at'] : 'now');

        $authorProfileId = isset($row['author_profile_id']) ? (int) $row['author_profile_id'] : null;

        return new self(
            id: $id,
            uuid: $uuid,
            title: $title,
            model: $model,
            collections: $collections,
            contextLimit: $contextLimit,
            messageCount: $messageCount,
            totalTokensInput: $totalTokensInput,
            totalTokensOutput: $totalTokensOutput,
            totalCostUsd: $totalCostUsd,
            createdAt: new \DateTimeImmutable($createdAtStr),
            lastActivity: new \DateTimeImmutable($lastActivityStr),
            authorProfileId: $authorProfileId,
        );
    }

    /**
     * Parse comma-separated collections or JSON array.
     *
     * @return array<string>
     */
    private static function parseCollections(mixed $collections): array
    {
        if (is_array($collections)) {
            return array_map('strval', $collections);
        }

        $collectionsStr = is_string($collections) ? $collections : '';

        if ($collectionsStr === '') {
            return [];
        }

        $decoded = json_decode($collectionsStr, true);
        if (is_array($decoded)) {
            return array_map('strval', $decoded);
        }

        return array_values(array_filter(array_map('trim', explode(',', $collectionsStr))));
    }

    /**
     * Get total tokens used.
     */
    public function totalTokens(): int
    {
        return $this->totalTokensInput + $this->totalTokensOutput;
    }

    /**
     * Get display title (with fallback).
     */
    public function displayTitle(): string
    {
        return $this->title ?? 'Chat vom ' . $this->createdAt->format('d.m.Y H:i');
    }

    /**
     * Check if session is active (has recent activity).
     */
    public function isRecentlyActive(int $hoursThreshold = 24): bool
    {
        $threshold = new \DateTimeImmutable("-{$hoursThreshold} hours");
        return $this->lastActivity > $threshold;
    }
}

Vollständig herunterladen

Aktionen

Herunterladen

Andere Versionen dieser Datei

ID Version Typ Größe Datum
1890 4 modified 4.0 KB 2025-12-28 01:01
1886 3 modified 4.0 KB 2025-12-28 01:00
1226 2 modified 3.9 KB 2025-12-25 10:50
1221 1 modified 2.9 KB 2025-12-25 10:49

← Zurück zur Übersicht