Files
rideaware-api/internal/equipment/model.go

84 lines
3.6 KiB
Go

package equipment
import "time"
type Equipment struct {
ID uint `gorm:"primaryKey" json:"id"`
UserID uint `gorm:"not null;index" json:"user_id"`
Name string `gorm:"not null" json:"name"`
Type string `gorm:"not null" json:"type"` // "bike", "shoes", "helmet", etc.
Brand string `gorm:"default:''" json:"brand"`
Model string `gorm:"default:''" json:"model"`
Weight float64 `gorm:"default:0" json:"weight"` // grams
Notes string `gorm:"default:''" json:"notes"`
Active bool `gorm:"default:true" json:"active"`
TotalDistance float64 `gorm:"default:0" json:"total_distance"` // km
TotalDuration int `gorm:"default:0" json:"total_duration"` // seconds
TotalRides int `gorm:"default:0" json:"total_rides"`
ServiceIntervalDistance float64 `gorm:"default:0" json:"service_interval_distance"` // km, 0 = no reminder
ServiceIntervalDuration int `gorm:"default:0" json:"service_interval_duration"` // hours, 0 = no reminder
LastServiceDate *time.Time `json:"last_service_date"`
DistanceSinceService float64 `gorm:"default:0" json:"distance_since_service"` // km since last service
DurationSinceService int `gorm:"default:0" json:"duration_since_service"` // seconds since last service
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// ServiceStatus indicates whether equipment needs servicing.
type ServiceStatus struct {
NeedsService bool `json:"needs_service"`
DistanceDue bool `json:"distance_due"`
DurationDue bool `json:"duration_due"`
DistanceSinceService float64 `json:"distance_since_service"` // km
DurationSinceService int `json:"duration_since_service"` // hours
ServiceIntervalDist float64 `json:"service_interval_distance"`
ServiceIntervalDur int `json:"service_interval_duration"`
}
// GetServiceStatus checks if the equipment is due for service.
func (e *Equipment) GetServiceStatus() ServiceStatus {
status := ServiceStatus{
DistanceSinceService: e.DistanceSinceService,
DurationSinceService: e.DurationSinceService / 3600,
ServiceIntervalDist: e.ServiceIntervalDistance,
ServiceIntervalDur: e.ServiceIntervalDuration,
}
if e.ServiceIntervalDistance > 0 && e.DistanceSinceService >= e.ServiceIntervalDistance {
status.DistanceDue = true
status.NeedsService = true
}
if e.ServiceIntervalDuration > 0 && e.DurationSinceService >= e.ServiceIntervalDuration*3600 {
status.DurationDue = true
status.NeedsService = true
}
return status
}
type TrainingZone struct {
ID uint `json:"id"`
Name string `json:"name"`
Min int `json:"min"`
Max int `json:"max"`
Color string `json:"color"`
}
type HRZones struct {
Zone1 TrainingZone `json:"zone_1"` // Recovery
Zone2 TrainingZone `json:"zone_2"` // Endurance
Zone3 TrainingZone `json:"zone_3"` // Tempo
Zone4 TrainingZone `json:"zone_4"` // Threshold
Zone5 TrainingZone `json:"zone_5"` // VO2 Max
}
type PowerZones struct {
Zone1 TrainingZone `json:"zone_1"` // Active Recovery
Zone2 TrainingZone `json:"zone_2"` // Endurance
Zone3 TrainingZone `json:"zone_3"` // Sweet Spot
Zone4 TrainingZone `json:"zone_4"` // Threshold
Zone5 TrainingZone `json:"zone_5"` // VO2 Max
Zone6 TrainingZone `json:"zone_6"` // Anaerobic
Zone7 TrainingZone `json:"zone_7"` // Neuromuscular
}