fix(activity): a run nothing here has open reads as interrupted, a rollback sums a stopped run's spend

- The scheduler keeps one registry of the runs this process has open, for the interval jobs and the
  ad-hoc runs alike. A row the table still says is `running` but no run here has open (its outcome
  failed to write) reads as interrupted, as the next start's sweep will close it: no pulsing dot
  beside "No run recorded yet".
- Migration 0109's downgrade sums a still-running run's quota events into its spend before the link
  to them is dropped, as the startup sweep would.
- A test holds that a dialog closing onto the same address leaves an open log line open.
This commit is contained in:
2026-10-18 21:21:19 +02:00
parent 13b7577d9f
commit 5082636f15
5 changed files with 109 additions and 21 deletions
@@ -114,6 +114,19 @@ afterEach(() => {
});
describe("AdminLogs", () => {
it("a dialog closing onto the same address leaves the open line open", async () => {
logsMock.mockResolvedValue({ items: [row(1)], accounts: {}, next_cursor: null });
renderConsole();
await waitFor(() => expect(lines()).toHaveLength(1));
fireEvent.click(lines()[0]!);
expect(lines()[0]!.getAttribute("aria-expanded")).toBe("true");
// A closing dialog steps back over its own history entry: a popstate onto the same address.
act(() => {
window.dispatchEvent(new PopStateEvent("popstate"));
});
expect(lines()[0]!.getAttribute("aria-expanded")).toBe("true");
});
it("a request id narrows the list to that request, with every other filter off", async () => {
window.history.replaceState(null, "", "/?page=activity&at=logs&lgrp=error&aq=boom");
logsMock.mockResolvedValue({ items: [row(1)], accounts: {}, next_cursor: null });