AssignEntityTaxonomyUseCase.php
- Pfad:
src/UseCases/Taxonomy/AssignEntityTaxonomyUseCase.php - Namespace: UseCases\Taxonomy
- Zeilen: 174 | Größe: 5,334 Bytes
- Geändert: 2025-12-27 23:22:46 | Gescannt: 2025-12-31 10:22:15
Code Hygiene Score: 88
- Dependencies: 80 (25%)
- LOC: 63 (20%)
- Methods: 100 (20%)
- Secrets: 100 (15%)
- Classes: 100 (10%)
- Magic Numbers: 100 (10%)
Keine Issues gefunden.
Dependencies 11
- constructor Domain\Repository\EntityTaxonomyRepositoryInterface
- constructor Domain\Repository\EntityRepositoryInterface
- constructor Domain\Repository\TaxonomyRepositoryInterface
- constructor Infrastructure\Audit\AuditService
- use Domain\Constants
- use Domain\Entity\EntityTaxonomyMapping
- use Domain\Repository\EntityRepositoryInterface
- use Domain\Repository\EntityTaxonomyRepositoryInterface
- use Domain\Repository\TaxonomyRepositoryInterface
- use Domain\ValueObject\Confidence
- use Infrastructure\Audit\AuditService
Klassen 1
-
AssignEntityTaxonomyUseCaseclass Zeile 17
Funktionen 8
-
__construct()public Zeile 19 -
execute()public Zeile 32 -
validateMapping()Zeile 77 -
batchAssign()Zeile 115 -
getValidationStats()Zeile 144 -
validateEntity()Zeile 149 -
validateTaxonomyTerm()Zeile 157 -
validateRelevance()Zeile 165
Versionen 2
-
v2
2025-12-27 23:22 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v1
2025-12-27 23:22 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
Code
<?php
declare(strict_types=1);
namespace UseCases\Taxonomy;
// @responsibility: Manuelle und automatische Entity-Taxonomie-Zuweisung
use Domain\Constants;
use Domain\Entity\EntityTaxonomyMapping;
use Domain\Repository\EntityRepositoryInterface;
use Domain\Repository\EntityTaxonomyRepositoryInterface;
use Domain\Repository\TaxonomyRepositoryInterface;
use Domain\ValueObject\Confidence;
use Infrastructure\Audit\AuditService;
final class AssignEntityTaxonomyUseCase
{
public function __construct(
private EntityTaxonomyRepositoryInterface $entityTaxonomyRepository,
private EntityRepositoryInterface $entityRepository,
private TaxonomyRepositoryInterface $taxonomyRepository,
private AuditService $auditService
) {
}
/**
* Assign a taxonomy term to an entity.
*
* @throws \InvalidArgumentException if validation fails
*/
public function execute(
int $entityId,
int $taxonomyTermId,
float $relevance
): int {
$this->validateEntity($entityId);
$this->validateTaxonomyTerm($taxonomyTermId);
$this->validateRelevance($relevance);
// Check if mapping already exists
if ($this->entityTaxonomyRepository->exists($entityId, $taxonomyTermId)) {
throw new \InvalidArgumentException(
"Mapping already exists for entity {$entityId} and term {$taxonomyTermId}"
);
}
$mapping = new EntityTaxonomyMapping();
$mapping->setEntityId($entityId);
$mapping->setTaxonomyTermId($taxonomyTermId);
$mapping->setRelevance(Confidence::fromFloat($relevance));
$mapping->setValidated(false);
$id = $this->entityTaxonomyRepository->save($mapping);
$this->auditService->logCreate(
table: 'entity_taxonomy_mapping',
id: $id,
data: [
'entity_id' => $entityId,
'taxonomy_term_id' => $taxonomyTermId,
'relevance' => $relevance,
'validated' => false,
],
actor: 'system',
actorType: 'pipeline'
);
return $id;
}
/**
* Validate an existing mapping (mark as human-verified).
*
* @throws \InvalidArgumentException if mapping not found
*/
public function validateMapping(int $mappingId): void
{
$mappings = $this->entityTaxonomyRepository->getUnvalidatedMappings(Constants::BATCH_LIMIT);
$found = null;
foreach ($mappings as $mapping) {
if ($mapping->getId() === $mappingId) {
$found = $mapping;
break;
}
}
if ($found === null) {
// Check if mapping exists at all
$result = $this->entityTaxonomyRepository->markAsValidated($mappingId);
if (!$result) {
throw new \InvalidArgumentException("Mapping {$mappingId} not found");
}
} else {
$this->entityTaxonomyRepository->markAsValidated($mappingId);
}
$this->auditService->logUpdate(
table: 'entity_taxonomy_mapping',
id: $mappingId,
oldData: ['validated' => false],
newData: ['validated' => true],
actor: 'user',
actorType: 'user'
);
}
/**
* Batch assign taxonomy terms to entities.
*
* @param array<array{entity_id: int, taxonomy_term_id: int, relevance: float}> $assignments
* @return array{success: int, errors: array<string>}
*/
public function batchAssign(array $assignments): array
{
$successCount = 0;
$errors = [];
foreach ($assignments as $index => $assignment) {
try {
$this->execute(
entityId: $assignment['entity_id'],
taxonomyTermId: $assignment['taxonomy_term_id'],
relevance: $assignment['relevance']
);
$successCount++;
} catch (\Exception $e) {
$errors[] = "Assignment {$index}: " . $e->getMessage();
}
}
return [
'success' => $successCount,
'errors' => $errors,
];
}
/**
* Get validation statistics.
*
* @return array{total: int, validated: int, pending: int}
*/
public function getValidationStats(): array
{
return $this->entityTaxonomyRepository->getValidationStats();
}
private function validateEntity(int $entityId): void
{
$entity = $this->entityRepository->find($entityId);
if ($entity === null) {
throw new \InvalidArgumentException("Entity {$entityId} not found");
}
}
private function validateTaxonomyTerm(int $termId): void
{
$term = $this->taxonomyRepository->find($termId);
if ($term === null) {
throw new \InvalidArgumentException("Taxonomy term {$termId} not found");
}
}
private function validateRelevance(float $relevance): void
{
if ($relevance < 0.0 || $relevance > 1.0) {
throw new \InvalidArgumentException(
"Relevance must be between 0.0 and 1.0, got {$relevance}"
);
}
}
}