refactor(ocr): route block lifecycle through TranscriptionService
OcrAsyncRunner was bypassing TranscriptionService — building blocks directly and calling blockRepository.save(), skipping sanitizeText() and saveVersion(). Also replaced N individual deleteBlock() calls with a single bulk deleteAllBlocksByDocument() for OCR re-runs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,6 @@ import org.raddatz.familienarchiv.dto.CreateAnnotationDTO;
|
||||
import org.raddatz.familienarchiv.model.*;
|
||||
import org.raddatz.familienarchiv.repository.OcrJobDocumentRepository;
|
||||
import org.raddatz.familienarchiv.repository.OcrJobRepository;
|
||||
import org.raddatz.familienarchiv.repository.TranscriptionBlockRepository;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -26,7 +25,6 @@ public class OcrAsyncRunner {
|
||||
private final DocumentService documentService;
|
||||
private final TranscriptionService transcriptionService;
|
||||
private final AnnotationService annotationService;
|
||||
private final TranscriptionBlockRepository blockRepository;
|
||||
private final FileService fileService;
|
||||
private final OcrJobRepository ocrJobRepository;
|
||||
private final OcrJobDocumentRepository ocrJobDocumentRepository;
|
||||
@@ -194,10 +192,7 @@ public class OcrAsyncRunner {
|
||||
}
|
||||
|
||||
private void clearExistingBlocks(UUID documentId) {
|
||||
List<TranscriptionBlock> existing = transcriptionService.listBlocks(documentId);
|
||||
for (TranscriptionBlock block : existing) {
|
||||
transcriptionService.deleteBlock(documentId, block.getId());
|
||||
}
|
||||
transcriptionService.deleteAllBlocksByDocument(documentId);
|
||||
}
|
||||
|
||||
private void createTranscriptionBlocks(UUID documentId, List<OcrBlockResult> blocks,
|
||||
@@ -216,15 +211,7 @@ public class OcrAsyncRunner {
|
||||
DocumentAnnotation annotation = annotationService.createOcrAnnotation(
|
||||
documentId, annotationDTO, userId, fileHash, block.polygon());
|
||||
|
||||
TranscriptionBlock transcriptionBlock = TranscriptionBlock.builder()
|
||||
.annotationId(annotation.getId())
|
||||
.documentId(documentId)
|
||||
.text(block.text() != null ? block.text() : "")
|
||||
.sortOrder(sortOrder)
|
||||
.source(BlockSource.OCR)
|
||||
.createdBy(userId)
|
||||
.updatedBy(userId)
|
||||
.build();
|
||||
blockRepository.save(transcriptionBlock);
|
||||
transcriptionService.createOcrBlock(documentId, annotation.getId(),
|
||||
block.text(), sortOrder, userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.raddatz.familienarchiv.dto.ReorderTranscriptionBlocksDTO;
|
||||
import org.raddatz.familienarchiv.dto.UpdateTranscriptionBlockDTO;
|
||||
import org.raddatz.familienarchiv.exception.DomainException;
|
||||
import org.raddatz.familienarchiv.exception.ErrorCode;
|
||||
import org.raddatz.familienarchiv.model.BlockSource;
|
||||
import org.raddatz.familienarchiv.model.Document;
|
||||
import org.raddatz.familienarchiv.model.DocumentAnnotation;
|
||||
import org.raddatz.familienarchiv.model.TranscriptionBlock;
|
||||
@@ -75,6 +76,24 @@ public class TranscriptionService {
|
||||
return saved;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public TranscriptionBlock createOcrBlock(UUID documentId, UUID annotationId,
|
||||
String text, int sortOrder, UUID userId) {
|
||||
String sanitized = sanitizeText(text);
|
||||
TranscriptionBlock block = TranscriptionBlock.builder()
|
||||
.annotationId(annotationId)
|
||||
.documentId(documentId)
|
||||
.text(sanitized)
|
||||
.sortOrder(sortOrder)
|
||||
.source(BlockSource.OCR)
|
||||
.createdBy(userId)
|
||||
.updatedBy(userId)
|
||||
.build();
|
||||
TranscriptionBlock saved = blockRepository.save(block);
|
||||
saveVersion(saved, userId);
|
||||
return saved;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public TranscriptionBlock updateBlock(UUID documentId, UUID blockId,
|
||||
UpdateTranscriptionBlockDTO dto, UUID userId) {
|
||||
@@ -106,6 +125,21 @@ public class TranscriptionService {
|
||||
blockId, annotationId, documentId);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteAllBlocksByDocument(UUID documentId) {
|
||||
List<TranscriptionBlock> blocks = blockRepository.findByDocumentIdOrderBySortOrderAsc(documentId);
|
||||
if (blocks.isEmpty()) return;
|
||||
|
||||
List<UUID> annotationIds = blocks.stream()
|
||||
.map(TranscriptionBlock::getAnnotationId)
|
||||
.toList();
|
||||
|
||||
blockRepository.deleteAll(blocks);
|
||||
blockRepository.flush();
|
||||
annotationRepository.deleteAllById(annotationIds);
|
||||
log.info("Bulk-deleted {} transcription blocks for document {}", blocks.size(), documentId);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void reorderBlocks(UUID documentId, ReorderTranscriptionBlocksDTO dto) {
|
||||
List<UUID> blockIds = dto.getBlockIds();
|
||||
|
||||
Reference in New Issue
Block a user