mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-30 06:12:06 -07:00
fix: guard disabled immersion retention windows
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
id: TASK-244
|
||||||
|
title: 'Assess and address PR #36 latest CodeRabbit review round 2'
|
||||||
|
status: In Progress
|
||||||
|
assignee: []
|
||||||
|
created_date: '2026-03-29 08:09'
|
||||||
|
labels:
|
||||||
|
- code-review
|
||||||
|
- pr-36
|
||||||
|
dependencies: []
|
||||||
|
references:
|
||||||
|
- 'https://github.com/ksyasuda/SubMiner/pull/36'
|
||||||
|
priority: high
|
||||||
|
ordinal: 3610
|
||||||
|
---
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||||
|
Inspect the newest CodeRabbit review round on PR #36, verify the actionable comment against the current branch, implement the confirmed fix, and verify the touched path.
|
||||||
|
<!-- SECTION:DESCRIPTION:END -->
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
<!-- AC:BEGIN -->
|
||||||
|
- [ ] #1 The actionable review comment is implemented or explicitly deferred with rationale.
|
||||||
|
- [ ] #2 Touched path is verified with the smallest sufficient test lane.
|
||||||
|
- [ ] #3 Current PR feedback is reduced to resolved or intentionally deferred suggestions.
|
||||||
|
<!-- AC:END -->
|
||||||
@@ -82,6 +82,65 @@ test('pruneRawRetention uses session retention separately from telemetry retenti
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('pruneRawRetention skips disabled retention windows', () => {
|
||||||
|
const dbPath = makeDbPath();
|
||||||
|
const db = new Database(dbPath);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ensureSchema(db);
|
||||||
|
const nowMs = 1_000_000_000;
|
||||||
|
|
||||||
|
db.exec(`
|
||||||
|
INSERT INTO imm_videos (
|
||||||
|
video_id, video_key, canonical_title, source_type, duration_ms, CREATED_DATE, LAST_UPDATE_DATE
|
||||||
|
) VALUES (
|
||||||
|
1, 'local:/tmp/video.mkv', 'Video', 1, 0, ${nowMs}, ${nowMs}
|
||||||
|
);
|
||||||
|
INSERT INTO imm_sessions (
|
||||||
|
session_id, session_uuid, video_id, started_at_ms, ended_at_ms, status, CREATED_DATE, LAST_UPDATE_DATE
|
||||||
|
) VALUES (
|
||||||
|
1, 'session-1', 1, ${nowMs - 1_000}, ${nowMs - 500}, 2, ${nowMs}, ${nowMs}
|
||||||
|
);
|
||||||
|
INSERT INTO imm_session_telemetry (
|
||||||
|
session_id, sample_ms, total_watched_ms, active_watched_ms, CREATED_DATE, LAST_UPDATE_DATE
|
||||||
|
) VALUES (
|
||||||
|
1, ${nowMs - 2_000}, 0, 0, ${nowMs}, ${nowMs}
|
||||||
|
);
|
||||||
|
INSERT INTO imm_session_events (
|
||||||
|
session_id, event_type, ts_ms, payload_json, CREATED_DATE, LAST_UPDATE_DATE
|
||||||
|
) VALUES (
|
||||||
|
1, 1, ${nowMs - 3_000}, '{}', ${nowMs}, ${nowMs}
|
||||||
|
);
|
||||||
|
`);
|
||||||
|
|
||||||
|
const result = pruneRawRetention(db, nowMs, {
|
||||||
|
eventsRetentionMs: Number.POSITIVE_INFINITY,
|
||||||
|
telemetryRetentionMs: Number.POSITIVE_INFINITY,
|
||||||
|
sessionsRetentionMs: Number.POSITIVE_INFINITY,
|
||||||
|
});
|
||||||
|
|
||||||
|
const remainingSessionEvents = db
|
||||||
|
.prepare('SELECT COUNT(*) AS count FROM imm_session_events')
|
||||||
|
.get() as { count: number };
|
||||||
|
const remainingTelemetry = db
|
||||||
|
.prepare('SELECT COUNT(*) AS count FROM imm_session_telemetry')
|
||||||
|
.get() as { count: number };
|
||||||
|
const remainingSessions = db
|
||||||
|
.prepare('SELECT COUNT(*) AS count FROM imm_sessions')
|
||||||
|
.get() as { count: number };
|
||||||
|
|
||||||
|
assert.equal(result.deletedSessionEvents, 0);
|
||||||
|
assert.equal(result.deletedTelemetryRows, 0);
|
||||||
|
assert.equal(result.deletedEndedSessions, 0);
|
||||||
|
assert.equal(remainingSessionEvents.count, 1);
|
||||||
|
assert.equal(remainingTelemetry.count, 1);
|
||||||
|
assert.equal(remainingSessions.count, 1);
|
||||||
|
} finally {
|
||||||
|
db.close();
|
||||||
|
cleanupDbPath(dbPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test('toMonthKey floors negative timestamps into the prior UTC month', () => {
|
test('toMonthKey floors negative timestamps into the prior UTC month', () => {
|
||||||
assert.equal(toMonthKey(-1), 196912);
|
assert.equal(toMonthKey(-1), 196912);
|
||||||
assert.equal(toMonthKey(-86_400_000), 196912);
|
assert.equal(toMonthKey(-86_400_000), 196912);
|
||||||
|
|||||||
@@ -53,25 +53,27 @@ export function pruneRawRetention(
|
|||||||
sessionsRetentionMs: number;
|
sessionsRetentionMs: number;
|
||||||
},
|
},
|
||||||
): RawRetentionResult {
|
): RawRetentionResult {
|
||||||
const eventCutoff = currentMs - policy.eventsRetentionMs;
|
const deletedSessionEvents = Number.isFinite(policy.eventsRetentionMs)
|
||||||
const telemetryCutoff = currentMs - policy.telemetryRetentionMs;
|
? (
|
||||||
const sessionsCutoff = currentMs - policy.sessionsRetentionMs;
|
db.prepare(`DELETE FROM imm_session_events WHERE ts_ms < ?`).run(
|
||||||
|
toDbMs(currentMs - policy.eventsRetentionMs),
|
||||||
const deletedSessionEvents = (
|
) as { changes: number }
|
||||||
db.prepare(`DELETE FROM imm_session_events WHERE ts_ms < ?`).run(toDbMs(eventCutoff)) as {
|
).changes
|
||||||
changes: number;
|
: 0;
|
||||||
}
|
const deletedTelemetryRows = Number.isFinite(policy.telemetryRetentionMs)
|
||||||
).changes;
|
? (
|
||||||
const deletedTelemetryRows = (
|
|
||||||
db
|
db
|
||||||
.prepare(`DELETE FROM imm_session_telemetry WHERE sample_ms < ?`)
|
.prepare(`DELETE FROM imm_session_telemetry WHERE sample_ms < ?`)
|
||||||
.run(toDbMs(telemetryCutoff)) as { changes: number }
|
.run(toDbMs(currentMs - policy.telemetryRetentionMs)) as { changes: number }
|
||||||
).changes;
|
).changes
|
||||||
const deletedEndedSessions = (
|
: 0;
|
||||||
|
const deletedEndedSessions = Number.isFinite(policy.sessionsRetentionMs)
|
||||||
|
? (
|
||||||
db
|
db
|
||||||
.prepare(`DELETE FROM imm_sessions WHERE ended_at_ms IS NOT NULL AND ended_at_ms < ?`)
|
.prepare(`DELETE FROM imm_sessions WHERE ended_at_ms IS NOT NULL AND ended_at_ms < ?`)
|
||||||
.run(toDbMs(sessionsCutoff)) as { changes: number }
|
.run(toDbMs(currentMs - policy.sessionsRetentionMs)) as { changes: number }
|
||||||
).changes;
|
).changes
|
||||||
|
: 0;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
deletedSessionEvents,
|
deletedSessionEvents,
|
||||||
|
|||||||
Reference in New Issue
Block a user