# Nodejs Backend Engineering

> Use when designing, implementing, reviewing, or refactoring Node.js/TypeScript backend systems and APIs across any framework, especially for architecture decisions, DDD tactical modeling, bounded contexts, vertical slices, hexagonal ports and adapters, clean boundaries, service/repository/client organization, domain events, outbox, CQRS, queues, validation, errors, observability, startup/shutdown, resource lifecycle, testing strategy, and maintainable full-stack backend engineering.

- Skill: `ly0o0o/nodejs-backend-engineering` (Agent Skill, multi-file: 12 files)
- Install (CLI): `npx skillmds@latest add ly0o0o/nodejs-backend-engineering`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ly0o0o/nodejs-backend-engineering/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: ly0o0o (https://skillmd.com/u/ly0o0o)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/ly0o0o/nodejs-backend-engineering

---


# Node.js Backend Engineering

## 定位

像老到、代码洁癖但不炫技的全栈工程师一样设计 Node.js 后端：先理解业务语言和变化方向，再选择最小足够的结构；先保护数据、权限、幂等和可观测性，再谈模式；先让一个真实用例闭环，再抽象。

架构不是目录名。架构是边界、依赖方向、状态一致性、故障语义和演进路径。

代码细节、语法洁癖、类型写法和局部重构交给 `nodejs-code-style`。本 Skill 负责系统组织、架构选择、DDD/ports-adapters/CQRS/事件/生命周期等后端工程判断。

## 工作流

1. 读现状。
   - 找入口：HTTP/RPC/CLI/queue/cron/webhook。
   - 找核心对象：用户、任务、订单、集合、额度、支付、消息、文件等。
   - 找副作用：DB、缓存、队列、第三方、邮件、对象存储、AI 调用。
   - 找风险：权限、租户、额度、幂等、事务、重试、迁移、部署顺序。

2. 选架构形态。
   - 先用下面的“选择路由器”，不要默认套 DDD 或 Clean Architecture。
   - 一个系统可以组合多种形态，但每个用例只能有一个清晰主组织方式。

3. 定边界。
   - 入口层做协议适配和校验。
   - 用例层编排业务动作和事务语义。
   - 领域层表达规则、不变量、状态流转。
   - repository/client/gateway 隔离外部世界。
   - runtime 层处理配置、日志、指标、健康检查、启动关闭。

4. 垂直落地。
   - 按一个用户可感知的用例完成：契约、schema、service/domain、repository/client、错误、日志、测试。
   - 不把大规模重构和新行为混成一个 diff。

5. 验证和记录。
   - 跑最小必要验证：type-check、test、lint、build、局部 smoke。
   - 架构方向影响长期演进时，写 ADR 或更新已有设计文档。

## 架构选择路由器

| 情况 | 默认选择 | 不要做 |
|---|---|---|
| 简单 CRUD、规则少、生命周期短 | transaction script 或薄 service | 为每张表创建 entity/repository/interface 工厂链 |
| 一个功能从入口到 DB 独立变化 | vertical slice / feature-first | 按技术层拆到满项目跳转 |
| 多个用例共享事务、权限、状态流转 | service + repository + domain rules | 把规则塞进 route 或 repository |
| 业务语言复杂，不变量多，状态非法组合多 | DDD tactical model：aggregate、value object、domain service | 只有 CRUD 也建贫血 entity |
| 框架、DB、队列、第三方不该污染核心 | ports and adapters / hexagonal boundary | 为每个函数都抽 port |
| 读模型和写模型差异很大 | CQRS / read model | 为普通列表查询上 CQRS |
| 一个事实发生后触发多个独立副作用 | domain event，可靠异步用 outbox | 一个同步副作用也做事件总线 |
| 遗留系统要逐步替换 | strangler + adapter + ADR | 一次性重写或边迁移边改业务语义 |

## 组合方式

常见优雅组合：

- `vertical slice + code style`：多数业务功能的默认落地方式。
- `vertical slice + DDD`：复杂用例内部用 aggregate/value object 保护规则。
- `hexagonal + external clients`：第三方、DB、队列、AI provider 通过 adapter 隔离。
- `DDD + domain events + outbox`：跨 aggregate/module 副作用需要最终一致性。
- `CQRS + read model`：写侧保护不变量，读侧为查询体验和性能服务。
- `strangler + ADR`：老系统逐步替换，每个阶段记录取舍和回滚路径。

避免组合成“全家桶架构”。每加一层，必须能说清楚它降低了什么复杂度。

## 默认依赖方向

```text
route/controller/worker -> use-case/application service -> domain rules
                                  |                         ^
                                  v                         |
                         repository/client/gateway --------+
```

原则：

- domain 不依赖框架、DB、HTTP、env、logger。
- service/use-case 不接具体 HTTP context，不返回 response。
- repository 管持久化和 JSON blob 边界，不调用第三方 API。
- client/gateway 管第三方协议、认证、超时、重试、错误映射，不改本地业务状态。
- worker/consumer 只管消息接收、ack/retry 策略和分发。

## DDD 使用门槛

DDD 适合复杂业务，不适合装饰普通 CRUD。满足多个条件再用：

- 业务专家和代码需要共享一套稳定语言。
- 状态流转和不变量比数据表更重要。
- 一个操作内必须保护一致性边界。
- 规则散落导致重复 bug 或沟通成本高。
- 模块边界和团队边界正在变得重要。

如果只是增删改查、字段映射或简单列表查询，优先保持简单。

## 文件组织

优先按业务能力组织，而不是默认按技术层堆目录。已有项目是 layer-first 时，不强行大改；在现有结构里保持边界即可。

好名字：

- `billing`
- `quotaReservation`
- `taskExecution`
- `creatorLookup`
- `collectionResult`

警惕：

- `utils`
- `helpers`
- `common`
- `manager`
- `core`
- `processor` 但什么都处理

## 硬规则

- 不把业务逻辑塞进 route、queue consumer、middleware 或脚本入口。
- 不让 service 依赖具体 HTTP framework request/context。
- 不让第三方 response、DB JSON blob、AI provider 原始输出传遍业务层。
- 不在没有幂等和重试设计前修改 ack/retry/DLQ 语义。
- 不把安全、鉴权、额度、租户隔离、数据写入只交给前端、prompt、注释或约定。
- 不为单测提前抽一堆 interface；生产边界需要时再抽。
- 不写吞错后返回空结果的兜底，除非业务明确允许且可观测。
- 不用 DDD、Clean、CQRS、Repository 这些词掩盖贫血模型和无意义跳转。

## 按需读取

- `references/architecture-decision-router.md`：架构形态选择、组合和反组合。
- `references/ddd-tactical-modeling.md`：Bounded Context、Ubiquitous Language、Aggregate、Value Object、Domain Event、ACL。
- `references/ports-adapters-and-clean-boundaries.md`：Hexagonal/Clean 边界、port/adapter 何时抽、何时别抽。
- `references/code-organization.md`：目录、文件职责、导出边界、feature-first 与 layer-first。
- `references/design-patterns.md`：Strategy、Adapter、Repository、State Machine、Pipeline、Outbox 等模式选择。
- `references/lifecycle-operations.md`：配置、日志、指标、AsyncLocalStorage、AbortSignal、queue、cache、shutdown。
- `references/real-code-patterns.md`：use case、aggregate、repository port、client adapter、domain event/outbox 代码样例。
- `references/evolution-and-decisions.md`：ADR、strangler、增量迁移、重构与行为变更分离。
- `references/review-checklist.md`：后端工程评审清单。
- `references/research-notes.md`：参考资料和取舍来源。

