Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 34 additions & 33 deletions src/SharedKernel/SharedKernel.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<PackageReadmeFile>Readme.md</PackageReadmeFile>
<Authors>Pandatech</Authors>
<Copyright>MIT</Copyright>
<Version>1.8.2</Version>
<Version>1.8.3</Version>
<PackageId>Pandatech.SharedKernel</PackageId>
<Title>Pandatech Shared Kernel Library</Title>
<PackageTags>Pandatech, shared kernel, library, OpenAPI, Swagger, utilities, scalar</PackageTags>
Expand All @@ -18,46 +18,47 @@
</PropertyGroup>

<ItemGroup>
<None Include="..\..\pandatech.png" Pack="true" PackagePath="\"/>
<None Include="..\..\Readme.md" Pack="true" PackagePath="\"/>
<None Include="..\..\pandatech.png" Pack="true" PackagePath="\" />
<None Include="..\..\Readme.md" Pack="true" PackagePath="\" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="OpenApi\UiAssets\**\*"/>
<EmbeddedResource Include="OpenApi\UiAssets\**\*" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.Prometheus.Metrics" Version="9.0.0"/>
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="9.0.0"/>
<PackageReference Include="Elastic.CommonSchema.Serilog" Version="9.0.0"/>
<PackageReference Include="FluentDateTime" Version="3.0.0"/>
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.0.0"/>
<PackageReference Include="HtmlSanitizer" Version="9.0.886"/>
<PackageReference Include="MediatR" Version="[12.5.0]"/>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.8"/>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.8"/>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="9.0.8"/>
<PackageReference Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="9.0.8"/>
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="9.8.0"/>
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.12.0"/>
<PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.8.0-rc.1"/>
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.12.0"/>
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.12.0"/>
<PackageReference Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.0.0-beta.12"/>
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.12.0"/>
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.12.0"/>
<PackageReference Include="AspNetCore.HealthChecks.Prometheus.Metrics" Version="9.0.0" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="9.0.0" />
<PackageReference Include="Elastic.CommonSchema.Serilog" Version="9.0.0" />
<PackageReference Include="FluentDateTime" Version="3.0.0" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.0.0" />
<PackageReference Include="HtmlSanitizer" Version="9.0.886" />
<PackageReference Include="MediatR" Version="[12.5.0]" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.8" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.8" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="9.0.8" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="9.0.8" />
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="9.8.0" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.8.0-rc.1" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.0.0-beta.12" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.12.0" />
<PackageReference Include="Pandatech.CommissionCalculator" Version="4.0.1" />
<PackageReference Include="Pandatech.Crypto" Version="6.1.1" />
<PackageReference Include="Pandatech.DistributedCache" Version="4.0.9"/>
<PackageReference Include="PandaTech.FileExporter" Version="4.1.2"/>
<PackageReference Include="PandaTech.FluentImporter" Version="3.0.9"/>
<PackageReference Include="Pandatech.FluentMinimalApiMapper" Version="2.0.4"/>
<PackageReference Include="Pandatech.PandaVaultClient" Version="4.0.6"/>
<PackageReference Include="Pandatech.ResponseCrafter" Version="5.2.2"/>
<PackageReference Include="Pandatech.DistributedCache" Version="4.0.9" />
<PackageReference Include="PandaTech.FileExporter" Version="4.1.2" />
<PackageReference Include="PandaTech.FluentImporter" Version="3.0.9" />
<PackageReference Include="Pandatech.FluentMinimalApiMapper" Version="2.0.4" />
<PackageReference Include="Pandatech.PandaVaultClient" Version="4.0.6" />
<PackageReference Include="Pandatech.ResponseCrafter" Version="5.2.2" />
<PackageReference Include="Scalar.AspNetCore" Version="2.8.5" />
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0"/>
<PackageReference Include="Serilog.Sinks.Async" Version="2.1.0"/>
<PackageReference Include="Serilog.Sinks.Grafana.Loki" Version="8.3.1"/>
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.4"/>
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="2.1.0" />
<PackageReference Include="Serilog.Sinks.Grafana.Loki" Version="8.3.1" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.4" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using CommissionCalculator.DTO;
using FluentValidation;
using FluentValidation.Validators;
using SharedKernel.ValidatorAndMediatR.Validators.Files;

namespace SharedKernel.ValidatorAndMediatR.Validators;
public sealed class CommissionRuleValidator<T> : PropertyValidator<T, CommissionRule?>
{
public override string Name => "CommissionRuleValidator";

public override bool IsValid(ValidationContext<T> context, CommissionRule? rule)
{
if (rule == null || rule.CommissionRangeConfigs.Count == 0)
{
context.AddFailure("The ranges list cannot be null or empty.");
return false;
}

if (rule.CommissionRangeConfigs.Any(
r => r is { Type: CommissionType.Percentage, CommissionAmount: < -10 or > 10 }))
{
context.AddFailure(
"For 'Percentage' CommissionType, the CommissionAmount should be between -10 and 10. Commissions over 1000% are not allowed.");
return false;
}

if (rule.CommissionRangeConfigs.Count == 1)
{
if (rule.CommissionRangeConfigs[0].RangeStart != 0 || rule.CommissionRangeConfigs[0].RangeEnd != 0)
{
context.AddFailure("In case of one range, both 'From' and 'To' should be 0.");
return false;
}

if (rule.CommissionRangeConfigs[0].MaxCommission != 0 && rule.CommissionRangeConfigs[0].MaxCommission <
rule.CommissionRangeConfigs[0].MinCommission)
{
context.AddFailure("MaxCommission should be greater than or equal to MinCommission.");
return false;
}

return true; //check
}
else
{
var rangeValidator = new CommissionRangeValidator<T>();
var rangeValidatorResult = rangeValidator.IsValid(context, rule);

return true && rangeValidatorResult;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using CommissionCalculator.DTO;
using FluentValidation;
using FluentValidation.Validators;

namespace SharedKernel.ValidatorAndMediatR.Validators.Files;
public sealed class CommissionRangeValidator<T> : PropertyValidator<T, CommissionRule?>
{
public override string Name => "CommissionRangeValidator";

public override bool IsValid(ValidationContext<T> context, CommissionRule? rule)
{
var startRule = rule!.CommissionRangeConfigs.FirstOrDefault(r => r is { RangeStart: 0, RangeEnd: > 0 });
if (startRule == null)
{
context.AddFailure("There should be at least one rule where From = 0.");
return false;
}

if (startRule.MaxCommission != 0 && startRule.MaxCommission < startRule.MinCommission)
{
context.AddFailure("MaxCommission should be greater than or equal to MinCommission.");
return false;
}

var verifiedRules = 1;

var lastTo = startRule.RangeEnd;

while (true)
{
var nextRule = rule.CommissionRangeConfigs.FirstOrDefault(r => r.RangeStart == lastTo);
if (nextRule is null && lastTo != 0)
{
context.AddFailure($"Gap detected. No rule found for 'From = {lastTo}'.");
return false;
}

if (nextRule is not null && nextRule.RangeStart == nextRule.RangeEnd)
{
context.AddFailure("Invalid rule. 'From' and 'To' cannot be equal.");
return false;
}

if (nextRule is not null && nextRule.MaxCommission != 0 && nextRule.MaxCommission < nextRule.MinCommission)
{
context.AddFailure("MaxCommission should be greater than or equal to MinCommission.");
return false;
}

if (lastTo == 0)
{
break;
}

verifiedRules++;

lastTo = nextRule!.RangeEnd;
}

if (verifiedRules != rule.CommissionRangeConfigs.Count)
{
context.AddFailure("There is some nested or gap ranges in the rules.");
return false;
}

return true; //check
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using FluentValidation;
using CommissionCalculator.DTO;
using FluentValidation;
using Microsoft.AspNetCore.Http;
using SharedKernel.Helpers;
using SharedKernel.ValidatorAndMediatR.Validators.Files;
Expand Down Expand Up @@ -80,4 +81,8 @@ public static IRuleBuilderOptions<T, string> IsXssSanitized<T>(this IRuleBuilder
{
return rb.SetValidator(new FilesMaxCountValidator<T>(maxCount));
}
public static IRuleBuilderOptions<T, CommissionRule?> ValidateCommissionRule<T>(this IRuleBuilder<T, CommissionRule?> rule)
{
return rule.SetValidator(new CommissionRuleValidator<T>());
}
}