本文档概述了shadcn全栈管理后台启动模板的完整全栈架构,包括后端系统、前端实现及其集成。它作为AI驱动开发的单一事实来源,确保整个技术栈的一致性。
这种统一方法将传统上分离的后端和前端架构文档结合起来,为现代全栈应用程序简化了开发流程,这些应用程序中这些关注点日益交织在一起。
shadcn全栈管理后台启动模板采用现代化的Jamstack架构风格,结合React前端和Hono后端框架。前端基于Vite构建工具和Tailwind CSS样式方案,后端使用TypeORM进行数据库操作和MySQL作为主数据库。架构采用单体部署方式,通过清晰的代码分离结构确保前后端开发一致性。该架构通过RESTful API规范、OpenAPI文档生成和类型安全的客户端集成,实现了PRD中要求的完整用户认证、权限管理和生产就绪状态。
基于PRD要求和开发环境配置,采用多八多云端开发容器环境作为部署平台:
平台选择:多八多云端容器环境
结构: Monorepo结构 Monorepo工具: Turborepo 包组织策略:
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等]
Jamstack架构: 静态站点生成与无服务器API结合 - 理由: 为内容密集型应用提供最佳性能和可扩展性 组件化UI: 基于TypeScript的可复用React组件 - 理由: 在大型代码库中保持可维护性和类型安全 仓库模式: 抽象数据访问逻辑 - 理由: 支持测试和未来数据库迁移的灵活性 API网关模式: 所有API调用的单一入口点 - 理由: 集中化认证、速率限制和监控
这是项目的最终技术选择。与用户合作确定所有选择。此表是单一事实来源 - 所有开发必须使用这些确切版本。
| 类别 | 技术 | 版本 | 用途 | 理由 |
|---|---|---|---|---|
| 前端语言 | 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 | 样式方案 | 实用优先,设计系统友好 |
基于PRD需求,定义将在前端和后端之间共享的核心数据模型/实体:
用途: 管理系统用户账户信息,支持认证和权限管理
关键属性:
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';
关系:
用途: 管理系统角色和权限配置
关键属性:
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过期时间自动清理
基于技术栈中选择的REST API风格,创建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'
后端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定义:
// 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(),
};
基于架构模式、技术栈和数据模型,识别全栈中的主要逻辑组件/服务:
责任: 处理用户认证、注册、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客户端责任: 管理用户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模式、数据验证责任: 提供通用的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泛型、类继承、装饰器模式责任: 自动生成标准RESTful路由,支持通用CRUD操作 关键接口:
GET /entity - 获取列表(支持分页、过滤、排序)GET /entity/:id - 获取单个实体POST /entity - 创建实体PUT /entity/:id - 更新实体DELETE /entity/:id - 删除实体
依赖: GenericCRUDService、Zod验证
技术栈: Hono路由工厂、OpenAPI自动生成flowchart TB
Frontend[前端应用] --> APIGateway[API网关]
APIGateway --> AuthService[认证服务]
APIGateway --> UserService[用户服务]
APIGateway --> RoleService[角色服务]
AuthService --> Redis[Redis缓存]
UserService --> DB[(MySQL数据库)]
RoleService --> DB
AuthService --> UserService
UserService --> RoleService
使用序列图说明关键系统工作流:
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
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
将概念数据模型转换为具体的数据库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;
// 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;
}
定义前端特定的架构细节:
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}
/>
);
});
// 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;
}
},
}));
// 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;
}
// 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 });
};
定义后端特定的架构细节:
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);
});
// 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 };
}
}
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);
}
});
创建包含前端和后端的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
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}
{
"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"
}
}
定义全栈应用程序的开发设置和工作流:
# 检查Node.js版本
node --version # 需要 >= 20.18.3
# 检查Docker和Docker Compose
docker --version
docker-compose --version
# 检查MySQL和Redis客户端
mysql --version
redis-cli --version
# 克隆项目
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服务
# 启动所有服务
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
# 前端 (.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
基于平台选择定义部署策略:
前端部署:
npm run builddist/后端部署:
npm run build# .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
| 环境 | 前端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 | 生产环境 |
定义全栈应用程序的安全和性能考虑:
前端安全:
default-src 'self'; script-src 'self' 'unsafe-inline'后端安全:
认证安全:
前端性能:
后端性能:
定义全栈应用程序的全面测试方法:
E2E Tests
/ \\
Integration Tests
/ \\
Frontend Unit Backend Unit
前端测试:
apps/admin/tests/
├── unit/ # 单元测试
├── components/ # 组件测试
├── hooks/ # Hook测试
└── __mocks__/ # 测试mock
后端测试:
apps/api/tests/
├── unit/ # 单元测试
├── integration/ # 集成测试
└── __mocks__/ # 测试mock
E2E测试:
tests/e2e/
├── auth/ # 认证流程测试
├── users/ # 用户管理测试
└── support/ # 测试支持
为AI代理定义最小但关键的标准。专注于防止常见错误的项目特定规则。这些将被开发代理使用。
类型共享: 始终在packages/shared中定义类型并从那里导入 API调用: 永远不要直接进行HTTP调用 - 使用服务层 环境变量: 仅通过配置对象访问,永远不要直接使用process.env 错误处理: 所有API路由必须使用标准错误处理程序 状态更新: 永远不要直接改变状态 - 使用适当的状态管理模式
| 元素 | 前端 | 后端 | 示例 |
|---|---|---|---|
| 组件 | PascalCase | - | UserProfile.tsx |
| Hooks | camelCase带'use' | - | useAuth.ts |
| API路由 | - | kebab-case | /api/user-profile |
| 数据库表 | - | snake_case | user_profiles |
定义前端和后端的统一错误处理:
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
interface ApiError {
error: {
code: string;
message: string;
details?: Record<string, any>;
timestamp: string;
requestId: string;
};
}
定义全栈应用程序的监控策略:
前端监控: 浏览器性能API + 自定义指标 后端监控: OpenTelemetry + Prometheus 错误跟踪: Sentry或类似服务 性能监控: 应用性能管理(APM)工具
前端指标:
后端指标: