DB-first library reads, mixed library indexing, and manual NFO refresh

- API reads now serve from media_items cache instead of scanning the filesystem
  on every request; scans (manual or scheduled) remain the write path
- NFO metadata is no longer parsed automatically during scans; title falls back
  to folder/filename — metadata can be refreshed per-item via the kabob menu
- Mixed libraries are now indexed in media_items (new mixed_file item type)
  with file_path stored; scanMixed walks recursively and upserts all files
- Added file_path column to media_items and migrated item_type CHECK constraint
  to include mixed_file via safe table-recreation migration
- New POST /api/nfo-refresh endpoint reads the .nfo for a single item and
  patches its DB row (supports movie, tv_series, tv_episode)
- Added "Refresh metadata" button to movie and TV series kabob menus

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Garret Patti
2026-04-06 18:20:21 -04:00
parent 01a4a1c0b7
commit 819748d1ff
12 changed files with 597 additions and 94 deletions

View File

@@ -1,6 +1,6 @@
import { NextRequest, NextResponse } from 'next/server'
import { getLibrary, resolveLibraryRoot } from '@/lib/libraries'
import { scanGamesLibrary } from '@/lib/games'
import { getLibrary } from '@/lib/libraries'
import { gamesFromDb } from '@/lib/games'
import { requireLibraryAccess } from '@/lib/auth'
export async function GET(request: NextRequest) {
@@ -22,7 +22,5 @@ export async function GET(request: NextRequest) {
return NextResponse.json({ error: 'Library is not a games library' }, { status: 400 })
}
const root = resolveLibraryRoot(library)
const games = scanGamesLibrary(root, libraryId)
return NextResponse.json(games)
return NextResponse.json(gamesFromDb(libraryId))
}