use crate::models::{ Movie, MovieId, MovieProfile, Person, PersonId, collections::{PageParams, Paginated}, }; #[derive(Clone, Debug, Default)] pub struct SearchQuery { pub text: Option, pub filters: SearchFilters, pub page: PageParams, } #[derive(Clone, Debug, Default)] pub struct SearchFilters { pub genre: Option, pub year: Option, pub person_id: Option, pub department: Option, pub language: Option, } #[derive(Clone, Debug)] pub struct SearchResults { pub movies: Paginated, pub people: Paginated, } #[derive(Clone, Debug)] pub struct MovieSearchHit { pub movie_id: MovieId, pub title: String, pub release_year: Option, pub director: Option, pub poster_path: Option, pub genres: Vec, } #[derive(Clone, Debug)] pub struct PersonSearchHit { pub person_id: PersonId, pub name: String, pub known_for_department: Option, pub profile_path: Option, /// Top movie titles this person is known for — populated at query time /// by joining relational tables, never from the index. pub known_for_titles: Vec, } /// Document submitted to the search index. /// Add a new variant here to make a new entity type searchable — the port never changes. pub enum IndexableDocument { Movie { id: MovieId, movie: Box, profile: Option>, }, Person { id: PersonId, person: Box, // known_for_titles intentionally absent — no reads inside a command flow }, } #[derive(Clone, Debug, PartialEq)] pub enum EntityType { Movie, Person, }