Files
apocapoc-api/internal/application/queries/get_todays_habits.go
T
david 90d5628a42 Fix today's habits timezone calculation and include entry data
- Calculate today based on user's timezone instead of always using UTC
- Include habit entry in response if it exists for the current day
- Update GetTodaysHabitsHandler to fetch and return entry information
- Add entry field to TodaysHabitDTO and TodaysHabitResponse
- Update tests to reflect new behavior of including completed habits
- Add test for habits with value entries
2025-11-29 02:09:30 +01:00

103 lines
2.2 KiB
Go

package queries
import (
"context"
"time"
"apocapoc-api/internal/domain/repositories"
"apocapoc-api/internal/domain/value_objects"
"apocapoc-api/internal/shared/utils"
)
type TodaysHabitEntryDTO struct {
ID string
Value *float64
CompletedAt time.Time
}
type TodaysHabitDTO struct {
ID string
Name string
Type value_objects.HabitType
TargetValue *float64
IsNegative bool
ScheduledDate time.Time
IsCarriedOver bool
Entry *TodaysHabitEntryDTO
}
type GetTodaysHabitsQuery struct {
UserID string
Timezone string
Date time.Time
}
type GetTodaysHabitsHandler struct {
habitRepo repositories.HabitRepository
entryRepo repositories.HabitEntryRepository
}
func NewGetTodaysHabitsHandler(
habitRepo repositories.HabitRepository,
entryRepo repositories.HabitEntryRepository,
) *GetTodaysHabitsHandler {
return &GetTodaysHabitsHandler{
habitRepo: habitRepo,
entryRepo: entryRepo,
}
}
func (h *GetTodaysHabitsHandler) Handle(
ctx context.Context,
query GetTodaysHabitsQuery,
) ([]TodaysHabitDTO, error) {
habits, err := h.habitRepo.FindActiveByUserID(ctx, query.UserID)
if err != nil {
return nil, err
}
var result []TodaysHabitDTO
for _, habit := range habits {
shouldAppear := utils.ShouldAppearToday(
string(habit.Frequency),
habit.SpecificDays,
habit.SpecificDates,
query.Date,
)
if !shouldAppear && !habit.CarryOver {
continue
}
entries, _ := h.entryRepo.FindByHabitIDAndDateRange(
ctx,
habit.ID,
query.Date,
query.Date,
)
var entryDTO *TodaysHabitEntryDTO
if len(entries) > 0 && entries[0].ScheduledDate.Format("2006-01-02") == query.Date.Format("2006-01-02") {
entryDTO = &TodaysHabitEntryDTO{
ID: entries[0].ID,
Value: entries[0].Value,
CompletedAt: entries[0].CompletedAt,
}
}
result = append(result, TodaysHabitDTO{
ID: habit.ID,
Name: habit.Name,
Type: habit.Type,
TargetValue: habit.TargetValue,
IsNegative: habit.IsNegative,
ScheduledDate: query.Date,
IsCarriedOver: !shouldAppear && habit.CarryOver,
Entry: entryDTO,
})
}
return result, nil
}