8000 POC A: return to the huddl you came from after signing in by MichaelDimmitt · Pull Request #672 · huddlz-hq/huddlz · GitHub
[go: up one dir, main page]

Skip to content

POC A: return to the huddl you came from after signing in - #672

Closed
MichaelDimmitt wants to merge 6 commits into
huddlz-hq:mainfrom
MichaelDimmitt:poc/670-return-to-origin
Closed

MichaelDimmitt wants to merge 6 commits into
huddlz-hq:mainfrom
MichaelDimmitt:poc/670-return-to-origin

Conversation

@MichaelDimmitt
@MichaelDimmitt MichaelDimmitt commented Oct 9, 2026 •
Copy link
Copy Markdown
Contributor

POC variant A — "Return to origin" for #670. Baseline variant: the one the other
five are measured against.

Summary

The return_to plumbing was already complete and already safe. It was unevenly
applied — two sign-in links on the same huddl page disagreed about whether the
person's intent was worth keeping:

 huddl page, signed out
   <Layouts.app>
     topbar
-      "Sign in"  -> /sign-in
-      "Sign up"  -> /register
+      "Sign in"  -> /sign-in?return_to=/groups/:slug/huddlz/:id
+      "Sign up"  -> /register?return_to=/groups/:slug/huddlz/:id
     "Sign in to RSVP" -> /sign-in?return_to=/groups/:slug/huddlz/:id   (already)

The person's journey, before and after:

 arrive on a huddl from a link or QR code
 click the topbar "Sign in"
 enter credentials
-land on /agenda          # shows only huddlz already RSVP'd to — this one is not there
-click the Groups chip    # not there either, if the huddl is outside their groups
-go to /discover
-search for the title     # and if they don't remember it, there is no way back at all
-click the huddl
+land back on the huddl
 click "RSVP to this huddl"

return_to is validated inside Layouts.app rather than at the call sites, so a page
cannot hand the header an off-site destination and any future caller is covered without
having to remember. The huddl and group pages pass the return destination they already
computed for their own buttons, so the header and the in-page call to action cannot drift
apart — on the group page that address still carries the join source tag, so attribution
survives the trip through auth.

Evidence

Screenshot

Correction: apologies. The teal "Header links now carry the return destination" banner in the first screenshot is a debug overlay injected only to print the link targets for the screenshot. It is not part of this change and nothing in the diff renders it. The second screenshot shows what the page actually looks like.

Debug overlay (not part of the change):

signed out on a huddl page, the overlay prints the real href of the two header links. Both now carry the return destination, which is the whole of this change and the one thing a screenshot of the chrome cannot otherwise show.

Variant A

Actual page:

No visual difference from before. Only the header links' destinations change, which is not shown in the screenshot.

Variant A, actual page

Before — mix test test/features_test.exs --only header_return_to. The failing test
output is itself the finding; both links appear in the same page:

Step failed: And I click link "Sign in"
  selector "a" returned 14 elements and 2 of them matched the text filter "Sign in":
    <a href="/sign-in" class="btn-secondary">Sign in</a>
    <a href="/sign-in?return_to=%2Fgroups%2Ftrail-pals%2Fhuddlz%2Ff5717f97-...">
      Sign in to RSVP

Naming the header explicitly, the real failure:

1) The header sign-in returns me to the huddl I was reading
   [passed] When I visit the "Dawn Walk" huddl page while signed out
   [passed] And I choose "Sign in" in the site header
   [passed] And I sign in as "guest@example.com" with password "Password123!"
   [failed] Then I should be on the huddl page for "Dawn Walk"
            Could not find any elements with selector "*" and text "Dawn Walk"

2) The header sign-up returns me to the huddl after confirming   [failed]
3) A tagged arrival keeps its source through the header sign-in  [failed]
4) The header sign-in returns me to the group I was reading      [failed]

5) An unsafe return destination cannot redirect the header sign-in   [passed]

Scenario 5 passing before implementation is the intended result: it documents that
AuthReturnTo.validate/1 already refused cross-host, protocol-relative, backslash,
bare-host and encoded-separator destinations. The guard needed no changes.

After — the same command, all five scenarios green. The pre-existing journeys over
the pages this touches (confirmation_participation, join_source, global_header) still
pass unchanged.

Measured click count

Before After
Clicks after credentials, to reach the huddl's RSVP button 3–5, or never 0
Total clicks from the huddl page to attending that huddl 5–7, or never 2

"Or never" is not rhetorical — a person who does not remember the huddl's title has no
path back from the agenda.

The huddl page's own "Sign in to RSVP" was already 2 clicks. So the headline is not that A
makes the best path faster; it is that A makes the most obvious path — the topbar button
that looks like the way to sign in — as fast as the best one.

Full findings, the entry point audit, and answers to the spec's open questions (link-level
vs session capture, JoinSourceTag, register-then-confirm) are in
docs/research/post-login-landing-pocs.md.

Merge Danger

Door: two-way.

Nothing is persisted, no schema or migration, no new route, no data-loading change. The
whole behavioral change is where two existing links point; reverting is deleting the
return_to attr.

Blast Radius: narrow.

No pixels change — two already-styled buttons point somewhere better. Every page other
than huddl show and group show leaves return_to nil and gets the bare paths it has
today. The landing page's sign-in stays bare, correctly: there is no origin to return to.

The one risk worth naming is open redirect, and it is the reason validation sits inside
Layouts.app instead of at the call sites. A scenario holds that guard.

Deliberately out of scope: the bare /sign-in redirects in live_user_auth.ex
(:live_user_required, :admin_required) and live/huddl_live.ex. Those fire when a
signed-out person hits a page that requires an account, not from a huddl or group page.
Worth a follow-up; including them would inflate the baseline and make the comparison less
honest.

Part of #670

Verified by scenario (failing -> passing) and a clean mix precommit
(warnings-as-errors compile, format, full test suite, credo --strict).

Model: Claude Opus 5.5 (claude-opus-5-5)

🤖 Generated with Claude Code

Issue huddlz-hq#670 asks for several competing proofs of concept, each as its own
draft PR, so one can be chosen and the rest declined. This is the shared
brief those PRs are built from: the problem, what the code already does,
one section per variant with its own task list, and the rubric they are
all judged against.

Records three findings that shape the variants: the return_to plumbing is
already complete and safe but only the huddl page's RSVP button produces
such a link; the agenda already loads both scopes every render to feed its
chip counts; and the agenda has no query for huddlz outside a person's
groups.

Part of huddlz-hq#670
The POC variants are compared partly on whether people want to use them,
so a variant that looks unfinished loses Desirable and Delightful for
reasons unrelated to its idea. Ask each one to polish the surface it
changes, and keep the scope discipline pointed at everything else.

Part of huddlz-hq#670
A person who arrives on a huddl page from a link or a QR code and reaches
for the header's "Sign in" loses the huddl they came for: the header's link
is a bare /sign-in, so they land on the agenda, which by definition does not
list a huddl they have not RSVP'd to yet.

These scenarios describe the journey the person expects. Four of the five
fail: signing in or signing up from the header does not come back. The fifth
passes already and is meant to — it documents that AuthReturnTo.validate/1
refuses an off-site return destination before any of this work.

- Cover sign-in from a huddl page and from a group page
- Cover sign-up, where email confirmation intervenes
- Cover a tagged arrival, so join attribution survives the sign-in hop

Part of huddlz-hq#670
The return_to plumbing was already complete and already safe. What it was
missing was reach: only the huddl page's RSVP call to action and the group
page's join button produced a return destination. The topbar's "Sign in" and
"Sign up" — the buttons that look like the way to sign in — were bare paths,
so the two sign-in links on the same page disagreed about whether the
person's intent was worth keeping.

Layouts.app now takes a return_to a page can fill in, and the topbar's
sign-in and sign-up carry it. Validation happens inside the component rather
than at the call sites, so no page can hand the header an off-site
destination and any future caller is covered without having to remember.

The huddl page and the group page pass the destination they already computed
for their own buttons, so the header and the in-page call to action cannot
drift apart. On the group page that address still carries the join source
tag, so attribution survives the trip through auth.

- Add a validated return_to attr to Layouts.app
- Point the topbar's sign-in and sign-up at it
- Pass each page's existing return destination from huddl and group show
- Record the measured click count and entry point audit in the POC spec

Part of huddlz-hq#670
The POC A Findings block was written with an unbounded string replace, so it
landed in all seven variants' sections and overwrote B through G's empty
placeholders. The doc then asserted A's click counts and terminology choice
as if they belonged to every variant, and would have conflicted with five
agents editing those same sections.

Rebuilt from the pristine doc: only variant A's section carries Findings, and
B through G have their placeholders back byte-for-byte.

Part of huddlz-hq#670
Copy link
Copy Markdown
Contributor

Thanks for catching the header sign-in issue, Michael. Returning people to the huddl or group they came from is the right fix. Closing this POC while we prepare a focused replacement that covers the sign-in return paths and preserves the page state through authentication.

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.

2 participants

0