feat: expanded health checks, deploy filtering, per-project notifications, error sanitization, and audit trail
- Expand health endpoint to check DB, Docker, and NPM connectivity (FUNC-M4) - Add project_id, stage_id, offset query params to deploys endpoint (FUNC-M5, FUNC-M6) - Add notification_url field to Stage model for per-project overrides (FUNC-M2) - Add NPM Ping method for health checking - Sanitize all internal error messages in API handlers (SEC-M4) - Add audit trail events for admin actions (FUNC-M3) - Add EventLog event type to event bus
This commit is contained in:
+22
-6
@@ -20,9 +20,21 @@ func (s *Server) listDeploys(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
deploys, err := s.store.GetRecentDeploys(limit)
|
||||
offsetStr := r.URL.Query().Get("offset")
|
||||
offset := 0
|
||||
if offsetStr != "" {
|
||||
if parsed, err := strconv.Atoi(offsetStr); err == nil && parsed >= 0 {
|
||||
offset = parsed
|
||||
}
|
||||
}
|
||||
|
||||
projectID := r.URL.Query().Get("project_id")
|
||||
stageID := r.URL.Query().Get("stage_id")
|
||||
|
||||
deploys, err := s.store.GetDeploys(projectID, stageID, limit, offset)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, "failed to list deploys: "+err.Error())
|
||||
slog.Error("failed to list deploys", "error", err)
|
||||
respondError(w, http.StatusInternalServerError, "internal server error")
|
||||
return
|
||||
}
|
||||
respondJSON(w, http.StatusOK, deploys)
|
||||
@@ -68,7 +80,8 @@ func (s *Server) inspectImage(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
info, err := s.docker.InspectImage(ctx, req.Image)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, "failed to inspect image: "+err.Error())
|
||||
slog.Error("failed to inspect image", "image", req.Image, "error", err)
|
||||
respondError(w, http.StatusInternalServerError, "internal server error")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -121,7 +134,8 @@ func (s *Server) quickDeploy(w http.ResponseWriter, r *http.Request) {
|
||||
Volumes: "{}",
|
||||
})
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, "failed to create project: "+err.Error())
|
||||
slog.Error("failed to create project", "error", err)
|
||||
respondError(w, http.StatusInternalServerError, "internal server error")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -134,14 +148,16 @@ func (s *Server) quickDeploy(w http.ResponseWriter, r *http.Request) {
|
||||
MaxInstances: 1,
|
||||
})
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, "failed to create stage: "+err.Error())
|
||||
slog.Error("failed to create stage", "error", err)
|
||||
respondError(w, http.StatusInternalServerError, "internal server error")
|
||||
return
|
||||
}
|
||||
|
||||
// Trigger deploy asynchronously.
|
||||
deployID, err := s.deployer.AsyncTriggerDeploy(r.Context(), project.ID, stage.ID, req.Tag)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, "failed to trigger deploy: "+err.Error())
|
||||
slog.Error("failed to trigger deploy", "error", err)
|
||||
respondError(w, http.StatusInternalServerError, "internal server error")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user