// models/personal_best.go package models import ( "time" "gorm.io/gorm" ) type DistanceType string const ( Distance5K DistanceType = "5k" Distance10K DistanceType = "10k" DistanceHalf DistanceType = "half_marathon" DistanceFull DistanceType = "marathon" DistanceOther DistanceType = "other" ) type PersonalBest struct { ID uint `json:"id" gorm:"primaryKey"` UserID uint `json:"user_id" gorm:"not null;index"` DistanceType DistanceType `json:"distance_type" gorm:"type:varchar(20);not null"` Time string `json:"time" gorm:"size:20;not null"` // Время в формате "HH:MM:SS" Pace string `json:"pace" gorm:"size:20"` // Темп Date time.Time `json:"date" gorm:"not null"` Verified bool `json:"verified" gorm:"default:false"` // Подтвержден ли результат EventName string `json:"event_name" gorm:"size:255"` // Название забега Location string `json:"location" gorm:"size:255"` // Место проведения CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` // Связи User User `json:"user,omitempty" gorm:"foreignKey:UserID"` } // BeforeCreate hook func (pb *PersonalBest) BeforeCreate(tx *gorm.DB) error { if pb.CreatedAt.IsZero() { pb.CreatedAt = time.Now() } if pb.UpdatedAt.IsZero() { pb.UpdatedAt = time.Now() } return nil } // BeforeUpdate hook func (pb *PersonalBest) BeforeUpdate(tx *gorm.DB) error { pb.UpdatedAt = time.Now() return nil } // DTO для создания личного рекорда type PersonalBestCreateRequest struct { DistanceType DistanceType `json:"distance_type" validate:"required,oneof=5k 10k half_marathon marathon other"` Time string `json:"time" validate:"required,max=20"` Pace string `json:"pace" validate:"max=20"` Date time.Time `json:"date" validate:"required"` EventName string `json:"event_name" validate:"max=255"` Location string `json:"location" validate:"max=255"` } // DTO для обновления личного рекорда type PersonalBestUpdateRequest struct { DistanceType DistanceType `json:"distance_type" validate:"omitempty,oneof=5k 10k half_marathon marathon other"` Time string `json:"time" validate:"omitempty,max=20"` Pace string `json:"pace" validate:"omitempty,max=20"` Date time.Time `json:"date"` EventName string `json:"event_name" validate:"omitempty,max=255"` Location string `json:"location" validate:"omitempty,max=255"` Verified bool `json:"verified"` } // PersonalBestsSummary представляет сводку лучших результатов по дистанциям type PersonalBestsSummary struct { Best5K string `json:"best_5k,omitempty"` Best5KPace string `json:"best_5k_pace,omitempty"` Best10K string `json:"best_10k,omitempty"` Best10KPace string `json:"best_10k_pace,omitempty"` BestHalf string `json:"best_half_marathon,omitempty"` BestHalfPace string `json:"best_half_marathon_pace,omitempty"` BestMarathon string `json:"best_marathon,omitempty"` BestMarathonPace string `json:"best_marathon_pace,omitempty"` }