feat(ql3): compare bounded task run outcomes

This commit is contained in:
whyour
2026-08-14 17:18:25 +08:00
parent a55613afaa
commit 828370c60b
22 changed files with 1802 additions and 22 deletions
@@ -0,0 +1,49 @@
import { RUN_STATUSES } from '@qinglong/runtime-core/run';
import {
normalizeTaskRunOutcomeWindowQuery,
type TaskRunOutcomeWindowQuery,
type TaskRunOutcomeWindowReader,
type TaskRunOutcomeWindowRecord,
} from '@qinglong/runtime-core/task-run-outcome-window';
import type { DatabaseSync } from 'node:sqlite';
import {
queryRows,
requiredEnum,
requiredInteger,
requiredString,
} from '../runPersistence';
export class LocalSqliteTaskRunOutcomeWindowReader
implements TaskRunOutcomeWindowReader
{
constructor(private readonly client: DatabaseSync) {}
async listRecentRunsByTask(
value: Readonly<TaskRunOutcomeWindowQuery>,
): Promise<readonly Readonly<TaskRunOutcomeWindowRecord>[]> {
const query = normalizeTaskRunOutcomeWindowQuery(value);
return queryRows(
this.client,
`SELECT
"id" AS "id",
"project_id" AS "projectId",
"task_id" AS "taskId",
"status" AS "status",
"created_at_ms" AS "createdAtMs"
FROM "Runs"
WHERE "project_id" = ? AND "task_id" = ?
ORDER BY "created_at_ms" DESC, "id" DESC
LIMIT ?`,
[query.projectId, query.taskId, query.limit],
).map((row) =>
Object.freeze({
id: requiredString(row, 'id'),
projectId: requiredString(row, 'projectId'),
taskId: requiredString(row, 'taskId'),
status: requiredEnum(row, 'status', RUN_STATUSES),
createdAtMs: requiredInteger(row, 'createdAtMs'),
}),
);
}
}