Refactor habit entries: remove soft delete and add smart pagination

Remove soft delete from HabitEntry:
- Eliminate DeletedAt field from entity and database
- Change UnmarkHabit from soft delete to hard delete
- Simplify all queries removing deleted_at checks
- Update migration to remove deleted_at column

Add date filtering and smart pagination to GetHabitEntries:
- Support optional from/to date parameters
- Implement intelligent pagination rules:
  * No date range: pagination required
  * Date range > 1 year: pagination required
  * Date range ≤ 1 year: pagination optional
- Pagination defaults (page=1, limit=50) only when required
- Return metadata with total count, page, and limit

Technical improvements:
- Cleaner codebase without soft delete complexity
- Better performance (no filtering in queries)
- More intuitive API with flexible pagination
- Comprehensive test coverage for validation rules
This commit is contained in:
2025-11-26 16:33:40 +01:00
parent 74cd2ec84d
commit 9f673bfca3
10 changed files with 309 additions and 129 deletions
+7 -11
View File
@@ -4,7 +4,6 @@ import (
"context"
"time"
"apocapoc-api/internal/domain/entities"
"apocapoc-api/internal/domain/repositories"
"apocapoc-api/internal/shared/errors"
)
@@ -57,22 +56,19 @@ func (h *UnmarkHabitHandler) Handle(ctx context.Context, cmd UnmarkHabitCommand)
return err
}
// Find the active entry for this date
var targetEntry *entities.HabitEntry
// Find the entry for this date
var targetEntryID string
for _, entry := range entries {
if entry.ScheduledDate.Equal(cmd.ScheduledDate) && entry.DeletedAt == nil {
targetEntry = entry
if entry.ScheduledDate.Equal(cmd.ScheduledDate) {
targetEntryID = entry.ID
break
}
}
if targetEntry == nil {
if targetEntryID == "" {
return errors.ErrNotFound
}
// Soft delete the entry
now := time.Now()
targetEntry.DeletedAt = &now
return h.entryRepo.Update(ctx, targetEntry)
// Hard delete the entry
return h.entryRepo.Delete(ctx, targetEntryID)
}