# ADAS Core Backend API > **ADAS Core** — Backend platform developed by **Epigram Technologies**. > Implements **Clean Architecture** with a **Modular Monolith** pattern, built on **.NET 8** and designed for scalability, maintainability, and flexible deployment in industrial and institutional environments. --- ## Table of Contents 1. [Overview](#overview) 2. [Architecture](#architecture) 3. [Solution Structure](#solution-structure) 4. [Functional Modules](#functional-modules) 5. [Getting Started](#getting-started) 6. [Configuration](#configuration) 7. [Authentication](#authentication) 8. [Logging](#logging) 9. [Testing](#testing) 10. [Technologies & Dependencies](#technologies--dependencies) 11. [Conventions & Best Practices](#conventions--best-practices) --- ## Overview ADAS Core is the main backend API for the ADAS platform. It follows a modular monolith architecture where business domains are organized into independent modules while sharing a common infrastructure and application core. Key characteristics: - **Clean Architecture**: Clear separation between Domain, Application, Infrastructure, and Presentation layers. - **Modular Monolith**: Business modules are self-contained and can be extracted into microservices if needed. - **Pluggable Authentication**: Supports multiple authentication strategies via a common abstraction layer. - **Structured Logging**: Full observability through Serilog with multiple sinks and enrichers. - **Production Ready**: Multi-configuration builds, Docker support, Prometheus metrics, and comprehensive test coverage. --- ## Architecture The architecture follows the principles of **Clean Architecture** (Onion Architecture), ensuring that business rules remain independent of frameworks, UI, and infrastructure concerns. ### Design Principles | Principle | Description | |-----------|-------------| | **Dependency Rule** | Dependencies always point inward. The Domain layer has zero external dependencies. | | **Separation of Concerns** | Each layer has a single responsibility (Domain, Application, Infrastructure, Authentication, Modules). | | **Framework Independence** | The Domain layer contains pure business logic without references to ASP.NET Core, databases, or external libraries. | | **Testability** | Business rules can be unit-tested in isolation without infrastructure concerns. | | **Modularity** | Functional domains are encapsulated in independent modules with minimal shared surface. | ### Layer Responsibilities | Layer | Projects | Responsibility | |-------|----------|--------------| | **Domain** | `adas-core.Domain` | Entities, value objects, domain events, business rules, and repository interfaces. | | **Application** | `adas-core.Application` | Use cases, application services, DTOs, and orchestration logic. | | **Infrastructure** | `adas-core.Infrastructure` | Persistence, messaging, caching, external APIs, and technical concerns. | | **Authentication** | `adas-core.Authentication` | Authentication abstractions, JWT handling, and security middleware. | | **Presentation** | `adas-core` (Host) | ASP.NET Core Web API, controllers, dependency injection composition, and module registration. | | **Modules** | `adas-core.module.*` | Independent business domains with their own entities, services, and controllers. | ### Architecture Diagram ```mermaid flowchart TB subgraph Presentation["Presentation Layer"] H[adas-core Host
ASP.NET Core Web API] end subgraph Auth["Authentication Layer"] A[adas-core.Authentication
JWT / Middleware / Abstractions] L[adas-core.LdapLogin] Lo[adas-core.LocalLogin] end subgraph Application["Application Layer"] AP[adas-core.Application
Use Cases / Services / DTOs] end subgraph Domain["Domain Layer"] D[adas-core.Domain
Entities / Rules / Interfaces] end subgraph Infrastructure["Infrastructure Layer"] I[adas-core.Infrastructure
Persistence / Messaging / Cache] end subgraph Modules["Business Modules"] M1[module.LightBeacons] M2[module.ProxyDevices] M3[module.Relays] end H --> A H --> AP AP --> D A --> AP A --> D L --> A Lo --> A Lo --> I I --> AP I --> M1 I --> M3 M1 --> D M2 --> D M3 --> D ``` ### Request Flow Example ```mermaid sequenceDiagram participant Client participant Host as adas-core (Host) participant Auth as Authentication participant App as Application participant Mod as Module participant Inf as Infrastructure participant DB as Database Client->>Host: HTTP Request Host->>Auth: Validate JWT / Authenticate Auth-->>Host: ClaimsPrincipal Host->>App: Invoke Use Case App->>Mod: Execute Business Logic Mod->>Inf: Persist / Query Inf->>DB: Database Operation DB-->>Inf: Result Inf-->>Mod: Data Mod-->>App: Domain Result App-->>Host: DTO / Response Host-->>Client: HTTP Response ``` > **Note on Dependencies**: The `Infrastructure` project references the `Application` and specific modules it supports. Modules reference `Domain` (preferentially) or `Application` for shared abstractions. The Host references all layers and wires them together via the dependency injection container. --- ## Solution Structure ``` adas-core/ ├── adas-core.sln # Main solution file ├── Dockerfile # Multi-stage Linux image ├── .dockerignore # Docker build exclusions ├── .gitignore / .gitattributes # Version control │ ├── adas-core/ # API Host (ASP.NET Core Web) │ ├── Program.cs # Application bootstrap │ ├── appsettings.json # Base configuration │ ├── appsettings.Local.json # Local overrides │ └── Properties/ │ └── launchSettings.json # Launch profiles │ ├── adas-core.Domain/ # Pure Domain layer │ ├── Entities/ │ ├── ValueObjects/ │ ├── Interfaces/ # Repository contracts │ └── Events/ # Domain events │ ├── adas-core.Application/ # Use Case layer │ ├── Services/ # Application services │ ├── DTOs/ # Data transfer objects │ └── Interfaces/ # Service contracts │ ├── adas-core.Infrastructure/ # Technical Infrastructure │ ├── Persistence/ # Data access implementations │ ├── Messaging/ # RabbitMQ / EasyNetQ wrappers │ └── Cache/ # Redis abstractions │ ├── adas-core.Authentication/ # Security abstractions │ ├── TokenService.cs # JWT generation / validation │ └── Middleware/ # Auth middleware │ ├── adas-core.LdapLogin/ # LDAP / Active Directory strategy │ └── LdapAuthenticationService.cs │ ├── adas-core.LocalLogin/ # Local database strategy │ └── LocalAuthenticationService.cs │ ├── adas-core.module.LightBeacons/ # Functional module: Light Beacons │ ├── adas-core.module.ProxyDevices/ # Functional module: Proxy Devices │ ├── adas-core.module.Relays/ # Functional module: Relays │ └── adas-core.Test/ # Automated test suite (NUnit) ``` ### Cross-Project Reference Rules ``` adas-core.Host → references → Domain, Application, Infrastructure, Authentication, Modules adas-core.Application → references → Domain adas-core.Infrastructure → references → Application, Modules adas-core.Authentication → references → Application, Domain adas-core.LdapLogin → references → Authentication adas-core.LocalLogin → references → Authentication, Infrastructure Modules → references → Domain (preferentially) adas-core.Test → references → Domain, Infrastructure, Host ``` --- ## Functional Modules Each module is an autonomous functional domain encapsulating its own business logic, entities, and services. | Module | Project | Description | |--------|---------|-------------| | **LightBeacons** | `adas-core.module.LightBeacons` | Management and control of light beacons: state, lighting patterns, visual alerts, and synchronization. | | **ProxyDevices** | `adas-core.module.ProxyDevices` | Administration of intermediary devices: registration, heartbeat, remote configuration, and telemetry. | | **Relays** | `adas-core.module.Relays` | Control of electromechanical/electronic relays: ON/OFF commands, time scheduling, and real-time status. | > Modules communicate with each other preferentially through **domain events** published via `EasyNetQ` (RabbitMQ). This ensures loose coupling and allows future extraction into independent microservices. ### Module Interaction Diagram ```mermaid flowchart LR subgraph Core["Application Core"] A[Application Layer] D[Domain Layer] I[Infrastructure Layer] end subgraph Modules["Business Modules"] M1[LightBeacons] M2[ProxyDevices] M3[Relays] end subgraph Bus["Message Bus"] R[(RabbitMQ\nvia EasyNetQ)] end M1 -->|reads/writes| I M2 -->|reads/writes| I M3 -->|reads/writes| I M1 -->|depends on| D M2 -->|depends on| D M3 -->|depends on| D M1 -.->|publishes events| R M2 -.->|publishes events| R M3 -.->|publishes events| R R -.->|consumes events| M1 R -.->|consumes events| M2 R -.->|consumes events| M3 ``` --- ## Getting Started ### Prerequisites | Requirement | Min. Version | Verification | |-------------|--------------|--------------| | [.NET SDK](https://dotnet.microsoft.com/download) | **8.0.x** | `dotnet --version` | | [Docker](https://docs.docker.com/get-docker/) *(optional)* | 24.x+ | `docker --version` | | MongoDB *(if not using Docker)* | 6.0+ | `mongod --version` | | Redis *(if not using Docker)* | 7.0+ | `redis-cli --version` | | RabbitMQ *(optional, for messaging)* | 3.12+ | `rabbitmqctl status` | ### Quick Start ```bash # 1. Clone the repository git clone cd adas-core # 2. Restore dependencies dotnet restore adas-core.sln # 3. Build the solution dotnet build adas-core.sln --configuration Release # 4. Run the API in development mode cd adas-core dotnet run --launch-profile "Development" ``` The API will be available by default at: - **HTTP**: `http://localhost:5000` - **HTTPS**: `https://localhost:5001` *(Ports are configurable in `Properties/launchSettings.json`.)* ### Docker Deployment ```bash # Build the image docker build -t adas-core:latest . # Run the container docker run -p 8080:80 \ -e ASPNETCORE_ENVIRONMENT=Production \ adas-core:latest ``` > The `Dockerfile` uses a multi-stage Linux-based build optimized for production deployment. ### Build Configurations The solution supports multiple build configurations for different environments: | Configuration | Purpose | |---------------|---------| | `Debug` | Local development with full debug symbols. | | `DebugNoMedia` | Debug without embedded media resources (faster compilation). | | `Release` | Optimized build for general production. | | `ReleaseNoMedia` | Release without media resources (smaller artifact). | | `H12O-Release` | Release profile for the **H12O** product line. | | `HRYC-Release` | Release profile for the **HRYC** product line. | | `SmacsServer` | Release profile for the **SMACS** server environment. | ```bash # Example: build a specific profile dotnet build adas-core.sln --configuration H12O-Release ``` > All `Release` and `H*-Release` configurations enforce `TreatWarningsAsErrors`, ensuring production-quality code. --- ## Configuration ### appsettings.json The application uses the standard ASP.NET Core configuration hierarchy: ```json { "ConnectionStrings": { "MongoDb": "mongodb://localhost:27017/adas-core", "Redis": "localhost:6379" }, "Authentication": { "Scheme": "Local", "Jwt": { "Secret": "your-secret-key-min-32-characters-long", "Issuer": "ADAS-Core", "Audience": "ADAS-Clients", "ExpirationMinutes": 60 } }, "Serilog": { "MinimumLevel": { "Default": "Information", "Override": { "Microsoft": "Warning", "System": "Warning" } } } } ``` ### Environment Variables | Variable | Purpose | Example | |----------|---------|---------| | `ASPNETCORE_ENVIRONMENT` | Runtime environment | `Development`, `Staging`, `Production` | | `ASPNETCORE_URLS` | Binding URLs | `http://+:80;https://+:443` | | `ConnectionStrings__MongoDb` | MongoDB connection string | `mongodb://...` | | `Authentication__Jwt__Secret` | JWT signing key | *(use secrets manager in production)* | ### User Secrets In development, store sensitive values using the .NET User Secrets manager: ```bash cd adas-core dotnet user-secrets set "Authentication:Jwt:Secret" "your-dev-secret-key" ``` --- ## Authentication The system implements a **multi-strategy authentication** model using a provider pattern. The host application registers the appropriate strategy at runtime based on configuration. ### Available Strategies | Strategy | Project | Description | |----------|---------|-------------| | **LDAP / Active Directory** | `adas-core.LdapLogin` | Corporate authentication against LDAP directories. Uses `Novell.Directory.Ldap.NETStandard`. | | **Local Database** | `adas-core.LocalLogin` | Internal authentication with users stored in MongoDB. Passwords hashed with **BCrypt**. | ### Architecture ```mermaid flowchart LR subgraph AuthLayer["Authentication Abstraction"] A[adas-core.Authentication\nJWT / Claims / Middleware] end subgraph Strategies["Concrete Strategies"] L[adas-core.LdapLogin] Lo[adas-core.LocalLogin] end subgraph Stores["Identity Stores"] LDAP[(LDAP / AD Server)] DB[(MongoDB)] end Client -->|HTTP Request| A A -->|resolve strategy| L A -->|resolve strategy| Lo L -->|bind| LDAP Lo -->|query| DB ``` ### Configuration Example ```json { "Authentication": { "Scheme": "Local", "Jwt": { "Secret": "<32-char-secret-key-here>", "Issuer": "ADAS-Core", "Audience": "ADAS-Clients", "ExpirationMinutes": 60 }, "Ldap": { "Server": "ldap.corp.local", "Port": 636, "UseSSL": true, "BindDN": "CN=service,OU=Users,DC=corp,DC=local" } } } ``` To switch strategies, change the `Authentication:Scheme` value to `"Ldap"` or `"Local"`. --- ## Logging The application uses **Serilog** for structured logging, integrated natively with ASP.NET Core. ### Features - **Structured JSON output** for machine parsing and aggregation. - **Automatic enrichment** with thread identifiers, exception details, and dynamic context properties. - **Multiple sinks**: Console for containers, rolling files for persistence. - **Compact format** for efficient storage and transmission. ### Configured Sinks | Sink | Output | Format | |------|--------|--------| | **Console** | Standard output / Docker logs | Compact JSON | | **File** | `./Logs/log-.txt` (daily rotation) | Compact JSON | ### Enrichers | Enricher | Source | Purpose | |----------|--------|---------| | `ThreadId` | `Serilog.Enrichers.Thread` | Track request thread correlation. | | `ExceptionDetails` | `Serilog.Exceptions` | Capture full exception object graphs. | | `DynamicProperties` | `Serilog.Enrichers.Dynamic` | Add runtime context properties. | ### Prometheus Metrics The `/metrics` endpoint exposes application and runtime metrics in Prometheus-compatible format: ```bash curl http://localhost:5000/metrics ``` --- ## Testing The `adas-core.Test` project provides comprehensive test coverage using **NUnit** as the test framework. ### Running Tests ```bash # Full test suite dotnet test adas-core.sln # With code coverage dotnet test adas-core.sln --collect:"XPlat Code Coverage" # Verbose output dotnet test adas-core.sln --logger "console;verbosity=detailed" ``` ### Test Types | Type | Description | Tools | |------|-------------|-------| | **Unit** | Isolated tests of domain rules and application services. | NUnit, Moq | | **Integration** | End-to-end tests with embedded MongoDB (`Mongo2Go`). | NUnit, Mongo2Go | | **Fakes** | Isolated tests of external dependencies using assembly shims. | Microsoft Fakes | ### Code Quality Gates - `TreatWarningsAsErrors = True` (Debug / Release) - Nullable reference types enabled across all projects - NUnit static analysis via `NUnit.Analyzers` - Coverlet code coverage collection --- ## Technologies & Dependencies ### Framework & Runtime | Technology | Version | |------------|---------| | .NET / ASP.NET Core | **8.0** | | C# Language | **12** | ### Key Libraries | Category | Package | Version | Purpose | |----------|---------|---------|---------| | **ORM** | `Microsoft.EntityFrameworkCore` | 8.0.27 | Relational data access | | **NoSQL** | `MongoDB.Driver` / `MongoDB.Bson` | 3.9.0 | MongoDB access and serialization | | **Migrations** | `MongoMigrations.Core` | 4.0.15 | MongoDB schema migrations | | **Cache** | `StackExchange.Redis` | 2.13.17 | Distributed caching | | **Messaging** | `EasyNetQ` | 8.1.4 | RabbitMQ async messaging | | **Push** | `WebPush` | 1.0.13 | Browser push notifications | | **Auth** | `Microsoft.AspNetCore.Authentication.JwtBearer` | 8.0.8 | JWT Bearer authentication | | **Auth** | `System.IdentityModel.Tokens.Jwt` | 8.18.0 | JWT token handling | | **Security** | `BCrypt.Net-Next` | 4.2.0 | Password hashing | | **Security** | `Novell.Directory.Ldap.NETStandard` | 4.0.0 | LDAP integration | | **Validation** | `FluentValidation` | 12.1.1 | Input validation rules | | **Mapping** | `AutoMapper` | 16.1.1 | Entity <-> DTO mapping | | **Scheduling** | `Quartz` | 3.18.1 | Background job scheduling | | **Scripts** | `Microsoft.CodeAnalysis.CSharp.Scripting` | 5.3.0 | Dynamic C# evaluation | | **Logging** | `Serilog` + sinks + enrichers | 4.x | Structured logging pipeline | | **Metrics** | `prometheus-net.AspNetCore` | 8.2.1 | Prometheus metrics endpoint | | **Testing** | `NUnit` / `NUnit3TestAdapter` | 4.6.1 / 6.2.0 | Unit testing framework | | **Testing** | `Moq` | 4.20.72 | Dependency mocking | | **Testing** | `Mongo2Go` | 4.1.0 | Embedded MongoDB for tests | | **Testing** | `coverlet.collector` | 10.0.1 | Code coverage | --- ## Conventions & Best Practices ### Code Style 1. **Naming**: `PascalCase` for types, methods, and properties; `camelCase` for parameters and locals. 2. **Namespaces**: Must match the physical file path (e.g., `adas_core.Domain.Entities`). 3. **Nullables**: Explicit nullable reference types are enforced (`nullable enable`). 4. **Interfaces**: Prefixed with `I` (e.g., `IRepository`, `ITokenService`). 5. **Async**: Asynchronous method names must end with `Async` suffix. 6. **XML Docs**: All public APIs must include XML documentation comments. ### Dependency Direction - The **Domain** layer must never reference any other project. - **Application** depends only on **Domain**. - **Infrastructure** depends on **Application** and modules it supports. - **Authentication** depends on **Application** and **Domain**. - Concrete login strategies depend on **Authentication**. - **Modules** depend on **Domain** (preferentially) or **Application** for shared abstractions. - **Tests** reference the layers under test; use mocking for external dependencies. ### Commit Messages Use descriptive English commit messages following conventional commits: ``` feat(beacon): add color pattern validation fix(auth): resolve JWT expiration drift refactor(infra): extract Redis connection factory docs(readme): update build instructions ``` ### Scalability Notes - **Modules** are designed to be extracted as independent microservices with minimal changes. - **Domain events** enable asynchronous inter-module communication without tight coupling. - **Message bus** (RabbitMQ via EasyNetQ) supports horizontal scaling of consumers. - **Redis** caching layer reduces database load for frequently accessed data. - **Prometheus metrics** allow monitoring and alerting in container orchestration environments. --- ## License Copyright (c) **Epigram Technologies** — All rights reserved. This software is proprietary and confidential. Reproduction, distribution, or modification without express written authorization from Epigram Technologies is prohibited. ---

ADAS Core v2.1  |  Built with .NET 8