server/internal/handlers/entries_create.go
Rama main · réplica de lectura del repositorio original.
package handlers
import (
"encoding/json"
"log"
"net/http"
"strings"
"time"
"blackbox/server/internal/hub"
"blackbox/shared/types"
"github.com/oklog/ulid/v2"
"gorm.io/gorm"
)
type createEntryRequest struct {
Title string `json:"title"`
Note string `json:"note"`
Services []string `json:"services"`
Timestamp string `json:"timestamp"`
}
func CreateEntry(database *gorm.DB, h *hub.Hub, incidentCh chan<- types.Entry, shutdown <-chan struct{}) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req createEntryRequest
if !decodeJSONBody(w, r, 1<<20, &req) {
return
}
req.Title = strings.TrimSpace(req.Title)
if req.Title == "" {
writeError(w, http.StatusBadRequest, "title is required")
return
}
timestamp := time.Now().UTC()
if req.Timestamp != "" {
parsed, err := time.Parse(time.RFC3339, req.Timestamp)
if err != nil {
writeError(w, http.StatusBadRequest, "invalid timestamp format")
return
}
timestamp = parsed.UTC()
}
serviceNames := req.Services
if serviceNames == nil {
serviceNames = []string{}
}
normalizedServices := make([]string, 0, len(serviceNames))
for _, name := range serviceNames {
normalized := strings.ToLower(strings.TrimSpace(name))
if normalized != "" {
normalizedServices = append(normalizedServices, normalized)
}
}
service := ""
if len(normalizedServices) > 0 {
service = normalizedServices[0]
}
metaBytes, err := json.Marshal(map[string]interface{}{
"note": req.Note,
"services": normalizedServices,
})
if err != nil {
writeError(w, http.StatusInternalServerError, "failed to encode metadata")
return
}
entry := types.Entry{
ID: ulid.Make().String(),
Timestamp: timestamp,
NodeName: "api",
Source: "api",
Service: service,
Event: "manual",
Content: req.Title,
Metadata: string(metaBytes),
}
if err := database.Create(&entry).Error; err != nil {
writeError(w, http.StatusInternalServerError, "failed to save entry")
return
}
dispatchToIncidentChannelWithShutdown(incidentCh, shutdown, entry)
if h != nil {
if msg := MarshalWSMessage("entry", entry); msg != nil {
h.Broadcast(msg)
}
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
if err := json.NewEncoder(w).Encode(entry); err != nil {
log.Printf("failed to encode create entry response for entry %s: %v", entry.ID, err)
}
}
}