Initial commit: Plataforma de Economía
Features: - React 18 + TypeScript frontend with Vite - Go + Gin backend API - PostgreSQL database - JWT authentication with refresh tokens - User management (admin panel) - Docker containerization - Progress tracking system - 4 economic modules structure Fixed: - Login with username or email - User creation without required email - Database nullable timestamps - API response field naming
This commit is contained in:
146
backend/internal/handlers/progreso.go
Normal file
146
backend/internal/handlers/progreso.go
Normal file
@@ -0,0 +1,146 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/ren/econ/backend/internal/models"
|
||||
"github.com/ren/econ/backend/internal/repository"
|
||||
)
|
||||
|
||||
type ProgresoHandler struct {
|
||||
progresoRepo *repository.ProgresoRepository
|
||||
}
|
||||
|
||||
func NewProgresoHandler(progresoRepo *repository.ProgresoRepository) *ProgresoHandler {
|
||||
return &ProgresoHandler{progresoRepo: progresoRepo}
|
||||
}
|
||||
|
||||
// GetProgreso godoc
|
||||
// @Summary Obtener todo el progreso
|
||||
// @Description Obtiene todo el progreso del usuario autenticado
|
||||
// @Tags progreso
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {array} models.Progreso
|
||||
// @Router /api/progreso [get]
|
||||
func (h *ProgresoHandler) GetProgreso(c *gin.Context) {
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "No autorizado"})
|
||||
return
|
||||
}
|
||||
|
||||
progresos, err := h.progresoRepo.GetByUsuario(c.Request.Context(), userID.(uuid.UUID))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Error al obtener progreso"})
|
||||
return
|
||||
}
|
||||
|
||||
if progresos == nil {
|
||||
progresos = []models.Progreso{}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, progresos)
|
||||
}
|
||||
|
||||
// GetProgresoModulo godoc
|
||||
// @Summary Obtener progreso por módulo
|
||||
// @Description Obtiene el progreso del usuario en un módulo específico
|
||||
// @Tags progreso
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param numero path int true "Número del módulo"
|
||||
// @Success 200 {array} models.Progreso
|
||||
// @Router /api/progreso/modulo/{numero} [get]
|
||||
func (h *ProgresoHandler) GetProgresoModulo(c *gin.Context) {
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "No autorizado"})
|
||||
return
|
||||
}
|
||||
|
||||
moduloNumero, err := strconv.Atoi(c.Param("numero"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Número de módulo inválido"})
|
||||
return
|
||||
}
|
||||
|
||||
progresos, err := h.progresoRepo.GetByModulo(c.Request.Context(), userID.(uuid.UUID), moduloNumero)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Error al obtener progreso"})
|
||||
return
|
||||
}
|
||||
|
||||
if progresos == nil {
|
||||
progresos = []models.Progreso{}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, progresos)
|
||||
}
|
||||
|
||||
// UpdateProgreso godoc
|
||||
// @Summary Guardar avance
|
||||
// @Description Guarda el progreso de un ejercicio
|
||||
// @Tags progreso
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param ejercicioId path int true "ID del ejercicio"
|
||||
// @Param progreso body models.ProgresoUpdate true "Datos del progreso"
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {object} map[string]string
|
||||
// @Router /api/progreso/{ejercicioId} [put]
|
||||
func (h *ProgresoHandler) UpdateProgreso(c *gin.Context) {
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "No autorizado"})
|
||||
return
|
||||
}
|
||||
|
||||
ejercicioID, err := strconv.Atoi(c.Param("ejercicioId"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "ID de ejercicio inválido"})
|
||||
return
|
||||
}
|
||||
|
||||
var req models.ProgresoUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
err = h.progresoRepo.Upsert(c.Request.Context(), userID.(uuid.UUID), ejercicioID, &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Error al guardar progreso: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Progreso guardado exitosamente"})
|
||||
}
|
||||
|
||||
// GetResumen godoc
|
||||
// @Summary Obtener resumen
|
||||
// @Description Obtiene estadísticas del progreso del usuario
|
||||
// @Tags progreso
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {object} models.ProgresoResumen
|
||||
// @Router /api/progreso/resumen [get]
|
||||
func (h *ProgresoHandler) GetResumen(c *gin.Context) {
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "No autorizado"})
|
||||
return
|
||||
}
|
||||
|
||||
resumen, err := h.progresoRepo.GetResumen(c.Request.Context(), userID.(uuid.UUID))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Error al obtener resumen"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, resumen)
|
||||
}
|
||||
Reference in New Issue
Block a user