feat(tasks): completed tasks are deleted after a delay (default 30 days), "Erledigte leeren"
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m34s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m34s
thoughts.completed_at is set by triggers on every way a task is completed (migration 14; tasks completed earlier count from the update). Users choose the delay (7/30/90/365 days or never, users.done_retention_days); for tasks in a list the owner's delay counts. An hourly job deletes expired completed tasks (not in the demo) and tells their viewers. POST /tasks/clear-done clears completed tasks the user may edit. The done tab shows the setting and the button. v0.35.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
66b28e1998
commit
f91926c208
16 files changed
+433
-6
No files matched your search
@@ -0,0 +1,59 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/sandrodach/mindsift/internal/auth"
|
||||
"github.com/sandrodach/mindsift/internal/storage"
|
||||
)
|
||||
|
||||
// startDoneCleanupTicker deletes completed tasks whose delay ran out (storage/done_cleanup.go), once
|
||||
// shortly after the start and then every hour.
|
||||
func (s *Server) startDoneCleanupTicker() {
|
||||
time.Sleep(2 * time.Minute)
|
||||
s.runDoneCleanup(time.Now())
|
||||
ticker := time.NewTicker(time.Hour)
|
||||
defer ticker.Stop()
|
||||
for now := range ticker.C {
|
||||
s.runDoneCleanup(now)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) runDoneCleanup(now time.Time) {
|
||||
deleted, err := s.store.PurgeExpiredDoneTasks(now)
|
||||
if err != nil {
|
||||
slog.Error("Aufräumen erledigter Aufgaben fehlgeschlagen", "error", err)
|
||||
return
|
||||
}
|
||||
if len(deleted) > 0 {
|
||||
slog.Info("Erledigte Aufgaben aufgeräumt", "count", len(deleted))
|
||||
}
|
||||
s.broadcastDeletedTasks(deleted)
|
||||
}
|
||||
|
||||
// broadcastDeletedTasks tells everyone who saw the tasks; there are no watcher notifications for this.
|
||||
func (s *Server) broadcastDeletedTasks(deleted []storage.DeletedTask) {
|
||||
for _, d := range deleted {
|
||||
audience := append(s.store.GetTaskListUserIDs(d.TaskListID), d.UserID)
|
||||
s.wsHub.BroadcastToUsers(audience, "TASK_DELETED", map[string]string{"id": d.ID})
|
||||
}
|
||||
}
|
||||
|
||||
// handleClearDoneTasks: "Erledigte leeren" for one task list (taskListId) or all the user can edit.
|
||||
func (s *Server) handleClearDoneTasks(w http.ResponseWriter, r *http.Request) {
|
||||
userID := auth.GetUserID(r.Context())
|
||||
var req struct {
|
||||
TaskListID string `json:"taskListId"`
|
||||
}
|
||||
_ = json.NewDecoder(r.Body).Decode(&req)
|
||||
deleted, err := s.store.ClearDoneTasks(userID, req.TaskListID)
|
||||
if err != nil {
|
||||
writeStoreError(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
s.broadcastDeletedTasks(deleted)
|
||||
writeJSON(w, http.StatusOK, map[string]int{"deleted": len(deleted)})
|
||||
}
|
||||
Reference in new issue
Block a user