fix(training): use KURRENT_RECOGNITION label for sender-based block queries #378

Merged
marcel merged 2 commits from fix/sender-training-use-kurrent-label into main 2026-05-04 15:26:05 +02:00
2 changed files with 108 additions and 3 deletions

View File

@@ -65,7 +65,7 @@ public interface TranscriptionBlockRepository extends JpaRepository<Transcriptio
JOIN Document d ON d.id = b.documentId JOIN Document d ON d.id = b.documentId
WHERE b.source = 'MANUAL' WHERE b.source = 'MANUAL'
AND d.sender.id = :personId AND d.sender.id = :personId
AND d.scriptType = 'HANDWRITING_KURRENT' AND 'KURRENT_RECOGNITION' MEMBER OF d.trainingLabels
""") """)
long countManualKurrentBlocksByPerson(@Param("personId") UUID personId); long countManualKurrentBlocksByPerson(@Param("personId") UUID personId);
@@ -74,7 +74,7 @@ public interface TranscriptionBlockRepository extends JpaRepository<Transcriptio
JOIN Document d ON d.id = b.documentId JOIN Document d ON d.id = b.documentId
WHERE b.source = 'MANUAL' WHERE b.source = 'MANUAL'
AND d.sender.id = :personId AND d.sender.id = :personId
AND d.scriptType = 'HANDWRITING_KURRENT' AND 'KURRENT_RECOGNITION' MEMBER OF d.trainingLabels
""") """)
List<TranscriptionBlock> findManualKurrentBlocksByPerson(@Param("personId") UUID personId); List<TranscriptionBlock> findManualKurrentBlocksByPerson(@Param("personId") UUID personId);
} }

View File

@@ -11,6 +11,7 @@ import org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabas
import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@@ -24,6 +25,7 @@ class TrainingBlockQueryTest {
@Autowired TranscriptionBlockRepository blockRepository; @Autowired TranscriptionBlockRepository blockRepository;
@Autowired DocumentRepository documentRepository; @Autowired DocumentRepository documentRepository;
@Autowired AnnotationRepository annotationRepository; @Autowired AnnotationRepository annotationRepository;
@Autowired PersonRepository personRepository;
private UUID kurrentDocId; private UUID kurrentDocId;
private UUID typewriterDocId; private UUID typewriterDocId;
@@ -36,7 +38,7 @@ class TrainingBlockQueryTest {
.title("Kurrent Brief") .title("Kurrent Brief")
.originalFilename("kurrent.pdf") .originalFilename("kurrent.pdf")
.status(DocumentStatus.UPLOADED) .status(DocumentStatus.UPLOADED)
.trainingLabels(new java.util.HashSet<>(Set.of(TrainingLabel.KURRENT_RECOGNITION))) .trainingLabels(new HashSet<>(Set.of(TrainingLabel.KURRENT_RECOGNITION)))
.build()); .build());
kurrentDocId = kurrentDoc.getId(); kurrentDocId = kurrentDoc.getId();
@@ -111,6 +113,109 @@ class TrainingBlockQueryTest {
assertThat(result).hasSize(2); assertThat(result).hasSize(2);
} }
// ─── sender-based queries ─────────────────────────────────────────────────
@Test
void findManualKurrentBlocksByPerson_includesBlockFromKurrentLabelledDocument() {
Person sender = personRepository.save(Person.builder().firstName("Karl").lastName("Test").build());
Document doc = documentRepository.save(Document.builder()
.title("Brief von Karl")
.originalFilename("karl.pdf")
.status(DocumentStatus.UPLOADED)
.sender(sender)
.trainingLabels(new HashSet<>(Set.of(TrainingLabel.KURRENT_RECOGNITION)))
.build());
UUID annId = annotationRepository.save(annotation(doc.getId())).getId();
blockRepository.save(block(doc.getId(), annId, BlockSource.MANUAL, false));
List<TranscriptionBlock> result = blockRepository.findManualKurrentBlocksByPerson(sender.getId());
assertThat(result).hasSize(1);
}
@Test
void findManualKurrentBlocksByPerson_excludesDocumentWithoutKurrentLabel() {
Person sender = personRepository.save(Person.builder().firstName("Karl").lastName("Test").build());
Document doc = documentRepository.save(Document.builder()
.title("Brief von Karl")
.originalFilename("karl.pdf")
.status(DocumentStatus.UPLOADED)
.sender(sender)
.build());
UUID annId = annotationRepository.save(annotation(doc.getId())).getId();
blockRepository.save(block(doc.getId(), annId, BlockSource.MANUAL, false));
List<TranscriptionBlock> result = blockRepository.findManualKurrentBlocksByPerson(sender.getId());
assertThat(result).isEmpty();
}
@Test
void findManualKurrentBlocksByPerson_excludesOcrBlocks() {
Person sender = personRepository.save(Person.builder().firstName("Karl").lastName("Test").build());
Document doc = documentRepository.save(Document.builder()
.title("Brief von Karl")
.originalFilename("karl.pdf")
.status(DocumentStatus.UPLOADED)
.sender(sender)
.trainingLabels(new HashSet<>(Set.of(TrainingLabel.KURRENT_RECOGNITION)))
.build());
UUID annId = annotationRepository.save(annotation(doc.getId())).getId();
blockRepository.save(block(doc.getId(), annId, BlockSource.OCR, false));
List<TranscriptionBlock> result = blockRepository.findManualKurrentBlocksByPerson(sender.getId());
assertThat(result).isEmpty();
}
@Test
void findManualKurrentBlocksByPerson_excludesOtherSender() {
Person karl = personRepository.save(Person.builder().firstName("Karl").lastName("Test").build());
Person anna = personRepository.save(Person.builder().firstName("Anna").lastName("Test").build());
Document doc = documentRepository.save(Document.builder()
.title("Brief von Karl")
.originalFilename("karl.pdf")
.status(DocumentStatus.UPLOADED)
.sender(karl)
.trainingLabels(new HashSet<>(Set.of(TrainingLabel.KURRENT_RECOGNITION)))
.build());
UUID annId = annotationRepository.save(annotation(doc.getId())).getId();
blockRepository.save(block(doc.getId(), annId, BlockSource.MANUAL, false));
List<TranscriptionBlock> result = blockRepository.findManualKurrentBlocksByPerson(anna.getId());
assertThat(result).isEmpty();
}
@Test
void countManualKurrentBlocksByPerson_matchesFindResult() {
Person sender = personRepository.save(Person.builder().firstName("Karl").lastName("Test").build());
Document doc = documentRepository.save(Document.builder()
.title("Brief von Karl")
.originalFilename("karl.pdf")
.status(DocumentStatus.UPLOADED)
.sender(sender)
.trainingLabels(new HashSet<>(Set.of(TrainingLabel.KURRENT_RECOGNITION)))
.build());
UUID annId = annotationRepository.save(annotation(doc.getId())).getId();
blockRepository.save(block(doc.getId(), annId, BlockSource.MANUAL, false));
blockRepository.save(block(doc.getId(), annId, BlockSource.MANUAL, true));
long count = blockRepository.countManualKurrentBlocksByPerson(sender.getId());
List<TranscriptionBlock> found = blockRepository.findManualKurrentBlocksByPerson(sender.getId());
assertThat(count).isEqualTo(found.size());
}
@Test
void countManualKurrentBlocksByPerson_returnsZeroWhenNoBlocksMatch() {
Person sender = personRepository.save(Person.builder().firstName("Karl").lastName("Test").build());
long count = blockRepository.countManualKurrentBlocksByPerson(sender.getId());
assertThat(count).isZero();
}
// ─── helpers ───────────────────────────────────────────────────────────── // ─── helpers ─────────────────────────────────────────────────────────────
private DocumentAnnotation annotation(UUID docId) { private DocumentAnnotation annotation(UUID docId) {