UNPKG

vibe-cli-tool

Version:

VibeCLI v1.9 - 模板商店生态,智能部署生成,多语言支持,交互式学习系统,企业级Web全栈应用CLI工具

702 lines (604 loc) 18.3 kB
# Web全栈架构规范 本文档定义了基于Next.js的Web全栈应用的完整架构规范和项目结构。 ## 🏗️ 架构概览 ### 系统架构图 ``` ┌─────────────────────────────────────────────────────────────┐ Next.js 全栈应用 ├─────────────────────────────────────────────────────────────┤ 前端层 (React + TypeScript) ├── Pages/App Router ├── React Components (UI组件) ├── State Management (Zustand + React Query) └── Client-side Routing ├─────────────────────────────────────────────────────────────┤ API层 (Next.js API Routes) ├── RESTful API Endpoints (/api/*) ├── Authentication & Authorization ├── Business Logic Services └── Error Handling & Validation ├─────────────────────────────────────────────────────────────┤ 数据层 (Prisma ORM + Database) ├── Database Schema (PostgreSQL/MySQL) ├── Data Models & Relations ├── Query Optimization └── Database Migrations └─────────────────────────────────────────────────────────────┘ ``` ## 📁 项目结构规范 ### 完整目录结构 ``` my-web-app/ ├── components/ # React组件 ├── ui/ # 基础UI组件 ├── Button.tsx ├── Input.tsx ├── Card.tsx ├── Dialog.tsx ├── Select.tsx ├── Table.tsx └── index.ts # 组件导出 ├── layout/ # 布局组件 ├── Layout.tsx ├── Navigation.tsx ├── Header.tsx ├── Sidebar.tsx └── Footer.tsx ├── forms/ # 表单组件 ├── LoginForm.tsx ├── RegisterForm.tsx ├── ProfileForm.tsx └── index.ts └── features/ # 功能模块组件 ├── auth/ ├── dashboard/ └── settings/ ├── pages/ # Next.js页面 (Pages Router) ├── api/ # API路由 ├── auth/ ├── login.ts ├── register.ts ├── refresh.ts └── logout.ts ├── users/ ├── index.ts ├── [id].ts └── profile.ts ├── admin/ └── health.ts ├── _app.tsx # App组件 ├── _document.tsx # Document组件 ├── index.tsx # 首页 ├── login.tsx # 登录页 ├── register.tsx # 注册页 ├── dashboard.tsx # 仪表板 ├── profile.tsx # 个人资料 └── admin/ # 管理页面 ├── lib/ # 核心库文件 ├── services/ # 业务服务层 ├── auth.ts ├── user.ts ├── api.ts └── logger.ts ├── hooks/ # React Hooks ├── useAuth.ts ├── useApi.ts ├── useLocalStorage.ts └── index.ts ├── stores/ # 状态管理 ├── auth.ts ├── user.ts ├── config.ts └── index.ts ├── middleware/ # API中间件 ├── auth.ts ├── error-handler.ts ├── enhanced-api.ts ├── validation.ts └── rate-limit.ts ├── utils/ # 工具函数 ├── auth-fetch.ts ├── errors.ts ├── response.ts ├── cn.ts └── constants.ts ├── validations/ # 数据验证 ├── auth.ts ├── user.ts ├── common.ts └── index.ts └── db/ # 数据库配置 ├── prisma.ts └── connection.ts ├── prisma/ # Prisma配置 ├── schema.prisma # 数据库模式 ├── migrations/ # 数据库迁移 └── seed.ts # 种子数据 ├── styles/ # 样式文件 ├── globals.css ├── components.css └── utils.css ├── types/ # TypeScript类型定义 ├── auth.ts ├── user.ts ├── api.ts ├── database.ts └── index.ts ├── public/ # 静态资源 ├── images/ ├── icons/ └── favicon.ico ├── docs/ # 项目文档 ├── tests/ # 测试文件 ├── __mocks__/ ├── components/ ├── pages/ └── utils/ ├── .env.example # 环境变量示例 ├── .env.local # 本地环境变量 ├── .gitignore ├── .eslintrc.json ├── .prettierrc ├── package.json ├── tsconfig.json ├── tailwind.config.js ├── next.config.js ├── prisma.config.js └── README.md ``` ### 目录职责说明 #### `/components` - 组件目录 - **ui/**: 可复用的基础UI组件,遵循设计系统 - **layout/**: 页面布局相关组件 - **forms/**: 表单组件,包含验证逻辑 - **features/**: 按功能模块组织的业务组件 #### `/pages` - 页面和API目录 - **api/**: Next.js API路由,按功能模块组织 - **页面文件**: 直接对应URL路径的页面组件 #### `/lib` - 核心业务逻辑 - **services/**: 业务服务层,封装复杂业务逻辑 - **hooks/**: 自定义React Hooks - **stores/**: 客户端状态管理 - **middleware/**: API中间件和通用处理逻辑 - **utils/**: 纯函数工具库 - **validations/**: 数据验证schema - **db/**: 数据库连接和配置 ## 🔧 技术架构规范 ### 1. 前端架构 #### 组件设计原则 ```typescript // 组件设计模式 interface ComponentProps { // 必需属性 children: React.ReactNode className?: string // 功能属性 variant?: 'primary' | 'secondary' | 'danger' size?: 'sm' | 'md' | 'lg' disabled?: boolean // 事件处理 onClick?: () => void onChange?: (value: string) => void } // 使用forwardRef支持ref传递 const Component = React.forwardRef<HTMLElement, ComponentProps>( ({ children, className, ...props }, ref) => { return ( <element ref={ref} className={cn(baseStyles, className)} {...props} > {children} </element> ) } ) Component.displayName = 'Component' ``` #### 状态管理架构 ```typescript // Zustand Store模式 interface AuthState { // 状态定义 user: User | null token: string | null isAuthenticated: boolean isLoading: boolean error: string | null // 操作方法 login: (credentials: LoginCredentials) => Promise<void> logout: () => void refreshToken: () => Promise<void> clearError: () => void // 计算属性 isAdmin: () => boolean hasPermission: (permission: string) => boolean } // React Query配置 const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 1000 * 60 * 5, // 5分钟 retry: 1, refetchOnWindowFocus: false, }, mutations: { retry: 1, }, }, }) ``` ### 2. API架构 #### API路由设计模式 ```typescript // 标准API路由结构 // pages/api/users/[id].ts import { NextApiRequest, NextApiResponse } from 'next' import { withAuth } from '@/lib/middleware/auth' import { withValidation } from '@/lib/middleware/validation' import { userService } from '@/lib/services/user' import { userUpdateSchema } from '@/lib/validations/user' interface ApiResponse<T = any> { success: boolean data?: T error?: string message?: string } async function handler( req: AuthenticatedRequest, res: NextApiResponse<ApiResponse> ) { const { id } = req.query const { method } = req switch (method) { case 'GET': return handleGet(req, res, id as string) case 'PUT': return handlePut(req, res, id as string) case 'DELETE': return handleDelete(req, res, id as string) default: return res.status(405).json({ success: false, error: 'Method not allowed' }) } } async function handleGet(req: AuthenticatedRequest, res: NextApiResponse, id: string) { try { const user = await userService.getUserById(id) if (!user) { return res.status(404).json({ success: false, error: 'User not found' }) } res.status(200).json({ success: true, data: user }) } catch (error) { throw error // 由错误中间件处理 } } export default withAuth( withValidation(userUpdateSchema, handler, { methods: ['PUT'] }) ) ``` #### 中间件架构 ```typescript // 增强型API中间件 export function withEnhancedApi( handler: ApiHandler, options: ApiMiddlewareOptions = {} ) { const { enableLogging = true, enableRateLimit = false, requireAuth = false, requiredPermissions = [], validationSchema, } = options return async (req: NextApiRequest, res: NextApiResponse) => { // 请求预处理 const enhancedReq = enhanceRequest(req) try { // 日志记录 if (enableLogging) { logRequest(enhancedReq) } // 频率限制 if (enableRateLimit) { await checkRateLimit(enhancedReq, res) } // 认证检查 if (requireAuth) { await authenticateRequest(enhancedReq) } // 权限检查 if (requiredPermissions.length > 0) { await checkPermissions(enhancedReq, requiredPermissions) } // 数据验证 if (validationSchema) { validateRequestData(enhancedReq, validationSchema) } // 执行处理器 await handler(enhancedReq, res) // 成功日志 if (enableLogging) { logSuccess(enhancedReq, res) } } catch (error) { // 错误处理 handleApiError(error, enhancedReq, res) } } } ``` ### 3. 数据库架构 #### Prisma Schema设计规范 ```prisma // 基础模型设计 model User { // 主键使用cuid id String @id @default(cuid()) // 基础字段 email String @unique username String? @unique name String? // 状态字段 status UserStatus @default(ACTIVE) tier UserTier @default(FREE) // 安全字段 passwordHash String @map("password_hash") // 时间戳 createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") lastActiveAt DateTime? @map("last_active_at") // 关系定义 sessions UserSession[] posts Post[] comments Comment[] // 索引优化 @@index([email]) @@index([status]) @@index([createdAt]) // 表名映射 @@map("users") } // 枚举定义 enum UserStatus { ACTIVE SUSPENDED INACTIVE PENDING } enum UserTier { FREE PRO ADMIN } ``` #### 数据库服务层模式 ```typescript // 服务层抽象 export abstract class BaseService<T> { protected abstract model: any async findById(id: string): Promise<T | null> { return await this.model.findUnique({ where: { id } }) } async findMany(where?: any, options?: any): Promise<T[]> { return await this.model.findMany({ where, ...options }) } async create(data: any): Promise<T> { return await this.model.create({ data }) } async update(id: string, data: any): Promise<T> { return await this.model.update({ where: { id }, data }) } async delete(id: string): Promise<T> { return await this.model.delete({ where: { id } }) } } // 具体服务实现 export class UserService extends BaseService<User> { protected model = prisma.user async createUser(data: CreateUserInput): Promise<User> { const passwordHash = await bcrypt.hash(data.password, 12) return await this.model.create({ data: { ...data, passwordHash, password: undefined // 移除明文密码 }, select: { id: true, email: true, name: true, status: true, tier: true, createdAt: true } }) } async getUserWithStats(id: string): Promise<UserWithStats | null> { return await this.model.findUnique({ where: { id }, include: { _count: { select: { posts: true, comments: true } }, sessions: { where: { expiresAt: { gt: new Date() } }, take: 1 } } }) } } ``` ## 🔒 安全架构 ### 认证授权流程 ```typescript // JWT认证流程 export class AuthService { async login(credentials: LoginCredentials): Promise<AuthResult> { // 1. 验证用户凭据 const user = await this.validateCredentials(credentials) // 2. 生成令牌 const tokens = await this.generateTokens(user) // 3. 保存会话 await this.createSession(user.id, tokens.refreshToken) // 4. 返回结果 return { user: this.sanitizeUser(user), tokens } } private async generateTokens(user: User): Promise<Tokens> { const payload = { userId: user.id, email: user.email, tier: user.tier, permissions: await this.getUserPermissions(user.id) } const accessToken = jwt.sign(payload, JWT_SECRET, { expiresIn: '1h' }) const refreshToken = jwt.sign( { userId: user.id }, REFRESH_SECRET, { expiresIn: '7d' } ) return { accessToken, refreshToken } } } ``` ### 数据验证架构 ```typescript // Zod验证Schema export const createUserSchema = z.object({ email: z.string().email('邮箱格式不正确'), password: z.string() .min(8, '密码至少8位') .regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/, '密码必须包含大小写字母和数字'), name: z.string().min(1, '姓名不能为空').optional(), terms: z.boolean().refine(val => val === true, '必须同意服务条款') }) // 运行时验证 export function validateData<T>( schema: z.ZodSchema<T>, data: unknown ): T { try { return schema.parse(data) } catch (error) { if (error instanceof z.ZodError) { throw new ValidationError( '数据验证失败', error.errors.map(e => ({ field: e.path.join('.'), message: e.message })) ) } throw error } } ``` ## 📊 性能架构 ### 缓存策略 ```typescript // 多层缓存架构 export class CacheManager { private memoryCache = new Map() private redisCache?: Redis async get<T>(key: string): Promise<T | null> { // 1. 内存缓存 if (this.memoryCache.has(key)) { return this.memoryCache.get(key) } // 2. Redis缓存 if (this.redisCache) { const cached = await this.redisCache.get(key) if (cached) { const data = JSON.parse(cached) this.memoryCache.set(key, data) return data } } return null } async set<T>(key: string, value: T, ttl: number = 300): Promise<void> { // 设置内存缓存 this.memoryCache.set(key, value) // 设置Redis缓存 if (this.redisCache) { await this.redisCache.setex(key, ttl, JSON.stringify(value)) } // 内存缓存TTL setTimeout(() => { this.memoryCache.delete(key) }, ttl * 1000) } } ``` ### 数据库优化 ```typescript // 查询优化模式 export class OptimizedUserService { async getUsersWithPagination(params: PaginationParams) { const { page = 1, limit = 20, search, filters } = params // 构建查询条件 const where = this.buildWhereClause(search, filters) // 并行执行查询和计数 const [users, total] = await Promise.all([ prisma.user.findMany({ where, select: { id: true, email: true, name: true, status: true, createdAt: true }, skip: (page - 1) * limit, take: limit, orderBy: { createdAt: 'desc' } }), prisma.user.count({ where }) ]) return { users, pagination: { page, limit, total, pages: Math.ceil(total / limit) } } } } ``` 这个架构规范为Web全栈应用提供了完整的技术架构指导,确保项目的可维护性、可扩展性和性能。