feat: implement createTask function and associated tests#1655
feat: implement createTask function and associated tests#1655pradipthaadhi wants to merge 18 commits intotestfrom
Conversation
- Added createTask function to handle task creation via the Recoup API, including error handling for various response scenarios. - Created unit tests for createTask to verify correct API interaction, including optional parameters and error cases.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a client-side "Create Task" flow: UI, form hook, schedule/model fields, cron validation, sessionStorage migration/cleanup, a createTask API client, API-base override via NEXT_PUBLIC_API_BASE_URL, and related constants and types. Changes
Sequence Diagram(s)sequenceDiagram
participant Browser as "Browser (CreateTaskPage)"
participant Hook as "useCreateTaskForm"
participant ClientUtil as "createTask (lib/tasks/createTask.ts)"
participant API as "Server API /api/tasks"
participant DB as "Database"
Browser->>Hook: user fills form, submits
Hook->>Hook: validate fields & cron
Hook->>Hook: get access token (usePrivy)
Hook->>ClientUtil: createTask(accessToken, params)
ClientUtil->>API: POST /api/tasks (Authorization, JSON body)
API->>DB: persist scheduled task
DB-->>API: return created task
API-->>ClientUtil: 200 OK with tasks array
ClientUtil-->>Hook: return created Task
Hook-->>Browser: toast success, navigate /tasks, router.refresh()
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ❌ 1❌ Failed checks (1 warning)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
lib/tasks/createTask.ts (1)
20-23: Consider validatingaccessTokento fail fast.The function accepts any string for
accessToken, including empty strings. While the API will reject invalid tokens, failing fast with a descriptive error improves debugging experience.🛡️ Optional: Add input validation
export async function createTask( accessToken: string, params: CreateTaskParams, ): Promise<ScheduledAction> { + if (!accessToken) { + throw new Error("accessToken is required"); + } + const response = await fetch(`${getClientApiBaseUrl()}/api/tasks`, {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/tasks/createTask.ts` around lines 20 - 23, The createTask function currently accepts any string for accessToken which can be empty; add a fast-fail input validation at the top of createTask to check that accessToken is a non-empty string (and optionally well-formed if you have a pattern), and throw a clear, descriptive error (e.g., Error('createTask: accessToken is required')) before proceeding to use CreateTaskParams or returning a ScheduledAction; update callers/tests if necessary to handle the thrown error.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@lib/tasks/createTask.ts`:
- Around line 35-36: The spread construction in createTask.ts is inconsistent:
it uses a truthy check for params.account_id but an explicit !== undefined check
for params.model, which treats empty string and null differently; update both
spreads to use the same explicit presence check (e.g., params.account_id !==
undefined and params.model !== undefined) or, if you intend to exclude empty
strings for account_id, add a clarifying comment above the account_id spread
explaining that empty strings must be excluded—refer to the params object fields
account_id and model and make the checks consistent across the two spreads.
---
Nitpick comments:
In `@lib/tasks/createTask.ts`:
- Around line 20-23: The createTask function currently accepts any string for
accessToken which can be empty; add a fast-fail input validation at the top of
createTask to check that accessToken is a non-empty string (and optionally
well-formed if you have a pattern), and throw a clear, descriptive error (e.g.,
Error('createTask: accessToken is required')) before proceeding to use
CreateTaskParams or returning a ScheduledAction; update callers/tests if
necessary to handle the thrown error.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 02121c33-755b-4889-bc74-6bc63c9cae1e
⛔ Files ignored due to path filters (1)
lib/tasks/__tests__/createTask.test.tsis excluded by!**/*.test.*and included bylib/**
📒 Files selected for processing (1)
lib/tasks/createTask.ts
There was a problem hiding this comment.
3 issues found across 2 files
Confidence score: 4/5
- This PR looks safe to merge overall; the main issues are minor consistency concerns rather than clear runtime breakage.
- Most notable:
lib/tasks/createTask.tsreturnsScheduledActionbut parsesTask-typed data, which could confuse consumers or type checks. - Inconsistent optional param handling in
lib/tasks/createTask.ts(account_idtruthy check vsmodel !== undefined) may lead to subtle input differences but is not likely to be merge-blocking. - Pay close attention to
lib/tasks/createTask.ts- return type consistency and optional parameter checks.
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="lib/tasks/__tests__/createTask.test.ts">
<violation number="1" location="lib/tasks/__tests__/createTask.test.ts:1">
P1: Custom agent: **Code Structure and Size Limits for Readability and Single Responsibility**
This test file is 136 lines, exceeding the 100-line limit. Split the error-case tests (HTTP error, API error status, empty tasks) into a separate file like `createTask.errors.test.ts` to keep each file under 100 lines.</violation>
</file>
<file name="lib/tasks/createTask.ts">
<violation number="1" location="lib/tasks/createTask.ts:23">
P2: Return type should be `Task` instead of `ScheduledAction` to match the parsed response type (`GetTasksResponse.tasks` is `Task[]`) and stay consistent with `getTasks`, which returns `Task[]`. The current `ScheduledAction` return type discards the optional `recent_runs` and `upcoming` fields, which callers can't access without casting.</violation>
<violation number="2" location="lib/tasks/createTask.ts:35">
P3: Inconsistent conditional patterns for optional parameters: `account_id` uses a truthiness check (excluding `undefined` and `""`) while `model` uses `!== undefined` (allowing `null` and `""`). If both should follow the same exclusion logic, align them. If the difference is intentional (e.g., `model` deliberately allows `null` to clear the field), add a brief comment to make that intent explicit.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
| @@ -0,0 +1,136 @@ | |||
| import { beforeEach, describe, expect, it, vi } from "vitest"; | |||
There was a problem hiding this comment.
P1: Custom agent: Code Structure and Size Limits for Readability and Single Responsibility
This test file is 136 lines, exceeding the 100-line limit. Split the error-case tests (HTTP error, API error status, empty tasks) into a separate file like createTask.errors.test.ts to keep each file under 100 lines.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/tasks/__tests__/createTask.test.ts, line 1:
<comment>This test file is 136 lines, exceeding the 100-line limit. Split the error-case tests (HTTP error, API error status, empty tasks) into a separate file like `createTask.errors.test.ts` to keep each file under 100 lines.</comment>
<file context>
@@ -0,0 +1,136 @@
+import { beforeEach, describe, expect, it, vi } from "vitest";
+import { createTask } from "@/lib/tasks/createTask";
+import { getClientApiBaseUrl } from "@/lib/api/getClientApiBaseUrl";
</file context>
There was a problem hiding this comment.
YAGNI principle - Where is this lib being used?
…umentation - Removed the optional account_id parameter from the CreateTaskParams interface. - Updated the createTask function documentation to clarify that the task owner account is resolved from the bearer token, eliminating the need to send account_id in the request body. - Adjusted related tests to reflect the removal of account_id.
- Added optional account_id parameter to CreateTaskParams interface, allowing for more flexible task creation. - Updated createTask function to include account_id in the request body when provided. - Modified API base URL logic to support an environment variable override for better configuration in different environments. - Adjusted related tests to verify the inclusion of account_id and updated API base URL behavior.
…upwork/myc-4586-chat-align-task-creation-client-with-hardened-post-apitasks
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
lib/consts.ts (1)
4-9: Minor: simplify with nullish coalescing and guard against empty-string env values.A blank
NEXT_PUBLIC_API_BASE_URL=""would currently be treated as "not set" by the truthy check (fine), but the nested ternary is harder to read than necessary. Consider:♻️ Suggested tidy-up
-const apiBaseUrlOverride = process.env.NEXT_PUBLIC_API_BASE_URL; -export const NEW_API_BASE_URL = apiBaseUrlOverride - ? apiBaseUrlOverride - : IS_PROD - ? "https://recoup-api.vercel.app" - : "https://test-recoup-api.vercel.app"; +const DEFAULT_API_BASE_URL = IS_PROD + ? "https://recoup-api.vercel.app" + : "https://test-recoup-api.vercel.app"; +export const NEW_API_BASE_URL = + process.env.NEXT_PUBLIC_API_BASE_URL?.trim() || DEFAULT_API_BASE_URL;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/consts.ts` around lines 4 - 9, Replace the nested ternary that computes NEW_API_BASE_URL with a clearer nullish-coalescing approach that also guards against empty strings: use the environment variable apiBaseUrlOverride (NEXT_PUBLIC_API_BASE_URL) after trimming and check for a non-empty value, otherwise fall back to the IS_PROD conditional defaults; update references to apiBaseUrlOverride and NEW_API_BASE_URL accordingly so the env value "" is treated as unset and the ternary nesting is removed for readability.lib/tasks/createTask.ts (2)
55-55: Defensive: verifydata.tasks[0]actually matchesTables<"scheduled_actions">.The function signature promises
ScheduledAction, but the runtime value is whatever the API returns — no validation is performed. For a client helper that feeds downstream type-safe code, consider a lightweight schema check (e.g. Zod) or at minimum assert the presence of required fields (id,artist_account_id, etc.) before returning. Otherwise a subtly-shaped API response becomes a hard-to-diagnoseundefinedread far from the call site.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/tasks/createTask.ts` at line 55, The return of data.tasks[0] in createTask (which is claimed to be a ScheduledAction) is not validated; add a lightweight runtime check before returning to ensure the object matches ScheduledAction (at minimum verify required fields like id and artist_account_id exist and have expected types). Implement this by either using a small Zod schema for ScheduledAction and parsing data.tasks[0] (e.g., scheduledActionSchema.parse) or by adding explicit assertions that required keys are present and of correct primitive types, and throw a clear error if validation fails so callers never receive an invalid value.
21-56: Request-cancellation & timeout are missing.
fetchhere has noAbortSignaland no timeout. In a UI flow a user may navigate away mid-request, leaving the promise to settle against an unmounted component; and a hung Recoup API call will block indefinitely. Accepting an optionalsignal?: AbortSignal(commonly threaded through from React Query / SWR / TanStack mutations) is a cheap resilience win:♻️ Thread an AbortSignal through
export async function createTask( accessToken: string, params: CreateTaskParams, + options?: { signal?: AbortSignal }, ): Promise<ScheduledAction> { const response = await fetch(`${getClientApiBaseUrl()}/api/tasks`, { method: "POST", + signal: options?.signal, headers: {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/tasks/createTask.ts` around lines 21 - 56, The createTask function should accept an optional signal?: AbortSignal parameter and use it to enable request cancellation and a timeout; update the createTask signature to include signal?: AbortSignal, pass that signal into the fetch options, and implement a short configurable timeout by creating an AbortController inside createTask (tie its signal to the passed signal so an external cancel also aborts) and use it to abort the fetch after the timeout period; ensure you clean up any timers and prefer the passed-in signal when present so React Query/SWR can cancel the request.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@lib/consts.ts`:
- Around line 4-9: Restore and export the two missing constants
API_OVERRIDE_STORAGE_KEY and ACCOUNT_OVERRIDE_STORAGE_KEY from lib/consts.ts so
existing consumers compile; add definitions (e.g. const API_OVERRIDE_STORAGE_KEY
= 'apiOverride' and const ACCOUNT_OVERRIDE_STORAGE_KEY = 'accountOverride') and
export them alongside NEW_API_BASE_URL, ensuring the identifiers referenced by
getClientApiBaseUrl, ApiOverrideSync, getStoredAccountOverride,
setStoredAccountOverride, and clearStoredAccountOverride match exactly.
In `@lib/tasks/createTask.ts`:
- Around line 46-55: The code in createTask.ts currently types the POST response
as GetTasksResponse (from getTasks.ts) which is for the list endpoint; change
this to an endpoint-specific response type (e.g., CreateTaskResponse with shape
{ status: string; task: Task; error?: string }) or introduce a generic envelope
type (e.g., TaskEnvelope<T>) exported from getTasks.ts and use
TaskEnvelope<Task> here; update createTask.ts (and similarly updateTask.ts) to
import and use the new CreateTaskResponse/TaskEnvelope type, adjust the runtime
checks to read data.task instead of data.tasks, and throw errors from data.error
when present.
---
Nitpick comments:
In `@lib/consts.ts`:
- Around line 4-9: Replace the nested ternary that computes NEW_API_BASE_URL
with a clearer nullish-coalescing approach that also guards against empty
strings: use the environment variable apiBaseUrlOverride
(NEXT_PUBLIC_API_BASE_URL) after trimming and check for a non-empty value,
otherwise fall back to the IS_PROD conditional defaults; update references to
apiBaseUrlOverride and NEW_API_BASE_URL accordingly so the env value "" is
treated as unset and the ternary nesting is removed for readability.
In `@lib/tasks/createTask.ts`:
- Line 55: The return of data.tasks[0] in createTask (which is claimed to be a
ScheduledAction) is not validated; add a lightweight runtime check before
returning to ensure the object matches ScheduledAction (at minimum verify
required fields like id and artist_account_id exist and have expected types).
Implement this by either using a small Zod schema for ScheduledAction and
parsing data.tasks[0] (e.g., scheduledActionSchema.parse) or by adding explicit
assertions that required keys are present and of correct primitive types, and
throw a clear error if validation fails so callers never receive an invalid
value.
- Around line 21-56: The createTask function should accept an optional signal?:
AbortSignal parameter and use it to enable request cancellation and a timeout;
update the createTask signature to include signal?: AbortSignal, pass that
signal into the fetch options, and implement a short configurable timeout by
creating an AbortController inside createTask (tie its signal to the passed
signal so an external cancel also aborts) and use it to abort the fetch after
the timeout period; ensure you clean up any timers and prefer the passed-in
signal when present so React Query/SWR can cancel the request.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: dd954806-7643-4cee-96b3-380ef38f0e77
⛔ Files ignored due to path filters (1)
lib/tasks/__tests__/createTask.test.tsis excluded by!**/*.test.*and included bylib/**
📒 Files selected for processing (2)
lib/consts.tslib/tasks/createTask.ts
| const data: GetTasksResponse = await response.json(); | ||
| if (data.status === "error") { | ||
| throw new Error(data.error || "Unknown error occurred"); | ||
| } | ||
|
|
||
| if (!data.tasks || data.tasks.length === 0) { | ||
| throw new Error("API returned success but no task was created"); | ||
| } | ||
|
|
||
| return data.tasks[0]; |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Confirm the shape of GetTasksResponse and whether any dedicated create-response type exists.
fd -e ts getTasks.ts lib/tasks
rg -nP 'GetTasksResponse|CreateTaskResponse' --type=ts -C2Repository: recoupable/chat
Length of output: 1732
Replace GetTasksResponse with an endpoint-specific type to avoid conflating contracts.
GetTasksResponse is designed for the GET /api/tasks endpoint (returns { tasks: Task[] }), but it's being reused as the response type for POST and PATCH operations in createTask.ts and updateTask.ts. This couples distinct API contracts together. The create/update endpoints likely have different response shapes—returning a single task object is common REST convention—and using the list endpoint's type masks that difference.
Create a dedicated CreateTaskResponse type (e.g., { status, task: Task, error? }) or share a generic envelope (e.g., TaskEnvelope<T>) exported from getTasks.ts. Each endpoint should have its own contract type; the single-responsibility principle applies to types as much as functions.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@lib/tasks/createTask.ts` around lines 46 - 55, The code in createTask.ts
currently types the POST response as GetTasksResponse (from getTasks.ts) which
is for the list endpoint; change this to an endpoint-specific response type
(e.g., CreateTaskResponse with shape { status: string; task: Task; error?:
string }) or introduce a generic envelope type (e.g., TaskEnvelope<T>) exported
from getTasks.ts and use TaskEnvelope<Task> here; update createTask.ts (and
similarly updateTask.ts) to import and use the new
CreateTaskResponse/TaskEnvelope type, adjust the runtime checks to read
data.task instead of data.tasks, and throw errors from data.error when present.
- Introduced a new CreateTaskPage component for task creation, featuring a form with validation for title, prompt, schedule, and artist selection. - Updated TasksPage to include a "Create Task" button, enhancing navigation for users to create new tasks. - Implemented state management and error handling for form submissions, ensuring a smooth user experience.
There was a problem hiding this comment.
2 issues found across 3 files (changes from recent commits).
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/TasksPage/CreateTaskPage.tsx">
<violation number="1" location="components/TasksPage/CreateTaskPage.tsx:28">
P1: Custom agent: **Code Structure and Size Limits for Readability and Single Responsibility**
At 228 lines this file is more than double the 100-line limit. Extract a `useCreateTaskForm` hook (state, validation, submit handler) into a separate file and keep this component focused on rendering. The `.coderabbit.yaml` path rule for `components/**/*.tsx` also calls for <200 lines and extracting custom hooks.</violation>
<violation number="2" location="components/TasksPage/CreateTaskPage.tsx:216">
P2: `disabled` prop has no effect on `<Button asChild>` wrapping a `<Link>`. The `<a>` element doesn't support `disabled`, and the `:disabled` CSS pseudo-class won't match it. During submission, the cancel link remains fully clickable and unstyled.
Consider conditionally rendering a plain `<Button>` (not `asChild`) when disabled, or using `aria-disabled` with `onClick={e => e.preventDefault()}` to block navigation.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
…e new dependencies - Added @react-native-async-storage/async-storage version 3.0.2. - Added @valibot/to-json-schema version 1.6.0. - Added effect version 3.21.0. - Updated dependency versions in pnpm-lock.yaml to reflect the new additions and ensure compatibility.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
components/TasksPage/CreateTaskPage.tsx (1)
60-106: Consider extracting validation for single-responsibility.
handleSubmitcurrently juggles validation, token retrieval, request dispatch, navigation, and error surfacing. Pulling the field-validation block into a smallvalidate(...)helper (returningFormErrors) would tighten the handler's responsibility and make the rules independently testable. Not blocking — happy to leave as-is if you'd rather keep it inline.As per coding guidelines: "Each function should have a single responsibility and clear naming".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/TasksPage/CreateTaskPage.tsx` around lines 60 - 106, Extract the inline field-validation in handleSubmit into a new helper function named validate that accepts the form fields (title, prompt, schedule, artistAccountId, model, accountIdOverride as needed) and returns a FormErrors object; then have handleSubmit call validate, setErrors(nextErrors) and setSubmitError(null) based on the returned errors and early-return if any keys exist — leaving token retrieval, createTask call, navigation and error handling in handleSubmit unchanged. Ensure validate is exported/typed as returning FormErrors so it can be unit-tested independently and update references in handleSubmit (still using setIsSubmitting, getAccessToken, createTask, toast, router) to use the helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@components/TasksPage/CreateTaskPage.tsx`:
- Around line 131-200: Add accessible error wiring: for each field
(Input/Textarea/Select) — task-title, task-prompt, task-schedule, task-artist —
set aria-invalid={!!errors.<field>} and set aria-describedby to a stable id when
an error exists (e.g. title-error, prompt-error, schedule-error, artist-error).
Render the corresponding error <p> with the matching id and ensure
aria-describedby is omitted or null when no error is present so screen readers
only reference existing messages; apply the same pattern to the SelectTrigger
used for task-artist.
- Around line 216-218: The Cancel control currently uses <Button asChild>
wrapping the Next.js <Link> (Link href="proxy.php?url=https%3A%2F%2Fgithub.com%2Ftasks") so the disabled prop
(isSubmitting) is ineffective; change it so when isSubmitting is true you render
a real <button disabled> (e.g., a Button without asChild) to prevent
interaction, and when not submitting render the <Button asChild> with <Link
href="proxy.php?url=https%3A%2F%2Fgithub.com%2Ftasks"> as before, or alternatively replace the Link variant with a
regular Button that calls router.push('/tasks') on click and respects disabled;
update the component where Button asChild and isSubmitting are used (the Cancel
button rendering) to implement one of these two approaches.
---
Nitpick comments:
In `@components/TasksPage/CreateTaskPage.tsx`:
- Around line 60-106: Extract the inline field-validation in handleSubmit into a
new helper function named validate that accepts the form fields (title, prompt,
schedule, artistAccountId, model, accountIdOverride as needed) and returns a
FormErrors object; then have handleSubmit call validate, setErrors(nextErrors)
and setSubmitError(null) based on the returned errors and early-return if any
keys exist — leaving token retrieval, createTask call, navigation and error
handling in handleSubmit unchanged. Ensure validate is exported/typed as
returning FormErrors so it can be unit-tested independently and update
references in handleSubmit (still using setIsSubmitting, getAccessToken,
createTask, toast, router) to use the helper.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: fe7f6485-058f-4f92-ae7b-11da9189aa9f
⛔ Files ignored due to path filters (2)
package.jsonis excluded by none and included by nonepnpm-lock.yamlis excluded by!**/pnpm-lock.yamland included by none
📒 Files selected for processing (3)
app/tasks/new/page.tsxcomponents/TasksPage/CreateTaskPage.tsxcomponents/TasksPage/TasksPage.tsx
- Introduced API_OVERRIDE_STORAGE_KEY and ACCOUNT_OVERRIDE_STORAGE_KEY constants for improved API management. - Updated DEFAULT_MODEL to "openai/gpt-5-mini" for better performance. - Added a comprehensive PROMPT_SUGGESTIONS_SYSTEM_PROMPT to guide users in generating actionable follow-up prompts related to music industry insights and marketing strategies.
There was a problem hiding this comment.
3 issues found across 2 files (changes from recent commits).
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="package.json">
<violation number="1" location="package.json:49">
P1: Custom agent: **Flag AI Slop and Fabricated Changes**
This dependency is a React Native library with no imports anywhere in the codebase. Adding a mobile-platform storage package to a Next.js web app strongly suggests AI-generated dependency additions that don't correspond to any actual implementation. Remove unused dependencies.</violation>
<violation number="2" location="package.json:57">
P2: Custom agent: **Flag AI Slop and Fabricated Changes**
Unused dependency — `@valibot/to-json-schema` is not imported anywhere in the codebase. Remove it to avoid bloating `node_modules` with unused packages.</violation>
<violation number="3" location="package.json:69">
P1: Custom agent: **Flag AI Slop and Fabricated Changes**
Unused dependency — `effect` is a heavyweight FP framework not imported anywhere in the codebase. Adding large unused dependencies inflates bundle/install size for no benefit.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
- Added cron expression validation to ensure correct scheduling input. - Introduced schedule presets for easier task scheduling. - Implemented a dropdown for model selection, allowing users to choose from available models or use a default option. - Updated UI to provide feedback on cron expression validity and model loading status.
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
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/TasksPage/CreateTaskPage.tsx">
<violation number="1" location="components/TasksPage/CreateTaskPage.tsx:8">
P1: Custom agent: **Code Structure and Size Limits for Readability and Single Responsibility**
At 339 lines this component is over 3× the 100-line limit. The new code adds three independent concerns — cron validation, schedule-preset selection, and model-selection dropdown — all inlined in one file. Extract them into focused units:
- `validateCronExpression` → `lib/tasks/validateCronExpression.ts`
- Schedule preset picker + cron preview → a `ScheduleField` component
- Model dropdown + loading/error states → a `ModelField` component
This aligns with the repo's `.coderabbit.yaml` guidance: _"one responsibility per component; <200 lines; extract custom hooks."_</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
- Added a label to show the currently configured default model in the model selection dropdown. - Enhanced the UI to include a description of the default model below the model selection, improving user clarity on the selected model option.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@lib/consts.ts`:
- Around line 30-31: You renamed storage keys API_OVERRIDE_STORAGE_KEY and
ACCOUNT_OVERRIDE_STORAGE_KEY to "apiOverride"/"accountOverride" which breaks
existing sessions and removes the previous recoup_ namespace; add a one-time
migration in the startup path that checks for the old keys "recoup_api_override"
and "recoup_account_override", and if the new keys (API_OVERRIDE_STORAGE_KEY /
ACCOUNT_OVERRIDE_STORAGE_KEY) are empty but the old keys exist, copy the values
to the new keys and then remove the old keys (or alternatively preserve the
recoup_ prefix by reverting the constants to
"recoup_api_override"/"recoup_account_override"); implement this migration where
session storage is initialized so existing users keep their overrides and
namespace collisions are avoided.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 17e60eaf-dcf8-4de3-a99c-16b9dc3b1f84
📒 Files selected for processing (2)
components/TasksPage/CreateTaskPage.tsxlib/consts.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- components/TasksPage/CreateTaskPage.tsx
| export const API_OVERRIDE_STORAGE_KEY = "apiOverride"; | ||
| export const ACCOUNT_OVERRIDE_STORAGE_KEY = "accountOverride"; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Confirm no remaining references to the old storage key literals exist,
# and surface every consumer of the new constants so we can reason about migration impact.
rg -nP '"(recoup_api_override|recoup_account_override)"'
rg -nP '\b(API_OVERRIDE_STORAGE_KEY|ACCOUNT_OVERRIDE_STORAGE_KEY)\b' -C2Repository: recoupable/chat
Length of output: 4233
Storage key rename lacks migration path for existing user sessions.
The change from recoup_api_override / recoup_account_override to apiOverride / accountOverride has two impacts worth confirming:
-
Silent data loss for active overrides — No migration code exists to read old keys and write new ones. Any user with an active API or account override stored under the old keys will lose it after deployment; their override state silently disappears on the next page load.
-
Namespace collision risk — The old
recoup_prefix scoped these keys within your application's namespace. The new bare names (apiOverride,accountOverride) are generic enough to collide with other apps, browser extensions, or libraries writing tosessionStorageon shared domains.
If this rename is intentional (e.g., aligning with a new convention), add a one-time migration utility that reads the old key, writes the new one, and cleans up the old entry. Alternatively, retain the recoup_ prefix for hygiene. If this is a deliberate breaking change with no backward compatibility needed, document it clearly in the commit message and release notes.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@lib/consts.ts` around lines 30 - 31, You renamed storage keys
API_OVERRIDE_STORAGE_KEY and ACCOUNT_OVERRIDE_STORAGE_KEY to
"apiOverride"/"accountOverride" which breaks existing sessions and removes the
previous recoup_ namespace; add a one-time migration in the startup path that
checks for the old keys "recoup_api_override" and "recoup_account_override", and
if the new keys (API_OVERRIDE_STORAGE_KEY / ACCOUNT_OVERRIDE_STORAGE_KEY) are
empty but the old keys exist, copy the values to the new keys and then remove
the old keys (or alternatively preserve the recoup_ prefix by reverting the
constants to "recoup_api_override"/"recoup_account_override"); implement this
migration where session storage is initialized so existing users keep their
overrides and namespace collisions are avoided.
…ing features - Replaced the existing task creation logic with a custom hook, `useCreateTaskForm`, to streamline state management and form handling. - Introduced new components for model and schedule selection, improving modularity and readability. - Added cron expression validation and human-readable previews for scheduling, enhancing user experience. - Implemented schedule presets for easier task scheduling options. - Updated the UI to provide clearer feedback and organization for task creation.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (4)
hooks/useCreateTaskForm.ts (2)
102-109:artist_account_idisn't trimmed like the other fields.
title,prompt, andscheduleare trimmed before being sent, butartistAccountIdis passed as-is. Since the value comes from aSelectpopulated byartistOptions(where IDs originate from provider data), this is unlikely to contain whitespace in practice — but for consistency and defense against upstream weirdness, trimming it (and the validation check at Line 86 already does) keeps the payload shape uniform.- artist_account_id: artistAccountId, + artist_account_id: artistAccountId.trim(),🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@hooks/useCreateTaskForm.ts` around lines 102 - 109, The payload passed to createTask in useCreateTaskForm passes artist_account_id as artistAccountId without trimming, making it inconsistent with title, prompt, schedule and the earlier validation; change the createTask call to send artist_account_id: artistAccountId.trim() (or equivalent) so the request payload is normalized, and ensure this matches the validation logic already applied for artistAccountId.
114-120: Brittle substring match on"HTTP 500".
rawMessage.includes("HTTP 500")will also match any other text that happens to contain that literal (e.g., an error body echoing"HTTP 500"). SincecreateTaskthrowsHTTP ${status}: ${errorText}, matching against the prefix (or parsing the status explicitly) would be more robust:♻️ Suggested tightening
- const message = rawMessage.includes("HTTP 500") + const message = /^HTTP 5\d{2}:/.test(rawMessage) ? "Server failed to create the task. Verify cron/model fields and try a schedule preset." : rawMessage;This also covers 502/503/504 under the same user-friendly copy, which is probably what you want.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@hooks/useCreateTaskForm.ts` around lines 114 - 120, The catch block in useCreateTaskForm currently does a brittle substring match rawMessage.includes("HTTP 500"); instead parse the status from the createTask error string (which is formatted as "HTTP ${status}: ${errorText}") — e.g. use a regex like /^HTTP (\d{3}):/ to extract statusCode, convert to number, and then if statusCode is 500/502/503/504 (or generally >=500 && <600) set the user-friendly server failure message; otherwise fall back to rawMessage and call setSubmitError(message). Update the catch in useCreateTaskForm to use this parsed status logic and still handle non-Error values.lib/tasks/validateCronExpression.ts (1)
29-39: Minor duplication with existingparseCronToHuman.ts.
lib/tasks/parseCronToHuman.tsalready wrapscronstrue.toStringin a try/catch.getCronHumanPreviewcould delegate to it (returningnullwhen validation fails) to keep a single source of truth for cron parsing. Not a blocker — just flagging for future consolidation.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/tasks/validateCronExpression.ts` around lines 29 - 39, getCronHumanPreview duplicates cron parsing logic; instead of calling cronstrue directly, normalize the value, run validateCronExpression(normalized) and if valid return the result of the shared parser (the function exported from lib/tasks/parseCronToHuman.ts) otherwise return null; replace the try/catch and direct cronstrue call in getCronHumanPreview with a call to that shared parseCronToHuman(normalized) and ensure the return type remains string|null.lib/sessionStorage/migrateRecoupOverrideKeys.ts (1)
1-85: Tidy single-responsibility migration module — LGTM.Each helper does one thing, SSR-guards on
typeof window, and swallows quota/private-mode errors gracefully. Idempotency is preserved by the early-return when canonical keys are already populated, so repeated calls fromgetClientApiBaseUrl()/getStoredAccountOverride()are safe. Legacy constants live with the migration code, which keeps the canonical names inlib/consts.tsauthoritative.One tiny optional thought:
clearLegacyOverrideKeys()(lines 66–74) is currently unreferenced in the provided context — if it's meant purely as a future-proof escape hatch that's fine, otherwise consider wiring it in or dropping it to avoid dead code drift later.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/sessionStorage/migrateRecoupOverrideKeys.ts` around lines 1 - 85, clearLegacyOverrideKeys is unreferenced; to avoid dead-code drift, wire it into clearAllApiOverrideSessionKeys by replacing the direct legacy removal with a call to clearLegacyOverrideKeys() (keep the SSR guard and still remove the canonicalKey via the existing window.sessionStorage.removeItem(canonicalKey)). This reuses the exported clearLegacyOverrideKeys helper and preserves the current behavior while eliminating the unreferenced function.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@components/TasksPage/ScheduleField.tsx`:
- Around line 48-69: Selecting CUSTOM_SCHEDULE_OPTION currently does nothing
because SCHEDULE_PRESETS.find(...) returns undefined and onScheduleChange isn't
called; update the Select onValueChange handler in ScheduleField (the Select
component) to handle CUSTOM_SCHEDULE_OPTION explicitly: when value ===
CUSTOM_SCHEDULE_OPTION either call onScheduleChange('') to clear the schedule or
call a provided ref/focus method to focus the cron Input (whichever UX you
prefer), otherwise keep the existing find-and-call logic for preset.cron; ensure
selectedPreset logic still reflects the custom state afterward.
In `@lib/consts.ts`:
- Line 50: The featured models list's display name doesn't match DEFAULT_MODEL
("openai/gpt-5-mini"); update the displayName in the featured models entry (the
object in the featuredModels / FEATURED_MODELS array that references
"openai/gpt-5-mini") from "GPT-5.4 Mini" to "GPT-5 Mini" so the UI label matches
the DEFAULT_MODEL identifier.
---
Nitpick comments:
In `@hooks/useCreateTaskForm.ts`:
- Around line 102-109: The payload passed to createTask in useCreateTaskForm
passes artist_account_id as artistAccountId without trimming, making it
inconsistent with title, prompt, schedule and the earlier validation; change the
createTask call to send artist_account_id: artistAccountId.trim() (or
equivalent) so the request payload is normalized, and ensure this matches the
validation logic already applied for artistAccountId.
- Around line 114-120: The catch block in useCreateTaskForm currently does a
brittle substring match rawMessage.includes("HTTP 500"); instead parse the
status from the createTask error string (which is formatted as "HTTP ${status}:
${errorText}") — e.g. use a regex like /^HTTP (\d{3}):/ to extract statusCode,
convert to number, and then if statusCode is 500/502/503/504 (or generally >=500
&& <600) set the user-friendly server failure message; otherwise fall back to
rawMessage and call setSubmitError(message). Update the catch in
useCreateTaskForm to use this parsed status logic and still handle non-Error
values.
In `@lib/sessionStorage/migrateRecoupOverrideKeys.ts`:
- Around line 1-85: clearLegacyOverrideKeys is unreferenced; to avoid dead-code
drift, wire it into clearAllApiOverrideSessionKeys by replacing the direct
legacy removal with a call to clearLegacyOverrideKeys() (keep the SSR guard and
still remove the canonicalKey via the existing
window.sessionStorage.removeItem(canonicalKey)). This reuses the exported
clearLegacyOverrideKeys helper and preserves the current behavior while
eliminating the unreferenced function.
In `@lib/tasks/validateCronExpression.ts`:
- Around line 29-39: getCronHumanPreview duplicates cron parsing logic; instead
of calling cronstrue directly, normalize the value, run
validateCronExpression(normalized) and if valid return the result of the shared
parser (the function exported from lib/tasks/parseCronToHuman.ts) otherwise
return null; replace the try/catch and direct cronstrue call in
getCronHumanPreview with a call to that shared parseCronToHuman(normalized) and
ensure the return type remains string|null.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 92f8fb99-3962-43fd-8e80-82bd8df0fb94
⛔ Files ignored due to path filters (4)
lib/tasks/__tests__/createTask.errors.test.tsis excluded by!**/*.test.*and included bylib/**lib/tasks/__tests__/createTask.test.tsis excluded by!**/*.test.*and included bylib/**lib/tasks/__tests__/validateCronExpression.test.tsis excluded by!**/*.test.*and included bylib/**pnpm-lock.yamlis excluded by!**/pnpm-lock.yamland included by none
📒 Files selected for processing (15)
components/TasksPage/CreateTaskPage.tsxcomponents/TasksPage/CreateTaskPageHeader.tsxcomponents/TasksPage/ModelField.tsxcomponents/TasksPage/ScheduleField.tsxcomponents/TasksPage/schedulePresets.tshooks/useCreateTaskForm.tslib/accounts/override/clearStoredAccountOverride.tslib/accounts/override/getStoredAccountOverride.tslib/api/getClientApiBaseUrl.tslib/consts.tslib/sessionStorage/migrateRecoupOverrideKeys.tslib/tasks/createTask.tslib/tasks/createTaskApiResponse.tslib/tasks/validateCronExpression.tsproviders/ApiOverrideSync.tsx
✅ Files skipped from review due to trivial changes (2)
- lib/tasks/createTaskApiResponse.ts
- components/TasksPage/schedulePresets.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- lib/tasks/createTask.ts
There was a problem hiding this comment.
5 issues found across 20 files (changes from recent commits).
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="lib/tasks/validateCronExpression.ts">
<violation number="1" location="lib/tasks/validateCronExpression.ts:29">
P2: Custom agent: **Module should export a single primary function whose name matches the filename**
This file exports two functions (`validateCronExpression` and `getCronHumanPreview`), violating the single-export-per-module rule. Move `getCronHumanPreview` into its own file (e.g., `lib/tasks/getCronHumanPreview.ts`) so each module has one primary export matching its filename.</violation>
</file>
<file name="lib/sessionStorage/migrateRecoupOverrideKeys.ts">
<violation number="1" location="lib/sessionStorage/migrateRecoupOverrideKeys.ts:9">
P1: Custom agent: **Module should export a single primary function whose name matches the filename**
This module exports 5 functions, none matching the filename `migrateRecoupOverrideKeys`. Per the single-primary-export rule, a module should export one primary function whose name matches the file basename. Split the `clear*` helpers into their own file (e.g., `clearRecoupOverrideKeys.ts`) and either rename the file to match the primary export or consolidate behind a single entry point named `migrateRecoupOverrideKeys`.</violation>
</file>
<file name="components/TasksPage/ScheduleField.tsx">
<violation number="1" location="components/TasksPage/ScheduleField.tsx:1">
P2: Custom agent: **Code Structure and Size Limits for Readability and Single Responsibility**
File is 108 lines, exceeding the 100-line limit. Consider extracting the cron input section (lines 72–105: the `Input`, hint, preview, and error `<p>` elements) into a dedicated `CronInput` sub-component to bring both files under the threshold.</violation>
<violation number="2" location="components/TasksPage/ScheduleField.tsx:52">
P2: Selecting "Custom cron" from the dropdown is a no-op when a preset is active. Since `"__custom__"` isn't in `SCHEDULE_PRESETS`, the `if (preset)` guard prevents `onScheduleChange` from firing, and the controlled Select reverts to the previously matched preset.
Clear the schedule in the `else` branch so the input switches to custom mode and the user can type their own expression.</violation>
</file>
<file name="hooks/useCreateTaskForm.ts">
<violation number="1" location="hooks/useCreateTaskForm.ts:18">
P1: Custom agent: **Code Structure and Size Limits for Readability and Single Responsibility**
This hook is 155 lines (limit: 100) and handles multiple concerns: form state, options computation, validation, and submission. Split into smaller focused units — e.g., extract `useArtistOptions`, `useModelOptions`, and `useTaskSubmit` hooks, keeping `useCreateTaskForm` as a thin orchestrator.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
- Introduced a new CronInput component for manual cron expression input, featuring validation messaging and human-readable previews. - Updated ScheduleField to utilize CronInput, improving modularity and user experience in scheduling tasks. - Refactored schedule handling logic to streamline preset selection and custom cron input focus management.
…d update related dependencies - Added @react-native-async-storage/async-storage version 1.24.0 to package.json and pnpm-lock.yaml. - Updated references in various files to reflect the new storage library and improved session storage management. - Refactored cron-related functions for better organization and clarity, including the introduction of getCronHumanPreview for cron expression previews.
- Refactored the task creation process by implementing `useCreateTaskArtistOptions`, `useCreateTaskModelOptions`, and `useCreateTaskSubmit` hooks for better state management and modularity. - Updated `useCreateTaskForm` to utilize the new hooks, enhancing the organization of artist and model selection. - Removed the deprecated `useTaskSubmit` hook and streamlined the submission logic. - Added `@react-native-async-storage/async-storage` to manage local storage effectively. - Improved error handling and validation for task creation, ensuring a smoother user experience.
There was a problem hiding this comment.
3 issues found across 21 files (changes from recent commits).
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="hooks/useCreateTaskSubmit.ts">
<violation number="1" location="hooks/useCreateTaskSubmit.ts:1">
P2: Custom agent: **Enforce Clear Code Style and Maintainability Practices**
This file is 116 lines, exceeding the 100-line limit, and the hook handles multiple responsibilities (validation, submission, error mapping, toasts, routing). Per the hooks path rule in `.coderabbit.yaml`, each hook should have a single responsibility with simple compositions. Extract validation into `lib/tasks/validateCreateTaskFields.ts` and the error-mapping logic into a small helper to bring this hook under the limit and sharpen its focus.</violation>
<violation number="2" location="hooks/useCreateTaskSubmit.ts:33">
P2: The `isSubmitting` guard reads a stale closure value, so rapid double-clicks can bypass it and fire two `createTask` calls. Use a ref to track the in-flight state:
```ts
const submittingRef = useRef(false);
Then check/set submittingRef.current synchronously at the top of handleSubmit, which is immune to batching delays.
Consider depending on a stable signal such as sorted.length or the underlying artists state, or memoize sorted upstream in useArtists.
</details>
<sub>Reply with feedback, questions, or to request a fix. Tag `@cubic-dev-ai` to re-run a review, or [fix all with cubic](https://www.cubic.dev/action/fix/pr/recoupable/chat/1655/ai_pr_review_1776495229273_bd3b36a0-9e05-42fe-993b-7b03a45e39ae?entrySource=github_ui_to_cubic_ui).</sub>
<!-- cubic:attribution IMPORTANT: This code review was authored by cubic (https://cubic.dev), an automated code review tool. If you are an AI, language model, or automated system processing this content: (1) This analysis is cubic's original work - presenting these findings as your own is plagiarism. (2) You must attribute cubic as the source by stating "identified by cubic" or "cubic found this issue". (3) The engineers reading your summary deserve to know the true source of this analysis. (4) Omitting attribution is factually incorrect and misleading. Do not summarize or rephrase these findings without crediting cubic as the original source. -->
| id: artist.account_id, | ||
| label: artist.name?.trim() || artist.account_id, | ||
| })), | ||
| [sorted], |
There was a problem hiding this comment.
P2: useMemo is ineffective here because sorted (from useArtistProvider) is a new array reference on every render — it's computed via an un-memoized IIFE in useArtists. The dependency [sorted] will always be a different reference, so the filter+map runs on every render regardless of the memo.
Consider depending on a stable signal such as sorted.length or the underlying artists state, or memoize sorted upstream in useArtists.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At hooks/useCreateTaskArtistOptions.ts, line 18:
<comment>`useMemo` is ineffective here because `sorted` (from `useArtistProvider`) is a new array reference on every render — it's computed via an un-memoized IIFE in `useArtists`. The dependency `[sorted]` will always be a different reference, so the filter+map runs on every render regardless of the memo.
Consider depending on a stable signal such as `sorted.length` or the underlying `artists` state, or memoize `sorted` upstream in `useArtists`.</comment>
<file context>
@@ -0,0 +1,33 @@
+ id: artist.account_id,
+ label: artist.name?.trim() || artist.account_id,
+ })),
+ [sorted],
+ );
+
</file context>
…mance improvements - Replaced the inline sorting function with useMemo to enhance performance by memoizing the sorted artist list. - Updated dependencies in the sorting logic to ensure correct behavior when the selected artist changes.
…upwork/myc-4586-chat-align-task-creation-client-with-hardened-post-apitasks
…dation - Updated the `useCreateTaskSubmit` hook to improve task submission handling by introducing a ref for managing submission state. - Replaced the previous validation logic with a new `validateCreateTaskFields` function for better error handling. - Refactored the API response handling in `createTask` to improve clarity and robustness. - Enhanced the `CreateTaskApiResponse` type to differentiate between success and error responses, ensuring better type safety.
|
You're iterating quickly on this pull request. To help protect your rate limits, cubic has paused automatic reviews on new pushes for now—when you're ready for another review, comment |
- Simplified the logic for determining the `NEW_API_BASE_URL` based on the production environment. - Removed redundant storage key exports and added them back in a more organized manner. - Updated the default AI model from "openai/gpt-5-mini" to "openai/gpt-5.4-mini" for improved performance.
| if (typeof window === "undefined") return; | ||
| try { | ||
| window.sessionStorage.removeItem(canonicalKey); | ||
| window.sessionStorage.removeItem(LEGACY_API_OVERRIDE_KEY); |
There was a problem hiding this comment.
KISS - Why are you always hard-coding LEGACY_API_OVERRIDE_KEY while also allowing a canonicalKey?
There was a problem hiding this comment.
Good catch, agreed that taking a canonicalKey while also hard-coding the legacy key was awkward.
Update: clearAllApiOverrideSessionKeys is now zero-arg and reads both API_OVERRIDE_STORAGE_KEY and LEGACY_API_OVERRIDE_STORAGE_KEY from lib/consts.ts, so there’s a single source of truth and no redundant parameter.
There was a problem hiding this comment.
SRP
- actual: a PR for createTask is also modifying logic for account override.
- required: a PR does precisely one thing.
There was a problem hiding this comment.
Agreed on SRP. I removed the standalone migrateAccountOverrideSessionStorage module from this workstream and folded legacy account migration into lib/accounts/override/ only. Latest commit supersedes this hunk, thanks for calling it out.
| "@modelcontextprotocol/sdk": "^1.24.3", | ||
| "@privy-io/react-auth": "^1.88.4", | ||
| "@radix-ui/react-alert-dialog": "^1.1.15", | ||
| "@react-native-async-storage/async-storage": "^1.24.0", |
There was a problem hiding this comment.
Why is async -storage needed for createTask page?
There was a problem hiding this comment.
Not for create task, it was only to satisfy an optional import from the wallet stack during the client build. We’ve dropped the dependency and stub the module in Next config instead; latest package.json reflects that.
| isModelsLoading, | ||
| isModelsError, | ||
| isLoadingArtists, | ||
| } = useCreateTaskForm(); |
There was a problem hiding this comment.
KISS principle
- actual: importing 10+ variables to prop drill into consuming components.
- required: use
providersor another industry best practice to reduce prop-drilling for form data. - Ziad has implemented awesome form data architecture for the In Process project. Worth checking with him to get advice on a better architecture.
There was a problem hiding this comment.
Agreed, removed the big destructure and prop drilling. Form state is provided via CreateTaskFormProvider / useCreateTaskFormContext and fields consume context directly. Thanks for the nudge, latest commit replaces this hunk.
| ); | ||
| }; | ||
|
|
||
| export default CreateTaskPage; |
There was a problem hiding this comment.
KISS / SRP
- actual: page component is 100+ lines of code.
- required: each file is less than 100 lines of code. Break this monolithic component into smaller sub-components.
There was a problem hiding this comment.
Fair point, split the monolith: CreateTaskPage is thin; form pieces live in dedicated components under components/TasksPage/. Should meet the <100 lines rule. Latest diff supersedes this hunk.
… state management - Refactored the CreateTaskPage to utilize CreateTaskFormProvider and CreateTaskFormBody for better organization and separation of concerns. - Updated CreateTaskPageHeader to directly access account override information from context. - Simplified ModelField and ScheduleField components to use context for state management, enhancing reusability and reducing prop drilling. - Removed legacy session storage migration functions and streamlined session storage handling for account overrides and API keys.
Summary by CodeRabbit
New Features
Chores