feat(audit): instrument TranscriptionService for TEXT_SAVED and BLOCK_REVIEWED
- reviewBlock: add userId param; log BLOCK_REVIEWED only on false→true - updateBlock: log TEXT_SAVED only when text actually changes; include pageNumber in payload (resolved from annotation) - Both events deferred via afterCommit() when inside a transaction - Update TranscriptionBlockController to pass user to reviewBlock() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -85,8 +85,10 @@ public class TranscriptionBlockController {
|
||||
@RequirePermission(Permission.WRITE_ALL)
|
||||
public TranscriptionBlock reviewBlock(
|
||||
@PathVariable UUID documentId,
|
||||
@PathVariable UUID blockId) {
|
||||
return transcriptionService.reviewBlock(documentId, blockId);
|
||||
@PathVariable UUID blockId,
|
||||
Authentication authentication) {
|
||||
UUID userId = requireUserId(authentication);
|
||||
return transcriptionService.reviewBlock(documentId, blockId, userId);
|
||||
}
|
||||
|
||||
@GetMapping("/{blockId}/history")
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.raddatz.familienarchiv.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.raddatz.familienarchiv.audit.AuditKind;
|
||||
import org.raddatz.familienarchiv.audit.AuditService;
|
||||
import org.raddatz.familienarchiv.dto.CreateAnnotationDTO;
|
||||
import org.raddatz.familienarchiv.dto.CreateTranscriptionBlockDTO;
|
||||
import org.raddatz.familienarchiv.dto.ReorderTranscriptionBlocksDTO;
|
||||
@@ -19,8 +21,12 @@ import org.raddatz.familienarchiv.repository.TranscriptionBlockRepository;
|
||||
import org.raddatz.familienarchiv.repository.TranscriptionBlockVersionRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
@@ -37,6 +43,7 @@ public class TranscriptionService {
|
||||
private final AnnotationService annotationService;
|
||||
private final DocumentService documentService;
|
||||
private final SenderModelService senderModelService;
|
||||
private final AuditService auditService;
|
||||
|
||||
public List<TranscriptionBlock> listBlocks(UUID documentId) {
|
||||
return blockRepository.findByDocumentIdOrderBySortOrderAsc(documentId);
|
||||
@@ -122,6 +129,7 @@ public class TranscriptionService {
|
||||
UpdateTranscriptionBlockDTO dto, UUID userId) {
|
||||
TranscriptionBlock block = getBlock(documentId, blockId);
|
||||
|
||||
String previousText = block.getText();
|
||||
String text = sanitizeText(dto.getText());
|
||||
block.setText(text);
|
||||
block.setSource(BlockSource.MANUAL);
|
||||
@@ -133,6 +141,12 @@ public class TranscriptionService {
|
||||
TranscriptionBlock saved = blockRepository.save(block);
|
||||
saveVersion(saved, userId);
|
||||
|
||||
if (!text.equals(previousText)) {
|
||||
Optional<DocumentAnnotation> annotation = annotationRepository.findById(block.getAnnotationId());
|
||||
int pageNumber = annotation.map(DocumentAnnotation::getPageNumber).orElse(0);
|
||||
logAfterCommit(AuditKind.TEXT_SAVED, userId, documentId, Map.of("pageNumber", pageNumber));
|
||||
}
|
||||
|
||||
Document doc = documentService.getDocumentById(documentId);
|
||||
if (doc.getSender() != null && doc.getScriptType() == ScriptType.HANDWRITING_KURRENT) {
|
||||
senderModelService.checkAndTriggerTraining(doc.getSender().getId());
|
||||
@@ -181,10 +195,15 @@ public class TranscriptionService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public TranscriptionBlock reviewBlock(UUID documentId, UUID blockId) {
|
||||
public TranscriptionBlock reviewBlock(UUID documentId, UUID blockId, UUID userId) {
|
||||
TranscriptionBlock block = getBlock(documentId, blockId);
|
||||
block.setReviewed(!block.isReviewed());
|
||||
return blockRepository.save(block);
|
||||
boolean wasReviewed = block.isReviewed();
|
||||
block.setReviewed(!wasReviewed);
|
||||
TranscriptionBlock saved = blockRepository.save(block);
|
||||
if (!wasReviewed && saved.isReviewed()) {
|
||||
logAfterCommit(AuditKind.BLOCK_REVIEWED, userId, documentId, null);
|
||||
}
|
||||
return saved;
|
||||
}
|
||||
|
||||
public List<TranscriptionBlockVersion> getBlockHistory(UUID documentId, UUID blockId) {
|
||||
@@ -208,4 +227,17 @@ public class TranscriptionService {
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private void logAfterCommit(AuditKind kind, UUID actorId, UUID documentId, Map<String, Object> payload) {
|
||||
if (TransactionSynchronizationManager.isActualTransactionActive()) {
|
||||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||
@Override
|
||||
public void afterCommit() {
|
||||
auditService.log(kind, actorId, documentId, payload);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
auditService.log(kind, actorId, documentId, payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user