feat: enrich AgentInstanceResponse with version/capabilities, add password reset endpoint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package com.cameleer3.server.app.controller;
|
package com.cameleer3.server.app.controller;
|
||||||
|
|
||||||
|
import com.cameleer3.server.app.dto.SetPasswordRequest;
|
||||||
import com.cameleer3.server.core.admin.AuditCategory;
|
import com.cameleer3.server.core.admin.AuditCategory;
|
||||||
import com.cameleer3.server.core.admin.AuditResult;
|
import com.cameleer3.server.core.admin.AuditResult;
|
||||||
import com.cameleer3.server.core.admin.AuditService;
|
import com.cameleer3.server.core.admin.AuditService;
|
||||||
@@ -12,6 +13,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
@@ -172,6 +174,18 @@ public class UserAdminController {
|
|||||||
return ResponseEntity.noContent().build();
|
return ResponseEntity.noContent().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/{userId}/password")
|
||||||
|
@Operation(summary = "Reset user password")
|
||||||
|
@ApiResponse(responseCode = "204", description = "Password reset")
|
||||||
|
public ResponseEntity<Void> resetPassword(
|
||||||
|
@PathVariable String userId,
|
||||||
|
@Valid @RequestBody SetPasswordRequest request,
|
||||||
|
HttpServletRequest httpRequest) {
|
||||||
|
userRepository.setPassword(userId, passwordEncoder.encode(request.password()));
|
||||||
|
auditService.log("reset_password", AuditCategory.USER_MGMT, userId, null, AuditResult.SUCCESS, httpRequest);
|
||||||
|
return ResponseEntity.noContent().build();
|
||||||
|
}
|
||||||
|
|
||||||
public record CreateUserRequest(String username, String displayName, String email, String password) {}
|
public record CreateUserRequest(String username, String displayName, String email, String password) {}
|
||||||
public record UpdateUserRequest(String displayName, String email) {}
|
public record UpdateUserRequest(String displayName, String email) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import jakarta.validation.constraints.NotNull;
|
|||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Schema(description = "Agent instance summary with runtime metrics")
|
@Schema(description = "Agent instance summary with runtime metrics")
|
||||||
public record AgentInstanceResponse(
|
public record AgentInstanceResponse(
|
||||||
@@ -17,6 +18,8 @@ public record AgentInstanceResponse(
|
|||||||
@NotNull List<String> routeIds,
|
@NotNull List<String> routeIds,
|
||||||
@NotNull Instant registeredAt,
|
@NotNull Instant registeredAt,
|
||||||
@NotNull Instant lastHeartbeat,
|
@NotNull Instant lastHeartbeat,
|
||||||
|
String version,
|
||||||
|
Map<String, Object> capabilities,
|
||||||
double tps,
|
double tps,
|
||||||
double errorRate,
|
double errorRate,
|
||||||
int activeRoutes,
|
int activeRoutes,
|
||||||
@@ -29,6 +32,7 @@ public record AgentInstanceResponse(
|
|||||||
info.id(), info.name(), info.group(),
|
info.id(), info.name(), info.group(),
|
||||||
info.state().name(), info.routeIds(),
|
info.state().name(), info.routeIds(),
|
||||||
info.registeredAt(), info.lastHeartbeat(),
|
info.registeredAt(), info.lastHeartbeat(),
|
||||||
|
info.version(), info.capabilities(),
|
||||||
0.0, 0.0,
|
0.0, 0.0,
|
||||||
0, info.routeIds() != null ? info.routeIds().size() : 0,
|
0, info.routeIds() != null ? info.routeIds().size() : 0,
|
||||||
uptime
|
uptime
|
||||||
@@ -38,6 +42,7 @@ public record AgentInstanceResponse(
|
|||||||
public AgentInstanceResponse withMetrics(double tps, double errorRate, int activeRoutes) {
|
public AgentInstanceResponse withMetrics(double tps, double errorRate, int activeRoutes) {
|
||||||
return new AgentInstanceResponse(
|
return new AgentInstanceResponse(
|
||||||
id, name, group, status, routeIds, registeredAt, lastHeartbeat,
|
id, name, group, status, routeIds, registeredAt, lastHeartbeat,
|
||||||
|
version, capabilities,
|
||||||
tps, errorRate, activeRoutes, totalRoutes, uptimeSeconds
|
tps, errorRate, activeRoutes, totalRoutes, uptimeSeconds
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.cameleer3.server.app.dto;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
public record SetPasswordRequest(
|
||||||
|
@NotBlank String password
|
||||||
|
) {}
|
||||||
@@ -198,6 +198,19 @@ export function useDeleteUser() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useSetPassword() {
|
||||||
|
const qc = useQueryClient();
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async ({ userId, password }: { userId: string; password: string }) => {
|
||||||
|
await adminFetch(`/users/${userId}/password`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ password }),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onSuccess: () => qc.invalidateQueries({ queryKey: ['admin', 'users'] }),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function useAssignRoleToUser() {
|
export function useAssignRoleToUser() {
|
||||||
const qc = useQueryClient();
|
const qc = useQueryClient();
|
||||||
return useMutation({
|
return useMutation({
|
||||||
|
|||||||
Reference in New Issue
Block a user