Expert guide for WebTools Pro - a Next.js file processing platform with 51+ tools for PDF, image, video, and AI-powered operations. Provides guidance on architecture, TypeScript patterns, API development, and deployment.
Expert assistant for **WebTools Pro**, a comprehensive Next.js 15.3 monolithic application providing 51+ professional file processing tools (PDF, image, video, AI-powered) with modern TypeScript architecture.
WebTools Pro is a production-ready file processing platform featuring:
```
web-tools/
├── src/
│ ├── app/
│ │ ├── api/ # API routes
│ │ │ ├── tools/ # Processing endpoints
│ │ │ │ ├── pdf/ # PDF processing
│ │ │ │ ├── image/ # Image processing
│ │ │ │ ├── video/ # Video processing
│ │ │ │ └── ai/ # AI processing
│ │ │ ├── files/ # File operations
│ │ │ └── admin/ # Admin endpoints
│ │ ├── tools/ # Tool UI pages
│ │ ├── layout.tsx # Root layout
│ │ └── page.tsx # Home page
│ ├── components/
│ │ ├── ui/ # shadcn/ui components
│ │ ├── tools/ # Tool-specific components
│ │ └── layout/ # Layout components
│ ├── lib/ # Utilities & engines
│ └── hooks/ # Custom React hooks
├── uploads/ # User uploads
├── outputs/ # Processed files
├── docs/ # Documentation
└── bmad-agent/ # Agent system
```
**Always use explicit types with Zod validation:**
```typescript
// Define interfaces for all data structures
interface FileMetadata {
fileId: string;
originalName: string;
mimeType: string;
size: number;
uploadedAt: string;
}
// Use Zod for runtime validation
import { z } from 'zod';
const uploadSchema = z.object({
file: z.instanceof(File),
operation: z.enum(['compress', 'convert', 'extract']),
options: z.object({
quality: z.number().min(1).max(100).optional(),
}),
});
// Never use 'any' type
// ❌ Bad: const processFile = (file: any) => { ... }
// ✅ Good: const processFile = (file: FileMetadata) => { ... }
```
**Use Server Components by default, Client Components only when needed:**
```typescript
// Server Component (default)
// src/app/tools/pdf/page.tsx
export default function PDFToolsPage() {
return (
<div className="container mx-auto py-8">
<h1 className="text-4xl font-bold mb-8">PDF Tools</h1>
{/* Static content */}
</div>
);
}
// Client Component (interactive only)
// src/components/tools/FileUpload.tsx
'use client';
import { useState } from 'react';
import { useDropzone } from 'react-dropzone';
export function FileUpload({ onUpload }: { onUpload: (file: File) => void }) {
// Interactive logic here
}
```
**Component naming conventions:**
**Follow this standard structure for all API routes:**
```typescript
// src/app/api/tools/pdf/compress/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';
const requestSchema = z.object({
fileId: z.string().uuid(),
quality: z.number().min(1).max(100).default(85),
});
export async function POST(request: NextRequest) {
try {
// 1. Validate input
const body = await request.json();
const { fileId, quality } = requestSchema.parse(body);
// 2. Check cache
const cached = await checkCache(`compress:${fileId}:${quality}`);
if (cached) return NextResponse.json(cached);
// 3. Process file
const result = await compressPDF(fileId, quality);
// 4. Cache result
await cacheResult(`compress:${fileId}:${quality}`, result);
// 5. Return response
return NextResponse.json({
success: true,
...result,
});
} catch (error) {
return NextResponse.json(
{ success: false, error: error.message },
{ status: 400 }
);
}
}
```
**Follow these steps in order:**
1. **Create API Route** at `src/app/api/tools/{category}/{tool-name}/route.ts`
2. **Create UI Page** at `src/app/tools/{category}/{tool-name}/page.tsx`
3. **Update Navigation** in category page and SmartNavigation component
4. **Implement Processing** using appropriate engine from `@/lib/`
**Standard three-step flow:**
```typescript
// 1. Upload file
const formData = new FormData();
formData.append('file', file);
const uploadRes = await fetch('/api/files/upload', {
method: 'POST',
body: formData,
});
const { fileId } = await uploadRes.json();
// 2. Process file
const processRes = await fetch('/api/tools/pdf/compress', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fileId, quality: 85 }),
});
const { outputFileId } = await processRes.json();
// 3. Download result
window.location.href = `/api/files/download?fileId=${outputFileId}`;
```
**Use centralized AppError class:**
```typescript
export class AppError extends Error {
constructor(
message: string,
public statusCode: number = 500,
public code?: string
) {
super(message);
}
}
// In API routes
try {
// ... processing
} catch (error) {
if (error instanceof AppError) {
return NextResponse.json(
{ error: error.message, code: error.code },
{ status: error.statusCode }
);
}
console.error('Unexpected error:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
```
**Use multi-tier caching system:**
```typescript
import { cacheManager } from '@/lib/cache';
// Check cache layers (memory → Redis → CDN)
const result = await cacheManager.get(key, {
memory: true,
redis: true,
ttl: 3600, // 1 hour
});
// Cache with tags for invalidation
await cacheManager.set(key, data, {
tags: ['pdf', `user:${userId}`],
ttl: 3600,
});
```
**Always validate file types, sizes, and filenames:**
```typescript
const ALLOWED_TYPES = {
pdf: ['application/pdf'],
image: ['image/jpeg', 'image/png', 'image/webp'],
video: ['video/mp4', 'video/webm'],
};
const MAX_FILE_SIZE = {
pdf: 50 * 1024 * 1024, // 50MB
image: 25 * 1024 * 1024, // 25MB
video: 500 * 1024 * 1024, // 500MB
};
const sanitizeFilename = (filename: string): string => {
return filename
.replace(/[^a-zA-Z0-9.-]/g, '_')
.replace(/\.{2,}/g, '.')
.toLowerCase();
};
```
**Image optimization:**
```typescript
import Image from 'next/image';
<Image
src="/tool-icon.png"
alt="Tool icon"
width={48}
height={48}
loading="lazy"
/>
```
**Code splitting:**
```typescript
const PDFViewer = dynamic(() => import('@/components/PDFViewer'), {
loading: () => <Skeleton className="w-full h-96" />,
ssr: false,
});
```
**API caching headers:**
```typescript
return NextResponse.json(data, {
headers: {
'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate',
},
});
```
**Always use shadcn/ui components:**
```typescript
import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';
import { Progress } from '@/components/ui/progress';
import { Skeleton } from '@/components/ui/skeleton';
```
```bash
npm run dev # Start dev server (port 8000)
npm run lint # Run ESLint
npm run build # Production build
npm run start # Production server
npx tsc --noEmit # Type checking
```
**Local development:**
```bash
npm install
npm run dev
```
**Production deployment:**
```bash
docker build -t web-tools .
./deploy-gcp.sh your-project-id us-central1
```
1. ❌ **Never use `any` type** - Always define proper TypeScript types
2. ❌ **Don't bypass validation** - Always validate with Zod schemas
3. ❌ **Don't ignore caching** - Use the multi-tier cache system
4. ❌ **Don't process files synchronously** - Use streaming for large files
5. ❌ **Don't hardcode values** - Use environment variables
6. ❌ **Don't skip error handling** - Always handle edge cases
7. ❌ **Don't create files without cleanup** - Implement TTL for temporary files
For architectural changes or major features, consult:
When asked to add a new PDF compression feature:
1. Review existing compression API at `src/app/api/tools/pdf/compress/route.ts`
2. Create new endpoint following API route pattern (validate → check cache → process → cache → return)
3. Implement UI page at `src/app/tools/pdf/new-feature/page.tsx`
4. Use shadcn/ui components for consistency
5. Add security validation for file types and sizes
6. Implement multi-tier caching
7. Add error handling with AppError
8. Test with type checking (`npx tsc --noEmit`)
When asked to optimize performance:
1. Check cache hit rates in multi-tier system
2. Use Next.js Image component for all images
3. Implement code splitting with dynamic imports
4. Add proper Cache-Control headers to API responses
5. Profile with Lighthouse and maintain >95 score
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/web-tools-platform-assistant/raw