Repository navigation
feat(api): Admin work-item list, detail and live event stream (#279) - #294
Merged
Merged
Conversation
…s progress changed (#279) UpdatedAt is the change cursor the admin event stream reads. A heartbeat that only extends the lease changed nothing an admin can see, so it no longer moves UpdatedAt; LeaseUntil already records that the Worker is alive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GET /api/v1/admin/work-items lists items newest request first, filtered by
status and kind and paged, with the stream cursor read before the page.
GET .../{id} returns one item or 404. GET .../events streams every changed
item as Server-Sent Events, re-querying UpdatedAt at WorkItemEvents:
IntervalSeconds (2 s); each event id is the cursor, so Last-Event-ID resumes
from it. A 10 s lookback, deduplicated against the previous poll, keeps a
change whose commit lands behind the cursor from being skipped.
The API reads work items only through IWorkItemReader, as WorkItemView.
A result is shown once an item succeeded; an error once it failed or was
cancelled.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ne place (#279) WorkItemView holds Core's WorkProgress rather than three loose fields, and the event id and the list cursor share the mapper's ISO formatter, so the two cursors cannot drift apart. Asserts the paging validation messages (two surviving mutants) and makes the HTTP event-stream test independent of when the server reaches its next poll. Documents the admin view and the heartbeat rule in CLAUDE.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #279. Part of #276 (design: ADR 0008, #276 "Admin API").
Summary
Three admin-only routes over the work queue, read through a new
IWorkItemReader(Core):UpdatedAtis the change cursor. A client lists, then subscribes withLast-Event-ID: <cursor>, so nothing that changes in between is missed:The 10 s lookback picks up a change that commits behind the cursor, and the dedupe set stops it being sent twice.
To make
UpdatedAtmean "changed", the Worker heartbeat now moves it only when the progress snapshot changes. Without that, every running item would be re-sent every 2 s.LeaseUntilstill shows that the Worker is alive.A comment-only migration updates the
UpdatedAtcolumn comment to match.The DTO shows
Result(as JSON) only forSucceeded, andErroronly forFailed/Cancelled. Times are ISO-8601 strings and enums are names.Evidence
UpdatedAtand extends the lease. A change to any of done, total or note moves it.ToQueryStringshape isWHERE "UpdatedAt" > @since ORDER BY "UpdatedAt", "Id".Timeline-driven): lookback, resume fromLast-Event-ID, an unreadable id, dedupe, an item changed again, a change committed behind the cursor, and the interval.event: work-item,id: 2026-10-18T09:00:09Z).scripts/mutation-changed.sh):Merge Danger
Door: two-way
Read-only endpoints, plus a heartbeat that writes less. The migration only changes a column comment.
Blast Radius: small
UpdatedAtas "last heartbeat" would now see the last change instead. Nothing in the repo does; liveness isLeaseUntil.DbContextand polls every 2 s.Cancelleditems show theirError(e.g. "superseded"). That decides the shape feat: Cancel queued and running work items #280 builds on.RequestedBymeans the item was scheduled.Errorholds an exception type and message, which can contain a NAS file path. Only admins can see it.Triage: #279's Design section now links ADR 0008 and #276's Admin API decisions, and the issue is relabelled
ready-for-agent.🤖 Generated with Claude Code