feat(ocr): add per-model history endpoints via path segments
Add findByPersonIdIsNullOrderByCreatedAtDesc + findByPersonIdOrderByCreatedAtDesc to
OcrTrainingRunRepository. Add dto/TrainingHistoryResponse. Expose
GET /api/ocr/training-info/global and GET /api/ocr/training-info/{personId} on
OcrController, both requiring ADMIN; getSenderTrainingHistory guards person existence
via PersonService and returns 404 for unknown personId.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.raddatz.familienarchiv.dto.BatchOcrDTO;
|
||||
import org.raddatz.familienarchiv.dto.OcrStatusDTO;
|
||||
import org.raddatz.familienarchiv.dto.TrainingHistoryResponse;
|
||||
import org.raddatz.familienarchiv.dto.TrainingInfoResponse;
|
||||
import org.raddatz.familienarchiv.dto.TriggerOcrDTO;
|
||||
import org.raddatz.familienarchiv.model.AppUser;
|
||||
@@ -135,6 +136,18 @@ public class OcrController {
|
||||
return ocrTrainingService.getTrainingInfo();
|
||||
}
|
||||
|
||||
@GetMapping("/api/ocr/training-info/global")
|
||||
@RequirePermission(Permission.ADMIN)
|
||||
public TrainingHistoryResponse getGlobalTrainingHistory() {
|
||||
return ocrTrainingService.getGlobalTrainingHistory();
|
||||
}
|
||||
|
||||
@GetMapping("/api/ocr/training-info/{personId}")
|
||||
@RequirePermission(Permission.ADMIN)
|
||||
public TrainingHistoryResponse getSenderTrainingHistory(@PathVariable UUID personId) {
|
||||
return ocrTrainingService.getSenderTrainingHistory(personId);
|
||||
}
|
||||
|
||||
private UUID resolveUserId(Authentication authentication) {
|
||||
if (authentication == null || !authentication.isAuthenticated()) return null;
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.raddatz.familienarchiv.dto;
|
||||
|
||||
import org.raddatz.familienarchiv.model.OcrTrainingRun;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public record TrainingHistoryResponse(
|
||||
List<OcrTrainingRun> runs,
|
||||
Map<String, String> personNames
|
||||
) {}
|
||||
@@ -19,4 +19,8 @@ public interface OcrTrainingRunRepository extends JpaRepository<OcrTrainingRun,
|
||||
boolean existsByPersonIdAndStatus(UUID personId, TrainingStatus status);
|
||||
|
||||
List<OcrTrainingRun> findTop20ByOrderByCreatedAtDesc();
|
||||
|
||||
List<OcrTrainingRun> findByPersonIdIsNullOrderByCreatedAtDesc();
|
||||
|
||||
List<OcrTrainingRun> findByPersonIdOrderByCreatedAtDesc(UUID personId);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.raddatz.familienarchiv.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.raddatz.familienarchiv.dto.TrainingHistoryResponse;
|
||||
import org.raddatz.familienarchiv.dto.TrainingInfoResponse;
|
||||
import org.raddatz.familienarchiv.exception.DomainException;
|
||||
import org.raddatz.familienarchiv.exception.ErrorCode;
|
||||
@@ -219,6 +220,17 @@ public class OcrTrainingService {
|
||||
);
|
||||
}
|
||||
|
||||
public TrainingHistoryResponse getGlobalTrainingHistory() {
|
||||
List<OcrTrainingRun> runs = trainingRunRepository.findByPersonIdIsNullOrderByCreatedAtDesc();
|
||||
return new TrainingHistoryResponse(runs, Map.of());
|
||||
}
|
||||
|
||||
public TrainingHistoryResponse getSenderTrainingHistory(UUID personId) {
|
||||
String personName = personService.getById(personId).getDisplayName();
|
||||
List<OcrTrainingRun> runs = trainingRunRepository.findByPersonIdOrderByCreatedAtDesc(personId);
|
||||
return new TrainingHistoryResponse(runs, Map.of(personId.toString(), personName));
|
||||
}
|
||||
|
||||
@EventListener(ApplicationReadyEvent.class)
|
||||
@Transactional
|
||||
public void recoverOrphanedRuns() {
|
||||
|
||||
Reference in New Issue
Block a user