package handlers import ( "fmt" "net/http" "git.linuxforward.com/byop/byop-engine/dbstore" "git.linuxforward.com/byop/byop-engine/models" "github.com/gin-gonic/gin" ) // ClientHandler handles client-related operations and contains integrated service logic type ClientHandler struct { store *dbstore.SQLiteStore } // NewClientHandler creates a new ClientHandler func NewClientHandler(store *dbstore.SQLiteStore) *ClientHandler { return &ClientHandler{ store: store, } } // ListClients returns all clients func (h *ClientHandler) ListClients(c *gin.Context) { filter := make(map[string]interface{}) ctx := c.Request.Context() // Attempt to bind query parameters, but allow empty filters if err := c.ShouldBindQuery(&filter); err != nil && len(filter) > 0 { appErr := models.NewErrValidation("invalid_query_params", nil, err) models.RespondWithError(c, appErr) return } clients, err := h.store.GetAllClients(ctx) if err != nil { appErr := models.NewErrInternalServer("failed_fetch_clients", fmt.Errorf("Failed to fetch clients: %w", err)) models.RespondWithError(c, appErr) return } c.JSON(http.StatusOK, clients) } // CreateClient creates a new client func (h *ClientHandler) CreateClient(c *gin.Context) { var client models.Client ctx := c.Request.Context() if err := c.ShouldBindJSON(&client); err != nil { appErr := models.NewErrValidation("invalid_request_body", nil, err) models.RespondWithError(c, appErr) return } // Validate client data if client.Name == "" { validationErrors := map[string]string{"name": "Client name is required"} appErr := models.NewErrValidation("client_name_required", validationErrors, nil) models.RespondWithError(c, appErr) return } err := h.store.CreateClient(ctx, &client) if err != nil { appErr := models.NewErrInternalServer("failed_create_client", fmt.Errorf("Failed to create client: %w", err)) models.RespondWithError(c, appErr) return } c.JSON(http.StatusCreated, client) } // GetClient returns a specific client func (h *ClientHandler) GetClient(c *gin.Context) { ctx := c.Request.Context() id, err := parseUintID(c, "id") if err != nil { models.RespondWithError(c, err) return } client, err := h.store.GetClientByID(ctx, id) if err != nil { models.RespondWithError(c, err) return } if client.ID == 0 { appErr := models.NewErrNotFound("client_not_found", fmt.Errorf("Client with ID %d not found", id)) models.RespondWithError(c, appErr) return } c.JSON(http.StatusOK, client) } // UpdateClient updates a client func (h *ClientHandler) UpdateClient(c *gin.Context) { ctx := c.Request.Context() id, err := parseUintID(c, "id") if err != nil { models.RespondWithError(c, err) return } var updatedClient models.Client if err := c.ShouldBindJSON(&updatedClient); err != nil { appErr := models.NewErrValidation("invalid_request_body", nil, err) models.RespondWithError(c, appErr) return } updatedClient.ID = id // Validate client data if updatedClient.Name == "" { validationErrors := map[string]string{"name": "Client name is required"} appErr := models.NewErrValidation("client_name_required", validationErrors, nil) models.RespondWithError(c, appErr) return } if err := h.store.UpdateClient(ctx, &updatedClient); err != nil { models.RespondWithError(c, err) return } c.JSON(http.StatusOK, updatedClient) } // DeleteClient deletes a client func (h *ClientHandler) DeleteClient(c *gin.Context) { ctx := c.Request.Context() id, err := parseUintID(c, "id") if err != nil { models.RespondWithError(c, err) return } if err := h.store.DeleteClient(ctx, id); err != nil { models.RespondWithError(c, err) return } c.Status(http.StatusNoContent) } // GetClientDeployments returns all deployments for a client func (h *ClientHandler) GetClientDeployments(c *gin.Context) { ctx := c.Request.Context() id, err := parseUintID(c, "id") if err != nil { models.RespondWithError(c, err) return } client, err := h.store.GetClientByID(ctx, id) if err != nil { models.RespondWithError(c, err) return } if client.ID == 0 { appErr := models.NewErrNotFound("client_not_found_for_deployments", fmt.Errorf("Client with ID %d not found", id)) models.RespondWithError(c, appErr) return } deployments := []models.Deployment{} c.JSON(http.StatusOK, deployments) }