PIMS/app/Modules/Movies
2025-12-07 01:28:02 -06:00
..
Http feat(movies): switch provider to TMDb and store full actor image URLs\n\n- Add TmdbMovieProvider (v3 endpoints, v4 Bearer auth); set TMDb as default provider\n- Update config/movies.php with TMDb image base and profile size; add TMDB_PROFILE_SIZE\n- Upsert: persist actor profile_path as FULL TMDb CDN URL; backfill existing rows\n- Migrations: add actors.profile_path and backfill full URLs\n- Models: allow mass-assign profile_path on Actor\n- Admin: default provider from config; comments and docs updated\n- Frontend: show actor image on /actors/{id}; minor TMDb wording fixes in admin UI\n- Docs: update root and Movies module READMEs; env example for TMDb\n- Tests: adjust for TMDb defaults and provider IDs\n\nIncludes updated public/build assets and manifest. 2025-12-07 01:28:02 -06:00
Models feat(movies): switch provider to TMDb and store full actor image URLs\n\n- Add TmdbMovieProvider (v3 endpoints, v4 Bearer auth); set TMDb as default provider\n- Update config/movies.php with TMDb image base and profile size; add TMDB_PROFILE_SIZE\n- Upsert: persist actor profile_path as FULL TMDb CDN URL; backfill existing rows\n- Migrations: add actors.profile_path and backfill full URLs\n- Models: allow mass-assign profile_path on Actor\n- Admin: default provider from config; comments and docs updated\n- Frontend: show actor image on /actors/{id}; minor TMDb wording fixes in admin UI\n- Docs: update root and Movies module READMEs; env example for TMDb\n- Tests: adjust for TMDb defaults and provider IDs\n\nIncludes updated public/build assets and manifest. 2025-12-07 01:28:02 -06:00
Providers feat(movies): switch provider to TMDb and store full actor image URLs\n\n- Add TmdbMovieProvider (v3 endpoints, v4 Bearer auth); set TMDb as default provider\n- Update config/movies.php with TMDb image base and profile size; add TMDB_PROFILE_SIZE\n- Upsert: persist actor profile_path as FULL TMDb CDN URL; backfill existing rows\n- Migrations: add actors.profile_path and backfill full URLs\n- Models: allow mass-assign profile_path on Actor\n- Admin: default provider from config; comments and docs updated\n- Frontend: show actor image on /actors/{id}; minor TMDb wording fixes in admin UI\n- Docs: update root and Movies module READMEs; env example for TMDb\n- Tests: adjust for TMDb defaults and provider IDs\n\nIncludes updated public/build assets and manifest. 2025-12-07 01:28:02 -06:00
routes feat(movies): switch provider to TMDb and store full actor image URLs\n\n- Add TmdbMovieProvider (v3 endpoints, v4 Bearer auth); set TMDb as default provider\n- Update config/movies.php with TMDb image base and profile size; add TMDB_PROFILE_SIZE\n- Upsert: persist actor profile_path as FULL TMDb CDN URL; backfill existing rows\n- Migrations: add actors.profile_path and backfill full URLs\n- Models: allow mass-assign profile_path on Actor\n- Admin: default provider from config; comments and docs updated\n- Frontend: show actor image on /actors/{id}; minor TMDb wording fixes in admin UI\n- Docs: update root and Movies module READMEs; env example for TMDb\n- Tests: adjust for TMDb defaults and provider IDs\n\nIncludes updated public/build assets and manifest. 2025-12-07 01:28:02 -06:00
Services feat(movies): switch provider to TMDb and store full actor image URLs\n\n- Add TmdbMovieProvider (v3 endpoints, v4 Bearer auth); set TMDb as default provider\n- Update config/movies.php with TMDb image base and profile size; add TMDB_PROFILE_SIZE\n- Upsert: persist actor profile_path as FULL TMDb CDN URL; backfill existing rows\n- Migrations: add actors.profile_path and backfill full URLs\n- Models: allow mass-assign profile_path on Actor\n- Admin: default provider from config; comments and docs updated\n- Frontend: show actor image on /actors/{id}; minor TMDb wording fixes in admin UI\n- Docs: update root and Movies module READMEs; env example for TMDb\n- Tests: adjust for TMDb defaults and provider IDs\n\nIncludes updated public/build assets and manifest. 2025-12-07 01:28:02 -06:00
README.md feat(movies): switch provider to TMDb and store full actor image URLs\n\n- Add TmdbMovieProvider (v3 endpoints, v4 Bearer auth); set TMDb as default provider\n- Update config/movies.php with TMDb image base and profile size; add TMDB_PROFILE_SIZE\n- Upsert: persist actor profile_path as FULL TMDb CDN URL; backfill existing rows\n- Migrations: add actors.profile_path and backfill full URLs\n- Models: allow mass-assign profile_path on Actor\n- Admin: default provider from config; comments and docs updated\n- Frontend: show actor image on /actors/{id}; minor TMDb wording fixes in admin UI\n- Docs: update root and Movies module READMEs; env example for TMDb\n- Tests: adjust for TMDb defaults and provider IDs\n\nIncludes updated public/build assets and manifest. 2025-12-07 01:28:02 -06:00

Movies Module

This module implements service-first Movies functionality, including:

  • Admin search + accept flow (TMDb)
  • Public browsing (Inertia pages) backed by JSON API
  • Strict controller→service separation

Endpoints

Admin (auth required)

  • GET /admin/movies → Inertia admin page (search + accept)
  • GET /admin/movies/search?q=&page= → JSON results from TMDb (20 per page)
  • GET /admin/movies/exists?provider_id= → Duplicate check
  • POST /admin/movies/accept { provider_id, mode: overwrite|duplicate } → Persist movie

Public

  • Inertia pages: GET /movies, GET /movies/{id}
  • JSON API: GET /api/movies, GET /api/movies/{id}

Data model

  • Fully normalized tables: movies, genres, actors, directors, studios, countries, languages + pivot tables.
  • Provider ID is not unique. Duplicates are allowed when “Save as Duplicate” is selected.
  • Images are stored as remote URLs only (not downloaded).

Services & Contracts

  • Provider: App\Modules\Movies\Services\Contracts\MovieProvider (TMDb implementation)
  • Browse: ListMoviesServiceInterface, ShowMovieServiceInterface
  • Admin: UpsertMovieServiceInterface, CheckMovieExistsServiceInterface

All DI bindings are registered in MoviesServiceProvider.

Admin flow

  1. Search calls /admin/movies/search (TMDb search). List shows poster, title, year only (no details calls).
  2. Accept button:
    • If unique, accepts immediately (no modal).
    • If duplicate exists by provider_id, shows modal: Overwrite | Save as Duplicate | Cancel.
  3. On successful accept, a small toast appears and the row is marked “Accepted”.

Public browsing

  • /movies (Inertia) fetches from /api/movies with infinite scroll. Each row shows poster, title, year, rating, genres, and a ~50-word description snippet.
  • /movies/{id} (Inertia) fetches from /api/movies/{id} and shows details with all relations.

Environment

Add to .env (values shown as placeholders):

# Active provider
MOVIES_PROVIDER=tmdb

# TMDb (v4 Read Access Token recommended)
TMDB_API_TOKEN=
TMDB_LANGUAGE=en-US
TMDB_CACHE_TTL=3600
TMDB_IMAGE_BASE=https://image.tmdb.org/t/p/
TMDB_POSTER_SIZE=w500
TMDB_BACKDROP_SIZE=w780
TMDB_PROFILE_SIZE=w185

Set your real TMDb token locally (you will provide it). Timezone is America/Chicago.

Actor images

  • When accepting a movie, actor profile images are stored on the actors.profile_path column as FULL TMDb CDN URLs (e.g., https://image.tmdb.org/t/p/w185/abc123.jpg).
  • You can adjust the size used via TMDB_PROFILE_SIZE.

Development

  • Run backend: php artisan serve
  • Frontend dev: npm install && npm run dev
  • Tests: ./vendor/bin/pest

Notes

  • Pagination: TMDb search uses 20/page; public DB pagination defaults to 20/page (configurable at request).
  • Controller classes contain no business logic; all logic resides in services.