Add ECMJobRunner.Domain entities and documentation
Introduced the `ECMJobRunner.Domain` project to support both .NET Framework 4.8 and .NET 8.0. Added `Profile`, `ProfileSqlJob`, and `ProfileHistory` entities to map to the database schema, including relationships and audit fields. Updated `ECMJobRunner.Domain.csproj` to enable multi-targeting and added dependencies for Entity Framework 6.5.1 and EF Core 8.0.11. Enabled nullable reference types and set the language version to `latest`. Added comprehensive documentation in `AGENTS.md` detailing the project structure, entities, database schema, and build instructions.
This commit is contained in:
142
ECMJobRunner.Domain/AGENTS.md
Normal file
142
ECMJobRunner.Domain/AGENTS.md
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
# ECMJobRunner.Domain
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
ECMJobRunner.Domain is a domain entity library for the ECM Job Runner system. This project contains entity models that represent the database schema for job runner configuration and execution history.
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
## Technologies
|
||||||
|
|
||||||
|
### Entity Framework
|
||||||
|
- **For .NET Framework 4.8**: Entity Framework 6.5.1
|
||||||
|
- **For .NET 8.0**: Entity Framework Core 8.0.11 with SQL Server provider
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
ECMJobRunner.Domain/
|
||||||
|
├── Entities/
|
||||||
|
│ ├── Profile.cs # Job configuration profile entity
|
||||||
|
│ ├── ProfileSqlJob.cs # SQL job configuration entity
|
||||||
|
│ └── ProfileHistory.cs # Job execution history entity
|
||||||
|
├── ECMJobRunner.Domain.csproj
|
||||||
|
└── AGENTS.md # This file
|
||||||
|
```
|
||||||
|
|
||||||
|
## Entities
|
||||||
|
|
||||||
|
### Profile
|
||||||
|
**Table:** `dbo.TBJR_CFG_PROFILE`
|
||||||
|
|
||||||
|
Represents a job runner profile configuration.
|
||||||
|
|
||||||
|
**Key Properties:**
|
||||||
|
- `Id` (PK): Primary key, auto-generated
|
||||||
|
- `Active`: Enable/disable switch
|
||||||
|
- `ProfileName`: Name of the profile
|
||||||
|
- `TypeId`: Profile type (0=ADSync, 1=GraphQL, 2=SQL-Job, 3=SQL and REST-Job)
|
||||||
|
- `Schedule`: Cron format schedule
|
||||||
|
- `Comment`: Optional description
|
||||||
|
|
||||||
|
**Relationships:**
|
||||||
|
- One-to-Many with `ProfileSqlJob` (SQL jobs)
|
||||||
|
- One-to-Many with `ProfileHistory` (execution history)
|
||||||
|
|
||||||
|
### ProfileSqlJob
|
||||||
|
**Table:** `dbo.TBJR_CFG_PROFILE_SQLJOB`
|
||||||
|
|
||||||
|
Represents individual SQL jobs within a profile.
|
||||||
|
|
||||||
|
**Key Properties:**
|
||||||
|
- `Id` (PK): Primary key, auto-generated
|
||||||
|
- `ProfileId` (FK): Foreign key to `Profile`
|
||||||
|
- `Active`: Enable/disable switch
|
||||||
|
- `Sequence`: Execution order within the profile
|
||||||
|
- `Name`: Optional job name
|
||||||
|
- `SqlCheckQuery`: SQL query for pre-check
|
||||||
|
- `SqlMainQuery`: Main SQL query
|
||||||
|
- `ApiCommand`: API command to execute
|
||||||
|
|
||||||
|
**Relationships:**
|
||||||
|
- Many-to-One with `Profile`
|
||||||
|
|
||||||
|
### ProfileHistory
|
||||||
|
**Table:** `dbo.TBJR_OUT_PROFILE_HISTORY`
|
||||||
|
|
||||||
|
Stores execution history and results of job profiles.
|
||||||
|
|
||||||
|
**Key Properties:**
|
||||||
|
- `Id` (PK): Primary key, auto-generated
|
||||||
|
- `ProfileId` (FK): Foreign key to `Profile`
|
||||||
|
- `ResultId`: Result status (0=OK, 1=ERROR, 2=WARNING)
|
||||||
|
- `ResultText`: Result message/details
|
||||||
|
|
||||||
|
**Relationships:**
|
||||||
|
- Many-to-One with `Profile`
|
||||||
|
|
||||||
|
## Database Schema Source
|
||||||
|
|
||||||
|
The entities are based on SQL Server tables located at:
|
||||||
|
```
|
||||||
|
M:\Datenbank\[DD_ECM]-Database\JobRunner\
|
||||||
|
```
|
||||||
|
|
||||||
|
The following SQL files define the schema:
|
||||||
|
- `[TBJR_CFG_PROFILE].sql` - Profile configuration table
|
||||||
|
- `[TBJR_CFG_PROFILE_SQLJOB].sql` - SQL job configuration table
|
||||||
|
- `[TBJR_OUT_PROFILE_HISTORY].sql` - Execution history table
|
||||||
|
- `[VWJR_CFG_PROFILE].sql` - Profile view (not implemented as entity)
|
||||||
|
- `[VWJR_CFG_PROFILE_SQLJOB].sql` - SQL job view (not implemented as entity)
|
||||||
|
|
||||||
|
## 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`)
|
||||||
|
- **Table Mapping**: Uses `[Table]` attribute to map to actual database table names
|
||||||
|
- **Column Mapping**: Uses `[Column]` attribute to map to actual column names
|
||||||
|
- Entity names are simplified without technical prefixes (Jr/Cfg/Out)
|
||||||
|
|
||||||
|
## Attributes Used
|
||||||
|
|
||||||
|
- `[Table]` - Specifies the database table name and schema
|
||||||
|
- `[Column]` - Specifies the database column name
|
||||||
|
- `[Key]` - Marks the primary key
|
||||||
|
- `[Required]` - Marks non-nullable properties
|
||||||
|
- `[MaxLength]` - Specifies maximum string length
|
||||||
|
- `[ForeignKey]` - Specifies foreign key relationships
|
||||||
|
- `[DatabaseGenerated]` - Specifies identity/auto-generated columns
|
||||||
|
|
||||||
|
## Building the Project
|
||||||
|
|
||||||
|
To build the project:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet build ECMJobRunner.Domain.csproj
|
||||||
|
```
|
||||||
|
|
||||||
|
To build for a specific framework:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet build ECMJobRunner.Domain.csproj -f net8.0
|
||||||
|
dotnet build ECMJobRunner.Domain.csproj -f net480
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Notes
|
||||||
|
|
||||||
|
- All entities include audit fields: `AddedWho`, `AddedWhen`, `ChangedWho`, `ChangedWhen`
|
||||||
|
- Navigation properties are marked as `virtual` to support lazy loading
|
||||||
|
- Nullable reference types are enabled for better null-safety
|
||||||
|
- XML documentation is generated for IntelliSense support
|
||||||
|
- Default values are set according to database constraints
|
||||||
|
|
||||||
|
## Company Information
|
||||||
|
|
||||||
|
**Author**: Digital Data GmbH
|
||||||
|
**Copyright**: 2026
|
||||||
|
**Repository**: http://git.dd:3000/AppStd/ECMJobRunner.git
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net480;net8.0</TargetFrameworks>
|
<TargetFrameworks>net480;net8.0</TargetFrameworks>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(MSBuildProjectName).xml</DocumentationFile>
|
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(MSBuildProjectName).xml</DocumentationFile>
|
||||||
<PackageId>ECMJobRunner.Domain</PackageId>
|
<PackageId>ECMJobRunner.Domain</PackageId>
|
||||||
<Authors>Digital Data GmbH</Authors>
|
<Authors>Digital Data GmbH</Authors>
|
||||||
@@ -9,7 +11,19 @@
|
|||||||
<Product>ECMJobRunner.Domain</Product>
|
<Product>ECMJobRunner.Domain</Product>
|
||||||
<Copyright>Copyright 2026</Copyright>
|
<Copyright>Copyright 2026</Copyright>
|
||||||
<RepositoryUrl>http://git.dd:3000/AppStd/ECMJobRunner.git</RepositoryUrl>
|
<RepositoryUrl>http://git.dd:3000/AppStd/ECMJobRunner.git</RepositoryUrl>
|
||||||
<PackageTags>digital data ecm job runner</PackageTags>
|
<PackageTags>digital data ecm job runner domain</PackageTags>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(TargetFramework)' == 'net480'">
|
||||||
|
<!-- Entity Framework 6 for .NET Framework 4.8 -->
|
||||||
|
<PackageReference Include="EntityFramework" Version="6.5.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||||
|
<!-- Entity Framework Core 8 for .NET 8 -->
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.11" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.11" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.11" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
101
ECMJobRunner.Domain/Entities/Profile.cs
Normal file
101
ECMJobRunner.Domain/Entities/Profile.cs
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace ECMJobRunner.Domain.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Job Runner Configuration Profile Entity
|
||||||
|
/// Represents a job runner profile configuration
|
||||||
|
/// Type: 0 = ADSync; 1 = GraphQL; 2 = SQL-Job; 3 = SQL and REST-Job
|
||||||
|
/// </summary>
|
||||||
|
[Table("TBJR_CFG_PROFILE", Schema = "dbo")]
|
||||||
|
public class Profile
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Primary Key
|
||||||
|
/// </summary>
|
||||||
|
[Key]
|
||||||
|
[Column("PK_TBJR_CFG_PROFILE_ID")]
|
||||||
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Active / Inactive switch
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("ACTIVE")]
|
||||||
|
public bool Active { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Optional profile name
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("PROFILE_NAME")]
|
||||||
|
[MaxLength(150)]
|
||||||
|
public string ProfileName { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Profile type: 0 = ADSync; 1 = GraphQL; 2 = SQL-Job; 3 = SQL and REST-Job
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("TYPE_ID")]
|
||||||
|
public byte TypeId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Schedule in Cron format
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("SCHEDULE")]
|
||||||
|
[MaxLength(150)]
|
||||||
|
public string Schedule { get; set; } = "0 30 4 ? * MON-SAT";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Optional description
|
||||||
|
/// </summary>
|
||||||
|
[Column("COMMENT")]
|
||||||
|
[MaxLength(500)]
|
||||||
|
public string? Comment { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Created by
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("ADDED_WHO")]
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string AddedWho { get; set; } = "DEFAULT";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Created at
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("ADDED_WHEN")]
|
||||||
|
public DateTime AddedWhen { get; set; } = DateTime.Now;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Modified by
|
||||||
|
/// </summary>
|
||||||
|
[Column("CHANGED_WHO")]
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string? ChangedWho { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Modified at
|
||||||
|
/// </summary>
|
||||||
|
[Column("CHANGED_WHEN")]
|
||||||
|
public DateTime? ChangedWhen { get; set; }
|
||||||
|
|
||||||
|
// Navigation properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SQL Jobs associated with this profile
|
||||||
|
/// </summary>
|
||||||
|
public virtual ICollection<ProfileSqlJob> SqlJobs { get; set; } = new List<ProfileSqlJob>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Profile execution history
|
||||||
|
/// </summary>
|
||||||
|
public virtual ICollection<ProfileHistory> ProfileHistories { get; set; } = new List<ProfileHistory>();
|
||||||
|
}
|
||||||
|
}
|
||||||
80
ECMJobRunner.Domain/Entities/ProfileHistory.cs
Normal file
80
ECMJobRunner.Domain/Entities/ProfileHistory.cs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace ECMJobRunner.Domain.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Profile Execution History
|
||||||
|
/// Stores the execution history and results of job runner profiles
|
||||||
|
/// Result ID: 0 = OK; 1 = ERROR; 2 = WARNING
|
||||||
|
/// </summary>
|
||||||
|
[Table("TBJR_OUT_PROFILE_HISTORY", Schema = "dbo")]
|
||||||
|
public class ProfileHistory
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Primary Key
|
||||||
|
/// </summary>
|
||||||
|
[Key]
|
||||||
|
[Column("PK_TBJR_OUT_PROFILE_HISTORY_ID")]
|
||||||
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Foreign Key to Profile
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("FK_TBJR_CFG_PROFILE_ID")]
|
||||||
|
[ForeignKey(nameof(Profile))]
|
||||||
|
public long ProfileId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Result ID: 0 = OK; 1 = ERROR; 2 = WARNING
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("RESULT_ID")]
|
||||||
|
public byte ResultId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Result text/message
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("RESULT_TEXT")]
|
||||||
|
public string ResultText { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Created by
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("ADDED_WHO")]
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string AddedWho { get; set; } = "DEFAULT";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Created at
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("ADDED_WHEN")]
|
||||||
|
public DateTime AddedWhen { get; set; } = DateTime.Now;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Modified by
|
||||||
|
/// </summary>
|
||||||
|
[Column("CHANGED_WHO")]
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string? ChangedWho { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Modified at
|
||||||
|
/// </summary>
|
||||||
|
[Column("CHANGED_WHEN")]
|
||||||
|
public DateTime? ChangedWhen { get; set; }
|
||||||
|
|
||||||
|
// Navigation properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Associated Profile
|
||||||
|
/// </summary>
|
||||||
|
public virtual Profile Profile { get; set; } = null!;
|
||||||
|
}
|
||||||
|
}
|
||||||
111
ECMJobRunner.Domain/Entities/ProfileSqlJob.cs
Normal file
111
ECMJobRunner.Domain/Entities/ProfileSqlJob.cs
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace ECMJobRunner.Domain.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// SQL Job Configuration for Profile
|
||||||
|
/// Represents individual SQL jobs within a job runner profile
|
||||||
|
/// </summary>
|
||||||
|
[Table("TBJR_CFG_PROFILE_SQLJOB", Schema = "dbo")]
|
||||||
|
public class ProfileSqlJob
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Primary Key
|
||||||
|
/// </summary>
|
||||||
|
[Key]
|
||||||
|
[Column("PK_TBJR_CFG_PROFILE_SQLJOB_ID")]
|
||||||
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Foreign Key to Profile
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("FK_TBJR_CFG_PROFILE_ID")]
|
||||||
|
[ForeignKey(nameof(Profile))]
|
||||||
|
public long ProfileId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Active / Inactive switch
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("ACTIVE")]
|
||||||
|
public bool Active { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sequence order within the profile
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("SEQUENCE")]
|
||||||
|
public short Sequence { get; set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Optional name
|
||||||
|
/// </summary>
|
||||||
|
[Column("NAME")]
|
||||||
|
[MaxLength(150)]
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SQL Check Query
|
||||||
|
/// </summary>
|
||||||
|
[Column("SQL_CHECK_QUERY")]
|
||||||
|
public string? SqlCheckQuery { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SQL Main Query
|
||||||
|
/// </summary>
|
||||||
|
[Column("SQL_MAIN_QUERY")]
|
||||||
|
public string? SqlMainQuery { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// API Command
|
||||||
|
/// </summary>
|
||||||
|
[Column("API_COMMAND")]
|
||||||
|
public string? ApiCommand { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Optional description
|
||||||
|
/// </summary>
|
||||||
|
[Column("COMMENT")]
|
||||||
|
[MaxLength(500)]
|
||||||
|
public string? Comment { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Created by
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("ADDED_WHO")]
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string AddedWho { get; set; } = "DEFAULT";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Created at
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Column("ADDED_WHEN")]
|
||||||
|
public DateTime AddedWhen { get; set; } = DateTime.Now;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Modified by
|
||||||
|
/// </summary>
|
||||||
|
[Column("CHANGED_WHO")]
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string? ChangedWho { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Modified at
|
||||||
|
/// </summary>
|
||||||
|
[Column("CHANGED_WHEN")]
|
||||||
|
public DateTime? ChangedWhen { get; set; }
|
||||||
|
|
||||||
|
// Navigation properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Associated Profile
|
||||||
|
/// </summary>
|
||||||
|
public virtual Profile Profile { get; set; } = null!;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user