Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Architecture

Overview

The CE-RISE Hex Core Service follows a strict hexagonal (ports and adapters) architecture. The domain and use-case logic in crates/core has no knowledge of HTTP, databases, or any specific IO provider. All external interactions are mediated through port traits.

Architecture Views

Digital Passport Interaction View

Digital Passport Interaction View

Digital Passport interaction flow showing both external consumption and internal processing: clients submit/query records, the core resolves model artifacts from registry/catalog sources, validates payloads, and reads/writes through configured backend adapters.

Deployment View

Hex Core Service Deployment View

Deployment-oriented architecture view of the hex-core service, showing inbound interfaces, core orchestration, outbound adapters, and runtime dependencies in one deployable unit.

The hexagonal architecture pattern used in this service is also illustrated in the following diagram:

                    ┌──────────────────────────────────────┐
                    │           INBOUND ADAPTERS           │
                    │  REST API (axum)  │  CLI  │  Tests   │
                    └──────────┬──────────────────────────-┘
                               │  calls inbound port traits
                    ┌──────────▼───────────────────────────-┐
                    │             CORE (crate)              │
                    │  ┌────────────────────────────────┐   │
                    │  │   Use Cases (implementations)  │   │
                    │  │  ValidateUseCase               │   │
                    │  │  RecordUseCase                 │   │
                    │  │  EnrichUseCase (opt.)          │   │
                    │  └────────────┬───────────────────┘   │
                    │               │  calls outbound port traits
                    └──────────────-│─────────────────────--┘
                                    │
              ┌─────────────────────┼──────────────────────┐
              │                     │                      │
   ┌──────────▼──────┐  ┌───────────▼──────┐  ┌────────────▼──────┐
   │ ArtifactRegistry│  │  ValidatorPort   │  │  RecordStorePort  │
   │ (catalog + URL  │  │  (SHACL / JSON   │  │  (HTTP IO adapter │
   │   fetch helper) │  │   Schema / OWL)  │  │   memory / db)    │
   └─────────────────┘  └──────────────────┘  └───────────────────┘

Layer dependency rules

The architecture enforces strict dependency constraints to maintain separation of concerns:

LayerAllowed dependenciesForbidden
core/domainstd, serde, thiserrorEverything else
core/portscore/domain, async-traitAny I/O
core/usecasescore/domain, core/portsAny I/O, HTTP, DB
registrycore/ports, reqwest, tokiocore/usecases
apicore/ports, axum, tower, jsonwebtokenDirect DB/IO
validator-*core/ports, validator-specific libsHTTP, DB
io-*core/ports, adapter-specific libsCore use cases

These rules ensure that:

  • The core domain remains pure and testable
  • Business logic has no coupling to infrastructure
  • Adapters can be swapped without affecting the core
  • Dependencies flow inward toward the domain

Layers

  • Domain (crates/core/src/domain) — entities, value objects, error types. No I/O.
  • Ports (crates/core/src/ports) — inbound use-case traits and outbound adapter traits.
  • Use cases (crates/core/src/usecases) — orchestration logic implementing inbound ports.
  • Registry (crates/registry) — catalog-backed ArtifactRegistryPort with URL artifact fetching.
  • REST adapter (crates/api) — axum HTTP server implementing the inbound interface.
  • IO adapters (crates/io-memory, crates/io-http) — RecordStorePort implementations.
  • Validators (crates/validator-jsonschema, crates/validator-shacl) — ValidatorPort implementations.

Key design decisions

Use-case error behavior (implemented)

  • ValidateUseCaseImpl propagates validator execution failures as domain errors.
  • RecordUseCaseImpl blocks writes when merged validation report fails.
  • RecordUseCaseImpl also propagates validator execution failures (they are not ignored).