summaryrefslogtreecommitdiff
path: root/Omni/Task
diff options
context:
space:
mode:
authorBen Sima <ben@bensima.com>2025-11-27 09:53:20 -0500
committerBen Sima <ben@bensima.com>2025-11-27 09:53:20 -0500
commit27792ace8ae994c84ccbed9b80671fd0e133bb6f (patch)
tree726eb313aefdfd4780e4b1cd50fdb532c00ab7e2 /Omni/Task
parentf981fdb4e6996f6e3e1a55f30d4fc264a2640857 (diff)
Add task_activity table schema
All components are in place: - `ActivityStage` enum with stages: Claiming, Running, Reviewing, Retryi - `TaskActivity` data type with all required fields - JSON instances (ToJSON/FromJSON) - SQLite instances (FromField/ToField for ActivityStage, FromRow/ToRow f - `task_activity` table in `initTaskDb` Build passes with no errors. Task-Id: t-148.1
Diffstat (limited to 'Omni/Task')
-rw-r--r--Omni/Task/Core.hs64
1 files changed, 64 insertions, 0 deletions
diff --git a/Omni/Task/Core.hs b/Omni/Task/Core.hs
index d1d92d5..3a5dd49 100644
--- a/Omni/Task/Core.hs
+++ b/Omni/Task/Core.hs
@@ -82,6 +82,21 @@ data RetryContext = RetryContext
}
deriving (Show, Eq, Generic)
+-- Activity stage for task_activity tracking
+data ActivityStage = Claiming | Running | Reviewing | Retrying | Completed | Failed
+ deriving (Show, Eq, Read, Generic)
+
+-- Task activity log entry
+data TaskActivity = TaskActivity
+ { activityId :: Maybe Int, -- NULL for new entries, set by DB
+ activityTaskId :: Text,
+ activityTimestamp :: UTCTime,
+ activityStage :: ActivityStage,
+ activityMessage :: Maybe Text,
+ activityMetadata :: Maybe Text -- JSON for extra data
+ }
+ deriving (Show, Eq, Generic)
+
instance ToJSON TaskType
instance FromJSON TaskType
@@ -114,6 +129,14 @@ instance ToJSON RetryContext
instance FromJSON RetryContext
+instance ToJSON ActivityStage
+
+instance FromJSON ActivityStage
+
+instance ToJSON TaskActivity
+
+instance FromJSON TaskActivity
+
-- HTTP API Instances (for Servant query params)
instance FromHttpApiData Status where
@@ -162,6 +185,16 @@ instance SQL.FromField Priority where
instance SQL.ToField Priority where
toField x = SQL.toField (show x :: String)
+instance SQL.FromField ActivityStage where
+ fromField f = do
+ t <- SQL.fromField f :: SQLOk.Ok String
+ case readMaybe t of
+ Just x -> pure x
+ Nothing -> SQL.returnError SQL.ConversionFailed f "Invalid ActivityStage"
+
+instance SQL.ToField ActivityStage where
+ toField x = SQL.toField (show x :: String)
+
-- Store dependencies as JSON text
instance SQL.FromField [Dependency] where
fromField f = do
@@ -203,6 +236,26 @@ instance SQL.ToRow Task where
SQL.toField (taskUpdatedAt t)
]
+instance SQL.FromRow TaskActivity where
+ fromRow =
+ TaskActivity
+ </ SQL.field
+ <*> SQL.field
+ <*> SQL.field
+ <*> SQL.field
+ <*> SQL.field
+ <*> SQL.field
+
+instance SQL.ToRow TaskActivity where
+ toRow a =
+ [ SQL.toField (activityId a),
+ SQL.toField (activityTaskId a),
+ SQL.toField (activityTimestamp a),
+ SQL.toField (activityStage a),
+ SQL.toField (activityMessage a),
+ SQL.toField (activityMetadata a)
+ ]
+
-- | Case-insensitive ID comparison
matchesId :: Text -> Text -> Bool
matchesId id1 id2 = normalizeId id1 == normalizeId id2
@@ -294,6 +347,17 @@ initTaskDb = do
\ attempt INTEGER NOT NULL DEFAULT 1, \
\ reason TEXT NOT NULL \
\)"
+ SQL.execute_
+ conn
+ "CREATE TABLE IF NOT EXISTS task_activity (\
+ \ id INTEGER PRIMARY KEY AUTOINCREMENT, \
+ \ task_id TEXT NOT NULL, \
+ \ timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, \
+ \ stage TEXT NOT NULL, \
+ \ message TEXT, \
+ \ metadata TEXT, \
+ \ FOREIGN KEY (task_id) REFERENCES tasks(id) \
+ \)"
-- Generate a sequential task ID (t-1, t-2, t-3, ...)
generateId :: IO Text