Review code for quality, security, performance, and best practices. Use when reviewing changes before commit, auditing code for issues, or suggesting improvements.
any unless necessary)// Bad: No validation
async function createUser(data: any) {
await prisma.user.create({ data });
}
// Good: Zod validation
import { z } from 'zod';
const userSchema = z.object({
email: z.string().email(),
name: z.string().min(2).max(100),
});
async function createUser(data: unknown) {
const validated = userSchema.parse(data);
await prisma.user.create({ data: validated });
}
// Bad: String concatenation
const query = `SELECT * FROM users WHERE id = '${userId}'`;
// Good: Parameterized query (Prisma handles this)
const user = await prisma.user.findUnique({ where: { id: userId } });
// Good: Raw query with parameters
const users = await prisma.$queryRaw`SELECT * FROM users WHERE id = ${userId}`;
// Bad: dangerouslySetInnerHTML without sanitization
<div dangerouslySetInnerHTML={{ __html: userInput }} />
// Good: Use text content (auto-escaped)
<div>{userInput}</div>
// Good: Sanitize if HTML needed
import DOMPurify from 'dompurify';
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />
// Bad: N+1 queries
const users = await prisma.user.findMany();
for (const user of users) {
const posts = await prisma.post.findMany({ where: { authorId: user.id } });
}
// Good: Include related data
const users = await prisma.user.findMany({
include: { posts: true },
});
// Bad: New object/array on every render
function Component() {
return <Child style={{ color: 'red' }} items={[1, 2, 3]} />;
}
// Good: Memoize or define outside
const style = { color: 'red' };
const items = [1, 2, 3];
function Component() {
return <Child style={style} items={items} />;
}
// Good: useMemo for computed values
function Component({ data }) {
const processed = useMemo(() => expensiveProcess(data), [data]);
return <Child data={processed} />;
}
// schema.prisma - Add indexes for frequently queried fields
model Post {
id String @id @default(cuid())
title String
authorId String
createdAt DateTime @default(now())
@@index([authorId])
@@index([createdAt])
}
// Bad: Function does too much
async function handleUserSubmit(formData: FormData) {
// Validates
// Creates user
// Sends email
// Updates analytics
// Logs event
}
// Good: Separated concerns
async function handleUserSubmit(formData: FormData) {
const data = validateUserData(formData);
const user = await createUser(data);
await sendWelcomeEmail(user);
trackUserSignup(user);
}
// Bad
const d = new Date();
const u = users.filter(x => x.a);
// Good
const currentDate = new Date();
const activeUsers = users.filter(user => user.isActive);
## Code Review: [Feature/File Name]
### Summary
Brief overview of changes and overall assessment.
### Issues Found
1. **[Severity: High/Medium/Low]** Description
- Location: `file.ts:line`
- Suggestion: How to fix
### Suggestions
- Performance: ...
- Code quality: ...
- Security: ...
### Approved: Yes/No (with conditions)
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer