From c400d81c87143dce4b2abd698e450ae95cc618b8 Mon Sep 17 00:00:00 2001 From: LordMathis Date: Mon, 2 Dec 2024 22:28:12 +0100 Subject: [PATCH] Add initial api doc comments --- server/cmd/server/main.go | 6 + server/internal/handlers/admin_handlers.go | 133 +++++++++++++++--- server/internal/handlers/auth_handlers.go | 51 ++++++- server/internal/handlers/file_handlers.go | 107 ++++++++++++-- server/internal/handlers/git_handlers.go | 27 +++- server/internal/handlers/user_handlers.go | 39 ++++- .../internal/handlers/workspace_handlers.go | 98 ++++++++++++- 7 files changed, 414 insertions(+), 47 deletions(-) diff --git a/server/cmd/server/main.go b/server/cmd/server/main.go index 929a769..ae26731 100644 --- a/server/cmd/server/main.go +++ b/server/cmd/server/main.go @@ -7,6 +7,12 @@ import ( "novamd/internal/app" ) +// @title NovaMD API +// @version 1.0 +// @description This is the API for NovaMD markdown note taking app. +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html +// @BasePath /api/v1 func main() { // Load configuration cfg, err := app.LoadConfig() diff --git a/server/internal/handlers/admin_handlers.go b/server/internal/handlers/admin_handlers.go index 02b436c..3d1a2db 100644 --- a/server/internal/handlers/admin_handlers.go +++ b/server/internal/handlers/admin_handlers.go @@ -31,7 +31,32 @@ type UpdateUserRequest struct { Role models.UserRole `json:"role,omitempty"` } -// AdminListUsers returns a list of all users +// WorkspaceStats holds workspace statistics +type WorkspaceStats struct { + UserID int `json:"userID"` + UserEmail string `json:"userEmail"` + WorkspaceID int `json:"workspaceID"` + WorkspaceName string `json:"workspaceName"` + WorkspaceCreatedAt time.Time `json:"workspaceCreatedAt"` + *storage.FileCountStats +} + +// SystemStats holds system-wide statistics +type SystemStats struct { + *db.UserStats + *storage.FileCountStats +} + +// AdminListUsers godoc +// @Summary List all users +// @Description Returns the list of all users +// @Tags Admin +// @Security BearerAuth +// @ID adminListUsers +// @Produce json +// @Success 200 {array} models.User +// @Failure 500 {string} "Failed to list users" +// @Router /admin/users [get] func (h *Handler) AdminListUsers() http.HandlerFunc { return func(w http.ResponseWriter, _ *http.Request) { users, err := h.DB.GetAllUsers() @@ -44,7 +69,24 @@ func (h *Handler) AdminListUsers() http.HandlerFunc { } } -// AdminCreateUser creates a new user +// AdminCreateUser godoc +// @Summary Create a new user +// @Description Create a new user as an admin +// @Tags Admin +// @Security BearerAuth +// @ID adminCreateUser +// @Accept json +// @Produce json +// @Param user body CreateUserRequest true "User details" +// @Success 200 {object} models.User +// @Failure 400 {string} "Invalid request body" +// @Failure 400 {string} "Email, password, and role are required" +// @Failure 400 {string} "Password must be at least 8 characters" +// @Failure 409 {string} "Email already exists" +// @Failure 500 {string} "Failed to hash password" +// @Failure 500 {string} "Failed to create user" +// @Failure 500 {string} "Failed to initialize user workspace" +// @Router /admin/users [post] func (h *Handler) AdminCreateUser() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req CreateUserRequest @@ -103,7 +145,18 @@ func (h *Handler) AdminCreateUser() http.HandlerFunc { } } -// AdminGetUser gets a specific user by ID +// AdminGetUser godoc +// @Summary Get a specific user +// @Description Get a specific user as an admin +// @Tags Admin +// @Security BearerAuth +// @ID adminGetUser +// @Produce json +// @Param userId path int true "User ID" +// @Success 200 {object} models.User +// @Failure 400 {string} "Invalid user ID" +// @Failure 404 {string} "User not found" +// @Router /admin/users/{userId} [get] func (h *Handler) AdminGetUser() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { userID, err := strconv.Atoi(chi.URLParam(r, "userId")) @@ -122,7 +175,23 @@ func (h *Handler) AdminGetUser() http.HandlerFunc { } } -// AdminUpdateUser updates a specific user +// AdminUpdateUser godoc +// @Summary Update a specific user +// @Description Update a specific user as an admin +// @Tags Admin +// @Security BearerAuth +// @ID adminUpdateUser +// @Accept json +// @Produce json +// @Param userId path int true "User ID" +// @Param user body UpdateUserRequest true "User details" +// @Success 200 {object} models.User +// @Failure 400 {string} "Invalid user ID" +// @Failure 400 {string} "Invalid request body" +// @Failure 404 {string} "User not found" +// @Failure 500 {string} "Failed to hash password" +// @Failure 500 {string} "Failed to update user" +// @Router /admin/users/{userId} [put] func (h *Handler) AdminUpdateUser() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { userID, err := strconv.Atoi(chi.URLParam(r, "userId")) @@ -172,7 +241,20 @@ func (h *Handler) AdminUpdateUser() http.HandlerFunc { } } -// AdminDeleteUser deletes a specific user +// AdminDeleteUser godoc +// @Summary Delete a specific user +// @Description Delete a specific user as an admin +// @Tags Admin +// @Security BearerAuth +// @ID adminDeleteUser +// @Param userId path int true "User ID" +// @Success 204 "No Content" +// @Failure 400 {string} "Invalid user ID" +// @Failure 400 {string} "Cannot delete your own account" +// @Failure 403 {string} "Cannot delete other admin users" +// @Failure 404 {string} "User not found" +// @Failure 500 {string} "Failed to delete user" +// @Router /admin/users/{userId} [delete] func (h *Handler) AdminDeleteUser() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -214,17 +296,18 @@ func (h *Handler) AdminDeleteUser() http.HandlerFunc { } } -// WorkspaceStats holds workspace statistics -type WorkspaceStats struct { - UserID int `json:"userID"` - UserEmail string `json:"userEmail"` - WorkspaceID int `json:"workspaceID"` - WorkspaceName string `json:"workspaceName"` - WorkspaceCreatedAt time.Time `json:"workspaceCreatedAt"` - *storage.FileCountStats -} - -// AdminListWorkspaces returns a list of all workspaces and their stats +// AdminListWorkspaces godoc +// @Summary List all workspaces +// @Description List all workspaces and their stats as an admin +// @Tags Admin +// @Security BearerAuth +// @ID adminListWorkspaces +// @Produce json +// @Success 200 {array} WorkspaceStats +// @Failure 500 {string} "Failed to list workspaces" +// @Failure 500 {string} "Failed to get user" +// @Failure 500 {string} "Failed to get file stats" +// @Router /admin/workspaces [get] func (h *Handler) AdminListWorkspaces() http.HandlerFunc { return func(w http.ResponseWriter, _ *http.Request) { workspaces, err := h.DB.GetAllWorkspaces() @@ -266,13 +349,17 @@ func (h *Handler) AdminListWorkspaces() http.HandlerFunc { } } -// SystemStats holds system-wide statistics -type SystemStats struct { - *db.UserStats - *storage.FileCountStats -} - -// AdminGetSystemStats returns system-wide statistics for admins +// AdminGetSystemStats godoc +// @Summary Get system statistics +// @Description Get system-wide statistics as an admin +// @Tags Admin +// @Security BearerAuth +// @ID adminGetSystemStats +// @Produce json +// @Success 200 {object} SystemStats +// @Failure 500 {string} "Failed to get user stats" +// @Failure 500 {string} "Failed to get file stats" +// @Router /admin/stats [get] func (h *Handler) AdminGetSystemStats() http.HandlerFunc { return func(w http.ResponseWriter, _ *http.Request) { userStats, err := h.DB.GetSystemStats() diff --git a/server/internal/handlers/auth_handlers.go b/server/internal/handlers/auth_handlers.go index a1bc4b7..d039623 100644 --- a/server/internal/handlers/auth_handlers.go +++ b/server/internal/handlers/auth_handlers.go @@ -34,7 +34,20 @@ type RefreshResponse struct { AccessToken string `json:"accessToken"` } -// Login handles user authentication and returns JWT tokens +// Login godoc +// @Summary Login +// @Description Logs in a user +// @Tags auth +// @ID login +// @Accept json +// @Produce json +// @Param body body LoginRequest true "Login request" +// @Success 200 {object} LoginResponse +// @Failure 400 {string} string "Invalid request body" +// @Failure 400 {string} string "Email and password are required" +// @Failure 401 {string} string "Invalid credentials" +// @Failure 500 {string} string "Failed to create session" +// @Router /auth/login [post] func (h *Handler) Login(authService *auth.SessionService) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req LoginRequest @@ -82,7 +95,16 @@ func (h *Handler) Login(authService *auth.SessionService) http.HandlerFunc { } } -// Logout invalidates the user's session +// Logout godoc +// @Summary Logout +// @Description Log out invalidates the user's session +// @Tags auth +// @ID logout +// @Security BearerAuth +// @Success 200 {string} string "OK" +// @Failure 400 {string} string "Session ID required" +// @Failure 500 {string} string "Failed to logout" +// @Router /auth/logout [post] func (h *Handler) Logout(authService *auth.SessionService) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { sessionID := r.Header.Get("X-Session-ID") @@ -101,7 +123,19 @@ func (h *Handler) Logout(authService *auth.SessionService) http.HandlerFunc { } } -// RefreshToken generates a new access token using a refresh token +// RefreshToken godoc +// @Summary Refresh token +// @Description Refreshes the access token using the refresh token +// @Tags auth +// @ID refreshToken +// @Accept json +// @Produce json +// @Param body body RefreshRequest true "Refresh request" +// @Success 200 {object} RefreshResponse +// @Failure 400 {string} string "Invalid request body" +// @Failure 400 {string} string "Refresh token required" +// @Failure 401 {string} string "Invalid refresh token" +// @Router /auth/refresh [post] func (h *Handler) RefreshToken(authService *auth.SessionService) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req RefreshRequest @@ -130,7 +164,16 @@ func (h *Handler) RefreshToken(authService *auth.SessionService) http.HandlerFun } } -// GetCurrentUser returns the currently authenticated user +// GetCurrentUser godoc +// @Summary Get current user +// @Description Returns the current authenticated user +// @Tags auth +// @ID getCurrentUser +// @Security BearerAuth +// @Produce json +// @Success 200 {object} models.User +// @Failure 404 {string} string "User not found" +// @Router /auth/me [get] func (h *Handler) GetCurrentUser() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) diff --git a/server/internal/handlers/file_handlers.go b/server/internal/handlers/file_handlers.go index 93ddd99..b0b52f1 100644 --- a/server/internal/handlers/file_handlers.go +++ b/server/internal/handlers/file_handlers.go @@ -12,7 +12,17 @@ import ( "github.com/go-chi/chi/v5" ) -// ListFiles returns a list of all files in the workspace +// ListFiles godoc +// @Summary List files +// @Description Lists all files in the user's workspace +// @Tags files +// @ID listFiles +// @Security BearerAuth +// @Produce json +// @Param workspace_name path string true "Workspace name" +// @Success 200 {array} string +// @Failure 500 {string} string "Failed to list files" +// @Router /workspaces/{workspace_name}/files [get] func (h *Handler) ListFiles() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -30,7 +40,19 @@ func (h *Handler) ListFiles() http.HandlerFunc { } } -// LookupFileByName returns the paths of files with the given name +// LookupFileByName godoc +// @Summary Lookup file by name +// @Description Returns the paths of files with the given name in the user's workspace +// @Tags files +// @ID lookupFileByName +// @Security BearerAuth +// @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" +// @Router /workspaces/{workspace_name}/files/lookup [get] func (h *Handler) LookupFileByName() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -54,7 +76,21 @@ func (h *Handler) LookupFileByName() http.HandlerFunc { } } -// GetFileContent returns the content of a file +// GetFileContent godoc +// @Summary Get file content +// @Description Returns the content of a file in the user's workspace +// @Tags files +// @ID getFileContent +// @Security BearerAuth +// @Produce plain +// @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" +// @Router /workspaces/{workspace_name}/files/* [get] func (h *Handler) GetFileContent() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -72,7 +108,7 @@ func (h *Handler) GetFileContent() http.HandlerFunc { } if os.IsNotExist(err) { - http.Error(w, "Failed to read file", http.StatusNotFound) + http.Error(w, "File not found", http.StatusNotFound) return } @@ -89,7 +125,21 @@ func (h *Handler) GetFileContent() http.HandlerFunc { } } -// SaveFile saves the content of a file +// SaveFile godoc +// @Summary Save file +// @Description Saves the content of a file in the user's workspace +// @Tags files +// @ID saveFile +// @Security BearerAuth +// @Accept plain +// @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" +// @Router /workspaces/{workspace_name}/files/* [post] func (h *Handler) SaveFile() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -119,7 +169,21 @@ func (h *Handler) SaveFile() http.HandlerFunc { } } -// DeleteFile deletes a file +// DeleteFile godoc +// @Summary Delete file +// @Description Deletes a file in the user's workspace +// @Tags files +// @ID deleteFile +// @Security BearerAuth +// @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" +// @Router /workspaces/{workspace_name}/files/* [delete] func (h *Handler) DeleteFile() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -153,7 +217,18 @@ func (h *Handler) DeleteFile() http.HandlerFunc { } } -// GetLastOpenedFile returns the last opened file in the workspace +// GetLastOpenedFile godoc +// @Summary Get last opened file +// @Description Returns the path of the last opened file in the user's workspace +// @Tags files +// @ID getLastOpenedFile +// @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" +// @Router /workspaces/{workspace_name}/files/last [get] func (h *Handler) GetLastOpenedFile() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -176,7 +251,21 @@ func (h *Handler) GetLastOpenedFile() http.HandlerFunc { } } -// UpdateLastOpenedFile updates the last opened file in the workspace +// UpdateLastOpenedFile godoc +// @Summary Update last opened file +// @Description Updates the last opened file in the user's workspace +// @Tags files +// @ID updateLastOpenedFile +// @Security BearerAuth +// @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" +// @Router /workspaces/{workspace_name}/files/last [put] func (h *Handler) UpdateLastOpenedFile() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -207,7 +296,7 @@ func (h *Handler) UpdateLastOpenedFile() http.HandlerFunc { return } - http.Error(w, "Failed to update file", http.StatusInternalServerError) + http.Error(w, "Failed to update last opened file", http.StatusInternalServerError) return } } diff --git a/server/internal/handlers/git_handlers.go b/server/internal/handlers/git_handlers.go index f34b12a..433a242 100644 --- a/server/internal/handlers/git_handlers.go +++ b/server/internal/handlers/git_handlers.go @@ -7,7 +7,20 @@ import ( "novamd/internal/context" ) -// StageCommitAndPush stages, commits, and pushes changes to the remote repository +// StageCommitAndPush godoc +// @Summary Stage, commit, and push changes +// @Description Stages, commits, and pushes changes to the remote repository +// @Tags git +// @ID stageCommitAndPush +// @Security BearerAuth +// @Produce json +// @Param workspace_name path string true "Workspace name" +// @Param body body string true "Commit message" +// @Success 200 {object} map[string]string +// @Failure 400 {string} string "Invalid request body" +// @Failure 400 {string} string "Commit message is required" +// @Failure 500 {string} string "Failed to stage, commit, and push changes" +// @Router /workspaces/{workspace_name}/git/commit [post] func (h *Handler) StageCommitAndPush() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -39,7 +52,17 @@ func (h *Handler) StageCommitAndPush() http.HandlerFunc { } } -// PullChanges pulls changes from the remote repository +// PullChanges godoc +// @Summary Pull changes from remote +// @Description Pulls changes from the remote repository +// @Tags git +// @ID pullChanges +// @Security BearerAuth +// @Produce json +// @Param workspace_name path string true "Workspace name" +// @Success 200 {object} map[string]string +// @Failure 500 {string} string "Failed to pull changes" +// @Router /workspaces/{workspace_name}/git/pull [post] func (h *Handler) PullChanges() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) diff --git a/server/internal/handlers/user_handlers.go b/server/internal/handlers/user_handlers.go index 210dd64..3e042df 100644 --- a/server/internal/handlers/user_handlers.go +++ b/server/internal/handlers/user_handlers.go @@ -22,7 +22,26 @@ type DeleteAccountRequest struct { Password string `json:"password"` } -// UpdateProfile updates the current user's profile +// UpdateProfile godoc +// @Summary Update profile +// @Description Updates the user's profile +// @Tags users +// @ID updateProfile +// @Security BearerAuth +// @Accept json +// @Produce json +// @Param body body UpdateProfileRequest true "Profile update request" +// @Success 200 {object} models.User +// @Failure 400 {string} string "Invalid request body" +// @Failure 400 {string} string "Current password is required to change password" +// @Failure 400 {string} string "New password must be at least 8 characters long" +// @Failure 400 {string} string "Current password is required to change email" +// @Failure 401 {string} string "Current password is incorrect" +// @Failure 404 {string} string "User not found" +// @Failure 409 {string} string "Email already in use" +// @Failure 500 {string} string "Failed to process new password" +// @Failure 500 {string} string "Failed to update profile" +// @Router /profile [put] func (h *Handler) UpdateProfile() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -113,7 +132,23 @@ func (h *Handler) UpdateProfile() http.HandlerFunc { } } -// DeleteAccount handles user account deletion +// DeleteAccount godoc +// @Summary Delete account +// @Description Deletes the user's account and all associated data +// @Tags users +// @ID deleteAccount +// @Security BearerAuth +// @Accept json +// @Produce json +// @Param body body DeleteAccountRequest true "Account deletion request" +// @Success 200 {object} map[string]string +// @Failure 400 {string} string "Invalid request body" +// @Failure 401 {string} string "Password is incorrect" +// @Failure 403 {string} string "Cannot delete the last admin account" +// @Failure 404 {string} string "User not found" +// @Failure 500 {string} string "Failed to verify admin status" +// @Failure 500 {string} string "Failed to delete account" +// @Router /profile [delete] func (h *Handler) DeleteAccount() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) diff --git a/server/internal/handlers/workspace_handlers.go b/server/internal/handlers/workspace_handlers.go index 514c9ff..4e65bdc 100644 --- a/server/internal/handlers/workspace_handlers.go +++ b/server/internal/handlers/workspace_handlers.go @@ -9,7 +9,16 @@ import ( "novamd/internal/models" ) -// ListWorkspaces returns a list of all workspaces for the current user +// ListWorkspaces godoc +// @Summary List workspaces +// @Description Lists all workspaces for the current user +// @Tags workspaces +// @ID listWorkspaces +// @Security BearerAuth +// @Produce json +// @Success 200 {array} models.Workspace +// @Failure 500 {string} string "Failed to list workspaces" +// @Router /workspaces [get] func (h *Handler) ListWorkspaces() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -27,7 +36,22 @@ func (h *Handler) ListWorkspaces() http.HandlerFunc { } } -// CreateWorkspace creates a new workspace +// CreateWorkspace godoc +// @Summary Create workspace +// @Description Creates a new workspace +// @Tags workspaces +// @ID createWorkspace +// @Security BearerAuth +// @Accept json +// @Produce json +// @Param body body models.Workspace true "Workspace" +// @Success 200 {object} models.Workspace +// @Failure 400 {string} string "Invalid request body" +// @Failure 400 {string} string "Invalid workspace" +// @Failure 500 {string} string "Failed to create workspace" +// @Failure 500 {string} string "Failed to initialize workspace directory" +// @Failure 500 {string} string "Failed to setup git repo" +// @Router /workspaces [post] func (h *Handler) CreateWorkspace() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -76,7 +100,17 @@ func (h *Handler) CreateWorkspace() http.HandlerFunc { } } -// GetWorkspace returns the current workspace +// GetWorkspace godoc +// @Summary Get workspace +// @Description Returns the current workspace +// @Tags workspaces +// @ID getWorkspace +// @Security BearerAuth +// @Produce json +// @Param workspace_name path string true "Workspace name" +// @Success 200 {object} models.Workspace +// @Failure 500 {string} string "Failed to get workspace" +// @Router /workspaces/{workspace_name} [get] func (h *Handler) GetWorkspace() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -106,7 +140,21 @@ func gitSettingsChanged(new, old *models.Workspace) bool { return false } -// UpdateWorkspace updates the current workspace +// UpdateWorkspace godoc +// @Summary Update workspace +// @Description Updates the current workspace +// @Tags workspaces +// @ID updateWorkspace +// @Security BearerAuth +// @Accept json +// @Produce json +// @Param workspace_name path string true "Workspace name" +// @Param body body models.Workspace true "Workspace" +// @Success 200 {object} models.Workspace +// @Failure 400 {string} string "Invalid request body" +// @Failure 500 {string} string "Failed to update workspace" +// @Failure 500 {string} string "Failed to setup git repo" +// @Router /workspaces/{workspace_name} [put] func (h *Handler) UpdateWorkspace() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -160,7 +208,23 @@ func (h *Handler) UpdateWorkspace() http.HandlerFunc { } } -// DeleteWorkspace deletes the current workspace +// DeleteWorkspace godoc +// @Summary Delete workspace +// @Description Deletes the current workspace +// @Tags workspaces +// @ID deleteWorkspace +// @Security BearerAuth +// @Produce json +// @Param workspace_name path string true "Workspace name" +// @Success 200 {object} map[string]string +// @Failure 400 {string} string "Cannot delete the last workspace" +// @Failure 500 {string} string "Failed to get workspaces" +// @Failure 500 {string} string "Failed to start transaction" +// @Failure 500 {string} string "Failed to update last workspace" +// @Failure 500 {string} string "Failed to delete workspace" +// @Failure 500 {string} string "Failed to rollback transaction" +// @Failure 500 {string} string "Failed to commit transaction" +// @Router /workspaces/{workspace_name} [delete] func (h *Handler) DeleteWorkspace() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -228,7 +292,16 @@ func (h *Handler) DeleteWorkspace() http.HandlerFunc { } } -// GetLastWorkspaceName returns the name of the last opened workspace +// GetLastWorkspaceName godoc +// @Summary Get last workspace name +// @Description Returns the name of the last opened workspace +// @Tags workspaces +// @ID getLastWorkspaceName +// @Security BearerAuth +// @Produce json +// @Success 200 {object} map[string]string +// @Failure 500 {string} string "Failed to get last workspace" +// @Router /workspaces/last [get] func (h *Handler) GetLastWorkspaceName() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r) @@ -246,7 +319,18 @@ func (h *Handler) GetLastWorkspaceName() http.HandlerFunc { } } -// UpdateLastWorkspaceName updates the name of the last opened workspace +// UpdateLastWorkspaceName godoc +// @Summary Update last workspace name +// @Description Updates the name of the last opened workspace +// @Tags workspaces +// @ID updateLastWorkspaceName +// @Security BearerAuth +// @Accept json +// @Produce json +// @Success 200 {object} map[string]string +// @Failure 400 {string} string "Invalid request body" +// @Failure 500 {string} string "Failed to update last workspace" +// @Router /workspaces/last [put] func (h *Handler) UpdateLastWorkspaceName() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, ok := context.GetRequestContext(w, r)