---
title: Movies Diary — Hexagonal Architecture
---
graph TB
subgraph Binaries["Binaries (thin: config + bootstrap + run)"]
SERVER["server
load config, bootstrap::build_server, axum::serve"]
WORKER["worker
bootstrap::build_worker
Concurrent dispatch, graceful shutdown"]
TUI["tui
Terminal UI (deprecated)"]
end
subgraph Config["config"]
CFG["AppConfig
defaults, config.toml / CONFIG_FILE,
legacy env names"]
end
subgraph Application["Application Layer"]
direction TB
DEPS["Deps
one narrow deps struct per use case"]
APP_PORTS["ReviewLogger
application-layer port"]
subgraph UseCases["Use Cases"]
UC_AUTH["auth
login, register"]
UC_DIARY["diary
log_review, edit_review,
get_diary, get_activity_feed,
export"]
UC_MOVIES["movies
get_movies, get_movie_profile,
enrich_movie, request_enrichment,
sync_poster, reindex_search,
merge_duplicates"]
UC_IMPORT["import
create_session, apply_mapping,
execute, profiles"]
UC_USERS["users
get_users, get_profile,
update_profile, delete_account"]
UC_WATCHLIST["watchlist
add, remove, get"]
UC_WRAPUP["wrapup
generate, compute,
list, delete"]
UC_GOALS["goals
create, update, delete,
get, list"]
UC_INTEGRATIONS["integrations
webhooks, watch_queue,
confirm, dismiss"]
UC_SEARCH["search
execute"]
UC_PERSON["person
get, get_credits"]
UC_SOCIAL["social
follow, unfollow,
accept, reject, block"]
end
subgraph EventHandlers["Event Handlers"]
EH_MOVIE["MovieEnrichmentHandler
on MovieEnrichmentRequested"]
EH_PERSON["PersonEnrichmentHandler
on PersonEnrichmentRequested"]
EH_DISCOVER["MovieDiscoveryIndexer"]
EH_CLEANUP["SearchCleanupHandler"]
EH_REINDEX["SearchReindexHandler"]
EH_WRAPUP["WrapUpEventHandler"]
EH_POSTER["PosterSyncHandler
poster sync"]
end
subgraph Jobs["Periodic Jobs"]
JOB_IMPORT["ImportSessionCleanup"]
JOB_WATCH["WatchEventCleanup"]
JOB_STALE["EnrichmentStaleness"]
JOB_WRAPGEN["WrapUpAutoGenerate"]
JOB_WRAPCLEAN["WrapUpCleanup"]
JOB_SESSION["RefreshSessionCleanup"]
JOB_DEDUP["MovieDeduplication
merge duplicate movie
records (daily)"]
end
WORKER_SVC["WorkerService
Semaphore(8), JoinSet,
shutdown signal"]
end
subgraph Domain["Domain Layer (0 dependencies)"]
direction TB
subgraph Models["Models"]
M_MOVIE["Movie, MovieSummary,
MovieProfile"]
M_REVIEW["Review, ReviewEdit,
DiaryEntry, FeedEntry"]
M_USER["User, UserSummary"]
M_PERSON["Person, PersonId,
PersonCredits"]
M_WATCHLIST["WatchlistEntry,
WatchEvent"]
M_GOAL["Goal, GoalWithProgress,
UserSettings, RemoteGoalEntry"]
M_WRAPUP["WrapUpReport,
MovieRef, PersonStat"]
M_SEARCH["SearchQuery,
SearchResults"]
end
subgraph Ports["Port Traits (Interfaces)"]
P_REPOS["MovieCommand / MovieQuery
ReviewRepository
DiaryQuery / StatsRepository
UserRepository / UserProfileFieldsRepository
WatchlistRepository
WatchEventCommand / WatchEventQuery
WebhookTokenRepository
ImportSessionRepository / ImportProfileRepository
MovieProfileRepository
WrapUpRepository / WrapUpStatsQuery
GoalCommand / GoalQuery
UserSettingsRepository / RefreshSessionRepository
MovieDeduplicator"]
P_SERVICES["AuthService
MetadataClient / MovieEnrichmentClient
PersonEnrichmentClient
PosterFetcherClient
ImageFetcher / ObjectStorage
EventPublisher / EventConsumer
PasswordHasher
DiaryExporter / DocumentParser
RssFeedRenderer / MediaServerParser"]
P_SEARCH["SearchPort / SearchCommand
PersonQuery / PersonCommand
FederatedProfileQuery"]
P_FEDERATION["SocialCommand / SocialQuery
FederationAdminQuery
LocalApContentQuery
RemoteWatchlistRepository
RemoteGoalRepository"]
end
subgraph DomainServices["Services (pure, no I/O)"]
DS_WRAPUP["WrapUpAnalyzer
build_report, compute_*"]
DS_REVIEW["ReviewHistoryAnalyzer
rating_trend"]
end
EVENTS["DomainEvent enum
ReviewLogged, MovieDiscovered,
GoalCreated, GoalUpdated,
UserDeleted, UserAccountMoved,
SearchReindexRequested, ..."]
VO["Value Objects
MovieId, UserId, Rating,
WatchMedium, Email, Username,
Password, ..."]
end
subgraph ApiTypes["api-types"]
DTO["DTOs
MovieDto, ReviewDto,
FeedEntryDto, UserSummaryDto,
HtmlPageContext, ..."]
end
subgraph Bootstrap["bootstrap"]
BS["build_server, build_worker
Composition root: the only crate that names adapters"]
end
subgraph EventPayload["event-payload"]
EP["Serde payloads for domain events"]
end
subgraph Adapters["Adapters (implement Port Traits)"]
direction TB
subgraph Http["HTTP driving adapter"]
A_HTTP["http-axum
JSON API, classic HTML (askama),
OpenAPI, federation-gated routes,
one refusal shape"]
end
subgraph Storage["Storage"]
A_SQLITE["sqlite
repositories per aggregate, FTS5 search,
social graph, durable event queue, migrations"]
A_OBJ["object-storage
S3 / filesystem"]
end
subgraph Messaging["Messaging"]
A_NATS["nats
JetStream / Core"]
A_EVT_PUB["event-publisher
In-memory channel"]
end
subgraph External["External Services"]
A_METADATA["metadata
TMDB / OMDb search/details"]
A_TMDB["tmdb-enrichment
Credits, keywords, cast"]
A_POSTER["poster-fetcher
TMDB image download"]
A_AUTH["auth
JWT tokens"]
end
subgraph Federation["Federation (feature-gated)"]
A_AP["activitypub
k_ap library; ActivityPubEventHandler
(reviews, watchlist, goals, UserDeleted, UserAccountMoved)"]
A_SQLITE_FED["sqlite-federation
k_ap repositories"]
end
subgraph Media["Media Processing"]
A_IMG["image-converter
AVIF/WebP"]
end
subgraph Formats["Formats"]
A_RSS["rss
Feed generation"]
A_EXPORT["export
CSV/JSON diary"]
A_IMPORT["importer
CSV/JSON/XLSX parser"]
A_MEDIA_SERVER["media-server
Jellyfin + Plex webhook parsers"]
end
end
%% Dependency arrows
SERVER -->|"loads"| Config
SERVER -->|"calls"| Bootstrap
WORKER -->|"loads"| Config
WORKER -->|"calls"| Bootstrap
Bootstrap -->|"wires"| Adapters
Bootstrap -->|"builds deps for"| Application
A_HTTP -->|"uses"| Application
A_HTTP -->|"maps to"| ApiTypes
TUI -->|"typed API access"| ApiTypes
Application -->|"depends on"| Domain
UC_WRAPUP -->|"delegates to"| DS_WRAPUP
Adapters -.->|"implements"| Ports
A_NATS -.->|"serialises with"| EventPayload
A_SQLITE -.->|"event queue serialises with"| EventPayload
%% Key data flows
A_HTTP ===|"HTTP"| DTO
WORKER ===|"Events"| EVENTS
classDef domain fill:#1a1a2e,stroke:#e94560,color:#fff
classDef app fill:#16213e,stroke:#0f3460,color:#fff
classDef adapter fill:#0f3460,stroke:#533483,color:#fff
classDef binary fill:#533483,stroke:#e94560,color:#fff
classDef api fill:#2a2a4a,stroke:#e94560,color:#fff
class Domain domain
class DomainServices domain
class Application app
class Adapters adapter
class Binaries binary
class Config app
class Bootstrap binary
class ApiTypes api