Skip to content

Conversation

@rossmanko
Copy link
Contributor

@rossmanko rossmanko commented Jan 19, 2026

Summary by CodeRabbit

  • New Features

    • Added new UI primitives: dialogs, dropdowns, labels, popovers, switches, tooltips.
  • Performance Improvements

    • Direct file lookup by storage ID for faster access.
    • Batched, parallel enrichment of chats to reduce per-item lookups.
  • Bug Fixes

    • Stricter file ownership validation that correctly returns not-found when appropriate.
  • Chores

    • Updated many dependencies to newer stable versions.

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

rossmanko and others added 2 commits January 19, 2026 09:57
Replace O(n) query that fetched all user files and filtered in JS
with O(1) direct index lookup by storage_id.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Jan 19, 2026

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

Project Deployment Review Updated (UTC)
hackerai Ready Ready Preview, Comment Jan 19, 2026 10:41pm

Request Review

@coderabbitai
Copy link

coderabbitai bot commented Jan 19, 2026

📝 Walkthrough

Walkthrough

Replace scan-based user file lookup with a direct by_storage_id index query, add explicit existence and ownership checks before generating signed S3 URLs, batch-fetch branched chats to avoid per-item DB awaits, and bump many dependencies including Radix UI packages.

Changes

Cohort / File(s) Summary
File storage / schema
convex/fileStorage.ts, convex/schema.ts
Add by_storage_id index to files; change file retrieval to query by_storage_id and validate existence + ownership; throw FILE_NOT_FOUND on miss instead of proceeding.
Chats batching
convex/chats.ts
Replace per-chat async enrichment with batched fetch of branched chats and a lookup map to apply branched_from_title without per-item awaits.
Dependencies
package.json
Bump many dependencies and devDependencies; add Radix UI packages. No exported API signature changes.

Sequence Diagram(s)

sequenceDiagram
  participant Client as Client
  participant Convex as Convex Function
  participant DB as Database (files table)
  participant S3 as S3 / Storage Service

  Client->>Convex: request getFileDownloadUrl(storage_id)
  Convex->>DB: query files by_storage_id index (storage_id)
  DB-->>Convex: file record or null
  alt file found and owner matches
    Convex->>S3: generate signed URL for `s3_key`
    S3-->>Convex: signed URL
    Convex-->>Client: return signed URL
  else not found or ownership mismatch
    Convex-->>Client: throw FILE_NOT_FOUND
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I hopped the index, swift and spry,
Found the file with a single eye.
Owner checked, the link unfurled,
Batched the chats, then leapt through the world.
🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The pull request title "Daily branch 2026 01 19" is vague and generic, using a date-based naming convention that does not convey meaningful information about the actual changes made. Revise the title to clearly summarize the main changes, such as "Optimize file storage lookup and batch chat enrichment" or similar descriptive phrasing that reflects the actual code modifications.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
  • 📝 Generate docstrings

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
package.json (1)

46-109: Address breaking changes in Stripe v20 and AWS SDK v3 upgrades.

The upgrades introduce breaking changes that require code updates:

  • Stripe Node.js v20: API version pinned to 2025-12-15.clover; resource namespaces (V2.Core, Account/AccountPerson/AccountToken) restructured; method and field names changed. Update import statements and type signatures; audit all Stripe API call sites and ensure call signatures match the v20 schema.

  • AWS SDK v3 (@aws-sdk/client-s3, @aws-sdk/s3-request-presigner): Modular package structure changed; presigner moved to separate package with new Command/Client pattern (getSignedUrl signature changed); PutObject parameter handling differs (signature mismatches possible with ContentDisposition, ServerSideEncryption, ACL, StorageClass); Node.js 16.x support dropped in newer v3 versions. Verify S3 upload flow end-to-end, ensure client upload headers match those in presigned URL generation, and confirm Node.js runtime meets SDK engine requirements.

Next.js 16.1.3 and PostHog-js v1.329.0 contain only bug fixes and no breaking changes.

rossmanko and others added 2 commits January 19, 2026 17:16
- getUserChats: batch fetch branched chat titles using Promise.all and Map
  lookup instead of N+1 individual queries per branched chat
- deleteAllChats: batch fetch messages, files, and summaries in parallel
  instead of nested sequential loops, reducing ~10k queries to ~200

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Batch fetch branched chat titles using Promise.all and Map lookup
instead of N+1 individual queries per branched chat in paginated results.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@convex/chats.ts`:
- Around line 741-767: The current code batches all chats with userChats ->
Promise.all(... .collect()) and then does Promise.all(fileIds.map(id =>
ctx.db.get(id))), which can exceed Convex read/memory and per-mutation call
limits; replace unbounded .collect() and Promise.all usage by streaming queries
with for await (const row of query) or using query.paginate() per chat to
accumulate messages without loading everything into memory, and limit concurrent
db.get calls (e.g., batch fileIds or use a bounded concurrency worker) when
building fileMap; update the blocks around allMessagesPerChat, the .collect()
call on ctx.db.query("messages").withIndex("by_chat_id", ...) and the files =
await Promise.all(fileIds.map(... ctx.db.get ...)) to use streaming/pagination
and bounded batching to avoid hitting Convex limits.

rossmanko and others added 2 commits January 19, 2026 17:36
Process chats in chunks of 5 to stay under Convex's 16MB single-function
read limit. Still batches file/message fetches within each chunk for efficiency.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The optimized versions caused errors. Reverting to the stable
original implementation that processes chats sequentially.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
convex/chats.ts (1)

452-519: Add a returns validator for getUserChats.

The getUserChats query function (line 452) omits a returns validator, which is required for all Convex functions per coding guidelines. Add the return schema to match the paginated chat shape with the enriched branched_from_title field.

Suggested fix
 export const getUserChats = query({
   args: {
     paginationOpts: paginationOptsValidator,
   },
+  returns: v.object({
+    page: v.array(
+      v.object({
+        _id: v.id("chats"),
+        _creationTime: v.number(),
+        id: v.string(),
+        title: v.string(),
+        user_id: v.string(),
+        finish_reason: v.optional(v.string()),
+        active_stream_id: v.optional(v.string()),
+        canceled_at: v.optional(v.number()),
+        default_model_slug: v.optional(
+          v.union(v.literal("ask"), v.literal("agent")),
+        ),
+        todos: v.optional(
+          v.array(
+            v.object({
+              id: v.string(),
+              content: v.string(),
+              status: v.union(
+                v.literal("pending"),
+                v.literal("in_progress"),
+                v.literal("completed"),
+                v.literal("cancelled"),
+              ),
+              sourceMessageId: v.optional(v.string()),
+            }),
+          ),
+        ),
+        branched_from_chat_id: v.optional(v.string()),
+        branched_from_title: v.optional(v.string()),
+        latest_summary_id: v.optional(v.id("chat_summaries")),
+        share_id: v.optional(v.string()),
+        share_date: v.optional(v.number()),
+        update_time: v.number(),
+      }),
+    ),
+    isDone: v.boolean(),
+    continueCursor: v.string(),
+  }),
   handler: async (ctx, args) => {

@rossmanko rossmanko merged commit a054f6e into main Jan 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants