feat: search reindex, worker improvements, person IDs, user display names

- add admin POST /api/v1/admin/reindex-search endpoint + event-driven handler
- backfill persons from movie_cast/movie_crew into persons table
- paginate person list_page/backfill_from_credits_batch to cap memory
- concurrent worker event dispatch with semaphore (max 8)
- graceful worker shutdown (drain in-flight tasks on SIGINT)
- always ack events, log handler errors as warnings (no infinite retry)
- NATS ack_wait 600s, AtomicBool guard against concurrent reindex
- add username/display_name to UserSummaryDto and users list
- add person_id to CastMemberDto/CrewMemberDto via get_movie_profile use case
- add movie_id to wrapup MovieRef, person_id to wrapup PersonStat
- thread tmdb_person_id through wrapup cast pipeline
- add is_federated to FeedEntryDto
- cap orphaned persons query with LIMIT 500
- add SPA link to classic site footer
This commit is contained in:
2026-06-04 14:43:28 +02:00
parent af8e58aeb8
commit bd7dc648c4
36 changed files with 693 additions and 118 deletions

View File

@@ -7,7 +7,7 @@ use domain::{
},
value_objects::{
Comment, Email, ExternalMetadataId, MovieId, MovieTitle, PosterPath, Rating, ReleaseYear,
ReviewId, UserId,
ReviewId, UserId, Username,
},
};
use uuid::Uuid;
@@ -237,6 +237,8 @@ impl MovieStatsRow {
pub(crate) struct UserSummaryRow {
pub id: String,
pub email: String,
pub username: String,
pub display_name: Option<String>,
pub total_movies: i64,
pub avg_rating: Option<f64>,
pub avatar_path: Option<String>,
@@ -247,6 +249,8 @@ impl UserSummaryRow {
Ok(UserSummary::new(
UserId::from_uuid(parse_uuid(&self.id)?),
Email::new(self.email)?,
Username::new(self.username)?,
self.display_name,
self.total_movies,
self.avg_rating,
self.avatar_path,