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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user