summaryrefslogtreecommitdiff
path: root/Omni
diff options
context:
space:
mode:
authorBen Sima <ben@bsima.me>2025-11-20 18:07:12 -0500
committerBen Sima <ben@bsima.me>2025-11-20 18:07:12 -0500
commit028bbda4282515b95a7555209d397aaf22d32244 (patch)
tree38c5527a546dcb1f877f3380f615ae4497faf50f /Omni
parent6e90d59acf45cc481e4e78101a36231af43cbd96 (diff)
feat: implement t-PpYZt2
Diffstat (limited to 'Omni')
-rw-r--r--Omni/Task.hs8
-rw-r--r--Omni/Task/Core.hs26
2 files changed, 32 insertions, 2 deletions
diff --git a/Omni/Task.hs b/Omni/Task.hs
index d1e672a..10136c9 100644
--- a/Omni/Task.hs
+++ b/Omni/Task.hs
@@ -312,7 +312,13 @@ unitTests =
ready <- getReadyTasks
-- Both should be ready since Related doesn't block
(taskId task1 `elem` map taskId ready) Test.@?= True
- (taskId task2 `elem` map taskId ready) Test.@?= True
+ (taskId task2 `elem` map taskId ready) Test.@?= True,
+ Test.unit "child task gets sequential ID" <| do
+ parent <- createTask "Parent" Epic Nothing Nothing P2 []
+ child1 <- createTask "Child 1" WorkTask (Just (taskId parent)) Nothing P2 []
+ child2 <- createTask "Child 2" WorkTask (Just (taskId parent)) Nothing P2 []
+ taskId child1 Test.@?= taskId parent <> ".1"
+ taskId child2 Test.@?= taskId parent <> ".2"
]
-- | Test CLI argument parsing to ensure docopt string matches actual usage
diff --git a/Omni/Task/Core.hs b/Omni/Task/Core.hs
index f7b7915..798f8fe 100644
--- a/Omni/Task/Core.hs
+++ b/Omni/Task/Core.hs
@@ -111,6 +111,28 @@ generateId = do
encoded = toBase62 (fromIntegral microseconds)
pure <| "t-" <> T.pack encoded
+-- Generate a child ID based on parent ID (e.g. "t-abc.1")
+generateChildId :: Text -> IO Text
+generateChildId parentId = do
+ tasks <- loadTasks
+ let children = filter (\t -> taskParent t == Just parentId) tasks
+ -- Find the max suffix
+ suffixes = mapMaybe (\t -> getSuffix parentId (taskId t)) children
+ nextSuffix = case suffixes of
+ [] -> 1
+ s -> maximum s + 1
+ pure <| parentId <> "." <> T.pack (show nextSuffix)
+
+getSuffix :: Text -> Text -> Maybe Int
+getSuffix parent childId =
+ if parent `T.isPrefixOf` childId && T.length childId > T.length parent
+ then
+ let rest = T.drop (T.length parent) childId
+ in if T.head rest == '.'
+ then readMaybe (T.unpack (T.tail rest))
+ else Nothing
+ else Nothing
+
-- Convert number to base62 (0-9, a-z, A-Z)
toBase62 :: Integer -> String
toBase62 0 = "0"
@@ -192,7 +214,9 @@ saveTask task = do
-- Create a new task
createTask :: Text -> TaskType -> Maybe Text -> Maybe Text -> Priority -> [Dependency] -> IO Task
createTask title taskType parent namespace priority deps = do
- tid <- generateId
+ tid <- case parent of
+ Nothing -> generateId
+ Just pid -> generateChildId pid
now <- getCurrentTime
let task =
Task