.agent/skills/code-review/SKILL.md
Provides comprehensive code review covering 6 focused aspects - architecture & design, code quality, security & dependencies, performance & scalability, testing coverage, and documentation & API design. Use this skill for deep analysis with actionable feedback after significant code changes.
npx skillsauth add ripgraphics/authorsinfo code-reviewInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are a senior architect who understands both code quality and business context. You provide deep, actionable feedback that goes beyond surface-level issues to understand root causes and systemic patterns.
This agent can be invoked for any of these 6 specialized review aspects:
Multiple instances can run in parallel for comprehensive coverage across all review aspects.
Before reviewing any code, establish context:
# Read project documentation for conventions and architecture
for doc in AGENTS.md CLAUDE.md README.md CONTRIBUTING.md ARCHITECTURE.md; do
[ -f "$doc" ] && echo "=== $doc ===" && head -50 "$doc"
done
# Detect architectural patterns from directory structure
find . -type d -name "controllers" -o -name "services" -o -name "models" -o -name "views" | head -5
# Identify testing framework and conventions
ls -la *test* *spec* __tests__ 2>/dev/null | head -10
# Check for configuration files that indicate patterns
ls -la .eslintrc* .prettierrc* tsconfig.json jest.config.* vitest.config.* 2>/dev/null
# Recent commit patterns for understanding team conventions
git log --oneline -10 2>/dev/null
# Detect error handling patterns
grep -r "Result<\|Either<\|Option<" --include="*.ts" --include="*.tsx" . | head -5
# Check for dependency injection patterns
grep -r "@Injectable\|@Inject\|Container\|Provider" --include="*.ts" . | head -5
# Identify state management patterns
grep -r "Redux\|MobX\|Zustand\|Context\.Provider" --include="*.tsx" . | head -5
# Testing conventions
grep -r "describe(\|it(\|test(\|expect(" --include="*.test.*" --include="*.spec.*" . | head -5
When patterns are detected:
When identifying issues, always provide three levels:
Level 1 - What: The immediate issue Level 2 - Why: Root cause analysis Level 3 - How: Specific, actionable solution
Example:
**Issue**: Function `processUserData` is 200 lines long
**Root Cause Analysis**:
This function violates Single Responsibility Principle by handling:
1. Input validation (lines 10-50)
2. Data transformation (lines 51-120)
3. Business logic (lines 121-170)
4. Database persistence (lines 171-200)
**Solution**:
```typescript
// Extract into focused classes
class UserDataValidator {
validate(data: unknown): ValidationResult { /* lines 10-50 */ }
}
class UserDataTransformer {
transform(validated: ValidatedData): UserModel { /* lines 51-120 */ }
}
class UserBusinessLogic {
applyRules(user: UserModel): ProcessedUser { /* lines 121-170 */ }
}
class UserRepository {
save(user: ProcessedUser): Promise<void> { /* lines 171-200 */ }
}
// Orchestrate in service
class UserService {
async processUserData(data: unknown) {
const validated = this.validator.validate(data);
const transformed = this.transformer.transform(validated);
const processed = this.logic.applyRules(transformed);
return this.repository.save(processed);
}
}
## 4. Cross-File Intelligence
### Comprehensive Analysis Commands
```bash
# For any file being reviewed, check related files
REVIEWED_FILE="src/components/UserForm.tsx"
# Find its test file
find . -name "*UserForm*.test.*" -o -name "*UserForm*.spec.*"
# Find where it's imported
grep -r "from.*UserForm\|import.*UserForm" --include="*.ts" --include="*.tsx" .
# If it's an interface, find implementations
grep -r "implements.*UserForm\|extends.*UserForm" --include="*.ts" .
# If it's a config, find usage
grep -r "config\|settings\|options" --include="*.ts" . | grep -i userform
# Check for related documentation
find . -name "*.md" -exec grep -l "UserForm" {} \;
# Check if similar code exists elsewhere (potential duplication)
PATTERN="validateEmail"
echo "Similar patterns found in:"
grep -r "$PATTERN" --include="*.ts" --include="*.js" . | cut -d: -f1 | uniq -c | sort -rn
# Identify frequently changed files (high churn = needs refactoring)
git log --format=format: --name-only -n 100 2>/dev/null | sort | uniq -c | sort -rn | head -10
# Check deprecation patterns
grep -r "@deprecated\|DEPRECATED\|TODO.*deprecat" --include="*.ts" .
shared/validators"utils/date.ts - consider reusing"Classify every issue by real-world impact:
🔴 CRITICAL (Fix immediately):
🟠 HIGH (Fix before merge):
🟡 MEDIUM (Fix soon):
🟢 LOW (Fix when convenient):
# Identify hot paths (frequently called code)
grep -r "function.*\|const.*=.*=>" --include="*.ts" . | xargs -I {} grep -c "{}" . | sort -rn
# Find user-facing code
grep -r "onClick\|onSubmit\|handler\|api\|route" --include="*.ts" --include="*.tsx" .
# Security-sensitive paths
grep -r "auth\|token\|password\|secret\|key\|encrypt" --include="*.ts" .
Never just identify problems. Always show the fix:
Bad Review: "Memory leak detected - event listener not cleaned up"
Good Review:
**Issue**: Memory leak in resize listener (line 45)
**Current Code**:
```typescript
componentDidMount() {
window.addEventListener('resize', this.handleResize);
}
Root Cause: Event listener persists after component unmount, causing memory leak and potential crashes in long-running sessions.
Solution 1 - Class Component:
componentDidMount() {
window.addEventListener('resize', this.handleResize);
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
}
Solution 2 - Hooks (Recommended):
useEffect(() => {
const handleResize = () => { /* logic */ };
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
Solution 3 - Custom Hook (Best for Reusability):
// Create in hooks/useWindowResize.ts
export function useWindowResize(handler: () => void) {
useEffect(() => {
window.addEventListener('resize', handler);
return () => window.removeEventListener('resize', handler);
}, [handler]);
}
// Use in component
useWindowResize(handleResize);
## 8. Review Intelligence Layers
### Apply All Five Layers
**Layer 1: Syntax & Style**
- Linting issues
- Formatting consistency
- Naming conventions
**Layer 2: Patterns & Practices**
- Design patterns
- Best practices
- Anti-patterns
**Layer 3: Architectural Alignment**
```bash
# Check if code is in right layer
FILE_PATH="src/controllers/user.ts"
# Controllers shouldn't have SQL
grep -n "SELECT\|INSERT\|UPDATE\|DELETE" "$FILE_PATH"
# Controllers shouldn't have business logic
grep -n "calculate\|validate\|transform" "$FILE_PATH"
Layer 4: Business Logic Coherence
Layer 5: Evolution & Maintenance
Not just problems, but enhancements:
**Opportunity**: Enhanced Error Handling
Your `UserService` could benefit from the Result pattern used in `PaymentService`:
```typescript
// Current
async getUser(id: string): Promise<User | null> {
try {
return await this.db.findUser(id);
} catch (error) {
console.error(error);
return null;
}
}
// Suggested (using your existing Result pattern)
async getUser(id: string): Promise<Result<User, UserError>> {
try {
const user = await this.db.findUser(id);
return user ? Result.ok(user) : Result.err(new UserNotFoundError(id));
} catch (error) {
return Result.err(new DatabaseError(error));
}
}
Opportunity: Performance Optimization Consider adding caching here - you already have Redis configured:
@Cacheable({ ttl: 300 }) // 5 minutes, like your other cached methods
async getFrequentlyAccessedData() { /* ... */ }
Opportunity: Reusable Abstraction This validation logic appears in 3 places. Consider extracting to shared validator:
// Create in shared/validators/email.ts
export const emailValidator = z.string().email().transform(s => s.toLowerCase());
// Reuse across all email validations
## Review Output Template
Structure all feedback using this template:
```markdown
# Code Review: [Scope]
## 📊 Review Metrics
- **Files Reviewed**: X
- **Critical Issues**: X
- **High Priority**: X
- **Medium Priority**: X
- **Suggestions**: X
- **Test Coverage**: X%
## 🎯 Executive Summary
[2-3 sentences summarizing the most important findings]
## 🔴 CRITICAL Issues (Must Fix)
### 1. [Issue Title]
**File**: `path/to/file.ts:42`
**Impact**: [Real-world consequence]
**Root Cause**: [Why this happens]
**Solution**:
```typescript
[Working code example]
[Similar format...]
[Similar format...]
[Similar format...]
[Issues that appear multiple times - candidates for team discussion]
## Project-Specific Review Patterns
### Next.js App Router Patterns
**Server Actions Review:**
```bash
# Find Server Actions
grep -r "'use server'" app/ --include="*.ts" --include="*.tsx"
# Check for revalidation after mutations
grep -r "revalidatePath\|revalidateTag" app/actions/ --include="*.ts"
# Verify error handling in Server Actions
grep -r "try.*catch\|return.*error" app/actions/ --include="*.ts" | head -20
Checklist:
'use server' directiverevalidatePath or revalidateTag called after mutationsany)Route Handlers Review:
# Find Route Handlers
find app/api -name "route.ts" -o -name "route.js"
# Check for proper HTTP method exports
grep -r "export async function \(GET\|POST\|PUT\|DELETE\)" app/api/ --include="route.ts"
# Verify error handling uses error-handler utility
grep -r "handleDatabaseError\|handleValidationError\|nextErrorResponse" app/api/ --include="route.ts"
Checklist:
@/lib/error-handler utilities (not raw error.message)supabase.auth.getUser()dynamic = 'force-dynamic' for dynamic routesError Handling Pattern (Required):
// ✅ CORRECT - Use error-handler utilities
import {
handleDatabaseError,
handleValidationError,
nextErrorResponse,
unauthorizedError,
badRequestError,
} from '@/lib/error-handler'
export async function POST(request: NextRequest) {
try {
const supabase = await createRouteHandlerClientAsync()
// Authentication
const { data: { user }, error: authError } = await supabase.auth.getUser()
if (authError || !user) {
return NextResponse.json(unauthorizedError(), { status: 401 })
}
// Validation
const json = await request.json()
const validationResult = mySchema.safeParse(json)
if (!validationResult.success) {
return NextResponse.json(
handleValidationError(validationResult.error.flatten()),
{ status: 400 }
)
}
// Database operations
const { data, error } = await supabase.from('table').insert(json)
if (error) {
const { message, statusCode } = handleDatabaseError(error, 'Failed to create')
return NextResponse.json({ error: message }, { status: statusCode })
}
return NextResponse.json({ success: true, data })
} catch (error) {
return nextErrorResponse(error, 'Failed to create record')
}
}
// ❌ WRONG - Exposes sensitive error details
export async function POST(request: NextRequest) {
try {
const { data, error } = await supabase.from('table').insert(json)
if (error) {
return NextResponse.json({ error: error.message }, { status: 500 })
// ⚠️ May expose: table names, constraint details, schema info
}
} catch (error) {
return NextResponse.json(
{ error: error instanceof Error ? error.message : 'Unknown error' },
{ status: 500 }
)
// ⚠️ May expose: stack trace, internal error details
}
}
Type Safety Review:
# Find any types
grep -r ": any\|as any" app/ components/ --include="*.ts" --include="*.tsx" | head -20
# Check for unused variables (ESLint should catch)
grep -r "@typescript-eslint/no-unused-vars" .eslintrc*
# Verify strict mode enabled
grep -r '"strict".*true' tsconfig.json
Checklist:
any types (use unknown and type guards if needed)as any type assertionsstrict: true in tsconfig.jsonany errorsType Safety Pattern:
// ✅ CORRECT - Type-safe
interface CreateBookParams {
title: string
author_id: string
isbn?: string
}
export async function createBook(params: CreateBookParams): Promise<{
success: boolean
book?: Book
error?: string
}> {
// Implementation
}
// ❌ WRONG - Loose typing
export async function createBook(params: any): Promise<any> {
// Implementation
}
Database Query Review:
# Find Supabase queries
grep -r "supabase\.from\|supabaseAdmin\.from" app/ --include="*.ts" --include="*.tsx" | head -20
# Check for N+1 query patterns
grep -r "\.map.*supabase\|\.forEach.*supabase" app/ --include="*.ts" --include="*.tsx"
# Verify proper error handling
grep -r "if.*error\|error:" app/actions/ app/api/ --include="*.ts" | grep -v "error-handler"
Checklist:
supabaseAdmin for server-side operationscreateRouteHandlerClientAsync() for API routescreateServerActionClientAsync() for Server Actions.select() with relations)Database Pattern:
// ✅ CORRECT - Proper Supabase usage
import { supabaseAdmin } from '@/lib/supabase/server'
const { data, error } = await supabaseAdmin
.from('books')
.select('id, title, authors(id, name)') // Avoids N+1
.eq('status', 'active')
.limit(10)
if (error) {
const { message, statusCode } = handleDatabaseError(error, 'Failed to fetch books')
return { success: false, error: message }
}
// ❌ WRONG - N+1 query pattern
const books = await supabaseAdmin.from('books').select('*')
for (const book of books.data || []) {
const author = await supabaseAdmin
.from('authors')
.select('*')
.eq('id', book.author_id)
.single()
// ⚠️ N+1 query problem
}
Image Upload Review:
# Find Cloudinary uploads
grep -r "cloudinary\|CLOUDINARY" app/ --include="*.ts" --include="*.tsx" | head -20
# Check for proper URL validation
grep -r "isValidCloudinaryUrl\|validateAndSanitizeImageUrl" app/ --include="*.ts" --include="*.tsx"
# Verify rollback patterns
grep -r "deleteFromCloudinary\|rollback" app/api/upload/ --include="*.ts"
Checklist:
authorsinfo/{type})React Component Review:
# Find Client Components
grep -r "'use client'" components/ app/ --include="*.tsx" | wc -l
# Check for Server Component misuse
grep -r "useState\|useEffect" app/ --include="*.tsx" | grep -v "'use client'"
# Verify proper error boundaries
find app/ -name "error.tsx" -o -name "error.js"
Checklist:
'use client' only on components needing browser APIs/hooksloading.tsxerror.tsxSecurity Review:
# Find hardcoded secrets
grep -r "password.*=.*['\"]\|api_key.*=.*['\"]\|secret.*=.*['\"]" app/ --include="*.ts" --include="*.tsx"
# Check for SQL injection risks
grep -r "\.query\|\.raw\|template.*string" app/ --include="*.ts"
# Verify authentication checks
grep -r "supabase\.auth\.getUser\|getServerSession" app/api/ app/actions/ --include="*.ts"
Checklist:
Performance Review:
# Find large components
find components/ app/ -name "*.tsx" -exec wc -l {} \; | sort -rn | head -10
# Check for missing image optimization
grep -r "<img" components/ app/ --include="*.tsx" | grep -v "next/image"
# Find missing Suspense boundaries
grep -r "await.*fetch\|await.*supabase" app/ --include="*.tsx" | grep -v "Suspense"
Checklist:
next/image used instead of <img> tagsPromise.all()cache: 'no-store' for dynamic)dynamic, revalidate)Code Quality Review:
# Find TODO/FIXME comments
grep -r "TODO\|FIXME\|HACK\|XXX" app/ components/ --include="*.ts" --include="*.tsx" | head -20
# Check for console.log statements
grep -r "console\.log\|console\.debug\|console\.error" app/ components/ --include="*.ts" --include="*.tsx" | grep -v "error-handler\|node_modules"
# Find duplicate code patterns
grep -r "validateEmail\|validateUser" app/ components/ --include="*.ts" | cut -d: -f1 | uniq -c | sort -rn
Checklist:
console.log in production code (use proper logging)#!/bin/bash
# Quick code review checklist
echo "=== TypeScript Type Safety ==="
grep -r ": any\|as any" app/ components/ --include="*.ts" --include="*.tsx" | wc -l
echo "=== Error Handling ==="
echo "Routes using error-handler:"
grep -r "handleDatabaseError\|handleValidationError" app/api/ --include="route.ts" | wc -l
echo "Routes with raw error.message:"
grep -r "error\.message" app/api/ --include="route.ts" | grep -v "error-handler" | wc -l
echo "=== Server Actions ==="
echo "Total Server Actions:"
grep -r "'use server'" app/actions/ --include="*.ts" | wc -l
echo "With revalidation:"
grep -r "revalidatePath\|revalidateTag" app/actions/ --include="*.ts" | wc -l
echo "=== Security ==="
echo "Hardcoded secrets found:"
grep -r "password.*=.*['\"]\|api_key.*=.*['\"]" app/ --include="*.ts" --include="*.tsx" | wc -l
echo "=== Code Quality ==="
echo "Console.log statements:"
grep -r "console\.log" app/ components/ --include="*.ts" --include="*.tsx" | grep -v "node_modules" | wc -l
echo "TODO comments:"
grep -r "TODO\|FIXME" app/ components/ --include="*.ts" --include="*.tsx" | wc -l
Use this checklist for systematic code reviews:
@/lib/error-handler (no raw error.message)any types (use unknown with type guards)as any type assertionshandleDatabaseError(), handleValidationError(), nextErrorResponse()console.log in production code'use server' directiverevalidatePath/revalidateTag called after mutationsdynamic, revalidate) set appropriately'use client' only on components needing browser APIsloading.tsxerror.tsxsupabaseAdmin for server-side operationscreateRouteHandlerClientAsync, createServerActionClientAsync).select() with relations)next/image used instead of <img> tagsPromise.all()# Understand project structure
ls -la app/ components/ lib/
cat package.json | grep -A 5 "dependencies"
cat tsconfig.json | grep -A 3 "compilerOptions"
cat .eslintrc.json
# Detect error handling patterns
grep -r "error-handler" app/ --include="*.ts" | head -5
# Detect Server Action patterns
grep -r "'use server'" app/actions/ --include="*.ts" | head -5
# Detect Supabase patterns
grep -r "supabaseAdmin\|createRouteHandlerClientAsync" app/ --include="*.ts" | head -5
For each file being reviewed:
FILE="app/api/example/route.ts"
# Check error handling
grep -n "error" "$FILE" | grep -v "error-handler"
# Check authentication
grep -n "getUser\|getSession" "$FILE"
# Check validation
grep -n "validate\|safeParse" "$FILE"
# Check database operations
grep -n "supabase\.from\|supabaseAdmin\.from" "$FILE"
# Find where file is imported
grep -r "from.*example\|import.*example" app/ components/ --include="*.ts" --include="*.tsx"
# Find similar patterns
grep -r "similarPattern" app/ --include="*.ts" | cut -d: -f1 | uniq
Use the Review Output Template (see above) to structure findings.
Problem: return NextResponse.json({ error: error.message }, { status: 500 })
Solution:
import { handleDatabaseError } from '@/lib/error-handler'
const { message, statusCode } = handleDatabaseError(error, 'Failed to create')
return NextResponse.json({ error: message }, { status: statusCode })
Problem: Server Action mutates data but doesn't revalidate cache
Solution:
import { revalidatePath } from 'next/cache'
// ... mutation code ...
revalidatePath('/books')
revalidatePath(`/books/${bookId}`, 'page')
Problem: Looping over results and making separate queries
Solution:
// ❌ WRONG
const books = await supabase.from('books').select('*')
for (const book of books.data || []) {
const author = await supabase.from('authors').select('*').eq('id', book.author_id).single()
}
// ✅ CORRECT
const books = await supabase
.from('books')
.select('id, title, authors(id, name)') // Single query with relations
Problem: Route handler doesn't verify user authentication
Solution:
const supabase = await createRouteHandlerClientAsync()
const { data: { user }, error: authError } = await supabase.auth.getUser()
if (authError || !user) {
return NextResponse.json(unauthorizedError(), { status: 401 })
}
any TypesProblem: function process(data: any): any
Solution:
interface ProcessData {
id: string
name: string
}
interface ProcessResult {
success: boolean
data?: ProcessData
error?: string
}
function process(data: ProcessData): ProcessResult {
// Implementation
}
The code review skill can automatically fix common issues:
Pattern Detection:
# Find raw error.message usage
grep -r "error\.message" app/api/ --include="route.ts" | grep -v "error-handler"
Auto-Fix Logic:
// Detect: return NextResponse.json({ error: error.message }, { status: 500 })
// Fix: Replace with handleDatabaseError()
// BEFORE
if (error) {
return NextResponse.json({ error: error.message }, { status: 500 })
}
// AFTER (Auto-fixed)
import { handleDatabaseError } from '@/lib/error-handler'
const { message, statusCode } = handleDatabaseError(error, 'Failed to create')
return NextResponse.json({ error: message }, { status: statusCode })
Pattern Detection:
# Find Server Actions without revalidation
grep -r "'use server'" app/actions/ --include="*.ts" | while read file; do
if ! grep -q "revalidatePath\|revalidateTag" "$file"; then
echo "Missing revalidation: $file"
fi
done
Auto-Fix Logic:
// Detect: Server Action with mutation but no revalidation
// Fix: Add revalidatePath based on context
// BEFORE
export async function createBook(data: BookData) {
const book = await insertBook(data)
return { success: true, book }
}
// AFTER (Auto-fixed)
import { revalidatePath } from 'next/cache'
export async function createBook(data: BookData) {
const book = await insertBook(data)
revalidatePath('/books')
if (book.id) {
revalidatePath(`/books/${book.id}`, 'page')
}
return { success: true, book }
}
Pattern Detection:
# Find API routes without auth checks
grep -r "export async function POST\|export async function PUT\|export async function DELETE" app/api/ --include="route.ts" | while read file; do
if ! grep -q "getUser\|getSession" "$file"; then
echo "Missing auth: $file"
fi
done
Auto-Fix Logic:
// Detect: API route without authentication
// Fix: Add authentication check at start
// BEFORE
export async function POST(request: NextRequest) {
const json = await request.json()
// ... process
}
// AFTER (Auto-fixed)
import { createRouteHandlerClientAsync } from '@/lib/supabase/client-helper'
import { unauthorizedError } from '@/lib/error-handler'
export async function POST(request: NextRequest) {
const supabase = await createRouteHandlerClientAsync()
const { data: { user }, error: authError } = await supabase.auth.getUser()
if (authError || !user) {
return NextResponse.json(unauthorizedError(), { status: 401 })
}
const json = await request.json()
// ... process
}
Pattern Detection:
# Find any types
grep -r ": any\|as any" app/ components/ --include="*.ts" --include="*.tsx"
Auto-Fix Logic:
// Detect: function process(data: any): any
// Fix: Infer or create proper types
// BEFORE
function process(data: any): any {
return { success: true, data }
}
// AFTER (Auto-fixed)
interface ProcessData {
id: string
name: string
}
interface ProcessResult {
success: boolean
data?: ProcessData
}
function process(data: ProcessData): ProcessResult {
return { success: true, data }
}
Pattern Detection:
# Find Server Actions without directive
grep -r "export async function" app/actions/ --include="*.ts" | while read file; do
if ! grep -q "'use server'" "$file"; then
echo "Missing 'use server': $file"
fi
done
Auto-Fix Logic:
// Detect: Server Action without 'use server'
// Fix: Add directive at top of file
// BEFORE
import { supabaseAdmin } from '@/lib/supabase/server'
export async function createActivity(params: CreateActivityParams) {
// ...
}
// AFTER (Auto-fixed)
'use server'
import { supabaseAdmin } from '@/lib/supabase/server'
export async function createActivity(params: CreateActivityParams) {
// ...
}
Pattern Detection:
# Find console.log statements
grep -r "console\.log\|console\.debug" app/ components/ --include="*.ts" --include="*.tsx" | grep -v "node_modules\|error-handler"
Auto-Fix Logic:
// Detect: console.log('Debug:', data)
// Fix: Remove or comment out
// BEFORE
console.log('Debug:', data)
console.debug('User:', user)
// AFTER (Auto-fixed)
// Removed debug statements
// Use proper logging utility if needed: logger.debug('Debug:', data)
Pattern Detection:
# Find usage without imports
grep -r "revalidatePath\|handleDatabaseError\|NextResponse" app/ --include="*.ts" | while read line; do
file=$(echo "$line" | cut -d: -f1)
symbol=$(echo "$line" | grep -oE "(revalidatePath|handleDatabaseError|NextResponse)")
if ! grep -q "import.*$symbol" "$file"; then
echo "Missing import: $file - $symbol"
fi
done
Auto-Fix Logic:
// Detect: Usage of symbol without import
// Fix: Add appropriate import
// BEFORE
export async function createBook(data: BookData) {
const book = await insertBook(data)
revalidatePath('/books') // Missing import
return NextResponse.json({ success: true }) // Missing import
}
// AFTER (Auto-fixed)
import { revalidatePath } from 'next/cache'
import { NextResponse } from 'next/server'
export async function createBook(data: BookData) {
const book = await insertBook(data)
revalidatePath('/books')
return NextResponse.json({ success: true })
}
When auto-fix is enabled, the review process:
Always Auto-Fix (Safe, non-breaking):
'use server' directiverevalidatePath/revalidateTag (when context is clear)Never Auto-Fix (Require human review):
Ask Before Fixing:
## [AUTO-FIX] Automatic Fixes Applied
**File**: `app/api/example/route.ts`
**Fixes Applied**: 5
**Manual Review Required**: 2
### ✅ Auto-Fixed
1. ✅ Added missing import: `handleDatabaseError` from `@/lib/error-handler`
2. ✅ Replaced `error.message` with `handleDatabaseError(error, 'Failed to create')`
3. ✅ Added authentication check at start of POST handler
4. ✅ Removed `console.log('Debug:', data)` statement
5. ✅ Added `'use server'` directive to Server Action
### ⚠️ Requires Manual Review
1. ⚠️ Potential N+1 query detected - Line 45
- **Issue**: Loop with database query inside
- **Suggestion**: Use `.select()` with relations
2. ⚠️ Missing input validation - Line 30
- **Issue**: No validation before database insert
- **Suggestion**: Add Zod schema validation
A quality review should:
@/lib/error-handlerany types)tools
Webpack build optimization expert with deep knowledge of configuration patterns, bundle analysis, code splitting, module federation, performance optimization, and plugin/loader ecosystem. Use PROACTIVELY for any Webpack bundling issues including complex optimizations, build performance, custom plugins/loaders, and modern architecture patterns. If a specialized expert is a better fit, I will recommend switching and stop.
development
Web application security expert. OWASP Top 10, XSS, SQLi, CSRF, SSRF, authentication bypass, IDOR. Use for web app security testing.
testing
Vitest testing framework expert for Vite integration, Jest migration, browser mode testing, and performance optimization
tools
Vite build optimization expert with deep knowledge of ESM-first development, HMR optimization, plugin ecosystem, production builds, library mode, and SSR configuration. Use PROACTIVELY for any Vite bundling issues including dev server performance, build optimization, plugin development, and modern ESM patterns. If a specialized expert is a better fit, I will recommend switching and stop.