# adas-core — API Host

> ASP.NET Core Web API host for the **ADAS Core** platform.  
> This project is the **Presentation Layer** and application entry point. It composes all lower layers (Domain, Application, Infrastructure, Authentication, and Modules) via dependency injection, configures the HTTP pipeline, and exposes REST endpoints, WebSocket hubs, and OpenAPI documentation.

---

## Table of Contents

1. [Overview](#overview)
2. [Responsibilities](#responsibilities)
3. [Project Structure](#project-structure)
4. [Dependencies](#dependencies)
5. [Configuration Profiles](#configuration-profiles)
6. [Middleware Pipeline](#middleware-pipeline)
7. [REST Endpoints](#rest-endpoints)
8. [WebSocket / SignalR Hubs](#websocket--signalr-hubs)
9. [Swagger & OpenAPI](#swagger--openapi)
10. [Serilog Bootstrap](#serilog-bootstrap)
11. [Build & Run](#build--run)
12. [Design Rules](#design-rules)

---

## Overview

The `adas-core` project is the executable ASP.NET Core application that hosts the entire ADAS backend. Its sole responsibility is to:

- Wire every layer and module into the **dependency injection container**.
- Load **environment-specific configuration**.
- Build the **HTTP request pipeline** (auth, CORS, error handling, routing).
- Expose **REST controllers**, **WebSocket (SignalR) hubs**, and **Prometheus metrics**.
- Bootstrap **Serilog** structured logging and **Swagger** API discovery.

It contains **no business logic** — all domain rules, use cases, and data access live in referenced projects.

---

## Responsibilities

| Concern | What this project does |
|---------|----------------------|
| **Composition Root** | Registers all repositories, services, authentication strategies, MongoDB, Redis, and SignalR into `IServiceCollection`. |
| **Configuration Loading** | Loads layered `appsettings.json` files (base + environment-specific) using `ConfigurationBuilder`. |
| **Pipeline Setup** | Configures middleware order: auth, CORS, WebSockets, error handling, controllers, SignalR hubs. |
| **API Exposure** | Defines ASP.NET Core controllers that delegate to Application-layer services. |
| **Real-Time Messaging** | Hosts SignalR hubs (`UciHub`) for WebSocket-based push communication. |
| **API Documentation** | Auto-generates Swagger / OpenAPI specs with Newtonsoft.Json and `ObjectId` schema mapping. |
| **Health & Metrics** | Exposes `/metrics` (Prometheus) and Swagger UI at runtime. |
| **Logging Initialization** | Bootstraps Serilog from configuration with dynamic trace identifiers and contextual enrichers. |

---

## Project Structure

```
adas-core/
├── Program.cs                          # Application bootstrap (DI registration + pipeline)
├── appsettings.json                    # Base configuration
├── appsettings.{Environment}.json    # Environment-specific overrides (see list below)
├── Properties/
│   └── launchSettings.json             # Launch profiles per environment
├── Configurations/
│   └── ServiceExtension.cs             # Extension methods: JWT auth, ProxyDevices, config binding
├── Controllers/                        # ASP.NET Core API controllers
│   ├── UserController.cs
│   ├── PatientController.cs
│   ├── DeviceController.cs
│   ├── AlarmController.cs
│   ├── LightBeaconController.cs
│   ├── ProxyDeviceController.cs
│   ├── RelayController.cs
│   ├── PumpsController.cs
│   ├── ObservationsController.cs
│   ├── TreatmentsController.cs
│   ├── DisplayController.cs
│   ├── ConfigObservationController.cs
│   ├── ConfigDisplayController.cs
│   ├── PointOfCareController.cs
│   ├── AdmissionController.cs
│   ├── DischargeController.cs
│   ├── AuditController.cs
│   ├── RabbitController.cs
│   ├── QXController.cs
│   ├── SendAlertController.cs
│   ├── SensorController.cs
│   ├── RecordingController.cs
│   ├── RecordingAlertController.cs
│   ├── ServiceConfigController.cs
│   ├── MasterListController.cs
│   ├── UnitController.cs
│   ├── NoticeController.cs
│   ├── MedicinesController.cs
│   ├── DiagnosisController.cs
│   ├── BoxController.cs
│   ├── CameraController.cs
│   ├── ApplicationController.cs
│   ├── GroupedObservationsController.cs
│   ├── PatientAppointmentController.cs
│   └── ...
├── ErrorMiddleware/
│   └── ErrorHandlerMiddleware.cs       # Global exception-handling middleware
├── Logging/
│   ├── LogExecutionContext.cs          # Ambient trace-identifier context
│   └── LogProvider.cs                  # Logger resolution helper
├── WebSocket/
│   ├── WebSocketMessageService.cs      # WebSocket outbound message service
│   └── Hubs/
│       └── UciHub.cs                   # SignalR hub for real-time subscriptions
└── Dockerfile                           # Multi-stage Linux container image
```

---

## Dependencies

### Downstream References (this project depends on)

| Project | Role |
|---------|------|
| `adas-core.Domain` | Domain entities, value objects, and repository contracts used by controllers for DTO mapping and route parameters. |
| `adas-core.Application` | Application services and DTOs invoked by controllers. |
| `adas-core.Infrastructure` | Infrastructure implementations registered in DI (repositories, MongoDB, Redis, messaging). |
| `adas-core.Authentication` | JWT middleware and authentication abstractions wired into the pipeline. |
| `adas-core.LdapLogin` | LDAP authentication strategy registered conditionally at startup. |
| `adas-core.LocalLogin` | Local database authentication strategy registered conditionally at startup. |
| `adas-core.module.LightBeacons` | Module controllers and services registered in DI. |
| `adas-core.module.ProxyDevices` | Module controllers and services registered in DI. |
| `adas-core.module.Relays` | Module controllers and services registered in DI. |

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

| Project | Reason |
|---------|--------|
| `adas-core.Test` | Integration tests exercise the full host pipeline, controllers, and DI container. |

---

## Configuration Profiles

The host supports multiple runtime environments via layered `appsettings` files. The base `appsettings.json` is always loaded first, then an environment-specific override is merged on top.

| Profile File | Environment | Typical Use |
|-------------|-------------|-------------|
| `appsettings.Local.json` | `Local` | Developer workstation |
| `appsettings.Develop.json` | `Develop` | Shared development server |
| `appsettings.LocalTest.json` | `LocalTest` | Automated integration tests |
| `appsettings.H12O.json` | `H12O` | Production site H12O |
| `appsettings.HRYCM.json` | `HRYCM` | Production site HRYCM |
| `appsettings.HPAZ.json` | `HPAZ` | Production site HPAZ |
| `appsettings.HPAZBastion.json` | `HPAZBastion` | Bastion / DMZ instance |
| `appsettings.HUVH-UCIN.json` | `HUVH-UCIN` | Hospital UVH UCIN ward |
| `appsettings.HUVH-UCIA.json` | `HUVH-UCIA` | Hospital UVH UCIA ward |
| `appsettings.CHUO.json` | `CHUO` | CHUO institution |
| `appsettings.CENTRAL_PHILIPS.json` | `CENTRAL_PHILIPS` | Philips central integration |
| `appsettings.NursePlan.json` | `NursePlan` | Nurse scheduling module |
| `appsettings.BombasBD.json` | `BombasBD` | Infusion pump database |
| `appsettings.Auditoria.json` | `Auditoria` | Audit / compliance instance |
| `appsettings.HGMM.json` | `HGMM` | HGMM environment |

### How profiles are resolved

```csharp
var configuration = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: false)
    .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true)
    .Build();
```

Set the active environment via the `ASPNETCORE_ENVIRONMENT` variable or a `launchSettings.json` profile.

---

## Middleware Pipeline

The HTTP pipeline is assembled in `Program.cs` in the following order:

```
1. Swagger + SwaggerUI         # API docs (dev/staging)
2. Static Files                # Static assets
3. Authentication              # JWT validation
4. Authorization               # Policy enforcement
5. WebSockets                  # Raw WS support
6. SignalR Hubs                # /subscribe, /chatMessage
7. CORS ("OpenCors")           # Allow any origin/method/header
8. ErrorHandlerMiddleware      # Global exception catching
9. Controllers                 # REST API routes
```

### Global Error Handling

`ErrorHandlerMiddleware` catches unhandled exceptions, logs them via Serilog, and returns a sanitized problem-details response. No exception leaks to the client in production.

### CORS Policy

```csharp
options.AddPolicy("OpenCors", policy =>
{
    policy.AllowAnyOrigin()
          .AllowAnyMethod()
          .AllowAnyHeader();
});
```

> **Security Note:** Review and restrict this policy for production deployments.

---

## REST Endpoints

Controllers expose domain-oriented resource groups. Each controller delegates to an Application-layer service and returns DTOs. Key controller families:

| Domain | Controllers |
|--------|-------------|
| **Patients** | `PatientController`, `AdmissionController`, `DischargeController`, `PatientAppointmentController` |
| **Observations** | `ObservationsController`, `GroupedObservationsController`, `ConfigObservationController`, `AlarmController`, `SensorController` |
| **Devices** | `DeviceController`, `ProxyDeviceController`, `RelayController`, `LightBeaconController`, `CameraController`, `PumpsController`, `BoxController` |
| **Clinical** | `TreatmentsController`, `MedicinesController`, `DiagnosisController`, `PointOfCareController` |
| **System** | `UserController`, `UnitController`, `MasterListController`, `ServiceConfigController`, `DisplayController`, `ConfigDisplayController` |
| **Messaging** | `RabbitController`, `SendAlertController`, `NoticeController` |
| **Media** | `RecordingController`, `RecordingAlertController`, `QXController` |
| **Audit** | `AuditController`, `ApplicationController` |

All endpoints require authentication (`[Authorize]` applied globally via a filter). Swagger UI lists available operations per environment.

---

## WebSocket / SignalR Hubs

### Hubs

| Hub | Route | Purpose |
|-----|-------|---------|
| `UciHub` | `/subscribe` | Real-time subscription channel for clients |
| `UciHub` | `/chatMessage` | Bidirectional chat / notification channel |

### WebSocket Options

```csharp
var webSocketOptions = new WebSocketOptions
{
    KeepAliveInterval = TimeSpan.FromSeconds(120)
};
app.UseWebSockets(webSocketOptions);
```

### WebSocket Message Service

`WebSocketMessageService` implements `IClientMessageService` and handles pushing outbound messages to connected SignalR clients, decoupling domain events from transport concerns.

---

## Swagger & OpenAPI

Swagger is enabled unconditionally:

```csharp
app.UseSwagger();
app.UseSwaggerUI();
```

### Customizations

- **Newtonsoft.Json** serializer registered globally (`ReferenceLoopHandling.Ignore`, `CamelCasePropertyNamesContractResolver`, `StringEnumConverter`, `ObjectIdConverter`).
- **Schema IDs** use fully qualified type names (`CustomSchemaIds(type => type.FullName)`) to prevent collisions.
- **`ObjectId` mapping** exposed as `string` with `format: objectid`.

Access the UI at `/swagger/index.html`.

---

## Serilog Bootstrap

Serilog is initialized from the `Serilog` configuration section with fallback to console-only:

```csharp
builder.Host.UseSerilog((_, loggerConfig) =>
{
    if (configuration.GetSection("Serilog").Exists())
    {
        loggerConfig.ReadFrom.Configuration(configuration, new() { SectionName = "Serilog" });
    }
    else
    {
        loggerConfig.MinimumLevel.Information().WriteTo.Console();
    }

    loggerConfig.Enrich.WithDynamicProperty(
        "TraceIdentifier",
        () => LogExecutionContext.TraceIdentifier);
});
```

### Dynamic Trace Identifier

`LogExecutionContext` sets a per-request `TraceIdentifier` (GUID) that flows through all enrichers, enabling end-to-end log correlation across layers and modules.

---

## Build & Run

### From CLI

```bash
cd adas-core
dotnet run --launch-profile "LOCAL"
```

Available launch profiles (from `Properties/launchSettings.json`):

| Profile | HTTPS | HTTP | Binding |
|---------|-------|------|---------|
| `LOCAL` | `https://localhost:7006` | `http://localhost:5006` | localhost |
| `HPAZ UCIP` | `https://localhost:7006` | `http://localhost:5006` | localhost |
| `HRYCM UCIP` | `https://0.0.0.0:7006` | `http://0.0.0.0:5006` | all interfaces |
| `H12O` | `https://localhost:7006` | `http://localhost:5006` | localhost |
| `HUVH-UCIN` | `https://0.0.0.0:7006` | `http://0.0.0.0:5006` | all interfaces |
| `CHUO` | `https://0.0.0.0:7006` | `http://0.0.0.0:5006` | all interfaces |
| `NursePlan` | `https://0.0.0.0:7006` | `http://0.0.0.0:5006` | all interfaces |
| `BombasBD` | `https://0.0.0.0:7006` | `http://0.0.0.0:5006` | all interfaces |
| `Auditoria` | `https://0.0.0.0:7006` | `http://0.0.0.0:5006` | all interfaces |
| `HUVH-UCIA` | `https://0.0.0.0:7006` | `http://0.0.0.0:5006` | all interfaces |
| `LocalTest` | `https://0.0.0.0:7006` | `http://0.0.0.0:5006` | all interfaces |
| `Develop` | `https://0.0.0.0:7006` | `http://0.0.0.0:5006` | all interfaces |
| `IIS Express` | IIS Express | — | `http://localhost:60532` / SSL `44358` |
| `Docker` | Docker mapped | — | auto-assigned |

### Docker

```bash
docker build -t adas-core:latest .
docker run -p 8080:80 -e ASPNETCORE_ENVIRONMENT=Production adas-core:latest
```

---

## Design Rules

1. **Thin Controllers** — Controllers must only validate input, invoke application services, and return DTOs. No business logic inside controllers.
2. **Global Authorization** — The `[Authorize]` filter is applied globally; anonymous endpoints must be explicitly opted out.
3. **Configuration Over Code** — Environment-specific behavior is driven by `appsettings` profiles, not conditional compilation.
4. **No Circular Dependencies** — The Host references all layers but is never referenced by Domain or Application.
5. **Singleton vs Scoped** — Repository registrations default to `Singleton` for stateless MongoDB access; scoped services are used only when per-request state is required (e.g., `PumpStateRepository`).
6. **Lazy Resolution** — Heavy services are wrapped in `Lazy<T>` to defer instantiation and reduce startup overhead.
7. **Middleware Order Matters** — Authentication must precede Authorization; WebSockets must precede SignalR hubs; ErrorHandler must wrap the Controller pipeline.
8. **Sensitive Data Protection** — JWT secrets and database connection strings must use User Secrets or environment variables in production; never commit them to source control.

---

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