package handlers import ( "net/http" "strings" "github.com/gin-gonic/gin" "github.com/tradarr/backend/internal/httputil" ) type reportRequest struct { SummaryID string `json:"summary_id"` Excerpts []string `json:"excerpts" binding:"required,min=1"` Question string `json:"question" binding:"required"` } func (h *Handler) CreateReport(c *gin.Context) { userID := c.GetString("userID") var req reportRequest if err := c.ShouldBindJSON(&req); err != nil { httputil.BadRequest(c, err) return } var summaryID *string if req.SummaryID != "" { summaryID = &req.SummaryID } // Joindre les extraits avec un séparateur visuel excerpt := buildExcerptContext(req.Excerpts) // Créer le rapport en DB avec status=generating, retourner immédiatement report, err := h.repo.CreatePendingReport(userID, summaryID, excerpt, req.Question) if err != nil { httputil.InternalError(c, err) return } // Lancer la génération en arrière-plan h.pipeline.GenerateReportAsync(report.ID, excerpt, req.Question, h.reportManager) c.JSON(http.StatusCreated, report) } func (h *Handler) ListReports(c *gin.Context) { userID := c.GetString("userID") reports, err := h.repo.ListReports(userID) if err != nil { httputil.InternalError(c, err) return } httputil.OK(c, reports) } func (h *Handler) DeleteReport(c *gin.Context) { userID := c.GetString("userID") id := c.Param("id") // Annuler la goroutine si elle tourne encore h.reportManager.Cancel(id) if err := h.repo.DeleteReport(id, userID); err != nil { httputil.InternalError(c, err) return } c.Status(http.StatusNoContent) } func (h *Handler) GetGeneratingStatus(c *gin.Context) { httputil.OK(c, gin.H{"generating": h.pipeline.IsGenerating()}) } func buildExcerptContext(excerpts []string) string { if len(excerpts) == 1 { return excerpts[0] } var sb strings.Builder for i, e := range excerpts { if i > 0 { sb.WriteString("\n\n---\n\n") } sb.WriteString(e) } return sb.String() }