diff --git a/internal/handlers/achievement_handler.go b/internal/handlers/achievement_handler.go index 5ac8282..5bcd122 100644 --- a/internal/handlers/achievement_handler.go +++ b/internal/handlers/achievement_handler.go @@ -1 +1,152 @@ package handlers + +import ( + "context" + "net/http" + "strconv" + + "github.com/labstack/echo/v4" + "github.com/sirupsen/logrus" + "theaesthetics.ru/base/internal/models" + "theaesthetics.ru/base/internal/services" +) + +type AchievementsHandler struct { + service *services.AchievementsService +} + +func NewAhievementsHandler(service *services.AchievementsService) *AchievementsHandler { + return &AchievementsHandler{service: service} +} + +func (h *AchievementsHandler) GetAllAchievements(c echo.Context) error { + ctx := c.Request().Context() + achievements, err := h.service.GetAllAchievements(ctx) + if err != nil { + logrus.Error(err) + + return c.JSON(http.StatusInternalServerError, map[string]string{ + "error": err.Error(), + }) + } + + return c.JSON(http.StatusOK, achievements) +} + +func (h *AchievementsHandler) GetAchievementById(c echo.Context) error { + ctx := c.Request().Context() + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + logrus.Error(err) + + return c.JSON(http.StatusBadRequest, map[string]string{ + "error": err.Error(), + }) + } + + var idu8 uint8 = uint8(id) + achievement, err := h.service.GetAchievementById(ctx, idu8) + + if err != nil { + logrus.Error(err) + + return c.JSON(http.StatusBadRequest, map[string]string{ + "error": err.Error(), + }) + } + return c.JSON(http.StatusOK, achievement) +} + +func (h *AchievementsHandler) CreateAchievement(c echo.Context) error { + ctx := context.Background() + var achieve models.Achievenment + err := c.Bind(&achieve) + + if err != nil { + logrus.Error(err) + + return c.JSON(http.StatusBadRequest, map[string]string{ + "error": err.Error(), + }) + } + + err = h.service.CreateAchievement(ctx, achieve) + + if err != nil { + logrus.Error(err) + + return c.JSON(http.StatusBadRequest, map[string]string{ + "error": err.Error(), + }) + } + + return c.JSON(http.StatusCreated, map[string]string{ + "message": "created", + }) +} + +func (h *AchievementsHandler) DeleteAchievement(c echo.Context) error { + ctx := context.Background() + id, err := strconv.Atoi(c.Param("id")) + + if err != nil { + logrus.Error(err) + + return c.JSON(http.StatusBadRequest, map[string]string{ + "error": err.Error(), + }) + } + uid := uint8(id) + err = h.service.DeleteAchievement(ctx, uid) + + if err != nil { + logrus.Error(err) + + return c.JSON(http.StatusBadRequest, map[string]string{ + "error": err.Error(), + }) + } + + return c.JSON(http.StatusOK, map[string]string{ + "message": "deleted", + }) +} + +func (h *AchievementsHandler) UpdateAchievement(c echo.Context) error { + ctx := context.Background() + id, err := strconv.Atoi(c.Param("id")) + + if err != nil { + logrus.Error(err) + + return c.JSON(http.StatusBadRequest, map[string]string{ + "error": err.Error(), + }) + } + uid := uint8(id) + + achieve := models.Achievenment{Id: uid} + err = c.Bind(&achieve) + + if err != nil { + logrus.Error(err) + + return c.JSON(http.StatusBadRequest, map[string]string{ + "error": err.Error(), + }) + } + + err = h.service.UpdateAchievement(ctx, achieve) + + if err != nil { + logrus.Error(err) + + return c.JSON(http.StatusInternalServerError, map[string]string{ + "error": err.Error(), + }) + } + + return c.JSON(http.StatusCreated, map[string]string{ + "message": "updated", + }) +} diff --git a/internal/handlers/exercise_handler.go b/internal/handlers/exercise_handler.go index 5ac8282..9d0f96e 100644 --- a/internal/handlers/exercise_handler.go +++ b/internal/handlers/exercise_handler.go @@ -1 +1,116 @@ package handlers + +import ( + "context" + "net/http" + "strconv" + + "github.com/labstack/echo/v4" + "github.com/sirupsen/logrus" + "theaesthetics.ru/base/internal/models" + "theaesthetics.ru/base/internal/services" +) + +type ExerciseHandler struct { + service *services.ExercisesService +} + +func NewExerciseHandler(service *services.ExercisesService) *ExerciseHandler { + return &ExerciseHandler{service: service} +} + +func (h *ExerciseHandler) GetAllExercises(c echo.Context) error { + ctx := context.Background() + exercises, err := h.service.GetAllExercises(ctx) + if err != nil { + logrus.WithError(err).Error("Failed to get exercises") + return respondWithError(c, http.StatusInternalServerError, err) + } + + return c.JSON(http.StatusOK, exercises) +} + +func (h *ExerciseHandler) GetExerciseById(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + logrus.WithError(err).Error("Invalid exercise ID") + return respondWithError(c, http.StatusBadRequest, err) + } + uid := uint8(id) + + ctx := context.Background() + exercise, err := h.service.GetExerciseById(ctx, uid) + if err != nil { + logrus.WithError(err).Error("Exercise not found") + return respondWithError(c, http.StatusNotFound, err) + } + + return c.JSON(http.StatusOK, exercise) +} + +func (h *ExerciseHandler) CreateExercise(c echo.Context) error { + ctx := context.Background() + + var exercise models.FullExercises + if err := c.Bind(&exercise); err != nil { + logrus.WithError(err).Error("Failed to bind request data") + return respondWithError(c, http.StatusBadRequest, err) + } + + id, err := h.service.CreateExercise(ctx, exercise) + if err != nil { + logrus.WithError(err).Error("Failed to create exercise") + return respondWithError(c, http.StatusInternalServerError, err) + } + + return c.JSON(http.StatusCreated, map[string]interface{}{ + "message": "Exercise created successfully", + "id": id, + }) +} + +func (h *ExerciseHandler) UpdateExercise(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + logrus.WithError(err).Error("Invalid exercise ID") + return respondWithError(c, http.StatusBadRequest, err) + } + uid := uint8(id) + + ctx := context.Background() + + var exercise models.FullExercises + if err := c.Bind(&exercise); err != nil { + logrus.WithError(err).Error("Failed to bind request data") + return respondWithError(c, http.StatusBadRequest, err) + } + + if err := h.service.UpdateExercise(ctx, uid, exercise); err != nil { + logrus.WithError(err).Error("Failed to update exercise") + return respondWithError(c, http.StatusInternalServerError, err) + } + + return c.JSON(http.StatusOK, map[string]string{ + "message": "Exercise updated successfully", + }) +} + +func (h *ExerciseHandler) DeleteExercise(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + logrus.WithError(err).Error("Invalid exercise ID") + return respondWithError(c, http.StatusBadRequest, err) + } + uid := uint8(id) + + ctx := context.Background() + + if err := h.service.DeleteExercise(ctx, uid); err != nil { + logrus.WithError(err).Error("Failed to delete exercise") + return respondWithError(c, http.StatusInternalServerError, err) + } + + return c.JSON(http.StatusOK, map[string]string{ + "message": "Exercise deleted successfully", + }) +} diff --git a/internal/handlers/user_handler.go b/internal/handlers/user_handler.go index 5ac8282..55888ee 100644 --- a/internal/handlers/user_handler.go +++ b/internal/handlers/user_handler.go @@ -1 +1,66 @@ package handlers + +import ( + "context" + "net/http" + "strconv" + + "github.com/labstack/echo/v4" + "github.com/sirupsen/logrus" + "theaesthetics.ru/base/internal/services" +) + +type UserHandler struct { + service *services.UserService +} + +func NewUserHandler(service *services.UserService) *UserHandler { + return &UserHandler{service: service} +} + +func (h *UserHandler) GetAllUsers(c echo.Context) error { + ctx := context.Background() + users, err := h.service.GetAllUsers(ctx) + if err != nil { + logrus.WithError(err).Error("Failed to get users") + return respondWithError(c, http.StatusInternalServerError, err) + } + + return c.JSON(http.StatusOK, users) +} + +func (h *UserHandler) GetUserById(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + logrus.WithError(err).Error("Invalid user ID") + return respondWithError(c, http.StatusBadRequest, err) + } + uid := uint(id) + + ctx := context.Background() + user, err := h.service.GetUserById(ctx, uid) + if err != nil { + logrus.WithError(err).Error("Failed to get user") + return respondWithError(c, http.StatusInternalServerError, err) + } + + return c.JSON(http.StatusOK, user) +} + +func (h *UserHandler) GetUserAchievements(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + logrus.WithError(err).Error("Invalid user ID") + return respondWithError(c, http.StatusBadRequest, err) + } + uid := uint(id) + + ctx := context.Background() + achievements, err := h.service.GetUserAchievements(ctx, uid) + if err != nil { + logrus.WithError(err).Error("Failed to get achievements") + return respondWithError(c, http.StatusInternalServerError, err) + } + + return c.JSON(http.StatusOK, achievements) +} diff --git a/internal/models/achievement.go b/internal/models/achievement.go index 2640e7f..6f939b4 100644 --- a/internal/models/achievement.go +++ b/internal/models/achievement.go @@ -1 +1,8 @@ package models + +type Achievenment struct { + Id uint8 `json:"id"` + Title string `json:"title"` + Description string `json:"descripton"` + Image string `json:"image"` +} diff --git a/internal/models/exercise.go b/internal/models/exercise.go index 2640e7f..f8c65fe 100644 --- a/internal/models/exercise.go +++ b/internal/models/exercise.go @@ -1 +1,30 @@ package models + +type Exercises struct { + Id uint8 `json:"id"` + Title string `json:"title"` + Image string `json:"image"` + Description string `json:"descripton"` + Video_url string `json:"video_url"` + EquipmentId uint8 `json:"equipment_id"` + Sets uint8 `json:"Sets"` + Reps uint8 `json:"Reps"` + Difficult uint8 `json:"Difficult"` + Lead_muscle_id uint8 `json:"lead_muscle_id"` +} + +type FullExercises struct { + Id uint8 `json:"id"` + Title string `json:"title"` + + Image string `json:"image"` + Description string `json:"descripton"` + Video_url string `json:"video_url"` + + Sets uint8 `json:"sets"` + Reps uint8 `json:"reps"` + Difficult uint8 `json:"difficult"` + + Equipment Equipment `json:"equipment"` + Muscles Muscles `json:"muscle"` +} diff --git a/internal/models/user.go b/internal/models/user.go index 2640e7f..d959eab 100644 --- a/internal/models/user.go +++ b/internal/models/user.go @@ -1 +1,23 @@ package models + +type User struct { + ID uint `json:"id"` + Login string `json:"login"` + Password string `json:"-"` + Nickname string `json:"nickname"` + Avatar string `json:"avatar,omitempty"` + AdvancedVersion bool `json:"advanced_version"` + Phone string `json:"phone,omitempty"` + IsVerifiedPhone bool `json:"is_verified_phone"` + Email string `json:"email"` + IsVerifiedMail bool `json:"is_verified_mail"` + Age int `json:"age,omitempty"` + Height int `json:"height,omitempty"` + Weight int `json:"weight,omitempty"` + Sex string `json:"sex,omitempty"` + DayStreak int `json:"day_streak"` + IsTrainToday bool `json:"is_train_today"` + Points int `json:"points"` + CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` +} diff --git a/internal/repository/achievement_repository.go b/internal/repository/achievement_repository.go index 50a4378..8713295 100644 --- a/internal/repository/achievement_repository.go +++ b/internal/repository/achievement_repository.go @@ -1 +1,116 @@ package repository + +import ( + "context" + "fmt" + + "github.com/jackc/pgx/v5/pgxpool" + "github.com/sirupsen/logrus" + "theaesthetics.ru/base/internal/models" +) + +const tableNameAchievement = "achievements" + +type AchievementsRepository struct { + db *pgxpool.Pool +} + +func NewAchievementsRepository(db *pgxpool.Pool) *AchievementsRepository { + return &AchievementsRepository{db: db} +} + +func (r *AchievementsRepository) GetAllAchievements(ctx context.Context) ([]models.Achievenment, error) { + query := `SELECT id, title, image, description FROM achievements` + rows, err := r.db.Query(ctx, query) + if err != nil { + return nil, err + } + defer rows.Close() + var achievements []models.Achievenment + for rows.Next() { + var achieve models.Achievenment + err := rows.Scan(&achieve.Id, &achieve.Title, &achieve.Image, &achieve.Description) + if err != nil { + return nil, err + } + achievements = append(achievements, achieve) + } + return achievements, nil +} + +func (r *AchievementsRepository) GetAchievementById(ctx context.Context, id uint8) (*models.Achievenment, error) { + query := `SELECT id, title, image, description FROM achievements WHERE id = $1` + row := r.db.QueryRow(ctx, query, id) + + achieve := &models.Achievenment{} + err := row.Scan(&achieve.Id, &achieve.Title, &achieve.Image, &achieve.Description) + + if err != nil { + return nil, err + } + + return achieve, nil +} + +func (r *AchievementsRepository) CreateAchievement(ctx context.Context, achieve models.Achievenment) error { + tx, err := r.db.Begin(ctx) + if err != nil { + return err + } + defer tx.Rollback(ctx) + + err = checkTitle(tx, ctx, achieve.Title, tableNameAchievement) + if err != nil { + return err + } + + query := `INSERT INTO achievements (title, image, description) VALUES ($1, $2, $3)` + _, err = r.db.Exec(ctx, query, achieve.Title, achieve.Image, achieve.Description) + if err != nil { + return err + } + + err = tx.Commit(ctx) + if err != nil { + return fmt.Errorf("transaction commit failed: %w", err) + } + + return nil +} + +func (r *AchievementsRepository) DeleteAchievement(ctx context.Context, id uint8) error { + query := `DELETE FROM achievements WHERE id = $1` + _, err := r.db.Exec(ctx, query, id) + if err != nil { + return err + } + + return nil +} + +func (r *AchievementsRepository) UpdateAchievement(ctx context.Context, achieve models.Achievenment) error { + tx, err := r.db.Begin(ctx) + if err != nil { + logrus.Error() + return err + } + defer tx.Rollback(ctx) + + err = checkTitle(tx, ctx, achieve.Title, tableNameAchievement) + if err != nil { + return err + } + + query := `UPDATE achievements SET title = $1, image = $2, description = $3 WHERE id = $4` + _, err = r.db.Exec(ctx, query, achieve.Title, achieve.Image, achieve.Description, achieve.Id) + if err != nil { + return err + } + + err = tx.Commit(ctx) + if err != nil { + return fmt.Errorf("transaction commit failed: %w", err) + } + + return nil +} diff --git a/internal/repository/equipment_repository.go b/internal/repository/equipment_repository.go index 802c758..b308a08 100644 --- a/internal/repository/equipment_repository.go +++ b/internal/repository/equipment_repository.go @@ -102,7 +102,7 @@ func (r *EquipmentRepository) UpdateEquipment(ctx context.Context, equipment mod } query := `UPDATE equipments SET title = $1, image = $2 WHERE id = $3` - _, err = r.db.Exec(ctx, query, equipment.Title, equipment.Image, equipment.Id) + _, err = tx.Exec(ctx, query, equipment.Title, equipment.Image, equipment.Id) if err != nil { return err } diff --git a/internal/repository/exercise_repository.go b/internal/repository/exercise_repository.go index 50a4378..ae2856a 100644 --- a/internal/repository/exercise_repository.go +++ b/internal/repository/exercise_repository.go @@ -1 +1,171 @@ package repository + +import ( + "context" + "fmt" + + "github.com/jackc/pgx/v5/pgxpool" + "theaesthetics.ru/base/internal/models" +) + +type ExercisesRepository struct { + db *pgxpool.Pool +} + +func NewExercisesRepository(db *pgxpool.Pool) *ExercisesRepository { + return &ExercisesRepository{db: db} +} +func (r *ExercisesRepository) GetAllExercises(ctx context.Context) ([]models.FullExercises, error) { + query := ` + SELECT + exercises.id, + exercises.title, + COALESCE(exercises.description, '') AS description, + COALESCE(exercises.image, '') AS image, + COALESCE(exercises.video_url, '') AS video_url, + exercises.sets, + exercises.reps, + exercises.difficult, + COALESCE(equipments.id, 0) AS equipment_id, + COALESCE(equipments.title, '') AS equipment_title, + COALESCE(equipments.image, '') AS equipment_image, + COALESCE(muscles.id, 0) AS muscle_id, + COALESCE(muscles.title, '') AS muscle_title, + COALESCE(muscles.image, '') AS muscle_image + FROM exercises + LEFT JOIN equipments ON equipments.id = exercises.equipment_id + LEFT JOIN muscles ON muscles.id = exercises.lead_muscle_id + ` + var exercises []models.FullExercises + + rows, err := r.db.Query(ctx, query) + if err != nil { + return nil, err + } + defer rows.Close() + + for rows.Next() { + var exercise models.FullExercises + err := rows.Scan(&exercise.Id, &exercise.Title, &exercise.Description, &exercise.Image, &exercise.Video_url, + &exercise.Sets, &exercise.Reps, &exercise.Difficult, + &exercise.Equipment.Id, &exercise.Equipment.Title, &exercise.Equipment.Image, + &exercise.Muscles.Id, &exercise.Muscles.Title, &exercise.Muscles.Image) + if err != nil { + return nil, err + } + + exercises = append(exercises, exercise) + } + + return exercises, nil +} + +func (r *ExercisesRepository) GetExerciseById(ctx context.Context, id uint8) (models.FullExercises, error) { + query := ` + SELECT + exercises.id, + exercises.title, + COALESCE(exercises.description, '') AS description, + COALESCE(exercises.image, '') AS image, + COALESCE(exercises.video_url, '') AS video_url, + exercises.sets, + exercises.reps, + exercises.difficult, + COALESCE(equipments.id, 0) AS equipment_id, + COALESCE(equipments.title, '') AS equipment_title, + COALESCE(equipments.image, '') AS equipment_image, + COALESCE(muscles.id, 0) AS muscle_id, + COALESCE(muscles.title, '') AS muscle_title, + COALESCE(muscles.image, '') AS muscle_image + FROM exercises + LEFT JOIN equipments ON equipments.id = exercises.equipment_id + LEFT JOIN muscles ON muscles.id = exercises.lead_muscle_id + WHERE exercises.id = $1; + + ` + var exercise models.FullExercises + + row := r.db.QueryRow(ctx, query, id) + err := row.Scan(&exercise.Id, &exercise.Title, &exercise.Description, &exercise.Image, &exercise.Video_url, + &exercise.Sets, &exercise.Reps, &exercise.Difficult, + &exercise.Equipment.Id, &exercise.Equipment.Title, &exercise.Equipment.Image, + &exercise.Muscles.Id, &exercise.Muscles.Title, &exercise.Muscles.Image) + + if err != nil { + return models.FullExercises{}, err + } + + return exercise, nil +} + +func (r *ExercisesRepository) CreateExercise(ctx context.Context, exercise models.FullExercises) (uint8, error) { + tx, err := r.db.Begin(ctx) + if err != nil { + return 0, err + } + defer tx.Rollback(ctx) + + query := ` + INSERT INTO exercises (title, description, image, video_url, sets, reps, difficult, equipment_id, lead_muscle_id) + VALUES ($1, $2, $3, $4, $5, $6, $7, + (SELECT id FROM equipments WHERE title = $8), + (SELECT id FROM muscles WHERE title = $9)) + RETURNING id + ` + + var id uint64 + err = tx.QueryRow(ctx, query, exercise.Title, exercise.Description, exercise.Image, exercise.Video_url, + exercise.Sets, exercise.Reps, exercise.Difficult, exercise.Equipment.Title, exercise.Muscles.Title).Scan(&id) + + if err != nil { + return 0, err + } + + err = tx.Commit(ctx) + if err != nil { + return 0, fmt.Errorf("transaction commit failed: %w", err) + } + + return uint8(id), nil +} + +func (r *ExercisesRepository) DeleteExercise(ctx context.Context, id uint8) error { + query := `DELETE FROM exercises WHERE id = $1` + + _, err := r.db.Exec(ctx, query, id) + if err != nil { + return err + } + + return nil +} + +func (r *ExercisesRepository) UpdateExercise(ctx context.Context, id uint8, exercise models.FullExercises) error { + tx, err := r.db.Begin(ctx) + if err != nil { + return err + } + defer tx.Rollback(ctx) + + query := ` + UPDATE exercises + SET title = $1, description = $2, image = $3, video_url = $4, + sets = $5, reps = $6, difficult = $7, + equipment_id = (SELECT id FROM equipments WHERE title = $8), + lead_muscle_id = (SELECT id FROM muscles WHERE title = $9) + WHERE id = $10 + ` + + _, err = tx.Exec(ctx, query, exercise.Title, exercise.Description, exercise.Image, exercise.Video_url, + exercise.Sets, exercise.Reps, exercise.Difficult, exercise.Equipment.Title, exercise.Muscles.Title, id) + + if err != nil { + return err + } + + err = tx.Commit(ctx) + if err != nil { + return fmt.Errorf("transaction commit failed: %w", err) + } + return err +} diff --git a/internal/repository/train_repository.go b/internal/repository/train_repository.go index 83a583b..936af19 100644 --- a/internal/repository/train_repository.go +++ b/internal/repository/train_repository.go @@ -89,7 +89,7 @@ func (r *TrainsRepository) CreateTrain(ctx context.Context, train models.Train) } query := `INSERT INTO trains (title, description, image, video_url, difficult, duration_time, lead_muscle_id) VALUES ($1, $2, $3, $4, $5, $6, $7)` - _, err = r.db.Exec(ctx, query, train.Title, train.Description, train.Image, train.Video_url, train.Difficult, train.Duration_time, train.Lead_muscle_id) + _, err = tx.Exec(ctx, query, train.Title, train.Description, train.Image, train.Video_url, train.Difficult, train.Duration_time, train.Lead_muscle_id) if err != nil { return err } diff --git a/internal/repository/user_repository.go b/internal/repository/user_repository.go index 50a4378..0cda4fa 100644 --- a/internal/repository/user_repository.go +++ b/internal/repository/user_repository.go @@ -1 +1,112 @@ package repository + +import ( + "context" + + "github.com/jackc/pgx/v5/pgxpool" + "theaesthetics.ru/base/internal/models" +) + +type UserRepository struct { + db *pgxpool.Pool +} + +func NewUserRepository(db *pgxpool.Pool) *UserRepository { + return &UserRepository{db: db} +} + +func (r *UserRepository) GetAllUsers(ctx context.Context) ([]models.User, error) { + query := ` + SELECT + id, login, nickname, COALESCE(avatar, '') AS avatar, advanced_version, + COALESCE(phone, '') AS phone, is_verified_phone, email, is_verified_mail, + COALESCE(age, 0) AS age, COALESCE(height, 0) AS height, COALESCE(weight, 0) AS weight, + COALESCE(sex, '') AS sex, day_streak, is_train_today, points, created_at, update_at + FROM users + ` + + var users []models.User + + rows, err := r.db.Query(ctx, query) + if err != nil { + return nil, err + } + defer rows.Close() + + for rows.Next() { + var user models.User + err := rows.Scan( + &user.ID, &user.Login, &user.Nickname, &user.Avatar, &user.AdvancedVersion, + &user.Phone, &user.IsVerifiedPhone, &user.Email, &user.IsVerifiedMail, + &user.Age, &user.Height, &user.Weight, &user.Sex, &user.DayStreak, + &user.IsTrainToday, &user.Points, &user.CreatedAt, &user.UpdatedAt, + ) + if err != nil { + return nil, err + } + + users = append(users, user) + } + + return users, nil +} + +func (r *UserRepository) GetUserById(ctx context.Context, id uint) (models.User, error) { + query := ` + SELECT + id, login, nickname, COALESCE(avatar, '') AS avatar, advanced_version, + COALESCE(phone, '') AS phone, is_verified_phone, email, is_verified_mail, + COALESCE(age, 0) AS age, COALESCE(height, 0) AS height, COALESCE(weight, 0) AS weight, + COALESCE(sex, '') AS sex, day_streak, is_train_today, points, created_at, update_at + FROM users + WHERE id = $1 + ` + + var user models.User + + row := r.db.QueryRow(ctx, query, id) + err := row.Scan( + &user.ID, &user.Login, &user.Nickname, &user.Avatar, &user.AdvancedVersion, + &user.Phone, &user.IsVerifiedPhone, &user.Email, &user.IsVerifiedMail, + &user.Age, &user.Height, &user.Weight, &user.Sex, &user.DayStreak, + &user.IsTrainToday, &user.Points, &user.CreatedAt, &user.UpdatedAt, + ) + if err != nil { + return models.User{}, err + } + + return user, nil +} + +func (r *UserRepository) GetUserAchievements(ctx context.Context, userId uint) ([]models.Achievenment, error) { + query := ` + SELECT + achievements.id, + achievements.title, + achievements.description, + achievements.image, + FROM achievements + JOIN user_achievements ON user_achievements.achievement_id = achievements.id + WHERE user_achievements.user_id = $1 + ` + + var achievements []models.Achievenment + + rows, err := r.db.Query(ctx, query, userId) + if err != nil { + return nil, err + } + defer rows.Close() + + for rows.Next() { + var achievement models.Achievenment + err := rows.Scan(&achievement.Id, &achievement.Title, &achievement.Description, &achievement.Image) + if err != nil { + return nil, err + } + + achievements = append(achievements, achievement) + } + + return achievements, nil +} diff --git a/internal/router/router.go b/internal/router/router.go index 795af8d..4d42a41 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -21,6 +21,16 @@ func InitRouter(e *echo.Echo, db *pgxpool.Pool) { api.PUT("/equipment/:id", eqHandler.UpdateEqipment) api.DELETE("/equipment/:id", eqHandler.DeleteEquipment) + ahRepo := repository.NewAchievementsRepository(db) + ahService := services.NewAchievementsService(ahRepo) + ahHandler := handlers.NewAhievementsHandler(ahService) + + api.GET("/ahievements", ahHandler.GetAllAchievements) + api.POST("/ahievements", ahHandler.CreateAchievement) + api.GET("/ahievements/:id", ahHandler.GetAchievementById) + api.PUT("/ahievements/:id", ahHandler.UpdateAchievement) + api.DELETE("/ahievements/:id", ahHandler.DeleteAchievement) + msRepo := repository.NewMusclesRepository(db) msService := services.NewMusclesService(msRepo) msHandler := handlers.NewMusclesHandler(msService) @@ -38,4 +48,23 @@ func InitRouter(e *echo.Echo, db *pgxpool.Pool) { api.GET("/trains", trHandler.GetAllTrains) api.POST("/train", trHandler.CreateTrain) api.GET("/trains/:id", trHandler.GetTrainById) + + exRepo := repository.NewExercisesRepository(db) + exService := services.NewExercisesService(exRepo) + exHandler := handlers.NewExerciseHandler(exService) + + api.GET("/exercises", exHandler.GetAllExercises) + api.POST("/exercises", exHandler.CreateExercise) + api.GET("/exercises/:id", exHandler.GetExerciseById) + api.PUT("/exercises/:id", exHandler.UpdateExercise) + api.DELETE("/exercises/:id", exHandler.DeleteExercise) + + usRepo := repository.NewUserRepository(db) + usService := services.NewUserService(usRepo) + usHandler := handlers.NewUserHandler(usService) + + api.GET("/users", usHandler.GetAllUsers) + api.GET("/users/:id", usHandler.GetUserById) + api.GET("/users/:id/achievements", usHandler.GetUserAchievements) + } diff --git a/internal/services/achievement_service.go b/internal/services/achievement_service.go index 5e568ea..8ba09e3 100644 --- a/internal/services/achievement_service.go +++ b/internal/services/achievement_service.go @@ -1 +1,36 @@ package services + +import ( + "context" + + "theaesthetics.ru/base/internal/models" + "theaesthetics.ru/base/internal/repository" +) + +type AchievementsService struct { + repo *repository.AchievementsRepository +} + +func NewAchievementsService(repo *repository.AchievementsRepository) *AchievementsService { + return &AchievementsService{repo: repo} +} + +func (s *AchievementsService) GetAllAchievements(ctx context.Context) ([]models.Achievenment, error) { + return s.repo.GetAllAchievements(ctx) +} + +func (s *AchievementsService) GetAchievementById(ctx context.Context, id uint8) (*models.Achievenment, error) { + return s.repo.GetAchievementById(ctx, id) +} + +func (s *AchievementsService) CreateAchievement(ctx context.Context, achieve models.Achievenment) error { + return s.repo.CreateAchievement(ctx, achieve) +} + +func (s *AchievementsService) DeleteAchievement(ctx context.Context, id uint8) error { + return s.repo.DeleteAchievement(ctx, id) +} + +func (s *AchievementsService) UpdateAchievement(ctx context.Context, achieve models.Achievenment) error { + return s.repo.UpdateAchievement(ctx, achieve) +} diff --git a/internal/services/exercise_service.go b/internal/services/exercise_service.go index 5e568ea..f1b4ba2 100644 --- a/internal/services/exercise_service.go +++ b/internal/services/exercise_service.go @@ -1 +1,36 @@ package services + +import ( + "context" + + "theaesthetics.ru/base/internal/models" + "theaesthetics.ru/base/internal/repository" +) + +type ExercisesService struct { + repo *repository.ExercisesRepository +} + +func NewExercisesService(repo *repository.ExercisesRepository) *ExercisesService { + return &ExercisesService{repo: repo} +} + +func (s *ExercisesService) GetAllExercises(ctx context.Context) ([]models.FullExercises, error) { + return s.repo.GetAllExercises(ctx) +} + +func (s *ExercisesService) GetExerciseById(ctx context.Context, id uint8) (models.FullExercises, error) { + return s.repo.GetExerciseById(ctx, id) +} + +func (s *ExercisesService) CreateExercise(ctx context.Context, exercise models.FullExercises) (uint8, error) { + return s.repo.CreateExercise(ctx, exercise) +} + +func (s *ExercisesService) UpdateExercise(ctx context.Context, id uint8, exercise models.FullExercises) error { + return s.repo.UpdateExercise(ctx, id, exercise) +} + +func (s *ExercisesService) DeleteExercise(ctx context.Context, id uint8) error { + return s.repo.DeleteExercise(ctx, id) +} diff --git a/internal/services/user_service.go b/internal/services/user_service.go index 5e568ea..8ce1d2b 100644 --- a/internal/services/user_service.go +++ b/internal/services/user_service.go @@ -1 +1,28 @@ package services + +import ( + "context" + + "theaesthetics.ru/base/internal/models" + "theaesthetics.ru/base/internal/repository" +) + +type UserService struct { + repo *repository.UserRepository +} + +func NewUserService(repo *repository.UserRepository) *UserService { + return &UserService{repo: repo} +} + +func (s *UserService) GetAllUsers(ctx context.Context) ([]models.User, error) { + return s.repo.GetAllUsers(ctx) +} + +func (s *UserService) GetUserById(ctx context.Context, id uint) (models.User, error) { + return s.repo.GetUserById(ctx, id) +} + +func (s *UserService) GetUserAchievements(ctx context.Context, userId uint) ([]models.Achievenment, error) { + return s.repo.GetUserAchievements(ctx, userId) +}