Commit Graph

57 Commits

Author SHA1 Message Date
cba1aa85d0 feat: Add root path redirect to Hangfire dashboard
- Map root path (/) to redirect to /hangfire dashboard
- Improves user experience by providing direct access to main dashboard
- Users accessing the application root will be automatically redirected to Hangfire
2026-07-13 09:51:53 +02:00
def4d7b7c7 refactor: Move log directory configuration to Application section
- Move LogDirectory from Logging section to Application section in appsettings.json
- Update Program.cs to read from Application:LogDirectory instead of Logging:LogDirectory
- Fix JSON schema validation warning for non-standard Logging properties
- Application section now holds custom application-specific settings
- Standard Logging and Serilog sections remain clean and schema-compliant
2026-07-13 09:51:01 +02:00
d61d14145a feat: Add Serilog SQLite sink and Serilog.UI dashboard with centralized log directory configuration
- Add Serilog.Sinks.SQLite v7.0.0 for structured logging to SQLite database
- Add Serilog.UI v3.2.0 and Serilog.UI.SqliteProvider v1.1.0 for web-based log viewer
- Add Serilog.Settings.Configuration v10.0.1 for configuration support
- Configure SQLite log storage at E:\LogFiles\Digital Data\ECMJobRunner.WebCron\logs.db
- Add Serilog.UI dashboard at /serilog-ui endpoint
- Centralize log directory configuration in appsettings.json (Logging:LogDirectory)
- Configure Serilog programmatically with Console and SQLite sinks
- Remove deprecated Serilog configuration from appsettings files (now using code-based config)
- Enable Serilog self-diagnostics for troubleshooting
- Both Serilog sink and Serilog.UI use same SQLite database path from configuration
2026-07-12 17:33:19 +02:00
8b0f97c330 feat: Add Hangfire cronjob system with web dashboard, Windows Service support, and Serilog file/console logging
- Add Hangfire packages (AspNetCore, Core, InMemory, SqlServer) with configurable storage (InMemory vs SQL Server)
- Configure Hangfire dashboard at /hangfire with AllowAllDashboardAuthorizationFilter (no auth for development)
- Add Microsoft.Extensions.Hosting.WindowsServices package with conditional UseWindowsService() based on HostingOptions:UseWindowsService config
- Create ProfileManager BackgroundService with IServiceScopeFactory for scoped service resolution per iteration
- Create AllowAllDashboardAuthorizationFilter for Hangfire dashboard access
- Create DtoExtensions with JobId() and ToJob() helper methods
- Configure Serilog with file sink (Production: Logs/log-.txt, daily rolling, 30 day retention) and console sink (Development)
- Add Serilog enrichers: FromLogContext, WithMachineName, WithThreadId
- Update appsettings.json with Hangfire:InMemory flag, HostingOptions:UseWindowsService flag, and Serilog configuration
- Create appsettings.Development.json with console-specific Serilog configuration
2026-07-12 04:49:22 +02:00
d50232b0bb feat: Add Windows Service hosting support
- Add Microsoft.Extensions.Hosting.WindowsServices package
- Add HostingOptions:UseWindowsService configuration flag to appsettings.json
- Configure Program.cs to optionally run as Windows Service based on config
- IIS hosting continues to work by default (UseWindowsService=false)
- Delete obsolete Worker.cs that was conflicting with ProfileManager
2026-07-12 00:23:59 +02:00
59bef13f5d fix: Resolve scoped service dependency issue in ProfileManager
- Replace IMediator constructor injection with IServiceScopeFactory
- Create new scope in ExecuteAsync loop to resolve scoped services (ISQLExecutor)
- Fixes: Cannot resolve scoped service from root provider error
- Enables ProfileManager to properly execute MediatR queries with scoped dependencies
2026-07-12 00:22:33 +02:00
475679c6e2 feat: Update Infrastructure DependencyInjection
- Update Infrastructure layer service registrations for Hangfire compatibility
2026-07-12 00:04:51 +02:00
3a1e16a7a0 feat: Update Application layer for Hangfire integration
- Add CronSchedule property to CfgProfileDto for scheduling support
- Create ProfileSqlJobDto for SQL job execution data transfer
- Update TriggeringDEXJobBatchCommand to accept ProfileId and Jobs collection
- Make TriggeringDEXJobBatchCommand public for Hangfire job activation
- Update Application DependencyInjection with required service registrations
2026-07-12 00:04:40 +02:00
7efc77ca51 feat: Add AllowAllDashboardAuthorizationFilter for development
- Create authorization filter to bypass Hangfire dashboard authentication
- Allow unrestricted access to /hangfire dashboard for local development
- Note: Should be replaced with proper authentication in production
2026-07-12 00:04:25 +02:00
ad2ab741ff feat: Add ProfileManager for automatic Hangfire job scheduling
- Create ProfileManager background service that polls database every 1 second
- Query active profiles with cron schedules via MediatR GetProfileQuery
- Auto-create/update Hangfire recurring jobs using IRecurringJobManager
- Jobs execute TriggeringDEXJobBatchCommand via IMediator dependency injection
- Add profile caching with schedule change detection to avoid redundant updates
- Create DtoExtensions with JobId() and ToJob() helper methods for profile-to-command conversion
2026-07-12 00:04:13 +02:00
eb7adc741a feat: Add Hangfire infrastructure with dynamic storage configuration
- Install Hangfire packages (Core, AspNetCore, SqlServer, InMemory)
- Configure Hangfire in Program.cs with boolean InMemory flag from appsettings
- Add Hangfire dashboard at /hangfire route
- Update appsettings.json with Hangfire:InMemory configuration
- Update launchSettings.json with new launch URL
- Remove obsolete Worker.cs background service
2026-07-12 00:04:00 +02:00
8255f1f6aa feat(application): add inactive profile validation with custom exception
- Create InactiveProfileException for profile active status validation
- Update TriggeringDEXJobBatchCommand to check profile active status before execution
- Add ICfgProfileRepository dependency to batch command handler
- Throw InactiveProfileException when attempting to execute inactive profiles
- Add profile not found validation with descriptive error message
- Reorganize commands under DEXJob/Commands directory structure
2026-07-11 19:16:35 +02:00
eaf24e05ee refactor(application): consolidate query architecture with AutoMapper integration
- Add AutoMapper profile for CfgProfile and ProfileSqlJob entity-to-DTO mappings
- Consolidate GetProfileByIdQuery and GetAllActiveProfilesQuery into unified GetProfileQuery
- Implement flexible filtering with nullable query options (Id, Active, TypeId, ProfileName)
- Add IncludeSqlJobs option for optimized SQL job loading
- Move CfgProfileDto to Common/Dtos for better architecture alignment
- Add comprehensive unit tests for GetProfileQuery with multiple filter scenarios
- Move ISQLExecutor interface from Domain to Application layer
- Add GetByIdWithSqlJobsAsync and GetAllActiveWithSqlJobsAsync to repository
2026-07-11 19:14:51 +02:00
3f924b75b0 chore(application): remove old ISQLExecutor interface location
- Delete ECMJobRunner.Application/Common/Interfaces/ISQLExecutor.cs
- Interface moved to ECMJobRunner.Domain/Interfaces/ (committed in 26ea1db)
2026-07-11 16:45:15 +02:00
52c0614975 test(application): add comprehensive unit tests for DEX job pipeline
- Add TriggeringDEXJobBatchCommandTests
  - Test batch command execution with multiple profiles
  - Verify batch ID generation and propagation
  - Mock ISQLExecutor and IRecClient dependencies
- Add MainQueryExecutionBehaviorTests
  - Test main query execution success path
  - Test SQL exception handling (JobSqlException)
  - Verify MainQueryResults population
- Add CheckQueryExecutionBehaviorTests
  - Test check query validation (ErrorAction.SkipInsert)
  - Test skip behavior for zero results
  - Test SQL exception handling
- All tests pass on both net480 and net8.0 frameworks
- Update ECM.JobRunner.sln with test project reference
- Upgrade Microsoft.Extensions.DependencyInjection to 8.0.1 (ReC.Client requirement)
2026-07-11 16:44:53 +02:00
5d2f128cc7 feat(application): add dependency injection configuration & documentation
- Implement DependencyInjection.cs with AddApplication() extension
  - Register MediatR with assembly scanning
  - Register pipeline behaviors in execution order:
    1. CheckQueryExecutionBehavior
    2. MainQueryExecutionBehavior
    3. ReCRequestExecutionBehavior
  - Conditional package versions (MediatR 9.0.0/12.4.1)
- Add comprehensive README.md
  - Architecture overview & CQRS pipeline flow
  - Configuration guide (DexJobOptions, ErrorAction)
  - DI setup examples (AddApplication, AddInfrastructure)
  - Exception handling patterns
  - Multi-targeting notes & troubleshooting
- Update project file with MediatR.Extensions.DependencyInjection
2026-07-11 16:44:39 +02:00
63a16410ea feat(application): implement MediatR pipeline behaviors for DEX job stages
- Add MainQueryExecutionBehavior
  - Execute main SQL query via ISQLExecutor
  - Populate command.MainQueryResults
  - Throw JobSqlException on failure
- Add CheckQueryExecutionBehavior
  - Execute check SQL query via ISQLExecutor
  - Validate ErrorAction.SkipInsert for zero results
  - Throw JobSqlException on failure/validation error
- Add ReCRequestExecutionBehavior
  - Execute ReC API requests for each main query result
  - Batch ID tracking, error handling
  - Throw JobHttpException on API failures
- Conditional compilation for MediatR signature differences
  - net480: Handle(request, cancellationToken, next)
  - net8.0: Handle(request, next, cancellationToken)
- Refactor TriggeringDEXJobCommand handler: delegate all logic to behaviors
2026-07-11 16:44:25 +02:00
222a5e24bf refactor(application): redesign exception hierarchy with flexible base class
- Replace DEXJobException with JobException base class
  - Flexible params-based detail collection
  - Automatic message formatting with visual separators
  - Optional null-handling for contextual details
- Add JobHttpException for HTTP client failures
  - Properties: ClientLibrary, ClientMethod
  - Use case: ReC API, REST requests
- Add JobSqlException for SQL query failures
  - Property: Query (virtual for customization)
  - Use case: Main/Check query execution
- Comprehensive XML documentation for all exception classes
2026-07-11 16:44:10 +02:00
26ea1db09f feat(infrastructure): implement ISQLExecutor with EF6/EF Core support
- Move ISQLExecutor interface from Application to Domain layer
  - Follow Clean Architecture: Infrastructure references Domain, not Application
  - Namespace: ECMJobRunner.Domain.Interfaces
- Implement SQLExecutor service with conditional compilation
  - EF6 (net480): Database.SqlQuery<T>()
  - EF Core (net8.0): Database.SqlQueryRaw<T>()
- Register ISQLExecutor in DI (AddInfrastructure, AddInfrastructureInMemory)
  - Scoped lifetime (aligns with DbContext)
2026-07-11 16:43:57 +02:00
4767bcfbe1 Add .NET 8.0 web app with minimal API and background worker
Introduced a new .NET 8.0 web application project with a minimal API setup.
Configured Swagger for API documentation and added a `Worker` class as a
background service for periodic tasks.

Added `launchSettings.json` to define development profiles for HTTP, HTTPS,
and IIS Express. Configured logging levels in `appsettings.json` and
`appsettings.Development.json`.

Included `Swashbuckle.AspNetCore` package for Swagger integration and
configured the HTTP request pipeline to support development and production
environments.
2026-07-11 12:56:58 +02:00
2af17ec870 feat: implement DEX job triggering commands with CQRS pattern
TriggeringDEXJobBatchCommand:
- Orchestrates batch job execution for a profile
- Creates unique 20-character timestamp-based batch ID
- Executes all SQL jobs sequentially for given profile ID
- Uses MediatR ISender to trigger individual job commands

TriggeringDEXJobCommand:
- Executes single DEX job with three-stage pipeline:
  1. Main Query: executes primary SQL with batch ID placeholder replacement
  2. Check Query: validates execution with return value check (> 0)
  3. ReC Request: invokes ReC API with batch ID reference
- Configurable error handling per stage via DexJobOptions
- Regex-based placeholder replacement for dynamic batch ID injection
- Returns Unit for void-like MediatR command pattern

Both commands include:
- Comprehensive XML documentation
- Primary constructor injection (modern C# syntax)
- Proper async/await with CancellationToken support
- Integration with ISQLExecutor and ReCClient abstractions
2026-07-11 12:38:42 +02:00
8a1a579501 feat: add DEX job exception handling and configuration
Exceptions:
- DEXJobException: custom exception with formatted error messages
  * Includes query name, batch ID, SQL query, and detailed error info
  * Two constructors: with inner exception or reason message
  * Comprehensive XML documentation

Options:
- DexJobOptions: hierarchical configuration for DEX job execution
  * Error handling per stage (MainQuery, CheckQuery, ReCRequest)
  * Granular error actions (OnExecution, IfNullOrWhiteSpace, OnUnexpectedResult)
  * Placeholder configuration with regex pattern support
  * Default BatchId placeholder: #INT#BATCH_ID (case-insensitive)
  * Fully documented with XML comments
2026-07-11 12:38:31 +02:00
7e267b427e feat: add DEX job common infrastructure
Add foundational types for DEX job execution:

Constants:
- ErrorAction enum (Ignore, Stop) for error handling strategy

DTOs:
- CheckQueryResult: check query execution result with ReturnValue
- MainQueryResult: main query execution result with ReturnValue

Interfaces:
- ISQLExecutor: abstraction for SQL query execution and DTO mapping

All types include comprehensive XML documentation
2026-07-11 12:38:21 +02:00
30a2a4ce3b build: add ReC.Client package reference
- Add ReC.Client v2.0.0-beta for DEX job HTTP request integration
2026-07-11 12:38:13 +02:00
46ad02f624 refactor: remove legacy projects from solution
- Remove ECM.JobRunner.Web project
- Remove ECM.JobRunner.Common (VB.NET) project
- Remove ECM.JobRunner.Windows (VB.NET) project
- Clean Architecture implementation focus
2026-07-11 12:38:06 +02:00
ee3af3e462 Add test infrastructure and repository tests
Introduced `CfgProfileDto` for testing and added a `FakeDataGenerator` utility for generating test data. Updated `ECMJobRunner.Tests.csproj` to support both `.NET Framework 4.8` and `.NET 8.0`, enabling nullable reference types and adding dependencies for testing frameworks, DI, and AutoMapper.

Added `TestFixture` to set up dependency injection and in-memory databases for tests. Created `TestMappingProfile` for AutoMapper configurations. Implemented `CfgProfileRepositoryTests` to validate repository methods, including `GetByIdAsync`, `GetAllAsync`, `AddAsync`, and `FindAsync`.

Enhanced test maintainability with `FluentAssertions` and realistic data generation using `Bogus`.
2026-07-09 16:09:19 +02:00
bd6c1c1309 Update AutoMapper versions and suppress NU1903 warning
- Suppressed AutoMapper vulnerability warning (NU1903) as acceptable.
- Updated comments for AutoMapper references to clarify alignment with Infrastructure.
- Added `AutoMapper.Extensions.Microsoft.DependencyInjection`:
  - Version 8.1.1 for .NET Framework 4.8.
  - Version 12.0.1 for .NET 8.
- Downgraded AutoMapper for .NET 8 from 13.0.1 to 12.0.1.
2026-07-09 15:58:52 +02:00
9bae0ab95c Refactor Repository and update project dependencies
Added `SaveChangesAsync` to `IRepository` for async persistence.
Introduced AutoMapper and DbContext dependencies in `Repository`.
Simplified EF Core operations by removing `#if NET48` logic.
Replaced `Task.Run` with direct EF Core calls for .NET Framework.
Updated AutoMapper version for .NET 8 and added EF Core testing.
Suppressed AutoMapper vulnerability warning in project file.
Performed general cleanup and improved maintainability.
2026-07-09 15:58:33 +02:00
574e5ed209 Add in-memory DB support for .NET 4.8 and .NET 8 testing
Introduced a `DbConnection` constructor in `JobRunnerDbContext`
for Entity Framework 6 to enable in-memory testing with the
Effort library. Added conditional compilation to support both
.NET Framework 4.8 and .NET 8.

Implemented `AddInfrastructureInMemory` in `DependencyExtension`
to register services with in-memory databases:
- For .NET 4.8, uses Effort's transient connection.
- For .NET 8, uses EF Core's in-memory provider.

Registered AutoMapper in both methods for object mapping. Added
`EntityMappingProfile` to define AutoMapper configurations,
enforcing explicit DTO-to-entity mappings. These changes improve
testability and maintainability across .NET versions.
2026-07-09 15:45:18 +02:00
5eca5f1d4b Remove SaveChangesAsync from IRepository interface
The `SaveChangesAsync` method was removed from the `IRepository`
interface in the `ECMJobRunner.Domain.Interfaces` namespace.
This method previously allowed saving all changes asynchronously
with an optional `CancellationToken` parameter.
2026-07-09 15:44:40 +02:00
65a51482dd Add ECMJobRunner.Tests and enhance DI for multi-frameworks
Added a new `ECMJobRunner.Tests` project to the solution for unit
testing, including build configurations for Debug and Release.

Enhanced the `DependencyExtension` class to support dependency
injection for both .NET Framework 4.8 (EF6) and .NET 8 (EF Core)
using conditional compilation. Registered `JobRunnerDbContext`
differently based on the target framework and added AutoMapper
registration for both frameworks.

Updated `ECMJobRunner.Infrastructure.csproj` to include new
package references for DI and AutoMapper in .NET Framework 4.8.
Improved code structure and readability by removing redundant
directives and aligning DI patterns across frameworks.
2026-07-09 13:48:55 +02:00
eb9c5c323a Update AGENTS.md and csproj for ECMJobRunner.Application
Added detailed documentation to AGENTS.md, including project overview, architecture, components, and usage examples for the ECMJobRunner.Application layer. Documented target frameworks (.NET Framework 4.8 and .NET 8.0) and their dependencies (AutoMapper and MediatR).

Updated ECMJobRunner.Application.csproj:
- Changed `<Product>` tag to reflect the correct project name.
- Added a project reference to ECMJobRunner.Domain.
- Introduced conditional NuGet package references for framework-specific dependencies.
2026-07-09 13:35:24 +02:00
7d53b599de Add Infrastructure layer with EF6/EF Core support
Introduced a robust Infrastructure layer for the ECMJobRunner system:
- Added `AGENTS.md` with detailed project documentation.
- Implemented generic repository and unit-of-work patterns.
- Added `CfgProfileRepository`, `ProfileSqlJobRepository`, and `ProfileHistoryRepository`.
- Integrated AutoMapper for DTO-to-entity mapping.
- Added multi-framework support for .NET Framework 4.8 (EF6) and .NET 8.0 (EF Core) using conditional compilation.
- Updated `ECMJobRunner.Infrastructure.csproj` with metadata fixes and dependencies.
- Introduced dependency injection extension for .NET 8.0.
- Enhanced project structure and database context with entity mappings.
2026-07-09 13:35:02 +02:00
ff6faa1e5b Add JobRunnerDbContext with multi-framework support
Introduce `JobRunnerDbContext` to support both EF6 (.NET 4.8)
and EF Core (.NET 8) using conditional compilation. Add `DbSet`
properties for `CfgProfiles`, `ProfileSqlJobs`, and
`ProfileHistories`. Provide constructors for both frameworks
to handle connection strings or options. Ensure compatibility
with multiple runtime environments.
2026-07-09 13:34:03 +02:00
3e007ccfeb Refactor domain layer to follow Clean Architecture
Updated the domain layer to align with Clean Architecture principles:
- Removed Entity Framework dependencies from the project.
- Updated AGENTS.md to document the new architecture.
- Introduced repository interfaces for data access abstraction.
- Added a generic IRepository interface for CRUD operations.
- Implemented entity-specific repositories for Profile, ProfileSqlJob, and ProfileHistory.
- Ensured the domain layer is infrastructure-independent with pure POCOs.
- Updated project structure and documentation for clarity.
2026-07-09 13:33:39 +02:00
ce47653831 Refactor Profile entity and update property constraints
Renamed `Profile` to `CfgProfile` across the codebase for clarity and consistency. Updated property constraints in `CfgProfile.cs`, `ProfileHistory.cs`, and `ProfileSqlJob.cs` to include maximum length validations. Changed navigation properties in `CfgProfile.cs` to use `IEnumerable` and made them nullable. Updated `ForeignKey` attributes in `ProfileHistory.cs` and `ProfileSqlJob.cs` to reference `CfgProfile`. Improved property descriptions for better documentation.
2026-07-09 13:23:46 +02:00
be8e58df84 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.
2026-07-09 12:45:09 +02:00
26dc58d82e Add Application and Infrastructure projects to solution
Two new projects, `ECMJobRunner.Application` and
`ECMJobRunner.Infrastructure`, were added to the solution file
(`ECM.JobRunner.sln`). Build configurations for these projects
were also added.

`ECMJobRunner.Application.csproj` targets both .NET Framework 4.8
and .NET 8.0, with properties such as `LangVersion`, `Nullable`,
and `PackageId` defined.

`ECMJobRunner.Infrastructure.csproj` also targets .NET Framework
4.8 and .NET 8.0. It includes conditional dependencies:
- For `net480`, it references `EntityFramework` 6.5.1.
- For `net8.0`, it references `Microsoft.EntityFrameworkCore`
  and related packages (version 8.0.11).
2026-07-09 11:48:10 +02:00
19c415da01 Add ECMJobRunner.Domain project to solution
A new project, `ECMJobRunner.Domain`, has been added to the solution file (`ECM.JobRunner.sln`). The project targets both .NET Framework 4.8 (`net480`) and .NET 8.0 (`net8.0`) and includes metadata for NuGet packaging, such as `PackageId`, `Authors`, and `RepositoryUrl`.

Build configurations for `Debug|Any CPU` and `Release|Any CPU` have been added to the solution configuration. The project file (`ECMJobRunner.Domain.csproj`) also specifies the generation of XML documentation files.
2026-07-09 10:52:57 +02:00
Jonathan Jenne
0b98902a7f 09-01-2023 2023-01-17 08:43:08 +01:00
Jonathan Jenne
7e7eee7299 23-12-2022 2022-12-23 13:27:30 +01:00
Jonathan Jenne
e3f271ac33 21-12-2022 2022-12-21 16:09:49 +01:00
Jonathan Jenne
6bca1f53f4 20-12-2022 2022-12-20 16:47:36 +01:00
Jonathan Jenne
1e925242bc 20-12-2022 2022-12-20 15:29:29 +01:00
Jonathan Jenne
3e2c4a9ab0 Fix URI Prefix error 2022-12-20 12:04:40 +01:00
Jonathan Jenne
343f47ca29 merge historyitem and statusitem 2022-12-20 12:00:15 +01:00
Jonathan Jenne
835467f0d7 remove history item 2022-12-20 11:57:31 +01:00
Jonathan Jenne
b1e95bc942 20-12-2022 2022-12-20 11:49:43 +01:00
Jonathan Jenne
45f8dd2aad 16-12-2022 2022-12-16 15:59:26 +01:00
Jonathan Jenne
63edd9e542 15-12-2022 ~ 2 2022-12-15 15:59:38 +01:00