package server import ( "encoding/json" "errors" "net/http" "github.com/go-chi/chi/v5" "git.wntrmute.dev/mc/mcq/internal/db" ) type putDocumentRequest struct { Title string `json:"title"` Body string `json:"body"` } func listDocumentsHandler(database *db.DB) http.HandlerFunc { return func(w http.ResponseWriter, _ *http.Request) { docs, err := database.ListDocuments() if err != nil { writeError(w, http.StatusInternalServerError, "failed to list documents") return } if docs == nil { docs = []db.Document{} } writeJSON(w, http.StatusOK, map[string]any{"documents": docs}) } } func getDocumentHandler(database *db.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { slug := chi.URLParam(r, "slug") doc, err := database.GetDocument(slug) if errors.Is(err, db.ErrNotFound) { writeError(w, http.StatusNotFound, "document not found") return } if err != nil { writeError(w, http.StatusInternalServerError, "failed to get document") return } writeJSON(w, http.StatusOK, doc) } } func putDocumentHandler(database *db.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { slug := chi.URLParam(r, "slug") var req putDocumentRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(w, http.StatusBadRequest, "invalid request body") return } if req.Title == "" { writeError(w, http.StatusBadRequest, "title is required") return } if req.Body == "" { writeError(w, http.StatusBadRequest, "body is required") return } info := tokenInfoFromContext(r.Context()) pushedBy := "unknown" if info != nil { pushedBy = info.Username } doc, err := database.PutDocument(slug, req.Title, req.Body, pushedBy) if err != nil { writeError(w, http.StatusInternalServerError, "failed to save document") return } writeJSON(w, http.StatusOK, doc) } } func deleteDocumentHandler(database *db.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { slug := chi.URLParam(r, "slug") err := database.DeleteDocument(slug) if errors.Is(err, db.ErrNotFound) { writeError(w, http.StatusNotFound, "document not found") return } if err != nil { writeError(w, http.StatusInternalServerError, "failed to delete document") return } w.WriteHeader(http.StatusNoContent) } } func markReadHandler(database *db.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { slug := chi.URLParam(r, "slug") doc, err := database.MarkRead(slug) if errors.Is(err, db.ErrNotFound) { writeError(w, http.StatusNotFound, "document not found") return } if err != nil { writeError(w, http.StatusInternalServerError, "failed to mark read") return } writeJSON(w, http.StatusOK, doc) } } func markUnreadHandler(database *db.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { slug := chi.URLParam(r, "slug") doc, err := database.MarkUnread(slug) if errors.Is(err, db.ErrNotFound) { writeError(w, http.StatusNotFound, "document not found") return } if err != nil { writeError(w, http.StatusInternalServerError, "failed to mark unread") return } writeJSON(w, http.StatusOK, doc) } }