Architecture Overview

Firmiana follows a layered architecture pattern typical of Micronaut applications.

Layer Diagram

┌──────────────────────────────────────────────────────┐
│                  HTTP Clients                         │
│         (Element, Cinny, Element X, curl)             │
└──────────────────┬───────────────────────────────────┘

┌──────────────────▼───────────────────────────────────┐
│              Controllers (43+)                        │
│  Matrix Client-Server API routes under                 │
│  /_matrix/client/v3, /_matrix/federation/v1, etc.     │
├──────────────────────────────────────────────────────┤
│              Security Layer                           │
│  MatrixAccessTokenValidator → Bearer token auth       │
│  CurrentUserService → Extract authenticated user      │
├──────────────────────────────────────────────────────┤
│              Services                                 │
│  RoomEventService, SyncNotifier, MatrixTokenService,  │
│  FederationRequestSigningService, etc.                │
├──────────────────────────────────────────────────────┤
│              Repositories                             │
│  Micronaut Data JDBC interfaces (@JdbcRepository)     │
├──────────────────────────────────────────────────────┤
│              Database                                 │
│  H2 embedded (file-based) + Flyway migrations         │
└──────────────────────────────────────────────────────┘

Key Components

Controllers

Controllers are organised by feature area under com.firmiana.matrix.controller:

PackagePurposeExample
controller/Top-level Matrix endpointsV3Controller, V3SyncController
controller/auth/AuthenticationV3LoginController, V3RegisterController
controller/room/Room operationsV1RoomController, V3RoomController
controller/user/User profile/accountV3ProfileController
controller/device/Device managementV3DeviceController
controller/media/Media upload/downloadMediaController, V1MediaController
federation/Server-Server APIFederationTransactionController

Services

Services contain business logic. The most significant:

ServiceResponsibilityLines
RoomEventServiceRoom events, membership, relations, redaction, federation EDUs~1175
SyncNotifier/sync long-polling, stream tokens, filter evaluation~800
MatrixTokenServiceToken lifecycle (create, validate, refresh, revoke)~400
FederationRequestSigningServiceRequest signing, signature verification~230
FederationDestinationQueueOutbound transaction queue with backoff~200
FederationKeyCacheRemote server key caching with TTL~150

Repositories

All repositories are Micronaut Data JDBC interfaces annotated with @JdbcRepository(dialect = Dialect.H2). They follow Micronaut Data naming conventions for query derivation.

Entities

Entities use Lombok @Data / @Getter / @Setter annotations mapped to H2 tables via @MappedEntity. Key entities: User, Room, Event, RoomMember, UserAccessToken, MediaMetadata, EventRelations, DeviceInbox.

Request Lifecycle

  1. HTTP request arrives at Netty
  2. Micronaut routes to the appropriate controller method
  3. MatrixAccessTokenValidator validates the bearer token against user_access_tokens table
  4. CurrentUserService extracts user identity into request context
  5. Controller delegates to service layer
  6. Service performs business logic, calls repositories
  7. Repository queries H2 via Micronaut Data JDBC
  8. Response serialized as JSON per Matrix spec

Cross-Cutting Concerns

  • Error handling: MatrixExceptionHandler converts exceptions to Matrix error responses
  • Rate limiting: RateLimiter with sliding window per-IP limiting
  • Logging: Logback with console + rolling file appender (logs/app.log)
  • Security headers: CSP, nosniff, DENY frame, HSTS
  • CORS: Configurable per-origin (permissive in development)