Optimize performance: batch DB ops, N+1 fixes, Suspense streaming, and Jotai best practices

- Add composite indexes on userEpisodeWatches and userMovieWatches for hot queries
- Batch episode tracking: wrap season/batch watches in single transaction (~8 queries vs 8*N)
- Fix N+1 patterns in credits, recommendations, and filmography with batch prefetch+insert
- Stream TV season hydration via Suspense instead of blocking page render
- Optimize webhook logs (per-connection LIMIT 10) and system health queries
- Merge genre filter waterfalls into single Promise.all fetch
- Migrate deprecated Jotai loadable() to unwrap()
- Replace isolated createStore()+Provider with useHydrateAtoms on root store
- Remove unnecessary atomWithStorage SSR guards (handled by Jotai internally)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-05 17:33:27 -05:00
co-authored by Claude Opus 4.6
parent ed825f3a78
commit f36ca0cbf8
23 changed files with 839 additions and 571 deletions
+29
View File
@@ -126,6 +126,35 @@ export function PersonDetailSkeleton() {
);
}
export function SeasonsSkeleton() {
return (
<div className="space-y-4">
<div className="flex items-center gap-3">
<Skeleton className="size-5 rounded" />
<Skeleton className="h-6 w-24" />
</div>
<div className="flex gap-2">
<Skeleton className="h-8 w-20 rounded-full" />
<Skeleton className="h-8 w-20 rounded-full" />
<Skeleton className="h-8 w-20 rounded-full" />
</div>
<div className="space-y-3">
{Array.from({ length: 4 }).map((_, i) => (
// biome-ignore lint/suspicious/noArrayIndexKey: static skeleton placeholders
<div key={i} className="flex gap-3 rounded-lg bg-card/50 p-3">
<Skeleton className="aspect-video w-32 shrink-0 rounded" />
<div className="flex-1 space-y-2 py-1">
<Skeleton className="h-4 w-2/3" />
<Skeleton className="h-3 w-full" />
<Skeleton className="h-3 w-1/2" />
</div>
</div>
))}
</div>
</div>
);
}
export function RecommendationsSkeleton() {
return (
<div className="space-y-4">
-1
View File
@@ -11,7 +11,6 @@ import {
IconPlus,
IconStarFilled,
} from "@tabler/icons-react";
import { type MotionStyle, type MotionValue, motion } from "motion/react";
import Image from "next/image";
import Link from "next/link";