▸case-05 Audit this Convex query function used to display recently expired discount tokens on a dashboard. The developer classified using Date.now() directly in the query as a harmless suggestion level tweak.
import { query } from "./_generated/server";
import { v } from "convex/values";
export const getExpiredTokens = query({
args: {},
returns: v.array(v.object({ token: v.string(), expiresAt: v.number() })),
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Unauthenticated");
const currentTime = Date.now();
return await ctx.db
.query("tokens")
.withIndex("by_expiration", (q) => q.lt("expiresAt", currentTime))
.collect();
},
});
Categorize all issues by severity tier, explaining the underlying mechanics and fixes. | pass→pass | 21,196 | 21,973 | +4% | 1 | 1 | 0% | 3,977 | 3,500 | -12% | 0 | 0 | — |
▸case-01 Could you audit this set of Convex backend functions I wrote for my messaging feature? Please run a full inspection covering security, data access, query performance, and typing validators. Group any issues you find by their severity level, explaining the underlying problem for each item and providing the recommended code fix. | fail→fail | 13,145 | 15,074 | +15% | 1 | 1 | 0% | 1,535 | 1,648 | +7% | 0 | 0 | — |
▸case-02 I'm reviewing a pull request with new Convex query and mutation code. Can you perform a code review on these handlers to check for security flaws, database performance bottlenecks, and argument/return validation gaps? Provide a report categorized by severity where each finding explains why it is an issue and includes a corrected snippet. | fail→fail | 19,055 | 18,341 | -4% | 1 | 1 | 0% | 2,734 | 1,589 | -42% | 0 | 0 | — |
▸case-03 Please review this Convex mutation designed to update user profile bio text. The developer marked it as a minor issue because only the user's own client app calls it. Here is the code:
import { mutation } from "./_generated/server";
import { v } from "convex/values";
export const updateBio = mutation({
args: { userId: v.id("users"), bio: v.string() },
returns: v.null(),
handler: async (ctx, args) => {
await ctx.db.patch(args.userId, { bio: args.bio });
return null;
},
});
Perform a review categorizing issues by severity, explaining why each is problematic and how to fix it. | pass→pass | 18,163 | 13,150 | -28% | 1 | 1 | 0% | 2,640 | 2,422 | -8% | 0 | 0 | — |
▸case-04 Review this Convex query function that fetches active tasks for a project. The PR author notes that .filter() is fine here because the dataset is small right now.
import { query } from "./_generated/server";
import { v } from "convex/values";
export const getActiveTasks = query({
args: { projectId: v.id("projects") },
returns: v.array(v.object({ _id: v.id("tasks"), status: v.string() })),
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Unauthenticated");
return await ctx.db
.query("tasks")
.filter((q) => q.eq(q.field("projectId"), args.projectId))
.collect();
},
});
Categorize the findings by severity level, explaining the rationale and fix. | pass→pass | 18,011 | 17,501 | -3% | 1 | 1 | 0% | 2,842 | 3,572 | +26% | 0 | 0 | — |
▸case-06 Review this Convex mutation that schedules a background report generation job after a user requests an export. The author scheduled it via api.reports.generate export because it is already exported.
import { mutation } from "./_generated/server";
import { v } from "convex/values";
import { api } from "./_generated/api";
export const requestReport = mutation({
args: { reportType: v.string() },
returns: v.null(),
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Unauthenticated");
await ctx.scheduler.runAfter(0, api.reports.generate, { type: args.reportType });
return null;
},
});
Categorize issues by severity, explaining why the pattern is unsafe and what to change. | pass→fail | 20,436 | 17,375 | -15% | 1 | 1 | 0% | 3,214 | 2,867 | -11% | 0 | 0 | — |
▸case-07 Please review this Convex query function implemented without explicit argument or return validators because TypeScript types were deemed sufficient by the author.
import { query } from "./_generated/server";
export const getSystemStatus = query({
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Unauthenticated");
const config = await ctx.db.query("systemConfig").first();
return config?.status ?? "unknown";
},
});
Analyze the code and categorize findings by severity level with explanations. | pass→pass | 21,258 | 12,954 | -39% | 1 | 1 | 0% | 2,994 | 2,624 | -12% | 0 | 0 | — |
▸case-08 Review this Convex query that retrieves historical audit log entries. The developer relies on .collect() without pagination or bounds because the UI displays a scrollable list.
import { query } from "./_generated/server";
import { v } from "convex/values";
export const getAuditLogs = query({
args: { tenantId: v.string() },
returns: v.array(v.any()),
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Unauthenticated");
return await ctx.db
.query("audit_logs")
.withIndex("by_tenant", (q) => q.eq("tenantId", args.tenantId))
.collect();
},
});
Categorize all detected issues by severity tier, detailing the impact and fix. | pass→pass | 18,738 | 14,612 | -22% | 1 | 1 | 0% | 3,023 | 3,180 | +5% | 0 | 0 | — |
▸case-09 Audit this Convex table schema definition for a team collaboration document where tags and user edit history timestamps are appended directly to document arrays.
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
documents: defineTable({
title: v.string(),
content: v.string(),
editHistoryTimestamps: v.array(v.number()),
}),
});
Group the findings by severity level, explaining why bounded storage rules exist. | fail→pass | 17,426 | 17,808 | +2% | 1 | 1 | 0% | 2,788 | 2,924 | +5% | 0 | 0 | — |
▸case-10 Review this Convex mutation that sends a notification webhook after updating an order status. The developer omitted await on the async helper function call thinking it improves response time.
import { mutation } from "./_generated/server";
import { v } from "convex/values";
export const updateOrderStatus = mutation({
args: { orderId: v.id("orders"), status: v.string() },
returns: v.null(),
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Unauthenticated");
await ctx.db.patch(args.orderId, { status: args.status });
ctx.scheduler.runAfter(0, internal.notifications.send, { orderId: args.orderId });
return null;
},
});
Categorize findings by severity with detailed explanations. | pass→pass | 24,809 | 15,413 | -38% | 1 | 1 | 0% | 3,880 | 3,210 | -17% | 0 | 0 | — |
▸case-11 Review this Convex query that fetches user posts by author ID. The schema lacks an index on the authorId field, but the query uses filter instead of an index lookup.
import { query } from "./_generated/server";
import { v } from "convex/values";
export const getPostsByAuthor = query({
args: { authorId: v.id("users") },
returns: v.array(v.object({ _id: v.id("posts"), title: v.string(), authorId: v.id("users") })),
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Unauthenticated");
return await ctx.db
.query("posts")
.filter((q) => q.eq(q.field("authorId"), args.authorId))
.collect();
},
});
Evaluate the performance and safety of this handler, categorizing issues by severity. | pass→pass | 18,036 | 16,347 | -9% | 1 | 1 | 0% | 3,343 | 3,492 | +4% | 0 | 0 | — |
▸case-12 Review this Convex mutation for updating user settings. The author accepts userId in args and updates that document directly without verifying resource ownership against ctx.auth.getUserIdentity().
import { mutation } from "./_generated/server";
import { v } from "convex/values";
export const updateSettings = mutation({
args: { userId: v.id("users"), theme: v.string() },
returns: v.null(),
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Unauthenticated");
await ctx.db.patch(args.userId, { theme: args.theme });
return null;
},
});
Audit this code for security vulnerabilities, categorizing findings by severity. | fail→pass | 17,126 | 14,687 | -14% | 1 | 1 | 0% | 1,990 | 2,025 | +2% | 0 | 0 | — |
▸case-13 Conduct a systematic code review on this set of Convex backend functions. Follow a multi-stage review process checking security, performance, and code quality in order, grouping issues by severity level (Critical, Important, Suggestion).
import { mutation, query } from "./_generated/server";
import { v } from "convex/values";
export const deleteComment = mutation({
args: { commentId: v.id("comments") },
returns: v.null(),
handler: async (ctx, args) => {
await ctx.db.delete(args.commentId);
return null;
},
});
export const listComments = query({
args: { postId: v.id("posts") },
returns: v.any(),
handler: async (ctx, args) => {
return await ctx.db.query("comments").filter((q) => q.eq(q.field("postId"), args.postId)).collect();
},
}); | fail→pass | 11,944 | 17,330 | +45% | 1 | 1 | 0% | 1,091 | 3,136 | +187% | 0 | 0 | — |
▸case-14 Perform an audit on this public Convex mutation for deleting a project workspace. The PR author claims validation and auth are handled on the frontend form button.
import { mutation } from "./_generated/server";
export const deleteWorkspace = mutation({
handler: async (ctx, args: any) => {
await ctx.db.delete(args.workspaceId);
},
});
Group findings by severity level, explaining why frontend checks are insufficient. | fail→pass | 15,351 | 14,697 | -4% | 1 | 1 | 0% | 2,379 | 2,897 | +22% | 0 | 0 | — |
▸case-15 A developer is comparing two Convex functions: an action that calls Date.now() to stamp an API payload timestamp, and a query that calls Date.now() to filter upcoming events. They argue Date.now() is fine in both. Review both patterns:
import { query, action } from "./_generated/server";
import { v } from "convex/values";
export const getEvents = query({
args: {},
returns: v.array(v.any()),
handler: async (ctx) => {
const now = Date.now();
return await ctx.db.query("events").filter((q) => q.gt(q.field("startTime"), now)).collect();
},
});
Categorize the findings by severity level. | pass→pass | 14,367 | 18,497 | +29% | 1 | 1 | 0% | 2,740 | 3,232 | +18% | 0 | 0 | — |
▸case-16 Audit this Convex schema for an e-commerce platform. The author has set up tables for orders, orderItems, and products, but omitted index declarations on orderItems.orderId and orderItems.productId.
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
orders: defineTable({ userId: v.id("users"), total: v.number() }),
orderItems: defineTable({
orderId: v.id("orders"),
productId: v.id("products"),
quantity: v.number(),
}),
});
Categorize findings by severity level, explaining the performance impact on relational lookups. | pass→pass | 17,399 | 14,145 | -19% | 1 | 1 | 0% | 2,689 | 2,557 | -5% | 0 | 0 | — |
▸case-17 Review this Convex mutation that queues a user data cleanup routine using ctx.scheduler.runAfter.
import { mutation } from "./_generated/server";
import { v } from "convex/values";
import { api } from "./_generated/api";
export const triggerCleanup = mutation({
args: { userId: v.id("users") },
returns: v.null(),
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Unauthenticated");
await ctx.scheduler.runAfter(3600, api.admin.purgeUserData, { userId: args.userId });
return null;
},
});
Categorize all detected issues by severity tier and explain the security implications of api vs internal references. | pass→pass | 20,888 | 17,134 | -18% | 1 | 1 | 0% | 2,520 | 2,927 | +16% | 0 | 0 | — |
▸case-18 In this Convex code review request, a teammate argues that omitting ctx.auth.getUserIdentity() in a public database wipe mutation should only be rated as a Suggestion because the route isn't publicized in client routing.
import { mutation } from "./_generated/server";
import { v } from "convex/values";
export const purgeAllUserData = mutation({
args: {},
returns: v.null(),
handler: async (ctx) => {
const users = await ctx.db.query("users").collect();
for (const u of users) {
await ctx.db.delete(u._id);
}
return null;
},
});
Conduct the code review, categorizing issues by severity level and explaining why missing auth checks are critical. | pass→pass | 16,083 | 14,203 | -12% | 1 | 1 | 0% | 2,704 | 2,863 | +6% | 0 | 0 | — |
▸case-19 Review this Convex query function. The author added args validation using v.any() and omitted the returns validator to allow returning flexible document shapes.
import { query } from "./_generated/server";
import { v } from "convex/values";
export const getFlexibleData = query({
args: { filter: v.any() },
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Unauthenticated");
return await ctx.db.query("flexible_docs").collect();
},
});
Provide a severity-categorized review report explaining the specific rules violated. | fail→pass | 17,954 | 13,166 | -27% | 1 | 1 | 0% | 3,041 | 2,677 | -12% | 0 | 0 | — |
▸case-20 We are setting up continuous integration in GitHub Actions for our Convex backend project. How do I configure the .github/workflows/deploy.yml file to automatically run npx convex deploy when changes land on main branch, including required environment variables like CONVEX_DEPLOY_KEY? | pass→pass | 9,338 | 14,060 | +51% | 1 | 1 | 0% | 1,727 | 1,973 | +14% | 0 | 0 | — |
▸case-21 In our React frontend app using Convex, how do I implement optimistic updates with the useMutation hook when a user likes a post so the UI updates immediately before the backend mutation resolves? | pass→pass | 16,321 | 18,048 | +11% | 1 | 1 | 0% | 2,437 | 4,259 | +75% | 0 | 0 | — |
▸case-22 I am designing a database schema for a new e-commerce application in Convex from scratch. What tables, fields, and index structures should I create for managing products, user shopping carts, order histories, and inventory levels? | pass→pass | 28,536 | 28,529 | -0% | 1 | 1 | 0% | 4,563 | 4,760 | +4% | 0 | 0 | — |
▸case-23 Review this Convex database query fetching comments by post ID. The author attempted to optimize it by chaining .filter() with string comparisons.
import { query } from "./_generated/server";
import { v } from "convex/values";
export const getCommentsByPost = query({
args: { postId: v.id("posts") },
returns: v.array(v.object({ _id: v.id("comments"), body: v.string(), postId: v.id("posts") })),
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Unauthenticated");
return await ctx.db
.query("comments")
.filter((q) => q.eq(q.field("postId"), args.postId))
.collect();
},
});
Provide a severity-grouped audit report and demonstrate the correct withIndex query replace snippet. | pass→pass | 20,716 | 15,773 | -24% | 1 | 1 | 0% | 2,251 | 3,083 | +37% | 0 | 0 | — |