130 lines
3.1 KiB
Go
130 lines
3.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"ci/internal/model"
|
|
"ci/internal/service"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// ProjectHandler handles project CRUD endpoints.
|
|
type ProjectHandler struct {
|
|
Svc *service.ProjectService
|
|
}
|
|
|
|
func NewProjectHandler(svc *service.ProjectService) *ProjectHandler {
|
|
return &ProjectHandler{Svc: svc}
|
|
}
|
|
|
|
// ListProjects returns all projects.
|
|
func (h *ProjectHandler) ListProjects(c *gin.Context) {
|
|
projects, err := h.Svc.ListProjects()
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if projects == nil {
|
|
projects = []model.Project{}
|
|
}
|
|
c.JSON(http.StatusOK, projects)
|
|
}
|
|
|
|
// GetProject returns a single project by ID.
|
|
func (h *ProjectHandler) GetProject(c *gin.Context) {
|
|
id, err := parseID(c)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project id"})
|
|
return
|
|
}
|
|
project, err := h.Svc.GetProject(id)
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "project not found"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, project)
|
|
}
|
|
|
|
// CreateProject creates a new project.
|
|
func (h *ProjectHandler) CreateProject(c *gin.Context) {
|
|
var p model.Project
|
|
if err := c.ShouldBindJSON(&p); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if p.Name == "" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "name is required"})
|
|
return
|
|
}
|
|
if p.Mode != "git" && p.Mode != "upload" {
|
|
p.Mode = "git" // default
|
|
}
|
|
if err := h.Svc.CreateProject(&p); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusCreated, p)
|
|
}
|
|
|
|
// UpdateProject updates an existing project.
|
|
func (h *ProjectHandler) UpdateProject(c *gin.Context) {
|
|
id, err := parseID(c)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project id"})
|
|
return
|
|
}
|
|
|
|
existing, err := h.Svc.GetProject(id)
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "project not found"})
|
|
return
|
|
}
|
|
|
|
var updates model.Project
|
|
if err := c.ShouldBindJSON(&updates); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
// Preserve fields that should not be updated from the request
|
|
updates.ID = existing.ID
|
|
updates.CreatedAt = existing.CreatedAt
|
|
updates.Status = existing.Status
|
|
updates.PID = existing.PID
|
|
// Preserve password if not sent
|
|
if updates.GitPassword == "" {
|
|
updates.GitPassword = existing.GitPassword
|
|
}
|
|
|
|
if err := h.Svc.UpdateProject(&updates); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, updates)
|
|
}
|
|
|
|
// DeleteProject deletes a project.
|
|
func (h *ProjectHandler) DeleteProject(c *gin.Context) {
|
|
id, err := parseID(c)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project id"})
|
|
return
|
|
}
|
|
if err := h.Svc.DeleteProject(id); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"message": "deleted"})
|
|
}
|
|
|
|
func parseID(c *gin.Context) (uint, error) {
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 64)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return uint(id), nil
|
|
}
|