fix(stats): harden duplicate-line cleanup and tracking

- Reject malformed requests and sub-day cleanup windows
- Reset deduplication across media and subtitle-track changes
- Handle karaoke bursts ending with a long hold frame
This commit is contained in:
2026-08-11 22:20:50 -07:00
parent fa4c734e30
commit 046a87a826
15 changed files with 410 additions and 55 deletions
+3 -3
View File
@@ -56,12 +56,12 @@ export interface CliInvocations {
texthookerOpenBrowser: boolean;
}
/** `--lookback-days` narrows the duplicate-line cleanup; anything unusable means no limit. */
/** `--lookback-days` narrows the duplicate-line cleanup; fractions are floored. */
function parseStatsLookbackDays(value: unknown): number | null {
if (typeof value !== 'string' && typeof value !== 'number') return null;
const days = Number(value);
if (!Number.isFinite(days) || days <= 0) {
throw new Error('Stats --lookback-days must be a positive number of days.');
if (!Number.isFinite(days) || days < 1) {
throw new Error('Stats --lookback-days must be at least one day.');
}
return Math.floor(days);
}
+9 -2
View File
@@ -244,6 +244,13 @@ test('parseArgs maps duplicate-line stats cleanup flags', () => {
assert.equal(parsed.statsCleanupDuplicateLines, true);
assert.equal(parsed.statsCleanupDryRun, true);
assert.equal(parsed.statsCleanupLookbackDays, 30);
const fractional = parseArgs(
['stats', 'cleanup', '--duplicate-lines', '--lookback-days', '1.5'],
'subminer',
{},
);
assert.equal(fractional.statsCleanupLookbackDays, 1);
});
test('parseArgs rejects duplicate-line flags without the duplicate-lines mode', () => {
@@ -265,7 +272,7 @@ test('parseArgs rejects combining lifetime and duplicate-line cleanup modes', ()
});
test('parseArgs rejects unusable lookback windows', () => {
for (const value of ['0', '-5', 'soon']) {
for (const value of ['0', '0.5', '-5', 'soon']) {
const error = withProcessExitIntercept(() => {
parseArgs(
['stats', 'cleanup', '--duplicate-lines', '--lookback-days', value],
@@ -275,7 +282,7 @@ test('parseArgs rejects unusable lookback windows', () => {
});
assert.equal(error.code, 1);
assert.match(error.stderr, /--lookback-days must be a positive number of days/);
assert.match(error.stderr, /--lookback-days must be at least one day/);
}
});