mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-05 15:44:21 +00:00
Regenerate docs
This commit is contained in:
@@ -5,9 +5,9 @@ Generated documentation for all packages in the NovaMD project.
|
|||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
- [cmd/server](#cmd-server)
|
- [cmd/server](#cmd-server)
|
||||||
|
- [docs](#docs)
|
||||||
- [internal/app](#internal-app)
|
- [internal/app](#internal-app)
|
||||||
- [internal/auth](#internal-auth)
|
- [internal/auth](#internal-auth)
|
||||||
- [internal/config](#internal-config)
|
|
||||||
- [internal/context](#internal-context)
|
- [internal/context](#internal-context)
|
||||||
- [internal/db](#internal-db)
|
- [internal/db](#internal-db)
|
||||||
- [internal/git](#internal-git)
|
- [internal/git](#internal-git)
|
||||||
@@ -23,6 +23,31 @@ Package main provides the entry point for the application. It loads the
|
|||||||
configuration, initializes the server, and starts the server.
|
configuration, initializes the server, and starts the server.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## docs
|
||||||
|
|
||||||
|
```go
|
||||||
|
package docs // import "novamd/docs"
|
||||||
|
|
||||||
|
Package docs Code generated by swaggo/swag. DO NOT EDIT
|
||||||
|
|
||||||
|
VARIABLES
|
||||||
|
|
||||||
|
var SwaggerInfo = &swag.Spec{
|
||||||
|
Version: "1.0",
|
||||||
|
Host: "",
|
||||||
|
BasePath: "/api/v1",
|
||||||
|
Schemes: []string{},
|
||||||
|
Title: "NovaMD API",
|
||||||
|
Description: "This is the API for NovaMD markdown note taking app.",
|
||||||
|
InfoInstanceName: "swagger",
|
||||||
|
SwaggerTemplate: docTemplate,
|
||||||
|
LeftDelim: "{{",
|
||||||
|
RightDelim: "}}",
|
||||||
|
}
|
||||||
|
SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## internal/app
|
## internal/app
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -31,124 +56,6 @@ package app // import "novamd/internal/app"
|
|||||||
Package app provides application-level functionality for initializing and
|
Package app provides application-level functionality for initializing and
|
||||||
running the server
|
running the server
|
||||||
|
|
||||||
FUNCTIONS
|
|
||||||
|
|
||||||
func SetupRoutes(r chi.Router, db db.Database, s storage.Manager, authMiddleware *auth.Middleware, sessionService *auth.SessionService)
|
|
||||||
SetupRoutes configures the API routes
|
|
||||||
|
|
||||||
|
|
||||||
TYPES
|
|
||||||
|
|
||||||
type Server struct {
|
|
||||||
// Has unexported fields.
|
|
||||||
}
|
|
||||||
Server represents the HTTP server and its dependencies
|
|
||||||
|
|
||||||
func NewServer(cfg *config.Config) (*Server, error)
|
|
||||||
NewServer initializes a new server instance with all dependencies
|
|
||||||
|
|
||||||
func (s *Server) Close() error
|
|
||||||
Close handles graceful shutdown of server dependencies
|
|
||||||
|
|
||||||
func (s *Server) Start() error
|
|
||||||
Start configures and starts the HTTP server
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## internal/auth
|
|
||||||
|
|
||||||
```go
|
|
||||||
package auth // import "novamd/internal/auth"
|
|
||||||
|
|
||||||
Package auth provides JWT token generation and validation
|
|
||||||
|
|
||||||
TYPES
|
|
||||||
|
|
||||||
type Claims struct {
|
|
||||||
jwt.RegisteredClaims // Embedded standard JWT claims
|
|
||||||
UserID int `json:"uid"` // User identifier
|
|
||||||
Role string `json:"role"` // User role (admin, editor, viewer)
|
|
||||||
Type TokenType `json:"type"` // Token type (access or refresh)
|
|
||||||
}
|
|
||||||
Claims represents the custom claims we store in JWT tokens
|
|
||||||
|
|
||||||
type JWTConfig struct {
|
|
||||||
SigningKey string // Secret key used to sign tokens
|
|
||||||
AccessTokenExpiry time.Duration // How long access tokens are valid
|
|
||||||
RefreshTokenExpiry time.Duration // How long refresh tokens are valid
|
|
||||||
}
|
|
||||||
JWTConfig holds the configuration for the JWT service
|
|
||||||
|
|
||||||
type JWTManager interface {
|
|
||||||
GenerateAccessToken(userID int, role string) (string, error)
|
|
||||||
GenerateRefreshToken(userID int, role string) (string, error)
|
|
||||||
ValidateToken(tokenString string) (*Claims, error)
|
|
||||||
RefreshAccessToken(refreshToken string) (string, error)
|
|
||||||
}
|
|
||||||
JWTManager defines the interface for managing JWT tokens
|
|
||||||
|
|
||||||
func NewJWTService(config JWTConfig) (JWTManager, error)
|
|
||||||
NewJWTService creates a new JWT service with the provided configuration
|
|
||||||
Returns an error if the signing key is missing
|
|
||||||
|
|
||||||
type Middleware struct {
|
|
||||||
// Has unexported fields.
|
|
||||||
}
|
|
||||||
Middleware handles JWT authentication for protected routes
|
|
||||||
|
|
||||||
func NewMiddleware(jwtManager JWTManager) *Middleware
|
|
||||||
NewMiddleware creates a new authentication middleware
|
|
||||||
|
|
||||||
func (m *Middleware) Authenticate(next http.Handler) http.Handler
|
|
||||||
Authenticate middleware validates JWT tokens and sets user information in
|
|
||||||
context
|
|
||||||
|
|
||||||
func (m *Middleware) RequireRole(role string) func(http.Handler) http.Handler
|
|
||||||
RequireRole returns a middleware that ensures the user has the required role
|
|
||||||
|
|
||||||
func (m *Middleware) RequireWorkspaceAccess(next http.Handler) http.Handler
|
|
||||||
RequireWorkspaceAccess returns a middleware that ensures the user has access
|
|
||||||
to the workspace
|
|
||||||
|
|
||||||
type SessionService struct {
|
|
||||||
// Has unexported fields.
|
|
||||||
}
|
|
||||||
SessionService manages user sessions in the database
|
|
||||||
|
|
||||||
func NewSessionService(db db.SessionStore, jwtManager JWTManager) *SessionService
|
|
||||||
NewSessionService creates a new session service with the given database and
|
|
||||||
JWT manager
|
|
||||||
|
|
||||||
func (s *SessionService) CleanExpiredSessions() error
|
|
||||||
CleanExpiredSessions removes all expired sessions from the database
|
|
||||||
|
|
||||||
func (s *SessionService) CreateSession(userID int, role string) (*models.Session, string, error)
|
|
||||||
CreateSession creates a new user session for a user with the given userID
|
|
||||||
and role
|
|
||||||
|
|
||||||
func (s *SessionService) InvalidateSession(sessionID string) error
|
|
||||||
InvalidateSession removes a session with the given sessionID from the
|
|
||||||
database
|
|
||||||
|
|
||||||
func (s *SessionService) RefreshSession(refreshToken string) (string, error)
|
|
||||||
RefreshSession creates a new access token using a refreshToken
|
|
||||||
|
|
||||||
type TokenType string
|
|
||||||
TokenType represents the type of JWT token (access or refresh)
|
|
||||||
|
|
||||||
const (
|
|
||||||
AccessToken TokenType = "access" // AccessToken - Short-lived token for API access
|
|
||||||
RefreshToken TokenType = "refresh" // RefreshToken - Long-lived token for obtaining new access tokens
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
## internal/config
|
|
||||||
|
|
||||||
```go
|
|
||||||
package config // import "novamd/internal/config"
|
|
||||||
|
|
||||||
Package config provides the configuration for the application
|
|
||||||
|
|
||||||
TYPES
|
TYPES
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@@ -156,7 +63,8 @@ type Config struct {
|
|||||||
WorkDir string
|
WorkDir string
|
||||||
StaticPath string
|
StaticPath string
|
||||||
Port string
|
Port string
|
||||||
AppURL string
|
RootURL string
|
||||||
|
Domain string
|
||||||
CORSOrigins []string
|
CORSOrigins []string
|
||||||
AdminEmail string
|
AdminEmail string
|
||||||
AdminPassword string
|
AdminPassword string
|
||||||
@@ -171,12 +79,132 @@ type Config struct {
|
|||||||
func DefaultConfig() *Config
|
func DefaultConfig() *Config
|
||||||
DefaultConfig returns a new Config instance with default values
|
DefaultConfig returns a new Config instance with default values
|
||||||
|
|
||||||
func Load() (*Config, error)
|
func LoadConfig() (*Config, error)
|
||||||
Load creates a new Config instance with values from environment variables
|
LoadConfig creates a new Config instance with values from environment
|
||||||
|
variables
|
||||||
|
|
||||||
func (c *Config) Validate() error
|
type Options struct {
|
||||||
Validate checks if the configuration is valid
|
Config *Config
|
||||||
|
Database db.Database
|
||||||
|
Storage storage.Manager
|
||||||
|
JWTManager auth.JWTManager
|
||||||
|
SessionManager auth.SessionManager
|
||||||
|
CookieService auth.CookieManager
|
||||||
|
}
|
||||||
|
Options holds all dependencies and configuration for the server
|
||||||
|
|
||||||
|
func DefaultOptions(cfg *Config) (*Options, error)
|
||||||
|
DefaultOptions creates server options with default configuration
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
// Has unexported fields.
|
||||||
|
}
|
||||||
|
Server represents the HTTP server and its dependencies
|
||||||
|
|
||||||
|
func NewServer(options *Options) *Server
|
||||||
|
NewServer creates a new server instance with the given options
|
||||||
|
|
||||||
|
func (s *Server) Close() error
|
||||||
|
Close handles graceful shutdown of server dependencies
|
||||||
|
|
||||||
|
func (s *Server) Router() chi.Router
|
||||||
|
Router returns the chi router for testing
|
||||||
|
|
||||||
|
func (s *Server) Start() error
|
||||||
|
Start configures and starts the HTTP server
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## internal/auth
|
||||||
|
|
||||||
|
```go
|
||||||
|
package auth // import "novamd/internal/auth"
|
||||||
|
|
||||||
|
Package auth provides JWT token generation and validation
|
||||||
|
|
||||||
|
Package auth provides JWT token generation and validation
|
||||||
|
|
||||||
|
FUNCTIONS
|
||||||
|
|
||||||
|
func NewSessionService(db db.SessionStore, jwtManager JWTManager) *sessionManager
|
||||||
|
NewSessionService creates a new session service with the given database and
|
||||||
|
JWT manager revive:disable:unexported-return
|
||||||
|
|
||||||
|
|
||||||
|
TYPES
|
||||||
|
|
||||||
|
type Claims struct {
|
||||||
|
jwt.RegisteredClaims // Embedded standard JWT claims
|
||||||
|
UserID int `json:"uid"` // User identifier
|
||||||
|
Role string `json:"role"` // User role (admin, editor, viewer)
|
||||||
|
Type TokenType `json:"type"` // Token type (access or refresh)
|
||||||
|
}
|
||||||
|
Claims represents the custom claims we store in JWT tokens
|
||||||
|
|
||||||
|
type CookieManager interface {
|
||||||
|
GenerateAccessTokenCookie(token string) *http.Cookie
|
||||||
|
GenerateRefreshTokenCookie(token string) *http.Cookie
|
||||||
|
GenerateCSRFCookie(token string) *http.Cookie
|
||||||
|
InvalidateCookie(cookieType string) *http.Cookie
|
||||||
|
}
|
||||||
|
CookieManager interface defines methods for generating cookies
|
||||||
|
|
||||||
|
func NewCookieService(isDevelopment bool, domain string) CookieManager
|
||||||
|
NewCookieService creates a new cookie service
|
||||||
|
|
||||||
|
type JWTConfig struct {
|
||||||
|
SigningKey string // Secret key used to sign tokens
|
||||||
|
AccessTokenExpiry time.Duration // How long access tokens are valid
|
||||||
|
RefreshTokenExpiry time.Duration // How long refresh tokens are valid
|
||||||
|
}
|
||||||
|
JWTConfig holds the configuration for the JWT service
|
||||||
|
|
||||||
|
type JWTManager interface {
|
||||||
|
GenerateAccessToken(userID int, role string, sessionID string) (string, error)
|
||||||
|
GenerateRefreshToken(userID int, role string, sessionID string) (string, error)
|
||||||
|
ValidateToken(tokenString string) (*Claims, error)
|
||||||
|
}
|
||||||
|
JWTManager defines the interface for managing JWT tokens
|
||||||
|
|
||||||
|
func NewJWTService(config JWTConfig) (JWTManager, error)
|
||||||
|
NewJWTService creates a new JWT service with the provided configuration
|
||||||
|
Returns an error if the signing key is missing
|
||||||
|
|
||||||
|
type Middleware struct {
|
||||||
|
// Has unexported fields.
|
||||||
|
}
|
||||||
|
Middleware handles JWT authentication for protected routes
|
||||||
|
|
||||||
|
func NewMiddleware(jwtManager JWTManager, sessionManager SessionManager, cookieManager CookieManager) *Middleware
|
||||||
|
NewMiddleware creates a new authentication middleware
|
||||||
|
|
||||||
|
func (m *Middleware) Authenticate(next http.Handler) http.Handler
|
||||||
|
Authenticate middleware validates JWT tokens and sets user information in
|
||||||
|
context
|
||||||
|
|
||||||
|
func (m *Middleware) RequireRole(role string) func(http.Handler) http.Handler
|
||||||
|
RequireRole returns a middleware that ensures the user has the required role
|
||||||
|
|
||||||
|
func (m *Middleware) RequireWorkspaceAccess(next http.Handler) http.Handler
|
||||||
|
RequireWorkspaceAccess returns a middleware that ensures the user has access
|
||||||
|
to the workspace
|
||||||
|
|
||||||
|
type SessionManager interface {
|
||||||
|
CreateSession(userID int, role string) (*models.Session, string, error)
|
||||||
|
RefreshSession(refreshToken string) (string, error)
|
||||||
|
ValidateSession(sessionID string) (*models.Session, error)
|
||||||
|
InvalidateSession(token string) error
|
||||||
|
CleanExpiredSessions() error
|
||||||
|
}
|
||||||
|
SessionManager is an interface for managing user sessions
|
||||||
|
|
||||||
|
type TokenType string
|
||||||
|
TokenType represents the type of JWT token (access or refresh)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AccessToken TokenType = "access" // AccessToken - Short-lived token for API access
|
||||||
|
RefreshToken TokenType = "refresh" // RefreshToken - Long-lived token for obtaining new access tokens
|
||||||
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
## internal/context
|
## internal/context
|
||||||
@@ -271,6 +299,7 @@ type Migration struct {
|
|||||||
type SessionStore interface {
|
type SessionStore interface {
|
||||||
CreateSession(session *models.Session) error
|
CreateSession(session *models.Session) error
|
||||||
GetSessionByRefreshToken(refreshToken string) (*models.Session, error)
|
GetSessionByRefreshToken(refreshToken string) (*models.Session, error)
|
||||||
|
GetSessionByID(sessionID string) (*models.Session, error)
|
||||||
DeleteSession(sessionID string) error
|
DeleteSession(sessionID string) error
|
||||||
CleanExpiredSessions() error
|
CleanExpiredSessions() error
|
||||||
}
|
}
|
||||||
@@ -350,7 +379,7 @@ TYPES
|
|||||||
type Client interface {
|
type Client interface {
|
||||||
Clone() error
|
Clone() error
|
||||||
Pull() error
|
Pull() error
|
||||||
Commit(message string) error
|
Commit(message string) (CommitHash, error)
|
||||||
Push() error
|
Push() error
|
||||||
EnsureRepo() error
|
EnsureRepo() error
|
||||||
}
|
}
|
||||||
@@ -359,6 +388,12 @@ type Client interface {
|
|||||||
func New(url, username, token, workDir, commitName, commitEmail string) Client
|
func New(url, username, token, workDir, commitName, commitEmail string) Client
|
||||||
New creates a new git Client instance
|
New creates a new git Client instance
|
||||||
|
|
||||||
|
type CommitHash plumbing.Hash
|
||||||
|
CommitHash represents a Git commit hash
|
||||||
|
|
||||||
|
func (h CommitHash) String() string
|
||||||
|
String returns the string representation of the CommitHash
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
URL string
|
URL string
|
||||||
Username string
|
Username string
|
||||||
@@ -380,6 +415,16 @@ Package handlers contains the request handlers for the api routes.
|
|||||||
|
|
||||||
TYPES
|
TYPES
|
||||||
|
|
||||||
|
type CommitRequest struct {
|
||||||
|
Message string `json:"message" example:"Initial commit"`
|
||||||
|
}
|
||||||
|
CommitRequest represents a request to commit changes
|
||||||
|
|
||||||
|
type CommitResponse struct {
|
||||||
|
CommitHash string `json:"commitHash" example:"a1b2c3d4"`
|
||||||
|
}
|
||||||
|
CommitResponse represents a response to a commit request
|
||||||
|
|
||||||
type CreateUserRequest struct {
|
type CreateUserRequest struct {
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
@@ -393,6 +438,17 @@ type DeleteAccountRequest struct {
|
|||||||
}
|
}
|
||||||
DeleteAccountRequest represents a user account deletion request
|
DeleteAccountRequest represents a user account deletion request
|
||||||
|
|
||||||
|
type DeleteWorkspaceResponse struct {
|
||||||
|
NextWorkspaceName string `json:"nextWorkspaceName"`
|
||||||
|
}
|
||||||
|
DeleteWorkspaceResponse contains the name of the next workspace after
|
||||||
|
deleting the current one
|
||||||
|
|
||||||
|
type ErrorResponse struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
ErrorResponse is a generic error response
|
||||||
|
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
DB db.Database
|
DB db.Database
|
||||||
Storage storage.Manager
|
Storage storage.Manager
|
||||||
@@ -403,92 +459,286 @@ func NewHandler(db db.Database, s storage.Manager) *Handler
|
|||||||
NewHandler creates a new handler with the given dependencies
|
NewHandler creates a new handler with the given dependencies
|
||||||
|
|
||||||
func (h *Handler) AdminCreateUser() http.HandlerFunc
|
func (h *Handler) AdminCreateUser() 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 CookieAuth @ID adminCreateUser
|
||||||
|
@Accept json @Produce json @Param user body CreateUserRequest true
|
||||||
|
"User details" @Success 200 {object} models.User @Failure 400 {object}
|
||||||
|
ErrorResponse "Invalid request body" @Failure 400 {object} ErrorResponse
|
||||||
|
"Email, password, and role are required" @Failure 400 {object} ErrorResponse
|
||||||
|
"Password must be at least 8 characters" @Failure 409 {object} ErrorResponse
|
||||||
|
"Email already exists" @Failure 500 {object} ErrorResponse "Failed to
|
||||||
|
hash password" @Failure 500 {object} ErrorResponse "Failed to create user"
|
||||||
|
@Failure 500 {object} ErrorResponse "Failed to initialize user workspace"
|
||||||
|
@Router /admin/users [post]
|
||||||
|
|
||||||
func (h *Handler) AdminDeleteUser() http.HandlerFunc
|
func (h *Handler) AdminDeleteUser() 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 CookieAuth @ID
|
||||||
|
adminDeleteUser @Param userId path int true "User ID" @Success 204 "No
|
||||||
|
Content" @Failure 400 {object} ErrorResponse "Invalid user ID" @Failure
|
||||||
|
400 {object} ErrorResponse "Cannot delete your own account" @Failure 403
|
||||||
|
{object} ErrorResponse "Cannot delete other admin users" @Failure 404
|
||||||
|
{object} ErrorResponse "User not found" @Failure 500 {object} ErrorResponse
|
||||||
|
"Failed to delete user" @Router /admin/users/{userId} [delete]
|
||||||
|
|
||||||
func (h *Handler) AdminGetSystemStats() http.HandlerFunc
|
func (h *Handler) AdminGetSystemStats() http.HandlerFunc
|
||||||
AdminGetSystemStats returns system-wide statistics for admins
|
AdminGetSystemStats godoc @Summary Get system statistics @Description Get
|
||||||
|
system-wide statistics as an admin @Tags Admin @Security CookieAuth @ID
|
||||||
|
adminGetSystemStats @Produce json @Success 200 {object} SystemStats @Failure
|
||||||
|
500 {object} ErrorResponse "Failed to get user stats" @Failure 500 {object}
|
||||||
|
ErrorResponse "Failed to get file stats" @Router /admin/stats [get]
|
||||||
|
|
||||||
func (h *Handler) AdminGetUser() http.HandlerFunc
|
func (h *Handler) AdminGetUser() 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 CookieAuth @ID adminGetUser @Produce
|
||||||
|
json @Param userId path int true "User ID" @Success 200 {object} models.User
|
||||||
|
@Failure 400 {object} ErrorResponse "Invalid user ID" @Failure 404 {object}
|
||||||
|
ErrorResponse "User not found" @Router /admin/users/{userId} [get]
|
||||||
|
|
||||||
func (h *Handler) AdminListUsers() http.HandlerFunc
|
func (h *Handler) AdminListUsers() http.HandlerFunc
|
||||||
AdminListUsers returns a list of all users
|
AdminListUsers godoc @Summary List all users @Description Returns the list
|
||||||
|
of all users @Tags Admin @Security CookieAuth @ID adminListUsers @Produce
|
||||||
|
json @Success 200 {array} models.User @Failure 500 {object} ErrorResponse
|
||||||
|
"Failed to list users" @Router /admin/users [get]
|
||||||
|
|
||||||
func (h *Handler) AdminListWorkspaces() http.HandlerFunc
|
func (h *Handler) AdminListWorkspaces() http.HandlerFunc
|
||||||
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 CookieAuth
|
||||||
|
@ID adminListWorkspaces @Produce json @Success 200 {array} WorkspaceStats
|
||||||
|
@Failure 500 {object} ErrorResponse "Failed to list workspaces" @Failure
|
||||||
|
500 {object} ErrorResponse "Failed to get user" @Failure 500 {object}
|
||||||
|
ErrorResponse "Failed to get file stats" @Router /admin/workspaces [get]
|
||||||
|
|
||||||
func (h *Handler) AdminUpdateUser() http.HandlerFunc
|
func (h *Handler) AdminUpdateUser() 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 CookieAuth @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 {object} ErrorResponse "Invalid user
|
||||||
|
ID" @Failure 400 {object} ErrorResponse "Invalid request body" @Failure 404
|
||||||
|
{object} ErrorResponse "User not found" @Failure 500 {object} ErrorResponse
|
||||||
|
"Failed to hash password" @Failure 500 {object} ErrorResponse "Failed to
|
||||||
|
update user" @Router /admin/users/{userId} [put]
|
||||||
|
|
||||||
func (h *Handler) CreateWorkspace() http.HandlerFunc
|
func (h *Handler) CreateWorkspace() http.HandlerFunc
|
||||||
CreateWorkspace creates a new workspace
|
CreateWorkspace godoc @Summary Create workspace @Description Creates a new
|
||||||
|
workspace @Tags workspaces @ID createWorkspace @Security CookieAuth @Accept
|
||||||
|
json @Produce json @Param body body models.Workspace true "Workspace"
|
||||||
|
@Success 200 {object} models.Workspace @Failure 400 {object} ErrorResponse
|
||||||
|
"Invalid request body" @Failure 400 {object} ErrorResponse "Invalid
|
||||||
|
workspace" @Failure 500 {object} ErrorResponse "Failed to create workspace"
|
||||||
|
@Failure 500 {object} ErrorResponse "Failed to initialize workspace
|
||||||
|
directory" @Failure 500 {object} ErrorResponse "Failed to setup git repo"
|
||||||
|
@Router /workspaces [post]
|
||||||
|
|
||||||
func (h *Handler) DeleteAccount() http.HandlerFunc
|
func (h *Handler) DeleteAccount() 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
|
||||||
|
CookieAuth @Accept json @Produce json @Param body body DeleteAccountRequest
|
||||||
|
true "Account deletion request" @Success 204 "No Content - Account deleted
|
||||||
|
successfully" @Failure 400 {object} ErrorResponse "Invalid request body"
|
||||||
|
@Failure 401 {object} ErrorResponse "Password is incorrect" @Failure 403
|
||||||
|
{object} ErrorResponse "Cannot delete the last admin account" @Failure 404
|
||||||
|
{object} ErrorResponse "User not found" @Failure 500 {object} ErrorResponse
|
||||||
|
"Failed to verify admin status" @Failure 500 {object} ErrorResponse "Failed
|
||||||
|
to delete account" @Router /profile [delete]
|
||||||
|
|
||||||
func (h *Handler) DeleteFile() http.HandlerFunc
|
func (h *Handler) DeleteFile() 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 CookieAuth
|
||||||
|
@Param workspace_name path string true "Workspace name" @Param
|
||||||
|
file_path path string true "File path" @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/{file_path} [delete]
|
||||||
|
|
||||||
func (h *Handler) DeleteWorkspace() http.HandlerFunc
|
func (h *Handler) DeleteWorkspace() http.HandlerFunc
|
||||||
DeleteWorkspace deletes the current workspace
|
DeleteWorkspace godoc @Summary Delete workspace @Description Deletes
|
||||||
|
the current workspace @Tags workspaces @ID deleteWorkspace @Security
|
||||||
|
CookieAuth @Produce json @Param workspace_name path string true "Workspace
|
||||||
|
name" @Success 200 {object} DeleteWorkspaceResponse @Failure 400 {object}
|
||||||
|
ErrorResponse "Cannot delete the last workspace" @Failure 500 {object}
|
||||||
|
ErrorResponse "Failed to get workspaces" @Failure 500 {object} ErrorResponse
|
||||||
|
"Failed to start transaction" @Failure 500 {object} ErrorResponse "Failed
|
||||||
|
to update last workspace" @Failure 500 {object} ErrorResponse "Failed to
|
||||||
|
delete workspace" @Failure 500 {object} ErrorResponse "Failed to rollback
|
||||||
|
transaction" @Failure 500 {object} ErrorResponse "Failed to commit
|
||||||
|
transaction" @Router /workspaces/{workspace_name} [delete]
|
||||||
|
|
||||||
func (h *Handler) GetCurrentUser() http.HandlerFunc
|
func (h *Handler) GetCurrentUser() http.HandlerFunc
|
||||||
GetCurrentUser returns the currently authenticated user
|
GetCurrentUser godoc @Summary Get current user @Description Returns
|
||||||
|
the current authenticated user @Tags auth @ID getCurrentUser @Security
|
||||||
|
CookieAuth @Produce json @Success 200 {object} models.User @Failure 404
|
||||||
|
{object} ErrorResponse "User not found" @Router /auth/me [get]
|
||||||
|
|
||||||
func (h *Handler) GetFileContent() http.HandlerFunc
|
func (h *Handler) GetFileContent() 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 CookieAuth @Produce plain @Param workspace_name path string
|
||||||
|
true "Workspace name" @Param file_path path string true "File path"
|
||||||
|
@Success 200 {string} string "Raw file content" @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/{file_path} [get]
|
||||||
|
|
||||||
func (h *Handler) GetLastOpenedFile() http.HandlerFunc
|
func (h *Handler) GetLastOpenedFile() 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 CookieAuth @Produce json @Param
|
||||||
|
workspace_name path string true "Workspace name" @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) GetLastWorkspaceName() http.HandlerFunc
|
func (h *Handler) GetLastWorkspaceName() 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 CookieAuth @Produce json @Success 200
|
||||||
|
{object} LastWorkspaceNameResponse @Failure 500 {object} ErrorResponse
|
||||||
|
"Failed to get last workspace" @Router /workspaces/last [get]
|
||||||
|
|
||||||
func (h *Handler) GetWorkspace() http.HandlerFunc
|
func (h *Handler) GetWorkspace() http.HandlerFunc
|
||||||
GetWorkspace returns the current workspace
|
GetWorkspace godoc @Summary Get workspace @Description Returns the current
|
||||||
|
workspace @Tags workspaces @ID getWorkspace @Security CookieAuth @Produce
|
||||||
|
json @Param workspace_name path string true "Workspace name" @Success 200
|
||||||
|
{object} models.Workspace @Failure 500 {object} ErrorResponse "Internal
|
||||||
|
server error" @Router /workspaces/{workspace_name} [get]
|
||||||
|
|
||||||
func (h *Handler) ListFiles() http.HandlerFunc
|
func (h *Handler) ListFiles() http.HandlerFunc
|
||||||
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 CookieAuth @Produce
|
||||||
|
json @Param workspace_name path string true "Workspace name" @Success 200
|
||||||
|
{array} storage.FileNode @Failure 500 {object} ErrorResponse "Failed to list
|
||||||
|
files" @Router /workspaces/{workspace_name}/files [get]
|
||||||
|
|
||||||
func (h *Handler) ListWorkspaces() http.HandlerFunc
|
func (h *Handler) ListWorkspaces() http.HandlerFunc
|
||||||
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 CookieAuth @Produce json @Success 200 {array} models.Workspace
|
||||||
|
@Failure 500 {object} ErrorResponse "Failed to list workspaces" @Router
|
||||||
|
/workspaces [get]
|
||||||
|
|
||||||
func (h *Handler) Login(authService *auth.SessionService) http.HandlerFunc
|
func (h *Handler) Login(authManager auth.SessionManager, cookieService auth.CookieManager) http.HandlerFunc
|
||||||
Login handles user authentication and returns JWT tokens
|
Login godoc @Summary Login @Description Logs in a user and returns a
|
||||||
|
session with access and refresh tokens @Tags auth @Accept json @Produce
|
||||||
|
json @Param body body LoginRequest true "Login request" @Success 200
|
||||||
|
{object} LoginResponse @Header 200 {string} X-CSRF-Token "CSRF token for
|
||||||
|
future requests" @Failure 400 {object} ErrorResponse "Invalid request
|
||||||
|
body" @Failure 400 {object} ErrorResponse "Email and password are required"
|
||||||
|
@Failure 401 {object} ErrorResponse "Invalid credentials" @Failure 500
|
||||||
|
{object} ErrorResponse "Failed to create session" @Failure 500 {object}
|
||||||
|
ErrorResponse "Failed to generate CSRF token" @Router /auth/login [post]
|
||||||
|
|
||||||
func (h *Handler) Logout(authService *auth.SessionService) http.HandlerFunc
|
func (h *Handler) Logout(authManager auth.SessionManager, cookieService auth.CookieManager) http.HandlerFunc
|
||||||
Logout invalidates the user's session
|
Logout godoc @Summary Logout @Description Log out invalidates the user's
|
||||||
|
session @Tags auth @ID logout @Success 204 "No Content" @Failure 400
|
||||||
|
{object} ErrorResponse "Session ID required" @Failure 500 {object}
|
||||||
|
ErrorResponse "Failed to logout" @Router /auth/logout [post]
|
||||||
|
|
||||||
func (h *Handler) LookupFileByName() http.HandlerFunc
|
func (h *Handler) LookupFileByName() 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 CookieAuth @Produce json @Param workspace_name
|
||||||
|
path string true "Workspace name" @Param filename query string true
|
||||||
|
"File name" @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) PullChanges() http.HandlerFunc
|
func (h *Handler) PullChanges() 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
|
||||||
|
CookieAuth @Produce json @Param workspace_name path string true "Workspace
|
||||||
|
name" @Success 200 {object} PullResponse @Failure 500 {object} ErrorResponse
|
||||||
|
"Failed to pull changes" @Router /workspaces/{workspace_name}/git/pull
|
||||||
|
[post]
|
||||||
|
|
||||||
func (h *Handler) RefreshToken(authService *auth.SessionService) http.HandlerFunc
|
func (h *Handler) RefreshToken(authManager auth.SessionManager, cookieService auth.CookieManager) 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 @Success 200 @Header 200 {string} X-CSRF-Token "New CSRF
|
||||||
|
token" @Failure 400 {object} ErrorResponse "Refresh token required" @Failure
|
||||||
|
401 {object} ErrorResponse "Invalid refresh token" @Failure 500 {object}
|
||||||
|
ErrorResponse "Failed to generate CSRF token" @Router /auth/refresh [post]
|
||||||
|
|
||||||
func (h *Handler) SaveFile() http.HandlerFunc
|
func (h *Handler) SaveFile() 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 CookieAuth
|
||||||
|
@Accept plain @Produce json @Param workspace_name path string true
|
||||||
|
"Workspace name" @Param file_path path string true "File path" @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/{file_path} [post]
|
||||||
|
|
||||||
func (h *Handler) StageCommitAndPush() http.HandlerFunc
|
func (h *Handler) StageCommitAndPush() http.HandlerFunc
|
||||||
StageCommitAndPush stages, commits, and pushes changes to the remote
|
StageCommitAndPush godoc @Summary Stage, commit, and push changes
|
||||||
repository
|
@Description Stages, commits, and pushes changes to the remote repository
|
||||||
|
@Tags git @ID stageCommitAndPush @Security CookieAuth @Produce json
|
||||||
|
@Param workspace_name path string true "Workspace name" @Param body body
|
||||||
|
CommitRequest true "Commit request" @Success 200 {object} CommitResponse
|
||||||
|
@Failure 400 {object} ErrorResponse "Invalid request body" @Failure
|
||||||
|
400 {object} ErrorResponse "Commit message is required" @Failure 500
|
||||||
|
{object} ErrorResponse "Failed to stage, commit, and push changes" @Router
|
||||||
|
/workspaces/{workspace_name}/git/commit [post]
|
||||||
|
|
||||||
func (h *Handler) UpdateLastOpenedFile() http.HandlerFunc
|
func (h *Handler) UpdateLastOpenedFile() 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 CookieAuth @Accept json @Produce json
|
||||||
|
@Param workspace_name path string true "Workspace name" @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) UpdateLastWorkspaceName() http.HandlerFunc
|
func (h *Handler) UpdateLastWorkspaceName() 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 CookieAuth @Accept json @Produce json
|
||||||
|
@Success 204 "No Content - Last workspace updated successfully" @Failure
|
||||||
|
400 {object} ErrorResponse "Invalid request body" @Failure 500 {object}
|
||||||
|
ErrorResponse "Failed to update last workspace" @Router /workspaces/last
|
||||||
|
[put]
|
||||||
|
|
||||||
func (h *Handler) UpdateProfile() http.HandlerFunc
|
func (h *Handler) UpdateProfile() http.HandlerFunc
|
||||||
UpdateProfile updates the current user's profile
|
UpdateProfile godoc @Summary Update profile @Description Updates the
|
||||||
|
user's profile @Tags users @ID updateProfile @Security CookieAuth @Accept
|
||||||
|
json @Produce json @Param body body UpdateProfileRequest true "Profile
|
||||||
|
update request" @Success 200 {object} models.User @Failure 400 {object}
|
||||||
|
ErrorResponse "Invalid request body" @Failure 400 {object} ErrorResponse
|
||||||
|
"Current password is required to change password" @Failure 400 {object}
|
||||||
|
ErrorResponse "New password must be at least 8 characters long" @Failure
|
||||||
|
400 {object} ErrorResponse "Current password is required to change email"
|
||||||
|
@Failure 401 {object} ErrorResponse "Current password is incorrect"
|
||||||
|
@Failure 404 {object} ErrorResponse "User not found" @Failure 409 {object}
|
||||||
|
ErrorResponse "Email already in use" @Failure 500 {object} ErrorResponse
|
||||||
|
"Failed to process new password" @Failure 500 {object} ErrorResponse "Failed
|
||||||
|
to update profile" @Router /profile [put]
|
||||||
|
|
||||||
func (h *Handler) UpdateWorkspace() http.HandlerFunc
|
func (h *Handler) UpdateWorkspace() http.HandlerFunc
|
||||||
UpdateWorkspace updates the current workspace
|
UpdateWorkspace godoc @Summary Update workspace @Description Updates
|
||||||
|
the current workspace @Tags workspaces @ID updateWorkspace @Security
|
||||||
|
CookieAuth @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 {object} ErrorResponse
|
||||||
|
"Invalid request body" @Failure 500 {object} ErrorResponse "Failed to update
|
||||||
|
workspace" @Failure 500 {object} ErrorResponse "Failed to setup git repo"
|
||||||
|
@Router /workspaces/{workspace_name} [put]
|
||||||
|
|
||||||
|
type LastOpenedFileResponse struct {
|
||||||
|
LastOpenedFilePath string `json:"lastOpenedFilePath"`
|
||||||
|
}
|
||||||
|
LastOpenedFileResponse represents a response to a last opened file request
|
||||||
|
|
||||||
|
type LastWorkspaceNameResponse struct {
|
||||||
|
LastWorkspaceName string `json:"lastWorkspaceName"`
|
||||||
|
}
|
||||||
|
LastWorkspaceNameResponse contains the name of the last opened workspace
|
||||||
|
|
||||||
type LoginRequest struct {
|
type LoginRequest struct {
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
@@ -497,22 +747,28 @@ type LoginRequest struct {
|
|||||||
LoginRequest represents a user login request
|
LoginRequest represents a user login request
|
||||||
|
|
||||||
type LoginResponse struct {
|
type LoginResponse struct {
|
||||||
AccessToken string `json:"accessToken"`
|
User *models.User `json:"user"`
|
||||||
RefreshToken string `json:"refreshToken"`
|
SessionID string `json:"sessionId,omitempty"`
|
||||||
User *models.User `json:"user"`
|
ExpiresAt time.Time `json:"expiresAt,omitempty"`
|
||||||
Session *models.Session `json:"session"`
|
|
||||||
}
|
}
|
||||||
LoginResponse represents a user login response
|
LoginResponse represents a user login response
|
||||||
|
|
||||||
type RefreshRequest struct {
|
type LookupResponse struct {
|
||||||
RefreshToken string `json:"refreshToken"`
|
Paths []string `json:"paths"`
|
||||||
}
|
}
|
||||||
RefreshRequest represents a refresh token request
|
LookupResponse represents a response to a file lookup request
|
||||||
|
|
||||||
type RefreshResponse struct {
|
type PullResponse struct {
|
||||||
AccessToken string `json:"accessToken"`
|
Message string `json:"message" example:"Pulled changes from remote"`
|
||||||
}
|
}
|
||||||
RefreshResponse represents a refresh token response
|
PullResponse represents a response to a pull http request
|
||||||
|
|
||||||
|
type SaveFileResponse struct {
|
||||||
|
FilePath string `json:"filePath"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
|
}
|
||||||
|
SaveFileResponse represents a response to a save file request
|
||||||
|
|
||||||
type StaticHandler struct {
|
type StaticHandler struct {
|
||||||
// Has unexported fields.
|
// Has unexported fields.
|
||||||
@@ -532,6 +788,12 @@ type SystemStats struct {
|
|||||||
}
|
}
|
||||||
SystemStats holds system-wide statistics
|
SystemStats holds system-wide statistics
|
||||||
|
|
||||||
|
type UpdateLastOpenedFileRequest struct {
|
||||||
|
FilePath string `json:"filePath"`
|
||||||
|
}
|
||||||
|
UpdateLastOpenedFileRequest represents a request to update the last opened
|
||||||
|
file
|
||||||
|
|
||||||
type UpdateProfileRequest struct {
|
type UpdateProfileRequest struct {
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
@@ -733,7 +995,7 @@ func (e *PathValidationError) Error() string
|
|||||||
type RepositoryManager interface {
|
type RepositoryManager interface {
|
||||||
SetupGitRepo(userID, workspaceID int, gitURL, gitUser, gitToken, commitName, commitEmail string) error
|
SetupGitRepo(userID, workspaceID int, gitURL, gitUser, gitToken, commitName, commitEmail string) error
|
||||||
DisableGitRepo(userID, workspaceID int)
|
DisableGitRepo(userID, workspaceID int)
|
||||||
StageCommitAndPush(userID, workspaceID int, message string) error
|
StageCommitAndPush(userID, workspaceID int, message string) (git.CommitHash, error)
|
||||||
Pull(userID, workspaceID int) error
|
Pull(userID, workspaceID int) error
|
||||||
}
|
}
|
||||||
RepositoryManager defines the interface for managing Git repositories.
|
RepositoryManager defines the interface for managing Git repositories.
|
||||||
@@ -809,7 +1071,7 @@ func (s *Service) SetupGitRepo(userID, workspaceID int, gitURL, gitUser, gitToke
|
|||||||
The repository is cloned from the given gitURL using the given gitUser and
|
The repository is cloned from the given gitURL using the given gitUser and
|
||||||
gitToken.
|
gitToken.
|
||||||
|
|
||||||
func (s *Service) StageCommitAndPush(userID, workspaceID int, message string) error
|
func (s *Service) StageCommitAndPush(userID, workspaceID int, message string) (git.CommitHash, error)
|
||||||
StageCommitAndPush stages, commit with the message, and pushes the changes
|
StageCommitAndPush stages, commit with the message, and pushes the changes
|
||||||
to the Git repository. The git repository belongs to the given userID and is
|
to the Git repository. The git repository belongs to the given userID and is
|
||||||
associated with the given workspaceID.
|
associated with the given workspaceID.
|
||||||
|
|||||||
Reference in New Issue
Block a user