mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-10-15 19:45:42 -04:00
fix(cron): judge stale seasons by the latest season fetch
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2 files changed
+36
-3
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import { beforeEach, describe, expect, test, vi } from "vitest";
|
||||
|
||||
import { cronRuns, titles } from "@sofa/db/schema";
|
||||
import { cronRuns, seasons, titles } from "@sofa/db/schema";
|
||||
import { clearAllTables, eq, insertTitle, testDb } from "@sofa/test/db";
|
||||
|
||||
import {
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
failCronRun,
|
||||
getLibraryTitlesDueForRefresh,
|
||||
getStaleLibraryTitles,
|
||||
getTitleIdsWithStaleSeasons,
|
||||
libraryRefreshIntervalMs,
|
||||
runIsolated,
|
||||
startCronRun,
|
||||
@@ -198,3 +199,30 @@ describe("getLibraryTitlesDueForRefresh", () => {
|
||||
expect(getLibraryTitlesDueForRefresh(["t-shell"], now)).toEqual(["t-shell"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getTitleIdsWithStaleSeasons", () => {
|
||||
const DAY = 24 * 60 * 60 * 1000;
|
||||
const now = Date.now();
|
||||
const cutoff = new Date(now - 7 * DAY);
|
||||
|
||||
function addSeason(id: string, titleId: string, seasonNumber: number, daysAgo: number) {
|
||||
testDb
|
||||
.insert(seasons)
|
||||
.values({ id, titleId, seasonNumber, lastFetchedAt: new Date(now - daysAgo * DAY) })
|
||||
.run();
|
||||
}
|
||||
|
||||
test("is not stale when the most recent season fetch is fresh", () => {
|
||||
insertTitle({ id: "tv-partial", tmdbId: 1, type: "tv" });
|
||||
addSeason("s-1", "tv-partial", 1, 30);
|
||||
addSeason("s-2", "tv-partial", 2, 1);
|
||||
expect(getTitleIdsWithStaleSeasons(["tv-partial"], cutoff).has("tv-partial")).toBe(false);
|
||||
});
|
||||
|
||||
test("is stale when every season was fetched long ago", () => {
|
||||
insertTitle({ id: "tv-old", tmdbId: 2, type: "tv" });
|
||||
addSeason("s-3", "tv-old", 1, 30);
|
||||
addSeason("s-4", "tv-old", 2, 30);
|
||||
expect(getTitleIdsWithStaleSeasons(["tv-old"], cutoff).has("tv-old")).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import { and, eq, gte, inArray, isNotNull, isNull, lt, or } from "drizzle-orm";
|
||||
import { and, eq, gte, inArray, isNotNull, isNull, lt, or, sql } from "drizzle-orm";
|
||||
|
||||
import { db } from "../client";
|
||||
import {
|
||||
@@ -111,14 +111,19 @@ export function getReturningTvShows() {
|
||||
.all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Titles whose most recent season fetch is older than `staleDate`. Uses the latest
|
||||
* season fetch (not any season) because partial refreshes only touch the newest seasons.
|
||||
*/
|
||||
export function getTitleIdsWithStaleSeasons(titleIds: string[], staleDate: Date) {
|
||||
if (titleIds.length === 0) return new Set<string>();
|
||||
return new Set(
|
||||
db
|
||||
.select({ titleId: seasons.titleId })
|
||||
.from(seasons)
|
||||
.where(and(inArray(seasons.titleId, titleIds), lt(seasons.lastFetchedAt, staleDate)))
|
||||
.where(inArray(seasons.titleId, titleIds))
|
||||
.groupBy(seasons.titleId)
|
||||
.having(sql`max(${seasons.lastFetchedAt}) < ${sql.param(staleDate, seasons.lastFetchedAt)}`)
|
||||
.all()
|
||||
.map((r) => r.titleId),
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user