jonnifyelixir
F5 / F5.09 / handoff

F5.09 · part 3 of 3

What ships in F6

F6 brings Phoenix. The temptation is to treat that as a rewrite, but the whole point of the boundary is that it is not. F6 replaces one thing — the thin web layer — with Phoenix and LiveView, and adds the Phoenix endpoint to the same supervision tree. Everything else is kept: the Portal facade is called unchanged, the closed %Portal.Error{} contract is the render surface, the engine and store behind the port are untouched, and the F5.07 tests carry over because they were written against the facade, not the web. The handoff is small on purpose: a stable boundary means the next chapter inherits a working engine and only has to dress it.

Three things F6 builds on. Select one to see what F6 does with it.

What F6 inherits

Three pieces cross the chapter boundary intact. The facade is the API F6 calls; the error contract is the closed set F6 renders; the supervision tree is the structure F6 extends with its endpoint. None of them is rewritten. Select one.

What F6 builds on · select one

THE FACADE · Portal enroll/2 · deliver_lesson/2 · progress_of/1 — called unchanged kept THE ERROR CONTRACT · %Portal.Error{} a closed set of codes — the UI render surface kept THE SUPERVISION TREE · Portal.Application engine + store — F6 adds the endpoint as a child extended

F6 builds on: the facade

what F6 does: F6 calls it unchanged

A good handoff is measured by how little moves. If the next chapter can call what you built without reading how you built it, the boundary held.

Kept and replaced

Only the web layer is replaced. The thin Plug router served by Bandit (F5.01) becomes Phoenix with LiveView; everything below the facade stays as it is. The picture is lopsided on purpose — that imbalance is the dividend of building a boundary.

At the F5 → F6 boundary

REPLACED WEB LAYER Plug/Bandit → Phoenix LiveView KEPT the facade · Portal the engine + store the error contract the F5.07 tests |

One box moves; four stay. The boundary drawn in F5.08 is what makes the column on the right immune to the change on the left.

The endpoint joins the tree

Concretely, the only change to the assembly is one more child. F6 adds PortalWeb.Endpoint to the supervision tree from F5.09.1; the engine and store entries are unchanged, and the same :one_for_one strategy now supervises the web too.

# F6: Phoenix adds its endpoint to the SAME tree — engine and store are untouched
def start(_type, _args) do
  children = [
    Portal.EventStore.adapter(),   # kept from F5.09.1
    {Portal.Engine, []},            # kept from F5.09.1
    PortalWeb.Endpoint             # NEW in F6: the Phoenix endpoint, supervised alongside
  ]

  Supervisor.start_link(children, strategy: :one_for_one, name: Portal.Supervisor)
end

The LiveView from F5.09.2 stops being a sketch and becomes the real thing, mounted by this endpoint — still calling only the facade.

The chapter is done

F5 set out to build the Portal engine the pragmatic way, and it is finished when each of these holds: the app runs from mix run and answers a real request; a command is checked by a contract and recorded as an event; state is a fold of the log held in a supervised process that replays on restart; the suite covers the pure core, properties, and the contract; the boundary is a port, a facade, and a closed error contract; and the whole thing is assembled, mounted behind a LiveView sketch, and described by a spec with build prompts. Each module left the Portal runnable, so the finale is an assembly, not a reckoning.

F5 · the engine

A thin server grew into a supervised, contract-checked engine behind a stable facade.

F6 · Phoenix

Replace the web layer, call the same facade, render the same error contract.

That closes F5 · Pragmatic Programming. The Portal began as a thin server and ends as a supervised engine behind a stable facade, mounted under a LiveView sketch, with a spec and prompts to rebuild it from nothing. F6 picks it up. Back to the lab or the F5 overview.

References

Primary sources for this lesson, and where it connects in the course.

Sources

Related in this course