# adas-core.Infrastructure — Persistence & Communication Layer

> The **Infrastructure Layer** of the ADAS Core platform.  
> Contains concrete implementations of repository contracts, MongoDB mapping configurations, message-bus integrations (RabbitMQ via EasyNetQ), Redis connectivity, and migration tooling. This layer translates between the **Domain** layer and external resources — databases, caches, and messaging brokers.

---

## Table of Contents

1. [Overview](#overview)
2. [Responsibilities](#responsibilities)
3. [Project Structure](#project-structure)
4. [Dependencies](#dependencies)
5. [MongoDB Repositories](#mongodb-repositories)
6. [MongoDB Class Maps](#mongodb-class-maps)
7. [MongoDB Migrations](#mongodb-migrations)
8. [Messaging (RabbitMQ / EasyNetQ)](#messaging-rabbitmq--easynetq)
9. [Redis Integration](#redis-integration)
10. [Infrastructure Utilities](#infrastructure-utilities)
11. [Design Rules](#design-rules)

---

## Overview

`adas-core.Infrastructure` implements the technical capabilities required by the Application and Domain layers. It is the only layer that knows about MongoDB, Redis, and RabbitMQ. Every interaction with external systems flows through this project, isolating the rest of the codebase from vendor-specific APIs.

Key characteristics:

- **Implements Contracts** — Satisfies every interface defined in `adas-core.Application.Repositories/Interfaces`.
- **Persistence Ignorance for Domain** — Domain entities remain POCOs; class-map contributors in `Utils/MongoMaps/` configure BSON serialization externally.
- **Message-Bus Abstraction** — RabbitMQ producer/consumer logic is abstracted behind Application-layer contracts while the concrete wiring lives here.
- **Migration Tooling** — MongoDB schema evolution scripts are versioned and executed by `MongoMigrations.Core`.
- **Host Builder Extensions** — Provides `MongoDbHostBuilderExtension` and `CacheHostBuilderExtension` for streamlined Host startup registration.

---

## Responsibilities

| Concern | What this project does |
|---------|----------------------|
| **Repository Implementation** | Concrete classes for ~40 MongoDB-backed repositories (CRUD, aggregate queries, archive operations). |
| **MongoDB Class Mapping** | `MongoMaps` contributors register BSON discriminators, conventions, and property mappings. |
| **Database Migrations** | Versioned migration scripts that evolve the MongoDB schema without downtime. |
| **Message Publishing** | `PublisherService` dispatches domain events through RabbitMQ via EasyNetQ. |
| **Message Receiving** | `ReceiverService` subscribes to inbound queues and routes messages to Application-layer handlers. |
| **Alert Dispatch** | `SendAlertService` delivers system alerts to external notification channels. |
| **Relay Integration** | `RelayService` communicates with physical relay hardware. |
| **Host Builder Extensions** | Convenience helpers for wiring MongoDB and Redis into the ASP.NET Core host. |
| **Custom BSON Converters** | Entity-specific serialization logic registered with the MongoDB driver. |

---

## Project Structure

```
adas-core.Infrastructure/
├── Repositories/                         # ~40 concrete MongoDB repository implementations
│   ├── MongoRepository.cs             # Generic base repository
│   ├── UserRepository.cs / PatientRepository.cs
│   ├── AdmissionRepository.cs / DischargeRepository.cs
│   ├── ObservationRepository.cs / ObservationArchiveRepository.cs
│   ├── TreatmentRepository.cs / TreatmentArchiveRepository.cs
│   ├── DiagnosisRepository.cs / DiagnosisArchiveRepository.cs
│   ├── AlarmRepository.cs / DeviceRepository.cs / CameraRepository.cs
│   ├── LightBeaconRepository.cs / RelayRepository.cs
│   ├── PumpStateRepository.cs / PumpObservationRepository.cs
│   ├── PumpArchiveRepository.cs / PumpAlarmEventRepository.cs
│   ├── PumpAlarmStateRepository.cs
│   ├── RecordingAlertRepository.cs / RecordingAlertArchiveRepository.cs
│   ├── DisplayRepository.cs / DisplayConfigRepository.cs
│   ├── DisplayCardConfigRepository.cs / DisplayChartConfigRepository.cs
│   ├── DisplayDetailConfigRepository.cs
│   ├── ConfigObservationRepository.cs
│   ├── ConfigPumpsRepository.cs / ConfigUnitsRepository.cs
│   ├── PointOfCareRepository.cs / PoCMappingRepository.cs
│   ├── PoCSettingsRepository.cs / UnitRepository.cs / SectionRepository.cs
│   ├── NoticeRepository.cs / ServiceConfigRepository.cs
│   ├── MasterListRepository.cs / MedicineRepository.cs
│   ├── PatientCarePlanRepository.cs / ArchivePatientCarePlanRepository.cs
│   ├── AppointmentRepository.cs / AppointmentArchiveRepository.cs
│   ├── PatientArchiveRepository.cs / AuthorityRepository.cs
│   └── HistoricalConfigChangesRepository.cs
│
├── Services/                           # Infrastructure-level services
│   ├── PublisherService.cs            # RabbitMQ outbound publishing via EasyNetQ
│   ├── ReceiverService.cs             # RabbitMQ inbound subscription via EasyNetQ
│   ├── SendAlertService.cs            # Alert delivery to external channels
│   └── RelayService.cs                # Physical relay communication
│
├── Utils/                              # Infrastructure helpers and extensions
│   ├── MongoDbHostBuilderExtension.cs
│   ├── CacheHostBuilderExtension.cs
│   ├── MongoUtils.cs
│   ├── TypesUtils.cs
│   ├── RabbitConsumerErrorStrategy.cs
│   ├── RabbitIErrorMessageSerializer.cs
│   ├── PatientObservationConverter.cs
│   ├── PatientObservationAlarmConverter.cs
│   ├── PatientPumpObservationConverter.cs
│   ├── PersonConverter.cs
│   ├── CustomPointOfCareConverter.cs
│   └── MongoMaps/                     # ~30 BSON class-map contributors
│       ├── IEntityMapContributor.cs
│       ├── PatientMapContributor.cs / UserMapContributor.cs
│       ├── ObservationMapContributor.cs / AlarmMapContributor.cs
│       ├── DeviceMapContributor.cs
│       ├── DisplayMapContributor.cs / DisplayHomeConfigContributor.cs
│       ├── CardMapContributor.cs / CellMapContributor.cs / RowMapContributor.cs
│       ├── ColorConfigMapContributor.cs / HeaderMapContributor.cs
│       ├── GraphMapContributor.cs / FormMapContributor.cs
│       ├── BannerConfigMapContributor.cs / BoxConfigMapContributor.cs
│       ├── ComunicationFlowMapContributor.cs / CameraContributor.cs
│       ├── BeaconMapContributor.cs / PumpMapContributor.cs
│       ├── RelayContributor.cs / UnitMapContributor.cs / SectionMapContributor.cs
│       ├── PoCMapContributor.cs / ObsUnitMapContributor.cs
│       ├── MasterListMapContributor.cs / NoticeControlMapContributor.cs
│       ├── ServiceConfigMapContributor.cs / StandardMapContributor.cs
│       └── TreatmentMapContributor.cs / AppointmentMapContributor.cs / AuthMapContributor.cs
│
└── Migrations/
    └── MongoMigrations/                  # Schema evolution scripts
        ├── U_0_1_0_UpdateDataPatien.cs
        ├── U_0_1_1_UpdateDisplayConfigDriver.cs
        ├── U_0_1_2_UpdatePointOfCareConfig.cs
        └── U_0_1_3_UpdateLanguageBarrier.cs
```

---

## Dependencies

### Downstream References

| Project | Role |
|---------|------|
| `adas-core.Domain` | Entities, value objects, enums, DTOs, settings models, and `IDefaultRepository` that this layer persists. |
| `adas-core.Application` | All repository interfaces (`I*Repository`) and service contracts (`IPublisherService`, `ISendAlertService`) implemented in this project. |
| `adas-core.module.LightBeacons` | Module contracts for beacon-specific persistence. |
| `adas-core.module.Relays` | Module contracts for relay-specific persistence. |

### Upstream References (projects that depend on this)

| Project | Reason |
|---------|--------|
| `adas-core` (Host) | Registers all infrastructure services and repositories in the DI container during startup. |
| `adas-core.Test` | Integration tests swap real repositories with in-memory substitutes or exercise the actual MongoDB-backed implementations. |

### NuGet Packages

| Package | Version | Purpose |
|---------|---------|---------|
| `MongoDB.Driver` | latest | MongoDB client for document persistence. |
| `EasyNetQ` | 8.1.4 | Higher-level RabbitMQ abstractions (publisher/consumer services). |
| `StackExchange.Redis` | 2.13.17 | Redis client for caching and distributed locking. |
| `MongoMigrations.Core` | 4.0.15 | Document schema migration framework. |
| `Microsoft.Extensions.Hosting.Abstractions` | 10.0.8 | `IHostedService` and background service registration. |
| `Microsoft.Extensions.Options` | 10.0.8 | Options-pattern configuration binding. |
| `AuditLogs` | 1.0.59 | Audit trail emission from repository write operations. |


## MongoDB Repositories

Every repository in this project implements a corresponding interface from `adas-core.Application.Repositories.Interfaces`. The generic base `MongoRepository<T>` provides CRUD, pagination, and queryable access using the MongoDB C# Driver.

### Base Repository

`MongoRepository<T>` implements `IMongoRepository<T>` and offers:
- `GetByIdAsync(ObjectId)` — single-document lookup by `_id`.
- `GetAllAsync()` — unfiltered collection enumeration.
- `InsertAsync(T)` — atomic insert.
- `UpdateAsync(ObjectId, T)` — full-document replacement.
- `DeleteAsync(ObjectId)` — removal by `_id`.

Specialized repositories override or extend these behaviors for aggregate-specific queries (e.g., `PatientRepository.GetActiveByUnitAsync`, `ObservationRepository.GetRangeAsync`).

### Repository Lifetime

Most repositories are registered as **Singletons** because they are stateless wrappers around a shared `IMongoDatabase`. The exception is `PumpStateRepository`, which may be **Scoped** when per-request pump-session tracking is required.

---

## MongoDB Class Maps

The `Utils/MongoMaps/` folder contains ~30 `IEntityMapContributor` implementations that register BSON mappings at application startup. This keeps the Domain layer free of MongoDB-specific attributes.

```csharp
public interface IEntityMapContributor
{
    void Configure();
}
```

| Contributor | Maps |
|-------------|------|
| `PatientMapContributor` | `Patient` entity — location history embedded array, `ObjectId` references to `Person` and `PointOfCare`. |
| `ObservationMapContributor` | Polymorphic observation hierarchy using BSON discriminators. |
| `DisplayMapContributor` | `Display` + `DisplayConfig` nested tree serialization. |
| `PumpMapContributor` | `PumpState`, `PumpAlarmEvent`, `PumpObservation` telemetry documents. |
| `DeviceMapContributor` | Discriminator-based polymorphic `Device` storage. |
| `AuthMapContributor` | `User` + `Authorization` embedded arrays. |

These contributors are invoked during Host startup via `MongoDbHostBuilderExtension`, ensuring all mappings are registered before any repository is accessed.

---

## MongoDB Migrations

Schema evolution is handled by `MongoMigrations.Core`. Each migration is a C# class named with a version prefix (`U_M_m_p_Description`) that executes idempotent update scripts.

| Migration | Purpose |
|-----------|---------|
| `U_0_1_0_UpdateDataPatien` | Corrects patient data inconsistencies post-deployment. |
| `U_0_1_1_UpdateDisplayConfigDriver` | Adds driver metadata to display configuration documents. |
| `U_0_1_2_UpdatePointOfCareConfig` | Introduces PoC-specific configuration fields. |
| `U_0_1_3_UpdateLanguageBarrier` | Adds language-barrier flag to patient records. |

Migrations are executed automatically at Host startup before controllers become available.

---

## Messaging (RabbitMQ / EasyNetQ)

The project integrates RabbitMQ through `EasyNetQ`, which simplifies AMQP operations to a pub/sub model.

| Service | Direction | Purpose |
|---------|-----------|---------|
| `PublisherService` | Outbound | Dispatches domain events (alarm triggered, patient admitted, observation recorded) to configured exchanges. |
| `ReceiverService` | Inbound | Subscribes to topic queues and forwards messages to Application-layer handlers. |
| `RabbitConsumerErrorStrategy` | Error handling | Implements dead-letter queue behavior and exponential backoff for failed deliveries. |
| `RabbitIErrorMessageSerializer` | Serialization | Custom error-body serializer for failed-message auditing. |

Connection strings and exchange topology are configured through `appsettings.json` (`RabbitMQSettings` defined in Domain).

---

## Redis Integration

Redis support is provided via `StackExchange.Redis` and registered through `CacheHostBuilderExtension`. The Infrastructure layer:

- Opens multiplexed connections to the Redis cluster.
- Provides connection management for the `RedisService` and `RedisLockProvider` defined in `adas-core.Application`.
- Registers `IDistributedCache` when available.

Redis is used primarily for:
- Distributed caching of frequently-read reference data (master lists, service configs).
- Distributed locking via `RedisLockProvider` to prevent race conditions on critical operations.
- Session token storage for refresh-token rotation.

---

## Infrastructure Utilities

| Utility | Purpose |
|---------|---------|
| `MongoUtils` | Connection-string building, database factory, and collection accessor helpers. |
| `TypesUtils` | Reflection-based type resolution for generic repository instantiation and converter discovery. |
| `PatientObservationConverter` | Custom BSON serialization for `PatientObservation` polymorphic values. |
| `PersonConverter` | BSON mapping for the `Person` embedded document. |
| `CustomPointOfCareConverter` | Specialized BSON logic for `PointOfCare` nested structures. |

---

## Design Rules

1. **Contracts Only from Upstream** — Infrastructure never defines its own interfaces for cross-cutting concerns. It implements contracts from `Application` or `Domain`.
2. **No Business Logic** — Repositories execute queries and return entities. No validation, no workflow, no decision-making. That belongs in Application.
3. **Technology Concentration** — All MongoDB, RabbitMQ, Redis, SMTP, and HTTP-specific code lives here. Inner layers remain technology-agnostic.
4. **Mapping Isolation** — BSON class maps, EF configurations, and serialization rules are centralized in `MongoMaps/`. No mapping attributes pollute Domain entities.
5. **Connection String Injection** — All external resource connection strings and API keys are injected via `IOptions<T>`; never hardcoded.
6. **Singleton by Default** — Stateless repositories and services are singletons. Scoped lifetimes are reserved only for per-request state.
7. **Migrations Are Idempotent** — Each migration script must be safe to run multiple times. Document versioning guards prevent double application.
8. **Error Translation** — Infrastructure exceptions (Mongo socket errors, RabbitMQ disconnects, SMTP failures) are caught and re-thrown as domain exceptions or logged, never leaked raw to controllers.
9. **No Direct Host Coupling** — Infrastructure is registered by the Host via extension methods (`AddMongoDb`, `AddCache`), but the project does not reference the Host assembly.
10. **Audit Trail Emission** — Write operations that mutate patient data, configurations, or alarms must emit an audit event via the `AuditLogs` package before returning.

---

<p align="center">
  Back to <a href="../README.md">adas-core Root README</a>
</p>