Ctrl K
ComunidadGuías…

server/internal/handlers/entries_create.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
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)
		}
	}
}