5c9abf5f94
modified: serv_nginx/api_bb/internal/models/training_plan.go new file: serv_nginx/api_bb/internal/service/training_plan_service.go create CRUD for traing_plan
291 lines
8.5 KiB
Go
291 lines
8.5 KiB
Go
// service/training_plan_service.go
|
|
package service
|
|
|
|
import (
|
|
"api_bb/internal/models"
|
|
"api_bb/internal/repository"
|
|
"api_bb/pkg/logger"
|
|
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type TrainingPlanService interface {
|
|
CreateTrainingPlan(userID uint, req *models.TrainingPlanCreateRequest) (*models.TrainingPlan, error)
|
|
GetTrainingPlansByUserID(userID uint) ([]models.TrainingPlan, error)
|
|
GetTrainingPlanByID(userID uint, planID uint) (*models.TrainingPlan, error)
|
|
UpdateTrainingPlan(userID uint, planID uint, req *models.TrainingPlanUpdateRequest) (*models.TrainingPlan, error)
|
|
DeleteTrainingPlan(userID uint, planID uint) error
|
|
GetActiveTrainingPlan(userID uint) (*models.TrainingPlan, error)
|
|
MarkTrainingPlanAsCompleted(userID uint, planID uint) error
|
|
UpdateCurrentWeek(userID uint, planID uint, currentWeek int) error
|
|
}
|
|
|
|
type trainingPlanService struct {
|
|
trainingPlanRepo repository.TrainingPlanRepository
|
|
logger logger.LoggerInterface
|
|
}
|
|
|
|
func NewTrainingPlanService(trainingPlanRepo repository.TrainingPlanRepository) TrainingPlanService {
|
|
return &trainingPlanService{
|
|
trainingPlanRepo: trainingPlanRepo,
|
|
logger: logger.NewWrapper(logger.Get().With(zap.String("service", "training_plan"))),
|
|
}
|
|
}
|
|
|
|
// CreateTrainingPlan создает новый план тренировок
|
|
func (s *trainingPlanService) CreateTrainingPlan(userID uint, req *models.TrainingPlanCreateRequest) (*models.TrainingPlan, error) {
|
|
s.logger.Debug("creating training plan",
|
|
zap.Uint("user_id", userID),
|
|
zap.String("title", req.Title),
|
|
)
|
|
|
|
plan := &models.TrainingPlan{
|
|
UserID: userID,
|
|
Title: req.Title,
|
|
Description: req.Description,
|
|
Weeks: req.Weeks,
|
|
WorkoutsPerWeek: req.WorkoutsPerWeek,
|
|
TargetDistance: req.TargetDistance,
|
|
TargetDate: req.TargetDate,
|
|
CurrentWeek: 1,
|
|
Completed: false,
|
|
}
|
|
|
|
if err := s.trainingPlanRepo.Create(plan); err != nil {
|
|
s.logger.Error("failed to create training plan in repository",
|
|
zap.Uint("user_id", userID),
|
|
zap.Error(err),
|
|
)
|
|
return nil, err
|
|
}
|
|
|
|
s.logger.Debug("training plan created successfully",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", plan.ID),
|
|
)
|
|
|
|
return plan, nil
|
|
}
|
|
|
|
// GetTrainingPlansByUserID возвращает все планы тренировок пользователя
|
|
func (s *trainingPlanService) GetTrainingPlansByUserID(userID uint) ([]models.TrainingPlan, error) {
|
|
s.logger.Debug("getting training plans for user", zap.Uint("user_id", userID))
|
|
|
|
plans, err := s.trainingPlanRepo.GetByUserID(userID)
|
|
if err != nil {
|
|
s.logger.Error("failed to get training plans from repository",
|
|
zap.Uint("user_id", userID),
|
|
zap.Error(err),
|
|
)
|
|
return nil, err
|
|
}
|
|
|
|
s.logger.Debug("training plans retrieved successfully",
|
|
zap.Uint("user_id", userID),
|
|
zap.Int("count", len(plans)),
|
|
)
|
|
|
|
return plans, nil
|
|
}
|
|
|
|
// GetTrainingPlanByID возвращает план тренировок по ID
|
|
func (s *trainingPlanService) GetTrainingPlanByID(userID uint, planID uint) (*models.TrainingPlan, error) {
|
|
s.logger.Debug("getting training plan by ID",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
)
|
|
|
|
plan, err := s.trainingPlanRepo.GetByID(planID)
|
|
if err != nil {
|
|
s.logger.Error("failed to get training plan from repository",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
zap.Error(err),
|
|
)
|
|
return nil, err
|
|
}
|
|
|
|
// Проверяем, что план принадлежит пользователю
|
|
if plan.UserID != userID {
|
|
s.logger.Warn("training plan access denied - user mismatch",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_user_id", plan.UserID),
|
|
zap.Uint("plan_id", planID),
|
|
)
|
|
return nil, repository.ErrNotFound
|
|
}
|
|
|
|
s.logger.Debug("training plan retrieved successfully",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
)
|
|
|
|
return plan, nil
|
|
}
|
|
|
|
// UpdateTrainingPlan обновляет план тренировок
|
|
func (s *trainingPlanService) UpdateTrainingPlan(userID uint, planID uint, req *models.TrainingPlanUpdateRequest) (*models.TrainingPlan, error) {
|
|
s.logger.Debug("updating training plan",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
)
|
|
|
|
// Сначала получаем существующий план
|
|
plan, err := s.GetTrainingPlanByID(userID, planID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Обновляем только переданные поля
|
|
if req.Title != "" {
|
|
plan.Title = req.Title
|
|
}
|
|
if req.Description != "" {
|
|
plan.Description = req.Description
|
|
}
|
|
if req.Weeks > 0 {
|
|
plan.Weeks = req.Weeks
|
|
}
|
|
if req.WorkoutsPerWeek > 0 {
|
|
plan.WorkoutsPerWeek = req.WorkoutsPerWeek
|
|
}
|
|
if req.TargetDistance != "" {
|
|
plan.TargetDistance = req.TargetDistance
|
|
}
|
|
if !req.TargetDate.IsZero() {
|
|
plan.TargetDate = req.TargetDate
|
|
}
|
|
|
|
// Сохраняем обновления
|
|
if err := s.trainingPlanRepo.Update(plan); err != nil {
|
|
s.logger.Error("failed to update training plan in repository",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
zap.Error(err),
|
|
)
|
|
return nil, err
|
|
}
|
|
|
|
s.logger.Debug("training plan updated successfully",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
)
|
|
|
|
return plan, nil
|
|
}
|
|
|
|
// DeleteTrainingPlan удаляет план тренировок
|
|
func (s *trainingPlanService) DeleteTrainingPlan(userID uint, planID uint) error {
|
|
s.logger.Debug("deleting training plan",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
)
|
|
|
|
// Проверяем, что план существует и принадлежит пользователю
|
|
_, err := s.GetTrainingPlanByID(userID, planID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Удаляем план
|
|
if err := s.trainingPlanRepo.Delete(planID); err != nil {
|
|
s.logger.Error("failed to delete training plan from repository",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
zap.Error(err),
|
|
)
|
|
return err
|
|
}
|
|
|
|
s.logger.Debug("training plan deleted successfully",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
)
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetActiveTrainingPlan возвращает активный план тренировок пользователя
|
|
func (s *trainingPlanService) GetActiveTrainingPlan(userID uint) (*models.TrainingPlan, error) {
|
|
s.logger.Debug("getting active training plan for user", zap.Uint("user_id", userID))
|
|
|
|
plan, err := s.trainingPlanRepo.GetActivePlan(userID)
|
|
if err != nil {
|
|
s.logger.Error("failed to get active training plan from repository",
|
|
zap.Uint("user_id", userID),
|
|
zap.Error(err),
|
|
)
|
|
return nil, err
|
|
}
|
|
|
|
s.logger.Debug("active training plan retrieved successfully",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", plan.ID),
|
|
)
|
|
|
|
return plan, nil
|
|
}
|
|
|
|
// MarkTrainingPlanAsCompleted помечает план тренировок как завершенный
|
|
func (s *trainingPlanService) MarkTrainingPlanAsCompleted(userID uint, planID uint) error {
|
|
s.logger.Debug("marking training plan as completed",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
)
|
|
|
|
// Проверяем, что план существует и принадлежит пользователю
|
|
_, err := s.GetTrainingPlanByID(userID, planID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Помечаем как завершенный
|
|
if err := s.trainingPlanRepo.MarkAsCompleted(planID); err != nil {
|
|
s.logger.Error("failed to mark training plan as completed in repository",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
zap.Error(err),
|
|
)
|
|
return err
|
|
}
|
|
|
|
s.logger.Debug("training plan marked as completed successfully",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
)
|
|
|
|
return nil
|
|
}
|
|
|
|
// UpdateCurrentWeek обновляет текущую неделю плана тренировок
|
|
func (s *trainingPlanService) UpdateCurrentWeek(userID uint, planID uint, currentWeek int) error {
|
|
s.logger.Debug("updating current week for training plan",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
zap.Int("current_week", currentWeek),
|
|
)
|
|
|
|
// Проверяем, что план существует и принадлежит пользователю
|
|
_, err := s.GetTrainingPlanByID(userID, planID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Обновляем текущую неделю
|
|
if err := s.trainingPlanRepo.UpdateCurrentWeek(planID, currentWeek); err != nil {
|
|
s.logger.Error("failed to update current week in repository",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
zap.Error(err),
|
|
)
|
|
return err
|
|
}
|
|
|
|
s.logger.Debug("current week updated successfully",
|
|
zap.Uint("user_id", userID),
|
|
zap.Uint("plan_id", planID),
|
|
zap.Int("current_week", currentWeek),
|
|
)
|
|
|
|
return nil
|
|
} |