feature/spoiler-flag (#25)
Some checks failed
CI / Check / Test (push) Has been cancelled

Reviewed-on: #25
This commit was merged in pull request #25.
This commit is contained in:
2026-10-25 18:52:11 +00:00
parent 9dd9df1f73
commit 4f3d99ec8e
66 changed files with 502 additions and 168 deletions

View File

@@ -52,7 +52,7 @@ impl SqliteDiaryRepository {
};
let sql = format!(
"SELECT m.id, m.external_metadata_id, m.title, m.release_year, m.director, m.poster_path,
r.id AS review_id, r.movie_id, r.user_id, r.rating, r.comment, r.watched_at, r.created_at, r.remote_actor_url, r.watch_medium
r.id AS review_id, r.movie_id, r.user_id, r.rating, r.comment, r.watched_at, r.created_at, r.remote_actor_url, r.watch_medium, r.spoilers
FROM reviews r
INNER JOIN movies m ON m.id = r.movie_id
ORDER BY {}
@@ -82,7 +82,7 @@ impl SqliteDiaryRepository {
};
let sql = format!(
"SELECT m.id, m.external_metadata_id, m.title, m.release_year, m.director, m.poster_path,
r.id AS review_id, r.movie_id, r.user_id, r.rating, r.comment, r.watched_at, r.created_at, r.remote_actor_url, r.watch_medium
r.id AS review_id, r.movie_id, r.user_id, r.rating, r.comment, r.watched_at, r.created_at, r.remote_actor_url, r.watch_medium, r.spoilers
FROM reviews r
INNER JOIN movies m ON m.id = r.movie_id
WHERE r.movie_id = ?
@@ -158,7 +158,7 @@ impl SqliteDiaryRepository {
};
let sql = format!(
"SELECT m.id, m.external_metadata_id, m.title, m.release_year, m.director, m.poster_path,
r.id AS review_id, r.movie_id, r.user_id, r.rating, r.comment, r.watched_at, r.created_at, r.remote_actor_url, r.watch_medium
r.id AS review_id, r.movie_id, r.user_id, r.rating, r.comment, r.watched_at, r.created_at, r.remote_actor_url, r.watch_medium, r.spoilers
FROM reviews r
INNER JOIN movies m ON m.id = r.movie_id
WHERE r.user_id = ?{remote_clause}{search_clause}
@@ -305,7 +305,7 @@ impl DiaryQuery for SqliteDiaryRepository {
let select_sql = format!(
"SELECT m.id, m.external_metadata_id, m.title, m.release_year, m.director, m.poster_path,
r.id AS review_id, r.movie_id, r.user_id, r.rating, r.comment,
r.watched_at, r.created_at, r.remote_actor_url, r.watch_medium,
r.watched_at, r.created_at, r.remote_actor_url, r.watch_medium, r.spoilers,
CASE WHEN r.remote_actor_url IS NOT NULL THEN COALESCE(a.handle, r.remote_actor_url)
ELSE COALESCE(u.email, r.user_id) END AS user_email
FROM reviews r
@@ -378,7 +378,7 @@ impl DiaryQuery for SqliteDiaryRepository {
.into_domain()?;
let viewings = sqlx::query_as::<_, ReviewRow>(
"SELECT id, movie_id, user_id, rating, comment, watched_at, created_at, remote_actor_url, watch_medium
"SELECT id, movie_id, user_id, rating, comment, watched_at, created_at, remote_actor_url, watch_medium, spoilers
FROM reviews WHERE movie_id = ? ORDER BY watched_at ASC",
)
.bind(&id_str)
@@ -396,7 +396,7 @@ impl DiaryQuery for SqliteDiaryRepository {
let uid = user_id.value().to_string();
let rows = sqlx::query_as::<_, DiaryRow>(
"SELECT m.id, m.external_metadata_id, m.title, m.release_year, m.director, m.poster_path,
r.id AS review_id, r.movie_id, r.user_id, r.rating, r.comment, r.watched_at, r.created_at, r.remote_actor_url, r.watch_medium
r.id AS review_id, r.movie_id, r.user_id, r.rating, r.comment, r.watched_at, r.created_at, r.remote_actor_url, r.watch_medium, r.spoilers
FROM reviews r
INNER JOIN movies m ON m.id = r.movie_id
WHERE r.user_id = ?
@@ -419,7 +419,7 @@ impl DiaryQuery for SqliteDiaryRepository {
Box::pin(async_stream::stream! {
let mut rows = sqlx::query_as::<_, DiaryRow>(
"SELECT m.id, m.external_metadata_id, m.title, m.release_year, m.director, m.poster_path,
r.id AS review_id, r.movie_id, r.user_id, r.rating, r.comment, r.watched_at, r.created_at, r.remote_actor_url, r.watch_medium
r.id AS review_id, r.movie_id, r.user_id, r.rating, r.comment, r.watched_at, r.created_at, r.remote_actor_url, r.watch_medium, r.spoilers
FROM reviews r
INNER JOIN movies m ON m.id = r.movie_id
WHERE r.user_id = ?
@@ -476,7 +476,7 @@ impl DiaryQuery for SqliteDiaryRepository {
let rows = sqlx::query_as::<_, FeedRow>(
"SELECT m.id, m.external_metadata_id, m.title, m.release_year, m.director, m.poster_path,
r.id AS review_id, r.movie_id, r.user_id, r.rating, r.comment,
r.watched_at, r.created_at, r.remote_actor_url, r.watch_medium,
r.watched_at, r.created_at, r.remote_actor_url, r.watch_medium, r.spoilers,
CASE WHEN r.remote_actor_url IS NOT NULL THEN COALESCE(a.handle, r.remote_actor_url)
ELSE COALESCE(u.email, r.user_id) END AS user_email
FROM reviews r

View File

@@ -81,6 +81,7 @@ pub(crate) struct ReviewRow {
pub created_at: String,
pub remote_actor_url: Option<String>,
pub watch_medium: Option<String>,
pub spoilers: bool,
}
impl ReviewRow {
@@ -95,6 +96,7 @@ impl ReviewRow {
self.created_at,
self.remote_actor_url,
self.watch_medium,
self.spoilers,
)
}
}
@@ -116,6 +118,7 @@ pub(crate) struct DiaryRow {
pub created_at: String,
pub remote_actor_url: Option<String>,
pub watch_medium: Option<String>,
pub spoilers: bool,
}
impl DiaryRow {
@@ -138,6 +141,7 @@ impl DiaryRow {
self.created_at,
self.remote_actor_url,
self.watch_medium,
self.spoilers,
)?;
Ok(DiaryEntry::new(movie, review))
}
@@ -189,6 +193,7 @@ pub(crate) struct FeedRow {
pub created_at: String,
pub remote_actor_url: Option<String>,
pub watch_medium: Option<String>,
pub spoilers: bool,
pub user_email: String,
}
@@ -212,6 +217,7 @@ impl FeedRow {
self.created_at,
self.remote_actor_url,
self.watch_medium,
self.spoilers,
)?;
let diary = DiaryEntry::new(movie, review);
Ok(FeedEntry::new(diary, self.user_email))

View File

@@ -36,8 +36,8 @@ impl ReviewRepository for SqliteReviewRepository {
};
sqlx::query(
"INSERT INTO reviews (id, movie_id, user_id, rating, comment, watched_at, created_at, remote_actor_url, watch_medium)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
"INSERT INTO reviews (id, movie_id, user_id, rating, comment, watched_at, created_at, remote_actor_url, watch_medium, spoilers)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
)
.bind(&id)
.bind(&movie_id)
@@ -48,6 +48,7 @@ impl ReviewRepository for SqliteReviewRepository {
.bind(&created_at)
.bind(&remote_actor_url)
.bind(review.watch_medium().map(|wm| wm.to_string()))
.bind(review.spoilers())
.execute(&self.pool)
.await
.map_err(adapter_common::map_sqlx_error)?;
@@ -58,7 +59,7 @@ impl ReviewRepository for SqliteReviewRepository {
async fn get_review_by_id(&self, review_id: &ReviewId) -> Result<Option<Review>, DomainError> {
let id = review_id.value().to_string();
sqlx::query_as::<_, ReviewRow>(
"SELECT id, movie_id, user_id, rating, comment, watched_at, created_at, remote_actor_url, watch_medium
"SELECT id, movie_id, user_id, rating, comment, watched_at, created_at, remote_actor_url, watch_medium, spoilers
FROM reviews WHERE id = ?",
)
.bind(&id)
@@ -77,12 +78,13 @@ impl ReviewRepository for SqliteReviewRepository {
let watch_medium = review.watch_medium().map(|wm| wm.to_string());
sqlx::query(
"UPDATE reviews SET rating = ?, comment = ?, watched_at = ?, watch_medium = ? WHERE id = ?",
"UPDATE reviews SET rating = ?, comment = ?, watched_at = ?, watch_medium = ?, spoilers = ? WHERE id = ?",
)
.bind(rating)
.bind(&comment)
.bind(&watched_at)
.bind(&watch_medium)
.bind(review.spoilers())
.bind(&id)
.execute(&self.pool)
.await
@@ -104,7 +106,7 @@ impl ReviewRepository for SqliteReviewRepository {
async fn get_all_reviews_for_user(&self, user_id: &UserId) -> Result<Vec<Review>, DomainError> {
let uid = user_id.value().to_string();
sqlx::query_as::<_, ReviewRow>(
"SELECT id, movie_id, user_id, rating, comment, watched_at, created_at, remote_actor_url, watch_medium
"SELECT id, movie_id, user_id, rating, comment, watched_at, created_at, remote_actor_url, watch_medium, spoilers
FROM reviews WHERE user_id = ? ORDER BY watched_at DESC",
)
.bind(&uid)