using KArtSell.BuildingBlocks.Time; using KArtSell.Modules.ModelOperations.Domain; namespace KArtSell.Modules.ModelOperations.Application; public sealed class ModelOperationRequestService( IApprovedModelContextReader contextReader, IModelOperationRequestRepository repository, IClock clock) : IModelOperationRequestService { public async Task RequestAsync( Guid scheduleId, string operationCode, string scopeKey, string automationMode, string idempotencyKey, string correlationId, CancellationToken cancellationToken) { var definition = ModelOperationRegistry.GetRequired(operationCode); ModelOperationExecutionBoundary.EnsureAllowed(definition); if (!definition.AutomationMode.ToContractValue().Equals(automationMode, StringComparison.OrdinalIgnoreCase)) throw new InvalidOperationException("Schedule automation mode does not match the approved operation registry."); var now = clock.UtcNow; var context = await contextReader.ReadAsync(scopeKey, now, cancellationToken); if (context is null) return null; context.VersionSet.EnsureValid(); var request = new ModelOperationRequest( Guid.NewGuid(), scheduleId, definition.OperationCode, scopeKey, definition.AutomationMode.ToContractValue(), idempotencyKey, context, correlationId, now); return await repository.AddAsync(request, cancellationToken) ? request : null; } }