Skip to content

feat(dashboard): add durable_dashboard package + engine and tooling overhaul#7

Merged
kasvith merged 13 commits intomainfrom
feat/dashboard
May 2, 2026
Merged

feat(dashboard): add durable_dashboard package + engine and tooling overhaul#7
kasvith merged 13 commits intomainfrom
feat/dashboard

Conversation

@kasvith
Copy link
Copy Markdown
Contributor

@kasvith kasvith commented May 1, 2026

Summary

  • Monorepo restructure (chore: restructure into path-dep monorepo workspace): moved :durable into durable/ as a sibling to durable_dashboard, modeled on elixir-nx/nx. Each package keeps its own mix.exs, mix.lock, _build/, and Hex publishing pipeline; cross-references go through path: deps. A thin root mix.exs fans out setup/compile/test/format/precommit to each published package. CI rewritten as per-package jobs gated by dorny/paths-filter with a single ci-status aggregator for branch protection.
  • Adds the new durable_dashboard Hex package: a LiveView-driven web UI (sidebar, command palette, workflow detail tabs, ReactFlow graph island, schedules/inputs lists, settings) backed by dashboard_counts/1 and list_executions_with_total/1. Design language codified in durable_dashboard/DESIGN.md.
  • Engine refinements across executor, queue, wait, log capture, scheduler resilience, and a new Durable.PubSub module that broadcasts workflow lifecycle events via Phoenix.PubSub.
  • Expanded mix durable.* task suite: doctor, gen.upgrade, inspect, migrations, pending, provide_input, retry, send_event plus existing tasks aligned around shared helpers.
  • Phoenix demo (examples/phoenix_demo) rebuilt around the new dashboard, with seed workflows and a fresh set of LiveViews (executions, pending inputs/events, schedules, home, workflow detail).
  • New scheduler resilience migration (v20260413000000_add_scheduler_resilience) and mix durable.gen.upgrade flow for shipping schema upgrades.
  • Substantial new test coverage: parallel, pubsub, scheduler resilience, executor crash modes, error sanitization, retry context, queue worker, postgres adapter, stale job recovery, wait timeout worker, plus dashboard component tests.

Test plan

  • cd durable && mix precommit (format, compile --warnings-as-errors, credo --strict, test)
  • cd durable_dashboard && mix test
  • cd durable_dashboard/assets && pnpm install && pnpm build
  • cd examples/phoenix_demo && mix test and smoke-test the demo against the dashboard
  • Verify cd durable && mix durable.doctor / durable.migrations / durable.gen.upgrade against a clean Postgres
  • From repo root: mix setup && mix compile && mix test (workspace coordinator fans out to both packages)

kasvith added 13 commits April 29, 2026 17:08
Embeddable web dashboard for Durable: Plug.Router entry → Phoenix
Router → per-page LiveViews (Overview, Workflows, Workflow detail,
Inputs, Schedules, Settings) with a single ReactFlow island for the
workflow graph. Mounted into a host app via the
`use DurableDashboard.Router` macro.
The overview page had two visible bugs:

- "View all" rendered as `<button href>` and never navigated, because
  Core.button always emitted a `<button>` regardless of the
  href/patch/navigate attrs already declared in :rest. Make button/1
  delegate to `<.link>` when navigation attrs are present, which also
  unbreaks the same call sites in stub_live.ex and workflow_live.ex.

- The Recent workflows row only navigated when clicking the workflow
  name; the rest of the row was dead space. Make the entire `<tr>` a
  click target via JS.dispatch("durable:goto", ...), matching the
  pattern DataTable already uses for the same forwarded-sub-router
  reason (see data_table.ex:506-511).

Also reorder the Recent workflows columns to ID, Workflow, Status,
Queue, Started, and reorder WorkflowsLive's column spec to match so
the overview stays a faithful preview of the full list.
- Three bug-report docs under docs/bug-reports/ covering the
  parallel-context-and-serialization investigation, fix plan, and
  follow-up audit.
- CLAUDE.md gains a "Dashboard UI work" pointer to
  durable_dashboard/DESIGN.md so contributors codify visual decisions
  before applying them.
- .gitignore picks up node_modules/ and package-lock.json so dashboard
  asset development doesn't leak into the repo.
Introduces Durable.PubSub, an optional Phoenix.PubSub-backed broadcaster
the engine uses to publish workflow_started / resumed / waiting /
completed / failed / cancelled events. Configuration is opt-in:

- `pubsub: :start` — Durable starts and owns its own Phoenix.PubSub.
- `pubsub: MyApp.PubSub` — reuse one already started by the host.
- omit `:pubsub` — broadcasting is disabled.

`phoenix_pubsub` is added as an optional dependency so existing users
who don't need broadcasting are unaffected. The supervisor adds the
PubSub child only when Durable owns it; a clear error message guides
users who opted in without adding the dep.
Adds V20260413000000AddSchedulerResilience migration that extends the
scheduled_workflows schema with state needed to survive scheduler
crashes mid-trigger. Scheduler API/runtime and the schema are updated
to use the new fields; a host-side migration template is included for
the demo app.

Also adds a scheduler_resilience_test covering the recovery paths.
A bundle of incremental engine work and the tests that go with it:

- Executor / step runner: crash-mode coverage and error sanitization,
  retry-context refinements.
- Queue / postgres adapter: worker-level tests, stale-job recovery
  integration test, adapter behaviour tweaks.
- Wait primitives: timeout-worker integration test plus broader
  wait_test coverage.
- Log capture, query, orchestration, DSL/step, repo: assorted
  improvements pulled from the parallel-context bug fixes referenced
  in docs/bug-reports/.
- Test support: shared TelemetryHandler, SinkWorkflow fixture, and a
  beefier DataCase that boots the full Durable supervision tree.
Adds six new operator-facing Mix tasks plus shared helpers:

- durable.doctor — health check across config, queue, scheduler, db.
- durable.inspect — drill into a single workflow execution.
- durable.pending — list workflows waiting on input or events.
- durable.provide_input — feed input to a paused workflow.
- durable.retry — re-run a failed workflow.
- durable.send_event — trigger a wait_for_event from the CLI.

Existing cancel/cleanup/list/run/status tasks pick up minor consistency
fixes via the new lib/mix/helpers.ex shared module.
- Replace the document/approval LiveViews with a richer set of pages:
  home, executions, pending-events, pending-inputs, schedules, plus a
  redesigned workflow_detail and a workflow_form component.
- Add seven sample workflows (content moderation, drip email, expense
  approval, hourly metrics cron, order fulfillment, payment, payment
  reconciliation) that exercise different Durable features.
- Add a seed_workflows mix task for populating demo data.
- Update layouts, router, application, configs, and asset CSS to match
  the new page layout.
- Bump mix.exs deps to pull in dashboard + new sample workflow needs.
Move :durable into durable/ as a sibling to durable_dashboard, modeled
on elixir-nx/nx. Each package keeps its own mix.exs, mix.lock, _build/,
and Hex publishing pipeline; cross-references go through path: deps. A
thin root mix.exs fans out setup/compile/test/format/precommit to each
published package. CI is rewritten as per-package jobs gated by
dorny/paths-filter with a single ci-status aggregator for branch
protection.
The new dashboard CI job runs `mix format --check-formatted`, which
caught two committed files that were never run through the formatter.
Plug 1.19 dropped this helper. Use put_in/2 on the conn struct, which
is what cookie_session does internally. Caught by the new dashboard
mix compile --warnings-as-errors step.
@kasvith kasvith merged commit d3b47ba into main May 2, 2026
4 checks passed
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