fix: use Modifier.Set() to maintain AttributeOrder invariant in API handlers

API handlers were populating SetAttributes directly without appending to
AttributeOrder. Since Apply() only iterates AttributeOrder, all updates
via PUT/POST were silently dropped — causing edits to revert and tasks
to disappear on reload.

Adds Modifier.Set() helper, safety net in Apply()/ApplyToNew(), adds
description and status to applyNonDateAttribute, and fixes the
recurrence->recur key mismatch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-25 22:42:57 +01:00
parent 201f32d095
commit 393b7a144a
3 changed files with 57 additions and 25 deletions
+16 -16
View File
@@ -130,35 +130,35 @@ func CreateTask(w http.ResponseWriter, r *http.Request) {
mod.AddTags = req.Tags
if req.Project != nil {
mod.SetAttributes["project"] = req.Project
mod.Set("project", req.Project)
}
if req.Priority != nil {
mod.SetAttributes["priority"] = req.Priority
mod.Set("priority", req.Priority)
}
if req.Due != nil {
dueStr := fmt.Sprintf("%d", *req.Due)
mod.SetAttributes["due"] = &dueStr
mod.Set("due", &dueStr)
}
if req.Scheduled != nil {
scheduledStr := fmt.Sprintf("%d", *req.Scheduled)
mod.SetAttributes["scheduled"] = &scheduledStr
mod.Set("scheduled", &scheduledStr)
}
if req.Wait != nil {
waitStr := fmt.Sprintf("%d", *req.Wait)
mod.SetAttributes["wait"] = &waitStr
mod.Set("wait", &waitStr)
}
if req.Until != nil {
untilStr := fmt.Sprintf("%d", *req.Until)
mod.SetAttributes["until"] = &untilStr
mod.Set("until", &untilStr)
}
if req.Recurrence != nil {
mod.SetAttributes["recurrence"] = req.Recurrence
mod.Set("recur", req.Recurrence)
}
// Create task
@@ -232,39 +232,39 @@ func UpdateTask(w http.ResponseWriter, r *http.Request) {
mod := engine.NewModifier()
if req.Description != nil {
mod.SetAttributes["description"] = req.Description
mod.Set("description", req.Description)
}
if req.Status != nil {
mod.SetAttributes["status"] = req.Status
mod.Set("status", req.Status)
}
if req.Priority != nil {
mod.SetAttributes["priority"] = req.Priority
mod.Set("priority", req.Priority)
}
if req.Project != nil {
mod.SetAttributes["project"] = req.Project
mod.Set("project", req.Project)
}
if req.Due != nil {
dueStr := fmt.Sprintf("%d", *req.Due)
mod.SetAttributes["due"] = &dueStr
mod.Set("due", &dueStr)
}
if req.Scheduled != nil {
scheduledStr := fmt.Sprintf("%d", *req.Scheduled)
mod.SetAttributes["scheduled"] = &scheduledStr
mod.Set("scheduled", &scheduledStr)
}
if req.Wait != nil {
waitStr := fmt.Sprintf("%d", *req.Wait)
mod.SetAttributes["wait"] = &waitStr
mod.Set("wait", &waitStr)
}
if req.Until != nil {
untilStr := fmt.Sprintf("%d", *req.Until)
mod.SetAttributes["until"] = &untilStr
mod.Set("until", &untilStr)
}
if req.Start != nil {
@@ -273,7 +273,7 @@ func UpdateTask(w http.ResponseWriter, r *http.Request) {
}
if req.Recurrence != nil {
mod.SetAttributes["recurrence"] = req.Recurrence
mod.Set("recur", req.Recurrence)
}
// Apply modifier