architecture.md 34 KB

shadcn全栈管理后台启动模板 Fullstack Architecture Document

1. Introduction

本文档概述了shadcn全栈管理后台启动模板的完整全栈架构,包括后端系统、前端实现及其集成。它作为AI驱动开发的单一事实来源,确保整个技术栈的一致性。

这种统一方法将传统上分离的后端和前端架构文档结合起来,为现代全栈应用程序简化了开发流程,这些应用程序中这些关注点日益交织在一起。

2. High Level Architecture

2.1 Technical Summary

shadcn全栈管理后台启动模板采用现代化的Jamstack架构风格,结合React前端和Hono后端框架。前端基于Vite构建工具和Tailwind CSS样式方案,后端使用TypeORM进行数据库操作和MySQL作为主数据库。架构采用单体部署方式,通过清晰的代码分离结构确保前后端开发一致性。该架构通过RESTful API规范、OpenAPI文档生成和类型安全的客户端集成,实现了PRD中要求的完整用户认证、权限管理和生产就绪状态。

2.2 Platform and Infrastructure Choice

基于PRD要求和开发环境配置,采用多八多云端开发容器环境作为部署平台:

平台选择:多八多云端容器环境

  • 前端部署: 同一容器内的Node.js服务
  • 后端部署: 同一容器内的Node.js服务
  • 数据库: MySQL 8.0.36(容器内,默认数据库d8dai)
  • 缓存: Redis 7(容器内)
  • 文件存储: MinIO(容器内)
  • 连接方式: 所有服务使用默认参数连接,正式环境参数相同

2.3 Repository Structure

结构: Monorepo结构 Monorepo工具: Turborepo 包组织策略:

  • apps/admin - 管理后台React应用(基于shadcn/ui)
  • apps/web - 面向用户的Web端React应用
  • apps/api - 后端Hono API
  • packages/shared - 共享类型和工具
  • packages/ui - 共享UI组件库
  • packages/config - 共享配置(ESLint、TypeScript等)

2.4 High Level Architecture Diagram

graph TB
    User[用户] --> Web[Web前端<br/>React + Vite]
    User --> Mobile[移动端<br/>响应式设计]

    Web --> API[API网关<br/>Hono框架]
    Mobile --> API

    API --> Auth[认证服务<br/>JWT + bcrypt]
    API --> UserService[用户服务]
    API --> DataService[数据服务]

    Auth --> DB[(MySQL数据库)]
    UserService --> DB
    DataService --> DB

    API --> Cache[Redis缓存]
    API --> Storage[MinIO存储]

    API --> External[外部服务<br/>OpenAI等]

2.5 Architectural Patterns

Jamstack架构: 静态站点生成与无服务器API结合 - 理由: 为内容密集型应用提供最佳性能和可扩展性 组件化UI: 基于TypeScript的可复用React组件 - 理由: 在大型代码库中保持可维护性和类型安全 仓库模式: 抽象数据访问逻辑 - 理由: 支持测试和未来数据库迁移的灵活性 API网关模式: 所有API调用的单一入口点 - 理由: 集中化认证、速率限制和监控

3. Tech Stack

这是项目的最终技术选择。与用户合作确定所有选择。此表是单一事实来源 - 所有开发必须使用这些确切版本。

Technology Stack Table

类别 技术 版本 用途 理由
前端语言 TypeScript 5.0+ 类型安全的React开发 提供完整的类型安全和开发体验
前端框架 React 19 用户界面构建 现代React特性,更好的性能
UI组件库 shadcn/ui 最新 管理后台UI组件 基于Tailwind的专业设计系统
状态管理 React Query (TanStack) 5 服务器状态管理 简化API数据管理和缓存
后端语言 TypeScript 5.0+ 类型安全的Node.js开发 前后端类型一致性
后端框架 Hono 4 Web框架和API开发 轻量级、高性能、TypeScript友好
API风格 REST - API接口规范 简单、通用、工具生态丰富
数据库 MySQL 8.0.36 主数据存储 关系型数据库,成熟稳定
缓存 Redis 7 会话和缓存 高性能内存数据库
文件存储 MinIO 最新 对象存储 S3兼容,自托管方案
认证 JWT + bcrypt 最新 用户认证和授权 无状态认证,密码安全加密
前端测试 Vitest 最新 单元和组件测试 Vite生态,快速测试运行
后端测试 Vitest 最新 API和单元测试 统一测试工具链
E2E测试 Playwright 最新 端到端测试 跨浏览器测试支持
构建工具 Vite 7 前端构建和开发服务器 快速冷启动,优秀开发体验
打包工具 Vite 7 代码打包和优化 统一构建工具链
IaC工具 Docker Compose 最新 本地环境编排 容器化开发环境
CI/CD GitHub Actions - 自动化部署 与GitHub生态集成
监控 - - 应用监控 后续阶段实现
日志 - - 应用日志 后续阶段实现
CSS框架 Tailwind CSS 4 样式方案 实用优先,设计系统友好

4. Data Models

基于PRD需求,定义将在前端和后端之间共享的核心数据模型/实体:

4.1 User(用户模型)

用途: 管理系统用户账户信息,支持认证和权限管理

关键属性:

  • id: string - 用户唯一标识符(UUID)
  • email: string - 用户邮箱,用于登录和通信
  • password: string - 加密后的密码(bcrypt哈希)
  • name: string - 用户显示名称
  • role: string - 用户角色(admin, user等)
  • status: string - 用户状态(active, inactive等)
  • createdAt: Date - 创建时间
  • updatedAt: Date - 最后更新时间

TypeScript接口:

interface User {
  id: string;
  email: string;
  password: string;
  name: string;
  role: UserRole;
  status: UserStatus;
  createdAt: Date;
  updatedAt: Date;
}

type UserRole = 'admin' | 'user';
type UserStatus = 'active' | 'inactive' | 'suspended';

关系:

  • 一个用户可以创建多个内容条目
  • 一个用户可以属于多个角色(如需扩展)

4.2 Role(角色模型)

用途: 管理系统角色和权限配置

关键属性:

  • id: string - 角色唯一标识符
  • name: string - 角色名称
  • permissions: string[] - 权限列表
  • description: string - 角色描述
  • createdAt: Date - 创建时间

TypeScript接口:

interface Role {
  id: string;
  name: string;
  permissions: Permission[];
  description: string;
  createdAt: Date;
}

type Permission = 'user:read' | 'user:write' | 'content:read' | 'content:write' | 'settings:read' | 'settings:write';

关系:

  • 一个角色可以分配给多个用户

会话管理策略

会话存储: Redis 存储内容: JWT令牌黑名单、用户会话状态 过期策略: 基于JWT过期时间自动清理

5. API Specification

基于技术栈中选择的REST API风格,创建OpenAPI 3.0规范:

OpenAPI 3.0规范(修订)

openapi: 3.0.0
info:
  title: shadcn管理后台API
  version: 1.0.0
  description: 基于Hono框架的RESTful API,支持用户认证和权限管理
servers:
  - url: http://localhost:8080/api
    description: 本地开发环境(8080端口)
  - url: https://your-domain.com:8080/api
    description: 生产环境(8080端口)

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  schemas:
    User:
      type: object
      properties:
        id:
          type: string
          format: uuid
        email:
          type: string
          format: email
        name:
          type: string
        role:
          type: string
          enum: [admin, user]
        status:
          type: string
          enum: [active, inactive, suspended]
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    AuthResponse:
      type: object
      properties:
        user:
          $ref: '#/components/schemas/User'
        token:
          type: string
        expiresIn:
          type: integer

    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            details:
              type: object

paths:
  /auth/login:
    post:
      summary: 用户登录
      tags: [认证]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  format: email
                password:
                  type: string
      responses:
        '200':
          description: 登录成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthResponse'
        '401':
          description: 认证失败
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /auth/register:
    post:
      summary: 用户注册
      tags: [认证]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  format: email
                password:
                  type: string
                name:
                  type: string
      responses:
        '201':
          description: 注册成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthResponse'
        '400':
          description: 请求参数错误
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /users:
    get:
      summary: 获取用户列表
      tags: [用户管理]
      security:
        - bearerAuth: []
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
      responses:
        '200':
          description: 用户列表
          content:
            application/json:
              schema:
                type: object
                properties:
                  users:
                    type: array
                    items:
                      $ref: '#/components/schemas/User'
                  total:
                    type: integer
                  page:
                    type: integer
                  limit:
                    type: integer
        '401':
          description: 未授权
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

基于hono/client的RPC方式

后端API路由定义:

// apps/api/src/routes/index.ts
export const app = new Hono()
  .route('/auth', authRoutes)
  .route('/users', userRoutes);

export type AppType = typeof app;

前端类型安全调用:

// apps/admin/src/lib/api-client.ts
import { hc } from 'hono/client';
import type { AppType } from '@api/routes'; // 直接从后端导入类型

export const apiClient = hc<AppType>('http://localhost:8080');

// 类型安全的API调用
const response = await apiClient.auth.login.$post({
  json: { email: 'user@example.com', password: 'password123' }
});
const data = await response.json(); // 自动类型推断

Zod Schema独立配置

共享Zod Schema定义:

// packages/shared/src/schemas/index.ts
export const userSchema = {
  create: z.object({
    email: z.string().email('请输入有效的邮箱地址'),
    name: z.string().min(1, '姓名不能为空'),
    password: z.string().min(6, '密码至少6位'),
    role: z.enum(['admin', 'user']).default('user'),
  }),

  update: z.object({
    email: z.string().email('请输入有效的邮箱地址').optional(),
    name: z.string().min(1, '姓名不能为空').optional(),
    role: z.enum(['admin', 'user']).optional(),
    status: z.enum(['active', 'inactive', 'suspended']).optional(),
  }).partial(),
};

6. Components

基于架构模式、技术栈和数据模型,识别全栈中的主要逻辑组件/服务:

6.1 认证服务 (AuthService)

责任: 处理用户认证、注册、JWT令牌生成和验证 关键接口:

  • login(email: string, password: string): Promise<AuthResponse>
  • register(userData: RegisterData): Promise<AuthResponse>
  • verifyToken(token: string): Promise<User>
  • logout(token: string): Promise<void> 依赖: UserService、Redis(令牌管理) 技术栈: Hono中间件、bcrypt、jsonwebtoken、Redis客户端

6.2 用户服务 (UserService)

责任: 管理用户CRUD操作、权限验证和用户状态管理 关键接口:

  • getUsers(query: UserQuery): Promise<User[]>
  • getUserById(id: string): Promise<User>
  • createUser(userData: CreateUserData): Promise<User>
  • updateUser(id: string, updates: Partial<User>): Promise<User>
  • deleteUser(id: string): Promise<void> 依赖: 数据库(TypeORM)、RoleService 技术栈: TypeORM Repository模式、数据验证

6.3 通用CRUD服务 (GenericCRUDService)

责任: 提供通用的CRUD操作基类,支持快速创建实体服务 关键接口:

  • findAll(query: PaginationQuery): Promise<Entity[]>
  • findById(id: string): Promise<Entity>
  • create(data: CreateDTO): Promise<Entity>
  • update(id: string, data: UpdateDTO): Promise<Entity>
  • delete(id: string): Promise<void> 依赖: TypeORM Repository、Zod验证 技术栈: TypeORM泛型、类继承、装饰器模式

6.4 通用CRUD路由 (GenericCRUDRouter)

责任: 自动生成标准RESTful路由,支持通用CRUD操作 关键接口:

  • GET /entity - 获取列表(支持分页、过滤、排序)
  • GET /entity/:id - 获取单个实体
  • POST /entity - 创建实体
  • PUT /entity/:id - 更新实体
  • DELETE /entity/:id - 删除实体 依赖: GenericCRUDService、Zod验证 技术栈: Hono路由工厂、OpenAPI自动生成

6.5 组件关系图

flowchart TB
    Frontend[前端应用] --> APIGateway[API网关]

    APIGateway --> AuthService[认证服务]
    APIGateway --> UserService[用户服务]
    APIGateway --> RoleService[角色服务]

    AuthService --> Redis[Redis缓存]
    UserService --> DB[(MySQL数据库)]
    RoleService --> DB

    AuthService --> UserService
    UserService --> RoleService

7. Core Workflows

使用序列图说明关键系统工作流:

7.1 用户登录工作流

sequenceDiagram
    participant User as 用户
    participant Frontend as 前端应用
    participant AuthService as 认证服务
    participant UserService as 用户服务
    participant Redis as Redis缓存
    participant DB as MySQL数据库

    User->>Frontend: 输入邮箱密码
    Frontend->>AuthService: POST /auth/login
    AuthService->>UserService: 验证用户凭证
    UserService->>DB: 查询用户信息
    DB-->>UserService: 返回用户数据
    UserService-->>AuthService: 验证结果

    alt 验证成功
        AuthService->>AuthService: 生成JWT令牌
        AuthService->>Redis: 存储令牌信息
        AuthService-->>Frontend: 返回用户信息和令牌
        Frontend->>Frontend: 存储令牌到localStorage
        Frontend-->>User: 登录成功,跳转首页
    else 验证失败
        AuthService-->>Frontend: 返回错误信息
        Frontend-->>User: 显示错误提示
    end

7.2 用户注册工作流

sequenceDiagram
    participant User as 用户
    participant Frontend as 前端应用
    participant AuthService as 认证服务
    participant UserService as 用户服务
    participant DB as MySQL数据库

    User->>Frontend: 填写注册信息
    Frontend->>Frontend: Zod表单验证
    Frontend->>AuthService: POST /auth/register
    AuthService->>UserService: 创建新用户
    UserService->>DB: 检查邮箱是否已存在
    DB-->>UserService: 返回检查结果

    alt 邮箱可用
        UserService->>UserService: 加密密码
        UserService->>DB: 插入用户记录
        DB-->>UserService: 返回创建的用户
        UserService-->>AuthService: 用户创建成功
        AuthService->>AuthService: 生成JWT令牌
        AuthService-->>Frontend: 返回用户信息和令牌
        Frontend-->>User: 注册成功,自动登录
    else 邮箱已存在
        UserService-->>AuthService: 返回错误
        AuthService-->>Frontend: 返回错误信息
        Frontend-->>User: 显示邮箱已存在提示
    end

8. Database Schema

将概念数据模型转换为具体的数据库Schema:

8.1 MySQL数据库Schema

-- 用户表
CREATE TABLE users (
    id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
    email VARCHAR(255) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL COMMENT 'bcrypt加密后的密码',
    name VARCHAR(100) NOT NULL,
    role ENUM('admin', 'user') NOT NULL DEFAULT 'user',
    status ENUM('active', 'inactive', 'suspended') NOT NULL DEFAULT 'active',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_email (email),
    INDEX idx_role (role),
    INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 角色表(支持权限扩展)
CREATE TABLE roles (
    id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
    name VARCHAR(50) UNIQUE NOT NULL,
    permissions JSON NOT NULL COMMENT '权限列表JSON数组',
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_name (name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 用户角色关联表(多对多关系)
CREATE TABLE user_roles (
    user_id CHAR(36) NOT NULL,
    role_id CHAR(36) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (user_id, role_id),
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
    FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE,
    INDEX idx_user_id (user_id),
    INDEX idx_role_id (role_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

8.2 TypeORM实体定义

// apps/api/src/entities/User.entity.ts
@Entity('users')
export class User {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ unique: true })
  email: string;

  @Column()
  password: string;

  @Column()
  name: string;

  @Column({ type: 'enum', enum: ['admin', 'user'], default: 'user' })
  role: string;

  @Column({ type: 'enum', enum: ['active', 'inactive', 'suspended'], default: 'active' })
  status: string;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;
}

9. Frontend Architecture

定义前端特定的架构细节:

9.1 组件架构

组件组织

src/
├── components/
│   ├── ui/                    # 基础UI组件(可复用)
│   ├── forms/                 # 表单组件
│   ├── layout/                # 布局组件
│   └── features/              # 功能组件

组件模板

// components/ui/button/Button.tsx
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';
  size?: 'default' | 'sm' | 'lg' | 'icon';
}

const Button = forwardRef<HTMLButtonElement, ButtonProps>(({ className, variant = 'default', size = 'default', ...props }, ref) => {
  return (
    <button
      className={cn(
        'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors',
        // ...样式类
      )}
      ref={ref}
      {...props}
    />
  );
});

9.2 状态管理架构

状态结构

// stores/auth-store.ts
export const useAuthStore = create<AuthState>((set, get) => ({
  user: null,
  token: localStorage.getItem('token'),
  isLoading: false,

  login: async (email: string, password: string) => {
    set({ isLoading: true });
    try {
      const response = await apiClient.auth.login.$post({ json: { email, password } });
      const { user, token } = await response.json();

      localStorage.setItem('token', token);
      set({ user, token, isLoading: false });
    } catch (error) {
      set({ isLoading: false });
      throw error;
    }
  },
}));

9.3 路由架构

路由组织

// routes/index.tsx
export const router = createBrowserRouter([
  {
    path: '/auth',
    element: <AuthLayout />,
    children: [
      { path: 'login', element: <LoginPage /> },
    ],
  },
  {
    path: '/',
    element: <AppLayout />,
    children: [
      { index: true, element: <DashboardPage /> },
      { path: 'users', element: <UsersPage /> },
    ],
  },
]);

保护路由模式

// components/auth/ProtectedRoute.tsx
export function ProtectedRoute({ children }: ProtectedRouteProps) {
  const { user, isLoading, initialize } = useAuthStore();
  const navigate = useNavigate();

  useEffect(() => {
    if (!isLoading && !user) {
      navigate('/auth/login');
    }
  }, [user, isLoading, navigate]);

  return user ? <>{children}</> : null;
}

9.4 前端服务层

API客户端设置

// lib/api-client.ts
export const apiClient = hc<AppType>(import.meta.env.VITE_API_URL || 'http://localhost:8080');

// 请求拦截器 - 自动添加token
apiClient._fetch = async (input, init) => {
  const token = localStorage.getItem('token');
  const headers = new Headers(init?.headers);

  if (token) {
    headers.set('Authorization', `Bearer ${token}`);
  }

  return fetch(input, { ...init, headers });
};

10. Backend Architecture

定义后端特定的架构细节:

10.1 服务架构

控制器/路由组织

src/
├── routes/                 # API路由
├── services/              # 业务服务
├── middleware/            # 中间件
├── entities/              # TypeORM实体
└── lib/                   # 工具库

控制器模板

// routes/users.ts
export const userRoutes = new Hono()
  .use('*', authMiddleware)

  .get('/', async (c) => {
    const { page, limit } = c.req.query();
    const users = await userService.getUsers({
      page: page ? parseInt(page) : 1,
      limit: limit ? parseInt(limit) : 20
    });
    return c.json(users);
  })

  .get('/:id', validationMiddleware(userSchema.idParam, 'param'), async (c) => {
    const { id } = c.req.valid('param');
    const user = await userService.getUserById(id);
    return c.json(user);
  });

10.2 数据库架构

Schema设计

// entities/User.entity.ts
@Entity('users')
export class User {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ unique: true })
  email: string;

  @Column()
  password: string;

  @BeforeInsert()
  @BeforeUpdate()
  async hashPassword() {
    if (this.password) {
      this.password = await bcrypt.hash(this.password, 12);
    }
  }
}

数据访问层

// services/GenericCRUDService.ts
export abstract class GenericCRUDService<T extends BaseEntity> {
  constructor(protected repository: Repository<T>) {}

  async findAll(query: any): Promise<{ data: T[]; total: number }> {
    const [data, total] = await this.repository.findAndCount({
      skip: (query.page - 1) * query.limit,
      take: query.limit,
    });
    return { data, total };
  }
}

10.3 认证架构

认证流程

sequenceDiagram
    participant Client as 客户端
    participant Middleware as 认证中间件
    participant Redis as Redis
    participant Service as 用户服务

    Client->>Middleware: 请求携带JWT
    Middleware->>Middleware: 解析JWT令牌
    Middleware->>Redis: 检查令牌是否在黑名单
    Redis-->>Middleware: 返回检查结果

    alt 令牌有效
        Middleware->>Service: 根据用户ID获取用户信息
        Service-->>Middleware: 返回用户数据
        Middleware-->>Client: 认证通过,继续处理
    else 令牌无效或过期
        Middleware-->>Client: 返回401错误
    end

中间件/守卫

// middleware/auth.ts
export const authMiddleware = createMiddleware(async (c, next) => {
  const authHeader = c.req.header('Authorization');

  if (!authHeader?.startsWith('Bearer ')) {
    return c.json({ error: 'Unauthorized' }, 401);
  }

  const token = authHeader.slice(7);

  try {
    // 检查Redis黑名单
    const isBlacklisted = await redis.get(`blacklist:${token}`);
    if (isBlacklisted) {
      return c.json({ error: 'Token revoked' }, 401);
    }

    // 验证JWT
    const decoded = jwt.verify(token, process.env.JWT_SECRET!) as { userId: string };
    c.set('userId', decoded.userId);

    await next();
  } catch (error) {
    return c.json({ error: 'Invalid token' }, 401);
  }
});

11. Unified Project Structure

创建包含前端和后端的Monorepo结构:

项目目录结构

shadcn-admin-template/
├── .github/                    # CI/CD工作流
├── apps/                       # 应用包
│   ├── admin/                  # 管理后台前端
│   ├── web/                    # 用户Web端
│   └── api/                    # 后端API应用
├── packages/                   # 共享包
│   ├── shared/                 # 共享类型/工具
│   ├── ui/                     # 共享UI组件
│   └── config/                 # 共享配置
├── infrastructure/             # 基础设施即代码
├── scripts/                    # 构建/部署脚本
├── docs/                       # 文档
├── .env.example                # 环境变量模板
├── package.json                # 根package.json
├── turbo.json                  # Turborepo配置
└── README.md

Monorepo配置 (turbo.json)

{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

根package.json脚本

{
  "scripts": {
    "dev": "turbo run dev",
    "build": "turbo run build",
    "lint": "turbo run lint",
    "test": "turbo run test",
    "dev:admin": "turbo run dev --filter=admin",
    "dev:api": "turbo run dev --filter=api"
  }
}

12. Development Workflow

定义全栈应用程序的开发设置和工作流:

12.1 Local Development Setup

Prerequisites

# 检查Node.js版本
node --version  # 需要 >= 20.18.3

# 检查Docker和Docker Compose
docker --version
docker-compose --version

# 检查MySQL和Redis客户端
mysql --version
redis-cli --version

Initial Setup

# 克隆项目
git clone <repository-url>
cd shadcn-admin-template

# 安装依赖
npm install

# 复制环境变量文件
cp .env.example .env

# 启动开发环境
npm run dev

# 或者启动特定服务
npm run dev:admin    # 只启动管理后台
npm run dev:api      # 只启动API服务

Development Commands

# 启动所有服务
npm run dev

# 启动前端开发服务器(管理后台)
cd apps/admin && npm run dev

# 启动后端开发服务器
cd apps/api && npm run dev

# 运行测试
npm run test

# 运行类型检查
npm run type-check

# 运行代码检查
npm run lint

12.2 Environment Configuration

Required Environment Variables

# 前端 (.env.local)
VITE_API_URL=http://localhost:8080
VITE_APP_NAME=shadcn管理后台

# 后端 (.env)
NODE_ENV=development
PORT=8080
JWT_SECRET=your-super-secret-jwt-key
JWT_EXPIRES_IN=7d

# 数据库连接
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=your-mysql-password
DB_DATABASE=d8dai

# Redis连接
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=

# MinIO连接
MINIO_ENDPOINT=localhost
MINIO_PORT=9000
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin
MINIO_BUCKET=uploads

# 共享环境变量
APP_NAME=shadcn-admin-template
LOG_LEVEL=info

开发环境快速启动脚本

#!/bin/bash
# scripts/start-dev.sh

echo "启动开发环境..."

# 启动Docker服务
docker-compose up -d

# 等待数据库就绪
echo "等待数据库就绪..."
sleep 10

# 运行数据库迁移
cd apps/api && npx typeorm migration:run

# 启动开发服务器
cd ../.. && npm run dev

13. Deployment Architecture

基于平台选择定义部署策略:

13.1 部署策略

前端部署:

  • 平台: 多八多云端容器环境(8080端口)
  • 构建命令: npm run build
  • 输出目录: dist/
  • CDN/边缘: 容器内Nginx反向代理

后端部署:

  • 平台: 多八多云端容器环境(8080端口)
  • 构建命令: npm run build
  • 部署方式: Node.js进程管理(PM2)

13.2 CI/CD流水线

# .github/workflows/ci.yaml
name: CI Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run type check
        run: npm run type-check

      - name: Run linting
        run: npm run lint

      - name: Run tests
        run: npm run test

  build:
    runs-on: ubuntu-latest
    needs: test
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Build applications
        run: npm run build

      - name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          name: build-artifacts
          path: |
            apps/admin/dist
            apps/api/dist

13.3 环境配置

环境 前端URL 后端URL 用途
开发 http://localhost:3000 http://localhost:8080 本地开发
测试 http://test.example.com http://api.test.example.com 预生产测试
生产 http://app.example.com http://api.example.com 生产环境

14. Security and Performance

定义全栈应用程序的安全和性能考虑:

14.1 安全要求

前端安全:

  • CSP头: default-src 'self'; script-src 'self' 'unsafe-inline'
  • XSS防护: 输入验证和输出编码
  • 安全存储: HTTP-only cookies存储敏感信息

后端安全:

  • 输入验证: Zod schema验证所有输入
  • 速率限制: 每分钟100次请求限制
  • CORS策略: 仅允许信任的域名

认证安全:

  • 令牌存储: HTTP-only cookies + secure标志
  • 会话管理: JWT短期令牌 + Redis刷新令牌
  • 密码策略: 最小长度8位,包含数字和特殊字符

14.2 性能优化

前端性能:

  • 包大小目标: < 500KB gzipped
  • 加载策略: 代码分割和懒加载
  • 缓存策略: Service Worker缓存静态资源

后端性能:

  • 响应时间目标: < 100ms P95
  • 数据库优化: 索引优化和查询缓存
  • 缓存策略: Redis缓存频繁访问数据

15. Testing Strategy

定义全栈应用程序的全面测试方法:

15.1 测试金字塔

        E2E Tests
       /          \\
Integration Tests
     /                \\
Frontend Unit  Backend Unit

15.2 测试组织

前端测试:

apps/admin/tests/
├── unit/          # 单元测试
├── components/    # 组件测试
├── hooks/         # Hook测试
└── __mocks__/     # 测试mock

后端测试:

apps/api/tests/
├── unit/          # 单元测试
├── integration/   # 集成测试
└── __mocks__/     # 测试mock

E2E测试:

tests/e2e/
├── auth/          # 认证流程测试
├── users/         # 用户管理测试
└── support/       # 测试支持

16. Coding Standards

为AI代理定义最小但关键的标准。专注于防止常见错误的项目特定规则。这些将被开发代理使用。

16.1 关键全栈规则

类型共享: 始终在packages/shared中定义类型并从那里导入 API调用: 永远不要直接进行HTTP调用 - 使用服务层 环境变量: 仅通过配置对象访问,永远不要直接使用process.env 错误处理: 所有API路由必须使用标准错误处理程序 状态更新: 永远不要直接改变状态 - 使用适当的状态管理模式

16.2 命名约定

元素 前端 后端 示例
组件 PascalCase - UserProfile.tsx
Hooks camelCase带'use' - useAuth.ts
API路由 - kebab-case /api/user-profile
数据库表 - snake_case user_profiles

17. Error Handling Strategy

定义前端和后端的统一错误处理:

17.1 错误流程

sequenceDiagram
    participant Client as 客户端
    participant API as API网关
    participant Service as 业务服务
    participant DB as 数据库

    Client->>API: API请求
    API->>Service: 调用业务逻辑
    Service->>DB: 数据库操作

    alt 操作成功
        DB-->>Service: 成功结果
        Service-->>API: 业务数据
        API-->>Client: 成功响应
    else 发生错误
        DB-->>Service: 数据库错误
        Service->>Service: 捕获并包装错误
        Service-->>API: 标准错误格式
        API->>API: 添加请求ID和时间戳
        API-->>Client: 错误响应
        Client->>Client: 统一错误处理
        Client-->>User: 显示友好错误信息
    end

17.2 错误响应格式

interface ApiError {
  error: {
    code: string;
    message: string;
    details?: Record<string, any>;
    timestamp: string;
    requestId: string;
  };
}

18. Monitoring and Observability

定义全栈应用程序的监控策略:

18.1 监控栈

前端监控: 浏览器性能API + 自定义指标 后端监控: OpenTelemetry + Prometheus 错误跟踪: Sentry或类似服务 性能监控: 应用性能管理(APM)工具

18.2 关键指标

前端指标:

  • 核心Web指标(LCP, FID, CLS)
  • JavaScript错误率
  • API响应时间
  • 用户交互跟踪

后端指标:

  • 请求速率
  • 错误率
  • 响应时间(P50, P95, P99)
  • 数据库查询性能