Files
seclusion/CLAUDE.md
charilezhou df69eedcd9 refactor(api): 移除 barrel imports 改用直接导入
- 将所有模块的 barrel imports 改为直接导入具体文件
- 删除不再需要的 index.ts 文件(共 10 个)
- 更新 CLAUDE.md 添加禁止后端使用 barrel imports 的规范
- 避免循环依赖问题,提高代码可追溯性

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 14:39:33 +08:00

9.2 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Seclusion 是一个基于 Next.js + NestJS 的 Monorepo 项目模板,使用 pnpm workspace + Turborepo 管理。

环境要求

  • Node.js >= 20.0.0
  • pnpm >= 9.0.0

Commands

# 启动数据库 (PostgreSQL + Redis)
docker compose -f deploy/docker-compose.yml up -d

# 开发(同时启动前后端)
pnpm dev

# 构建
pnpm build

# 代码检查
pnpm lint
pnpm format        # 格式化
pnpm format:check  # 检查格式

# 测试
pnpm test
cd apps/api && pnpm test:watch  # 单个测试文件监听
cd apps/api && pnpm test:cov    # 测试覆盖率报告

# 数据库
pnpm db:generate   # 生成 Prisma Client
pnpm db:push       # 推送 schema 到数据库
pnpm db:migrate    # 运行迁移
cd apps/api && pnpm db:studio   # 打开 Prisma Studio

Architecture

Monorepo 结构

  • apps/web - Next.js 16 前端 (端口 3000),使用 React 19 + Tailwind CSS v4
  • apps/api - NestJS 10 后端 (端口 4000API 文档: /api/docs)
  • packages/shared - 共享类型定义、工具函数和加密模块
  • packages/eslint-config - 共享 ESLint 9 flat config 配置
  • packages/typescript-config - 共享 TypeScript 配置

前端架构 (apps/web)

状态管理分类

状态类型 管理方式 示例
服务端状态 TanStack Query 用户列表、详情数据
客户端全局状态 Zustand 认证信息、主题设置
组件本地状态 useState 表单输入、弹窗开关
URL 状态 Next.js Router 分页参数、筛选条件

数据请求分层

Component → Hook (TanStack Query) → Service → http
  • Service 层 (services/*.service.ts): 封装 API 调用
  • Hook 层 (hooks/use*.ts): 封装 TanStack Query提供 queryKey 管理
  • http (lib/http.ts): Axios HTTP 客户端封装含加密处理、Token 自动刷新

后端模块 (apps/api)

NestJS 采用模块化架构:

  • PrismaModule - 全局数据库服务,内置软删除扩展
  • CryptoModule - 全局加密服务AES-256-GCM 请求/响应加密
  • AuthModule - JWT 认证注册、登录、token 验证)
  • UserModule - 用户 CRUD继承 CrudService 基类
  • CaptchaModule - 验证码服务,支持多场景验证

认证流程:使用 @Public() 装饰器标记公开接口,其他接口需要 JWT Bearer Token。使用 @CurrentUser() 装饰器获取当前登录用户信息(类型为 AuthUser)。

后端导入规范:禁止使用 Barrel Imports

后端代码禁止使用 index.ts 统一导出barrel exports必须直接从具体文件导入

// ❌ 错误 - 使用 barrel import
import { RequirePermission } from '@/permission';
import { PrismaService } from '@/prisma';

// ✅ 正确 - 直接导入具体文件
import { RequirePermission } from '@/permission/decorators/require-permission.decorator';
import { PrismaService } from '@/prisma/prisma.service';

// ✅ 正确 - 模块内部使用相对路径
import { RequirePermission } from '../decorators/require-permission.decorator';

原因:

  • 避免循环依赖
  • 更清晰的依赖关系
  • 更好的 IDE 跳转体验

软删除机制

PrismaService 使用 $extends 实现底层自动软删除:

  • 查询自动过滤: findManyfindFirstfindUniquecount 自动添加 deletedAt: null 条件
  • 删除自动转换: deletedeleteMany 自动转换为设置 deletedAt 时间戳
  • 绕过过滤: 显式指定 deletedAt 条件可查询已删除数据,如 where: { deletedAt: { not: null } }

启用软删除的模型在 apps/api/src/prisma/prisma.service.tsSOFT_DELETE_MODELS 数组中配置。

通信加密

基于 AES-256-GCM 的请求/响应 Body 加密,通过 ENABLE_ENCRYPTION 环境变量控制:

  • 后端: CryptoModule 提供 CryptoServiceEncryptionInterceptor
  • 前端: apps/web/src/lib/crypto.ts 封装加密客户端
  • 共享: packages/shared/src/crypto/ 提供跨平台加密实现
  • 跳过加密: 使用 @SkipEncryption() 装饰器标记不需要加密的接口

CRUD 基类

apps/api/src/common/crud/ 提供通用 CRUD 服务和 DTO

  • CrudService<T> - 泛型基类,提供分页查询、软删除、恢复等方法
  • PaginationQueryDto - 分页查询参数 DTO
  • createPaginatedResponseDto(ItemDto) - 分页响应 DTO 工厂函数

分页响应 DTO 使用示例:

import { createPaginatedResponseDto } from '@/common/crud';

export class UserResponseDto { ... }
export class PaginatedUserResponseDto extends createPaginatedResponseDto(UserResponseDto) {}

Swagger 文档规范

所有 API 接口必须完整定义 Swagger 文档:

Controller 装饰器要求:

  • @ApiTags() - 接口分组标签
  • @ApiOperation() - 接口描述
  • @ApiOkResponse() / @ApiCreatedResponse() - 成功响应类型
  • @ApiBearerAuth() - 需要认证的接口(非 @Public() 接口)

DTO 定义要求:

  • 所有请求和响应都必须定义对应的 DTO class
  • 使用 @ApiProperty() / @ApiPropertyOptional() 装饰每个字段
  • 必须包含 exampledescription 属性

示例:

// dto/example.dto.ts
export class ExampleResponseDto implements ExampleResponse {
  @ApiProperty({ example: 'clxxx', description: '记录 ID' })
  id: string;
}

// example.controller.ts
@ApiTags('示例')
@ApiBearerAuth()
@Controller('example')
export class ExampleController {
  @Get(':id')
  @ApiOperation({ summary: '获取示例详情' })
  @ApiOkResponse({ type: ExampleResponseDto, description: '示例详情' })
  findOne(@Param('id') id: string): Promise<ExampleResponseDto> {
    return this.service.findOne(id);
  }
}

共享包使用

// 类型导入
import type { User, AuthUser, UserResponse, TokenPayload } from '@seclusion/shared';
import type { ApiResponse, PaginatedResponse } from '@seclusion/shared';

// 工具函数
import { formatDate, generateId } from '@seclusion/shared';

// 加密模块
import { createBrowserCrypto, createNodeCrypto } from '@seclusion/shared/crypto';

// 常量(使用 const + type 模式)
import { CaptchaScene } from '@seclusion/shared';

注意: packages/shared 中的工具函数应优先使用 lodash-es 实现。

前后端共享类型设计规范

为避免类型重复定义和前后端不一致,遵循以下设计原则:

类型定义位置

类型 定义位置 说明
枚举/常量 packages/shared 使用 const + type 模式
接口类型 packages/shared 纯类型定义,无装饰器
后端 DTO apps/api 实现共享接口,添加 Swagger/验证装饰器
前端特有类型 apps/web/src/types/ 组件 Props、表单状态等

枚举定义方式(使用 const + type 替代 enum

// packages/shared/src/types/index.ts
export const CaptchaScene = {
  LOGIN: 'login',
  REGISTER: 'register',
} as const;
export type CaptchaScene = (typeof CaptchaScene)[keyof typeof CaptchaScene];

后端 DTO 实现共享接口

// apps/api/src/xxx/dto/example.dto.ts
import type { ExampleResponse } from '@seclusion/shared';

export class ExampleResponseDto implements ExampleResponse {
  @ApiProperty({ description: '示例字段', example: 'value' })
  field: string;
}

新增共享类型检查清单

  • 类型定义在 packages/shared/src/types/
  • 枚举使用 const + type 模式
  • 后端 DTO 使用 implements 实现共享接口
  • 前端直接从 @seclusion/shared 导入使用

Environment Variables

环境变量在各应用目录下独立配置:

位置 文件 用途 是否提交
apps/api .env.example 后端配置模板
apps/api .env 后端默认配置
apps/api .env.local 后端本地覆盖(敏感信息)
apps/web .env 前端默认配置
apps/web .env.local 前端本地覆盖

加密相关配置

# apps/api/.env
ENABLE_ENCRYPTION=false
ENCRYPTION_KEY=<32字节Base64密钥>

# apps/web/.env
NEXT_PUBLIC_ENABLE_ENCRYPTION=false
NEXT_PUBLIC_ENCRYPTION_KEY=<与后端相同的密钥>

生成密钥: openssl rand -base64 32

Documentation

项目文档统一存放在 docs/ 目录下:

docs/
├── web/                    # 前端相关文档
│   └── DESIGN.md          # Web 前端设计文档
├── api/                    # 后端相关文档
└── shared/                 # 共享模块文档
文档 说明
docs/web/DESIGN.md Web 前端整体设计(技术栈、目录结构、状态管理、实施计划)

Key Files

  • deploy/docker-compose.yml - PostgreSQL + Redis 容器配置
  • apps/api/prisma/schema.prisma - 数据库模型定义PostgreSQLID 使用 cuid2
  • apps/api/src/prisma/prisma.service.ts - Prisma 服务,含软删除扩展
  • apps/api/src/common/crud/ - CRUD 基类和分页 DTO
  • apps/api/src/common/crypto/ - 后端加密模块
  • packages/shared/src/types/ - 共享类型定义
  • packages/shared/src/crypto/ - 跨平台加密实现
  • apps/web/src/types/ - 前端特有类型定义