using Dapper; using KArtSell.BuildingBlocks.Data; using KArtSell.BuildingBlocks.Versioning; using KArtSell.Modules.ModelOperations.Application; namespace KArtSell.Modules.ModelOperations.Infrastructure; public sealed class DapperApprovedModelContextReader(IDbConnectionFactory connectionFactory) : IApprovedModelContextReader { private const string Sql = """ select mv.scope_key as ScopeKey, mv.model_version as ModelVersion, mv.config_version as ConfigVersion, mv.code_sha as CodeSha, mv.contract_version as ContractVersion, mv.lifecycle_state as LifecycleState, mv.effective_at as EffectiveAt, dm.dataset_id as DatasetId, dm.content_hash as DataHash from governance.model_version_registry mv join lateral ( select dataset_id, content_hash from evaluation.dataset_manifest where scope_key = mv.scope_key and status = 'APPROVED' and frozen_at <= @AsOf order by frozen_at desc limit 1 ) dm on true where mv.scope_key = @ScopeKey and mv.lifecycle_state in ('RESEARCH', 'CHALLENGER', 'SHADOW', 'CANDIDATE', 'APPROVED') and mv.effective_at <= @AsOf order by mv.effective_at desc limit 1; """; public async Task ReadAsync( string scopeKey, DateTimeOffset asOf, CancellationToken cancellationToken) { await using var connection = await connectionFactory.OpenAsync(cancellationToken); var row = await connection.QuerySingleOrDefaultAsync(new CommandDefinition( Sql, new { ScopeKey = scopeKey, AsOf = asOf }, cancellationToken: cancellationToken)); if (row is null) return null; return new ApprovedModelContext( row.ScopeKey, new VersionSet(row.DatasetId, row.DataHash, row.ModelVersion, row.ConfigVersion, row.CodeSha, row.ContractVersion), row.LifecycleState, row.EffectiveAt); } private sealed record Row( string ScopeKey, string DatasetId, string DataHash, string ModelVersion, string ConfigVersion, string CodeSha, string ContractVersion, string LifecycleState, DateTimeOffset EffectiveAt); }