Skip to content

v2: events page — activity feed and subscription management - #214

Closed
xBalbinus wants to merge 3 commits into
dev-v2from
feat/v2-events-ui
Closed

v2: events page — activity feed and subscription management#214
xBalbinus wants to merge 3 commits into
dev-v2from
feat/v2-events-ui

Conversation

@xBalbinus

Copy link
Copy Markdown

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:

  • Activity — the org's ingested events, newest first, filterable by service and event key (both drawn from the plugin trigger catalog). A row expands into the raw payload and the delivery attempts made for it, so "why didn't my trigger fire" is answerable from the page.
  • Subscriptions — the rules that turn a matching event into a workflow run or an orchestrator prompt: list, create, enable/disable, delete. The create dialog offers only catalog keys, so a subscription cannot name an event the ingest matcher can never match. Targets: your orchestrator, the org orchestrator, or an owned workflow (resolved to its name in the list).

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 errorText from 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/web suite 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.

@valet-valet-turnkey-dev valet-valet-turnkey-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR is well-structured and the implementation matches the stated intent. Two minor-but-real issues worth fixing before merge:

  1. packages/web/src/components/events/subscriptions-panel.tsx:272 — When the user selects "Run a workflow" and workflows[0] happens to be undefined (the list loads empty initially, then fills in), target.workflowId is set to "". canSubmit treats this as valid (targetReady only checks kind === "orchestrator" OR workflowId.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 before workflowsQ completes, the guard fails silently.

    • targetReady should additionally require workflows.length > 0 when target.kind === "workflow", or workflowId !== "" (which is already there — but workflows[0]?.id ?? "" means workflowId is "" until data loads, and the length > 0 check on the radio's disabled prop doesn't protect canSubmit).
  2. packages/web/src/api/events.ts:56useEvent accepts id: string | null and guards with enabled: id !== null, but when called from EventDetail it is always passed a real string (eventId: string). The hook's id ?? "" fallback means an empty string would be passed to api.getEvent("") if enabled were ever true with a null/empty id. This is harmless as written today but the id ?? "" inside queryFn is a silent footgun — prefer an assertion or a non-null cast consistent with the enabled guard, so a future caller passing "" doesn't silently fire a bad request.


Created on behalf of Xiangan He xiangan@turnkey.io

@xBalbinus

Copy link
Copy Markdown
Author

Superseded by #216, which carries this diff plus #215 and a shared-component pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant