refactor: 全面优化后端代码质量与架构
- app.ts 单体路由拆分为 routes/ + helpers + middleware + static 独立模块 - 类型去重:CheckFailure/CheckResult 以 shared/api.ts 为唯一源头,收紧 phase 联合类型 - es-toolkit 替换:isPlainObject/isNil/isEmptyObject/isEqual/isError/Semaphore/groupBy - Bun 内置 API:Object.fromEntries 替代手写 headersToRecord - bun:sqlite 规范:prepare() → query() 利用内置缓存,避免 N+1 查询 - 新增 getLatestChecksMap/allGetTargetStats 批量查询方法 - 新增 backend-code-quality/api-route-separation/batch-data-queries 规范 - 补充 openspec/config.yaml 后端开发规范与 DEVELOPMENT.md 后端开发指引
This commit is contained in:
@@ -297,4 +297,75 @@ describe("ProbeStore", () => {
|
||||
|
||||
cascadeStore.close();
|
||||
});
|
||||
|
||||
test("getLatestChecksMap 返回所有 target 的最新 check", () => {
|
||||
const targets = store.getTargets();
|
||||
const map = store.getLatestChecksMap();
|
||||
expect(map).toBeInstanceOf(Map);
|
||||
|
||||
for (const target of targets) {
|
||||
const latest = map.get(target.id);
|
||||
if (latest) {
|
||||
expect(latest.target_id).toBe(target.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("getLatestChecksMap 对无记录的 target 不包含 key", () => {
|
||||
const freshStore = new ProbeStore(join(tempDir, "fresh-map.db"));
|
||||
freshStore.syncTargets([
|
||||
{
|
||||
type: "http",
|
||||
name: "no-records",
|
||||
group: "default",
|
||||
http: { url: "http://no.records", method: "GET", headers: {}, maxBodyBytes: 104857600 },
|
||||
intervalMs: 30000,
|
||||
timeoutMs: 10000,
|
||||
},
|
||||
]);
|
||||
|
||||
const map = freshStore.getLatestChecksMap();
|
||||
expect(map.size).toBe(0);
|
||||
|
||||
freshStore.close();
|
||||
});
|
||||
|
||||
test("getAllTargetStats 返回所有 target 的聚合统计", () => {
|
||||
const targets = store.getTargets();
|
||||
const t1Id = targets[0]!.id;
|
||||
const t2Id = targets[1]!.id;
|
||||
|
||||
const stats = store.getAllTargetStats();
|
||||
expect(stats).toBeInstanceOf(Map);
|
||||
|
||||
const stats1 = stats.get(t1Id);
|
||||
expect(stats1).toBeDefined();
|
||||
expect(stats1!.totalChecks).toBeGreaterThan(0);
|
||||
expect(stats1!.availability).toBeGreaterThanOrEqual(0);
|
||||
|
||||
const stats2 = stats.get(t2Id);
|
||||
if (stats2) {
|
||||
expect(stats2!.totalChecks).toBe(0);
|
||||
expect(stats2!.availability).toBe(0);
|
||||
}
|
||||
});
|
||||
|
||||
test("getAllTargetStats 对无记录的 target 不包含 key", () => {
|
||||
const freshStore = new ProbeStore(join(tempDir, "fresh-stats.db"));
|
||||
freshStore.syncTargets([
|
||||
{
|
||||
type: "http",
|
||||
name: "no-stats",
|
||||
group: "default",
|
||||
http: { url: "http://no.stats", method: "GET", headers: {}, maxBodyBytes: 104857600 },
|
||||
intervalMs: 30000,
|
||||
timeoutMs: 10000,
|
||||
},
|
||||
]);
|
||||
|
||||
const stats = freshStore.getAllTargetStats();
|
||||
expect(stats.size).toBe(0);
|
||||
|
||||
freshStore.close();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user