database-expert
Expert database architect specializing in schema design, query optimization, data modeling, and migration strategies. Japanese: データベースエキスパート
Generate Next.js Route Handlers (API routes) with proper patterns and validation.
> /plugin marketplace add Fujigo-Software/f5-framework-claudeHow it fires
How this agent gets triggered: by you, by Claude, or both.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Generate Next.js Route Handlers (API routes) with proper patterns and validation.
Generate Next.js Route Handlers (API routes) with proper patterns and validation.
required: - route: string # API route path - methods: array # HTTP methods (GET, POST, etc.) optional: - entity: string # Entity name for CRUD - auth_required: boolean # Requires authentication - validation: object # Zod schema definition - response_type: string # Response format
app/api/{route}/
├── route.ts # Route handler
└── types.ts # Request/Response types (if complex)// app/api/products/route.ts
import { NextResponse } from 'next/server';
import { z } from 'zod';
import { db } from '@/lib/db';
// GET /api/products
export async function GET(request: Request) {
try {
const { searchParams } = new URL(request.url);
const page = Number(searchParams.get('page')) || 1;
const limit = Number(searchParams.get('limit')) || 10;
const skip = (page - 1) * limit;
const [products, total] = await Promise.all([
db.product.findMany({
skip,
take: limit,
orderBy: { createdAt: 'desc' },
}),
db.product.count(),
]);
return NextResponse.json({
data: products,
pagination: {
page,
limit,
total,
totalPages: Math.ceil(total / limit),
},
});
} catch (error) {
console.error('GET /api/products error:', error);
return NextResponse.json(
{ error: 'Internal Server Error' },
{ status: 500 }
);
}
}
// POST /api/products
const createProductSchema = z.object({
name: z.string().min(2).max(100),
description: z.string().max(1000).optional(),
price: z.number().min(0),
categoryId: z.string().uuid(),
});
export async function POST(request: Request) {
try {
const body = await request.json();
const validatedData = createProductSchema.safeParse(body);
if (!validatedData.success) {
return NextResponse.json(
{ error: 'Validation failed', details: validatedData.error.flatten() },
{ status: 400 }
);
}
const product = await db.product.create({
data: validatedData.data,
});
return NextResponse.json(product, { status: 201 });
} catch (error) {
console.error('POST /api/products error:', error);
return NextResponse.json(
{ error: 'Internal Server Error' },
{ status: 500 }
);
}
}// app/api/products/[id]/route.ts
import { NextResponse } from 'next/server';
import { z } from 'zod';
import { db } from '@/lib/db';
interface RouteParams {
params: { id: string };
}
// GET /api/products/[id]
export async function GET(request: Request, { params }: RouteParams) {
try {
const product = await db.product.findUnique({
where: { id: params.id },
include: { category: true },
});
if (!product) {
return NextResponse.json(
{ error: 'Product not found' },
{ status: 404 }
);
}
return NextResponse.json(product);
} catch (error) {
console.error(`GET /api/products/${params.id} error:`, error);
return NextResponse.json(
{ error: 'Internal Server Error' },
{ status: 500 }
);
}
}
// PATCH /api/products/[id]
const updateProductSchema = z.object({
name: z.string().min(2).max(100).optional(),
description: z.string().max(1000).optional(),
price: z.number().min(0).optional(),
categoryId: z.string().uuid().optional(),
});
export async function PATCH(request: Request, { params }: RouteParams) {
try {
const body = await request.json();
const validatedData = updateProductSchema.safeParse(body);
if (!validatedData.success) {
return NextResponse.json(
{ error: 'Validation failed', details: validatedData.error.flatten() },
{ status: 400 }
);
}
const product = await db.product.update({
where: { id: params.id },
data: validatedData.data,
});
return NextResponse.json(product);
} catch (error) {
if ((error as any).code === 'P2025') {
return NextResponse.json(
{ error: 'Product not found' },
{ status: 404 }
);
}
console.error(`PATCH /api/products/${params.id} error:`, error);
return NextResponse.json(
{ error: 'Internal Server Error' },
{ status: 500 }
);
}
}
// DELETE /api/products/[id]
export async function DELETE(request: Request, { params }: RouteParams) {
try {
await db.product.delete({
where: { id: params.id },
});
return new NextResponse(null, { status: 204 });
} catch (error) {
if ((error as any).code === 'P2025') {
return NextResponse.json(
{ error: 'Product not found' },
{ status: 404 }
);
}
console.error(`DELETE /api/products/${params.id} error:`, error);
return NextResponse.json(
{ error: 'Internal Server Error' },
{ status: 500 }
);
}
}// app/api/user/profile/route.ts
import { NextResponse } from 'next/server';
import { auth } from '@/lib/auth';
import { db } from '@/lib/db';
export async function GET() {
const session = await auth();
if (!session?.user) {
return NextResponse.json(
{ error: 'Unauthorized' },
{ status: 401 }
);
}
const user = await db.user.findUnique({
where: { id: session.user.id },
select: {
id: true,
name: true,
email: true,
image: true,
createdAt: true,
},
});
return NextResponse.json(user);
}
export async function PATCH(requeRepo: Fujigo-Software/f5-framework-claude
Expert database architect specializing in schema design, query optimization, data modeling, and migration strategies. Japanese: データベースエキスパート
Expert DevOps architect specializing in CI/CD pipelines, infrastructure as code, containerization, and monitoring. Japanese: DevOpsアーキテクト
Mobile app architecture specialist. iOS, Android, React Native, Flutter.
Backend architecture specialist. Microservices, APIs, databases.
Frontend architecture specialist. React, Vue, Angular, Next.js.