v2: events page — activity feed and subscription management - #214
v2: events page — activity feed and subscription management#214xBalbinus wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
The PR is well-structured and the implementation matches the stated intent. Two minor-but-real issues worth fixing before merge:
-
packages/web/src/components/events/subscriptions-panel.tsx:272 — When the user selects "Run a workflow" andworkflows[0]happens to be undefined (the list loads empty initially, then fills in),target.workflowIdis set to"".canSubmittreats this as valid (targetReadyonly checkskind === "orchestrator"ORworkflowId.length > 0), so the submit path can fire with an empty workflow ID before the workflows query resolves. The race is narrow but real: if the user clicks the radio beforeworkflowsQcompletes, the guard fails silently.targetReadyshould additionally requireworkflows.length > 0whentarget.kind === "workflow", orworkflowId !== ""(which is already there — butworkflows[0]?.id ?? ""meansworkflowIdis""until data loads, and thelength > 0check on the radio'sdisabledprop doesn't protectcanSubmit).
-
packages/web/src/api/events.ts:56 —useEventacceptsid: string | nulland guards withenabled: id !== null, but when called fromEventDetailit is always passed a real string (eventId: string). The hook'sid ?? ""fallback means an empty string would be passed toapi.getEvent("")ifenabledwere ever true with a null/empty id. This is harmless as written today but theid ?? ""insidequeryFnis a silent footgun — prefer an assertion or a non-null cast consistent with theenabledguard, so a future caller passing""doesn't silently fire a bad request.
Created on behalf of Xiangan He xiangan@turnkey.io
Summary
The event system (feed, catalog, subscriptions —
docs/specs/2026-07-20-event-system-design.md) has had a full API since it landed, but no UI: events and subscriptions were invisible in the product. This adds the first UI over it, a top-level Events page with two tabs:Subscription filters stay API-only in this pass: a row shows its filter count, and the create dialog does not build filters yet.
Also extracted
errorTextfrom the skill editor into~/lib/error-text.ts(it now takes a fallback message) so the create dialog surfaces the API's validation messages ("unknown event key: …") instead of a bare status line.Verification
@valet/websuite passes (589, including 6 new page tests) and the flow was exercised against the local dev stack: create → toggle off → delete, each confirmed server-side.