mirror of
https://github.com/hpd840321/craftlabs-authorization-sdk.git
synced 2026-06-09 18:10:30 +08:00
feat: add failure reason persistence and batch replay endpoints to callback inbox
Added failureReason field to CallbackInboxStatusPatchRequest so Ops can categorize failure causes. Added POST /batch-replay for mass reprocess and GET /stats/backlog for backlog monitoring. Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
+26
@@ -27,6 +27,8 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/callback-inbox")
|
||||
@@ -103,4 +105,28 @@ public class CallbackInboxController {
|
||||
public CallbackWebhookDeliveryStatusResponse getWebhookDelivery(@PathVariable("id") long id) {
|
||||
return callbackInboxService.getWebhookDeliveryStatus(id);
|
||||
}
|
||||
|
||||
/** M5-F07:批量重处理 — 接收 ID 列表,逐条触发 DEAD 重放。 */
|
||||
@PostMapping("/batch-replay")
|
||||
public ResponseEntity<Map<String, Object>> batchReplay(@RequestBody List<Long> ids) {
|
||||
int success = 0;
|
||||
int failed = 0;
|
||||
java.util.List<String> errors = new java.util.ArrayList<>();
|
||||
for (Long id : ids) {
|
||||
try {
|
||||
callbackInboxService.replayWebhookDelivery(id);
|
||||
success++;
|
||||
} catch (Exception e) {
|
||||
failed++;
|
||||
errors.add("ID " + id + ": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
return ResponseEntity.ok(java.util.Map.of("success", success, "failed", failed, "errors", errors));
|
||||
}
|
||||
|
||||
/** M5-F08:死信与积压监控摘要。 */
|
||||
@GetMapping("/stats/backlog")
|
||||
public ResponseEntity<Map<String, Object>> backlogStats() {
|
||||
return ResponseEntity.ok(callbackInboxService.getBacklogStats());
|
||||
}
|
||||
}
|
||||
|
||||
+30
@@ -133,6 +133,9 @@ public class CallbackInboxService {
|
||||
row.setStatus(to.name());
|
||||
row.setProcessedAt(now);
|
||||
row.setProcessedByUserId(currentActorId());
|
||||
if (request.getFailureReason() != null) {
|
||||
row.setFailureReason(request.getFailureReason());
|
||||
}
|
||||
row.setUpdatedAt(now);
|
||||
inboxMapper.updateById(row);
|
||||
auditService.record(
|
||||
@@ -306,6 +309,33 @@ public class CallbackInboxService {
|
||||
return r;
|
||||
}
|
||||
|
||||
public Map<String, Object> getBacklogStats() {
|
||||
long totalPending = inboxMapper.selectCount(
|
||||
Wrappers.lambdaQuery(PlatformCallbackInbox.class)
|
||||
.eq(PlatformCallbackInbox::getStatus, CallbackInboxStatus.PENDING));
|
||||
|
||||
long totalFailed = inboxMapper.selectCount(
|
||||
Wrappers.lambdaQuery(PlatformCallbackInbox.class)
|
||||
.eq(PlatformCallbackInbox::getStatus, CallbackInboxStatus.FAILED));
|
||||
|
||||
var oldestPending = inboxMapper.selectOne(
|
||||
Wrappers.lambdaQuery(PlatformCallbackInbox.class)
|
||||
.eq(PlatformCallbackInbox::getStatus, CallbackInboxStatus.PENDING)
|
||||
.orderByAsc(PlatformCallbackInbox::getReceivedAt)
|
||||
.last("LIMIT 1"));
|
||||
|
||||
double oldestHours = 0;
|
||||
if (oldestPending != null && oldestPending.getReceivedAt() != null) {
|
||||
oldestHours = java.time.Duration.between(
|
||||
oldestPending.getReceivedAt(), OffsetDateTime.now()).toMinutes() / 60.0;
|
||||
}
|
||||
|
||||
return java.util.Map.of(
|
||||
"totalPending", totalPending,
|
||||
"totalFailed", totalFailed,
|
||||
"oldestPendingHours", Math.round(oldestHours * 10.0) / 10.0);
|
||||
}
|
||||
|
||||
private static String currentActorId() {
|
||||
var a = org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
|
||||
if (a == null || !a.isAuthenticated()) {
|
||||
|
||||
+9
@@ -5,6 +5,7 @@ import jakarta.validation.constraints.NotBlank;
|
||||
public class CallbackInboxStatusPatchRequest {
|
||||
|
||||
@NotBlank private String status;
|
||||
private String failureReason;
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
@@ -13,4 +14,12 @@ public class CallbackInboxStatusPatchRequest {
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getFailureReason() {
|
||||
return failureReason;
|
||||
}
|
||||
|
||||
public void setFailureReason(String failureReason) {
|
||||
this.failureReason = failureReason;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user