The new JRNI builder — a WYSIWYG, typed step-sequence configurator for the booking flow a customer walks through (appointments · events · walk-in queues), with a live brand-themed preview that is the published experience. A component within the Events Studio application, installable per-account.
Current: Phase 0 (access foundation — two-layer gating, both tiers) in flight; Phases 1, 2, 3, 4 & 5 verified on branch · building on branch feat/journey-builder in voyage via a Codex factory (Codex implements each turn, Claude orchestrates + independently verifies). Only Phase 6 (e2e acceptance on a deploy) remains after access.
JourneyConfig step-sequence configurator (a fixed, reorderable/toggleable stage catalogue with per-stage settings + a live two-way-bound preview). It is NOT a block/page "Canvas" builder, and persistence is structured config JSON, not a blocks[] array. The published journey captures real input — it's the customer's live booking flow.
Seven phases from the engineering spec. Build order leads with the type foundation, then the gated surface, then access, then the editor/persist/render, then a live end-to-end acceptance walk.
| Phase | Status | Scope |
|---|---|---|
| Phase 1 | Verified on branch | Type foundation: @voyage/journey-runtime (the JourneyConfig model + 7-stage catalogue + default-order-by-type + pure helpers) and the @voyage/journey-builder package skeleton. No UI/DOM deps in the runtime so the public bundle stays lean. |
| Phase 2 | Verified on branch | Shell route + nav skeleton: exported JourneyBuilderRoute, inline gated /journeys + /journeys/:id/edit, a gated primary-nav "Journeys" item (disabled → redirect to dashboard), an honest empty-state list + type-picker modal, and the three-zone editor scaffold rendering a real journey-runtime preview. Gate verified enabled+disabled; axe-clean; no horizontal scroll desktop/mobile. 72c63832. |
| Phase 0 | In flight | Access foundation (both layers, both tiers): control-plane feature_catalog flag journey_builder + a dedicated journey.build capability, enforced at app route-guard AND API; SAML JIT configurable attribute mapping; conflict UX = hide nav + redirect-with-toast, never error. Meets the identity-stack security bar. (Deferred through Phases 1–5 by design; now being wired by composing into the existing identity infra.) |
| Phase 3 | Verified on branch | Builder surface: the three-zone editor (top bar · ~372px Customize sidebar · live preview canvas with clickable step strip), per-stage settings panels, reorder/enable-disable, custom text + branding/footer, and the live two-way binding that is the WYSIWYG loop. ?step= URL state + per-page document.title. 1cb82688. |
| Phase 4 | Verified on branch | Persistence + publish: JourneySurfaceRow + journey_surfaces D1 table (partial unique index = one live per (tenant,journey)), seven v1/journeys endpoints on the events worker, atomic single-live publish via batch([demote, promote]), parameterized + signed-context tenant scoping, admin-gated, audited. Editor Save/Publish wired real (honest offline fallback). SDK-friendly camelCase DTOs + paginated list. 06e290b9. |
| Phase 5 | In flight | Public render: PublicJourneyRoute at one slug per journey — sequential branded full-page steps (header · step body · summary rail · Back/Continue), SPA transitions with ?step=, per-journey BrandKit, and input capture via the existing submitPublicRegistration. Preview render and public render share journey-runtime — byte-identical. |
| Phase 6 | Planned | End-to-end acceptance on a live deploy: create → configure stages → save draft → publish → load the public journey → complete it → read the captured registration back. Axe-clean, no horizontal scroll at any breakpoint, full keyboard operability, URL-state safe, both access layers enforced. |
One row per Codex turn; each independently verified by Claude before acceptance. Chronological, newest at the bottom. All commits are local on feat/journey-builder (not pushed).
| Turn | Status | Scope | Commit |
|---|---|---|---|
| Turn 1 · Phase 1 | Verified on branch |
Built:
|
fed0b73d |
| Turn 2 · Phase 2 | Verified on branch |
Built:
|
72c63832 |
| Turn 3 · Phase 3 | Verified on branch |
Built (the WYSIWYG core):
|
1cb82688 |
| Turn 4 · Phase 4 | Verified on branch |
Built (Save/Publish made real):
|
06e290b9 |
| Turn 5 · Phase 5 | Verified on branch |
Built (public render + input capture):
|
5b15f679 |
| Turn 6 · Phase 0 | In flight |
Building (access foundation — two-layer gating, both tiers):
journey.build) at both tiers; a hand-crafted API request without the capability is rejected (UI-hide is not the only control). Identity-stack bar (audit, parameterized, no enumeration). Claude exercises the deny paths at the API tier before accepting.
|
— |
Canonical engineering spec committed in-repo at docs/journey-builder/engineering-spec.html (from the Claude Design handoff + the Journey Builder.fig prototype). Access model is firm; four naming/SSO defaults are PM/Platform calls.
journey_builder (operator/platform-level; hides nav + builder + the Designer-capability assignment UI when absent).journey.build (custom-role off the administrator prefab for v1; SSO via configurable attribute mapping). Enforced app-level AND API-level.event_id seam is surfaced; merging is a product decision).Operator direction (2026-06-04): the WYSIWYG builder is one consumer of the Voyage journey/registration APIs. Anyone — including Claude — should be able to custom-build their own journey / event-registration portal against the same backend APIs. Queued as a follow-on after the core builder (not in the current v1 phases).
Before any SDK or custom app can call a Voyage tenant, there must be a first-class way to mint and manage credentials. This is Voyage's responsibility to build once and document — not something each integrator reinvents. It is a prerequisite for the SDK/reference-app deliverables below.
v1/journeys, the public render + submitPublicRegistration capture seam), authenticating via the credentialing plane above.