163 lines
5.2 KiB
Go
163 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))
|
||
|
|
}
|