feat: add import status tracking to MassImportService
The async import previously ran fire-and-forget with no way to know if it succeeded, failed, or was still running. - Add ImportStatus record (state, message, processed count, startedAt) and a volatile currentStatus field updated throughout the async run - POST /api/admin/trigger-import now returns 202 Accepted with initial status - GET /api/admin/import-status lets callers poll for the current state Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import org.raddatz.familienarchiv.security.Permission;
|
|||||||
import org.raddatz.familienarchiv.security.RequirePermission;
|
import org.raddatz.familienarchiv.security.RequirePermission;
|
||||||
import org.raddatz.familienarchiv.service.MassImportService;
|
import org.raddatz.familienarchiv.service.MassImportService;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@@ -19,8 +20,13 @@ public class AdminController {
|
|||||||
private final MassImportService massImportService;
|
private final MassImportService massImportService;
|
||||||
|
|
||||||
@PostMapping("/trigger-import")
|
@PostMapping("/trigger-import")
|
||||||
public ResponseEntity<String> triggerMassImport() {
|
public ResponseEntity<MassImportService.ImportStatus> triggerMassImport() {
|
||||||
massImportService.runImportAsync();
|
massImportService.runImportAsync();
|
||||||
return ResponseEntity.ok("Massenimport gestartet.");
|
return ResponseEntity.accepted().body(massImportService.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/import-status")
|
||||||
|
public ResponseEntity<MassImportService.ImportStatus> importStatus() {
|
||||||
|
return ResponseEntity.ok(massImportService.getStatus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -32,6 +33,16 @@ import java.util.stream.Stream;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class MassImportService {
|
public class MassImportService {
|
||||||
|
|
||||||
|
public enum State { IDLE, RUNNING, DONE, FAILED }
|
||||||
|
|
||||||
|
public record ImportStatus(State state, String message, int processed, LocalDateTime startedAt) {}
|
||||||
|
|
||||||
|
private volatile ImportStatus currentStatus = new ImportStatus(State.IDLE, "Kein Import gestartet.", 0, null);
|
||||||
|
|
||||||
|
public ImportStatus getStatus() {
|
||||||
|
return currentStatus;
|
||||||
|
}
|
||||||
|
|
||||||
private final DocumentRepository documentRepository;
|
private final DocumentRepository documentRepository;
|
||||||
private final S3Client s3Client;
|
private final S3Client s3Client;
|
||||||
|
|
||||||
@@ -52,23 +63,15 @@ public class MassImportService {
|
|||||||
|
|
||||||
@Async
|
@Async
|
||||||
public void runImportAsync() {
|
public void runImportAsync() {
|
||||||
runImport();
|
currentStatus = new ImportStatus(State.RUNNING, "Import läuft...", 0, LocalDateTime.now());
|
||||||
}
|
|
||||||
|
|
||||||
public String runImport() {
|
|
||||||
try {
|
try {
|
||||||
// 1. Excel finden
|
|
||||||
File excelFile = findExcelFile();
|
File excelFile = findExcelFile();
|
||||||
log.info("Starte Massenimport aus: {}", excelFile.getAbsolutePath());
|
log.info("Starte Massenimport aus: {}", excelFile.getAbsolutePath());
|
||||||
|
|
||||||
// 2. Excel verarbeiten
|
|
||||||
int processed = processExcel(excelFile);
|
int processed = processExcel(excelFile);
|
||||||
|
currentStatus = new ImportStatus(State.DONE, "Import abgeschlossen. " + processed + " Dokumente verarbeitet.", processed, currentStatus.startedAt());
|
||||||
return "Import abgeschlossen. " + processed + " Dokumente verarbeitet.";
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Massenimport fehlgeschlagen", e);
|
log.error("Massenimport fehlgeschlagen", e);
|
||||||
return "Fehler: " + e.getMessage();
|
currentStatus = new ImportStatus(State.FAILED, "Fehler: " + e.getMessage(), 0, currentStatus.startedAt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user