From be8e58df84f70e1236e5a3a57c339a8e7d342fe7 Mon Sep 17 00:00:00 2001 From: TekH Date: Thu, 9 Jul 2026 12:45:09 +0200 Subject: [PATCH] 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. --- ECMJobRunner.Domain/AGENTS.md | 142 ++++++++++++++++++ .../ECMJobRunner.Domain.csproj | 16 +- ECMJobRunner.Domain/Entities/Profile.cs | 101 +++++++++++++ .../Entities/ProfileHistory.cs | 80 ++++++++++ ECMJobRunner.Domain/Entities/ProfileSqlJob.cs | 111 ++++++++++++++ 5 files changed, 449 insertions(+), 1 deletion(-) create mode 100644 ECMJobRunner.Domain/AGENTS.md create mode 100644 ECMJobRunner.Domain/Entities/Profile.cs create mode 100644 ECMJobRunner.Domain/Entities/ProfileHistory.cs create mode 100644 ECMJobRunner.Domain/Entities/ProfileSqlJob.cs diff --git a/ECMJobRunner.Domain/AGENTS.md b/ECMJobRunner.Domain/AGENTS.md new file mode 100644 index 0000000..836f962 --- /dev/null +++ b/ECMJobRunner.Domain/AGENTS.md @@ -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 diff --git a/ECMJobRunner.Domain/ECMJobRunner.Domain.csproj b/ECMJobRunner.Domain/ECMJobRunner.Domain.csproj index 37684e6..2101351 100644 --- a/ECMJobRunner.Domain/ECMJobRunner.Domain.csproj +++ b/ECMJobRunner.Domain/ECMJobRunner.Domain.csproj @@ -2,6 +2,8 @@ net480;net8.0 + latest + enable bin\$(Configuration)\$(TargetFramework)\$(MSBuildProjectName).xml ECMJobRunner.Domain Digital Data GmbH @@ -9,7 +11,19 @@ ECMJobRunner.Domain Copyright 2026 http://git.dd:3000/AppStd/ECMJobRunner.git - digital data ecm job runner + digital data ecm job runner domain + + + + + + + + + + + + diff --git a/ECMJobRunner.Domain/Entities/Profile.cs b/ECMJobRunner.Domain/Entities/Profile.cs new file mode 100644 index 0000000..ee8f851 --- /dev/null +++ b/ECMJobRunner.Domain/Entities/Profile.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ECMJobRunner.Domain.Entities +{ + /// + /// Job Runner Configuration Profile Entity + /// Represents a job runner profile configuration + /// Type: 0 = ADSync; 1 = GraphQL; 2 = SQL-Job; 3 = SQL and REST-Job + /// + [Table("TBJR_CFG_PROFILE", Schema = "dbo")] + public class Profile + { + /// + /// Primary Key + /// + [Key] + [Column("PK_TBJR_CFG_PROFILE_ID")] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public long Id { get; set; } + + /// + /// Active / Inactive switch + /// + [Required] + [Column("ACTIVE")] + public bool Active { get; set; } = true; + + /// + /// Optional profile name + /// + [Required] + [Column("PROFILE_NAME")] + [MaxLength(150)] + public string ProfileName { get; set; } = null!; + + /// + /// Profile type: 0 = ADSync; 1 = GraphQL; 2 = SQL-Job; 3 = SQL and REST-Job + /// + [Required] + [Column("TYPE_ID")] + public byte TypeId { get; set; } + + /// + /// Schedule in Cron format + /// + [Required] + [Column("SCHEDULE")] + [MaxLength(150)] + public string Schedule { get; set; } = "0 30 4 ? * MON-SAT"; + + /// + /// Optional description + /// + [Column("COMMENT")] + [MaxLength(500)] + public string? Comment { get; set; } + + /// + /// Created by + /// + [Required] + [Column("ADDED_WHO")] + [MaxLength(50)] + public string AddedWho { get; set; } = "DEFAULT"; + + /// + /// Created at + /// + [Required] + [Column("ADDED_WHEN")] + public DateTime AddedWhen { get; set; } = DateTime.Now; + + /// + /// Modified by + /// + [Column("CHANGED_WHO")] + [MaxLength(50)] + public string? ChangedWho { get; set; } + + /// + /// Modified at + /// + [Column("CHANGED_WHEN")] + public DateTime? ChangedWhen { get; set; } + + // Navigation properties + + /// + /// SQL Jobs associated with this profile + /// + public virtual ICollection SqlJobs { get; set; } = new List(); + + /// + /// Profile execution history + /// + public virtual ICollection ProfileHistories { get; set; } = new List(); + } +} diff --git a/ECMJobRunner.Domain/Entities/ProfileHistory.cs b/ECMJobRunner.Domain/Entities/ProfileHistory.cs new file mode 100644 index 0000000..ca8acdc --- /dev/null +++ b/ECMJobRunner.Domain/Entities/ProfileHistory.cs @@ -0,0 +1,80 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ECMJobRunner.Domain.Entities +{ + /// + /// Profile Execution History + /// Stores the execution history and results of job runner profiles + /// Result ID: 0 = OK; 1 = ERROR; 2 = WARNING + /// + [Table("TBJR_OUT_PROFILE_HISTORY", Schema = "dbo")] + public class ProfileHistory + { + /// + /// Primary Key + /// + [Key] + [Column("PK_TBJR_OUT_PROFILE_HISTORY_ID")] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public long Id { get; set; } + + /// + /// Foreign Key to Profile + /// + [Required] + [Column("FK_TBJR_CFG_PROFILE_ID")] + [ForeignKey(nameof(Profile))] + public long ProfileId { get; set; } + + /// + /// Result ID: 0 = OK; 1 = ERROR; 2 = WARNING + /// + [Required] + [Column("RESULT_ID")] + public byte ResultId { get; set; } + + /// + /// Result text/message + /// + [Required] + [Column("RESULT_TEXT")] + public string ResultText { get; set; } = string.Empty; + + /// + /// Created by + /// + [Required] + [Column("ADDED_WHO")] + [MaxLength(50)] + public string AddedWho { get; set; } = "DEFAULT"; + + /// + /// Created at + /// + [Required] + [Column("ADDED_WHEN")] + public DateTime AddedWhen { get; set; } = DateTime.Now; + + /// + /// Modified by + /// + [Column("CHANGED_WHO")] + [MaxLength(50)] + public string? ChangedWho { get; set; } + + /// + /// Modified at + /// + [Column("CHANGED_WHEN")] + public DateTime? ChangedWhen { get; set; } + + // Navigation properties + + /// + /// Associated Profile + /// + public virtual Profile Profile { get; set; } = null!; + } +} diff --git a/ECMJobRunner.Domain/Entities/ProfileSqlJob.cs b/ECMJobRunner.Domain/Entities/ProfileSqlJob.cs new file mode 100644 index 0000000..bc167b4 --- /dev/null +++ b/ECMJobRunner.Domain/Entities/ProfileSqlJob.cs @@ -0,0 +1,111 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ECMJobRunner.Domain.Entities +{ + /// + /// SQL Job Configuration for Profile + /// Represents individual SQL jobs within a job runner profile + /// + [Table("TBJR_CFG_PROFILE_SQLJOB", Schema = "dbo")] + public class ProfileSqlJob + { + /// + /// Primary Key + /// + [Key] + [Column("PK_TBJR_CFG_PROFILE_SQLJOB_ID")] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public long Id { get; set; } + + /// + /// Foreign Key to Profile + /// + [Required] + [Column("FK_TBJR_CFG_PROFILE_ID")] + [ForeignKey(nameof(Profile))] + public long ProfileId { get; set; } + + /// + /// Active / Inactive switch + /// + [Required] + [Column("ACTIVE")] + public bool Active { get; set; } = true; + + /// + /// Sequence order within the profile + /// + [Required] + [Column("SEQUENCE")] + public short Sequence { get; set; } = 0; + + /// + /// Optional name + /// + [Column("NAME")] + [MaxLength(150)] + public string? Name { get; set; } + + /// + /// SQL Check Query + /// + [Column("SQL_CHECK_QUERY")] + public string? SqlCheckQuery { get; set; } + + /// + /// SQL Main Query + /// + [Column("SQL_MAIN_QUERY")] + public string? SqlMainQuery { get; set; } + + /// + /// API Command + /// + [Column("API_COMMAND")] + public string? ApiCommand { get; set; } + + /// + /// Optional description + /// + [Column("COMMENT")] + [MaxLength(500)] + public string? Comment { get; set; } + + /// + /// Created by + /// + [Required] + [Column("ADDED_WHO")] + [MaxLength(50)] + public string AddedWho { get; set; } = "DEFAULT"; + + /// + /// Created at + /// + [Required] + [Column("ADDED_WHEN")] + public DateTime AddedWhen { get; set; } = DateTime.Now; + + /// + /// Modified by + /// + [Column("CHANGED_WHO")] + [MaxLength(50)] + public string? ChangedWho { get; set; } + + /// + /// Modified at + /// + [Column("CHANGED_WHEN")] + public DateTime? ChangedWhen { get; set; } + + // Navigation properties + + /// + /// Associated Profile + /// + public virtual Profile Profile { get; set; } = null!; + } +}