diff options
| author | Ben Sima <ben@bensima.com> | 2025-11-27 09:53:20 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bensima.com> | 2025-11-27 09:53:20 -0500 |
| commit | 27792ace8ae994c84ccbed9b80671fd0e133bb6f (patch) | |
| tree | 726eb313aefdfd4780e4b1cd50fdb532c00ab7e2 | |
| parent | f981fdb4e6996f6e3e1a55f30d4fc264a2640857 (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
| -rw-r--r-- | Omni/Task/Core.hs | 64 |
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 |
