diff --git a/.env.example b/.env.example
index 79f9f93..ba25f2a 100644
--- a/.env.example
+++ b/.env.example
@@ -53,7 +53,7 @@ EVENT_BUS_BACKEND=db
# EVENT_BUS_BACKEND=nats
# NATS_URL=nats://localhost:4222
# NATS_MODE=jetstream # "jetstream" (default, at-least-once) or "core" (fire-and-forget)
-# NATS_SUBJECT_PREFIX=movies-diary.events
+# NATS_SUBJECT_PREFIX=screened.events
# NATS_STREAM_NAME=MOVIES_DIARY_EVENTS
# NATS_CONSUMER_NAME=worker
diff --git a/README.md b/README.md
index a8c06c6..ff5f9a9 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Movies Diary
+# Screened
A self-hosted, server-side rendered movie logging system with a full REST API. Built in Rust — no JavaScript in the HTML interface, just HTML forms and an RSS feed. Designed to run as a lightweight widget embedded on a personal site or as a backend for third-party clients.
@@ -10,7 +10,7 @@ A self-hosted, server-side rendered movie logging system with a full REST API. B
- Movie enrichment via TMDb — full cast, crew, genres, keywords, runtime, budget/revenue, ratings; fetched automatically on movie discovery and refreshed every 30 days; exposed via `GET /api/v1/movies/{id}/profile`
- RSS/Atom feed for public subscription (global and per-user)
- JWT authentication via cookie (HTML) or Bearer token (REST API)
-- ActivityPub federation — follow/unfollow remote users, accept/reject/remove followers, federated reviews broadcast as `Note` objects with `#MoviesDiary` + `#MovieTitle` hashtags, paginated outbox, boost/Announce tracking, NodeInfo discovery endpoint, shared inbox delivery, actor profile sync (bio, avatar, discoverable)
+- ActivityPub federation — follow/unfollow remote users, accept/reject/remove followers, federated reviews broadcast as `Note` objects with `#Screened` + `#MovieTitle` hashtags, paginated outbox, boost/Announce tracking, NodeInfo discovery endpoint, shared inbox delivery, actor profile sync (bio, avatar, discoverable)
- Federation moderation — instance-level domain blocking (admin-managed), per-user actor blocking with `Block` activity, delivery filter excludes blocked actors and blocked-domain inboxes
- CSV and JSON diary export
- File importer: upload CSV, TSV, JSON, or XLSX from any source (Letterboxd, IMDb, etc.), map columns to domain fields via a step-by-step wizard or REST API, save mapping profiles for repeat imports
diff --git a/crates/adapters/activitypub/src/lib.rs b/crates/adapters/activitypub/src/lib.rs
index c6484c6..be0ca77 100644
--- a/crates/adapters/activitypub/src/lib.rs
+++ b/crates/adapters/activitypub/src/lib.rs
@@ -6,6 +6,8 @@ pub mod review_handler;
pub(crate) mod urls;
pub mod user_adapter;
+use domain::PRODUCT_NAME;
+
// Re-export the generic base types that callers need
pub use activitypub_base::{
ActivityPubService, ApFederationConfig, ApObjectHandler, ApUser, ApUserRepository,
@@ -46,7 +48,7 @@ pub async fn wire(
}),
base_url.clone(),
allow_registration,
- "movies-diary".to_string(),
+ PRODUCT_NAME.to_lowercase(),
cfg!(debug_assertions),
)
.await?,
diff --git a/crates/adapters/activitypub/src/objects.rs b/crates/adapters/activitypub/src/objects.rs
index 3f04a53..bac5a01 100644
--- a/crates/adapters/activitypub/src/objects.rs
+++ b/crates/adapters/activitypub/src/objects.rs
@@ -69,9 +69,9 @@ pub fn review_to_ap_object(
let tag = vec![
ApHashtag {
kind: "Hashtag".to_string(),
- href: Url::parse(&format!("{}/tags/moviesdiary", base_url))
+ href: Url::parse(&format!("{}/tags/screened", base_url))
.expect("valid base_url"),
- name: "#MoviesDiary".to_string(),
+ name: "#Screened".to_string(),
},
ApHashtag {
kind: "Hashtag".to_string(),
@@ -137,7 +137,7 @@ mod tests {
);
assert_eq!(obj.tag.len(), 2);
let names: Vec<&str> = obj.tag.iter().map(|t| t.name.as_str()).collect();
- assert!(names.contains(&"#MoviesDiary"));
+ assert!(names.contains(&"#Screened"));
assert!(names.contains(&"#Dune"));
}
}
diff --git a/crates/adapters/nats/src/config.rs b/crates/adapters/nats/src/config.rs
index 402e63d..1056a93 100644
--- a/crates/adapters/nats/src/config.rs
+++ b/crates/adapters/nats/src/config.rs
@@ -28,9 +28,9 @@ impl NatsConfig {
};
let subject_prefix = std::env::var("NATS_SUBJECT_PREFIX")
- .unwrap_or_else(|_| "movies-diary.events".to_string());
+ .unwrap_or_else(|_| "screened.events".to_string());
let stream_name = std::env::var("NATS_STREAM_NAME")
- .unwrap_or_else(|_| "MOVIES_DIARY_EVENTS".to_string());
+ .unwrap_or_else(|_| "SCREENED_EVENTS".to_string());
let consumer_name = std::env::var("NATS_CONSUMER_NAME")
.unwrap_or_else(|_| "worker".to_string());
@@ -61,8 +61,8 @@ mod tests {
let cfg = NatsConfig::from_env().unwrap();
assert_eq!(cfg.url, "nats://localhost:4222");
assert_eq!(cfg.mode, NatsMode::JetStream);
- assert_eq!(cfg.subject_prefix, "movies-diary.events");
- assert_eq!(cfg.stream_name, "MOVIES_DIARY_EVENTS");
+ assert_eq!(cfg.subject_prefix, "screened.events");
+ assert_eq!(cfg.stream_name, "SCREENED_EVENTS");
assert_eq!(cfg.consumer_name, "worker");
unsafe { std::env::remove_var("NATS_URL"); }
diff --git a/crates/adapters/template-askama/templates/base.html b/crates/adapters/template-askama/templates/base.html
index 8ea0eac..3b3fd74 100644
--- a/crates/adapters/template-askama/templates/base.html
+++ b/crates/adapters/template-askama/templates/base.html
@@ -9,7 +9,7 @@
content="A personal movie diary — track what you watch, rate and review films."
/>
-
+
@@ -26,7 +26,7 @@
- Movies Diary
+ Screened