mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-05 23:44:22 +00:00
Add initial api doc comments
This commit is contained in:
@@ -7,6 +7,12 @@ import (
|
|||||||
"novamd/internal/app"
|
"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() {
|
func main() {
|
||||||
// Load configuration
|
// Load configuration
|
||||||
cfg, err := app.LoadConfig()
|
cfg, err := app.LoadConfig()
|
||||||
|
|||||||
@@ -31,7 +31,32 @@ type UpdateUserRequest struct {
|
|||||||
Role models.UserRole `json:"role,omitempty"`
|
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 {
|
func (h *Handler) AdminListUsers() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, _ *http.Request) {
|
return func(w http.ResponseWriter, _ *http.Request) {
|
||||||
users, err := h.DB.GetAllUsers()
|
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 {
|
func (h *Handler) AdminCreateUser() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var req CreateUserRequest
|
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 {
|
func (h *Handler) AdminGetUser() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
userID, err := strconv.Atoi(chi.URLParam(r, "userId"))
|
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 {
|
func (h *Handler) AdminUpdateUser() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
userID, err := strconv.Atoi(chi.URLParam(r, "userId"))
|
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 {
|
func (h *Handler) AdminDeleteUser() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
ctx, ok := context.GetRequestContext(w, r)
|
||||||
@@ -214,17 +296,18 @@ func (h *Handler) AdminDeleteUser() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WorkspaceStats holds workspace statistics
|
// AdminListWorkspaces godoc
|
||||||
type WorkspaceStats struct {
|
// @Summary List all workspaces
|
||||||
UserID int `json:"userID"`
|
// @Description List all workspaces and their stats as an admin
|
||||||
UserEmail string `json:"userEmail"`
|
// @Tags Admin
|
||||||
WorkspaceID int `json:"workspaceID"`
|
// @Security BearerAuth
|
||||||
WorkspaceName string `json:"workspaceName"`
|
// @ID adminListWorkspaces
|
||||||
WorkspaceCreatedAt time.Time `json:"workspaceCreatedAt"`
|
// @Produce json
|
||||||
*storage.FileCountStats
|
// @Success 200 {array} WorkspaceStats
|
||||||
}
|
// @Failure 500 {string} "Failed to list workspaces"
|
||||||
|
// @Failure 500 {string} "Failed to get user"
|
||||||
// AdminListWorkspaces returns a list of all workspaces and their stats
|
// @Failure 500 {string} "Failed to get file stats"
|
||||||
|
// @Router /admin/workspaces [get]
|
||||||
func (h *Handler) AdminListWorkspaces() http.HandlerFunc {
|
func (h *Handler) AdminListWorkspaces() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, _ *http.Request) {
|
return func(w http.ResponseWriter, _ *http.Request) {
|
||||||
workspaces, err := h.DB.GetAllWorkspaces()
|
workspaces, err := h.DB.GetAllWorkspaces()
|
||||||
@@ -266,13 +349,17 @@ func (h *Handler) AdminListWorkspaces() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SystemStats holds system-wide statistics
|
// AdminGetSystemStats godoc
|
||||||
type SystemStats struct {
|
// @Summary Get system statistics
|
||||||
*db.UserStats
|
// @Description Get system-wide statistics as an admin
|
||||||
*storage.FileCountStats
|
// @Tags Admin
|
||||||
}
|
// @Security BearerAuth
|
||||||
|
// @ID adminGetSystemStats
|
||||||
// AdminGetSystemStats returns system-wide statistics for admins
|
// @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 {
|
func (h *Handler) AdminGetSystemStats() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, _ *http.Request) {
|
return func(w http.ResponseWriter, _ *http.Request) {
|
||||||
userStats, err := h.DB.GetSystemStats()
|
userStats, err := h.DB.GetSystemStats()
|
||||||
|
|||||||
@@ -34,7 +34,20 @@ type RefreshResponse struct {
|
|||||||
AccessToken string `json:"accessToken"`
|
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 {
|
func (h *Handler) Login(authService *auth.SessionService) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var req LoginRequest
|
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 {
|
func (h *Handler) Logout(authService *auth.SessionService) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
sessionID := r.Header.Get("X-Session-ID")
|
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 {
|
func (h *Handler) RefreshToken(authService *auth.SessionService) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var req RefreshRequest
|
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 {
|
func (h *Handler) GetCurrentUser() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
ctx, ok := context.GetRequestContext(w, r)
|
||||||
|
|||||||
@@ -12,7 +12,17 @@ import (
|
|||||||
"github.com/go-chi/chi/v5"
|
"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 {
|
func (h *Handler) ListFiles() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
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 {
|
func (h *Handler) LookupFileByName() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
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 {
|
func (h *Handler) GetFileContent() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
ctx, ok := context.GetRequestContext(w, r)
|
||||||
@@ -72,7 +108,7 @@ func (h *Handler) GetFileContent() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
http.Error(w, "Failed to read file", http.StatusNotFound)
|
http.Error(w, "File not found", http.StatusNotFound)
|
||||||
return
|
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 {
|
func (h *Handler) SaveFile() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
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 {
|
func (h *Handler) DeleteFile() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
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 {
|
func (h *Handler) GetLastOpenedFile() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
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 {
|
func (h *Handler) UpdateLastOpenedFile() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
ctx, ok := context.GetRequestContext(w, r)
|
||||||
@@ -207,7 +296,7 @@ func (h *Handler) UpdateLastOpenedFile() http.HandlerFunc {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Error(w, "Failed to update file", http.StatusInternalServerError)
|
http.Error(w, "Failed to update last opened file", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,20 @@ import (
|
|||||||
"novamd/internal/context"
|
"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 {
|
func (h *Handler) StageCommitAndPush() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
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 {
|
func (h *Handler) PullChanges() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
ctx, ok := context.GetRequestContext(w, r)
|
||||||
|
|||||||
@@ -22,7 +22,26 @@ type DeleteAccountRequest struct {
|
|||||||
Password string `json:"password"`
|
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 {
|
func (h *Handler) UpdateProfile() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
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 {
|
func (h *Handler) DeleteAccount() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
ctx, ok := context.GetRequestContext(w, r)
|
||||||
|
|||||||
@@ -9,7 +9,16 @@ import (
|
|||||||
"novamd/internal/models"
|
"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 {
|
func (h *Handler) ListWorkspaces() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
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 {
|
func (h *Handler) CreateWorkspace() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
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 {
|
func (h *Handler) GetWorkspace() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
ctx, ok := context.GetRequestContext(w, r)
|
||||||
@@ -106,7 +140,21 @@ func gitSettingsChanged(new, old *models.Workspace) bool {
|
|||||||
return false
|
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 {
|
func (h *Handler) UpdateWorkspace() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
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 {
|
func (h *Handler) DeleteWorkspace() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
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 {
|
func (h *Handler) GetLastWorkspaceName() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
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 {
|
func (h *Handler) UpdateLastWorkspaceName() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, ok := context.GetRequestContext(w, r)
|
ctx, ok := context.GetRequestContext(w, r)
|
||||||
|
|||||||
Reference in New Issue
Block a user