chore: agents update

This commit is contained in:
xiaojunnuo
2026-05-05 22:17:09 +08:00
parent 91a1b97550
commit 72b6597817
3 changed files with 47 additions and 3 deletions
+2 -1
View File
@@ -106,7 +106,7 @@ Certd 是一个支持私有化部署的 SSL/TLS 证书自动化管理平台。
- 前端 `pnpm dev`:启动 Vite 开发服务
- 前端 `pnpm build`:生产构建
- 前端 `pnpm tsc`:类型检查
- 前端 `pnpm test:unit`Vitest 单元测试
- 前端暂不跑单元测试;当前 `test:unit` 只是占位脚本
## 流水线与插件模型
@@ -207,5 +207,6 @@ Get-ChildItem packages\ui\certd-client\src\views\certd
- 实现新功能或修复行为缺陷前,先补对应单元测试,并先运行测试确认它处于失败状态;再实现功能或修复代码,反复运行聚焦单元测试直到通过。若某项改动确实不适合先写单元测试,应在回复中说明原因和替代验证方式。
- 后补单元测试时,应先基于对正确行为的实际预期编写测试,而不是为了迎合现有实现改写预期;如果运行后出现红灯,且通过测试需要修改已有实现,应先向用户确认这是确实的 bug,还是原本需求/既有行为就是如此;确认后再修改原始实现,避免把测试补充变成未经确认的行为改动。
- 后端纯单元测试用例放在 `src` 目录内,并尽量与被测文件相邻,例如 `src/utils/random.test.ts`;对应 `test:unit` 只跑 `src/**/*.test.ts`,构建/打包配置应排除这些 `*.test.ts` 文件。
- 单个 monorepo 包运行单元测试时,优先使用 `corepack pnpm --dir <包目录> test:unit`,例如 `corepack pnpm --dir packages\ui\certd-server test:unit``corepack pnpm --dir packages\core\basic test:unit``corepack pnpm --dir packages\plugins\plugin-lib test:unit`;也可以用包名过滤,例如 `corepack pnpm --filter @certd/ui-server test:unit`。前端 `packages\ui\certd-client` 暂时不跑单元测试。
- 前端 TS/Vue/locale 等文件改动后,优先只对本次改动文件运行项目现有自动格式化/修复,例如 `corepack pnpm --dir packages\ui\certd-client exec prettier --write <files>``corepack pnpm --dir packages\ui\certd-client exec eslint --fix <files>`;不要为了格式化无关文件而扩大 diff。项目保留了 `tslint` 依赖,但当前主要使用 ESLint + Prettier。
- 优先对改动包运行聚焦的测试或类型检查;只有跨包影响明显时再考虑全 monorepo 构建。
@@ -80,4 +80,47 @@ describe("TldClient", () => {
(TldClient as any).rdapSsRequestTimes = originalRequestTimes;
}
});
it("clears rdapSsRequestTimes entries older than 24 hours", async () => {
const now = Date.now();
const originalRequestTimes = (TldClient as any).rdapSsRequestTimes;
try {
const recentTime = now - 1000 * 60 * 60;
const oldTime = now - 25 * 60 * 60 * 1000;
(TldClient as any).rdapSsRequestTimes = [oldTime, recentTime];
const client = new TldClient() as any;
await client.waitRdapSsRateLimit();
const times = (TldClient as any).rdapSsRequestTimes;
assert.equal(times.length, 2);
assert.ok(times.every((t: number) => now - t < 24 * 60 * 60 * 1000));
} finally {
(TldClient as any).rdapSsRequestTimes = originalRequestTimes;
}
});
it("keeps rdapSsRequestTimes entries within 24 hours and removes those exactly at boundary", async () => {
const now = Date.now();
const originalRequestTimes = (TldClient as any).rdapSsRequestTimes;
try {
const boundaryTime = now - 24 * 60 * 60 * 1000;
const withinTime = now - 23 * 60 * 60 * 1000;
(TldClient as any).rdapSsRequestTimes = [boundaryTime, withinTime];
const client = new TldClient() as any;
await client.waitRdapSsRateLimit();
const times = (TldClient as any).rdapSsRequestTimes as number[];
assert.equal(times.length, 2);
assert.ok(times.every((t: number) => now - t < 24 * 60 * 60 * 1000));
assert.ok(times.includes(withinTime));
} finally {
(TldClient as any).rdapSsRequestTimes = originalRequestTimes;
}
});
});
@@ -18,6 +18,7 @@ export class TldClient {
{ windowMs: 24 * 60 * 60 * 1000, max: 12000 },
];
private static readonly RDAP_SS_MAX_WAIT_MS = 3 * 60 * 1000;
private static readonly RDAP_SS_DATA_RETENTION_MS = 24 * 60 * 60 * 1000;
private static rdapSsRequestTimes: number[] = [];
private rdapMap: Record<string, string> = {};
@@ -177,8 +178,7 @@ export class TldClient {
private async waitRdapSsRateLimit() {
while (true) {
const now = Date.now();
const maxWindowMs = Math.max(...TldClient.RDAP_SS_RATE_LIMITS.map(item => item.windowMs));
TldClient.rdapSsRequestTimes = TldClient.rdapSsRequestTimes.filter(time => now - time < maxWindowMs);
TldClient.rdapSsRequestTimes = TldClient.rdapSsRequestTimes.filter(time => now - time < TldClient.RDAP_SS_DATA_RETENTION_MS);
const waitMs = TldClient.RDAP_SS_RATE_LIMITS.reduce((maxWaitMs, limit) => {
const times = TldClient.rdapSsRequestTimes.filter(time => now - time < limit.windowMs);