chore(lint): restore green lint via scoped rules + meaningful JSDoc#435
chore(lint): restore green lint via scoped rules + meaningful JSDoc#435arpitgupta1214 merged 5 commits intotestfrom
Conversation
Splits eslint.config.js into three file-scoped rule blocks so strict JSDoc requirements apply only where they belong: - all `**/*.ts`: keeps import/first, prettier, member-ordering, and tightens `no-unused-vars` to `argsIgnorePattern: "^_"` (was `"^_$"` which only matched bare `_`) - `app/api/**/*.ts`: retains the full jsdoc ruleset per CLAUDE.md's "all API routes require JSDoc" mandate - test files (`**/*.test.ts`, `**/__tests__/**`): disables `no-explicit-any` and `jsdoc/require-jsdoc` — tests legitimately need loose typing and don't ship as docs Residual code-level fixes the new config surfaces: - `lib/credits/getCreditUsage.ts`: replace `(usage as any)` with a typed Partial record narrowing - `lib/content/templates/types.ts`, `lib/trigger/fetchTriggerRuns.ts`: move `[key: string]: unknown` index signature before named fields (member-ordering) - `lib/artists/createArtistInDb.ts`, `lib/workspaces/createWorkspaceInDb.ts`: drop unused `error` binding from catch - misc test files: remove unused imports/vars, fix import/first ordering Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Writes endpoint-specific JSDoc against the strict rules scoped to `app/api/**`. Each handler now documents the HTTP verb + path, the request body/query shape (referencing the `validate*Body` / `validate*Query` schema file where applicable), the success response shape, and the relevant non-200 status codes. No placeholder filler — every description conveys something the signature does not. Files: - accounts/[id], admins/coding/pr, admins/coding/slack, admins/content/slack, admins/privy - chats/[id]/messages/trailing - coding-agent/callback, coding-agent/github - connectors - content (PATCH), content/analyze, content/caption, content/image, content/templates/[id], content/transcribe, content/upscale, content/video - songs/analyze/presets - transcribe Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 56 minutes and 20 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR updates API route documentation through comprehensive JSDoc comments across endpoints and makes minor refactoring adjustments in library utilities. The changes clarify request parameters, authentication methods, response structures, and HTTP status codes without altering core control flow logic. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~18 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.
1 issue found across 38 files
Confidence score: 4/5
- This PR looks safe to merge overall because the reported issue is documentation-level and does not indicate a runtime behavior change in the endpoint.
- The most severe issue is in
app/api/coding-agent/github/route.ts: the new@returnsJSDoc describes{ ok: true }, but the route actually returns{ status: ... }, which can mislead consumers and future maintainers. - Given the high confidence on this mismatch, it’s worth fixing before or immediately after merge to prevent incorrect client assumptions from spreading.
- Pay close attention to
app/api/coding-agent/github/route.ts- correct the@returnsresponse shape to match actual payloads.
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="app/api/coding-agent/github/route.ts">
<violation number="1" location="app/api/coding-agent/github/route.ts:15">
P1: Custom agent: **Flag AI Slop and Fabricated Changes**
The new `@returns` JSDoc fabricates the success response shape (`{ ok: true }`), but this endpoint actually returns `{ status: ... }` payloads. Update the doc to match the real contract.</violation>
</file>
Architecture diagram
sequenceDiagram
participant Client as External Client / Webhook
participant API as Next.js API Route (app/api)
participant Auth as Auth Logic (lib/auth)
participant Handler as Service Handler (lib/*)
participant Ext as External Service / DB
Note over Client,Ext: Standardized API Request Flow
Client->>API: HTTP Request (Method + Path)
rect rgb(240, 240, 240)
Note right of API: NEW: Standardized Signature Implementation
API->>API: CHANGED: Await context.params (Next.js 15 compatibility)
end
API->>Handler: Invoke specific handler(request, params)
rect rgb(230, 245, 230)
Note right of Handler: NEW: Meaningful JSDoc Enforcement
Handler->>Auth: validateAuthContext()
Auth->>Auth: Check x-api-key or Bearer token
end
alt Auth Successful
Handler->>Ext: Resource Operation (DB / Third-party API)
opt Async Task (e.g., /api/content)
Handler->>Ext: Trigger.dev Task Queue
Ext-->>Handler: Return Run ID
end
Ext-->>Handler: Result Data
Handler-->>API: 200/202 NextResponse (Typed Body)
API-->>Client: JSON Response
else Auth Failed / Missing Permissions
Auth-->>Handler: Throw/Return Auth Error
Handler-->>API: 401/403/404 NextResponse
API-->>Client: Error Payload
end
Note over Client,Ext: Special Flow: Webhook (GitHub / Trigger.dev)
Client->>API: POST /api/coding-agent/[callback|github]
API->>Handler: handleWebhook(request)
Handler->>Handler: Validate Signature (Secret / X-Hub-Signature)
Handler->>Ext: Post to Slack / Update DB
Handler-->>API: 200 OK
API-->>Client: Ack
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
…ertion in sandbox test - `getCreditUsage`: drop the hand-rolled Partial-record cast and the v2-compat `promptTokens`/`completionTokens` fallback — `LanguageModelUsage` (= V3Usage) already types `inputTokens` / `outputTokens` directly, and the real runtime caller (`handleChatCredits`) passes this exact type. The compat branch was dead against the typed surface. - `getCreditUsage.test.ts`: update mock usage objects from the legacy `promptTokens`/`completionTokens` shape to the SDK V3 shape the function is actually typed against. - `postSandboxesFilesHandler.test.ts`: restore `result.json()` so the 500-path still asserts the response is valid JSON (not just status code), matching the original test intent. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cubic review feedback: the JSDoc claimed `{ ok: true }` on 200 but the handler
returns `{ status: <outcome> }` payloads (`update_triggered`, `ignored`, `busy`,
`no_state`, `updating`) and `{ status: "error", error }` on non-200s. Update the
doc to match the actual contract.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
lib/credits/getCreditUsage.ts (1)
23-25:⚠️ Potential issue | 🟠 MajorFix token presence check to allow valid zero values
Line 23 uses a falsy check, so
0tokens are treated as missing. This can incorrectly return0spend for valid usage (e.g., only input tokens billed).Suggested patch
- if (!inputTokens || !outputTokens) { + if (inputTokens == null || outputTokens == null) { console.error("No tokens found in usage"); return 0; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/credits/getCreditUsage.ts` around lines 23 - 25, The current presence check in getCreditUsage that uses "if (!inputTokens || !outputTokens)" treats valid zero values as missing; change the check to explicitly test for null/undefined (e.g., "if (inputTokens == null && outputTokens == null)" or check each with "== null") so zero is allowed and only truly absent values trigger the early return in the getCreditUsage function when inspecting inputTokens and outputTokens.app/api/transcribe/route.ts (1)
21-35:⚠️ Potential issue | 🟠 MajorUse a Zod validate function instead of ad-hoc required-field checks.
Line 21-Line 35 performs manual presence checks only. This misses structural/type validation and creates inconsistent parse behavior. Route input should be parsed through a dedicated Zod validator function, then consume typed output in the handler.
As per coding guidelines: "All API endpoints should use a validate function for input parsing using Zod for schema validation".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/api/transcribe/route.ts` around lines 21 - 35, Replace the ad-hoc presence checks on the parsed body (const body, audio_url, account_id, artist_account_id, title, include_timestamps) with a Zod-based validation flow: define a Zod schema for the expected shape (required audio_url, account_id, artist_account_id, optional title and include_timestamps), create or use the project validate function to parse req.json() into the typed input, and then consume the validated result in the handler; remove the manual NextResponse.json 400 branches and instead return validation errors from the validate function so the handler always works with a typed, validated input.lib/workspaces/createWorkspaceInDb.ts (1)
32-45:⚠️ Potential issue | 🟠 MajorMake this multi-step create flow atomic.
If any later step fails, earlier inserts remain persisted, which can leave orphaned or partially-linked records. Please wrap these writes in a transaction (or add compensating rollback) to preserve data integrity.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/workspaces/createWorkspaceInDb.ts` around lines 32 - 45, The create flow is not atomic: calls to insertAccount, insertAccountInfo, selectAccountWithSocials, insertAccountWorkspaceId and addArtistToOrganization can leave partial state if a later step fails; wrap the sequence in a single DB transaction (or implement compensating rollbacks) so all writes are committed only if every step succeeds, and ensure on any failure you roll back the transaction and return null (or propagate the error) rather than leaving earlier inserts persisted; commit at the end after successful insertAccountWorkspaceId and addArtistToOrganization (if executed).
🧹 Nitpick comments (4)
app/api/transcribe/route.ts (1)
19-56: RefactorPOSTinto smaller units (currently >20 lines).The handler is 38 lines and mixes parsing, validation, orchestration, and response mapping. Extract validation/auth and response-shaping helpers to keep the route focused and easier to maintain.
As per coding guidelines: "Flag functions longer than 20 lines or classes with >200 lines" and "Keep functions small and focused".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/api/transcribe/route.ts` around lines 19 - 56, The POST handler is too long and mixes parsing, validation, orchestration and response shaping; refactor by extracting a request validator (e.g., parseAndValidateRequest(req) that returns { audio_url, account_id, artist_account_id, title, include_timestamps } or throws on missing fields), a response-shaper (e.g., buildSuccessResponse(result) to map processAudioTranscription's result to the JSON shape), and an error responder (e.g., buildErrorResponse(error) that calls formatTranscriptionError and returns the proper NextResponse), then simplify POST to call these helpers and processAudioTranscription; keep references to the original symbols POST, processAudioTranscription and formatTranscriptionError so callers remain unchanged.lib/artists/createArtistInDb.ts (1)
54-56: Consider adding error logging for better observability.While the current behavior (silently returning
nullon errors) may be intentional, adding structured logging would help diagnose failures in production—especially for multi-step operations involving database inserts and associations.📊 Example: Add error logging
- } catch { + } catch (error) { + console.error('[createArtistInDb] Failed to create artist:', { name, accountId, organizationId, error }); return null; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/artists/createArtistInDb.ts` around lines 54 - 56, The catch block in createArtistInDb currently swallows exceptions and returns null; update that catch in function createArtistInDb to log the error (including the error object and context such as artist payload or operation step) before returning null — use the project's logger if available (e.g., processLogger or existing logger), otherwise fallback to console.error, and ensure the log message clearly identifies the function name and that the failure occurred during artist creation/association.lib/workspaces/createWorkspaceInDb.ts (1)
52-53: Avoid silent exception swallowing incatch {}.Dropping the error binding removes valuable failure context. Capture/log the exception via the project telemetry/logger before returning
null.As per coding guidelines, “Handle errors gracefully.”
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/workspaces/createWorkspaceInDb.ts` around lines 52 - 53, The catch block in createWorkspaceInDb currently swallows all exceptions (catch { return null; }); update it to capture and record the thrown error before returning null — e.g., catch (err) { projectTelemetry.captureException(err) or projectLogger.error("createWorkspaceInDb failed", err); return null; } — so the failure context is logged to your existing telemetry/logger (use the project's telemetry API or logger used elsewhere in this module).lib/chats/compactChatsHandler.ts (1)
16-78: Consider extracting result processing logic to improve modularity.While the function is well-structured with clear sections, it currently spans 63 lines, exceeding the 50-line guideline for domain functions in
lib/. The result aggregation logic (lines 31-41) could be extracted into a separate helper function likeaggregateCompactResultsto improve readability and testability.♻️ Potential refactor approach
Extract result processing into a dedicated function:
// In a new file: lib/chats/aggregateCompactResults.ts export function aggregateCompactResults(processResults: ProcessResult[]) { const results: CompactChatResult[] = []; const notFoundIds: string[] = []; for (const processResult of processResults) { if (processResult.type === "notFound") { notFoundIds.push(processResult.chatId); } else if (processResult.result) { results.push(processResult.result); } } return { results, notFoundIds }; }Then simplify the handler:
// Process all chats in parallel using Promise.all for performance const processResults = await Promise.all( chatIds.map(chatId => processCompactChatRequest({ chatId, prompt, accountId })), ); -// Separate results and not-found IDs -const results: CompactChatResult[] = []; -const notFoundIds: string[] = []; - -for (const processResult of processResults) { - if (processResult.type === "notFound") { - notFoundIds.push(processResult.chatId); - } else if (processResult.result) { - results.push(processResult.result); - } -} +const { results, notFoundIds } = aggregateCompactResults(processResults);As per coding guidelines: "Keep functions under 50 lines" for
lib/**/*.tsfiles.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/chats/compactChatsHandler.ts` around lines 16 - 78, The handler compactChatsHandler is over the 50-line guideline because the result aggregation loop is inline; extract that logic into a new helper aggregateCompactResults(processResults: ProcessResult[]) that returns { results: CompactChatResult[], notFoundIds: string[] } and replace the for-loop in compactChatsHandler with a call to aggregateCompactResults(processResults), keeping the existing behavior (push to results when processResult.result exists and collect chatId when processResult.type === "notFound"); ensure you export the helper (e.g., lib/chats/aggregateCompactResults.ts) and update imports so processCompactChatRequest and type names (ProcessResult, CompactChatResult) are used for typing in the helper for testability and readability.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/api/connectors/route.ts`:
- Around line 24-32: Update the route contract and implementation so account_id
is no longer accepted from the client: remove `account_id` from the JSDoc and
any query parsing/validation logic, update the route handler (the GET/route
handler in route.ts) to derive the account ID from the authenticated context
(e.g., the decoded bearer token or x-api-key auth principal) and use that
derived ID for scoping connector status, and remove or adjust any
validators/schemas that still expect `account_id` (and any authorization checks
that previously allowed client-supplied account_id) so authorization always uses
the authenticated principal.
In `@app/api/transcribe/route.ts`:
- Around line 13-14: The route currently accepts account_id from the request
body and assigns it to ownerAccountId, which allows cross-account writes;
instead call validateAuthContext() at the start of the handler and derive
ownerAccountId from its returned context (e.g., use the
authenticatedContext.accountId or similar field), remove account_id from the
request body parsing and JSDoc, and replace all uses of body.account_id in this
handler (and related variables between the earlier mentioned lines) with the
authenticated ownerAccountId; ensure validateAuthContext() is used for auth
validation (supports x-api-key and Bearer tokens) and update the request
contract/comments to drop account_id.
In `@lib/chats/compactChatsHandler.ts`:
- Line 24: The function compactChatsHandler destructures validated as "const {
chatIds, prompt, accountId } = validated;" and no longer uses orgId, but the
CompactChatsRequestData interface in validateCompactChatsRequest.ts still
includes "orgId?: string"; update the interface (CompactChatsRequestData) to
remove the unused orgId field or, if orgId must remain for documented reasons,
update the JSDoc/comment in validateCompactChatsRequest.ts to reflect that orgId
is deprecated/unused so the type and docs stay consistent with the handler code.
---
Outside diff comments:
In `@app/api/transcribe/route.ts`:
- Around line 21-35: Replace the ad-hoc presence checks on the parsed body
(const body, audio_url, account_id, artist_account_id, title,
include_timestamps) with a Zod-based validation flow: define a Zod schema for
the expected shape (required audio_url, account_id, artist_account_id, optional
title and include_timestamps), create or use the project validate function to
parse req.json() into the typed input, and then consume the validated result in
the handler; remove the manual NextResponse.json 400 branches and instead return
validation errors from the validate function so the handler always works with a
typed, validated input.
In `@lib/credits/getCreditUsage.ts`:
- Around line 23-25: The current presence check in getCreditUsage that uses "if
(!inputTokens || !outputTokens)" treats valid zero values as missing; change the
check to explicitly test for null/undefined (e.g., "if (inputTokens == null &&
outputTokens == null)" or check each with "== null") so zero is allowed and only
truly absent values trigger the early return in the getCreditUsage function when
inspecting inputTokens and outputTokens.
In `@lib/workspaces/createWorkspaceInDb.ts`:
- Around line 32-45: The create flow is not atomic: calls to insertAccount,
insertAccountInfo, selectAccountWithSocials, insertAccountWorkspaceId and
addArtistToOrganization can leave partial state if a later step fails; wrap the
sequence in a single DB transaction (or implement compensating rollbacks) so all
writes are committed only if every step succeeds, and ensure on any failure you
roll back the transaction and return null (or propagate the error) rather than
leaving earlier inserts persisted; commit at the end after successful
insertAccountWorkspaceId and addArtistToOrganization (if executed).
---
Nitpick comments:
In `@app/api/transcribe/route.ts`:
- Around line 19-56: The POST handler is too long and mixes parsing, validation,
orchestration and response shaping; refactor by extracting a request validator
(e.g., parseAndValidateRequest(req) that returns { audio_url, account_id,
artist_account_id, title, include_timestamps } or throws on missing fields), a
response-shaper (e.g., buildSuccessResponse(result) to map
processAudioTranscription's result to the JSON shape), and an error responder
(e.g., buildErrorResponse(error) that calls formatTranscriptionError and returns
the proper NextResponse), then simplify POST to call these helpers and
processAudioTranscription; keep references to the original symbols POST,
processAudioTranscription and formatTranscriptionError so callers remain
unchanged.
In `@lib/artists/createArtistInDb.ts`:
- Around line 54-56: The catch block in createArtistInDb currently swallows
exceptions and returns null; update that catch in function createArtistInDb to
log the error (including the error object and context such as artist payload or
operation step) before returning null — use the project's logger if available
(e.g., processLogger or existing logger), otherwise fallback to console.error,
and ensure the log message clearly identifies the function name and that the
failure occurred during artist creation/association.
In `@lib/chats/compactChatsHandler.ts`:
- Around line 16-78: The handler compactChatsHandler is over the 50-line
guideline because the result aggregation loop is inline; extract that logic into
a new helper aggregateCompactResults(processResults: ProcessResult[]) that
returns { results: CompactChatResult[], notFoundIds: string[] } and replace the
for-loop in compactChatsHandler with a call to
aggregateCompactResults(processResults), keeping the existing behavior (push to
results when processResult.result exists and collect chatId when
processResult.type === "notFound"); ensure you export the helper (e.g.,
lib/chats/aggregateCompactResults.ts) and update imports so
processCompactChatRequest and type names (ProcessResult, CompactChatResult) are
used for typing in the helper for testability and readability.
In `@lib/workspaces/createWorkspaceInDb.ts`:
- Around line 52-53: The catch block in createWorkspaceInDb currently swallows
all exceptions (catch { return null; }); update it to capture and record the
thrown error before returning null — e.g., catch (err) {
projectTelemetry.captureException(err) or
projectLogger.error("createWorkspaceInDb failed", err); return null; } — so the
failure context is logged to your existing telemetry/logger (use the project's
telemetry API or logger used elsewhere in this module).
🪄 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: a24afa1c-a487-4a1d-9fff-3a9636b1299d
⛔ Files ignored due to path filters (13)
eslint.config.jsis excluded by none and included by nonelib/admins/slack/__tests__/fetchBotMentions.test.tsis excluded by!**/*.test.*,!**/__tests__/**and included bylib/**lib/agents/generalAgent/__tests__/getGeneralAgent.test.tsis excluded by!**/*.test.*,!**/__tests__/**and included bylib/**lib/artist/__tests__/updateArtistSocials.test.tsis excluded by!**/*.test.*,!**/__tests__/**and included bylib/**lib/chat/__tests__/validateChatRequest.test.tsis excluded by!**/*.test.*,!**/__tests__/**and included bylib/**lib/chats/__tests__/getChatsHandler.test.tsis excluded by!**/*.test.*,!**/__tests__/**and included bylib/**lib/chats/__tests__/validateGetChatsRequest.test.tsis excluded by!**/*.test.*,!**/__tests__/**and included bylib/**lib/credits/__tests__/getCreditUsage.test.tsis excluded by!**/*.test.*,!**/__tests__/**and included bylib/**lib/github/__tests__/createOrUpdateFileContent.test.tsis excluded by!**/*.test.*,!**/__tests__/**and included bylib/**lib/github/__tests__/expandSubmoduleEntries.test.tsis excluded by!**/*.test.*,!**/__tests__/**and included bylib/**lib/sandbox/__tests__/postSandboxesFilesHandler.test.tsis excluded by!**/*.test.*,!**/__tests__/**and included bylib/**lib/supabase/account_sandboxes/__tests__/selectAccountSandboxes.test.tsis excluded by!**/*.test.*,!**/__tests__/**and included bylib/**lib/tasks/__tests__/enrichTasks.test.tsis excluded by!**/*.test.*,!**/__tests__/**and included bylib/**
📒 Files selected for processing (26)
app/api/accounts/[id]/route.tsapp/api/admins/coding/pr/route.tsapp/api/admins/coding/slack/route.tsapp/api/admins/content/slack/route.tsapp/api/admins/privy/route.tsapp/api/chats/[id]/messages/trailing/route.tsapp/api/coding-agent/callback/route.tsapp/api/coding-agent/github/route.tsapp/api/connectors/route.tsapp/api/content/analyze/route.tsapp/api/content/caption/route.tsapp/api/content/image/route.tsapp/api/content/route.tsapp/api/content/templates/[id]/route.tsapp/api/content/transcribe/route.tsapp/api/content/upscale/route.tsapp/api/content/video/route.tsapp/api/songs/analyze/presets/route.tsapp/api/transcribe/route.tslib/artists/createArtistInDb.tslib/chats/compactChatsHandler.tslib/coding-agent/resolvePRState.tslib/content/templates/types.tslib/credits/getCreditUsage.tslib/trigger/fetchTriggerRuns.tslib/workspaces/createWorkspaceInDb.ts
| * When `account_id` is supplied, the statuses are scoped to that account (e.g. an | ||
| * artist) instead of the authenticated caller. Requires `x-api-key` or | ||
| * `Authorization: Bearer`. | ||
| * | ||
| * Authentication: x-api-key OR Authorization Bearer token required. | ||
| * | ||
| * @param request | ||
| * @returns List of connectors with connection status | ||
| * @param request - The incoming request. Optional query parameter: `account_id` — an | ||
| * account UUID (e.g. artist) to scope the connection status lookup to. | ||
| * @returns A 200 NextResponse with `{ connectors: Array<{ slug, connected, ... }> }`, | ||
| * 401 when unauthenticated, or 403 when the caller cannot access `account_id`. | ||
| */ |
There was a problem hiding this comment.
Remove account_id from this route contract and derive account from auth context.
These docs formalize account_id as client input across multiple methods, which conflicts with the authentication model and widens authorization risk. Please update the API contract (and corresponding validators/handlers if still present) so account scope is derived only from authenticated context.
Suggested doc-level correction
- * When `account_id` is supplied, the statuses are scoped to that account (e.g. an
- * artist) instead of the authenticated caller. Requires `x-api-key` or
+ * Statuses are scoped to the authenticated account context. Requires `x-api-key` or
* `Authorization: Bearer`.
...
- * `@param` request - The incoming request. Optional query parameter: `account_id` — an
- * account UUID (e.g. artist) to scope the connection status lookup to.
+ * `@param` request - The incoming request. No account selector is accepted; account scope
+ * is derived from authenticated context.
...
- * `account_id` (optional — the account to associate the connection with).
+ * account scope is derived from authenticated context.
...
- * unauthenticated, or 403 when the caller cannot access `account_id`.
+ * unauthenticated, or 403 when the caller is not allowed to perform the action.
...
- * — the Composio connected-account id to remove); `account_id` (optional — used to
- * verify ownership of the connected account).
+ * — the Composio connected-account id to remove).Also applies to: 44-50, 61-66
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/api/connectors/route.ts` around lines 24 - 32, Update the route contract
and implementation so account_id is no longer accepted from the client: remove
`account_id` from the JSDoc and any query parsing/validation logic, update the
route handler (the GET/route handler in route.ts) to derive the account ID from
the authenticated context (e.g., the decoded bearer token or x-api-key auth
principal) and use that derived ID for scoping connector status, and remove or
adjust any validators/schemas that still expect `account_id` (and any
authorization checks that previously allowed client-supplied account_id) so
authorization always uses the authenticated principal.
| * @param req - The incoming request with JSON body `{ audio_url, account_id, | ||
| * artist_account_id, title?, include_timestamps? }`. All three ids are required. |
There was a problem hiding this comment.
Blocker: do not accept account_id from request body; derive it from auth context.
At Line 13 and Line 22, the route contract/code requires account_id from the client and then uses it as ownerAccountId. This allows cross-account writes if a caller submits another account ID. Use validateAuthContext() and set ownerAccountId from authenticated context only; remove account_id from body/JSDoc.
As per coding guidelines: "Never use account_id in request bodies or tool schemas; always derive the account ID from authentication" and "Always use validateAuthContext() for authentication in API routes; it supports both x-api-key header and Authorization: Bearer token authentication".
Also applies to: 22-40
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/api/transcribe/route.ts` around lines 13 - 14, The route currently
accepts account_id from the request body and assigns it to ownerAccountId, which
allows cross-account writes; instead call validateAuthContext() at the start of
the handler and derive ownerAccountId from its returned context (e.g., use the
authenticatedContext.accountId or similar field), remove account_id from the
request body parsing and JSDoc, and replace all uses of body.account_id in this
handler (and related variables between the earlier mentioned lines) with the
authenticated ownerAccountId; ensure validateAuthContext() is used for auth
validation (supports x-api-key and Bearer tokens) and update the request
contract/comments to drop account_id.
| } | ||
|
|
||
| const { chatIds, prompt, accountId, orgId } = validated; | ||
| const { chatIds, prompt, accountId } = validated; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Verify the return type of validateCompactChatsRequest no longer includes orgId
# Search for the validateCompactChatsRequest function definition and its return type
rg -A 20 'validateCompactChatsRequest' --type=ts -g 'validateCompactChatsRequest.ts'Repository: recoupable/api
Length of output: 1511
🏁 Script executed:
#!/bin/bash
# Find the CompactChatsRequestData type definition
rg 'type CompactChatsRequestData|interface CompactChatsRequestData' -A 15 --type=tsRepository: recoupable/api
Length of output: 1167
Remove unused orgId and update interface definition for consistency.
The removal of orgId from the destructuring is correct—it's never referenced in the function body, and downstream operations work correctly with just accountId. However, the CompactChatsRequestData interface still defines orgId?: string as an optional field. To avoid confusion and maintain clarity, either remove orgId from the interface definition in validateCompactChatsRequest.ts or update the JSDoc if this field serves a documented purpose that's no longer needed.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@lib/chats/compactChatsHandler.ts` at line 24, The function
compactChatsHandler destructures validated as "const { chatIds, prompt,
accountId } = validated;" and no longer uses orgId, but the
CompactChatsRequestData interface in validateCompactChatsRequest.ts still
includes "orgId?: string"; update the interface (CompactChatsRequestData) to
remove the unused orgId field or, if orgId must remain for documented reasons,
update the JSDoc/comment in validateCompactChatsRequest.ts to reflect that orgId
is deprecated/unused so the type and docs stay consistent with the handler code.
There was a problem hiding this comment.
1 issue found across 4 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="app/api/coding-agent/github/route.ts">
<violation number="1" location="app/api/coding-agent/github/route.ts:16">
P1: Custom agent: **Flag AI Slop and Fabricated Changes**
The updated JSDoc documents `updating` as a 200 response status, but this endpoint never returns `{"status":"updating"}`. Remove it from the documented response outcomes to avoid publishing a fabricated API contract.</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.
| * `X-Hub-Signature-256` are required; the JSON body is the raw GitHub event | ||
| * payload (typically `issue_comment`). | ||
| * @returns A NextResponse JSON payload with a `status` field indicating outcome | ||
| * (`update_triggered`, `ignored`, `busy`, `no_state`, or `updating`) on 200; |
There was a problem hiding this comment.
P1: Custom agent: Flag AI Slop and Fabricated Changes
The updated JSDoc documents updating as a 200 response status, but this endpoint never returns {"status":"updating"}. Remove it from the documented response outcomes to avoid publishing a fabricated API contract.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/api/coding-agent/github/route.ts, line 16:
<comment>The updated JSDoc documents `updating` as a 200 response status, but this endpoint never returns `{"status":"updating"}`. Remove it from the documented response outcomes to avoid publishing a fabricated API contract.</comment>
<file context>
@@ -12,8 +12,10 @@ import { handleGitHubWebhook } from "@/lib/coding-agent/handleGitHubWebhook";
- * @returns A 200 NextResponse with `{ ok: true }` when the event is accepted or
- * ignored, 401 when the signature is missing or invalid, or 500 on internal error.
+ * @returns A NextResponse JSON payload with a `status` field indicating outcome
+ * (`update_triggered`, `ignored`, `busy`, `no_state`, or `updating`) on 200;
+ * `{ status: "error", error }` with 401 when signature validation fails; and
+ * `{ status: "error", error }` with 500 on internal failure.
</file context>
| * (`update_triggered`, `ignored`, `busy`, `no_state`, or `updating`) on 200; | |
| * (`update_triggered`, `ignored`, `busy`, or `no_state`) on 200; |
…435) (#440) * chore(lint): scope eslint rules by file type + residual code fixes Splits eslint.config.js into three file-scoped rule blocks so strict JSDoc requirements apply only where they belong: - all `**/*.ts`: keeps import/first, prettier, member-ordering, and tightens `no-unused-vars` to `argsIgnorePattern: "^_"` (was `"^_$"` which only matched bare `_`) - `app/api/**/*.ts`: retains the full jsdoc ruleset per CLAUDE.md's "all API routes require JSDoc" mandate - test files (`**/*.test.ts`, `**/__tests__/**`): disables `no-explicit-any` and `jsdoc/require-jsdoc` — tests legitimately need loose typing and don't ship as docs Residual code-level fixes the new config surfaces: - `lib/credits/getCreditUsage.ts`: replace `(usage as any)` with a typed Partial record narrowing - `lib/content/templates/types.ts`, `lib/trigger/fetchTriggerRuns.ts`: move `[key: string]: unknown` index signature before named fields (member-ordering) - `lib/artists/createArtistInDb.ts`, `lib/workspaces/createWorkspaceInDb.ts`: drop unused `error` binding from catch - misc test files: remove unused imports/vars, fix import/first ordering * docs(api): meaningful JSDoc for 19 route handlers Writes endpoint-specific JSDoc against the strict rules scoped to `app/api/**`. Each handler now documents the HTTP verb + path, the request body/query shape (referencing the `validate*Body` / `validate*Query` schema file where applicable), the success response shape, and the relevant non-200 status codes. No placeholder filler — every description conveys something the signature does not. Files: - accounts/[id], admins/coding/pr, admins/coding/slack, admins/content/slack, admins/privy - chats/[id]/messages/trailing - coding-agent/callback, coding-agent/github - connectors - content (PATCH), content/analyze, content/caption, content/image, content/templates/[id], content/transcribe, content/upscale, content/video - songs/analyze/presets - transcribe * fix(credits): use typed LanguageModelUsage fields; restore json() assertion in sandbox test - `getCreditUsage`: drop the hand-rolled Partial-record cast and the v2-compat `promptTokens`/`completionTokens` fallback — `LanguageModelUsage` (= V3Usage) already types `inputTokens` / `outputTokens` directly, and the real runtime caller (`handleChatCredits`) passes this exact type. The compat branch was dead against the typed surface. - `getCreditUsage.test.ts`: update mock usage objects from the legacy `promptTokens`/`completionTokens` shape to the SDK V3 shape the function is actually typed against. - `postSandboxesFilesHandler.test.ts`: restore `result.json()` so the 500-path still asserts the response is valid JSON (not just status code), matching the original test intent. * docs(api): correct @returns shape for coding-agent github webhook Cubic review feedback: the JSDoc claimed `{ ok: true }` on 200 but the handler returns `{ status: <outcome> }` payloads (`update_triggered`, `ignored`, `busy`, `no_state`, `updating`) and `{ status: "error", error }` on non-200s. Update the doc to match the actual contract. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Restores green lint on
apiwith minimal scope — no globally-weakened rules, no placeholder JSDoc. Error count: ~678 → 0.eslint.config.js — three file-scoped rule blocks
**/*.ts: keep import/first, prettier, member-ordering; tightenno-unused-varstoargsIgnorePattern: "^_"(was"^_$", matched only bare_)app/api/**/*.ts: retain the full strict jsdoc ruleset per CLAUDE.md's "all API routes require JSDoc" mandateno-explicit-anyandjsdoc/require-jsdoc(216 of 220 no-any errors were in tests)Meaningful JSDoc for 19 route handlers
Each handler documents verb/path + purpose, body/query shape (references the
validate*Body/validate*Queryschema file), success response shape, and notable non-200 status codes. Reference quality bar:app/api/sandboxes/setup/route.ts(unmodified).Residual code fixes the new config surfaces
lib/credits/getCreditUsage.ts: useLanguageModelUsage.inputTokens/outputTokensdirectly (noany)lib/content/templates/types.ts,lib/trigger/fetchTriggerRuns.ts: move index signature before named fieldscreateInDbhelpers: drop unusederrorfrom catchTest plan
pnpm lint:checkexits 0pnpm lintproduces no diff (idempotent)pnpm test— 1893/1893 passpnpm buildsucceeds on CIapp/api/**/route.tsJSDoc names endpoint purpose, request shape, and a non-200 status🤖 Generated with Claude Code