fix(scenario-logs): fix out-of-order run log persistence

- Add seq column assigned in call order to fix logs racing each other
  as fire-and-forget writes (e.g. a snippet's "started" entry could be
  saved after its "finished" entry)
- Log snippet start/finish/failure via context.runSnippet, matching
  existing step start/pass/fail logging
- Rework Markdown log export to per-entry sections instead of a table
- Version bump: 1.10.0 -> 1.10.1
This commit is contained in:
Andrii Arsenin
2026-09-15 13:17:29 +03:00
parent ce85aa02f1
commit 85a87b5fb2
6 changed files with 53 additions and 16 deletions
+6 -13
View File
@@ -402,7 +402,7 @@ export class ScenarioService {
);
const logs = await this.runLogRepo.find({
where: q?.trim() ? { runId, message: Like(`%${q.trim()}%`) } : { runId },
order: { createdAt: "ASC" },
order: { seq: "ASC", createdAt: "ASC" },
});
return Object.assign(run, { logs });
}
@@ -422,7 +422,7 @@ export class ScenarioService {
);
const logs = await this.runLogRepo.find({
where: { runId },
order: { createdAt: "ASC" },
order: { seq: "ASC", createdAt: "ASC" },
});
if (format === "csv") {
@@ -439,17 +439,10 @@ export class ScenarioService {
return rows.join("\n");
}
const lines = [
`# Run ${runId} logs`,
"",
"| Timestamp | Level | Message |",
"| --- | --- | --- |",
...logs.map(
(l) =>
`| ${l.createdAt.toISOString()} | ${l.level} | ${l.message.replace(/\|/g, "\\|").replace(/\n/g, "<br>")} |`,
),
];
return lines.join("\n");
const sections = logs.map(
(l) => `## [${l.level}] ${l.createdAt.toISOString()}\n\n${l.message}`,
);
return [`# Run ${runId} logs`, ...sections].join("\n\n");
}
async waitForRun(