package httpapi import ( "io" "net/http" "strings" "tutor/internal/ingestion" "tutor/internal/ontology" ) func (h Handler) uploadMaterial(w http.ResponseWriter, r *http.Request) { if h.ontology == nil { writeError(w, http.StatusNotFound, "ontology not configured") return } if err := r.ParseMultipartForm(32 << 20); err != nil { writeError(w, http.StatusBadRequest, "invalid multipart form") return } file, header, err := r.FormFile("file") if err != nil { writeError(w, http.StatusBadRequest, "file field required") return } defer file.Close() if !ingestion.IsSupported(header.Filename) { writeError(w, http.StatusBadRequest, "unsupported file format; supported: .md, .markdown, .pdf, .docx") return } data, err := io.ReadAll(file) if err != nil { writeError(w, http.StatusInternalServerError, "failed to read file") return } result, err := ingestion.ParseFromBytes(header.Filename, data) if err != nil { if strings.Contains(err.Error(), "unsupported") { writeError(w, http.StatusBadRequest, "parse error: "+err.Error()) return } writeError(w, http.StatusInternalServerError, "parse error: "+err.Error()) return } title := r.FormValue("title") if title == "" { title = result.Title } ingestResult, err := h.ontology.Ingest(ontology.IngestInput{ Title: title, SourceType: result.Format, Body: result.Body, }) if err != nil { writeError(w, http.StatusBadRequest, err.Error()) return } writeJSON(w, http.StatusCreated, ingestResult) }