# Architecture Hexagonal (ports & adapters) architecture. Dependencies point inward — adapters implement domain ports, application orchestrates use cases, presentation handles HTTP. ## Crate dependency graph ```mermaid graph TD subgraph Entry Points bootstrap["bootstrap
HTTP server, DI wiring"] worker["worker
background job consumer"] end subgraph Interface Layer presentation["presentation
axum handlers, extractors, AppState"] api_types["api-types
DTOs, OpenAPI"] end subgraph Application Layer application["application
use cases, FederationEventService"] end subgraph Domain Layer domain["domain
models, value objects, events, port traits"] end subgraph Adapters postgres["postgres
UserRepo, ThoughtRepo, LikeRepo,
BoostRepo, FollowRepo, BlockRepo,
TagRepo, FeedRepo, FederationContentRepo, ...
"] activitypub["activitypub
FederationActionPort,
FederationBroadcastPort,
FederationSchedulerPort
(wraps k-ap)
"] postgres_fed["postgres-federation
k-ap DB traits"] postgres_search["postgres-search
SearchPort"] auth["auth
AuthService, ApiKeyService"] nats["nats
EventPublisher, EventConsumer"] storage["storage
MediaStore"] event_transport["event-transport
event delivery"] event_payload["event-payload
event serialization"] end bootstrap --> presentation bootstrap --> application bootstrap --> postgres bootstrap --> postgres_fed bootstrap --> postgres_search bootstrap --> activitypub bootstrap --> auth bootstrap --> nats bootstrap --> storage bootstrap --> event_transport bootstrap --> event_payload worker --> application worker --> activitypub worker --> postgres worker --> postgres_fed worker --> nats worker --> event_transport worker --> event_payload presentation --> application presentation --> api_types presentation --> domain application --> domain postgres --> domain activitypub --> domain postgres_fed -.-> domain postgres_search --> domain postgres_search --> postgres auth --> domain nats --> domain storage --> domain event_transport --> domain event_payload --> domain ``` ## Domain ports ```mermaid classDiagram class domain { <> } namespace Data Ports { class UserRepository { <> find_by_id() find_by_username() save() update_profile() } class ThoughtRepository { <> save() find_by_id() delete() update_content() } class LikeRepository { <> } class BoostRepository { <> } class FollowRepository { <> } class BlockRepository { <> } class TagRepository { <> } class FeedRepository { <> } class NotificationRepository { <> } class EngagementRepository { <> } class SearchPort { <> } } namespace Federation Ports { class FederationContentRepository { <> outbox_entries_for_actor() find_remote_actor_id() intern_remote_actor() accept_note() retract_note() } class FederationBroadcastPort { <> broadcast_create() broadcast_delete() broadcast_update() broadcast_announce() broadcast_like() } class FederationActionPort { <> } class FederationLookupPort { <> } class FederationFollowPort { <> } class FederationFollowRequestPort { <> } class FederationFetchPort { <> } class FederationBlockPort { <> } class FederationSchedulerPort { <> } } namespace Infra Ports { class EventPublisher { <> } class EventConsumer { <> } class AuthService { <> } class PasswordHasher { <> } class MediaStore { <> } } FederationActionPort --|> FederationLookupPort FederationActionPort --|> FederationFollowPort FederationActionPort --|> FederationFollowRequestPort FederationActionPort --|> FederationFetchPort FederationActionPort --|> FederationBlockPort ``` ## Dependency rule ``` bootstrap/worker ──► presentation ──► application ──► domain ◄── adapters ``` - **domain** — zero framework deps, pure business logic, defines all port traits - **application** — orchestrates use cases, depends only on domain - **presentation** — HTTP handlers (axum), depends on domain + application - **adapters** — implement domain ports, depend inward on domain only - **bootstrap/worker** — composition roots, wire adapters into ports