diff options
Diffstat (limited to 'internal/store/native_tasks.go')
| -rw-r--r-- | internal/store/native_tasks.go | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/internal/store/native_tasks.go b/internal/store/native_tasks.go index 9d9af2c..ea5212c 100644 --- a/internal/store/native_tasks.go +++ b/internal/store/native_tasks.go @@ -21,6 +21,20 @@ import ( // completion: the HTTP response was 200, but nothing in the database changed. var ErrNativeTaskNotFound = errors.New("native task not found") +// visibleChainTaskClause is the single source of truth for "which chain tasks +// belong on the list." Every task query that hides locked chain work must use +// this rather than spelling the predicate out inline -- see +// TestChainVisibilityPredicate_UsedEverywhereChainUnlockedIsFiltered. +// +// The chain's own status matters as much as the task's lock state: pausing a +// chain is meant to take its work off the list entirely, but for a long time +// these queries checked only chain_unlocked, so a paused chain's head task kept +// appearing exactly like an active one -- the pause control did nothing to the +// list it was supposed to affect. +const visibleChainTaskClause = `(t.chain_id = '' OR (t.chain_unlocked = 1 AND EXISTS ( + SELECT 1 FROM task_chains c WHERE c.id = t.chain_id AND c.status = 'active' + )))` + // GetNativeTasks returns all non-completed native tasks. func (s *Store) GetNativeTasks() ([]models.Task, error) { rows, err := s.db.Query(` @@ -49,9 +63,9 @@ func (s *Store) GetNativeTasksByDateRange(start, end time.Time) ([]models.Task, recurrence_freq, recurrence_interval, recurrence_weekdays, recurrence_series_id, next_occurrence_override, estimated_minutes, chain_id, chain_position, chain_unlocked, bucket_id, bucket_state, bucket_last_active_at - FROM native_tasks + FROM native_tasks t WHERE completed = 0 AND due_date IS NOT NULL AND due_date >= ? AND due_date < ? - AND (chain_id = '' OR chain_unlocked = 1) + AND `+visibleChainTaskClause+` ORDER BY due_date ASC, priority DESC `, start, end) if err != nil { @@ -73,9 +87,9 @@ func (s *Store) GetOverdueNativeTasks(before time.Time) ([]models.Task, error) { recurrence_freq, recurrence_interval, recurrence_weekdays, recurrence_series_id, next_occurrence_override, estimated_minutes, chain_id, chain_position, chain_unlocked, bucket_id, bucket_state, bucket_last_active_at - FROM native_tasks + FROM native_tasks t WHERE completed = 0 AND due_date IS NOT NULL AND due_date < ? - AND (chain_id = '' OR chain_unlocked = 1) + AND `+visibleChainTaskClause+` ORDER BY due_date ASC, priority DESC `, before) if err != nil { @@ -92,9 +106,9 @@ func (s *Store) GetUndatedNativeTasks() ([]models.Task, error) { recurrence_freq, recurrence_interval, recurrence_weekdays, recurrence_series_id, next_occurrence_override, estimated_minutes, chain_id, chain_position, chain_unlocked, bucket_id, bucket_state, bucket_last_active_at - FROM native_tasks + FROM native_tasks t WHERE completed = 0 AND due_date IS NULL - AND (chain_id = '' OR chain_unlocked = 1) + AND `+visibleChainTaskClause+` AND bucket_state != 'dormant' ORDER BY priority DESC, created_at ASC `) |
