# ECMJobRunner.Domain ## Project Overview ECMJobRunner.Domain is the **domain layer** for the ECM Job Runner system following **Clean Architecture** principles. This project contains: - **Entity models** that represent the business domain - **Repository interfaces** for data access abstraction - **Domain logic** (currently none, pure data entities) **Key Principle**: This layer has **NO** external dependencies - it's the core of the application. ## Target Frameworks - **.NET Framework 4.8** (`net480`) - **.NET 8.0** (`net8.0`) The project is multi-targeted to support both legacy .NET Framework applications and modern .NET 8 applications. ## Architecture This project follows **Clean Architecture** principles: - **No infrastructure dependencies** (no Entity Framework, no database concerns) - **Pure domain entities** without ORM attributes - **Repository pattern interfaces** for data access abstraction - **Dependency inversion** - infrastructure depends on domain, not vice versa ## Project Structure ``` ECMJobRunner.Domain/ ├── Entities/ │ ├── Profile.cs # Job configuration profile entity │ ├── ProfileSqlJob.cs # SQL job configuration entity │ └── ProfileHistory.cs # Job execution history entity ├── Interfaces/ │ ├── IRepository.cs # Generic repository interface │ ├── IProfileRepository.cs # Profile-specific repository │ ├── IProfileSqlJobRepository.cs │ ├── IProfileHistoryRepository.cs │ └── IUnitOfWork.cs # Unit of Work pattern interface ├── ECMJobRunner.Domain.csproj └── AGENTS.md # This file ``` ## Entities ### Profile Represents a job runner profile configuration. **Properties:** - `Id` (long): Primary key - `Active` (bool): Enable/disable switch - `ProfileName` (string, max 150): Name of the profile - `TypeId` (byte): Profile type (0=ADSync, 1=GraphQL, 2=SQL-Job, 3=SQL and REST-Job) - `Schedule` (string, max 150): Cron format schedule - `Comment` (string?, max 500): Optional description - `AddedWho`, `AddedWhen`, `ChangedWho`, `ChangedWhen`: Audit fields **Navigation Properties:** - `SqlJobs` (IEnumerable?): Associated SQL jobs - `ProfileHistories` (IEnumerable?): Execution history ### ProfileSqlJob Represents individual SQL jobs within a profile. **Properties:** - `Id` (long): Primary key - `ProfileId` (long): Foreign key to Profile - `Active` (bool): Enable/disable switch - `Sequence` (short): Execution order within the profile - `Name` (string?, max 150): Optional job name - `SqlCheckQuery` (string?): SQL query for pre-check - `SqlMainQuery` (string?): Main SQL query - `ApiCommand` (string?): API command to execute - `Comment` (string?, max 500): Optional description - Audit fields **Navigation Properties:** - `Profile` (Profile?): Associated profile ### ProfileHistory Stores execution history and results of job profiles. **Properties:** - `Id` (long): Primary key - `ProfileId` (long): Foreign key to Profile - `ResultId` (byte): Result status (0=OK, 1=ERROR, 2=WARNING) - `ResultText` (string): Result message/details - Audit fields **Navigation Properties:** - `Profile` (Profile?): Associated profile ## Repository Interfaces ### IRepository Generic repository interface providing CRUD operations: - `GetById(id)`, `GetByIdAsync(id)` - `GetAll()`, `GetAllAsync()` - `Find(predicate)`, `FindAsync(predicate)` - `SingleOrDefault(predicate)`, `SingleOrDefaultAsync(predicate)` - `Add(entity)`, `AddRange(entities)` - `Update(entity)`, `Remove(entity)`, `RemoveRange(entities)` ### Entity-Specific Repositories - `IProfileRepository : IRepository` - `IProfileSqlJobRepository : IRepository` - `IProfileHistoryRepository : IRepository` ### IUnitOfWork Manages transactions and provides access to all repositories: - `Profiles`: IProfileRepository - `ProfileSqlJobs`: IProfileSqlJobRepository - `ProfileHistories`: IProfileHistoryRepository - `SaveChanges()`, `SaveChangesAsync()` ## Database Schema Source The entities map to SQL Server tables located at: ``` M:\Datenbank\[DD_ECM]-Database\JobRunner\ ``` **Table Mappings** (handled in Infrastructure layer): - `Profile` → `dbo.TBJR_CFG_PROFILE` - `ProfileSqlJob` → `dbo.TBJR_CFG_PROFILE_SQLJOB` - `ProfileHistory` → `dbo.TBJR_OUT_PROFILE_HISTORY` ## Naming Conventions - **Entity Classes**: Clean Pascal case (e.g., `Profile` instead of `TBJR_CFG_PROFILE`) - **Properties**: Pascal case (e.g., `ProfileName` instead of `PROFILE_NAME`) - **No ORM attributes** - entities are pure POCOs - **Navigation properties** are nullable `IEnumerable?` (loaded only when explicitly included) ## Dependencies **NONE** - This is a core domain layer with zero external dependencies. ## Building the Project ```bash dotnet build ECMJobRunner.Domain.csproj ``` For specific framework: ```bash dotnet build ECMJobRunner.Domain.csproj -f net8.0 dotnet build ECMJobRunner.Domain.csproj -f net480 ``` ## Development Notes - **Clean Architecture**: Domain layer is independent of infrastructure concerns - **Navigation properties**: Nullable IEnumerable - populated only when explicitly loaded via `.Include()` - **No ORM attributes**: Pure POCOs - mapping is done in Infrastructure layer - **Repository pattern**: All data access through interfaces - **Unit of Work pattern**: Transaction management abstraction ## Related Projects - **ECMJobRunner.Infrastructure**: Implements repositories and DbContext - **ECMJobRunner.Application**: Application layer with business logic ## Company Information **Author**: Digital Data GmbH **Copyright**: 2026 **Repository**: http://git.dd:3000/AppStd/ECMJobRunner.git