feat: Jellyfin/Plex auto-import via watch queue
Some checks failed
CI / Check / Test (push) Failing after 6m5s

Webhook ingestion from media servers — movies land in a pending
watch queue, user rates and confirms to create diary entries.

- domain: WatchEvent, WebhookToken models, MediaServerParser port
- adapters: jellyfin + plex parser crates, SQLite + Postgres repos
- application: ingest/confirm/dismiss/cleanup use cases, token mgmt
- presentation: webhook endpoints (bearer + query param auth),
  watch queue + integrations settings HTML pages, OpenAPI docs
- worker: WatchEventCleanupJob (daily, 30d retention)

Movie resolution deferred to confirm — single canonical path
through log_review for enrichment, poster fetch, federation.
This commit is contained in:
2026-06-02 17:34:16 +02:00
parent 6bd728fd50
commit aadad3cfb0
65 changed files with 2946 additions and 38 deletions

View File

@@ -7,6 +7,7 @@ pub mod search;
pub mod social;
pub mod users;
pub mod watchlist;
pub mod webhook;
pub use auth::*;
pub use common::*;
@@ -16,3 +17,4 @@ pub use movies::*;
pub use social::*;
pub use users::*;
pub use watchlist::*;
pub use webhook::*;

View File

@@ -0,0 +1,61 @@
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, Deserialize, utoipa::ToSchema)]
pub struct GenerateTokenRequest {
pub provider: String,
pub label: Option<String>,
}
#[derive(Debug, Clone, Serialize, utoipa::ToSchema)]
pub struct GenerateTokenResponse {
pub id: String,
pub token: String,
pub webhook_url: String,
}
#[derive(Debug, Clone, Serialize, utoipa::ToSchema)]
pub struct WebhookTokenDto {
pub id: String,
pub provider: String,
pub label: Option<String>,
pub created_at: String,
pub last_used_at: Option<String>,
}
#[derive(Debug, Clone, Serialize, utoipa::ToSchema)]
pub struct WatchQueueEntryDto {
pub id: String,
pub title: String,
pub year: Option<u16>,
pub movie_id: Option<String>,
pub source: String,
pub watched_at: String,
}
#[derive(Debug, Clone, Deserialize, utoipa::ToSchema)]
pub struct ConfirmWatchRequest {
pub confirmations: Vec<ConfirmWatchEntry>,
}
#[derive(Debug, Clone, Deserialize, utoipa::ToSchema)]
pub struct ConfirmWatchEntry {
pub watch_event_id: Uuid,
pub rating: u8,
pub comment: Option<String>,
}
#[derive(Debug, Clone, Serialize, utoipa::ToSchema)]
pub struct ConfirmWatchResponse {
pub confirmed: u32,
}
#[derive(Debug, Clone, Deserialize, utoipa::ToSchema)]
pub struct DismissWatchRequest {
pub event_ids: Vec<Uuid>,
}
#[derive(Debug, Clone, Serialize, utoipa::ToSchema)]
pub struct DismissWatchResponse {
pub dismissed: u32,
}