feat(handler): add Application handler, routes, and wiring
Add ApplicationHandler with CRUD + Submit endpoints. Register 6 routes, wire in app.go, update main_test.go references. 22 handler tests. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
174
internal/handler/application.go
Normal file
174
internal/handler/application.go
Normal file
@@ -0,0 +1,174 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gcy_hpc_server/internal/model"
|
||||
"gcy_hpc_server/internal/server"
|
||||
"gcy_hpc_server/internal/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ApplicationHandler struct {
|
||||
appSvc *service.ApplicationService
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewApplicationHandler(appSvc *service.ApplicationService, logger *zap.Logger) *ApplicationHandler {
|
||||
return &ApplicationHandler{appSvc: appSvc, logger: logger}
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) ListApplications(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize < 1 {
|
||||
pageSize = 20
|
||||
}
|
||||
|
||||
apps, total, err := h.appSvc.ListApplications(c.Request.Context(), page, pageSize)
|
||||
if err != nil {
|
||||
h.logger.Error("failed to list applications", zap.Error(err))
|
||||
server.InternalError(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
server.OK(c, gin.H{
|
||||
"applications": apps,
|
||||
"total": total,
|
||||
"page": page,
|
||||
"page_size": pageSize,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) CreateApplication(c *gin.Context) {
|
||||
var req model.CreateApplicationRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Warn("invalid request body for create application", zap.Error(err))
|
||||
server.BadRequest(c, "invalid request body")
|
||||
return
|
||||
}
|
||||
if req.Name == "" || req.ScriptTemplate == "" {
|
||||
h.logger.Warn("missing required fields for create application")
|
||||
server.BadRequest(c, "name and script_template are required")
|
||||
return
|
||||
}
|
||||
if len(req.Parameters) == 0 {
|
||||
req.Parameters = json.RawMessage(`[]`)
|
||||
}
|
||||
|
||||
id, err := h.appSvc.CreateApplication(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
h.logger.Error("failed to create application", zap.Error(err))
|
||||
server.InternalError(c, err.Error())
|
||||
return
|
||||
}
|
||||
h.logger.Info("application created", zap.Int64("id", id))
|
||||
server.Created(c, gin.H{"id": id})
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) GetApplication(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
h.logger.Warn("invalid application id", zap.String("id", c.Param("id")))
|
||||
server.BadRequest(c, "invalid id")
|
||||
return
|
||||
}
|
||||
app, err := h.appSvc.GetApplication(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
h.logger.Error("failed to get application", zap.Int64("id", id), zap.Error(err))
|
||||
server.InternalError(c, err.Error())
|
||||
return
|
||||
}
|
||||
if app == nil {
|
||||
h.logger.Warn("application not found", zap.Int64("id", id))
|
||||
server.NotFound(c, "application not found")
|
||||
return
|
||||
}
|
||||
server.OK(c, app)
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) UpdateApplication(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
h.logger.Warn("invalid application id for update", zap.String("id", c.Param("id")))
|
||||
server.BadRequest(c, "invalid id")
|
||||
return
|
||||
}
|
||||
var req model.UpdateApplicationRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Warn("invalid request body for update application", zap.Int64("id", id), zap.Error(err))
|
||||
server.BadRequest(c, "invalid request body")
|
||||
return
|
||||
}
|
||||
if err := h.appSvc.UpdateApplication(c.Request.Context(), id, &req); err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
h.logger.Warn("application not found for update", zap.Int64("id", id))
|
||||
server.NotFound(c, "application not found")
|
||||
return
|
||||
}
|
||||
h.logger.Error("failed to update application", zap.Int64("id", id), zap.Error(err))
|
||||
server.InternalError(c, "failed to update application")
|
||||
return
|
||||
}
|
||||
h.logger.Info("application updated", zap.Int64("id", id))
|
||||
server.OK(c, gin.H{"message": "application updated"})
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) DeleteApplication(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
h.logger.Warn("invalid application id for delete", zap.String("id", c.Param("id")))
|
||||
server.BadRequest(c, "invalid id")
|
||||
return
|
||||
}
|
||||
if err := h.appSvc.DeleteApplication(c.Request.Context(), id); err != nil {
|
||||
h.logger.Error("failed to delete application", zap.Int64("id", id), zap.Error(err))
|
||||
server.InternalError(c, err.Error())
|
||||
return
|
||||
}
|
||||
h.logger.Info("application deleted", zap.Int64("id", id))
|
||||
server.OK(c, gin.H{"message": "application deleted"})
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) SubmitApplication(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
h.logger.Warn("invalid application id for submit", zap.String("id", c.Param("id")))
|
||||
server.BadRequest(c, "invalid id")
|
||||
return
|
||||
}
|
||||
var req model.ApplicationSubmitRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Warn("invalid request body for submit application", zap.Int64("id", id), zap.Error(err))
|
||||
server.BadRequest(c, "invalid request body")
|
||||
return
|
||||
}
|
||||
resp, err := h.appSvc.SubmitFromApplication(c.Request.Context(), id, req.Values)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
if strings.Contains(errStr, "not found") {
|
||||
h.logger.Warn("application not found for submit", zap.Int64("id", id))
|
||||
server.NotFound(c, errStr)
|
||||
return
|
||||
}
|
||||
if strings.Contains(errStr, "validation") {
|
||||
h.logger.Warn("application submit validation failed", zap.Int64("id", id), zap.Error(err))
|
||||
server.BadRequest(c, errStr)
|
||||
return
|
||||
}
|
||||
h.logger.Error("failed to submit application", zap.Int64("id", id), zap.Error(err))
|
||||
server.InternalError(c, errStr)
|
||||
return
|
||||
}
|
||||
h.logger.Info("application submitted", zap.Int64("id", id), zap.Int32("job_id", resp.JobID))
|
||||
server.Created(c, resp)
|
||||
}
|
||||
Reference in New Issue
Block a user