155 lines
3.0 KiB
Markdown
155 lines
3.0 KiB
Markdown
|
|
# OpenSpec 应用规范 (OpenSpec Applied Specification)
|
|||
|
|
|
|||
|
|
## 1. 规范概述
|
|||
|
|
|
|||
|
|
本文档记录 BLS OldRCU Heartbeat Backend 的详细技术规范,涵盖系统设计、实现标准、最佳实践和质量保证指标。
|
|||
|
|
|
|||
|
|
## 2. 设计原则
|
|||
|
|
|
|||
|
|
### 2.1 核心原则
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
P1. 性能优先 (Performance First)
|
|||
|
|
- 热路径优化(Parser 手写验证器)
|
|||
|
|
- 批量处理(Kafka 批量消费、DB 批量 Upsert)
|
|||
|
|
- 异步非阻塞(async/await,Event Loop 友好)
|
|||
|
|
|
|||
|
|
P2. 可靠性为主 (Reliability Paramount)
|
|||
|
|
- 时间序列保护(WHERE ts_ms 条件)
|
|||
|
|
- 冗余去重(5秒 + 30秒双层)
|
|||
|
|
- 失败重试(缓冲重入队)
|
|||
|
|
|
|||
|
|
P3. 可维护性设计 (Maintainability)
|
|||
|
|
- 清晰的模块划分
|
|||
|
|
- 完整的单元测试覆盖
|
|||
|
|
- 详细的 OpenSpec 文档
|
|||
|
|
|
|||
|
|
P4. 成本优化 (Cost Efficiency)
|
|||
|
|
- 最小化 DB 写入频率
|
|||
|
|
- 内存占用控制
|
|||
|
|
- 开源依赖优先
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 3. 实现标准
|
|||
|
|
|
|||
|
|
### 3.1 代码组织标准
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 文件头必须包含用途注释
|
|||
|
|
/**
|
|||
|
|
* HeartbeatParser - Kafka 消息验证与解析
|
|||
|
|
*
|
|||
|
|
* 职责:
|
|||
|
|
* - JSON 格式验证
|
|||
|
|
* - 字段类型检查(ts_ms, hotel_id, room_id, device_id)
|
|||
|
|
* - 返回规范化对象或 null
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
export function parseHeartbeat(rawMessage) {
|
|||
|
|
// ... implementation
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.2 命名规范
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 常量:UPPER_SNAKE_CASE
|
|||
|
|
const MAX_BUFFER_SIZE = 5000;
|
|||
|
|
const COOLDOWN_MS = 30000;
|
|||
|
|
|
|||
|
|
// 函数:camelCase,动词开头
|
|||
|
|
const parseHeartbeat = (raw) => {};
|
|||
|
|
const upsertBatch = (records) => {};
|
|||
|
|
|
|||
|
|
// 类:PascalCase
|
|||
|
|
class HeartbeatBuffer {}
|
|||
|
|
|
|||
|
|
// 私有方法:_camelCase
|
|||
|
|
_getCooldownDelayMs() {}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.3 错误处理标准
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// ✓ 推荐:使用 try-catch 包装 async 操作
|
|||
|
|
try {
|
|||
|
|
const result = await pool.query(sql, params);
|
|||
|
|
} catch (err) {
|
|||
|
|
logger.error(`Query failed: ${err.message}`, err);
|
|||
|
|
throw err;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ✓ 推荐:验证失败返回 null
|
|||
|
|
function parseHeartbeat(raw) {
|
|||
|
|
if (validation_fails) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 4. 性能规范
|
|||
|
|
|
|||
|
|
### 4.1 关键路径性能要求
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// Parser 解析单条消息 < 1ms
|
|||
|
|
// Buffer 添加单条记录 < 0.5ms
|
|||
|
|
// Buffer 刷新 5000 条记录 < 100ms
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.2 吞吐量目标
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
理论最大: 30,000 msg/s
|
|||
|
|
当前建议监控: 消费速率应 >= 25K msg/s
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 5. 安全规范
|
|||
|
|
|
|||
|
|
### 5.1 SQL 注入防护
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// ✓ 使用参数化查询
|
|||
|
|
const result = await pool.query(query, [userInput1, userInput2]);
|
|||
|
|
|
|||
|
|
// ✗ 字符串拼接(危险!)
|
|||
|
|
const result = await pool.query(`INSERT VALUES ('${userInput1}')`);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.2 环境变量管理
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// ✓ 使用 dotenv
|
|||
|
|
const dbPassword = process.env.POSTGRES_PASSWORD_G5;
|
|||
|
|
|
|||
|
|
// ✗ 硬编码敏感信息
|
|||
|
|
const dbPassword = "password123";
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 6. 可测试性规范
|
|||
|
|
|
|||
|
|
### 6.1 单元可测性设计
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// ✓ 纯函数,易于测试
|
|||
|
|
export function parseHeartbeat(raw) {
|
|||
|
|
// 无副作用
|
|||
|
|
return parsed || null;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 7. 部署规范
|
|||
|
|
|
|||
|
|
### 7.1 构建标准
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
npm ci # 精确依赖安装
|
|||
|
|
npm run test # 单元测试
|
|||
|
|
npm run build # Vite 构建
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**文档版本**: 1.0.0
|
|||
|
|
**最后更新**: 2026-03-11
|