DEF-004 — Post-Spotify consent returns to /rankings without auto-opening Export¶
Summary¶
After approving Spotify access (login + consent), the app redirected back to /rankings but landed on the standard Rankings view. The user had to click Export to Spotify a second time to reopen the export UI. Expected behavior is to auto-open the Export panel upon return so the user can continue the in-progress export without additional clicks.
Environment¶
- App:
Melodex(local dev) - Commit:
333d6ca - Browser:
Firefox(desktop) - Device:
Windows 11 - Network:
Spectrum(~450 up / 11 down) - Date/Time:
2025-11-10
Triage¶
- Severity:
Minor - Priority:
High
Preconditions¶
- Valid Spotify account.
- User begins export from
/rankings(some items selected, optional name/description entered).
Steps to Reproduce (original)¶
- On
/rankings, click Export to Spotify. - In Spotify, complete login and click Agree to grant scopes.
- Observe redirect back to the app at
/rankings.
Expected Result¶
- App resumes the export flow automatically: Export UI opens after OAuth with previous context (checked items, name/description) intact.
Actual Result¶
- Page returns to
/rankingsshowing the standard Rankings view. - User must click Export to Spotify again to proceed.
Impact¶
- Increases friction in a critical conversion path.
- Heightens risk of lost context (e.g., description text, selections).
- Potentially increases abandonment if combined with separate export errors.
Attachments¶
- Console breadcrumb:
Local dev: overriding Amplify redirect URLs - Server trace showing
/auth/session200 followed by return to/rankingswithout auto-open (LINK) - Short screen capture of the double-click requirement (LINK)
Suspected Areas¶
- Missing/ignored export intent on the OAuth round-trip (
returnTo/ state). /rankingsmount logic not consuming an intent flag to open Export.- Over-eager
/auth/sessiongating causing re-auth loops in some statuses. - Filters not preserved in redirect, making the post-return view feel reset.
Diagnostics¶
- Reproduced consistently with a personal Spotify account.
- Observed
/auth/session→ 200 prior to the second manual click. - Verified redirect lands on
/rankingswithout selection UI automatically opening.
Owner: Michael DeReus
Status: Resolved
Opened: 2025-11-10
Closed: 2025-12-12
Linked Items¶
- Risks:
- R-01: Onboarding/auth failures
- R-02: Token refresh failures (silent 401s) break export mid-flow
- R-12: Legal / Terms non-compliance (Spotify/Deezer API usage)
- R-20: User confusion about export scope (filters vs. selection)
- Related Tests: IT-001, IT-002, IT-010, UI-001, E2E-003, E2E-007, E2E-Export-OAuth-Resume (new)
Fix Reference¶
- Commit:
98fd350 - PR:
#33- fix: DEF-004 - CI:
Root Cause¶
- Intent not persisted: The client initiated
/auth/startwithout a durable export intent (e.g.,returnTo=/rankings?export=1or equivalent state). After OAuth,/rankingsmounted with no signal to auto-open Export. - Loop-prone gating: Client treated ambiguous
/auth/sessionoutcomes (e.g.,304, parse issues) as “not connected”, occasionally re-triggering/auth/startand preventing the resume path. - Filter context not carried: Active
genre/subgenrewere not appended toreturnTo, so the view appeared reset even when the user had filtered before export.
Changes¶
- OAuth intent carry & resume
- Build
returnTo=/rankings?export=1when sending the user to/auth/start; also drop a fallback sessionStorage intent flag to survive provider quirks. - On return to
/rankings, consumeexport=1or the intent flag and auto-open selection mode, seeding visible items. - After opening, clean
?export=1from the URL (avoid sticky behavior on refresh).
- Build
- Session check hardening
ensureSpotifyConnected()now usescache:'no-store'and only redirects for 401/403 or explicit{ connected:false }.- Ambiguous statuses (e.g.,
304,204, transient 5xx with parsable body) are treated as connected to prevent auth loops.
- Filter persistence
- Include current
genre/subgenreinreturnToso the post-OAuth list matches the pre-OAuth view. - Rankings initial fetch reads filters from
location.searchinstead of forcing defaults.
- Include current
- Minor QoL
- Stabilized selection-mode open path and seeded default playlist name deterministically.
Verification¶
- Integration:
- IT-Auth-OAuthResume (new):
/auth/callback→/auth/session {connected:true}→ auto-open Export on/rankings?export=1without a second click.
- IT-Auth-OAuthResume (new):
- E2E:
- E2E-Export-OAuth-Resume (new): Start from
/rankings?genre=pop&subgenre=any; after consent, Export opens automatically and the same filters are applied. No repeated/auth/startand no extra click is required.
- E2E-Export-OAuth-Resume (new): Start from
- Manual:
- Confirm no re-auth loop; confirm
?export=1is removed post-open; confirm selections/name/description persist where applicable.
- Confirm no re-auth loop; confirm
Verified in: 98fd350 on 2025-12-12
Verification Status: Pass