feat(domain): add WrapUpReport model and supporting types

This commit is contained in:
2026-06-02 21:40:43 +02:00
parent c878c0358f
commit e8b2d4f7ee
2 changed files with 121 additions and 0 deletions

View File

@@ -19,6 +19,8 @@ pub use watchlist::{WatchlistEntry, WatchlistWithMovie};
pub mod remote_watchlist;
pub use remote_watchlist::RemoteWatchlistEntry;
pub mod watch_event;
pub mod wrapup;
pub use wrapup::*;
pub use watch_event::{
ParsedPlaybackEvent, PersistedWatchEvent, WatchEvent, WatchEventSource, WatchEventStatus,
WebhookToken,

View File

@@ -0,0 +1,119 @@
use chrono::NaiveDate;
use uuid::Uuid;
#[derive(Clone, Debug)]
pub struct DateRange {
pub start: NaiveDate,
pub end: NaiveDate,
}
#[derive(Clone, Debug)]
pub struct MovieRef {
pub title: String,
pub year: u16,
pub runtime_minutes: Option<u32>,
pub poster_path: Option<String>,
}
#[derive(Clone, Debug)]
pub struct UserRef {
pub user_id: Uuid,
pub display_name: String,
}
#[derive(Clone, Debug)]
pub struct PersonStat {
pub name: String,
pub count: u32,
pub avg_rating: f64,
}
#[derive(Clone, Debug)]
pub struct GenreStat {
pub genre: String,
pub count: u32,
pub avg_rating: f64,
}
#[derive(Clone, Debug)]
pub struct KeywordStat {
pub keyword: String,
pub count: u32,
}
#[derive(Clone, Debug)]
pub struct LangStat {
pub language: String,
pub count: u32,
}
#[derive(Clone, Debug)]
pub struct MonthCount {
pub year_month: String,
pub label: String,
pub count: u32,
}
#[derive(Clone, Debug)]
pub enum WrapUpScope {
User(Uuid),
Global,
}
#[derive(Clone, Debug)]
pub struct WrapUpReport {
pub scope: WrapUpScope,
pub date_range: DateRange,
pub generated_at: chrono::DateTime<chrono::Utc>,
// Core viewing
pub total_movies: u32,
pub total_watch_time_minutes: u32,
pub movies_per_month: Vec<MonthCount>,
pub busiest_month: Option<String>,
pub busiest_day_of_week: Option<String>,
pub avg_rating: Option<f64>,
pub rating_distribution: [u32; 5],
pub longest_movie: Option<MovieRef>,
pub shortest_movie: Option<MovieRef>,
// People insights
pub top_directors: Vec<PersonStat>,
pub top_actors: Vec<PersonStat>,
pub director_diversity: u32,
pub actor_diversity: u32,
// Genre & taste
pub top_genres: Vec<GenreStat>,
pub genre_diversity: u32,
pub highest_rated_genre: Option<String>,
pub lowest_rated_genre: Option<String>,
pub top_keywords: Vec<KeywordStat>,
// Financial/production (None when data unavailable)
pub total_budget_watched: Option<i64>,
pub avg_budget: Option<i64>,
pub language_distribution: Vec<LangStat>,
pub oldest_movie: Option<MovieRef>,
pub newest_movie: Option<MovieRef>,
// Rewatch stats
pub total_rewatches: u32,
pub most_rewatched_movie: Option<MovieRef>,
pub avg_rating_change_on_rewatch: Option<f64>,
// Highlights
pub highest_rated_movie: Option<MovieRef>,
pub lowest_rated_movie: Option<MovieRef>,
pub first_movie_of_period: Option<MovieRef>,
pub last_movie_of_period: Option<MovieRef>,
// Global-only (None for per-user)
pub most_active_user: Option<UserRef>,
pub most_watched_movie_global: Option<MovieRef>,
pub total_users_active: Option<u32>,
// Asset references for renderers
pub poster_paths: Vec<String>,
pub top_cast_profile_paths: Vec<String>,
}