namespace Tiku.Application.Security; public enum FeatureAccessOperation { Read, Write } public sealed record FeatureAccessDecision( bool Allowed, string? DenialCode, string FeatureCode, FeatureAccessOperation Operation); public sealed record FeatureQuotaSnapshot( string MetricCode, long UsedValue, long LimitValue, int UsedPercent, bool Warning, bool Exceeded, DateTimeOffset PeriodStart, DateTimeOffset PeriodEnd); public interface IFeatureAccessService { Task EvaluateAsync( Guid tenantId, string featureCode, FeatureAccessOperation operation, CancellationToken cancellationToken = default); Task> GetEnabledFeaturesAsync( Guid tenantId, FeatureAccessOperation operation = FeatureAccessOperation.Read, CancellationToken cancellationToken = default); Task> FilterPermissionCodesAsync( Guid tenantId, IEnumerable permissionCodes, FeatureAccessOperation operation = FeatureAccessOperation.Read, CancellationToken cancellationToken = default); Task> GetQuotaSummaryAsync( Guid tenantId, CancellationToken cancellationToken = default); Task TryConsumeQuotaAsync( Guid tenantId, string metricCode, long amount, CancellationToken cancellationToken = default); Task ReleaseQuotaAsync( Guid tenantId, string metricCode, long amount, CancellationToken cancellationToken = default); } public sealed class FeatureAccessException(string message, string code) : Exception(message) { public string Code { get; } = code; }