Commit Graph

48 Commits

Author SHA1 Message Date
b844339795 fix(domain): ImportSession::new() generates own ID, add from_persistence() 2026-06-12 01:41:03 +02:00
aec5f6b058 feat(dependencies): add async-stream and bytes to Cargo.toml and Cargo.lock
Some checks failed
CI / Check / Test (push) Has been cancelled
refactor(adapters): update diary.rs to use BoxStream from futures
2026-06-12 01:20:45 +02:00
9c44330f14 feat(adapters): stream_user_history in SQLite and Postgres diary adapters 2026-06-12 01:10:21 +02:00
40cb15e7cb refactor(postgres): split fat PostgresRepository into per-port structs
Some checks failed
CI / Check / Test (push) Has been cancelled
2026-06-12 00:00:15 +02:00
8ac87a3735 refactor: split jobs.rs into per-context modules 2026-06-11 14:44:23 +02:00
3a3f3b3889 db: refresh_sessions migration + SQLite/Postgres adapters 2026-06-11 14:31:46 +02:00
517a18da8a db: person enrichment migrations + adapter updates 2026-06-11 13:34:10 +02:00
7df24a19ee domain: add person enrichment fields, event, port 2026-06-11 13:30:19 +02:00
d389e26e39 fix: broadcast goal progress on review log, fix goal handler security gaps
Some checks failed
CI / Check / Test (push) Has been cancelled
- Broadcast GoalUpdated AP note after ReviewLogged so federated goal
  progress reflects the new review count without requiring a manual goal edit
- Add attribution check in GoalObjectHandler::on_update (mirrors
  review_handler) to prevent any remote actor from overwriting another's goal
- Implement on_actor_removed in GoalObjectHandler via new
  RemoteGoalRepository::remove_all_by_actor — remote goals were never
  cleaned up when an actor unfollowed or was deleted
- Add remove_all_by_actor to SQLite, Postgres, Noop, and test Panic impls
2026-06-10 02:40:25 +02:00
6d3182525f fmt
Some checks failed
CI / Check / Test (push) Has been cancelled
2026-06-09 02:16:18 +02:00
7bcbc59587 fix: implement get_all_reviews_for_user, add crate metadata
Some checks failed
CI / Check / Test (push) Failing after 43s
Replace todo!() stubs in sqlite/postgres adapters with
actual queries. Add description+license to presentation crate.
2026-06-09 02:12:35 +02:00
fff5f4af2f feat: goals — "watch N movies in YEAR" with progress bar
Domain: Goal entity, UserSettings (federation toggle), RemoteGoalEntry.
Ports: GoalRepository, UserSettingsRepository, RemoteGoalRepository.
Adapters: sqlite + postgres repos, migrations, AP content query extensions.
Application: CRUD use cases (create/update/delete/get/list), settings use cases.
API: 7 endpoints (/goals CRUD, /users/{id}/goals, /settings) with utoipa docs.
Federation: GoalObject (Note + goal discriminator), outbound broadcast with
per-user toggle, inbound GoalObjectHandler in CompositeObjectHandler.
SPA: API client + hooks, GoalCard (shadcn Card+Progress+DropdownMenu),
GoalSheet (Drawer), profile integration (editable own, read-only others),
federation toggle in settings (Switch).
Classic HTML: glassmorphic goal card on profile, Frutiger Aero styling.
Progress computed from existing reviews — backwards compatible.
2026-06-08 22:37:52 +02:00
886f26c7dc fix: broadcast AP Update after poster sync to fix missing posters on remote instances
Some checks failed
CI / Check / Test (push) Has been cancelled
New movies had no poster at AP broadcast time (race between poster sync
and ReviewLogged handler). PosterSynced event now fires after sync
completes, triggering Update notes so remote apps get the poster URL.
2026-06-04 23:12:27 +02:00
bd7dc648c4 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
2026-06-04 14:43:28 +02:00
4206bb4b06 fix: diary sort_by rating_desc/rating_asc in all/movie queries 2026-06-04 01:28:35 +02:00
d94ccbe057 refactor: store typed WrapUpReport in domain, serialize in adapters
Some checks failed
CI / Check / Test (push) Failing after 45s
2026-06-03 01:25:16 +02:00
e8e83d3f16 assets + fmt
Some checks failed
CI / Check / Test (push) Has been cancelled
2026-06-03 01:13:06 +02:00
fc086de7f7 refactor: move DateRange validation to value object, add delete/cleanup
Some checks failed
CI / Check / Test (push) Failing after 40s
2026-06-03 00:58:07 +02:00
241063c914 feat: wrapup date validation, delete endpoint, failed record cleanup
Some checks failed
CI / Check / Test (push) Failing after 41s
2026-06-03 00:54:08 +02:00
bf0350c87a fmt
Some checks failed
CI / Check / Test (push) Failing after 6m39s
2026-06-02 23:50:20 +02:00
5a6abdcc23 feat(adapters): WrapUpStatsQuery + WrapUpRepository for postgres/sqlite 2026-06-02 22:04:46 +02:00
b9210b6c4e fix: batch N+1 queries in import duplicate check and watch event dismiss
Some checks failed
CI / Check / Test (push) Failing after 5m54s
apply_mapping: 2 batch queries instead of up to 2N per-row lookups
dismiss: single fetch + single update instead of 2N per-event queries
2026-06-02 20:05:15 +02:00
ac7edd6953 WIP: federation + integrations
Some checks failed
CI / Check / Test (push) Failing after 5m56s
2026-06-02 19:50:19 +02:00
aadad3cfb0 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.
2026-06-02 17:34:16 +02:00
6bd728fd50 feat: replace instance actor decorator with real DB row
Some checks failed
CI / Check / Test (push) Failing after 52s
Migrations (postgres + sqlite) insert a service actor with a well-known
UUID. Removes the InstanceActorUserRepo wrapper.
2026-05-30 03:16:03 +02:00
2355f89bed refactor: fix all clippy warnings properly
- UserProfile struct groups display_name/bio/avatar/banner/also_known_as/profile_fields
- User::from_persistence takes UserProfile (6 args, was 11)
- PersistedReview struct for Review::from_persistence (1 arg, was 8)
- WatchlistApInput struct for watchlist_to_ap_object (1 arg, was 8)
- ActivityPubDeps struct for activitypub::wire (1 arg, was 11)
- FederationRepos type alias for wire() return types
- FeedSortBy: impl std::str::FromStr instead of inherent from_str
- postgres users.rs: row_to_user takes &PgRow like sqlite
- collapse nested ifs in multipart handlers
- type alias for complex return types (image-converter, worker)
- tui: allow large_enum_variant at crate level (pre-existing, unrelated)
2026-05-29 11:19:02 +02:00
68a939f6c4 Refactor code for improved readability and consistency
- Simplified error handling in `PostgresApContentQuery` and `SqliteApContentQuery` by aligning the formatting of `try_get` calls.
- Removed unnecessary line breaks and improved formatting in various repository implementations for better readability.
- Consolidated imports in `lib.rs` and `factory.rs` to maintain a cleaner structure.
- Enhanced consistency in async function signatures across multiple files.
- Updated test helpers and use cases to streamline code and improve clarity.
- Refactored `InMemory` repositories to enhance readability by aligning method implementations.
2026-05-29 10:58:44 +02:00
624cfe5799 feat: migrate k-ap 0.1.10→0.3.1, fix AP gaps
- split FederationRepository into FollowRepository, ActorRepository, BlocklistRepository, ActivityRepository
- RemoteActor: 5 new fields (bio, banner_url, followers_url, following_url, also_known_as)
- ApObjectHandler split: get_local_objects_page/count_local_posts → ApContentReader trait
- builder API: positional args → named setters
- broadcast_create_note/update_note: add ApVisibility + mentioned_inboxes params
- backfill_outbox → import_remote_outbox
- ApUser: also_known_as Option<String> → Vec<String>, new fields

AP gaps fixed:
- add GET /users/{id}/followers + /following with content negotiation
- wire EventPublisher into builder via FederationEventBridge adapter
- add display_name field full stack (domain→DB→API→AP)
- DB-side outbox pagination (get_local_reviews_page)
- set featured_url on ApUser
2026-05-29 10:42:53 +02:00
51bd580a04 watchlist backfill
Some checks failed
CI / Check / Test (push) Failing after 57s
CI / Release build (push) Has been skipped
2026-05-28 03:52:38 +02:00
e41d85bd7e feat: show user avatars on /users page
All checks were successful
CI / Check / Test / Build (push) Successful in 24m46s
2026-05-13 23:45:19 +02:00
19171806b9 fmt
Some checks failed
CI / Check / Test / Build (push) Has been cancelled
2026-05-13 23:38:57 +02:00
fdd61ae701 feat: refactor user profile handling and integrate ApProfileField structure 2026-05-13 22:59:38 +02:00
815178e6a4 feat(ap): ActivityPub spec compliance and profile completeness
Phase 1 — spec compliance:
- Add AS_PUBLIC constant; add to/cc fields to CreateActivity, DeleteActivity,
  UpdateActivity, AddActivity; populate on all broadcast call sites
- Add @context to outbox CreateActivity items
- Set manuallyApprovesFollowers: true to match actual Pending follow flow
- Gate PermissiveVerifier behind FEDERATION_DEBUG env var
- Add updated timestamp to Person actor JSON
- Improve actor update delivery logging

Phase 2a Batch 1 — AP layer:
- Add /inbox shared inbox route; add endpoints.sharedInbox to Person
- Paginate followers and following collections (20/page, OrderedCollectionPage)

Phase 2a Batch 2 — profile completeness:
- DB migrations: banner_path, also_known_as columns; user_profile_fields table
- ProfileField value object; UserProfileFieldsRepository port
- Banner image upload (stored via image-converter, surfaced as image in Person)
- alsoKnownAs field in Person (account migration support)
- Custom profile fields (up to 4 PropertyValue attachments in Person)
- Profile settings UI: banner preview/upload, alsoKnownAs input, fields form
- PUT /api/v1/profile/fields API endpoint
2026-05-13 22:21:41 +02:00
5cd7409491 feat(postgres): persist outbox_url, implement get_following_outbox_url 2026-05-13 01:24:34 +02:00
53df90ab1f feat: MovieDto enrichment, movie detail page, PWA, watchlist, watchlist federation 2026-05-13 00:23:45 +02:00
2fd8734d23 fix: close search index consistency gaps (orphan cleanup, discovery indexing, poster sync) 2026-05-12 19:05:22 +02:00
c6770659c5 feat: extensible search engine with person entities (FTS5/tsvector) 2026-05-12 18:47:06 +02:00
cea414fe60 refactor: split ImageRefPort into ImageRefCommand and ImageRefQuery 2026-05-12 15:10:49 +02:00
696e3e170c feat: async image conversion service (avif/webp) with backfill 2026-05-12 15:05:28 +02:00
4269eca582 feat: implement movie listing functionality with pagination and search 2026-05-12 13:57:55 +02:00
38d13fbff1 feat: implement TMDb enrichment for movie profiles
- Add SqliteMovieProfileRepository for managing movie profiles in SQLite.
- Create TmdbEnrichmentClient to fetch movie details from TMDb API.
- Implement enrichment event handling with EnrichmentHandler.
- Introduce periodic jobs for cleaning up expired import sessions and checking for stale movie profiles.
- Update application context to include movie profile repository.
- Add API endpoint to retrieve movie profiles.
- Extend domain models with new structures for movie enrichment (Genre, Keyword, CastMember, CrewMember, MovieProfile).
- Modify event system to include MovieEnrichmentRequested event.
- Enhance tests to cover new functionality and ensure stability.
2026-05-12 13:23:41 +02:00
f0620f5aa1 feat: discoverability (NodeInfo, hashtags) and moderation (domain/actor blocking)
- NodeInfo at /.well-known/nodeinfo + /nodeinfo/2.0
- Hashtags #MoviesDiary + #MovieTitle on review posts; /tags/{tag} redirect
- Domain blocking: blocked_domains table, admin API + HTML, inbox enforcement
- Per-actor blocking: blocked_actors table, user API + HTML, BlockActivity send/receive
- Delivery filter excludes blocked actors and blocked-domain inboxes
2026-05-12 01:05:46 +02:00
80f620c840 feat: image storage generalization, user profile, and federation polish
- Replace PosterStorage with generic ImageStorage port (IMAGE_STORAGE_BACKEND/PATH env vars)
- Rename poster-storage crate to image-storage; serve at /images/{*key}
- Add bio and avatar_path to User model (migration 0009_user_profile)
- update_profile use case with avatar upload, mime validation, old avatar cleanup
- GET/PUT /api/v1/profile and GET/POST /settings/profile HTML page
- Enrich AP Person actor with summary, icon, url, discoverable fields
- Store remote actor avatar_url (migration 0010_ap_remote_actor_avatar)
- Shared inbox delivery via collect_inboxes deduplication
- Broadcast Update(Person) to followers on UserUpdated event
- Paginated outbox: OrderedCollection + OrderedCollectionPage with cursor
- Announce/boost tracking in ap_announces table (migration 0011_ap_announces)
2026-05-11 22:59:52 +02:00
b2a2aa4262 movie detail page + importer architecture fix 2026-05-10 23:59:26 +02:00
f2f1317660 importer feature 2026-05-10 21:23:56 +02:00
810d051dee Refactor event payload handling across adapters
- Introduced `event-payload` crate to centralize event payload definitions.
- Updated NATS and PostgreSQL adapters to use the new `EventPayload` type.
- Removed redundant event payload definitions and conversion implementations from NATS and PostgreSQL adapters.
- Simplified SQLite event queue to utilize the new `EventPayload`.
- Refactored wiring functions for PostgreSQL and SQLite to improve database connection handling and migration.
- Cleaned up presentation and worker crates by removing unused event publisher dependencies and related wiring functions.
2026-05-10 18:41:42 +02:00
dca50b46d1 feat: add SQLite and PostgreSQL event queue adapters with migrations 2026-05-10 17:46:16 +02:00
597685520c feat: postgresql adapter 2026-05-10 01:57:10 +02:00