339 lines
15 KiB
Markdown
339 lines
15 KiB
Markdown
# adas-core.Application — Use Case Layer
|
|
|
|
> The **Application Layer** of the ADAS Core platform.
|
|
> Contains application services, use case orchestration, repository contracts, caching abstractions, and domain-specific exceptions. This layer defines **what** the system does, delegating **how** to the Infrastructure layer.
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
1. [Overview](#overview)
|
|
2. [Responsibilities](#responsibilities)
|
|
3. [Project Structure](#project-structure)
|
|
4. [Dependencies](#dependencies)
|
|
5. [Repository Contracts](#repository-contracts)
|
|
6. [Application Services](#application-services)
|
|
7. [Caching Abstractions](#caching-abstractions)
|
|
8. [Exceptions](#exceptions)
|
|
9. [Environment Customizations](#environment-customizations)
|
|
10. [Design Rules](#design-rules)
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
`adas-core.Application` sits between the **Domain** and **Infrastructure** layers. It orchestrates domain entities into complete use cases, enforces application-level rules, and exposes repository contracts that Infrastructure implements.
|
|
|
|
Key characteristics:
|
|
|
|
- **Pure orchestration** — Services coordinate domain objects but contain no persistence logic.
|
|
- **Repository contracts** — Interfaces in `Repositories/Interfaces/` define data access contracts; concrete implementations live in `adas-core.Infrastructure`.
|
|
- **DTO-less where possible** — Services consume and return domain entities directly when serialization concerns are handled upstream.
|
|
- **Pluggable caching** — Abstracted behind `ICacheService` with Redis or in-memory fallbacks.
|
|
- **Environment-specific logic** — Calculated observations vary per deployment via the `Customizations` folder.
|
|
|
|
---
|
|
|
|
## Responsibilities
|
|
|
|
| Concern | What this project does |
|
|
|---------|----------------------|
|
|
| **Use Case Orchestration** | Application services execute high-level workflows (admit patient, record observation, trigger alert, etc.). |
|
|
| **Repository Contracts** | Defines `I*` repository interfaces that Infrastructure must satisfy. |
|
|
| **Caching Strategy** | Provides `ICacheService`, `ILockProvider`, and `LockManagerService` for distributed or in-memory caching. |
|
|
| **External Provider Facade** | `AdasProvider` / `BaseProvider` abstract external integrations so domain logic remains clean. |
|
|
| **Real-Time Subscriptions** | `SubscribersService` and grouped subscriber models manage WebSocket client subscriptions. |
|
|
| **Calculated Observations** | `CalculatedObservationsService` evaluates patient observations using rules customized per environment. |
|
|
| **Scheduled Jobs** | `SchedulerService` coordinates Quartz-based background tasks. |
|
|
| **Exception Taxonomy** | Domain-relevant exceptions (`NotFoundException`, `ConflictException`, etc.) for predictable error handling. |
|
|
|
|
---
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
adas-core.Application/
|
|
├── Repositories/
|
|
│ └── Interfaces/ # Repository contracts (~40 interfaces)
|
|
│ ├── IMongoRepository.cs
|
|
│ ├── IUserRepository.cs
|
|
│ ├── IPatientRepository.cs
|
|
│ ├── IAdmissionRepository.cs
|
|
│ ├── IObservationRepository.cs
|
|
│ ├── ITreatmentRepository.cs
|
|
│ ├── IAlarmRepository.cs
|
|
│ ├── IDeviceRepository.cs
|
|
│ ├── ILightBeaconRepository.cs
|
|
│ ├── IRelayRepository.cs
|
|
│ ├── IPump*Repository.cs
|
|
│ ├── IRecordingAlertRepository.cs
|
|
│ ├── IConfig*Repository.cs
|
|
│ ├── IUnitRepository.cs
|
|
│ ├── IDisplay*Repository.cs
|
|
│ ├── IAppointmentRepository.cs
|
|
│ ├── IPatientCarePlanRepository.cs
|
|
│ ├── IMasterListRepository.cs
|
|
│ └── ...
|
|
├── Services/
|
|
│ ├── Interfaces/ # Service contracts (~40 interfaces)
|
|
│ │ ├── IAuthService.cs
|
|
│ │ ├── IPatientService.cs
|
|
│ │ ├── IObservationService.cs
|
|
│ │ ├── ICalculatedObservationsService.cs
|
|
│ │ ├── ITreatmentService.cs
|
|
│ │ ├── IDeviceService.cs
|
|
│ │ ├── IAlarmService.cs
|
|
│ │ ├── IDisplayService.cs
|
|
│ │ ├── IConfigObservationService.cs
|
|
│ │ ├── IUnitService.cs
|
|
│ │ ├── IAppointmentService.cs
|
|
│ │ ├── IPublisherService.cs
|
|
│ │ ├── ICacheService.cs
|
|
│ │ ├── ILockProvider.cs
|
|
│ │ └── ...
|
|
│ ├── AuthService.cs
|
|
│ ├── PatientService.cs
|
|
│ ├── AdmissionService.cs
|
|
│ ├── ObservationService.cs
|
|
│ ├── CalculatedObservationsService.cs
|
|
│ ├── DefaultCalculatedObservations.cs
|
|
│ ├── TreatmentService.cs
|
|
│ ├── AlarmService.cs
|
|
│ ├── DeviceService.cs
|
|
│ ├── CameraService.cs
|
|
│ ├── Config*Service.cs
|
|
│ ├── DisplayService.cs
|
|
│ ├── PointOfCareService.cs
|
|
│ ├── AppointmentService.cs
|
|
│ ├── PatientCarePlanService.cs
|
|
│ ├── Archive*Service.cs
|
|
│ ├── Recording*Service.cs
|
|
│ ├── MasterListService.cs
|
|
│ ├── MasterListServiceFactory.cs
|
|
│ ├── PermissionService.cs
|
|
│ ├── AdminPanelService.cs
|
|
│ ├── FileService.cs
|
|
│ ├── LocalAuditService.cs
|
|
│ ├── SubscribersService.cs
|
|
│ ├── SchedulerService.cs
|
|
│ └── Caching/
|
|
│ ├── CacheService.cs
|
|
│ ├── NoCacheService.cs
|
|
│ ├── RedisService.cs
|
|
│ ├── CacheDispatcher.cs
|
|
│ ├── LockManagerService.cs
|
|
│ ├── InMemoryLockProvider.cs
|
|
│ └── RedisLockProvider.cs
|
|
├── Exceptions/
|
|
│ ├── APIRequestException.cs
|
|
│ ├── BadRequestException.cs
|
|
│ ├── ConflictException.cs
|
|
│ ├── NotFoundException.cs
|
|
│ ├── UnauthorizedException.cs
|
|
│ ├── TokenException.cs
|
|
│ ├── UnprocessableEntityException.cs
|
|
│ └── ...
|
|
├── Customizations/ # Environment-specific calculated-observation rules
|
|
│ ├── BD/
|
|
│ ├── CHUO/
|
|
│ ├── H12O/UCIN/
|
|
│ ├── HGM/
|
|
│ ├── HPAZ/
|
|
│ ├── HRYC/
|
|
│ ├── HUVH/UCIN/
|
|
│ ├── HUVH/UCIA/
|
|
│ └── NursePlan/
|
|
│ └── CalculatedObservations.cs
|
|
├── Providers/
|
|
│ ├── BaseProvider.cs
|
|
│ └── AdasProvider.cs
|
|
└── Subscriptions/
|
|
├── SubscribersService.cs
|
|
├── WsSuscriber.cs
|
|
└── WsSubscriberGrouped.cs
|
|
```
|
|
|
|
---
|
|
|
|
## Dependencies
|
|
|
|
### Downstream References
|
|
|
|
| Project | Role |
|
|
|---------|------|
|
|
| `adas-core.Domain` | Domain entities, value objects, and business rules consumed by application services. |
|
|
|
|
### Upstream References (projects that depend on this)
|
|
|
|
| Project | Reason |
|
|
|---------|--------|
|
|
| `adas-core` (Host) | Registers application services and invokes them from controllers. |
|
|
| `adas-core.Infrastructure` | Implements all repository contracts defined in `Repositories/Interfaces/`. |
|
|
| `adas-core.Authentication` | Uses `IAuthService` and user-related service contracts. |
|
|
| `adas-core.module.LightBeacons` | Consumes shared application service interfaces. |
|
|
| `adas-core.module.ProxyDevices` | Consumes shared application service interfaces. |
|
|
| `adas-core.module.Relays` | Consumes shared application service interfaces. |
|
|
| `adas-core.Test` | Mocks application service interfaces in unit tests. |
|
|
|
|
### NuGet Packages
|
|
|
|
| Package | Version | Purpose |
|
|
|---------|---------|---------|
|
|
| `AutoMapper` | 16.1.1 | Entity ↔ projection mapping. |
|
|
| `MongoDB.Driver` | 3.9.0 | Repository interface type signatures. |
|
|
| `Quartz` | 3.18.1 | Scheduling primitives for background jobs. |
|
|
| `StackExchange.Redis` | 2.13.17 | Redis caching abstractions. |
|
|
| `Microsoft.Extensions.Caching.Memory` | 10.0.8 | In-memory caching fallback. |
|
|
| `Microsoft.Extensions.Http` | 10.0.8 | Typed HTTP clients for provider integrations. |
|
|
| `Microsoft.IdentityModel.JsonWebTokens` | 8.18.0 | JWT validation helpers for auth services. |
|
|
| `Microsoft.CodeAnalysis.CSharp.Scripting` | 5.3.0 | Dynamic expression evaluation for calculated observations. |
|
|
| `AuditLogs` | 1.0.59 | Audit trail tagging in use cases. |
|
|
|
|
---
|
|
|
|
## Repository Contracts
|
|
|
|
All repository interfaces reside in `Repositories/Interfaces/`. They are **contracts only** — no implementation. This enforces the Dependency Inversion Principle: Application defines the interface, Infrastructure provides the concrete MongoDB-backed classes.
|
|
|
|
### Generic Base Contract
|
|
|
|
```csharp
|
|
public interface IMongoRepository<T> where T : class
|
|
{
|
|
Task<T?> GetByIdAsync(ObjectId id);
|
|
Task<IEnumerable<T>> GetAllAsync();
|
|
Task<T> InsertAsync(T entity);
|
|
Task UpdateAsync(ObjectId id, T entity);
|
|
Task DeleteAsync(ObjectId id);
|
|
}
|
|
```
|
|
|
|
### Specialized Contracts
|
|
|
|
Derived interfaces extend `IMongoRepository<T>` or stand alone for aggregate-specific queries:
|
|
|
|
- `IPatientRepository` — CRUD + admission/discharge history lookups.
|
|
- `IObservationRepository` — Inserts with archive triggers, range queries.
|
|
- `IPumpStateRepository` — Scoped lifetime; tracks real-time pump telemetry.
|
|
- `IAlarmRepository` — Acknowledge, escalate, and history retrieval.
|
|
- `IDisplayConfigRepository` — Display layout and card/chart configuration.
|
|
|
|
> **Rule:** Every repository method name must describe intent, not mechanism (e.g., `GetActiveByUnitAsync` rather than `FindByQuery`).
|
|
|
|
---
|
|
|
|
## Application Services
|
|
|
|
Services in `Services/` encapsulate complete use cases. They are registered as **Singletons** in the DI container unless they hold per-request state.
|
|
|
|
### Service Categories
|
|
|
|
| Category | Examples |
|
|
|----------|----------|
|
|
| **Patient Management** | `PatientService`, `AdmissionService`, `DischargeService`, `PatientCarePlanService` |
|
|
| **Observations** | `ObservationService`, `ObservationDemoService`, `CalculatedObservationsService`, `GroupedObservationService` |
|
|
| **Clinical** | `TreatmentService`, `MedicineService`, `DiagnosisService` |
|
|
| **Devices** | `DeviceService`, `CameraService`, `PumpService` |
|
|
| **Alerts** | `AlarmService`, `AlertValuesService` |
|
|
| **Configuration** | `ConfigObservationService`, `ConfigPumpsService`, `ConfigUnitsService`, `ServiceConfigService` |
|
|
| **Displays** | `DisplayService`, `DisplayConfigService` |
|
|
| **System** | `AuthService`, `PermissionService`, `UnitService`, `MasterListService`, `AdminPanelService` |
|
|
| **Archival** | `ArchivePatientObservationsService`, `ArchivedPatientService`, `HistoricalConfigChangesService` |
|
|
| **Communication** | `SubscribersService`, `PublisherService`, `ClientMessageService` |
|
|
|
|
### Calculated Observations
|
|
|
|
`CalculatedObservationsService` evaluates derived metrics (e.g., early warning scores, trend indicators) using `ICalculatedObservations` strategy pattern. Per-environment overrides are loaded from the `Customizations/` folder based on `ASPNETCORE_ENVIRONMENT`.
|
|
|
|
Example environment mappings:
|
|
|
|
| Environment | Customization Path |
|
|
|-------------|--------------------|
|
|
| `H12O` | `Customizations/H12O/UCIN/CalculatedObservations.cs` |
|
|
| `HRYCM` | `Customizations/HRYC/CalculatedObservations.cs` |
|
|
| `HPAZ` | `Customizations/HPAZ/CalculatedObservations.cs` |
|
|
| `HUVH-UCIN` | `Customizations/HUVH/UCIN/CalculatedObservations.cs` |
|
|
| `HUVH-UCIA` | `Customizations/HUVH/UCIA/CalculatedObservations.cs` |
|
|
| `CHUO` | `Customizations/CHUO/CalculatedObservations.cs` |
|
|
| `NursePlan` | `Customizations/NursePlan/CalculatedObservations.cs` |
|
|
|
|
---
|
|
|
|
## Caching Abstractions
|
|
|
|
The caching stack abstracts Redis and in-memory behind common interfaces so services remain cache-agnostic.
|
|
|
|
| Component | Responsibility |
|
|
|-----------|-------------|
|
|
| `ICacheService` | Contract for get, set, remove, and sliding/absolute expiration. |
|
|
| `CacheService` | Composite dispatcher that routes to Redis or memory. |
|
|
| `RedisService` | Concrete Redis implementation using `StackExchange.Redis`. |
|
|
| `NoCacheService` | Null-object pattern for disabling cache in test environments. |
|
|
| `ILockProvider` | Distributed or in-memory lock acquisition. |
|
|
| `LockManagerService` | Orchestrates lock lifecycle (acquire, extend, release). |
|
|
| `RedisLockProvider` | Redis-backed distributed locking. |
|
|
| `InMemoryLockProvider` | Lightweight semaphore-based locking for single-instance deployments. |
|
|
|
|
---
|
|
|
|
## Exceptions
|
|
|
|
The `Exceptions/` folder defines a predictable error taxonomy used by controllers to map to HTTP status codes.
|
|
|
|
| Exception | Mapped HTTP Status | Usage |
|
|
|-----------|-------------------|-------|
|
|
| `BadRequestException` | `400 Bad Request` | Malformed input, validation failure. |
|
|
| `UnauthorizedException` | `401 Unauthorized` | Missing or invalid credentials. |
|
|
| `ForbbidenException` | `403 Forbidden` | Authenticated but insufficient permissions. |
|
|
| `NotFoundException` | `404 Not Found` | Resource does not exist. |
|
|
| `ConflictException` | `409 Conflict` | Concurrent modification or duplicate key. |
|
|
| `UnprocessableEntityException` | `422 Unprocessable Entity` | Semantic validation failure. |
|
|
| `InvalidFormatException` | `400 Bad Request` | Payload format mismatch. |
|
|
| `CustomArgumentException` | `400 Bad Request` | Invalid argument supplied. |
|
|
| `APIRequestException` | `502 Bad Gateway` | External provider call failure. |
|
|
| `TokenException` | `401 Unauthorized` | JWT parsing or validation error. |
|
|
|
|
---
|
|
|
|
## Environment Customizations
|
|
|
|
`Customizations/` contains per-client overrides for `CalculatedObservations`. These are compiled into the assembly conditionally or selected at runtime based on environment.
|
|
|
|
This avoids branching domain logic and keeps environment-specific rules isolated:
|
|
|
|
```
|
|
Customizations/
|
|
├── BD/
|
|
├── CHUO/
|
|
├── H12O/UCIN/
|
|
├── HGM/
|
|
├── HPAZ/
|
|
├── HRYC/
|
|
├── HUVH/UCIN/
|
|
├── HUVH/UCIA/
|
|
└── NursePlan/
|
|
```
|
|
|
|
> **Rule:** Customizations may only override `ICalculatedObservations`; they must not introduce new repository calls or bypass service contracts.
|
|
|
|
---
|
|
|
|
## Design Rules
|
|
|
|
1. **No Persistence Logic** — Application services never call MongoDB, Redis, or HTTP clients directly. They use injected repository interfaces and provider abstractions.
|
|
2. **Dependency Direction** — This project references **only** `adas-core.Domain`. No references to Infrastructure, Authentication, or Modules.
|
|
3. **Contracts First** — All repositories and external providers must expose an interface in this project before Infrastructure implements them.
|
|
4. **Single Responsibility Per Service** — One service per bounded-context use case; avoid god services.
|
|
5. **Environment Agnosticism** — Core services must compile and run without environment-specific customizations. Overrides are opt-in.
|
|
6. **Exception-Driven Flow Control** — Use typed exceptions for expected error paths; never throw raw `Exception` or `ApplicationException`.
|
|
7. **Thread Safety** — Singleton services must be stateless or use immutable state. Per-request state lives in scoped repositories.
|
|
8. **Cache Invalidation Ownership** — The service that writes data is responsible for invalidating related cache keys.
|
|
9. **Lazy Evaluation** — Heavy graph traversals use deferred execution until the repository materializes results.
|
|
10. **Audit Trail Awareness** — Sensitive mutations (patient admission, alarm acknowledge, config changes) must tag audit metadata before returning.
|
|
|
|
---
|
|
|
|
<p align="center">
|
|
Back to <a href="../README.md">adas-core Root README</a>
|
|
</p>
|