mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-05 15:44:21 +00:00
Update api docs
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"novamd/internal/context"
|
||||
"novamd/internal/storage"
|
||||
@@ -12,6 +13,28 @@ import (
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
// LookupResponse represents a response to a file lookup request
|
||||
type LookupResponse struct {
|
||||
Paths []string `json:"paths"`
|
||||
}
|
||||
|
||||
// SaveFileResponse represents a response to a save file request
|
||||
type SaveFileResponse struct {
|
||||
FilePath string `json:"filePath"`
|
||||
Size int64 `json:"size"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
// LastOpenedFileResponse represents a response to a last opened file request
|
||||
type LastOpenedFileResponse struct {
|
||||
LastOpenedFilePath string `json:"lastOpenedFilePath"`
|
||||
}
|
||||
|
||||
// UpdateLastOpenedFileRequest represents a request to update the last opened file
|
||||
type UpdateLastOpenedFileRequest struct {
|
||||
FilePath string `json:"filePath"`
|
||||
}
|
||||
|
||||
// ListFiles godoc
|
||||
// @Summary List files
|
||||
// @Description Lists all files in the user's workspace
|
||||
@@ -20,8 +43,8 @@ import (
|
||||
// @Security BearerAuth
|
||||
// @Produce json
|
||||
// @Param workspace_name path string true "Workspace name"
|
||||
// @Success 200 {array} string
|
||||
// @Failure 500 {string} string "Failed to list files"
|
||||
// @Success 200 {array} storage.FileNode
|
||||
// @Failure 500 {object} ErrorResponse "Failed to list files"
|
||||
// @Router /workspaces/{workspace_name}/files [get]
|
||||
func (h *Handler) ListFiles() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -32,7 +55,7 @@ func (h *Handler) ListFiles() http.HandlerFunc {
|
||||
|
||||
files, err := h.Storage.ListFilesRecursively(ctx.UserID, ctx.Workspace.ID)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to list files", http.StatusInternalServerError)
|
||||
respondError(w, "Failed to list files", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -49,9 +72,9 @@ func (h *Handler) ListFiles() http.HandlerFunc {
|
||||
// @Produce json
|
||||
// @Param workspace_name path string true "Workspace name"
|
||||
// @Param filename query string true "File name"
|
||||
// @Success 200 {object} map[string][]string
|
||||
// @Failure 400 {string} string "Filename is required"
|
||||
// @Failure 404 {string} string "File not found"
|
||||
// @Success 200 {object} LookupResponse
|
||||
// @Failure 400 {object} ErrorResponse "Filename is required"
|
||||
// @Failure 404 {object} ErrorResponse "File not found"
|
||||
// @Router /workspaces/{workspace_name}/files/lookup [get]
|
||||
func (h *Handler) LookupFileByName() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -62,17 +85,17 @@ func (h *Handler) LookupFileByName() http.HandlerFunc {
|
||||
|
||||
filename := r.URL.Query().Get("filename")
|
||||
if filename == "" {
|
||||
http.Error(w, "Filename is required", http.StatusBadRequest)
|
||||
respondError(w, "Filename is required", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
filePaths, err := h.Storage.FindFileByName(ctx.UserID, ctx.Workspace.ID, filename)
|
||||
if err != nil {
|
||||
http.Error(w, "File not found", http.StatusNotFound)
|
||||
respondError(w, "File not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
respondJSON(w, map[string][]string{"paths": filePaths})
|
||||
respondJSON(w, &LookupResponse{Paths: filePaths})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,10 +109,10 @@ func (h *Handler) LookupFileByName() http.HandlerFunc {
|
||||
// @Param workspace_name path string true "Workspace name"
|
||||
// @Param file_path path string true "File path"
|
||||
// @Success 200 {string} "File content"
|
||||
// @Failure 400 {string} string "Invalid file path"
|
||||
// @Failure 404 {string} string "File not found"
|
||||
// @Failure 500 {string} string "Failed to read file"
|
||||
// @Failure 500 {string} string "Failed to write response"
|
||||
// @Failure 400 {object} ErrorResponse "Invalid file path"
|
||||
// @Failure 404 {object} ErrorResponse "File not found"
|
||||
// @Failure 500 {object} ErrorResponse "Failed to read file"
|
||||
// @Failure 500 {object} ErrorResponse "Failed to write response"
|
||||
// @Router /workspaces/{workspace_name}/files/* [get]
|
||||
func (h *Handler) GetFileContent() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -103,23 +126,23 @@ func (h *Handler) GetFileContent() http.HandlerFunc {
|
||||
if err != nil {
|
||||
|
||||
if storage.IsPathValidationError(err) {
|
||||
http.Error(w, "Invalid file path", http.StatusBadRequest)
|
||||
respondError(w, "Invalid file path", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
http.Error(w, "File not found", http.StatusNotFound)
|
||||
respondError(w, "File not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
http.Error(w, "Failed to read file", http.StatusInternalServerError)
|
||||
respondError(w, "Failed to read file", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
_, err = w.Write(content)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to write response", http.StatusInternalServerError)
|
||||
respondError(w, "Failed to write response", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -135,10 +158,10 @@ func (h *Handler) GetFileContent() http.HandlerFunc {
|
||||
// @Produce json
|
||||
// @Param workspace_name path string true "Workspace name"
|
||||
// @Param file_path path string true "File path"
|
||||
// @Success 200 {string} "File saved successfully"
|
||||
// @Failure 400 {string} string "Failed to read request body"
|
||||
// @Failure 400 {string} string "Invalid file path"
|
||||
// @Failure 500 {string} string "Failed to save file"
|
||||
// @Success 200 {object} SaveFileResponse
|
||||
// @Failure 400 {object} ErrorResponse "Failed to read request body"
|
||||
// @Failure 400 {object} ErrorResponse "Invalid file path"
|
||||
// @Failure 500 {object} ErrorResponse "Failed to save file"
|
||||
// @Router /workspaces/{workspace_name}/files/* [post]
|
||||
func (h *Handler) SaveFile() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -150,22 +173,29 @@ func (h *Handler) SaveFile() http.HandlerFunc {
|
||||
filePath := chi.URLParam(r, "*")
|
||||
content, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to read request body", http.StatusBadRequest)
|
||||
respondError(w, "Failed to read request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err = h.Storage.SaveFile(ctx.UserID, ctx.Workspace.ID, filePath, content)
|
||||
if err != nil {
|
||||
if storage.IsPathValidationError(err) {
|
||||
http.Error(w, "Invalid file path", http.StatusBadRequest)
|
||||
respondError(w, "Invalid file path", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
http.Error(w, "Failed to save file", http.StatusInternalServerError)
|
||||
respondError(w, "Failed to save file", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
respondJSON(w, map[string]string{"message": "File saved successfully"})
|
||||
response := SaveFileResponse{
|
||||
FilePath: filePath,
|
||||
Size: int64(len(content)),
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
respondJSON(w, response)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,11 +208,11 @@ func (h *Handler) SaveFile() http.HandlerFunc {
|
||||
// @Produce string
|
||||
// @Param workspace_name path string true "Workspace name"
|
||||
// @Param file_path path string true "File path"
|
||||
// @Success 200 {string} "File deleted successfully"
|
||||
// @Failure 400 {string} string "Invalid file path"
|
||||
// @Failure 404 {string} string "File not found"
|
||||
// @Failure 500 {string} string "Failed to delete file"
|
||||
// @Failure 500 {string} string "Failed to write response"
|
||||
// @Success 204 "No Content - File deleted successfully"
|
||||
// @Failure 400 {object} ErrorResponse "Invalid file path"
|
||||
// @Failure 404 {object} ErrorResponse "File not found"
|
||||
// @Failure 500 {object} ErrorResponse "Failed to delete file"
|
||||
// @Failure 500 {object} ErrorResponse "Failed to write response"
|
||||
// @Router /workspaces/{workspace_name}/files/* [delete]
|
||||
func (h *Handler) DeleteFile() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -195,25 +225,20 @@ func (h *Handler) DeleteFile() http.HandlerFunc {
|
||||
err := h.Storage.DeleteFile(ctx.UserID, ctx.Workspace.ID, filePath)
|
||||
if err != nil {
|
||||
if storage.IsPathValidationError(err) {
|
||||
http.Error(w, "Invalid file path", http.StatusBadRequest)
|
||||
respondError(w, "Invalid file path", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
http.Error(w, "File not found", http.StatusNotFound)
|
||||
respondError(w, "File not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
http.Error(w, "Failed to delete file", http.StatusInternalServerError)
|
||||
respondError(w, "Failed to delete file", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, err = w.Write([]byte("File deleted successfully"))
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to write response", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,9 +250,9 @@ func (h *Handler) DeleteFile() http.HandlerFunc {
|
||||
// @Security BearerAuth
|
||||
// @Produce json
|
||||
// @Param workspace_name path string true "Workspace name"
|
||||
// @Success 200 {object} map[string]string
|
||||
// @Failure 400 {string} string "Invalid file path"
|
||||
// @Failure 500 {string} string "Failed to get last opened file"
|
||||
// @Success 200 {object} LastOpenedFileResponse
|
||||
// @Failure 400 {object} ErrorResponse "Invalid file path"
|
||||
// @Failure 500 {object} ErrorResponse "Failed to get last opened file"
|
||||
// @Router /workspaces/{workspace_name}/files/last [get]
|
||||
func (h *Handler) GetLastOpenedFile() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -238,16 +263,16 @@ func (h *Handler) GetLastOpenedFile() http.HandlerFunc {
|
||||
|
||||
filePath, err := h.DB.GetLastOpenedFile(ctx.Workspace.ID)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to get last opened file", http.StatusInternalServerError)
|
||||
respondError(w, "Failed to get last opened file", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := h.Storage.ValidatePath(ctx.UserID, ctx.Workspace.ID, filePath); err != nil {
|
||||
http.Error(w, "Invalid file path", http.StatusBadRequest)
|
||||
respondError(w, "Invalid file path", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
respondJSON(w, map[string]string{"lastOpenedFilePath": filePath})
|
||||
respondJSON(w, &LastOpenedFileResponse{LastOpenedFilePath: filePath})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,11 +285,12 @@ func (h *Handler) GetLastOpenedFile() http.HandlerFunc {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param workspace_name path string true "Workspace name"
|
||||
// @Success 200 {object} map[string]string
|
||||
// @Failure 400 {string} string "Invalid request body"
|
||||
// @Failure 400 {string} string "Invalid file path"
|
||||
// @Failure 404 {string} string "File not found"
|
||||
// @Failure 500 {string} string "Failed to update file"
|
||||
// @Param body body UpdateLastOpenedFileRequest true "Update last opened file request"
|
||||
// @Success 204 "No Content - Last opened file updated successfully"
|
||||
// @Failure 400 {object} ErrorResponse "Invalid request body"
|
||||
// @Failure 400 {object} ErrorResponse "Invalid file path"
|
||||
// @Failure 404 {object} ErrorResponse "File not found"
|
||||
// @Failure 500 {object} ErrorResponse "Failed to update file"
|
||||
// @Router /workspaces/{workspace_name}/files/last [put]
|
||||
func (h *Handler) UpdateLastOpenedFile() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -273,12 +299,10 @@ func (h *Handler) UpdateLastOpenedFile() http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
var requestBody struct {
|
||||
FilePath string `json:"filePath"`
|
||||
}
|
||||
var requestBody UpdateLastOpenedFileRequest
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&requestBody); err != nil {
|
||||
http.Error(w, "Invalid request body", http.StatusBadRequest)
|
||||
respondError(w, "Invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -287,25 +311,25 @@ func (h *Handler) UpdateLastOpenedFile() http.HandlerFunc {
|
||||
_, err := h.Storage.GetFileContent(ctx.UserID, ctx.Workspace.ID, requestBody.FilePath)
|
||||
if err != nil {
|
||||
if storage.IsPathValidationError(err) {
|
||||
http.Error(w, "Invalid file path", http.StatusBadRequest)
|
||||
respondError(w, "Invalid file path", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
http.Error(w, "File not found", http.StatusNotFound)
|
||||
respondError(w, "File not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
http.Error(w, "Failed to update last opened file", http.StatusInternalServerError)
|
||||
respondError(w, "Failed to update last opened file", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := h.DB.UpdateLastOpenedFile(ctx.Workspace.ID, requestBody.FilePath); err != nil {
|
||||
http.Error(w, "Failed to update last opened file", http.StatusInternalServerError)
|
||||
respondError(w, "Failed to update last opened file", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
respondJSON(w, map[string]string{"message": "Last opened file updated successfully"})
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user