From 7966eb9ce705ac835b2336fcd6aedffebd54234d Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Sat, 29 Nov 2025 23:42:43 -0500 Subject: Expand intervention page to show all human action items All tests pass and lint is clean. The implementation is complete: **Changes made:** 1. **Omni/Task/Core.hs:** - Added `EpicForReview` data type to hold epic with progress info - Added `HumanActionItems` data type to group all three categories - Added `getHumanActionItems` function that returns: - `failedTasks`: Tasks with retry_attempt >= 3 - `epicsInReview`: Epics where all children are Done (and has at le - `humanTasks`: HumanTask type tasks in Open status 2. **Omni/Jr/Web.hs:** - Updated `InterventionPage` data type to use `HumanActionItems` - Updated `interventionHandler` to call `getHumanActionItems` - Rewrote `ToHtml InterventionPage` to show 3 sections with headers - Added `renderEpicReviewCard` for epic review cards with "Approve & - Renamed navbar link from "Intervention" to "Human Action" Task-Id: t-193.5 --- Omni/Task/Core.hs | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'Omni/Task') diff --git a/Omni/Task/Core.hs b/Omni/Task/Core.hs index e4986c1..07c74fc 100644 --- a/Omni/Task/Core.hs +++ b/Omni/Task/Core.hs @@ -74,6 +74,20 @@ data TaskProgress = TaskProgress } deriving (Show, Eq, Generic) +data EpicForReview = EpicForReview + { epicTask :: Task, + epicTotal :: Int, + epicCompleted :: Int + } + deriving (Show, Eq, Generic) + +data HumanActionItems = HumanActionItems + { failedTasks :: [Task], + epicsInReview :: [EpicForReview], + humanTasks :: [Task] + } + deriving (Show, Eq, Generic) + data AggregatedMetrics = AggregatedMetrics { aggTotalCostCents :: Int, aggTotalDurationSeconds :: Int, @@ -1429,6 +1443,35 @@ getInterventionTasks = do let highRetryIds = [retryTaskId ctx | ctx <- retryContexts, retryAttempt ctx >= 3] pure [t | t <- allTasks, taskId t `elem` highRetryIds] +-- | Get all items needing human action +getHumanActionItems :: IO HumanActionItems +getHumanActionItems = do + allTasks <- loadTasks + retryContexts <- getAllRetryContexts + let highRetryIds = [retryTaskId ctx | ctx <- retryContexts, retryAttempt ctx >= 3] + failed = [t | t <- allTasks, taskId t `elem` highRetryIds] + epics = [t | t <- allTasks, taskType t == Epic, taskStatus t /= Done] + epicsReady = + [ EpicForReview + { epicTask = e, + epicTotal = total, + epicCompleted = completed + } + | e <- epics, + let children = [c | c <- allTasks, taskParent c == Just (taskId e)], + let total = length children, + total > 0, + let completed = length [c | c <- children, taskStatus c == Done], + completed == total + ] + human = [t | t <- allTasks, taskType t == HumanTask, taskStatus t == Open] + pure + HumanActionItems + { failedTasks = failed, + epicsInReview = epicsReady, + humanTasks = human + } + -- | Get all retry contexts from the database getAllRetryContexts :: IO [RetryContext] getAllRetryContexts = -- cgit v1.2.3