address audit findings: schedule validation, settings json guard, pipeline types, a11y labels
Build and Push Docker Image / build (push) Successful in 58s

This commit is contained in:
2026-04-13 15:48:55 +02:00
parent c0bcbaec1b
commit c5ea37aab9
13 changed files with 161 additions and 37 deletions
+16 -8
View File
@@ -1,15 +1,23 @@
import { api } from "~/shared/lib/api";
import type { PipelineReviewItem } from "~/shared/lib/types";
import { ColumnShell } from "./ColumnShell";
import { PipelineCard } from "./PipelineCard";
import { SeriesCard } from "./SeriesCard";
interface ReviewColumnProps {
items: any[];
items: PipelineReviewItem[];
total: number;
jellyfinUrl: string;
onMutate: () => void;
}
interface SeriesGroup {
name: string;
key: string;
jellyfinId: string | null;
episodes: PipelineReviewItem[];
}
export function ReviewColumn({ items, total, jellyfinUrl, onMutate }: ReviewColumnProps) {
const truncated = total > items.length;
@@ -29,24 +37,24 @@ export function ReviewColumn({ items, total, jellyfinUrl, onMutate }: ReviewColu
};
// Group by series (movies are standalone)
const movies = items.filter((i: any) => i.type === "Movie");
const seriesMap = new Map<string, { name: string; key: string; jellyfinId: string | null; episodes: any[] }>();
const movies = items.filter((i) => i.type === "Movie");
const seriesMap = new Map<string, SeriesGroup>();
for (const item of items.filter((i: any) => i.type === "Episode")) {
const key = item.series_jellyfin_id ?? item.series_name;
for (const item of items.filter((i) => i.type === "Episode")) {
const key = item.series_jellyfin_id ?? item.series_name ?? String(item.item_id);
if (!seriesMap.has(key)) {
seriesMap.set(key, { name: item.series_name, key, jellyfinId: item.series_jellyfin_id, episodes: [] });
seriesMap.set(key, { name: item.series_name ?? "", key, jellyfinId: item.series_jellyfin_id, episodes: [] });
}
seriesMap.get(key)!.episodes.push(item);
}
// Interleave movies and series, sorted by confidence (high first)
const allItems = [
...movies.map((m: any) => ({ type: "movie" as const, item: m, sortKey: m.confidence === "high" ? 0 : 1 })),
...movies.map((m) => ({ type: "movie" as const, item: m, sortKey: m.confidence === "high" ? 0 : 1 })),
...[...seriesMap.values()].map((s) => ({
type: "series" as const,
item: s,
sortKey: s.episodes.every((e: any) => e.confidence === "high") ? 0 : 1,
sortKey: s.episodes.every((e) => e.confidence === "high") ? 0 : 1,
})),
].sort((a, b) => a.sortKey - b.sortKey);