PIMS/app/Modules/Movies/README.md

73 lines
2.8 KiB
Markdown

# 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.