Backup #794

ID794
Dateipfad/var/www/dev.campus.systemische-tools.de/src/Infrastructure/Validation/CollectionValidator.php
Version1
Typ modified
Größe4.7 KB
Hash92a6e963198335922b637a483ccd6a831e8814691d1adce673257f87fbae60dd
Datum2025-12-23 08:06:28
Geändert vonclaude-code-hook
GrundClaude Code Pre-Hook Backup vor Edit-Operation
Datei existiert Ja

Dateiinhalt

<?php

declare(strict_types=1);

namespace Infrastructure\Validation;

use Infrastructure\Persistence\CollectionRepository;

/**
 * Validator for RAG collection compatibility.
 *
 * Ensures that:
 * - Selected collections have compatible vector sizes
 * - Embedding dimensions match collection requirements
 *
 * @package Infrastructure\Validation
 */
final class CollectionValidator
{
    public function __construct(
        private CollectionRepository $repository
    ) {
    }

    /**
     * Validate that all selected collections have compatible vector sizes.
     *
     * Returns ValidationResult with vector_size as data if valid.
     *
     * @param array<string> $collectionIds Array of collection_id values
     */
    public function validateSelection(array $collectionIds): ValidationResult
    {
        if (count($collectionIds) === 0) {
            return ValidationResult::ok();
        }

        $collections = $this->repository->findByIds($collectionIds);

        // Check all collections exist
        $foundIds = array_column($collections, 'collection_id');
        $missing = array_diff($collectionIds, $foundIds);
        if (!empty($missing)) {
            return ValidationResult::error(
                'Collections nicht gefunden: ' . implode(', ', $missing)
            );
        }

        // Check all have same vector_size
        $vectorSizes = array_unique(array_column($collections, 'vector_size'));

        if (count($vectorSizes) > 1) {
            $details = [];
            foreach ($collections as $col) {
                $details[] = "{$col['display_name']}: {$col['vector_size']}d";
            }

            return ValidationResult::error(
                'Inkompatible Collections: Unterschiedliche Vektorgrößen ('
                . implode(', ', $details) . ')'
            );
        }

        return ValidationResult::ok((int) ($vectorSizes[0] ?? 0));
    }

    /**
     * Validate that an embedding vector matches the expected collection dimension.
     *
     * @param string       $collectionId The collection to check against
     * @param array<float> $embedding    The embedding vector
     */
    public function validateEmbedding(string $collectionId, array $embedding): ValidationResult
    {
        $collection = $this->repository->find($collectionId);

        if ($collection === null) {
            return ValidationResult::error(
                "Collection '$collectionId' nicht gefunden"
            );
        }

        $expectedSize = (int) $collection['vector_size'];
        $actualSize = count($embedding);

        if ($expectedSize !== $actualSize) {
            return ValidationResult::error(
                "Dimension Mismatch: Collection '{$collection['display_name']}' "
                . "erwartet {$expectedSize}d, Embedding hat {$actualSize}d"
            );
        }

        return ValidationResult::ok();
    }

    /**
     * Validate embedding against multiple collections.
     *
     * First validates collection compatibility, then checks embedding dimension.
     *
     * @param array<string> $collectionIds Collections to search
     * @param array<float>  $embedding     The embedding vector
     */
    public function validateSearchRequest(array $collectionIds, array $embedding): ValidationResult
    {
        // First validate collections are compatible
        $selectionResult = $this->validateSelection($collectionIds);
        if (!$selectionResult->isValid()) {
            return $selectionResult;
        }

        // Then check embedding dimension
        $expectedSize = $selectionResult->getData();
        if ($expectedSize !== null && $expectedSize > 0) {
            $actualSize = count($embedding);
            if ($expectedSize !== $actualSize) {
                return ValidationResult::error(
                    "Embedding hat {$actualSize}d, Collections erwarten {$expectedSize}d"
                );
            }
        }

        return ValidationResult::ok();
    }

    /**
     * Check if collections exist and are searchable.
     *
     * @param array<string> $collectionIds
     */
    public function validateSearchable(array $collectionIds): ValidationResult
    {
        if (empty($collectionIds)) {
            return ValidationResult::ok();
        }

        $collections = $this->repository->findByIds($collectionIds);

        foreach ($collections as $col) {
            if (!$col['is_active']) {
                return ValidationResult::error(
                    "Collection '{$col['display_name']}' ist nicht aktiv"
                );
            }
            if (!$col['is_searchable']) {
                return ValidationResult::error(
                    "Collection '{$col['display_name']}' ist nicht durchsuchbar"
                );
            }
        }

        return ValidationResult::ok();
    }
}

Vollständig herunterladen

Aktionen

Herunterladen

← Zurück zur Übersicht