go-first/internal/handler/handler.go
2026-10-07 15:21:47 +02:00

162 lines
5.2 KiB
Go

package handler
import (
"net/http"
"github.com/dnoulet/go-first/internal/model"
"github.com/dnoulet/go-first/internal/service"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
)
type Handler struct {
skillService *service.SkillService
projectService *service.ProjectService
experienceService *service.ExperienceService
serviceService *service.ServiceService
contactService *service.ContactService
}
func NewHandler(
skillService *service.SkillService,
projectService *service.ProjectService,
experienceService *service.ExperienceService,
serviceService *service.ServiceService,
contactService *service.ContactService,
) *Handler {
return &Handler{
skillService: skillService,
projectService: projectService,
experienceService: experienceService,
serviceService: serviceService,
contactService: contactService,
}
}
func (h *Handler) RegisterRoutes(r *gin.Engine) {
api := r.Group("/api/v1")
{
api.GET("/health", h.HealthCheck)
api.GET("/skills", h.GetSkills)
api.GET("/skills/:id", h.GetSkill)
api.GET("/projects", h.GetProjects)
api.GET("/projects/featured", h.GetFeaturedProjects)
api.GET("/projects/:id", h.GetProject)
api.GET("/experience", h.GetExperience)
api.GET("/services", h.GetServices)
api.POST("/contact", h.SubmitContact)
}
}
func (h *Handler) HealthCheck(c *gin.Context) {
c.JSON(http.StatusOK, model.SuccessResponse(gin.H{
"status": "ok",
"service": "go-first",
"version": "1.0.0",
}))
}
func (h *Handler) GetSkills(c *gin.Context) {
category := c.Query("category")
skills, err := h.skillService.GetAll(c.Request.Context(), category)
if err != nil {
log.Error().Err(err).Msg("Failed to get skills")
c.JSON(http.StatusInternalServerError, model.ErrorResponse("INTERNAL_ERROR", "Failed to retrieve skills", err.Error()))
return
}
c.JSON(http.StatusOK, model.SuccessResponse(skills))
}
func (h *Handler) GetSkill(c *gin.Context) {
idStr := c.Param("id")
id, err := uuid.Parse(idStr)
if err != nil {
c.JSON(http.StatusBadRequest, model.ErrorResponse("INVALID_ID", "Invalid skill ID", err.Error()))
return
}
skill, err := h.skillService.GetByID(c.Request.Context(), id)
if err != nil {
log.Error().Err(err).Str("id", idStr).Msg("Failed to get skill")
c.JSON(http.StatusNotFound, model.ErrorResponse("NOT_FOUND", "Skill not found", err.Error()))
return
}
c.JSON(http.StatusOK, model.SuccessResponse(skill))
}
func (h *Handler) GetProjects(c *gin.Context) {
category := c.Query("category")
featured := c.Query("featured") == "true"
projects, err := h.projectService.GetAll(c.Request.Context(), category, featured)
if err != nil {
log.Error().Err(err).Msg("Failed to get projects")
c.JSON(http.StatusInternalServerError, model.ErrorResponse("INTERNAL_ERROR", "Failed to retrieve projects", err.Error()))
return
}
c.JSON(http.StatusOK, model.SuccessResponse(projects))
}
func (h *Handler) GetFeaturedProjects(c *gin.Context) {
projects, err := h.projectService.GetFeatured(c.Request.Context())
if err != nil {
log.Error().Err(err).Msg("Failed to get featured projects")
c.JSON(http.StatusInternalServerError, model.ErrorResponse("INTERNAL_ERROR", "Failed to retrieve featured projects", err.Error()))
return
}
c.JSON(http.StatusOK, model.SuccessResponse(projects))
}
func (h *Handler) GetProject(c *gin.Context) {
idStr := c.Param("id")
id, err := uuid.Parse(idStr)
if err != nil {
c.JSON(http.StatusBadRequest, model.ErrorResponse("INVALID_ID", "Invalid project ID", err.Error()))
return
}
project, err := h.projectService.GetByID(c.Request.Context(), id)
if err != nil {
log.Error().Err(err).Str("id", idStr).Msg("Failed to get project")
c.JSON(http.StatusNotFound, model.ErrorResponse("NOT_FOUND", "Project not found", err.Error()))
return
}
c.JSON(http.StatusOK, model.SuccessResponse(project))
}
func (h *Handler) GetExperience(c *gin.Context) {
experience, err := h.experienceService.GetAll(c.Request.Context())
if err != nil {
log.Error().Err(err).Msg("Failed to get experience")
c.JSON(http.StatusInternalServerError, model.ErrorResponse("INTERNAL_ERROR", "Failed to retrieve experience", err.Error()))
return
}
c.JSON(http.StatusOK, model.SuccessResponse(experience))
}
func (h *Handler) GetServices(c *gin.Context) {
services, err := h.serviceService.GetAll(c.Request.Context())
if err != nil {
log.Error().Err(err).Msg("Failed to get services")
c.JSON(http.StatusInternalServerError, model.ErrorResponse("INTERNAL_ERROR", "Failed to retrieve services", err.Error()))
return
}
c.JSON(http.StatusOK, model.SuccessResponse(services))
}
func (h *Handler) SubmitContact(c *gin.Context) {
var req model.ContactForm
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, model.ErrorResponse("VALIDATION_ERROR", "Invalid request body", err.Error()))
return
}
submission, err := h.contactService.Create(c.Request.Context(), &req)
if err != nil {
log.Error().Err(err).Msg("Failed to create contact submission")
c.JSON(http.StatusInternalServerError, model.ErrorResponse("INTERNAL_ERROR", "Failed to submit contact form", err.Error()))
return
}
c.JSON(http.StatusCreated, model.SuccessResponse(submission))
}