F6 · the capstone lab · module 9
The live dashboard
This is the lab where the whole course converges. The goal is a real-time operations dashboard: a
single screen that shows how many courses and enrollments exist, a live feed of what is happening, and how many
people are watching right now — all updating the instant anything changes, for everyone at once, with no
reload. Nothing here is new machinery. The dashboard is a LiveView (F6.06) holding a small
read model on its socket: counts seeded from the contexts (F6.04) at mount,
plus a capped stream for the activity feed. It comes alive because the engine emits
domain events (F5) and the domain broadcasts them on a topic (F6.07); the dashboard
subscribes on its connected mount and, in handle_info/2, folds each event into
the read model — bump a count, prepend a feed row. Because one broadcast fans out to every subscribed
LiveView, every open dashboard updates together, and Presence turns “who is subscribed”
into a live viewer count. Protected by the auth from F6.08 and clustered across nodes in production, it is the
same supervised system you have built all along — now observing itself in real time.
Three dives: build the dashboard as a read model, broadcast engine events into it, and serve many clients live — F5, F6.04, F6.06, F6.07, and F6.08, wired into one screen.
One event, every dashboard live
read model — enrollments 41, 3 clients live
Emit an event: the engine broadcasts on "events", handle_info/2 folds it, and every client mirrors the new count.
Three moves of the lab
The lab is three moves, one per dive. Build the dashboard LiveView and seed its read model from the contexts. Broadcast engine events and fold them in as they arrive. Serve many clients so every viewer stays in sync, with a live count. Select a move.
The lab · select a move
move: build
does: a read model seeded from contexts
The dashboard writes nothing. It seeds from the read side of the domain and then keeps itself current by listening — a projection over the event stream, not another source of truth.
Where the course converges
Follow one event all the way through. The F5 engine records a fact; the context broadcasts it on the
"events" topic the moment the write succeeds; PubSub fans that one message out to
every subscribed dashboard; each dashboard’s handle_info/2 folds it into its read
model and pushes a diff to its browser; and Presence keeps the viewer count honest. Every layer you built has a
place in this single path.
engine → broadcast → every dashboard, folded & live
There is no orchestrator in the middle deciding who needs what. Each dashboard independently folds the same event into its own view, and the runtime delivers the message to all of them. That is the BEAM model, end to end.
Three deep dives
In order: build the dashboard and seed its read model; broadcast engine events and fold them in; and serve many clients with a live viewer count, clustered for production.
handle_info/2.Presence viewer count; read-only, clustered across nodes.eight modules of parts
an engine, contexts, routing, templates, LiveView, PubSub, and a deploy.
one live screen
the dashboard assembles them into a real-time view of the running system.
Start with building the dashboard, then broadcasting engine events, then many clients, live. This is the final module of the Phoenix chapter and of the course — the capstone over everything in F6 and the F5 engine beneath it.
References
Live state over a socket, handling broadcasts, streams for collections, and the built-in dashboard as a real-world example of the pattern.
Sources
- Phoenix.LiveView — live state over a socket.
- Phoenix.LiveView — handle_info/2 — folding broadcasts into a LiveView.
- Phoenix.LiveView — stream/3 — large, append-only collections.
- Phoenix LiveDashboard — the built-in monitoring UI, a real-world LiveView fed by telemetry.
Related in this course
- F6.09.1 · Build the dashboard
- F6.09.2 · Broadcast engine events
- F6.09.3 · Many clients, live
- F6.07 · PubSub — the fan-out the dashboard rides on.
- F6 · Phoenix Framework