Skip to content

计划覆盖对照 ​

原计划(NestJS 学习计划,Java/Spring 背景)的每一项,都在这里对应到网站上讲解它的小节。读完这里列出的所有小节, 就覆盖了整个计划。

计划的通用章节 ​

计划章节内容对应小节
开头2026 年 11 月 9 日开始,共 11 天,前置要求,技术栈,贯穿始终的 TaskFlow 项目计划与方法
1. 工作方式上午理论(3 小时),下午实践(3 小时),30 分钟写 LEARNINGS.md + 打 jour-XX 标签,11 月 11 日放假,每天一次提交方法、学习日志
2. 日程11 天的主题和交付物日程
3. Spring ↔ NestJS 对照表34 条对应关系Web、依赖注入、数据、请求管道、配置、安全、异步、测试、工具链
4. 事件循环与 thread-per-request一个 JS 线程,处处 await,不做繁重计算,没有 await 的 Promise,Promise.all,WebFlux事件循环、带来的影响、CPU 计算、WebFlux
4. 注入容器类型被擦除,emitDecoratorMetadata,接口要用 token,声明与导出,forwardRef类型擦除、token、没有扫描、循环依赖
4. 生态npm 与 lockfile,没有 JVM,装饰器就是函数生态
6. 领域模型USER、PROJECT、PROJECT_MEMBER、TASK;状态模型、状态
7. Docker Composedb、db-test(tmpfs)、adminer、可选的 redis;.env.exampledocker-compose.yml、.env 文件
8. 仓库结构目标目录结构,命名约定目录结构、约定
9. 进度跟踪J1 到 J11 的勾选框进度跟踪
10. 学习资源官方文档、TypeORM、Fundamentals 课程、Node 事件循环学习资源
11. 常见陷阱8 个陷阱漏写 await、synchronize、直接返回实体、循环依赖、单例里的状态、校验、相等性与 this、@Res()

J1 · Node 与 Nest 基础 ​

计划条目对应小节
Node、事件循环(各个阶段、微任务与宏任务)事件循环
Promise、async/awaitPromise 与 async/await
ES 模块 / CommonJSES 模块与 CommonJS
Nest 项目结构:main.ts、AppModule、AppController、AppServiceNest 项目结构
Nest CLI:nest new、nest g module/controller/service/resourceNest CLI、Nest CLI 速查
npm i -g @nestjs/cli,然后 nest new taskflow生成项目
docker-compose.yml(PostgreSQL + Adminer)Docker Compose
返回 { status: 'ok' } 的 GET /healthGET /health
git 仓库、.gitignore、README.md、LEARNINGS.mdgit 仓库
练习:/block 对比 /ping,再改用 await sleep(5000)事件循环练习
SpringApplication.run ↔ NestFactory.createNest 项目结构

J2 · 控制器、DTO、校验 ​

计划条目对应小节
路由装饰器路由
状态码(@HttpCode)状态码
API 版本API 版本
用类写 DTO,class-validator,class-transformerDTO 与校验
全局 ValidationPipe(whitelist、transform、forbidNonWhitelisted)全局 ValidationPipe
@nestjs/mapped-types:PartialType、PickType、OmitTypeMapped types
nest g resource projects生成资源
带校验的 CreateProjectDto、UpdateProjectDtoDTO
内存版增删改查内存版增删改查
通过 @Query() 和一个 QueryDto 实现分页和过滤分页
@Valid + Bean Validation ↔ ValidationPipe + class-validatorSpring → NestJS
ResponseEntity ↔ 对象 + @HttpCode(或 @Res(),应避免)状态码、陷阱

J3 · 依赖注入与模块 ​

计划条目对应小节
Provider:useClass、useValue、useFactory、useExistingProvider
自定义 token、@Inject、@OptionalToken
Scope:default、request、transient(代价与限制)Scope
模块:imports、exports、@Global模块
动态模块(forRoot、forRootAsync)动态模块
把逻辑独立到 ProjectsService 里ProjectsService
ProjectsStore 抽象(接口 + token),内存实现ProjectsStore
放共用工具的 CommonModuleCommonModule
@Configuration + @Bean ↔ useFactoryProvider
按条件生效的 profile ↔ 根据配置选择 providerProjectsStore

J4 · PostgreSQL 与 TypeORM ​

计划条目对应小节
@nestjs/typeorm、forRoot / forRootAsync / forFeature@nestjs/typeorm
实体、列实体
PostgreSQL 类型:uuid、timestamptz、jsonb、枚举PostgreSQL 类型
Repository:find、findOne、save、softDeleteRepository
QueryBuilderQueryBuilder
synchronize: true 只在开发环境用synchronize
Project 实体Project 实体
用 TypeORM 替换内存实现,不改控制器ProjectsStore 背后的 TypeORM
开发用种子数据种子数据
JpaRepository ↔ Repository<T>;没有派生查询(ILike、QueryBuilder);没有 Page<T>(findAndCount + skip/take)Spring → NestJS、搜索与分页

J5 · 关系、迁移、事务 ​

计划条目对应小节
OneToMany、ManyToOne、ManyToMany关系
加载方式:eager、lazy、relations: []加载
N+1 问题、leftJoinAndSelectN+1
迁移:generate、run、revert;关闭 synchronize迁移
事务:dataSource.transaction()、QueryRunner事务、QueryRunner
关联到 Project 的 Task 实体Task 实体
POST /projects/:id/tasks、PATCH /tasks/:id/status接口
归档项目及其任务(事务)归档
生成第一个迁移并纳入版本控制第一个迁移
@Transactional ↔ 没有声明式的对应物,要把 manager 传下去事务

J6 · 请求管道 ​

计划条目对应小节
执行顺序 Middleware → … → Exception Filters执行顺序
内置 HTTP 异常HTTP 异常
ExceptionFilter、@Catch()、APP_FILTER全局过滤器
管道:ParseUUIDPipe、ParseEnumPipe、自定义管道管道
拦截器:日志、计时、响应映射、缓存拦截器
函数式或类形式的中间件、configure(consumer)中间件
problem+json 格式的全局 AllExceptionsFilterAllExceptionsFilter
TypeORM 错误:唯一约束冲突 → 409,找不到 → 404TypeORM 错误
LoggingInterceptor(耗时、方法、路由)LoggingInterceptor
CorrelationIdMiddlewareCorrelationIdMiddleware
@ControllerAdvice ↔ APP_FILTER;Filter ↔ 中间件;@Around ↔ 拦截器Spring → NestJS

J7 · 配置与日志 ​

计划条目对应小节
ConfigModule.forRoot({ isGlobal, validate })ConfigModule
registerAs、类型化配置类型化配置
校验环境变量 schema(Joi 或 class-validator)校验
日志:Nest 的 Logger 或 nestjs-pino日志
OnModuleInit、OnApplicationShutdown、enableShutdownHooks()生命周期
.env.development、.env.test、.env.example(只有它纳入版本控制).env 文件
数据库、JWT、端口的类型化配置类型化配置
通过 nestjs-pino 输出带 correlationId 的 JSON 日志JSON 日志
@ConfigurationProperties ↔ registerAs;@PostConstruct ↔ OnModuleInit;@PreDestroy ↔ OnModuleDestroy;profile ↔ NODE_ENVSpring → NestJS、多环境配置

J8 · 认证与授权 ​

计划条目对应小节
@nestjs/passport + passport-jwt、@nestjs/jwtPassport 与 JWT
哈希:argon2 或 bcrypt密码哈希
AuthGuard、全局 guard、@Public()全局 guard、公开路由
参数装饰器(@CurrentUser())@CurrentUser()
RBAC:@Roles() + 使用 Reflector 的 RolesGuardRBAC
users 模块(User,角色 ADMIN / MEMBER)users 模块
POST /auth/register、POST /auth/login(refresh token 可选)注册与登录、refresh token
全局 JWT guard,@Public() 公开路由全局 JWT guard
用户只能看到自己的项目用户只能看到自己的项目
SecurityFilterChain ↔ 全局 guard;@PreAuthorize ↔ @Roles;SecurityContextHolder ↔ @CurrentUser()Spring → NestJS

J9 · 事件、定时任务、队列 ​

计划条目对应小节
@nestjs/event-emitter:emit、@OnEvent、异步监听器应用事件
@nestjs/schedule:@Cron、@Interval、@Timeout定时任务
@nestjs/bullmq:processor、重试、退避Redis 任务
监听器抛出的异常不会传回调用方异步错误
task.status.changed 事件 → NotificationsListener事件
每天运行的 OVERDUE 定时任务OVERDUE 定时任务
可选:用 Redis + BullMQ 处理通知BullMQ 队列
ApplicationEventPublisher ↔ EventEmitter2;@EventListener ↔ @OnEvent;@Scheduled ↔ @Cron;JMS / Batch ↔ BullMQSpring → NestJS

J10 · 测试 ​

计划条目对应小节
Jest:describe、it、jest.fn()、jest.mock()、beforeEachJest
带模拟 provider(useValue)的 Test.createTestingModuleTesting module
用 supertest 和专用数据库做端到端测试(Testcontainers 或 Compose)端到端测试、测试数据库
模拟 repository:getRepositoryToken(Entity)模拟 repository
ProjectsService 和 TasksService 的单元测试单元测试
端到端:register → login → 项目 → 任务 → 状态端到端流程
覆盖率阈值、npm run test:cov覆盖率阈值
Mockito ↔ jest.fn() / jest.Mocked<T>;@SpringBootTest + MockMvc ↔ testing module + supertest;@DataJpaTest ↔ 真实数据库Spring → NestJS

J11 · 收尾与上线 ​

计划条目对应小节
@nestjs/swagger:CLI 插件、@ApiProperty、@ApiTags、@ApiBearerAuthSwagger
@nestjs/terminus:数据库、内存、磁盘健康检查
helmet、CORS、@nestjs/throttler安全
多阶段 Dockerfile、非 root、npm ci --omit=devDockerfile
GitLab CI:lint、测试、构建镜像CI
/docs 上的 Swagger/docs 上的 Swagger
Terminus 的 /health(readiness 和 liveness)/health
Dockerfile 以及 Compose 里的 app 服务Docker
.gitlab-ci.yml:install、lint、test、build流水线
最终回顾:LEARNINGS.md、README最终回顾

计划之外 ​

下面这些小节不在计划里,它们来自用当前版本(NestJS 12、TypeORM 1.1、BullMQ 6)搭建 TaskFlow 时实际遇到的问题: