Loading...
Loading...
Compare original and translation side by side
| Dimension | Question |
|---|---|
| Architectural Fit | Does this follow routes → controllers → services → repositories? |
| Business Logic Complexity | How complex is the domain logic? |
| Data Risk | Does this affect critical data paths or transactions? |
| Operational Risk | Does this impact auth, billing, messaging, or infra? |
| Testability | Can this be reliably unit + integration tested? |
| 维度 | 问题 |
|---|---|
| 架构契合度 | 是否遵循路由→控制器→服务→数据仓库的分层结构? |
| 业务逻辑复杂度 | 领域逻辑的复杂程度如何? |
| 数据风险 | 是否会影响关键数据路径或事务? |
| 运维风险 | 是否会影响认证、计费、消息传递或基础设施? |
| 可测试性 | 是否能可靠地进行单元测试与集成测试? |
BFRI = (Architectural Fit + Testability) − (Complexity + Data Risk + Operational Risk)-10 → +10BFRI = (架构契合度 + 可测试性) − (复杂度 + 数据风险 + 运维风险)-10 → +10| BFRI | Meaning | Action |
|---|---|---|
| 6–10 | Safe | Proceed |
| 3–5 | Moderate | Add tests + monitoring |
| 0–2 | Risky | Refactor or isolate |
| < 0 | Dangerous | Redesign before coding |
| BFRI | 含义 | 操作建议 |
|---|---|---|
| 6–10 | 安全 | 继续推进 |
| 3–5 | 中等风险 | 添加测试与监控 |
| 0–2 | 高风险 | 重构或隔离功能 |
| < 0 | 危险 | 编码前重新设计 |
Routes → Controllers → Services → Repositories → Database路由 → 控制器 → 服务 → 数据仓库 → 数据库// ❌ NEVER
router.post('/create', async (req, res) => {
await prisma.user.create(...);
});
// ✅ ALWAYS
router.post('/create', (req, res) =>
userController.create(req, res)
);// ❌ 绝对禁止
router.post('/create', async (req, res) => {
await prisma.user.create(...);
});
// ✅ 必须遵守
router.post('/create', (req, res) =>
userController.create(req, res)
);BaseControllerBaseControllerexport class UserController extends BaseController {
async getUser(req: Request, res: Response): Promise<void> {
try {
const user = await this.userService.getById(req.params.id);
this.handleSuccess(res, user);
} catch (error) {
this.handleError(error, res, 'getUser');
}
}
}res.jsonexport class UserController extends BaseController {
async getUser(req: Request, res: Response): Promise<void> {
try {
const user = await this.userService.getById(req.params.id);
this.handleSuccess(res, user);
} catch (error) {
this.handleError(error, res, 'getUser');
}
}
}res.jsoncatch (error) {
Sentry.captureException(error);
throw error;
}console.logcatch (error) {
Sentry.captureException(error);
throw error;
}console.log// ❌ NEVER
process.env.JWT_SECRET;
// ✅ ALWAYS
import { config } from '@/config/unifiedConfig';
config.auth.jwtSecret;// ❌ 绝对禁止
process.env.JWT_SECRET;
// ✅ 必须遵守
import { config } from '@/config/unifiedConfig';
config.auth.jwtSecret;const schema = z.object({
email: z.string().email(),
});
const input = schema.parse(req.body);const schema = z.object({
email: z.string().email(),
});
const input = schema.parse(req.body);src/
├── config/ # unifiedConfig
├── controllers/ # BaseController + controllers
├── services/ # Business logic
├── repositories/ # Prisma access
├── routes/ # Express routes
├── middleware/ # Auth, validation, errors
├── validators/ # Zod schemas
├── types/ # Shared types
├── utils/ # Helpers
├── tests/ # Unit + integration tests
├── instrument.ts # Sentry (FIRST IMPORT)
├── app.ts # Express app
└── server.ts # HTTP serversrc/
├── config/ # unified配置
├── controllers/ # BaseController + 业务控制器
├── services/ # 业务逻辑
├── repositories/ # Prisma数据库访问
├── routes/ # Express路由
├── middleware/ # 认证、验证、错误处理中间件
├── validators/ # Zod验证规则
├── types/ # 共享类型定义
├── utils/ # 工具函数
├── tests/ # 单元测试 + 集成测试
├── instrument.ts # Sentry初始化(第一个导入)
├── app.ts # Express应用实例
└── server.ts # HTTP服务器| Layer | Convention |
|---|---|
| Controller | |
| Service | |
| Repository | |
| Routes | |
| Validators | |
| 层级 | 命名规范 |
|---|---|
| 控制器 | |
| 服务 | |
| 数据仓库 | |
| 路由 | |
| 验证器 | |
export class UserService {
constructor(
private readonly userRepository: UserRepository
) {}
}export class UserService {
constructor(
private readonly userRepository: UserRepository
) {}
}await userRepository.findActiveUsers();await userRepository.findActiveUsers();router.get(
'/users',
asyncErrorWrapper((req, res) =>
controller.list(req, res)
)
);router.get(
'/users',
asyncErrorWrapper((req, res) =>
controller.list(req, res)
)
);describe('UserService', () => {
it('creates a user', async () => {
expect(user).toBeDefined();
});
});describe('UserService', () => {
it('creates a user', async () => {
expect(user).toBeDefined();
});
});