Initial commit: Homelab API
This commit is contained in:
191
internal/service/habit.go
Normal file
191
internal/service/habit.go
Normal file
@@ -0,0 +1,191 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/daniil/homelab-api/internal/model"
|
||||
"github.com/daniil/homelab-api/internal/repository"
|
||||
)
|
||||
|
||||
type HabitService struct {
|
||||
habitRepo *repository.HabitRepository
|
||||
}
|
||||
|
||||
func NewHabitService(habitRepo *repository.HabitRepository) *HabitService {
|
||||
return &HabitService{habitRepo: habitRepo}
|
||||
}
|
||||
|
||||
func (s *HabitService) Create(userID int64, req *model.CreateHabitRequest) (*model.Habit, error) {
|
||||
habit := &model.Habit{
|
||||
UserID: userID,
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
Color: defaultString(req.Color, "#6366f1"),
|
||||
Icon: defaultString(req.Icon, "check"),
|
||||
Frequency: defaultString(req.Frequency, "daily"),
|
||||
TargetDays: req.TargetDays,
|
||||
TargetCount: defaultInt(req.TargetCount, 1),
|
||||
}
|
||||
|
||||
if err := s.habitRepo.Create(habit); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return habit, nil
|
||||
}
|
||||
|
||||
func (s *HabitService) Get(id, userID int64) (*model.Habit, error) {
|
||||
return s.habitRepo.GetByID(id, userID)
|
||||
}
|
||||
|
||||
func (s *HabitService) List(userID int64, includeArchived bool) ([]model.Habit, error) {
|
||||
habits, err := s.habitRepo.ListByUser(userID, includeArchived)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if habits == nil {
|
||||
habits = []model.Habit{}
|
||||
}
|
||||
return habits, nil
|
||||
}
|
||||
|
||||
func (s *HabitService) Update(id, userID int64, req *model.UpdateHabitRequest) (*model.Habit, error) {
|
||||
habit, err := s.habitRepo.GetByID(id, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.Name != nil {
|
||||
habit.Name = *req.Name
|
||||
}
|
||||
if req.Description != nil {
|
||||
habit.Description = *req.Description
|
||||
}
|
||||
if req.Color != nil {
|
||||
habit.Color = *req.Color
|
||||
}
|
||||
if req.Icon != nil {
|
||||
habit.Icon = *req.Icon
|
||||
}
|
||||
if req.Frequency != nil {
|
||||
habit.Frequency = *req.Frequency
|
||||
}
|
||||
if req.TargetDays != nil {
|
||||
habit.TargetDays = req.TargetDays
|
||||
}
|
||||
if req.TargetCount != nil {
|
||||
habit.TargetCount = *req.TargetCount
|
||||
}
|
||||
if req.IsArchived != nil {
|
||||
habit.IsArchived = *req.IsArchived
|
||||
}
|
||||
|
||||
if err := s.habitRepo.Update(habit); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return habit, nil
|
||||
}
|
||||
|
||||
func (s *HabitService) Delete(id, userID int64) error {
|
||||
return s.habitRepo.Delete(id, userID)
|
||||
}
|
||||
|
||||
func (s *HabitService) Log(habitID, userID int64, req *model.LogHabitRequest) (*model.HabitLog, error) {
|
||||
// Verify habit exists and belongs to user
|
||||
if _, err := s.habitRepo.GetByID(habitID, userID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
date := time.Now().Truncate(24 * time.Hour)
|
||||
if req.Date != "" {
|
||||
parsed, err := time.Parse("2006-01-02", req.Date)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
date = parsed
|
||||
}
|
||||
|
||||
log := &model.HabitLog{
|
||||
HabitID: habitID,
|
||||
UserID: userID,
|
||||
Date: date,
|
||||
Count: defaultInt(req.Count, 1),
|
||||
Note: req.Note,
|
||||
}
|
||||
|
||||
if err := s.habitRepo.CreateLog(log); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return log, nil
|
||||
}
|
||||
|
||||
func (s *HabitService) GetLogs(habitID, userID int64, days int) ([]model.HabitLog, error) {
|
||||
// Verify habit exists and belongs to user
|
||||
if _, err := s.habitRepo.GetByID(habitID, userID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
to := time.Now()
|
||||
from := to.AddDate(0, 0, -days)
|
||||
|
||||
logs, err := s.habitRepo.GetLogs(habitID, userID, from, to)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if logs == nil {
|
||||
logs = []model.HabitLog{}
|
||||
}
|
||||
return logs, nil
|
||||
}
|
||||
|
||||
func (s *HabitService) DeleteLog(logID, userID int64) error {
|
||||
return s.habitRepo.DeleteLog(logID, userID)
|
||||
}
|
||||
|
||||
func (s *HabitService) GetHabitStats(habitID, userID int64) (*model.HabitStats, error) {
|
||||
// Verify habit exists and belongs to user
|
||||
if _, err := s.habitRepo.GetByID(habitID, userID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.habitRepo.GetStats(habitID, userID)
|
||||
}
|
||||
|
||||
func (s *HabitService) GetOverallStats(userID int64) (*model.OverallStats, error) {
|
||||
habits, err := s.habitRepo.ListByUser(userID, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
allHabits, err := s.habitRepo.ListByUser(userID, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
todayLogs, err := s.habitRepo.GetUserLogsForDate(userID, time.Now().Truncate(24*time.Hour))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &model.OverallStats{
|
||||
TotalHabits: len(allHabits),
|
||||
ActiveHabits: len(habits),
|
||||
TodayCompleted: len(todayLogs),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func defaultString(val, def string) string {
|
||||
if val == "" {
|
||||
return def
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func defaultInt(val, def int) int {
|
||||
if val == 0 {
|
||||
return def
|
||||
}
|
||||
return val
|
||||
}
|
||||
Reference in New Issue
Block a user