fix(telemetry): 회차 1 review 반영 — attempts 의미 통일 + DI 우회 제거 + 매직 슬라이스 제거
PR #13 회차 1 리뷰의 actionable 1건 + suggestion 3건 반영. - `AiWorker` 의 `attempts` 필드가 success/failure 경로에서 비대칭 의미 (0-index vs count) 였던 문제. 둘 다 `attempt + 1` (실제 시도 횟수, 1-based) 로 통일. stats markdown 의 평균/분포 해석이 일관됨. - `Date.now()` 직접 호출이 `opts.now` DI 를 우회하던 두 곳을 `this.now().getTime()` 으로 교체. 추후 durationMs 분포 테스트 작성 가능. - `TelemetryService.emit` 의 `this.now()` 두 번 호출을 한 번 캐시로 통합. KST 자정 경계에서 ts 와 파일명 일자 불일치 가능성 제거. - `readAllRecent` 의 `n.slice(7, 17)` 매직 슬라이스를 정규식 capture 그룹으로 교체. prefix 변경 시 한 곳만 수정. 테스트: AiWorker 성공 케이스의 `attempts: 0` → `attempts: 1` 갱신. 게이트: typecheck 0 errors, 245/245 unit tests pass. Deferred (v0.2.4 backlog): 'aborted' user-cancel false-positive, tray menu submenu 분리. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -55,9 +55,12 @@ export class TelemetryService {
|
||||
}
|
||||
|
||||
async emit(input: EmitInput): Promise<void> {
|
||||
const ts = this.now().toISOString();
|
||||
// 회차 1 review (PR #13) — `now()` 한 번만 호출. KST 자정 경계에서 ts 와 파일명 일자가
|
||||
// 어긋나는 것을 방지.
|
||||
const nowDate = this.now();
|
||||
const ts = nowDate.toISOString();
|
||||
const event = validateEvent({ ts, kind: input.kind, payload: input.payload });
|
||||
const filePath = join(this.dir, `events-${todayKstIso(this.now())}.jsonl`);
|
||||
const filePath = join(this.dir, `events-${todayKstIso(nowDate)}.jsonl`);
|
||||
try {
|
||||
await mkdir(this.dir, { recursive: true });
|
||||
await appendFile(filePath, JSON.stringify(event) + '\n', 'utf8');
|
||||
@@ -77,9 +80,14 @@ export class TelemetryService {
|
||||
}
|
||||
const cutoffMs = this.now().getTime() - this.retentionDays * 24 * 60 * 60 * 1000;
|
||||
const cutoffIso = todayKstIso(new Date(cutoffMs));
|
||||
// 회차 1 review (PR #13) — 매직 슬라이스 `n.slice(7, 17)` 대신 정규식 capture 그룹으로
|
||||
// 일자를 추출. prefix 변경 시 정규식 한 곳만 고치면 됨.
|
||||
const datePattern = /^events-(\d{4}-\d{2}-\d{2})\.jsonl$/;
|
||||
const fileNames = entries
|
||||
.filter((n) => /^events-\d{4}-\d{2}-\d{2}\.jsonl$/.test(n))
|
||||
.filter((n) => n.slice(7, 17) >= cutoffIso)
|
||||
.filter((n) => {
|
||||
const m = datePattern.exec(n);
|
||||
return m !== null && m[1]! >= cutoffIso;
|
||||
})
|
||||
.sort();
|
||||
for (const name of fileNames) {
|
||||
let raw: string;
|
||||
|
||||
Reference in New Issue
Block a user