using Tiku.Domain.Learning; namespace Tiku.Application.Learning; public sealed record LearningAccessSnapshot( Guid TenantId, Guid UserId, Guid BusinessLineId, LearningRegionAccessStrategy RegionAccessStrategy, IReadOnlySet LicensedRegionIds, Guid? TargetRegionId, IReadOnlySet ContentSliceIds, IReadOnlySet ClassAssignmentIds, long GrantVersion, long ContentVersion, long StrongRevocationVersion, DateTimeOffset ValidUntil, DateTimeOffset GeneratedAt); public sealed record LearningResourceAccessDecision( Guid ContentSliceId, PracticeAccessMode AccessMode, Guid? EntitlementId, Guid? ClassAssignmentId, LearningAccessSnapshot Snapshot); public interface ILearningAccessService { Task GetSnapshotAsync( LearningActor actor, CancellationToken cancellationToken = default); Task EnsureResourceAccessAsync( LearningActor actor, LearningContentResourceType resourceType, Guid resourceId, CancellationToken cancellationToken = default); Task EnsureStrongRevocationVersionAsync( LearningActor actor, long expectedVersion, CancellationToken cancellationToken = default); Task InvalidateAsync(Guid tenantId, Guid userId, CancellationToken cancellationToken = default); } public sealed class LearningAccessException(string code, string message) : LearningException(code, message);