Skip to content

Refactor/workspace api routes#22

Merged
urjitc merged 14 commits into
mainfrom
refactor/workspace-api-routes
Jan 15, 2026
Merged

Refactor/workspace api routes#22
urjitc merged 14 commits into
mainfrom
refactor/workspace-api-routes

Conversation

@urjitc

@urjitc urjitc commented Jan 15, 2026

Copy link
Copy Markdown
Member

Important

Refactor workspace API routes to centralize auth checks, standardize error handling, and improve performance by parallelizing operations.

  • Refactor:
    • Centralized auth and ownership checks using requireAuth, verifyWorkspaceOwnership, and verifyWorkspaceOwnershipWithData in workspace-helpers.ts.
    • Standardized error handling with withErrorHandling wrapper in workspace-helpers.ts.
    • Parallelized request processing in route.ts, events/route.ts, snapshot/route.ts, snapshots/route.ts, reorder/route.ts, and slug/[slug]/route.ts.
  • Behavior:
    • Snapshot and workspace endpoints maintain public behavior but ensure metadata defaults and non-blocking snapshot creation.
    • Improved input validation and ownership enforcement in reorder/route.ts and route.ts.
  • Misc:
    • Removed redundant session fetching by using requireAuthWithUserInfo in route.ts.

This description was created by Ellipsis for db0cd57. You can customize this summary. It will automatically update as commits are pushed.


Summary by CodeRabbit

  • Refactor

    • Centralized authentication and ownership checks across workspace APIs, added a standardized error-handling wrapper, and parallelized request processing for faster, more consistent endpoints.
    • Internal reorganizations preserve existing public endpoints and ensure workspace metadata defaults are populated.
  • Bug Fixes

    • Reduced race conditions, more consistent error responses, non-blocking snapshot creation, and stronger input validation for workspace reorder operations.

✏️ Tip: You can customize this high-level summary in your review settings.

- Add getAuthenticatedUser() for session management
- Add requireAuth() for authentication requirement
- Add verifyWorkspaceOwnership() for ownership checks
- Add verifyWorkspaceOwnershipWithData() for full workspace data
- Add withErrorHandling() wrapper for consistent error handling

These helpers eliminate code duplication across workspace API routes.
- Replace duplicate auth code with requireAuth()
- Wrap handlers with withErrorHandling()
- Parallelize params and auth operations for better performance
- Replace duplicate auth/ownership checks with helpers
- Wrap GET, PATCH, DELETE handlers with withErrorHandling()
- Parallelize independent operations (params, auth, body parsing)
- Reduce code duplication by ~60 lines
- Replace duplicate auth code with requireAuth()
- Wrap handler with withErrorHandling()
- Parallelize params and auth operations
- Replace duplicate auth code with requireAuth()
- Wrap handler with withErrorHandling()
- Maintain existing functionality with cleaner code
- Replace duplicate auth/ownership checks with helpers
- Wrap GET and POST handlers with withErrorHandling()
- Parallelize params, auth, and body parsing operations
- Maintain performance timing measurements
- Replace duplicate auth/ownership checks with helpers
- Wrap GET, POST, PUT handlers with withErrorHandling()
- Parallelize params and auth operations
- Reduce code duplication across all three handlers
- Replace duplicate auth/ownership checks with helpers
- Wrap handler with withErrorHandling()
- Parallelize params and auth operations
@vercel

vercel Bot commented Jan 15, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Review Updated (UTC)
thinkexv2 Ready Ready Preview, Comment Jan 15, 2026 11:33pm

@coderabbitai

coderabbitai Bot commented Jan 15, 2026

Copy link
Copy Markdown

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Refactors workspace API routes to internal handle* functions wrapped by withErrorHandling, centralizes auth/ownership via new workspace-helpers (requireAuth, verifyWorkspaceOwnership*), parallelizes params/body/auth resolution, and removes in-route try/catch blocks. Public endpoints (GET/POST/PATCH/PUT/DELETE) remain unchanged.

Changes

Cohort / File(s) Summary
Events route
src/app/api/workspaces/[id]/events/route.ts
GET/POST moved to handleGET/handlePOST and exported via withErrorHandling. Auth/ownership now via requireAuth()/verifyWorkspaceOwnership; body parsing parallelized; local try/catch removed.
Workspace core (id)
src/app/api/workspaces/[id]/route.ts
GET/PATCH/DELETE refactored to handle* + withErrorHandling. Auth/params parallelized and ownership verified via verifyWorkspaceOwnershipWithData. State loading delegated to helpers; inline try/catch removed.
Snapshot (id)
src/app/api/workspaces/[id]/snapshot/route.ts
GET/POST/PUT refactored to handle* + withErrorHandling. Ownership checks via verifyWorkspaceOwnership(With)Data; snapshot flows preserved; GET uses workspace.name for title.
Snapshots list
src/app/api/workspaces/[id]/snapshots/route.ts
GET refactored to handleGET + wrapper. Replaced inline ownership DB checks with verifyWorkspaceOwnership; error handling centralized.
Reorder
src/app/api/workspaces/reorder/route.ts
POST moved to handlePOST + wrapper. Uses requireAuth(), adds input validation, verifies ownership for each workspace id, and updates sortOrder.
Workspaces list & slug lookup
src/app/api/workspaces/route.ts, src/app/api/workspaces/slug/[slug]/route.ts
GET/POST (list) and slug GET refactored to handle* + withErrorHandling. Auth via requireAuth()/requireAuthWithUserInfo(). State defaults populated from workspace metadata when missing.
New helpers
src/lib/api/workspace-helpers.ts
New module exporting getAuthenticatedUser, requireAuth, requireAuthWithUserInfo, verifyWorkspaceOwnership, verifyWorkspaceOwnershipWithData, and withErrorHandling. Centralizes auth, ownership checks, and standardized error-to-NextResponse conversion.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Client
participant Route as API Route (handle*)
participant Helpers as workspace-helpers
participant DB
participant Logger

Client->>Route: HTTP request (params/body)
par Parallel resolve
Route->>Helpers: requireAuth() → userId
Route->>Route: parse params / body
end
Route->>Helpers: verifyWorkspaceOwnership(id, userId)
Helpers->>DB: SELECT workspace by id
DB-->>Helpers: workspace row / not found
Helpers-->>Route: workspace data or error
Route->>DB: main DB operations (query/insert/update)
DB-->>Route: results
Route-->>Client: NextResponse success
alt Error thrown
Route->>Logger: log unexpected error
Helpers-->>Client: NextResponse error
end

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰
I hopped through routes both wide and deep,
Wrapped handlers snug so errors sleep,
Auth friends lined up, checks all in place,
Promises raced, no wasted pace—
A carrot-coded hop, refactor complete!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The PR title 'Refactor/workspace api routes' is vague and generic, using a non-descriptive term 'Refactor' that does not convey the specific nature of the changes (centralized auth/error handling). Consider a more specific title such as 'Centralize workspace API authentication and error handling' or 'Add auth/error handling helpers to workspace routes' to better reflect the main objectives.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

🧹 Recent nitpick comments
src/app/api/workspaces/[id]/events/route.ts (1)

205-221: Minor: Invalid JSON returns 500 instead of 400.

The parallel body parsing at line 209 is a good performance optimization. However, if the client sends malformed JSON, request.json() throws an error that gets caught by withErrorHandling, resulting in a generic 500 response rather than a 400 Bad Request.

Consider wrapping json() for better error messages (optional)
  // Start independent operations in parallel
  const paramsPromise = params;
  const authPromise = requireAuth();
- const bodyPromise = request.json();
+ const bodyPromise = request.json().catch(() => {
+   throw NextResponse.json({ error: "Invalid JSON body" }, { status: 400 });
+ });

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 70f9d7d and db0cd57.

📒 Files selected for processing (1)
  • src/app/api/workspaces/[id]/events/route.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/app/api/workspaces/[id]/events/route.ts (2)
src/lib/api/workspace-helpers.ts (3)
  • requireAuth (102-108)
  • verifyWorkspaceOwnership (31-50)
  • withErrorHandling (80-97)
src/app/api/workspaces/[id]/route.ts (1)
  • GET (43-43)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🔇 Additional comments (3)
src/app/api/workspaces/[id]/events/route.ts (3)

12-33: Clean parallel execution pattern with proper timing.

The refactored authentication flow correctly:

  • Starts requireAuth() in parallel with params resolution
  • Captures timing immediately before each await, measuring sequential blocking time
  • Uses centralized verifyWorkspaceOwnership for consistent access control

This aligns well with the pattern established in other route handlers and the commit fix for timing measurements.


223-228: Input validation looks good.

The validation correctly checks for required fields before proceeding with the ownership check and database operations. The early return with a 400 status provides clear feedback to API consumers.


315-322: LGTM!

The success response format and withErrorHandling wrapper follow the established patterns in this codebase.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


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

@ellipsis-dev ellipsis-dev Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Important

Looks good to me! 👍

Reviewed everything up to 16a01fa in 2 minutes and 28 seconds. Click for details.
  • Reviewed 1075 lines of code in 8 files
  • Skipped 0 files when reviewing.
  • Skipped posting 4 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. src/app/api/workspaces/[id]/events/route.ts:16
  • Draft comment:
    The 'timings' object is computed (e.g. startTime, auth, workspaceCheck, etc.) but never logged or returned. Consider either logging these metrics for debugging or removing them to keep the code clean.
  • Reason this comment was not posted:
    Comment was on unchanged code.
2. src/app/api/workspaces/route.ts:126
  • Draft comment:
    The variable 'session' is used to extract the user's display name but is never defined in this scope. Update the code to retrieve the session (or include the needed user data) so that 'session.user' is available.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
3. src/app/api/workspaces/reorder/route.ts:41
  • Draft comment:
    Sequentially updating each workspace in a loop can lead to performance issues with larger arrays. Consider batching these updates into a single query or using a transaction to improve efficiency.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
4. src/lib/api/workspace-helpers.ts:80
  • Draft comment:
    The error handling in 'withErrorHandling' checks for 'status' and 'json' properties on the error object. For more robust error detection, consider using 'instanceof NextResponse' or wrapping errors in a custom error type.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 30% vs. threshold = 50% The comment is suggesting a refactor to use instanceof instead of property checking. However, this suggestion may not actually work correctly. When you throw NextResponse.json(), you're throwing the return value of that method (a NextResponse object), but instanceof checks work on the prototype chain. The real question is whether error instanceof NextResponse would work when a NextResponse is thrown. Actually, it should work since NextResponse is a class and throwing an instance would preserve the prototype chain. But the current approach is also valid and works. This feels like a "nice to have" refactor suggestion rather than fixing a bug. The comment uses "consider" which makes it sound optional. It's not pointing out a clear defect, just suggesting an alternative approach that might be "more robust" - but is it really? Without testing, we can't be sure instanceof would work better here. The instanceof approach might actually be cleaner and more idiomatic TypeScript. The current property checking could match other objects that happen to have status and json properties. The suggestion could be a legitimate improvement in type safety. While instanceof might be more idiomatic, the comment doesn't provide strong evidence that the current approach is wrong or problematic. It's a speculative suggestion about what "might be more robust" without demonstrating an actual issue. The current code works for its intended purpose of catching thrown NextResponse objects from the helper functions. This is a speculative code quality suggestion without strong evidence of a problem. The comment uses "consider" and suggests an alternative that "might be more robust" but doesn't demonstrate that the current approach is incorrect or causes issues. Per the rules, we should not keep speculative comments.

Workflow ID: wflow_wmaRrA1vjScWTnbE

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

@greptile-apps

greptile-apps Bot commented Jan 15, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR successfully refactors workspace API routes by centralizing authentication and ownership checks into reusable helper functions. The refactor eliminates code duplication, standardizes error handling with withErrorHandling wrapper, and adds parallelization to improve response times across multiple routes.

Key improvements:

  • New workspace-helpers.ts module provides requireAuth(), verifyWorkspaceOwnership(), and withErrorHandling() for consistent patterns
  • Eliminated duplicate session fetch in POST /api/workspaces by using requireAuthWithUserInfo()
  • Added parallelization of independent async operations (auth, params, body parsing) across most routes
  • Standardized error handling with try-catch wrapper that properly returns NextResponse errors

Issues found:

  • Timing measurements in events/route.ts are incorrect due to parallelization - metrics exclude the parallel wait time
  • Sequential database updates in reorder/route.ts cause unnecessary round-trips
  • Minor inconsistency: reorder/route.ts doesn't parallelize auth and body parsing like other routes

Confidence Score: 4/5

  • Safe to merge with minor timing measurement inaccuracy
  • Well-executed refactor that improves code quality and maintainability. The timing measurement issue in events route doesn't affect functionality, only observability metrics. The sequential updates in reorder are a performance concern but not a correctness issue.
  • Pay attention to src/app/api/workspaces/[id]/events/route.ts for the timing measurement bug that affects performance metrics accuracy

Important Files Changed

Filename Overview
src/lib/api/workspace-helpers.ts New helper module centralizing auth and ownership checks - clean implementation with proper error handling
src/app/api/workspaces/[id]/events/route.ts Parallelization added but timing measurements incorrect due to parallel execution affecting metrics
src/app/api/workspaces/reorder/route.ts Refactored with new helpers, but sequential updates and missing parallelization opportunity

Sequence Diagram

sequenceDiagram
    participant Client
    participant Route
    participant Helper
    participant DB

    Client->>Route: POST event request

    par Parallel
        Route->>Helper: requireAuth()
        Helper-->>Route: authenticated user
    and
        Route->>Route: parse request body
    end

    Route->>Helper: verifyWorkspaceOwnership()
    Helper->>DB: check workspace ownership
    
    alt Unauthorized
        DB-->>Helper: not found or wrong owner
        Helper-->>Route: error response
        Route-->>Client: 403/404 error
    else Authorized
        DB-->>Helper: verified
        Helper-->>Route: workspace verified
        Route->>DB: append event to log
        
        alt Version conflict
            DB-->>Route: conflict
            Route-->>Client: conflict with current state
        else Success
            DB-->>Route: event appended
            Route->>Route: snapshot check (async)
            Route-->>Client: success
        end
    end
Loading

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Additional Comments (1)

  1. src/app/api/workspaces/route.ts, line 127 (link)

    logic: session is undefined here - it was removed during refactoring but this line still references it

    Should userName be derived from the Better Auth session or is it acceptable to use just the userId we already have?

8 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment thread src/lib/api/workspace-helpers.ts Outdated
return await handler(...args);
} catch (error) {
// If error is already a NextResponse (from verifyWorkspaceOwnership), return it
if (error && typeof error === 'object' && 'status' in error && 'json' in error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

logic: Checking for 'json' property doesn't reliably detect NextResponse instances - NextResponse objects don't have a json property. This means thrown NextResponse errors won't be handled correctly.

Suggested change
if (error && typeof error === 'object' && 'status' in error && 'json' in error) {
if (error instanceof NextResponse) {
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/api/workspace-helpers.ts
Line: 85:85

Comment:
**logic:** Checking for `'json'` property doesn't reliably detect NextResponse instances - `NextResponse` objects don't have a `json` property. This means thrown NextResponse errors won't be handled correctly.

```suggestion
      if (error instanceof NextResponse) {
```

How can I resolve this? If you propose a fix, please make it concise.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/api/workspaces/route.ts (1)

125-131: Critical: session is undefined - will cause ReferenceError.

The code references session.user.name and session.user.email, but session is never defined in this function. After refactoring to use requireAuth(), the session object is no longer available. This will crash when customInitialState is provided.

Suggested fix: fetch session data or pass user info through requireAuth

Option 1 - Extend requireAuth to return user info:

// In workspace-helpers.ts, modify requireAuth:
export async function requireAuth(): Promise<{ userId: string; userName?: string }> {
  const session = await auth.api.getSession({ headers: await headers() });
  if (!session) {
    throw NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }
  return { 
    userId: session.user.id,
    userName: session.user.name || session.user.email || undefined
  };
}

Option 2 - Add a separate helper to get user info or fetch session directly in this route when needed.

🤖 Fix all issues with AI agents
In `@src/app/api/workspaces/`[id]/route.ts:
- Line 5: The file imports verifyWorkspaceOwnershipWithData but calls
verifyWorkspaceOwnership at runtime, causing a missing-import error; update the
import line to also import verifyWorkspaceOwnership (add it alongside
requireAuth, verifyWorkspaceOwnershipWithData, withErrorHandling) so the
function verifyWorkspaceOwnership used in the handlers on lines where it's
invoked is available; ensure the import statement names match the exported
symbol exactly.

In `@src/app/api/workspaces/`[id]/snapshot/route.ts:
- Line 9: The file imports verifyWorkspaceOwnershipWithData but not
verifyWorkspaceOwnership, causing a runtime ReferenceError when handlePOST and
handlePUT call verifyWorkspaceOwnership; fix by adding verifyWorkspaceOwnership
to the import list from "@/lib/api/workspace-helpers" so both
verifyWorkspaceOwnership and verifyWorkspaceOwnershipWithData are available to
the functions handlePOST and handlePUT.
🧹 Nitpick comments (13)
src/lib/api/workspace-helpers.ts (2)

83-87: Fragile NextResponse detection via duck-typing.

The check 'status' in error && 'json' in error could match objects that aren't NextResponse instances (e.g., custom error objects with these properties). Consider using instanceof Response or checking for a more specific marker.

Suggested improvement
-      if (error && typeof error === 'object' && 'status' in error && 'json' in error) {
-        return error as NextResponse;
+      if (error instanceof Response) {
+        return error as NextResponse;
       }

27-46: Consider simplifying return type.

The function returns { userId: string } but the caller already has userId. Since this is a verification function, it could return void (or Promise<void>) instead, or alternatively return nothing of interest. The current return value is unused by callers.

src/app/api/workspaces/[id]/route.ts (2)

16-21: Redundant variable assignment.

const paramsPromise = params; is unnecessary since params is already a Promise. You can await it directly.

Simplified version
-  // Start independent operations in parallel
-  const paramsPromise = params;
-  const authPromise = requireAuth();
-  
-  const { id } = await paramsPromise;
-  const userId = await authPromise;
+  // Start auth in parallel with params resolution
+  const authPromise = requireAuth();
+  const { id } = await params;
+  const userId = await authPromise;

26-33: Inconsistent indentation.

Lines 26-27 have extra indentation compared to the surrounding code, suggesting copy-paste artifacts. Consider aligning with the rest of the function.

src/app/api/workspaces/[id]/snapshots/route.ts (2)

16-20: Consider parallelizing params and auth for consistency.

Other routes in this PR parallelize params and requireAuth(). For consistency:

Parallel pattern
-  const { id } = await params;
-  const userId = await requireAuth();
+  const authPromise = requireAuth();
+  const { id } = await params;
+  const userId = await authPromise;

29-36: Type safety loss with as any cast.

Casting s.state to any loses type safety. If SnapshotInfo.state has a defined type, consider using that type instead.

src/app/api/workspaces/slug/[slug]/route.ts (1)

42-46: Duplicated state metadata fallback logic.

This exact logic exists in src/app/api/workspaces/[id]/route.ts (lines 29-33). Consider extracting to a helper function if this pattern is used elsewhere.

src/app/api/workspaces/reorder/route.ts (1)

10-56: Inconsistent indentation within handlePOST.

Lines 13-54 have extra indentation (4 spaces) compared to lines 11 and 55, likely leftover from a removed try-catch block. This should be normalized for readability.

🔧 Suggested fix to normalize indentation
 async function handlePOST(request: NextRequest) {
   const userId = await requireAuth();
 
-    const body = await request.json();
-    const { workspaceIds } = body;
+  const body = await request.json();
+  const { workspaceIds } = body;
 
-    if (!Array.isArray(workspaceIds)) {
-      return NextResponse.json({ error: "workspaceIds must be an array" }, { status: 400 });
-    }
+  if (!Array.isArray(workspaceIds)) {
+    return NextResponse.json({ error: "workspaceIds must be an array" }, { status: 400 });
+  }
 
-    if (workspaceIds.length === 0) {
-      return NextResponse.json({ error: "workspaceIds array cannot be empty" }, { status: 400 });
-    }
+  if (workspaceIds.length === 0) {
+    return NextResponse.json({ error: "workspaceIds array cannot be empty" }, { status: 400 });
+  }
 
-    // Verify all workspaces belong to the user
-    const userWorkspaces = await db
-      .select({ id: workspaces.id, userId: workspaces.userId, sortOrder: workspaces.sortOrder })
-      .from(workspaces)
-      .where(inArray(workspaces.id, workspaceIds));
+  // Verify all workspaces belong to the user
+  const userWorkspaces = await db
+    .select({ id: workspaces.id, userId: workspaces.userId, sortOrder: workspaces.sortOrder })
+    .from(workspaces)
+    .where(inArray(workspaces.id, workspaceIds));
 
-    // Check that all workspaces exist and belong to the user
-    if (userWorkspaces.length !== workspaceIds.length) {
-      return NextResponse.json({ error: "Some workspaces not found" }, { status: 404 });
-    }
+  // Check that all workspaces exist and belong to the user
+  if (userWorkspaces.length !== workspaceIds.length) {
+    return NextResponse.json({ error: "Some workspaces not found" }, { status: 404 });
+  }
 
-    const allOwned = userWorkspaces.every((w) => w.userId === userId);
-    if (!allOwned) {
-      return NextResponse.json({ error: "Access denied: Only owned workspaces can be reordered" }, { status: 403 });
-    }
+  const allOwned = userWorkspaces.every((w) => w.userId === userId);
+  if (!allOwned) {
+    return NextResponse.json({ error: "Access denied: Only owned workspaces can be reordered" }, { status: 403 });
+  }
 
-    // Update sort_order for each workspace
-    for (let index = 0; index < workspaceIds.length; index++) {
-      const workspaceId = workspaceIds[index];
-      
-      await db
-        .update(workspaces)
-        .set({ sortOrder: index })
-        .where(
-          and(
-            eq(workspaces.id, workspaceId),
-            eq(workspaces.userId, userId) // Extra safety check
-          )
-        );
-    }
+  // Update sort_order for each workspace
+  for (let index = 0; index < workspaceIds.length; index++) {
+    const workspaceId = workspaceIds[index];
+    
+    await db
+      .update(workspaces)
+      .set({ sortOrder: index })
+      .where(
+        and(
+          eq(workspaces.id, workspaceId),
+          eq(workspaces.userId, userId) // Extra safety check
+        )
+      );
+  }
 
   return NextResponse.json({ success: true });
 }
src/app/api/workspaces/[id]/snapshot/route.ts (2)

15-45: LGTM on handleGET refactoring.

The parallel auth/params pattern and use of verifyWorkspaceOwnershipWithData (which returns workspace data needed for the response) is appropriate here. Minor indentation inconsistencies exist on lines 29-35 (extra indent) but the logic is correct.

Consider normalizing the indentation on lines 29-35 to match the rest of the function.


53-82: Inconsistent indentation and extra indent remnants in handlePOST.

Lines 67-75 have extra indentation, likely leftover from a removed try-catch block. The same pattern exists in handlePUT (lines 104-118).

src/app/api/workspaces/[id]/events/route.ts (3)

12-33: Timing measurement may be misleading.

authPromise is initiated on line 21, but timings.auth (lines 26-28) only measures the time spent awaiting the already-running promise, not the total authentication time. If the auth completes before paramsPromise, the measured time could be near-zero.

Consider either:

  1. Measuring from when requireAuth() is called (line 21)
  2. Removing the timing if it's not providing meaningful data

The parallel auth/params pattern itself is good for performance.


35-191: Inconsistent indentation in handleGET body.

Lines 35-189 have extra indentation (4 spaces) compared to the function declaration and return statement. This appears to be leftover from a removed try-catch block and should be normalized for consistency.


16-17: timings object is populated but never used in response.

The timings object is populated throughout both handleGET and handlePOST but is never included in the response. If this is debug instrumentation, consider either:

  1. Adding it to the response in development mode
  2. Removing the timing code if no longer needed
  3. Logging it for observability
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e477ba5 and 16a01fa.

📒 Files selected for processing (8)
  • src/app/api/workspaces/[id]/events/route.ts
  • src/app/api/workspaces/[id]/route.ts
  • src/app/api/workspaces/[id]/snapshot/route.ts
  • src/app/api/workspaces/[id]/snapshots/route.ts
  • src/app/api/workspaces/reorder/route.ts
  • src/app/api/workspaces/route.ts
  • src/app/api/workspaces/slug/[slug]/route.ts
  • src/lib/api/workspace-helpers.ts
🧰 Additional context used
🧬 Code graph analysis (7)
src/app/api/workspaces/route.ts (1)
src/lib/api/workspace-helpers.ts (2)
  • requireAuth (98-104)
  • withErrorHandling (76-93)
src/app/api/workspaces/reorder/route.ts (1)
src/lib/api/workspace-helpers.ts (2)
  • requireAuth (98-104)
  • withErrorHandling (76-93)
src/app/api/workspaces/slug/[slug]/route.ts (2)
src/lib/api/workspace-helpers.ts (2)
  • requireAuth (98-104)
  • withErrorHandling (76-93)
src/app/api/workspaces/[id]/route.ts (1)
  • GET (43-43)
src/app/api/workspaces/[id]/events/route.ts (3)
src/lib/api/workspace-helpers.ts (3)
  • requireAuth (98-104)
  • verifyWorkspaceOwnership (27-46)
  • withErrorHandling (76-93)
src/app/api/workspaces/slug/[slug]/route.ts (1)
  • GET (56-56)
src/app/api/workspaces/[id]/route.ts (1)
  • GET (43-43)
src/app/api/workspaces/[id]/snapshot/route.ts (1)
src/lib/api/workspace-helpers.ts (4)
  • requireAuth (98-104)
  • verifyWorkspaceOwnershipWithData (52-71)
  • withErrorHandling (76-93)
  • verifyWorkspaceOwnership (27-46)
src/app/api/workspaces/[id]/route.ts (1)
src/lib/api/workspace-helpers.ts (4)
  • requireAuth (98-104)
  • verifyWorkspaceOwnershipWithData (52-71)
  • withErrorHandling (76-93)
  • verifyWorkspaceOwnership (27-46)
src/app/api/workspaces/[id]/snapshots/route.ts (1)
src/lib/api/workspace-helpers.ts (3)
  • requireAuth (98-104)
  • verifyWorkspaceOwnership (27-46)
  • withErrorHandling (76-93)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: Greptile Review
🔇 Additional comments (13)
src/lib/api/workspace-helpers.ts (3)

11-21: LGTM!

Clean implementation of session retrieval with proper null handling.


52-71: LGTM!

Returns full workspace data after ownership verification - useful for routes that need the workspace record.


98-104: LGTM!

Clean authentication requirement helper that throws on failure.

src/app/api/workspaces/[id]/route.ts (2)

49-86: PATCH handler logic is correct.

The parallel execution of params, auth, and body parsing is a good optimization. The conditional update logic properly handles optional fields.

Note: Inconsistent indentation on lines 66-84 should be fixed for consistency.


95-115: LGTM!

DELETE handler correctly verifies ownership before deletion. The cascade deletion comment is helpful documentation.

src/app/api/workspaces/route.ts (2)

15-46: LGTM!

Clean implementation of workspace listing with proper authentication and result formatting.


197-203: LGTM!

Correctly returns 201 status for successful resource creation.

src/app/api/workspaces/[id]/snapshots/route.ts (1)

38-41: LGTM!

Handler correctly returns snapshots after ownership verification.

src/app/api/workspaces/slug/[slug]/route.ts (2)

23-37: Inconsistent error response compared to /api/workspaces/[id].

This route returns "Workspace not found" (404) for both non-existent workspaces and access-denied cases (since ownership is baked into the query). The /api/workspaces/[id] route distinguishes between 404 (not found) and 403 (access denied).

This inconsistency could be intentional (slug routes shouldn't reveal existence of others' workspaces) or unintentional. Consider documenting the rationale or aligning behavior.


56-57: LGTM!

Handler correctly implements workspace retrieval by slug with proper authentication and error handling wrapper.

src/app/api/workspaces/reorder/route.ts (1)

58-58: LGTM on the refactoring pattern.

The route correctly uses withErrorHandling wrapper with a descriptive route name, aligning with the PR's goal of centralizing error handling across workspace routes.

src/app/api/workspaces/[id]/events/route.ts (2)

199-233: Good use of parallel operations in handlePOST.

Starting params, requireAuth(), and request.json() in parallel (lines 207-209) before awaiting them is an effective optimization. However, ensure that if request.json() fails (e.g., invalid JSON), the error is properly caught by withErrorHandling.

The ownership check (line 232) correctly happens after authentication, ensuring the user is verified before accessing workspace data.

Note: Lines 235-313 have the same indentation inconsistency as handleGET.


193-193: LGTM on the export pattern.

Both GET and POST exports correctly use withErrorHandling with descriptive route names matching the pattern used across other workspace routes.

Also applies to: 322-322

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment thread src/app/api/workspaces/[id]/route.ts Outdated
Comment thread src/app/api/workspaces/[id]/snapshot/route.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

4 issues found across 8 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="src/app/api/workspaces/route.ts">

<violation number="1" location="src/app/api/workspaces/route.ts:16">
P1: The `session` variable is no longer defined after this refactor, but it's still referenced later in `handlePOST` to get the user's display name (`session.user.name`, `session.user.email`). The `requireAuth()` helper only returns `userId` as a string. This will silently break user name tracking in workspace events.</violation>
</file>

<file name="src/lib/api/workspace-helpers.ts">

<violation number="1" location="src/lib/api/workspace-helpers.ts:85">
P2: Use `instanceof Response` instead of duck-typing to detect thrown NextResponse objects. The current check could incorrectly match non-Response objects that happen to have `status` and `json` properties.</violation>
</file>

<file name="src/app/api/workspaces/[id]/events/route.ts">

<violation number="1" location="src/app/api/workspaces/[id]/events/route.ts:26">
P2: Timing measurement for `auth` is inaccurate because `authStart` is recorded after `requireAuth()` has already started. This measures wait time, not execution time. Move `authStart = Date.now()` before starting the promise, or remove the misleading timing metric since parallel execution makes individual timing measurement unreliable.</violation>

<violation number="2" location="src/app/api/workspaces/[id]/events/route.ts:218">
P2: Timing measurement for `bodyParse` is inaccurate because `bodyStart` is recorded after `request.json()` has already started executing. This measures wait time, not parsing time.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/app/api/workspaces/route.ts
Comment thread src/lib/api/workspace-helpers.ts Outdated
Comment thread src/app/api/workspaces/[id]/events/route.ts
Comment thread src/app/api/workspaces/[id]/events/route.ts
@urjitc

urjitc commented Jan 15, 2026

Copy link
Copy Markdown
Member Author

@greptile @CodeRabbit

@coderabbitai

coderabbitai Bot commented Jan 15, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@urjitc, hello! I'm here. How can I help you with this PR? I can:

  • Review specific files or changes
  • Answer questions about the refactoring
  • Generate tests or documentation
  • Help with any issues you're encountering
  • Provide insights on the architecture changes

What would you like me to do?

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I see you've mentioned @CodeRabbit but haven't provided a specific question or comment to respond to. This PR shows a nice refactoring of workspace API routes to improve consistency and maintainability by:

  1. Introducing helper functions in workspace-helpers.ts for common operations like authentication and authorization
  2. Standardizing error handling with the withErrorHandling wrapper
  3. Optimizing performance by parallelizing independent operations (auth, params parsing, body parsing)
  4. Reducing code duplication across all the workspace route handlers

The refactoring maintains the same functionality while making the code more maintainable and consistent. Is there something specific about this refactoring you'd like me to review or discuss?

@urjitc

urjitc commented Jan 15, 2026

Copy link
Copy Markdown
Member Author

@greptile review the pr again

@urjitc

urjitc commented Jan 15, 2026

Copy link
Copy Markdown
Member Author

@CodeRabbit review the pr again

@coderabbitai

coderabbitai Bot commented Jan 15, 2026

Copy link
Copy Markdown

@urjitc, I'll review the PR changes again for you.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@ellipsis-dev ellipsis-dev Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Important

Looks good to me! 👍

Reviewed 6ff442a in 1 minute and 36 seconds. Click for details.
  • Reviewed 64 lines of code in 4 files
  • Skipped 0 files when reviewing.
  • Skipped posting 4 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. src/app/api/workspaces/[id]/route.ts:5
  • Draft comment:
    Import now includes verifyWorkspaceOwnership; ensure that using verifyWorkspaceOwnership (for PATCH/DELETE) vs verifyWorkspaceOwnershipWithData (for GET) is intentional and consistent.
  • Reason this comment was not posted:
    Comment looked like it was already resolved.
2. src/app/api/workspaces/[id]/snapshot/route.ts:9
  • Draft comment:
    Addition of verifyWorkspaceOwnership in the import reinforces consistent auth checks; verify that GET uses the full data function while POST/PUT use the basic check.
  • Reason this comment was not posted:
    Comment looked like it was already resolved.
3. src/app/api/workspaces/route.ts:129
  • Draft comment:
    Session retrieval now uses 'await headers()' with auth.api.getSession; consider caching headers if used multiple times to avoid redundant calls.
  • Reason this comment was not posted:
    Comment looked like it was already resolved.
4. src/lib/api/workspace-helpers.ts:85
  • Draft comment:
    Refactored error check to use 'instanceof Response' for error handling; ensure that all manually thrown responses are proper Response instances.
  • Reason this comment was not posted:
    Comment looked like it was already resolved.

Workflow ID: wflow_rFf6gNlVaS1oIZLN

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 4 files (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="src/app/api/workspaces/route.ts">

<violation number="1" location="src/app/api/workspaces/route.ts:129">
P2: Duplicate session fetch. `requireAuth()` already calls `auth.api.getSession()` internally (via `getAuthenticatedUser()`). Calling it again here to get `userName` makes two auth API calls per request. Consider modifying `requireAuth()` or `getAuthenticatedUser()` to return the full session object (including `user.name` and `user.email`), then use that data here.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/app/api/workspaces/route.ts Outdated

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Additional Comments (1)

  1. src/app/api/workspaces/reorder/route.ts, line 40-53 (link)

    style: sequential updates could cause race conditions with concurrent reorder requests - use a transaction or batch update

8 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +16 to +17
const { id } = await params;
const userId = await requireAuth();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

style: missing parallelization optimization present in other routes - params and requireAuth() could be resolved concurrently

Suggested change
const { id } = await params;
const userId = await requireAuth();
const paramsPromise = params;
const authPromise = requireAuth();
const { id } = await paramsPromise;
const userId = await authPromise;

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/app/api/workspaces/[id]/snapshots/route.ts
Line: 16:17

Comment:
**style:** missing parallelization optimization present in other routes - `params` and `requireAuth()` could be resolved concurrently

```suggestion
  const paramsPromise = params;
  const authPromise = requireAuth();
  
  const { id } = await paramsPromise;
  const userId = await authPromise;
```

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

Replace duck-typing check with instanceof Response to reliably detect
thrown NextResponse errors. Also extend getAuthenticatedUser to return
user name and email, and add requireAuthWithUserInfo helper to avoid
duplicate session fetches.
Use requireAuthWithUserInfo instead of requireAuth followed by a separate
session fetch. This reduces API calls from 2 to 1 per request and fixes
the undefined session reference issue.
Move timing start markers before promise creation to accurately measure
execution time rather than just wait time. This fixes inaccurate auth
and bodyParse timing metrics.
Start params and requireAuth() promises concurrently to reduce latency,
matching the optimization pattern used in other workspace API routes.
@urjitc

urjitc commented Jan 15, 2026

Copy link
Copy Markdown
Member Author

@greptile check again

@ellipsis-dev ellipsis-dev Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Important

Looks good to me! 👍

Reviewed 70f9d7d in 1 minute and 30 seconds. Click for details.
  • Reviewed 19 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. src/app/api/workspaces/[id]/snapshots/route.ts:16
  • Draft comment:
    Consider using Promise.all to concurrently await params and requireAuth for brevity. For example: const [ { id }, userId ] = await Promise.all([params, requireAuth()]);
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 35% vs. threshold = 50% The PR author clearly made an intentional change to parallelize these operations, as evidenced by the comment "Start independent operations in parallel". The comment is suggesting a different way to achieve the same parallelization using Promise.all. This is a code quality/style suggestion. The rules say "Comments that suggest code quality refactors are good! But only if they are actionable and clear." This comment is actionable and clear. However, I need to consider if this is "obvious or unimportant". The current code works correctly and achieves parallelization. Using Promise.all would be more idiomatic and concise, but both approaches are valid. This feels like a minor stylistic preference rather than a significant improvement. The comment is actionable and provides a valid alternative that is more concise and idiomatic. The suggestion to use Promise.all is a common pattern in JavaScript/TypeScript for parallel operations and could be considered a best practice. This might be valuable feedback rather than just a trivial style preference. While Promise.all is more idiomatic, the current approach is also correct and clear. The comment is suggesting a minor refactor for brevity, which falls into a gray area. Given the rule to err on the side of deleting comments unless there's STRONG EVIDENCE they're correct and important, and considering this is more of a stylistic preference than a necessary change, it's borderline whether this adds enough value to keep. This is a valid but minor stylistic suggestion. The current code correctly achieves parallelization, and while Promise.all would be more concise, this is not a significant improvement. Given the rules emphasize removing comments that aren't clearly necessary and avoiding minor style suggestions, this comment should likely be removed.

Workflow ID: wflow_cwZlCMBogjymUgXP

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

2 issues found across 4 files (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="src/app/api/workspaces/[id]/events/route.ts">

<violation number="1" location="src/app/api/workspaces/[id]/events/route.ts:21">
P2: Timing measurement for `auth` is inaccurate. Moving `authStart` before the auth promise but keeping an intermediate `await paramsPromise` means the measurement captures `max(auth_time, params_time)` instead of the actual auth duration. Consider wrapping the async operation to measure its true duration, or moving `authStart` immediately before `await authPromise`.</violation>

<violation number="2" location="src/app/api/workspaces/[id]/events/route.ts:210">
P2: Timing measurement for `bodyParse` is inaccurate. Since `bodyStart` is captured before two other `await` statements (paramsPromise and authPromise), the measurement includes time spent waiting for those operations rather than just body parsing time.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/app/api/workspaces/[id]/events/route.ts Outdated
Comment thread src/app/api/workspaces/[id]/events/route.ts Outdated
Move timing start markers to immediately before awaiting each promise
to measure only the actual operation duration, not time spent waiting
for other parallel operations. This ensures auth and bodyParse timings
accurately reflect their individual execution times.
@sonarqubecloud

Copy link
Copy Markdown

@urjitc

urjitc commented Jan 15, 2026

Copy link
Copy Markdown
Member Author

@greptile review this pr again

@ellipsis-dev ellipsis-dev Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Important

Looks good to me! 👍

Reviewed db0cd57 in 1 minute and 33 seconds. Click for details.
  • Reviewed 38 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 3 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. src/app/api/workspaces/[id]/events/route.ts:26
  • Draft comment:
    In GET, authStart is now set after params resolution. Confirm if measuring only the actual requireAuth wait time (excluding params wait) is intentional.
  • Reason this comment was not posted:
    Comment looked like it was already resolved.
2. src/app/api/workspaces/[id]/events/route.ts:214
  • Draft comment:
    In POST, authStart is now moved to after params resolution. Ensure this change aligns with your intent for measuring requireAuth latency.
  • Reason this comment was not posted:
    Comment looked like it was already resolved.
3. src/app/api/workspaces/[id]/events/route.ts:218
  • Draft comment:
    In POST, bodyStart now starts after auth measurement. Verify if this ordering (which may underreport the full JSON parsing time) is deliberate.
  • Reason this comment was not posted:
    Comment looked like it was already resolved.

Workflow ID: wflow_PpWLavqmukqZnInG

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

@urjitc

urjitc commented Jan 15, 2026

Copy link
Copy Markdown
Member Author

@CodeRabbit review this pr again

@coderabbitai

coderabbitai Bot commented Jan 15, 2026

Copy link
Copy Markdown

@urjitc, I'll review the PR changes again.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Additional Comments (1)

  1. src/app/api/workspaces/reorder/route.ts, line 41-52 (link)

    style: sequential updates cause N database round-trips - use Promise.all or batch update for better performance

8 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +26 to +28
const authStart = Date.now();
const userId = await authPromise;
timings.auth = Date.now() - authStart;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

logic: timing measurement incorrect - measures only promise wait time, not actual auth duration since auth already started at line 21

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/app/api/workspaces/[id]/events/route.ts
Line: 26:28

Comment:
**logic:** timing measurement incorrect - measures only promise wait time, not actual auth duration since auth already started at line 21

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +11 to 13
const userId = await requireAuth();

const body = await request.json();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

style: could parallelize auth and body parsing like other routes for consistency and slight performance gain

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/app/api/workspaces/reorder/route.ts
Line: 11:13

Comment:
**style:** could parallelize auth and body parsing like other routes for consistency and slight performance gain

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

2 issues found across 1 file (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="src/app/api/workspaces/[id]/events/route.ts">

<violation number="1" location="src/app/api/workspaces/[id]/events/route.ts:26">
P2: Timing measurement is inaccurate. `authStart` is set after `requireAuth()` has already started executing (it's a promise that begins immediately). This will underreport auth time since it only measures remaining wait time, not total execution time. Move `const authStart = Date.now();` back to before `const authPromise = requireAuth();`.</violation>

<violation number="2" location="src/app/api/workspaces/[id]/events/route.ts:218">
P2: Timing measurement is inaccurate. `bodyStart` is set after `request.json()` has already started executing (it's a promise that begins immediately). This will underreport body parsing time since it only measures remaining wait time, not total execution time. Move `const bodyStart = Date.now();` back to before `const bodyPromise = request.json();`.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

const userId = await authPromise;
timings.auth = Date.now() - authStart;

const bodyStart = Date.now();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: Timing measurement is inaccurate. bodyStart is set after request.json() has already started executing (it's a promise that begins immediately). This will underreport body parsing time since it only measures remaining wait time, not total execution time. Move const bodyStart = Date.now(); back to before const bodyPromise = request.json();.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/app/api/workspaces/[id]/events/route.ts, line 218:

<comment>Timing measurement is inaccurate. `bodyStart` is set after `request.json()` has already started executing (it's a promise that begins immediately). This will underreport body parsing time since it only measures remaining wait time, not total execution time. Move `const bodyStart = Date.now();` back to before `const bodyPromise = request.json();`.</comment>

<file context>
@@ -205,17 +205,17 @@ async function handlePOST(
   const userId = await authPromise;
   timings.auth = Date.now() - authStart;
 
+  const bodyStart = Date.now();
   const body = await bodyPromise;
   timings.bodyParse = Date.now() - bodyStart;
</file context>

const paramsResolved = await paramsPromise;
const id = paramsResolved.id;

const authStart = Date.now();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: Timing measurement is inaccurate. authStart is set after requireAuth() has already started executing (it's a promise that begins immediately). This will underreport auth time since it only measures remaining wait time, not total execution time. Move const authStart = Date.now(); back to before const authPromise = requireAuth();.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/app/api/workspaces/[id]/events/route.ts, line 26:

<comment>Timing measurement is inaccurate. `authStart` is set after `requireAuth()` has already started executing (it's a promise that begins immediately). This will underreport auth time since it only measures remaining wait time, not total execution time. Move `const authStart = Date.now();` back to before `const authPromise = requireAuth();`.</comment>

<file context>
@@ -18,12 +18,12 @@ async function handleGET(
   const paramsResolved = await paramsPromise;
   const id = paramsResolved.id;
 
+  const authStart = Date.now();
   const userId = await authPromise;
   timings.auth = Date.now() - authStart;
</file context>

@urjitc
urjitc merged commit f8e60f9 into main Jan 15, 2026
9 checks passed
@urjitc
urjitc deleted the refactor/workspace-api-routes branch January 15, 2026 23:38
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Dev Board Jan 15, 2026
This was referenced Feb 3, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Feb 23, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Mar 27, 2026
This was referenced Apr 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant