feat(studio): station journal review surface in the diagram view#643
Open
themightychris wants to merge 12 commits into
Open
feat(studio): station journal review surface in the diagram view#643themightychris wants to merge 12 commits into
themightychris wants to merge 12 commits into
Conversation
themightychris
changed the base branch from
main
to
feat/station-journal-entries
June 24, 2026 13:56
Collaborator
Author
themightychris
marked this pull request as ready for review
June 24, 2026 21:17
This was referenced Jul 14, 2026
Surface companion-captured journal entries in Pathways Studio so they can be reviewed at a desk and closed. Adds to the station diagram LiveView: - A "Journal" toolbar button (open-entry count badge) opening a drawer that lists entries newest-first with target chip (station/node/pathway/pin), author, time, note, and photo thumbnails (full image opens in a new tab). - Close / reopen as a desk action: close_journal_entry/2 + reopen_journal_entry/1 context fns set/clear closed_at + closed_by. Closed entries stay in the list, de-emphasized with a "Closed by X · when" badge — never hidden or filtered out. - Pin markers on the level diagram overlay, drawn from diagram_x/diagram_y in the same 0–100 space as node markers, filtered to the active level by stop_level_id; clicking one opens the drawer focused on that entry. Photo URLs reuse the field-capture path; author/closer names resolve to emails. LiveView tests cover listing, close (stays visible), reopen, the pin marker, and the count badge. Stacks on the journal backend (#641) until it merges. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UyezV5kznW5rbRFVsoXWvh
The journal was an overlay drawer that blocked the diagram while open, forcing the reviewer to flip back and forth. But the entries are the *input* to the editing work — they should stay visible while you edit. Convert it to a docked side rail that takes layout space: the diagram canvas flexes to share width, the journal sits beside it (sticky, independently scrollable), and the toolbar button toggles it. Both stay fully interactive. Renamed the assign/handlers to journal_panel_* to match. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UyezV5kznW5rbRFVsoXWvh
…e it The docked-in-the-sub_header panel still got covered when a node/pathway edit drawer (a fixed right-0 overlay) opened — so you couldn't read the journal while editing. Make the journal a fixed full-height right rail (its own scroll), reserve its width on #diagram-page (pr-96), and shift the shared slide-in drawers + their overlay left by the rail width via a `.journal-open .app-drawer` CSS hook. Now the node/pathway edit drawer opens to the LEFT of the journal — both visible at once. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UyezV5kznW5rbRFVsoXWvh
A sticky All | Open | Closed button group at the top of the journal rail filters the list (default All — closed entries still show by default, consistent with the never-hidden treatment). Open = no closed_at; Closed = closed_at set. Empty-state message reflects the active filter. LiveView test covers all three scopes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UyezV5kznW5rbRFVsoXWvh
The target chip overflowed for long node names and gave no way to correlate an entry to the map. Now: - Target chip is a truncating pill (full name in title) and a click affordance: node/pathway open their editor (edit_child_stop/edit_pathway) beside the journal; a pin highlights its marker (pulsing ring). - Diagram → journal: nodes/pathways with an OPEN entry show a subtle amber "!" indicator while the journal is open; clicking it opens/focuses that entry in the rail (rings it + scrolls into view via a phx:journal_focus event). Threads journal_targets (target_id→entry_id, open-only) + journal_focus_id through diagram_canvas → overlay → stops/pathways/pin layers. Tests cover the clickable chip and focus_journal_entry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UyezV5kznW5rbRFVsoXWvh
The node/pathway "has an open entry" indicators were rendered inside the phx-update="stream" stops/pathways layers, which don't re-render on assign changes — so toggling the journal never made them appear. Move them to a dedicated non-stream journal_indicators_layer fed by server-resolved positions (node = its diagram point, pathway = from/to midpoint), so they react to journal open/close and entry changes. Test asserts none when closed, indicator when open. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UyezV5kznW5rbRFVsoXWvh
The journal pin markers and node/pathway "!" indicators were drawn in diagram space, so they scaled with zoom — unlike node markers, which the DiagramCanvas hook counter-scales. Tag both with data-journal-scale + data-center-x/y and add a counter-scale pass in scaleOverlayElements (transform scale 1/iconScale about each center), so they hold a fixed on-screen size like node markers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UyezV5kznW5rbRFVsoXWvh
The map→journal indicators + pins were already scoped to the active level, but a chip click (journal→map) called edit_child_stop/edit_pathway/focus_journal_pin directly, which don't switch level — so a target on another level acted off the visible diagram. Route chips through a new journal_locate (keyed by entry id): resolve the target's level (pin → its stop_level; node/pathway → the stop's GTFS level_id), switch the diagram there if needed (reusing search_stop's pipeline, extracted as switch_to_level/2), then open the editor / focus the pin. Tests cover same-level open + the cross-level switch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UyezV5kznW5rbRFVsoXWvh
- Node + pathway editors are mutually exclusive now: opening the node editor
closes the pathway drawer and vice-versa. They were both staying open (same
z-50, pathway rendered later + wider, so it only *looked* closed in one order).
- Note bodies no longer render with a leading indent: the whitespace-pre-wrap
<p> had the interpolation on its own line, so the markup's indentation was
preserved as text. Inlined {entry.body}.
- Each rail entry shows its target's level as a small tag (resolved in
load_journal via entry_level_name), so you see an entry's level before clicking.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UyezV5kznW5rbRFVsoXWvh
…format
The previous inline fix was undone by the HEEx formatter, which reflowed
>{entry.body}</p> onto its own indented line; whitespace-pre-wrap then rendered
that markup indentation as a leading indent. phx-no-format keeps it flush.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UyezV5kznW5rbRFVsoXWvh
Complaint: the journal rail looked like the edit drawers (white surface, emerald header, right-anchored), so an open editor beside it read as double-stacked panels. Re-style the rail as a distinct reference surface, not another modal: muted recessed background (bg-base-200, no shadow) with an amber identity (amber left-edge accent, amber header + clipboard icon, amber active filter + focus ring). Open entries become white lifted cards floating on the muted rail; closed ones blend in. The white, shadowed, emerald editors now clearly float in front. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UyezV5kznW5rbRFVsoXWvh
The station-journal backend merged to main via #655 (replacing #641, which this branch was stacked on). Same tables and wire contract, different domain shape — journal operations now go through GtfsPlanner.Gtfs.StationJournal with a trusted Scope struct: - load_journal builds a Scope from the LiveView's already-authorized org/version/station + current user and calls Gtfs.list_station_journal/1; photos arrive preloaded on each entry (the separate photo listing and group_by are gone). - Photo thumbnails use PhotoStorage.public_path/2 instead of a hand-rolled field-captures URL helper. - switch_to_level drops assign_selectable_reference_stop_levels/ sync_reference_overlay_state — main replaced the reference-overlay internals with the other-levels work (#646); the journal pipeline mirrors main's search_stop level switch. - Test fixtures insert JournalEntry rows directly (the 641-era upsert_journal_entry sync path no longer exists; the companion's write path is the scoped sync API, which these desktop read/close tests don't exercise). Full suite on this branch: 2012 tests, 0 failures, 6 skipped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HoGkr6FT6SKZCYDBkNqKBj
themightychris
force-pushed
the
feat/station-journal-desktop
branch
from
July 14, 2026 21:34
d21b591 to
a1d67fd
Compare
themightychris
changed the base branch from
feat/station-journal-entries
to
main
July 14, 2026 21:34
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Station journal — desktop review surface (Pathways Studio)
Surfaces companion-captured journal entries in the Studio station diagram view so they can be reviewed at a desk and closed. Implements the desktop side of
specs/api/station-journal.md(spec lives in the companion repo, pathways-field-companion).What it adds
Gtfs.close_journal_entry/2+reopen_journal_entry/1set/clearclosed_at+closed_by. Closed entries stay in the list, de-emphasized with a "Closed by X · when" badge — never hidden or filtered out.diagram_x/diagram_yin the same 0–100 space as node markers, filtered to the active level bystop_level_id; clicking one opens the drawer focused on that entry.Photo URLs reuse the field-capture path; author/closer ids resolve to emails.
Verification
closed_at/closed_by(confirmed via the bundle API).Not in scope
🤖 Generated with Claude Code