Skip to content

release: onboarding sequence → prod (chat#1867) — router, steps, first-task emails, add-artist, Kimi K3#1880

Merged
sweetmantech merged 7 commits into
mainfrom
test
Jul 22, 2026
Merged

release: onboarding sequence → prod (chat#1867) — router, steps, first-task emails, add-artist, Kimi K3#1880
sweetmantech merged 7 commits into
mainfrom
test

Conversation

@sweetmantech

@sweetmantech sweetmantech commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Promotes the onboarding sequence bundle from test to main/prod. Tracking: chat#1867.

⚠️ Merge gate — include #1879 first

chat#1879 (seed the catalog by kicking POST /api/valuation on first artist add) is not yet on test and is required — without it a brand-new signup dead-ends at "Claim your catalog" (verified). Merge #1879test before merging this release (it auto-joins this PR). Everything below was verified end-to-end with #1879 on preview: fresh signup → add artist → auto socials + auto catalog → schedule weekly report → onboarding complete, Mondays-9am emailing task created.

What's included (6 merged to test, + #1879 pending)

PR What
#1872 State-derived onboarding router (resume-on-landing + skip-for-now)
#1873 Post-valuation catalog report page (/catalogs/[catalogId])
#1870 Roster + socials verification steps
#1871 First-task step — pre-run report + confirm weekly schedule
#1877 First-task weekly report emails (LA EQUIS template) + Kimi K3 default + DRY chat renderer
#1878 /artists "Add New Artist" → shared Spotify search (kills the loop)
#1879 (merge to test first) Seed the catalog on first artist add → closes the dead-end

Prod-impact call-outs (review before merge)

Verified

End-to-end on preview (multiple fresh signups): add-artist Spotify search, auto-catalog seed (0→1, real bands), first-task pre-run + confirm → weekly emailing task (Mondays 9am), onboarding completes and Home shows the catalog-value + weekly-task state. CI green on the constituent PRs (incl. the organizeModels fix).


Summary by cubic

Promotes the new onboarding sequence to production to help new accounts activate faster. Ships a state-driven router, a real catalog report, roster/social verification, a pre-run weekly report that emails, a Spotify “Add New Artist” dialog that seeds the first catalog, and switches the default model to moonshotai/kimi-k3 (chat#1867).

  • New Features

    • State-derived onboarding router with resume-on-landing and skip-for-now; pinned checklist after skip.
    • Roster + socials steps: confirm artists; edit/add profile links; proceeds even with no matches.
    • Catalog report at /catalogs/[catalogId]: valuation echo, stats, per-release table with art, insights, and one CTA to set up a weekly report; Manage songs is a secondary tab.
    • First-task step: pre-run the weekly report via chat, then “get this every Monday?”; report emails; uses the shared chat renderer.
    • Global “Add New Artist” dialog with Spotify search; fixes the /artists loop; on the first artist add, auto-seeds a catalog by calling POST /api/valuation.
  • Migration

    • Default chat model is now moonshotai/kimi-k3 (replaces openai/gpt-5.4-mini); expect higher cost.
    • Incomplete accounts will see the onboarding sequence on landing; activated accounts continue to the normal home.

Written for commit d4023f5. Summary will update on new commits.

Review in cubic

sweetmantech and others added 6 commits July 21, 2026 06:43
…ing + skip-for-now (#1872)

* feat(onboarding): state-derived onboarding router with resume-on-landing + skip-for-now

On every authenticated landing, chat home derives the onboarding step
from the activation checkpoint predicates (has artists -> artists have
socials -> has claimed catalog -> has enabled task) over existing data
sources, never a stored wizard cursor (#1867). Incomplete
accounts resume the sequence at the first unmet step; an always-visible
skip drops to the app with a dismissible session-scoped checklist;
activated accounts never see it. Step cards are titled placeholders
linking to the existing pages until the step PRs land.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(onboarding): review fixes — checklist clipped by right rail, account-scoped session flags, storage safety, fresh catalogs per landing, roster-error fail-open, h3 card heading

Fixes the preview-verified dismiss bug and all cubic findings on #1872:

- Dismiss live bug: the checklist was position:fixed to the viewport, so
  the z-[65] ArtistsSidebar rail overlapped its right edge and clipped
  the dismiss button off-screen. Now absolute within the (relative) home
  content area. Gate state was already single-owner (HomePage passes
  callbacks down) — locked in with a HomePage-level dismiss/skip/resume
  test.
- P1 cross-account leak: skip/dismiss sessionStorage keys are scoped by
  account id and re-derived when the account in the tab changes
  (useOnboardingSessionFlags).
- P2 storage safety: read/write go through safe helpers that no-op on
  throwing storage so the gate fails open instead of crashing.
- P2 catalogs staleness: useRefreshCatalogsOnLanding invalidates the
  catalogs cache on onboarding mount for one fresh read per landing;
  useCatalogs behavior unchanged for other consumers.
- P2 roster-error fail-open: useArtistsRoster now exposes isError;
  deriveOnboardingState keeps isReady false on roster error so the view
  resolves to none.
- P3 hook length: projection extracted to pure deriveOnboardingState.
- P3 heading hierarchy: step card h1 -> h3 under the container h2.

Tests: TDD red-first; +26 tests (jsdom + @testing-library/react added as
devDeps; vitest include extended to .test.tsx). 174 passing; tsc clean
apart from the 7 pre-existing main errors in lib/emails tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(onboarding): make the skip checklist a persistent, non-dismissible reminder

Remove the checklist-dismissed escape hatch entirely. After "skip for now"
the bottom-right "Finish setting up" card is now always present while
onboarding is incomplete (survives refresh via the session skip flag), and
clicking it re-opens the sequence — there is no way to permanently hide it.

Net-removal: drops the second session flag, its storage read/write usage,
the dismissChecklist callback threading, the X/Dismiss button, and the
separate "Resume setup" button (the card header is now the resume trigger).
getOnboardingView collapses to two views (sequence | checklist) and
OnboardingFlag to a single member.

+47 / -134. Full suite 181 pass, tsc clean on touched files, prettier clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(onboarding): restore plain title + add explicit "Continue" button

The checklist header "Finish setting up" is a plain title again (it read as
non-clickable). Re-opening the sequence is now a clearly-styled primary
"Continue" button at the bottom of the card, replacing the ambiguous
click-the-header affordance.

Suite 181 pass, tsc clean on touched files, prettier clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…67 sequence step 1) (#1873)

The marketing valuation CTA landed on a bare Catalog Songs admin screen.
/catalogs/{id} now opens as a real catalog report: valuation echo
(central value + range via the ported marketing formula), lifetime
streams, tracks/releases measured, per-release table with album art,
per-section diagnosis + prescription copy, and one primary CTA
(set up your weekly report -> /tasks). The existing songs/ISRC
management UI stays reachable as a secondary Manage songs tab.

Valuation math mirrors marketing/lib/valuation (identical constants;
age from the api's catalog_age_years, 5y default). Release rollups are
null-safe on album/name/artist metadata independently of the sibling
crash-fix PR. Reuses the chat#1852 useCatalogMeasurements hook,
extending its response type with the v2 aggregate fields as optionals.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat: roster + socials verification onboarding steps (chat#1867)

Two self-contained onboarding step components for the chat#1867
sequence, mounted standalone at /onboarding/roster so the slice is
user-testable before the onboarding router lands:

- ConfirmRosterStep: shows the auto-created artist(s) from the
  valuation flow, inline "add another artist" for multi-artist
  managers (existing POST /api/artists endpoint), confirm to advance.
- VerifySocialsStep: per rostered artist, lists the auto-matched
  socials with handle + follower count; each match is confirmed or
  rejected, wrong matches are fixed by pasting the correct profile
  link (existing PATCH /api/artists/{id} profileUrls path), and
  artists with no socials record an explicit "none".

Verification state is pure client-side logic (lib/onboarding/*,
TDD'd): verdict reducers, per-artist and step-level resolution
predicates, PATCH payload building with APPPLE->APPLE platform-key
normalization, and a follower-count accessor tolerant of the API's
snake_case rows behind chat's camelCase SOCIAL type.

No new endpoints, tables, or context providers - hooks compose the
existing ArtistProvider / OrganizationProvider / Privy auth.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(onboarding): simplify verify-socials to accept-by-default (chat#1867)

Per design review: drop the per-social Correct/Wrong verdicts, the
resolution/gating machinery, and the explicit "This artist has no socials"
button. Matches are accepted by default; the only actions are Edit (fix a
wrong link, existing PATCH profileUrls path) and — for an artist with no
matches — a soft nudge + "Add a profile". Continue always proceeds (empty
= implicit none).

Deletes the verdict code that would otherwise be merged and immediately
removed: socialVerificationTypes, applySocialVerdict, isArtistSocialsResolved,
areAllArtistsResolved, markArtistHasNoSocials, findSocialIdByPlatform,
useSocialsVerification, SocialVerifyRow (+ their tests). Net −13 files.

Note: "Remove/delete a social" (the other half of the design) needs a new
api endpoint — the api's PATCH profileUrls is per-platform merge with no
delete-social path — tracked as a fast-follow on chat#1867.

Full suite 144 pass, tsc clean on touched files, lint + prettier clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(onboarding): always offer Add-a-profile per artist, not just empty ones

A matched-social list can still be missing platforms (e.g. Spotify found
but no Instagram). Surface 'Add a profile' below every artist's socials,
not only when zero were auto-matched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…chedule (#1871)

Sequence final step for chat#1867 (respec 2026-07-20, pre-run shape):
generate the first weekly catalog report immediately through the normal
chat pipeline (same POST /api/chat transport a send uses), show it
finished, then ask one question — "get this every Monday?". Confirm
creates the enabled weekly task via the existing POST /api/tasks path
(which also mints the schedule) and shows the next-run time; decline
creates nothing.

Mounted standalone at /onboarding/first-task so the step is
user-testable before the OnboardingSequence container exists. The
pre-run prompt and the scheduled task prompt come from one builder, so
the preview the user confirms is byte-for-byte what Monday's run uses.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
… template + Kimi K3 (chat#1867) (#1877)

* feat(onboarding): first-task weekly report actually emails (LA EQUIS template + Kimi K3)

The first-task prompt generated a report but never emailed it (email is a
prompt-driven send_email call, and the prompt had no recipient or send
instruction) — proven by firing the created task: the agent ran and persisted
a report, but email_send_log stayed empty.

Generalize buildFirstTaskPrompt from the proven LA EQUIS weekly report
(scheduled_action 39fb5f68, running week over week): resolve the artist's
Spotify id from its connected profile -> capture this week's play counts ->
compute real week-over-week per-track deltas -> build a fully hex-specced
inline-CSS HTML email -> send via the recoup-platform-email-helper skill ->
confirm the Resend id. Carries the sandbox no-python and anti-fabrication
guardrails verbatim (what makes the send reliable). Thread the account email
(recipientEmail) + artistAccountId through both callers so the pre-run preview
and the Monday scheduled task both send to the account holder.

Bump both surfaces from DEFAULT_MODEL (openai/gpt-5.4-mini — completes the data
calls but gives up before composing the long HTML email, the LA EQUIS lesson)
to a new REPORT_MODEL (moonshotai/kimi-k3), which reliably composes and sends.

chat#1867 (first-task email-prompt gap).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(onboarding): default model -> Kimi K3 (KISS); harden email-less + shell paths

Address review feedback on #1877:

- Sweets (KISS): collapse the new REPORT_MODEL constant into DEFAULT_MODEL —
  set DEFAULT_MODEL = moonshotai/kimi-k3 app-wide (the fast gpt-5.4-mini default
  gave up before composing the long HTML report email). Revert both onboarding
  hooks to DEFAULT_MODEL; relabel the featured picker entry (id: DEFAULT_MODEL)
  from "GPT-5.4 Mini" to "Kimi K3" so it isn't mislabeled.
- CodeRabbit (email-less login): a wallet/phone/social-only Privy account has no
  email — FirstTaskStep now shows a distinct "add an email" alert (not an
  infinite "Preparing…"), and useConfirmFirstTask's onError distinguishes
  EMAIL_REQUIRED from a generic retry.
- Codex (shell-safety): artist/track/album names are user-entered; add a prompt
  guardrail to pass them as single quoted args so a name with quotes/;/$() can't
  alter the email-helper command.

Codex "non-Pro users get rejected" P2 is a false positive: the prior default
(gpt-5.4-mini) is also non-free by isFreeModel yet ships as the default, so the
API does not hard-block non-free default models.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Update lib/consts.ts

* chore(models): refresh featured model list to latest per series

Sweets: while touching the featured list, bring every entry to its series'
latest (verified present in the AI Gateway catalog):
- GPT-5.2 -> GPT-5.5
- Claude Opus 4.5 -> 4.8
- Claude Sonnet 4.5 -> Sonnet 5
- Gemini 2.5 Flash Lite -> Gemini 3.5 Flash Lite
- Gemini 3 Pro -> Gemini 3.1 Pro
- Grok 4 -> Grok 4.5
(Kimi K3 already latest.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(chat): reuse the real Message renderer in the first-task pre-run (DRY)

The onboarding pre-run rendered only the last assistant message's TEXT
(getReportTextFromMessages -> <Response>), dropping tool-call and reasoning
components — a downgraded, diverging copy of the chat UI. #1877's tool-heavy
email workflow made the gap obvious (raw narration, no tool components).

Reuse the normal chat's <Message>/<MessageParts> so tool calls/results get their
real components. MessageParts was coupled to useVercelChatContext (status +
reload); decouple it: both are now optional props with a context fallback, so
the normal chat is behaviorally unchanged (props omitted -> context used) while
the pre-run supplies them without mounting a provider (VercelChatProvider owns
its own useChat instance, so wrapping the pre-run would double the chat).

- VercelChatProvider: export VercelChatContext for the optional read.
- MessageParts/Message: optional status/reload props, fall back to context.
- useFirstTaskReport: expose messages + status.
- FirstTaskReportRun: render assistant messages via <Message> (filtering out the
  auto-sent prompt user message), not a text dump.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e /artists loop (chat#1867) (#1878)

* fix(artists): Add New Artist opens a shared Spotify search (kills the /artists loop)

"Add New Artist" (and the sidebar/header equivalents) called toggleCreation,
which pushed `/?q=create a new artist` and relied on the home CHAT to interpret
it. The onboarding router (chat#1872) now intercepts the home for incomplete
accounts and renders "Finish setting up" instead, so the query never ran — the
"Open your roster" CTA bounced back to /artists → infinite loop.

Replace the redirect with a shared Spotify artist-search dialog:
- lib/spotify/parseSpotifyArtistResults.ts — pure parser for the
  GET /api/spotify/search?type=artist envelope (id/name/imageUrl/profileUrl/followers).
- lib/artists/addSpotifyArtist.ts — create by name (POST /api/artists) then link
  the Spotify image + profile URL (PATCH), so the roster gets real data.
- useSpotifyArtistSearch (debounced, abortable) + useAddSpotifyArtist hooks.
- components/Artists/SpotifyArtistSearch.tsx — the shared typeahead (reused next
  for social enrichment + verify-socials).
- components/Artists/AddArtistDialog.tsx — global dialog, mounted in layout.
- useArtistMode.toggleCreation now opens the dialog (isCreationOpen/closeCreation)
  instead of the redirect — fixes /artists, sidebar, and header at once.

TDD: parseSpotifyArtistResults 5/5, addSpotifyArtist 2/2, red→green. tsc clean on
touched files, eslint/prettier clean.

chat#1867 (/artists add-artist loop).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(artists): reuse canonical Spotify types; drop redundant parser (−106 LOC)

Simplification pass on the add-artist slice:
- Delete lib/spotify/parseSpotifyArtistResults.ts (+ its 5 tests) and the custom
  SpotifyArtistResult type — types/spotify.ts already exports SpotifySearchResponse
  ({ artists?: { items: SpotifyArtistSearchResult[] } }) and SpotifyArtistSearchResult
  (id/name/external_urls/images/followers). useSpotifyArtistSearch now reads
  `data.artists?.items` directly and returns the canonical type; the component and
  addSpotifyArtist read images[0].url / followers.total / external_urls.spotify inline.

Kept (checked, "no simpler"): addSpotifyArtist's two-step create→link, because
POST /api/artists only accepts a name; and useSpotifyArtistSearch, since there is
no existing debounced-search hook to reuse.

Net -106 LOC; behavior unchanged; addSpotifyArtist 2/2 green, tsc 0 new.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cursor

cursor Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@vercel

vercel Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
chat Ready Ready Preview Jul 22, 2026 2:25am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@sweetmantech, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 48 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 085dd442-72bc-42b3-931e-3137ad65c63c

📥 Commits

Reviewing files that changed from the base of the PR and between 8aaa15c and d4023f5.

⛔ Files ignored due to path filters (31)
  • components/Home/__tests__/HomePage.onboarding.test.tsx is excluded by !**/*.test.* and included by components/**
  • hooks/__tests__/useOnboardingSessionFlags.test.tsx is excluded by !**/*.test.* and included by hooks/**
  • hooks/__tests__/useRefreshCatalogsOnLanding.test.tsx is excluded by !**/*.test.* and included by hooks/**
  • lib/ai/__tests__/organizeModels.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/artists/__tests__/addSpotifyArtist.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/artists/__tests__/createRosterArtist.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/catalog/__tests__/buildReleaseRollups.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/buildFirstTaskParams.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/buildFirstTaskPrompt.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/buildSocialFixPayload.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/deriveOnboardingState.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/getFirstTaskConfirmPhase.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/getFirstTaskRunPhase.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/getFirstTaskSchedule.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/getOnboardingCheckpoints.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/getOnboardingFlagKey.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/getOnboardingStep.edge.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/getOnboardingStep.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/getOnboardingStepContent.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/getOnboardingView.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/getReportTextFromMessages.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/getSocialFollowerCount.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/readOnboardingFlag.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/onboarding/__tests__/writeOnboardingFlag.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/valuation/__tests__/buildReportInsights.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/valuation/__tests__/computeCatalogValuation.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/valuation/__tests__/nlsBandFromSpotifyGross.test.ts is excluded by !**/*.test.* and included by lib/**
  • lib/valuation/__tests__/runValuation.test.ts is excluded by !**/*.test.* and included by lib/**
  • package.json is excluded by none and included by none
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml and included by none
  • vitest.config.ts is excluded by none and included by none
📒 Files selected for processing (83)
  • app/catalogs/[catalogId]/page.tsx
  • app/layout.tsx
  • app/onboarding/first-task/page.tsx
  • app/onboarding/roster/page.tsx
  • components/Artists/AddArtistDialog.tsx
  • components/Artists/SpotifyArtistSearch.tsx
  • components/Catalog/CatalogSongsPage.tsx
  • components/Catalog/report/CatalogReleaseRow.tsx
  • components/Catalog/report/CatalogReleasesTable.tsx
  • components/Catalog/report/CatalogReportContent.tsx
  • components/Catalog/report/CatalogReportCta.tsx
  • components/Catalog/report/CatalogReportError.tsx
  • components/Catalog/report/CatalogReportInsights.tsx
  • components/Catalog/report/CatalogReportPage.tsx
  • components/Catalog/report/CatalogReportSkeleton.tsx
  • components/Catalog/report/CatalogReportStats.tsx
  • components/Catalog/report/CatalogValuationCard.tsx
  • components/Catalog/report/ReleaseArtTile.tsx
  • components/Home/HomePage.tsx
  • components/Onboarding/AddArtistForm.tsx
  • components/Onboarding/ArtistSocialsCard.tsx
  • components/Onboarding/ConfirmRosterStep.tsx
  • components/Onboarding/FirstTaskConfirm.tsx
  • components/Onboarding/FirstTaskReportRun.tsx
  • components/Onboarding/FirstTaskStep.tsx
  • components/Onboarding/OnboardingChecklist.tsx
  • components/Onboarding/OnboardingCheckpointList.tsx
  • components/Onboarding/OnboardingSequence.tsx
  • components/Onboarding/OnboardingStepCard.tsx
  • components/Onboarding/RosterArtistRow.tsx
  • components/Onboarding/RosterSocialsFlow.tsx
  • components/Onboarding/RosterVerifiedPanel.tsx
  • components/Onboarding/SocialFixForm.tsx
  • components/Onboarding/SocialRow.tsx
  • components/Onboarding/VerifySocialsStep.tsx
  • components/VercelChat/MessageParts.tsx
  • components/VercelChat/message.tsx
  • hooks/artists/useArtistsRoster.ts
  • hooks/onboarding/useAddRosterArtist.ts
  • hooks/onboarding/useSocialFix.ts
  • hooks/useAddSpotifyArtist.ts
  • hooks/useAlbumArtwork.ts
  • hooks/useArtistMode.tsx
  • hooks/useArtists.tsx
  • hooks/useCatalogReportSongs.ts
  • hooks/useConfirmFirstTask.ts
  • hooks/useFirstTaskReport.ts
  • hooks/useOnboardingGate.ts
  • hooks/useOnboardingSessionFlags.ts
  • hooks/useOnboardingState.ts
  • hooks/useRefreshCatalogsOnLanding.ts
  • hooks/useSpotifyArtistSearch.ts
  • lib/ai/featuredModels.ts
  • lib/artists/addSpotifyArtist.ts
  • lib/artists/createRosterArtist.ts
  • lib/catalog/buildReleaseRollups.ts
  • lib/catalog/getCatalogMeasurements.ts
  • lib/consts.ts
  • lib/onboarding/buildFirstTaskParams.ts
  • lib/onboarding/buildFirstTaskPrompt.ts
  • lib/onboarding/buildSocialFixPayload.ts
  • lib/onboarding/deriveOnboardingState.ts
  • lib/onboarding/getFirstTaskConfirmPhase.ts
  • lib/onboarding/getFirstTaskRunPhase.ts
  • lib/onboarding/getFirstTaskSchedule.ts
  • lib/onboarding/getOnboardingCheckpoints.ts
  • lib/onboarding/getOnboardingFlagKey.ts
  • lib/onboarding/getOnboardingStep.ts
  • lib/onboarding/getOnboardingStepContent.ts
  • lib/onboarding/getOnboardingView.ts
  • lib/onboarding/getReportTextFromMessages.ts
  • lib/onboarding/getSocialFollowerCount.ts
  • lib/onboarding/normalizeSocialPlatform.ts
  • lib/onboarding/readOnboardingFlag.ts
  • lib/onboarding/types.ts
  • lib/onboarding/writeOnboardingFlag.ts
  • lib/spotify/getAlbumArtwork.ts
  • lib/valuation/buildReportInsights.ts
  • lib/valuation/computeCatalogValuation.ts
  • lib/valuation/formatCompact.ts
  • lib/valuation/nlsBandFromSpotifyGross.ts
  • lib/valuation/runValuation.ts
  • providers/VercelChatProvider.tsx
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

… artist add (chat#1867) (#1879)

* feat(onboarding): seed the catalog by kicking /api/valuation on first artist add

Closes the onboarding catalog dead-end for direct signups. When the first artist
is added via the Spotify search (#1878 already links their Spotify profile),
useAddSpotifyArtist now fire-and-forget kicks POST /api/valuation
{ spotify_artist_id } (api#776) — only when the account has no catalog yet —
which materializes the catalog + value band in ~20s. So the "Claim your catalog"
step is already complete by the time the user reaches it, and they flow through
to the first-task step (weekly report emails).

- lib/valuation/runValuation.ts — client POST /api/valuation (TDD 2/2).
- hooks/useAddSpotifyArtist.ts — background kick on first add (gated on an empty,
  loaded catalogs query), surfaced via a toast.promise ("Valuing … → Your catalog
  is ready"), invalidating the catalogs query on success so the sequence advances.

chat#1867 (seed onboarding catalog on first artist add).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test(models): fix organizeModels fixture — featured id gpt-5.2 → gpt-5.5 (post-#1877)

The featured-models refresh in #1877 replaced openai/gpt-5.2 with openai/gpt-5.5,
but organizeModels.test.ts still asserted gpt-5.2 was featured — failing CI on
test. Update the fixture + assertion to a currently-featured id.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sweetmantech
sweetmantech merged commit d258412 into main Jul 22, 2026
3 of 4 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd463f85c5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread lib/ai/featuredModels.ts
{
id: "openai/gpt-5.2",
displayName: "GPT-5.2",
id: "openai/gpt-5.5",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Update the featured-model test fixture

With this featured ID renamed, the existing lib/ai/__tests__/organizeModels.test.ts fixture still uses openai/gpt-5.2 and asserts that it appears in featuredModels. organizeModels will now treat that fixture as an ordinary model, so the repo's Vitest suite fails until the fixture/assertion is updated alongside the model rename.

Useful? React with 👍 / 👎.

() =>
deriveOnboardingState({
authenticated,
artists,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Filter workspaces before deriving artist onboarding

When the roster contains workspace entries (ArtistRecord.isWorkspace) but no real artists, this passes those workspaces into onboarding state. getOnboardingCheckpoints then counts state.artists.length > 0, while the roster/socials UI filters workspaces out, so workspace-only users skip the real artist checkpoint and land on socials/tasks for a non-artist. Filter out isWorkspace records before deriving the onboarding checkpoints.

Useful? React with 👍 / 👎.

): UseQueryResult<CatalogSongsResponse> => {
return useQuery({
queryKey: ["catalogReportSongs", catalogId],
queryFn: () => getCatalogSongs(catalogId, REPORT_SONGS_PAGE_SIZE, 1),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fetch complete catalog data before whole-catalog rollups

For catalogs with more than 100 songs, this hook only fetches page 1, but CatalogReportContent presents the release table and concentration insight as if they describe the whole catalog. The report can therefore omit releases/tracks after the first page and divide partial release streams by whole-catalog totalStreams, producing misleading rollups; paginate/fetch aggregates server-side or label the table as a top-100 sample.

Useful? React with 👍 / 👎.

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.

1 participant