Commit Graph
9 Commits
Author SHA1 Message Date
jakeandClaude Opus 4.6 f16ccc2f3f Replace title mutation API routes with server actions
Move all title page mutations (status, rating, movie watch, episode
watch/unwatch, season watch/unwatch) from API route handlers to server
actions called directly from TitleInteractionProvider. Same optimistic
update pattern, no behavioral change — just eliminates the fetch()
round-trip through 5 API routes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 15:47:04 -05:00
jakeandClaude Opus 4.6 c1867a4f23 Convert dashboard and title pages to server components with granular Suspense
Replace fully client-side dashboard and title detail pages with server
component orchestrators that fetch data directly via service functions,
eliminating extra network round-trips through API routes. Each section
streams independently through its own Suspense boundary.

- Extract getUserStats(), getTitleWithChildren(), getRecommendationsForTitle()
  into service layer; update getNewAvailableFeed() to include tmdbId/voteAverage
- Split dashboard into server sections (stats, continue watching, library,
  recommendations) with client children for animations
- Split title page into server hero + client interaction provider with shared
  context for optimistic mutations across actions and seasons
- Add generateMetadata with OG tags, server-side TMDB ID resolution via
  redirect(), loading.tsx and not-found.tsx for both pages
- Add per-section skeleton components, fix ContinueWatchingSkeleton dimensions
- Remove 6 unused API routes (feed/*, titles/[id] GET, titles/[id]/recommendations)
- Remove components/stats-summary.tsx, add lib/types/title.ts for shared types

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 15:42:42 -05:00
jakeandClaude Opus 4.6 081f53beac Add instant navigation from search results via TMDB IDs in URL
Navigate instantly to /titles/tmdb-{id}-{type} and show a skeleton
while the new /api/titles/resolve endpoint handles the full import
(TMDB fetch, availability, recommendations, colors). Existing titles
resolve in ~5ms; the URL is replaced with the UUID once resolved.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 15:13:51 -05:00
jakeandClaude Opus 4.6 ee723e41d6 Add TMDB image caching pipeline and resolve image URLs server-side
Introduce a local disk cache for TMDB images served through a proxy API
route (/api/images/[...path]), eliminating direct client-side CDN
dependencies. Images are cached by category (posters, backdrops, stills,
logos) and served with immutable cache headers.

Move all tmdbImageUrl() calls from client components to API routes and
server components so clients receive ready-to-use URLs. This removes the
need to expose TMDB_IMAGE_BASE_URL and IMAGE_CACHE_ENABLED via
next.config.ts env block. The landing page is split into a server
wrapper (app/page.tsx) and client component (components/landing-page.tsx).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 13:10:17 -05:00
jakeandClaude Opus 4.6 cb0f366d44 Add dynamic color theming from poster art using node-vibrant
Extract dominant colors from movie/TV poster images server-side and use
them to create per-title atmospheric effects on detail pages — tinted
backdrop gradients, ambient glow orbs, and colored poster shadows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 12:29:13 -05:00
jakeandClaude Opus 4.6 96213c3086 Add Docker packaging and migrate from better-sqlite3 to libsql
Docker self-hosting support:
- Dockerfile (multi-stage Alpine build with tini init)
- docker-compose.yml with named volume for SQLite persistence
- /api/health endpoint for container health checks
- Auto-migration on startup via drizzle-orm/libsql/migrator
- Graceful shutdown (SIGTERM stops scheduler, closes DB)
- Next.js standalone output mode for minimal image size

Database driver migration (better-sqlite3 → @libsql/client):
- Eliminates native C++ compilation, enabling Alpine Docker images
- All DB queries converted from sync to async across services and routes
- DATABASE_URL now uses libsql file: prefix format
- drizzle.config.ts dialect changed to turso for libsql support
- Initial migration files generated in drizzle/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 13:14:57 -05:00
jakeandClaude Opus 4.6 bebc4dc9fa Fix intermittent missing episodes for TV shows
TV episodes were missing when: (1) a title existed as a recommendation
"shell" with no episode data, (2) a prior refreshTvChildren() call
failed partway through, or (3) the title detail page was loaded before
episodes finished importing. importTitle() now re-fetches episodes for
existing TV titles with zero seasons, the GET endpoint hydrates shell
titles on access, and refreshTvChildren() handles per-season errors
gracefully instead of aborting entirely.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:10:04 -05:00
jakeandClaude Opus 4.6 095b64ab42 Simplify auth, remove abstraction layers, add shadcn components
- Delete lib/api/errors.ts and lib/api/auth-guard.ts, inline
  NextResponse.json() error responses directly in route handlers
- Replace non-standard amber CSS variables with primary/primary-foreground
- Regenerate shadcn UI components with biome-ignore comments
- Add CLAUDE.md for repository guidance
- Update dependencies and pnpm lockfile

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 15:00:15 -05:00
jakeandClaude Opus 4.6 b02ff1cdc1 Implement full Couch Potato movie & TV tracking app
Add all 10 milestones: Drizzle ORM + SQLite database with WAL mode,
Better Auth email/password authentication, TMDB API integration for
search and metadata import, TV season/episode caching, user tracking
(watchlist/status/watches/ratings with auto-transitions), discovery
feeds (continue watching, library, recommendations), US streaming
availability via TMDB providers, background job scheduler with
instrumentation hook, and dark cinema-themed frontend with DM Serif
Display + DM Sans typography and amber accent design system.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 14:42:13 -05:00