# 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