Skip to content

feat: homepage tasks module — recent runs + one-click starter task (Catalog HQ 2/3, chat#1850)#1853

Open
sweetmantech wants to merge 1 commit into
feat/home-valuation-herofrom
feat/home-tasks-module
Open

feat: homepage tasks module — recent runs + one-click starter task (Catalog HQ 2/3, chat#1850)#1853
sweetmantech wants to merge 1 commit into
feat/home-valuation-herofrom
feat/home-tasks-module

Conversation

@sweetmantech

@sweetmantech sweetmantech commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

What this does

Second PR of the Catalog HQ homepage stack (#1850). Adds the "Your label at work" tasks module under the valuation hero:

  • Accounts with task history see their most recent runs (capped at 5) from the existing GET /api/tasks/runs — run name, status pill, finished-at — each row linking to the existing /tasks/{runId} detail page.
  • Fresh accounts (zero runs, artist selected) see one pre-wired suggestion card: "Weekly valuation + streams report for {artist}, Mondays". One click creates the scheduled task via the existing POST /api/tasks path (which also mints the Trigger schedule), then the module shows it as scheduled.
  • While loading or on any fetch failure the module renders nothing — home never blocks on it.

Honest scope note on sent emails: the issue asks for each run's sent email (subject + sent-at). No existing chat-consumable endpoint exposes per-run email subjects today — GET /api/tasks/runs returns taskIdentifier/status/timestamps/metadata only, and the email send log isn't surfaced through any api.recoupable.dev endpoint the chat app uses. Per the module's ONLY-existing-endpoints constraint, this PR shows what IS available (run name, status, finished-at). Surfacing email subjects needs an api-side addition (runs response or an email-log endpoint) — left open on #1850.

Uses only existing hooks/patterns: useTaskRuns (existing), new useCreateStarterTask mirroring useCreateTask (auth + artist from providers), pure getHomeTasksModuleState selector for the module's render decision.

Tests (TDD — confirmed RED before implementing)

12 new unit tests, full suite 109 passed (31 files):

  • lib/home/__tests__/getHomeTasksModuleState.test.ts — runs shown for accounts with history, capped at 5; starter card for fresh account with artist; hidden while loading / on failure / without artist (the Done-when).
  • lib/home/__tests__/createStarterTask.test.ts — the one-click creation call fires POST /api/tasks with the exact payload (title, 0 9 * * 1 Monday schedule, artist_account_id, model); error propagation.
  • lib/home/__tests__/buildStarterTaskParams.test.ts — starter task title/schedule/prompt contents.

pnpm exec tsc --noEmit: no new errors (same two pre-existing failures as on main). eslint + prettier clean on changed files.

Screenshots

N/A (no preview screenshot in this PR; run/starter states verified via unit tests — see PR comment for preview verification).

Stack

Part of a 3-PR stack for chat#1850 (merge in order, each PR only after its base):

  1. feat: homepage valuation hero (Catalog HQ 1/3, chat#1850) #1852 feat/home-valuation-hero → base main
  2. this PR feat/home-tasks-module → base feat/home-valuation-hero
  3. feat/home-command-bar → base feat/home-tasks-module

When #1852 merges, this PR gets re-targeted to main.

Tracked in #1850.

🤖 Generated with Claude Code


Summary by cubic

Adds the "Your label at work" tasks module under the valuation hero to show recent task runs or let new users schedule a weekly valuation + streams report in one click. Uses existing GET /api/tasks/runs and POST /api/tasks, matches chat#1850, and never blocks the page.

  • New Features
    • Shows recent runs (max 5) with name, status, and finished-at; each links to /tasks/{runId} and a header link goes to /tasks.
    • For fresh accounts with an artist, displays a starter card that schedules a Monday 9am report in one click and reflects the scheduled state.
    • Hides the module while loading, on fetch error, or when no artist is selected.
    • Email subjects for past runs are not displayed because current APIs don’t expose them (tracked in chat#1850).

Written for commit 2874fed. Summary will update on new commits.

Review in cubic

@cursor

cursor Bot commented Jul 6, 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 6, 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 6, 2026 10:15pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • main
  • test

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5726f6e7-cea8-4bec-83f6-7b51266a0824

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/home-tasks-module

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.

@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: 5eb9fc8dae

ℹ️ 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".

if (runs.length > 0)
return { view: "runs", runs: runs.slice(0, MAX_HOME_RUNS) };

return hasArtist ? { view: "starter" } : { view: "hidden" };

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 Prevent duplicate starter schedules after reload

When a user creates the starter task, the persisted result is a scheduled action, but this selector only looks at run history. Until the first scheduled run happens, useTaskRuns still returns []; after a page reload the mutation's local isScheduled state is gone, so the homepage offers "Schedule it" again and another click creates a duplicate Monday task. Include existing scheduled actions in this decision, or otherwise persist/hide the starter once the task exists.

Useful? React with 👍 / 👎.

Comment on lines +28 to +30
if (!artistAccountId || !artistName) {
throw new Error("ARTIST_REQUIRED");
}

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 Handle selected artists with missing names

For a selected artist/workspace whose name is null or empty, the module still renders because it only checks account_id, and the card displays the fallback "your artist"; however this mutation throws ARTIST_REQUIRED, so clicking the visible CTA fails with "Please select an artist first" even though an artist is selected. Use the same fallback for task creation or require a usable name before showing the starter card.

Useful? React with 👍 / 👎.

@cubic-dev-ai cubic-dev-ai 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.

3 issues found across 11 files

Confidence score: 3/5

  • In hooks/useCreateStarterTask.ts, isScheduled is derived from mutation success and isn’t reset when selectedArtist changes, so the starter card can show the wrong status for the newly selected artist; that can mislead users into thinking a task is already scheduled when it isn’t — reset mutation state on artist change (or derive scheduled state from artist-scoped data) before merging.
  • In lib/home/getHomeTasksModuleState.ts, relying on mutation isSuccess means a reload can temporarily drop isScheduled while useTaskRuns is still empty, so the starter card reappears and users can re-trigger scheduling; this risks duplicate/confusing scheduling flows — persist/derive scheduled state from server-backed task/run data across reloads before merging.
  • In components/Home/StarterTaskCard.tsx, the “Schedule it” button is clickable in states where useCreateStarterTask will always fail (e.g., missing selectedArtist), creating avoidable error-toast loops and a frustrating UX — gate/disable the button on required preconditions, not just pending state.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="components/Home/StarterTaskCard.tsx">

<violation number="1" location="components/Home/StarterTaskCard.tsx:39">
P2: Users can click "Schedule it" in a state where creation is guaranteed to fail, causing an avoidable error toast loop. The button is only disabled during pending state, but `useCreateStarterTask` requires a non-null `selectedArtist.name`, so disabling when required artist fields are missing would prevent this broken path.</violation>
</file>

<file name="hooks/useCreateStarterTask.ts">

<violation number="1" location="hooks/useCreateStarterTask.ts:23">
P2: The starter card can show a false "scheduled" state after artist switching, because `isScheduled` is tied to mutation success and never reset. Consider resetting mutation state when `selectedArtist` changes (or deriving scheduled status from fetched tasks) so the UI reflects the current artist.</violation>
</file>

<file name="lib/home/getHomeTasksModuleState.ts">

<violation number="1" location="lib/home/getHomeTasksModuleState.ts:34">
P2: After a page reload, the mutation's `isSuccess` (used as `isScheduled`) resets and `useTaskRuns` still returns `[]` until the first scheduled run actually executes. This means the starter card reappears and the user can create duplicate Monday tasks on each visit.

Consider incorporating existing scheduled actions (e.g., from a `useScheduledActions` query or persisted flag) into this decision, so that once the weekly task exists the module no longer offers to create it again.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

<button
type="button"
onClick={() => handleCreateStarterTask()}
disabled={isCreating}

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: Users can click "Schedule it" in a state where creation is guaranteed to fail, causing an avoidable error toast loop. The button is only disabled during pending state, but useCreateStarterTask requires a non-null selectedArtist.name, so disabling when required artist fields are missing would prevent this broken path.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At components/Home/StarterTaskCard.tsx, line 39:

<comment>Users can click "Schedule it" in a state where creation is guaranteed to fail, causing an avoidable error toast loop. The button is only disabled during pending state, but `useCreateStarterTask` requires a non-null `selectedArtist.name`, so disabling when required artist fields are missing would prevent this broken path.</comment>

<file context>
@@ -0,0 +1,48 @@
+      <button
+        type="button"
+        onClick={() => handleCreateStarterTask()}
+        disabled={isCreating}
+        className="shrink-0 rounded-xl bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground transition-colors hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50"
+      >
</file context>

const {
mutate: handleCreateStarterTask,
isPending: isCreating,
isSuccess: isScheduled,

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: The starter card can show a false "scheduled" state after artist switching, because isScheduled is tied to mutation success and never reset. Consider resetting mutation state when selectedArtist changes (or deriving scheduled status from fetched tasks) so the UI reflects the current artist.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At hooks/useCreateStarterTask.ts, line 23:

<comment>The starter card can show a false "scheduled" state after artist switching, because `isScheduled` is tied to mutation success and never reset. Consider resetting mutation state when `selectedArtist` changes (or deriving scheduled status from fetched tasks) so the UI reflects the current artist.</comment>

<file context>
@@ -0,0 +1,58 @@
+  const {
+    mutate: handleCreateStarterTask,
+    isPending: isCreating,
+    isSuccess: isScheduled,
+  } = useMutation({
+    mutationFn: async () => {
</file context>

if (runs.length > 0)
return { view: "runs", runs: runs.slice(0, MAX_HOME_RUNS) };

return hasArtist ? { view: "starter" } : { view: "hidden" };

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: After a page reload, the mutation's isSuccess (used as isScheduled) resets and useTaskRuns still returns [] until the first scheduled run actually executes. This means the starter card reappears and the user can create duplicate Monday tasks on each visit.

Consider incorporating existing scheduled actions (e.g., from a useScheduledActions query or persisted flag) into this decision, so that once the weekly task exists the module no longer offers to create it again.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/home/getHomeTasksModuleState.ts, line 34:

<comment>After a page reload, the mutation's `isSuccess` (used as `isScheduled`) resets and `useTaskRuns` still returns `[]` until the first scheduled run actually executes. This means the starter card reappears and the user can create duplicate Monday tasks on each visit.

Consider incorporating existing scheduled actions (e.g., from a `useScheduledActions` query or persisted flag) into this decision, so that once the weekly task exists the module no longer offers to create it again.</comment>

<file context>
@@ -0,0 +1,35 @@
+  if (runs.length > 0)
+    return { view: "runs", runs: runs.slice(0, MAX_HOME_RUNS) };
+
+  return hasArtist ? { view: "starter" } : { view: "hidden" };
+}
</file context>

@sweetmantech

Copy link
Copy Markdown
Collaborator Author

Preview verification (sha 5eb9fc8, https://chat-git-feat-home-tasks-module-recoup.vercel.app/):

  • Vercel preview build: SUCCESS.
  • Loaded the preview homepage signed out: unchanged current experience (greeting + input + login modal), no tasks module (runs query is auth-gated), zero console errors — the module correctly renders nothing rather than blocking home.
  • Not verified on preview: the authenticated states (runs list for an account with history; starter card + one-click creation for a fresh account). I could not complete a Privy OTP login from this run (no access to the OTP inbox). Those behaviors are covered by unit tests (getHomeTasksModuleState, createStarterTask payload) and need a manual authenticated pass — recommend the clone-to-own-account [TEST] pattern before merge, since one click here creates a real schedule via POST /api/tasks.

@cursor

cursor Bot commented Jul 6, 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.

… (chat#1850)

'Your label at work' module under the valuation hero: recent task runs
from the existing GET /api/tasks/runs (run name, status, finished-at),
capped at five, linking to the run detail pages. Fresh accounts get one
pre-wired suggestion (weekly valuation + streams report, Mondays 9am)
that creates the scheduled task in one click through the existing
POST /api/tasks path.

Module state is a pure, fully-tested selector; the module renders
nothing while loading or on failure so home never blocks on it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sweetmantech sweetmantech force-pushed the feat/home-tasks-module branch from c2d0e25 to 2874fed Compare July 6, 2026 22:13
@cursor

cursor Bot commented Jul 6, 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.

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