feat(weekly-rotation): make the mix shareable - #14587
Merged
Merged
Conversation
A Weekly Rotation can now be linked. Sharing produces /explore/weekly-rotation/:handle, which shows that listener's mix to anyone (the endpoint is public), and unfurls with a 2x2 collage of the mix's first four tracks rendered by og.audius.co. The bare /explore/weekly-rotation stays the signed-in user's own mix. Under /explore rather than /:handle/weekly-rotation because /:handle/:slug is the track permalink pattern. - common: `weeklyRotation` share type, request and content; the content is just the listener, since there is no entity behind the mix. useWeeklyRotation takes an optional userId. Share analytics get a `weeklyRotation` kind. Copy says Wednesday: the rollover moved. - web: Share button on the page; the share modal builds the link from the handle and copies it directly, there being no social saga to route through. The handle route is registered in both router trees and gets a Vike SSR entry that emits the collage as og:image with the period stamped into the URL as a cache-buster. getWeeklyRotationPeriod mirrors the API's Wednesday-shifted ISO week and carries the same test cases. - mobile: share icon in the top bar, the share drawer offers DM, X, Copy Link and the system sheet (the story paths need a single streamable track, which a mix does not have), the screen takes an optional handle, and explore/weekly-rotation/:handle? is deep-linkable. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
This was referenced Sep 8, 2026
dylanjeffers
added a commit
to AudiusProject/api
that referenced
this pull request
Sep 8, 2026
… shared (#1034) ## Why Weekly Rotation is becoming shareable (`audius.co/explore/weekly-rotation/:handle`: AudiusProject/apps#14587 and AudiusProject/og#6). Two things on the API side had to change for a shared link to mean anything. ## What **Rollover moves to Wednesday 00:00 UTC** (was the ISO week boundary, Monday). Product call from Michael's Weekly Rotation thread: Monday already belongs to the other weekly surfaces and Friday is Spotify's. The period is still identified by an ISO `(year, week)` pair, it's the ISO week shifted forward two days, so cache keys, the jitter seed and share links keep their shape. `weeklyRotationPeriod` / `weeklyRotationPeriodStart` are inverses and tested as such. **Listener history is frozen at the rollover instant.** Plays, saves, reposts and follows are now read as of the period's start (`@periodStart`) rather than the request. Before this, playing a track *from* the mix met the played-exclusion and removed it on the next cache miss, so a mix shared on Wednesday was a different, shorter list by Thursday. The mix has to survive being listened to. Still drifts mid-week: the trending candidate pool and engagement counts. Freezing those needs a stored snapshot table; not in scope here. ## Tests - `TestWeeklyRotationPeriod`: rollover instant, one second before it, Monday/Tuesday belonging to the previous period, non-UTC input, the 2026/2027 year boundary, and a round trip over every hour of 2026. - `TestV1UsersWeeklyRotationKeepsTracksPlayedThisPeriod`: a play dated now leaves the track in the mix; a play from 8 days ago still excludes. - Existing fixtures dated their history 8 days back so they predate any possible rollover. All eight weekly-rotation tests pass against the compose DB. ## Not in this PR Michael's thread also describes the mix as new music from artists you follow / have liked. The shipped ranking does the opposite on purpose (followed artists demoted, For You is the in-network surface). Needs a product decision before anyone touches the scoring. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
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.
What
A Weekly Rotation can now be shared. Share produces
audius.co/explore/weekly-rotation/:handle, which shows that listener's mix to anyone (the endpoint is public, no auth), and unfurls with a 2x2 collage of the mix's first four tracks rendered byog.audius.co/weekly-rotation/:handle?week=YYYY-WW.The bare
/explore/weekly-rotationstays the signed-in user's own mix. Under/explorerather than/:handle/weekly-rotationbecause/:handle/:slugis the track permalink pattern.By package
common
ShareType/ShareModalRequest/ShareContentgainweeklyRotation. The content is just the listener (User): there's no entity behind the mix, the link is a function of the handle.useWeeklyRotation({ userId })takes an optional target user; defaults to the viewer.Share/ShareToTwitteranalytics get aweeklyRotationkind.WEEKLY_ROTATION_USER_PAGE+weeklyRotationPage(handle). Copy says Wednesday: the rollover moved (api PR).web
Shareevent the sagas emit, there being no social saga for a non-entity.useUserByHandle, titles as "{name}'s Weekly Rotation" for someone else's mix, and only the handle route getsog:image+ canonical (the bare route is per-viewer and shouldn't be indexed as anyone's).ssr/weekly-rotation(/explore/weekly-rotation/@handle): fetches the user for the name, emits the collage URL asog:image,summary_large_image. The bare route still falls to the explore handler, which now has aweekly-rotationentry inexploreMap.utils/weeklyRotationPeriod.ts: dependency-free mirror of the API's Wednesday-shifted ISO week, used by SSR (which avoids@audius/common/utils) and the client. Same test cases as the Go side so they can't drift apart. 7 vitest cases.mobile
WeeklyRotationScreentakes an optionalhandleparam;explore/weekly-rotation/:handle?added to the explore deep-link map.Verified
tscclean in common, web, mobile. ESLint clean on every touched file.weeklyRotationPeriod.test.tspasses.Not verified
Depends on
og:image500s and unfurlers show no image).Product note
Michael's Weekly Rotation thread describes the mix as new music from artists you follow / have liked. The shipped ranking does the opposite on purpose. Not changed here; flagged on the api PR.
🤖 Generated with Claude Code