package handlers import ( "net/http" "strconv" "github.com/breakpilot/ai-compliance-sdk/internal/iace" "github.com/gin-gonic/gin" ) // ListFailureKnowledge handles GET /failure-knowledge. // Read-only unified failure-knowledge ontology (Component → FailureMode → // Mechanism → Effect → Hazard → Harm → Control) curated from commercially-usable // open sources (currently NASA NTRS, public domain). Optional ?domain= filter. // This is the shared corpus that seeds the FMEA library and the CE hazard side. func (h *IACEHandler) ListFailureKnowledge(c *gin.Context) { var items []iace.FailureKnowledge if d := c.Query("domain"); d != "" { items = iace.FailureKnowledgeByDomain(d) } else { items = iace.AllFailureKnowledge() } if items == nil { items = []iace.FailureKnowledge{} } c.JSON(http.StatusOK, gin.H{ "failure_knowledge": items, "total": len(items), }) } // HarvestNTRSFailures handles GET /failure-knowledge/ntrs. // Live-harvests NASA NTRS lessons-learned metadata and returns only the records // that pass the public-reuse licence gate (Stage 1 of the bulk loader). Tuple // extraction from the abstracts is a downstream step. func (h *IACEHandler) HarvestNTRSFailures(c *gin.Context) { q := c.DefaultQuery("q", "lessons learned failure") limit, _ := strconv.Atoi(c.DefaultQuery("limit", "25")) lessons, err := iace.FetchNTRSLessons(c.Request.Context(), q, limit) if err != nil { c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()}) return } out := []gin.H{} skipped := 0 for _, l := range lessons { ok, lic := iace.NTRSUsable(l) if !ok { skipped++ continue } out = append(out, gin.H{ "id": l.ID, "title": l.Title, "abstract": l.Abstract, "license": lic, "pdf_url": iace.NTRSPDFURL(l), "is_lessons_learned": l.IsLessonsLearned, }) } c.JSON(http.StatusOK, gin.H{ "query": q, "usable": out, "usable_count": len(out), "skipped_non_open": skipped, "total_fetched": len(lessons), }) }