package handlers import ( "fmt" "net/http" "github.com/breakpilot/ai-compliance-sdk/internal/iace" "github.com/gin-gonic/gin" "github.com/google/uuid" ) // ExportFMEA handles GET /projects/:id/fmea/export // Returns an xlsx file in VDA FMEA format. func (h *IACEHandler) ExportFMEA(c *gin.Context) { projectID, err := uuid.Parse(c.Param("id")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"}) return } ctx := c.Request.Context() project, err := h.store.GetProject(ctx, projectID) if err != nil || project == nil { c.JSON(http.StatusNotFound, gin.H{"error": "project not found"}) return } // Load components components, _ := h.store.ListComponents(ctx, projectID) // Load all failure modes allFMs := iace.GetFailureModeLibrary() // Build FMEA rows: each component × matching FMs var rows []iace.FMEAExportRow for _, comp := range components { compType := string(comp.ComponentType) var compFMs []iace.FailureModeEntry for _, fm := range allFMs { if fm.ComponentType == compType { compFMs = append(compFMs, fm) } } if len(compFMs) == 0 { // Fallback: mechanical FMs for _, fm := range allFMs { if fm.ComponentType == "mechanical" && len(compFMs) < 3 { compFMs = append(compFMs, fm) } } } for _, fm := range compFMs { s, o, d := fm.DefaultSeverity, fm.DefaultOccurrence, fm.DefaultDetection rows = append(rows, iace.FMEAExportRow{ ComponentName: comp.Name, ComponentType: compType, FailureMode: fm.NameDE, FailureEffect: fm.Effect, FailureCause: fm.DetectionHint, Severity: s, Occurrence: o, Detection: d, RPZ: s * o * d, AP: iace.CalculateAP(s, o, d), Measure: "", DetectionHint: fm.DetectionHint, }) } } xlsxBytes, err := iace.GenerateFMEAExcel(project.MachineName, rows) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("Excel generation failed: %v", err)}) return } filename := fmt.Sprintf("FMEA-%s.xlsx", project.MachineName) c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename)) c.Data(http.StatusOK, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", xlsxBytes) }