taskStaleness returns (daysSinceLastTouch, stale) for an in-progress task. "Last touch" is max(updated_at, newest update file mtime). Staleness threshold is configurable via FLOW_STALE_DAYS (default 3).
(t *flowdb.Task, root string)
| 622 | // task. "Last touch" is max(updated_at, newest update file mtime). |
| 623 | // Staleness threshold is configurable via FLOW_STALE_DAYS (default 3). |
| 624 | func taskStaleness(t *flowdb.Task, root string) (int, bool) { |
| 625 | last, err := time.Parse(time.RFC3339, t.UpdatedAt) |
| 626 | if err != nil { |
| 627 | return 0, false |
| 628 | } |
| 629 | updatesDir := filepath.Join(root, "tasks", t.Slug, "updates") |
| 630 | if entries, err := os.ReadDir(updatesDir); err == nil { |
| 631 | for _, e := range entries { |
| 632 | if e.IsDir() || filepath.Ext(e.Name()) != ".md" { |
| 633 | continue |
| 634 | } |
| 635 | info, err := e.Info() |
| 636 | if err != nil { |
| 637 | continue |
| 638 | } |
| 639 | if info.ModTime().After(last) { |
| 640 | last = info.ModTime() |
| 641 | } |
| 642 | } |
| 643 | } |
| 644 | age := time.Since(last) |
| 645 | days := int(age / (24 * time.Hour)) |
| 646 | threshold := staleDaysThreshold() |
| 647 | return days, age > time.Duration(threshold)*24*time.Hour |
| 648 | } |
| 649 | |
| 650 | // daysInStatus returns the number of days the task has been in its |
| 651 | // current status. Uses status_changed_at if set, else falls back to |
no test coverage detected