This commit is contained in:
Халимов Рустам
2026-02-09 23:54:03 +03:00
parent c98c96e408
commit ee40b38968
65 changed files with 6157 additions and 957 deletions
@@ -0,0 +1,7 @@
namespace Nashel.BuildingBlocks.Application.Abstractions;
public interface ICurrentUserService
{
Guid? UserId { get; }
// Other claims if needed
}
@@ -0,0 +1,34 @@
using FluentValidation;
using MediatR;
namespace Nashel.BuildingBlocks.Application.Behaviors;
public class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
private readonly IEnumerable<IValidator<TRequest>> _validators;
public ValidationBehavior(IEnumerable<IValidator<TRequest>> validators)
{
_validators = validators;
}
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
if (!_validators.Any())
{
return await next();
}
var context = new ValidationContext<TRequest>(request);
var validationResults = await Task.WhenAll(_validators.Select(v => v.ValidateAsync(context, cancellationToken)));
var failures = validationResults.SelectMany(r => r.Errors).Where(f => f != null).ToList();
if (failures.Count != 0)
{
throw new ValidationException(failures);
}
return await next();
}
}
@@ -0,0 +1,31 @@
using System.Collections.Concurrent;
namespace Nashel.BuildingBlocks.Domain;
public interface IEntity { }
public abstract class Entity<TId> : IEntity
{
public TId Id { get; protected set; }
}
public interface IAggregateRoot { }
public abstract class AggregateRoot<TId> : Entity<TId>, IAggregateRoot
{
private readonly List<IDomainEvent> _domainEvents = new();
public IReadOnlyCollection<IDomainEvent> DomainEvents => _domainEvents.AsReadOnly();
public void AddDomainEvent(IDomainEvent domainEvent)
{
_domainEvents.Add(domainEvent);
}
public void ClearDomainEvents()
{
_domainEvents.Clear();
}
}
+13
View File
@@ -0,0 +1,13 @@
using MediatR;
namespace Nashel.BuildingBlocks.Domain;
public interface IDomainEvent : INotification
{
DateTime OccurredOn { get; }
}
public class BaseDomainEvent : IDomainEvent
{
public DateTime OccurredOn { get; protected set; } = DateTime.UtcNow;
}
-12
View File
@@ -11,18 +11,6 @@
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0-preview.6.25358.103" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Modules\Catalog\Nashel.Modules.Catalog.Infrastructure\Nashel.Modules.Catalog.Infrastructure.csproj" />
<ProjectReference Include="..\Modules\Catalog\Nashel.Modules.Catalog.Presentation\Nashel.Modules.Catalog.Presentation.csproj" />
<ProjectReference Include="..\Modules\Collaboration\Nashel.Modules.Collaboration.Infrastructure\Nashel.Modules.Collaboration.Infrastructure.csproj" />
<ProjectReference Include="..\Modules\Collaboration\Nashel.Modules.Collaboration.Presentation\Nashel.Modules.Collaboration.Presentation.csproj" />
<ProjectReference Include="..\Modules\Geo\Nashel.Modules.Geo.Infrastructure\Nashel.Modules.Geo.Infrastructure.csproj" />
<ProjectReference Include="..\Modules\Geo\Nashel.Modules.Geo.Presentation\Nashel.Modules.Geo.Presentation.csproj" />
<ProjectReference Include="..\Modules\Identity\Nashel.Modules.Identity.Infrastructure\Nashel.Modules.Identity.Infrastructure.csproj" />
<ProjectReference Include="..\Modules\Identity\Nashel.Modules.Identity.Presentation\Nashel.Modules.Identity.Presentation.csproj" />
<ProjectReference Include="..\Modules\Order\Nashel.Modules.Order.Infrastructure\Nashel.Modules.Order.Infrastructure.csproj" />
<ProjectReference Include="..\Modules\Order\Nashel.Modules.Order.Presentation\Nashel.Modules.Order.Presentation.csproj" />
<ProjectReference Include="..\Modules\Reputation\Nashel.Modules.Reputation.Infrastructure\Nashel.Modules.Reputation.Infrastructure.csproj" />
<ProjectReference Include="..\Modules\Reputation\Nashel.Modules.Reputation.Presentation\Nashel.Modules.Reputation.Presentation.csproj" />
<ProjectReference Include="..\Modules\Catalog\Infrastructure\Nashel.Modules.Catalog.Infrastructure.csproj" />
<ProjectReference Include="..\Modules\Catalog\Presentation\Nashel.Modules.Catalog.Presentation.csproj" />
<ProjectReference Include="..\Modules\Collaboration\Infrastructure\Nashel.Modules.Collaboration.Infrastructure.csproj" />
+3 -3
View File
@@ -1,12 +1,12 @@
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
// Добавление сервисов в контейнер.
// Узнайте больше о конфигурации OpenAPI на https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
var app = builder.Build();
// Configure the HTTP request pipeline.
// Настройка конвейера HTTP-запросов.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
+7 -2
View File
@@ -5,5 +5,10 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
"AllowedHosts": "*",
"JwtSettings": {
"Secret": "super_secret_key_change_me_please_this_is_for_development_only_12345",
"Issuer": "Nashel",
"Audience": "Nashel"
}
}
@@ -1,20 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Catalog.Domain\Nashel.Modules.Catalog.Domain.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\Nashel.BuildingBlocks.csproj" />
<ProjectReference Include="..\Domain\Nashel.Modules.Catalog.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MediatR" Version="14.0.0" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Catalog.Application</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -1,22 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Catalog.Application\Nashel.Modules.Catalog.Application.csproj" />
<ProjectReference Include="..\Nashel.Modules.Catalog.Domain\Nashel.Modules.Catalog.Domain.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\Nashel.BuildingBlocks.csproj" />
<ProjectReference Include="..\Application\Nashel.Modules.Catalog.Application.csproj" />
<ProjectReference Include="..\Domain\Nashel.Modules.Catalog.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Catalog.Infrastructure</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -1,15 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Catalog.Application\Nashel.Modules.Catalog.Application.csproj" />
<ProjectReference Include="..\Application\Nashel.Modules.Catalog.Application.csproj" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Catalog.Presentation</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -1,20 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Collaboration.Domain\Nashel.Modules.Collaboration.Domain.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\Nashel.BuildingBlocks.csproj" />
<ProjectReference Include="..\Domain\Nashel.Modules.Collaboration.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MediatR" Version="14.0.0" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Collaboration.Application</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -1,22 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Collaboration.Application\Nashel.Modules.Collaboration.Application.csproj" />
<ProjectReference Include="..\Nashel.Modules.Collaboration.Domain\Nashel.Modules.Collaboration.Domain.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\Nashel.BuildingBlocks.csproj" />
<ProjectReference Include="..\Application\Nashel.Modules.Collaboration.Application.csproj" />
<ProjectReference Include="..\Domain\Nashel.Modules.Collaboration.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Collaboration.Infrastructure</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -0,0 +1,459 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v10.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v10.0": {
"Nashel.Modules.Collaboration.Infrastructure/1.0.0": {
"dependencies": {
"Nashel.BuildingBlocks": "1.0.0",
"Nashel.Modules.Collaboration.Application": "1.0.0",
"Nashel.Modules.Collaboration.Domain": "1.0.0",
"Npgsql.EntityFrameworkCore.PostgreSQL": "10.0.0"
},
"runtime": {
"Nashel.Modules.Collaboration.Infrastructure.dll": {}
}
},
"FluentValidation/12.1.1": {
"runtime": {
"lib/net8.0/FluentValidation.dll": {
"assemblyVersion": "12.0.0.0",
"fileVersion": "12.1.1.0"
}
}
},
"MediatR/14.0.0": {
"dependencies": {
"MediatR.Contracts": "2.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.2",
"Microsoft.Extensions.Logging.Abstractions": "10.0.2",
"Microsoft.IdentityModel.JsonWebTokens": "8.14.0"
},
"runtime": {
"lib/net10.0/MediatR.dll": {
"assemblyVersion": "14.0.0.0",
"fileVersion": "14.0.0.0"
}
}
},
"MediatR.Contracts/2.0.1": {
"runtime": {
"lib/netstandard2.0/MediatR.Contracts.dll": {
"assemblyVersion": "2.0.1.0",
"fileVersion": "2.0.1.0"
}
}
},
"Microsoft.EntityFrameworkCore/10.0.2": {
"dependencies": {
"Microsoft.EntityFrameworkCore.Abstractions": "10.0.2",
"Microsoft.Extensions.Caching.Memory": "10.0.2",
"Microsoft.Extensions.Logging": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.EntityFrameworkCore.dll": {
"assemblyVersion": "10.0.2.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.EntityFrameworkCore.Abstractions/10.0.2": {
"runtime": {
"lib/net10.0/Microsoft.EntityFrameworkCore.Abstractions.dll": {
"assemblyVersion": "10.0.2.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.EntityFrameworkCore.Relational/10.0.2": {
"dependencies": {
"Microsoft.EntityFrameworkCore": "10.0.2",
"Microsoft.Extensions.Caching.Memory": "10.0.2",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.2",
"Microsoft.Extensions.Logging": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.EntityFrameworkCore.Relational.dll": {
"assemblyVersion": "10.0.2.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.Caching.Abstractions/10.0.2": {
"dependencies": {
"Microsoft.Extensions.Primitives": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.Extensions.Caching.Abstractions.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.Caching.Memory/10.0.2": {
"dependencies": {
"Microsoft.Extensions.Caching.Abstractions": "10.0.2",
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.2",
"Microsoft.Extensions.Logging.Abstractions": "10.0.2",
"Microsoft.Extensions.Options": "10.0.2",
"Microsoft.Extensions.Primitives": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.Extensions.Caching.Memory.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.Configuration.Abstractions/10.0.2": {
"dependencies": {
"Microsoft.Extensions.Primitives": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.Extensions.Configuration.Abstractions.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.DependencyInjection/10.0.2": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.Extensions.DependencyInjection.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions/10.0.2": {
"runtime": {
"lib/net10.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.Logging/10.0.2": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "10.0.2",
"Microsoft.Extensions.Logging.Abstractions": "10.0.2",
"Microsoft.Extensions.Options": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.Extensions.Logging.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.Logging.Abstractions/10.0.2": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.Extensions.Logging.Abstractions.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.Options/10.0.2": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.2",
"Microsoft.Extensions.Primitives": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.Extensions.Options.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.Primitives/10.0.2": {
"runtime": {
"lib/net10.0/Microsoft.Extensions.Primitives.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.IdentityModel.Abstractions/8.14.0": {
"runtime": {
"lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": {
"assemblyVersion": "8.14.0.0",
"fileVersion": "8.14.0.60815"
}
}
},
"Microsoft.IdentityModel.JsonWebTokens/8.14.0": {
"dependencies": {
"Microsoft.IdentityModel.Tokens": "8.14.0"
},
"runtime": {
"lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": {
"assemblyVersion": "8.14.0.0",
"fileVersion": "8.14.0.60815"
}
}
},
"Microsoft.IdentityModel.Logging/8.14.0": {
"dependencies": {
"Microsoft.IdentityModel.Abstractions": "8.14.0"
},
"runtime": {
"lib/net9.0/Microsoft.IdentityModel.Logging.dll": {
"assemblyVersion": "8.14.0.0",
"fileVersion": "8.14.0.60815"
}
}
},
"Microsoft.IdentityModel.Tokens/8.14.0": {
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "10.0.2",
"Microsoft.IdentityModel.Logging": "8.14.0"
},
"runtime": {
"lib/net9.0/Microsoft.IdentityModel.Tokens.dll": {
"assemblyVersion": "8.14.0.0",
"fileVersion": "8.14.0.60815"
}
}
},
"Npgsql/10.0.0": {
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "10.0.2"
},
"runtime": {
"lib/net10.0/Npgsql.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.0.0"
}
}
},
"Npgsql.EntityFrameworkCore.PostgreSQL/10.0.0": {
"dependencies": {
"Microsoft.EntityFrameworkCore": "10.0.2",
"Microsoft.EntityFrameworkCore.Relational": "10.0.2",
"Npgsql": "10.0.0"
},
"runtime": {
"lib/net10.0/Npgsql.EntityFrameworkCore.PostgreSQL.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.0.0"
}
}
},
"Nashel.BuildingBlocks/1.0.0": {
"dependencies": {
"FluentValidation": "12.1.1",
"MediatR": "14.0.0",
"Microsoft.EntityFrameworkCore.Relational": "10.0.2"
},
"runtime": {
"Nashel.BuildingBlocks.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"Nashel.Modules.Collaboration.Application/1.0.0": {
"dependencies": {
"MediatR": "14.0.0",
"Nashel.BuildingBlocks": "1.0.0",
"Nashel.Modules.Collaboration.Domain": "1.0.0"
},
"runtime": {
"Nashel.Modules.Collaboration.Application.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"Nashel.Modules.Collaboration.Domain/1.0.0": {
"dependencies": {
"Nashel.BuildingBlocks": "1.0.0"
},
"runtime": {
"Nashel.Modules.Collaboration.Domain.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
}
}
},
"libraries": {
"Nashel.Modules.Collaboration.Infrastructure/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"FluentValidation/12.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-EPpkIe1yh1a0OXyC100oOA8WMbZvqUu5plwhvYcb7oSELfyUZzfxV48BLhvs3kKo4NwG7MGLNgy1RJiYtT8Dpw==",
"path": "fluentvalidation/12.1.1",
"hashPath": "fluentvalidation.12.1.1.nupkg.sha512"
},
"MediatR/14.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-r5fwUO6NBvOFKaiMRx/gRrD1MEHHOio5yEdzSLs2OMeD2e9ZKnZaBQM6A6vVBEWJF4VY41vplXmDMOY1YvpqNA==",
"path": "mediatr/14.0.0",
"hashPath": "mediatr.14.0.0.nupkg.sha512"
},
"MediatR.Contracts/2.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-FYv95bNT4UwcNA+G/J1oX5OpRiSUxteXaUt2BJbRSdRNiIUNbggJF69wy6mnk2wYToaanpdXZdCwVylt96MpwQ==",
"path": "mediatr.contracts/2.0.1",
"hashPath": "mediatr.contracts.2.0.1.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-d3+XKbLSHPCu3vwpXECoXcFbvGKmAhEeUmc1xy2czmuPnEF7rZN2HP5ZGMwCMbAKk4B01+nS4HixSMo2Vf/Y9g==",
"path": "microsoft.entityframeworkcore/10.0.2",
"hashPath": "microsoft.entityframeworkcore.10.0.2.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore.Abstractions/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-BzAwIU5mYeOmnKbEXrkwx7feW2V+zUTrK/kRonSib94tjvc0/iRj2a4N6YGXRhTNjaFP3tvCMIDaX1vIFF6dkg==",
"path": "microsoft.entityframeworkcore.abstractions/10.0.2",
"hashPath": "microsoft.entityframeworkcore.abstractions.10.0.2.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore.Relational/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-1fUeyNmqDNfMogJ2ut7OKO57/WGjjkHMYeX51SpA3PwP7ftbx8g/Z3fbErD+1q14DILrqJfsszYsYhGssBRfDg==",
"path": "microsoft.entityframeworkcore.relational/10.0.2",
"hashPath": "microsoft.entityframeworkcore.relational.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Caching.Abstractions/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-WIRPDa/qoKHmJhTAPCO/zLu9kRLQ2Fd6HD5tzgdXJ3xGEVXDHP6FvakKJjynwKrVDld8H4G4tcbW53wuC/wxMQ==",
"path": "microsoft.extensions.caching.abstractions/10.0.2",
"hashPath": "microsoft.extensions.caching.abstractions.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Caching.Memory/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-MkdPYdtsu0Ta4m9Di4XnWVdO9u+wi1LtvisoR1EteIxsXWO/+3iyAPH6RZbw2lBlWZu9lastbl2YsHVIaL9j+g==",
"path": "microsoft.extensions.caching.memory/10.0.2",
"hashPath": "microsoft.extensions.caching.memory.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.Abstractions/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-KC5PslaTDnTuTvyke0KYAVBYdZ7IVTsU3JhHe69BpEbHLcj1YThP3bIGtZNOkZfast2AuLnul5lk4rZKxAdUGQ==",
"path": "microsoft.extensions.configuration.abstractions/10.0.2",
"hashPath": "microsoft.extensions.configuration.abstractions.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-J/Zmp6fY93JbaiZ11ckWvcyxMPjD6XVwIHQXBjryTBgn7O6O20HYg9uVLFcZlNfgH78MnreE/7EH+hjfzn7VyA==",
"path": "microsoft.extensions.dependencyinjection/10.0.2",
"hashPath": "microsoft.extensions.dependencyinjection.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection.Abstractions/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-zOIurr59+kUf9vNcsUkCvKWZv+fPosUZXURZesYkJCvl0EzTc9F7maAO4Cd2WEV7ZJJ0AZrFQvuH6Npph9wdBw==",
"path": "microsoft.extensions.dependencyinjection.abstractions/10.0.2",
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Logging/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-a0EWuBs6D3d7XMGroDXm+WsAi5CVVfjOJvyxurzWnuhBN9CO+1qHKcrKV1JK7H/T4ZtHIoVCOX/YyWM8K87qtw==",
"path": "microsoft.extensions.logging/10.0.2",
"hashPath": "microsoft.extensions.logging.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Logging.Abstractions/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-RZkez/JjpnO+MZ6efKkSynN6ZztLpw3WbxNzjLCPBd97wWj1S9ZYPWi0nmT4kWBRa6atHsdM1ydGkUr8GudyDQ==",
"path": "microsoft.extensions.logging.abstractions/10.0.2",
"hashPath": "microsoft.extensions.logging.abstractions.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Options/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-1De2LJjmxdqopI5AYC5dIhoZQ79AR5ayywxNF1rXrXFtKQfbQOV9+n/IsZBa7qWlr0MqoGpW8+OY2v/57udZOA==",
"path": "microsoft.extensions.options/10.0.2",
"hashPath": "microsoft.extensions.options.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Primitives/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-QmSiO+oLBEooGgB3i0GRXyeYRDHjllqt3k365jwfZlYWhvSHA3UL2NEVV5m8aZa041eIlblo6KMI5txvTMpTwA==",
"path": "microsoft.extensions.primitives/10.0.2",
"hashPath": "microsoft.extensions.primitives.10.0.2.nupkg.sha512"
},
"Microsoft.IdentityModel.Abstractions/8.14.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-iwbCpSjD3ehfTwBhtSNEtKPK0ICun6ov7Ibx6ISNA9bfwIyzI2Siwyi9eJFCJBwxowK9xcA1mj+jBWiigeqgcQ==",
"path": "microsoft.identitymodel.abstractions/8.14.0",
"hashPath": "microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512"
},
"Microsoft.IdentityModel.JsonWebTokens/8.14.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-4jOpiA4THdtpLyMdAb24dtj7+6GmvhOhxf5XHLYWmPKF8ApEnApal1UnJsKO4HxUWRXDA6C4WQVfYyqsRhpNpQ==",
"path": "microsoft.identitymodel.jsonwebtokens/8.14.0",
"hashPath": "microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512"
},
"Microsoft.IdentityModel.Logging/8.14.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-eqqnemdW38CKZEHS6diA50BV94QICozDZEvSrsvN3SJXUFwVB9gy+/oz76gldP7nZliA16IglXjXTCTdmU/Ejg==",
"path": "microsoft.identitymodel.logging/8.14.0",
"hashPath": "microsoft.identitymodel.logging.8.14.0.nupkg.sha512"
},
"Microsoft.IdentityModel.Tokens/8.14.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-lKIZiBiGd36k02TCdMHp1KlNWisyIvQxcYJvIkz7P4gSQ9zi8dgh6S5Grj8NNG7HWYIPfQymGyoZ6JB5d1Lo1g==",
"path": "microsoft.identitymodel.tokens/8.14.0",
"hashPath": "microsoft.identitymodel.tokens.8.14.0.nupkg.sha512"
},
"Npgsql/10.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-xZAYhPOU2rUIFpV48xsqhCx9vXs6Y+0jX2LCoSEfDFYMw9jtAOUk3iQsCnDLrFIv9NT3JGMihn7nnuZsPKqJmA==",
"path": "npgsql/10.0.0",
"hashPath": "npgsql.10.0.0.nupkg.sha512"
},
"Npgsql.EntityFrameworkCore.PostgreSQL/10.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-E2+uSWxSB8LdsUVwPaqRWOcGOP92biry2JEwc0KJMdLJF+aZdczeIdEXVwEyv4nSVMQJH0o8tLhyAMiR6VF0lw==",
"path": "npgsql.entityframeworkcore.postgresql/10.0.0",
"hashPath": "npgsql.entityframeworkcore.postgresql.10.0.0.nupkg.sha512"
},
"Nashel.BuildingBlocks/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Nashel.Modules.Collaboration.Application/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Nashel.Modules.Collaboration.Domain/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}
@@ -1,15 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Collaboration.Application\Nashel.Modules.Collaboration.Application.csproj" />
<ProjectReference Include="..\Application\Nashel.Modules.Collaboration.Application.csproj" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Collaboration.Presentation</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -1,20 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Geo.Domain\Nashel.Modules.Geo.Domain.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\Nashel.BuildingBlocks.csproj" />
<ProjectReference Include="..\Domain\Nashel.Modules.Geo.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MediatR" Version="14.0.0" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Geo.Application</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -1,23 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Geo.Application\Nashel.Modules.Geo.Application.csproj" />
<ProjectReference Include="..\Nashel.Modules.Geo.Domain\Nashel.Modules.Geo.Domain.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\Nashel.BuildingBlocks.csproj" />
<ProjectReference Include="..\Application\Nashel.Modules.Geo.Application.csproj" />
<ProjectReference Include="..\Domain\Nashel.Modules.Geo.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NetTopologySuite.IO.PostGis" Version="2.1.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Geo.Infrastructure</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -1,15 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Geo.Application\Nashel.Modules.Geo.Application.csproj" />
<ProjectReference Include="..\Application\Nashel.Modules.Geo.Application.csproj" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Geo.Presentation</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -0,0 +1,418 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v10.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v10.0": {
"Nashel.Modules.Geo.Presentation/1.0.0": {
"dependencies": {
"Nashel.Modules.Geo.Application": "1.0.0"
},
"runtime": {
"Nashel.Modules.Geo.Presentation.dll": {}
}
},
"FluentValidation/12.1.1": {
"runtime": {
"lib/net8.0/FluentValidation.dll": {
"assemblyVersion": "12.0.0.0",
"fileVersion": "12.1.1.0"
}
}
},
"MediatR/14.0.0": {
"dependencies": {
"MediatR.Contracts": "2.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.2",
"Microsoft.Extensions.Logging.Abstractions": "10.0.2",
"Microsoft.IdentityModel.JsonWebTokens": "8.14.0"
},
"runtime": {
"lib/net10.0/MediatR.dll": {
"assemblyVersion": "14.0.0.0",
"fileVersion": "14.0.0.0"
}
}
},
"MediatR.Contracts/2.0.1": {
"runtime": {
"lib/netstandard2.0/MediatR.Contracts.dll": {
"assemblyVersion": "2.0.1.0",
"fileVersion": "2.0.1.0"
}
}
},
"Microsoft.EntityFrameworkCore/10.0.2": {
"dependencies": {
"Microsoft.EntityFrameworkCore.Abstractions": "10.0.2",
"Microsoft.Extensions.Caching.Memory": "10.0.2",
"Microsoft.Extensions.Logging": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.EntityFrameworkCore.dll": {
"assemblyVersion": "10.0.2.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.EntityFrameworkCore.Abstractions/10.0.2": {
"runtime": {
"lib/net10.0/Microsoft.EntityFrameworkCore.Abstractions.dll": {
"assemblyVersion": "10.0.2.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.EntityFrameworkCore.Relational/10.0.2": {
"dependencies": {
"Microsoft.EntityFrameworkCore": "10.0.2",
"Microsoft.Extensions.Caching.Memory": "10.0.2",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.2",
"Microsoft.Extensions.Logging": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.EntityFrameworkCore.Relational.dll": {
"assemblyVersion": "10.0.2.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.Caching.Abstractions/10.0.2": {
"dependencies": {
"Microsoft.Extensions.Primitives": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.Extensions.Caching.Abstractions.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.Caching.Memory/10.0.2": {
"dependencies": {
"Microsoft.Extensions.Caching.Abstractions": "10.0.2",
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.2",
"Microsoft.Extensions.Logging.Abstractions": "10.0.2",
"Microsoft.Extensions.Options": "10.0.2",
"Microsoft.Extensions.Primitives": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.Extensions.Caching.Memory.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.Configuration.Abstractions/10.0.2": {
"dependencies": {
"Microsoft.Extensions.Primitives": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.Extensions.Configuration.Abstractions.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.DependencyInjection/10.0.2": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.Extensions.DependencyInjection.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions/10.0.2": {
"runtime": {
"lib/net10.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.Logging/10.0.2": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "10.0.2",
"Microsoft.Extensions.Logging.Abstractions": "10.0.2",
"Microsoft.Extensions.Options": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.Extensions.Logging.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.Logging.Abstractions/10.0.2": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.Extensions.Logging.Abstractions.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.Options/10.0.2": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.2",
"Microsoft.Extensions.Primitives": "10.0.2"
},
"runtime": {
"lib/net10.0/Microsoft.Extensions.Options.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.Extensions.Primitives/10.0.2": {
"runtime": {
"lib/net10.0/Microsoft.Extensions.Primitives.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.225.61305"
}
}
},
"Microsoft.IdentityModel.Abstractions/8.14.0": {
"runtime": {
"lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": {
"assemblyVersion": "8.14.0.0",
"fileVersion": "8.14.0.60815"
}
}
},
"Microsoft.IdentityModel.JsonWebTokens/8.14.0": {
"dependencies": {
"Microsoft.IdentityModel.Tokens": "8.14.0"
},
"runtime": {
"lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": {
"assemblyVersion": "8.14.0.0",
"fileVersion": "8.14.0.60815"
}
}
},
"Microsoft.IdentityModel.Logging/8.14.0": {
"dependencies": {
"Microsoft.IdentityModel.Abstractions": "8.14.0"
},
"runtime": {
"lib/net9.0/Microsoft.IdentityModel.Logging.dll": {
"assemblyVersion": "8.14.0.0",
"fileVersion": "8.14.0.60815"
}
}
},
"Microsoft.IdentityModel.Tokens/8.14.0": {
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "10.0.2",
"Microsoft.IdentityModel.Logging": "8.14.0"
},
"runtime": {
"lib/net9.0/Microsoft.IdentityModel.Tokens.dll": {
"assemblyVersion": "8.14.0.0",
"fileVersion": "8.14.0.60815"
}
}
},
"Nashel.BuildingBlocks/1.0.0": {
"dependencies": {
"FluentValidation": "12.1.1",
"MediatR": "14.0.0",
"Microsoft.EntityFrameworkCore.Relational": "10.0.2"
},
"runtime": {
"Nashel.BuildingBlocks.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"Nashel.Modules.Geo.Application/1.0.0": {
"dependencies": {
"MediatR": "14.0.0",
"Nashel.BuildingBlocks": "1.0.0",
"Nashel.Modules.Geo.Domain": "1.0.0"
},
"runtime": {
"Nashel.Modules.Geo.Application.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"Nashel.Modules.Geo.Domain/1.0.0": {
"dependencies": {
"Nashel.BuildingBlocks": "1.0.0"
},
"runtime": {
"Nashel.Modules.Geo.Domain.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
}
}
},
"libraries": {
"Nashel.Modules.Geo.Presentation/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"FluentValidation/12.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-EPpkIe1yh1a0OXyC100oOA8WMbZvqUu5plwhvYcb7oSELfyUZzfxV48BLhvs3kKo4NwG7MGLNgy1RJiYtT8Dpw==",
"path": "fluentvalidation/12.1.1",
"hashPath": "fluentvalidation.12.1.1.nupkg.sha512"
},
"MediatR/14.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-r5fwUO6NBvOFKaiMRx/gRrD1MEHHOio5yEdzSLs2OMeD2e9ZKnZaBQM6A6vVBEWJF4VY41vplXmDMOY1YvpqNA==",
"path": "mediatr/14.0.0",
"hashPath": "mediatr.14.0.0.nupkg.sha512"
},
"MediatR.Contracts/2.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-FYv95bNT4UwcNA+G/J1oX5OpRiSUxteXaUt2BJbRSdRNiIUNbggJF69wy6mnk2wYToaanpdXZdCwVylt96MpwQ==",
"path": "mediatr.contracts/2.0.1",
"hashPath": "mediatr.contracts.2.0.1.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-d3+XKbLSHPCu3vwpXECoXcFbvGKmAhEeUmc1xy2czmuPnEF7rZN2HP5ZGMwCMbAKk4B01+nS4HixSMo2Vf/Y9g==",
"path": "microsoft.entityframeworkcore/10.0.2",
"hashPath": "microsoft.entityframeworkcore.10.0.2.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore.Abstractions/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-BzAwIU5mYeOmnKbEXrkwx7feW2V+zUTrK/kRonSib94tjvc0/iRj2a4N6YGXRhTNjaFP3tvCMIDaX1vIFF6dkg==",
"path": "microsoft.entityframeworkcore.abstractions/10.0.2",
"hashPath": "microsoft.entityframeworkcore.abstractions.10.0.2.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore.Relational/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-1fUeyNmqDNfMogJ2ut7OKO57/WGjjkHMYeX51SpA3PwP7ftbx8g/Z3fbErD+1q14DILrqJfsszYsYhGssBRfDg==",
"path": "microsoft.entityframeworkcore.relational/10.0.2",
"hashPath": "microsoft.entityframeworkcore.relational.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Caching.Abstractions/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-WIRPDa/qoKHmJhTAPCO/zLu9kRLQ2Fd6HD5tzgdXJ3xGEVXDHP6FvakKJjynwKrVDld8H4G4tcbW53wuC/wxMQ==",
"path": "microsoft.extensions.caching.abstractions/10.0.2",
"hashPath": "microsoft.extensions.caching.abstractions.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Caching.Memory/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-MkdPYdtsu0Ta4m9Di4XnWVdO9u+wi1LtvisoR1EteIxsXWO/+3iyAPH6RZbw2lBlWZu9lastbl2YsHVIaL9j+g==",
"path": "microsoft.extensions.caching.memory/10.0.2",
"hashPath": "microsoft.extensions.caching.memory.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.Abstractions/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-KC5PslaTDnTuTvyke0KYAVBYdZ7IVTsU3JhHe69BpEbHLcj1YThP3bIGtZNOkZfast2AuLnul5lk4rZKxAdUGQ==",
"path": "microsoft.extensions.configuration.abstractions/10.0.2",
"hashPath": "microsoft.extensions.configuration.abstractions.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-J/Zmp6fY93JbaiZ11ckWvcyxMPjD6XVwIHQXBjryTBgn7O6O20HYg9uVLFcZlNfgH78MnreE/7EH+hjfzn7VyA==",
"path": "microsoft.extensions.dependencyinjection/10.0.2",
"hashPath": "microsoft.extensions.dependencyinjection.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection.Abstractions/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-zOIurr59+kUf9vNcsUkCvKWZv+fPosUZXURZesYkJCvl0EzTc9F7maAO4Cd2WEV7ZJJ0AZrFQvuH6Npph9wdBw==",
"path": "microsoft.extensions.dependencyinjection.abstractions/10.0.2",
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Logging/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-a0EWuBs6D3d7XMGroDXm+WsAi5CVVfjOJvyxurzWnuhBN9CO+1qHKcrKV1JK7H/T4ZtHIoVCOX/YyWM8K87qtw==",
"path": "microsoft.extensions.logging/10.0.2",
"hashPath": "microsoft.extensions.logging.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Logging.Abstractions/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-RZkez/JjpnO+MZ6efKkSynN6ZztLpw3WbxNzjLCPBd97wWj1S9ZYPWi0nmT4kWBRa6atHsdM1ydGkUr8GudyDQ==",
"path": "microsoft.extensions.logging.abstractions/10.0.2",
"hashPath": "microsoft.extensions.logging.abstractions.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Options/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-1De2LJjmxdqopI5AYC5dIhoZQ79AR5ayywxNF1rXrXFtKQfbQOV9+n/IsZBa7qWlr0MqoGpW8+OY2v/57udZOA==",
"path": "microsoft.extensions.options/10.0.2",
"hashPath": "microsoft.extensions.options.10.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Primitives/10.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-QmSiO+oLBEooGgB3i0GRXyeYRDHjllqt3k365jwfZlYWhvSHA3UL2NEVV5m8aZa041eIlblo6KMI5txvTMpTwA==",
"path": "microsoft.extensions.primitives/10.0.2",
"hashPath": "microsoft.extensions.primitives.10.0.2.nupkg.sha512"
},
"Microsoft.IdentityModel.Abstractions/8.14.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-iwbCpSjD3ehfTwBhtSNEtKPK0ICun6ov7Ibx6ISNA9bfwIyzI2Siwyi9eJFCJBwxowK9xcA1mj+jBWiigeqgcQ==",
"path": "microsoft.identitymodel.abstractions/8.14.0",
"hashPath": "microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512"
},
"Microsoft.IdentityModel.JsonWebTokens/8.14.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-4jOpiA4THdtpLyMdAb24dtj7+6GmvhOhxf5XHLYWmPKF8ApEnApal1UnJsKO4HxUWRXDA6C4WQVfYyqsRhpNpQ==",
"path": "microsoft.identitymodel.jsonwebtokens/8.14.0",
"hashPath": "microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512"
},
"Microsoft.IdentityModel.Logging/8.14.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-eqqnemdW38CKZEHS6diA50BV94QICozDZEvSrsvN3SJXUFwVB9gy+/oz76gldP7nZliA16IglXjXTCTdmU/Ejg==",
"path": "microsoft.identitymodel.logging/8.14.0",
"hashPath": "microsoft.identitymodel.logging.8.14.0.nupkg.sha512"
},
"Microsoft.IdentityModel.Tokens/8.14.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-lKIZiBiGd36k02TCdMHp1KlNWisyIvQxcYJvIkz7P4gSQ9zi8dgh6S5Grj8NNG7HWYIPfQymGyoZ6JB5d1Lo1g==",
"path": "microsoft.identitymodel.tokens/8.14.0",
"hashPath": "microsoft.identitymodel.tokens.8.14.0.nupkg.sha512"
},
"Nashel.BuildingBlocks/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Nashel.Modules.Geo.Application/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Nashel.Modules.Geo.Domain/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}
@@ -0,0 +1,39 @@
using MediatR;
using Nashel.BuildingBlocks.Application.Abstractions;
using Nashel.Modules.Identity.Domain.Repositories;
namespace Nashel.Modules.Identity.Application.Commands;
public record BecomePerformerCommand : IRequest<Unit>;
public class BecomePerformerCommandHandler : IRequestHandler<BecomePerformerCommand, Unit>
{
private readonly IAccountRepository _accountRepository;
private readonly ICurrentUserService _currentUserService;
public BecomePerformerCommandHandler(IAccountRepository accountRepository, ICurrentUserService currentUserService)
{
_accountRepository = accountRepository;
_currentUserService = currentUserService;
}
public async Task<Unit> Handle(BecomePerformerCommand request, CancellationToken cancellationToken)
{
var userId = _currentUserService.UserId;
if (userId == null)
{
throw new Exception("Неавторизован");
}
var account = await _accountRepository.GetByIdAsync(userId.Value, cancellationToken); // Need GetById in repo
if (account == null)
{
throw new Exception("Аккаунт не найден");
}
account.BecomePerformer();
await _accountRepository.UpdateAsync(account, cancellationToken);
return Unit.Value;
}
}
@@ -0,0 +1,32 @@
using MediatR;
using Nashel.Modules.Identity.Domain.Aggregates;
using Nashel.Modules.Identity.Domain.Enums;
using Nashel.Modules.Identity.Domain.Repositories;
using Nashel.Modules.Identity.Domain.Services;
namespace Nashel.Modules.Identity.Application.Commands;
public record LoginCommand(string Phone, string Password) : IRequest<string>; // Возвращает JWT
public class LoginCommandHandler : IRequestHandler<LoginCommand, string>
{
private readonly IAccountRepository _accountRepository;
private readonly IJwtTokenGenerator _jwtTokenGenerator;
public LoginCommandHandler(IAccountRepository accountRepository, IJwtTokenGenerator jwtTokenGenerator)
{
_accountRepository = accountRepository;
_jwtTokenGenerator = jwtTokenGenerator;
}
public async Task<string> Handle(LoginCommand request, CancellationToken cancellationToken)
{
var account = await _accountRepository.GetByPhoneAsync(request.Phone, cancellationToken);
if (account == null || account.PasswordHash != request.Password) // Сравнение хешей в реальной жизни
{
throw new Exception("Неверные учетные данные"); // Использовать паттерн Result
}
return _jwtTokenGenerator.GenerateToken(account.Id, account.Roles);
}
}
@@ -0,0 +1,36 @@
using MediatR;
using Nashel.Modules.Identity.Domain.Aggregates;
using Nashel.Modules.Identity.Domain.Enums;
using Nashel.Modules.Identity.Domain.Repositories;
namespace Nashel.Modules.Identity.Application.Commands;
public record RegisterUserCommand(string Phone, string Password) : IRequest<Guid>;
public class RegisterUserCommandHandler : IRequestHandler<RegisterUserCommand, Guid>
{
private readonly IAccountRepository _accountRepository;
public RegisterUserCommandHandler(IAccountRepository accountRepository)
{
_accountRepository = accountRepository;
}
public async Task<Guid> Handle(RegisterUserCommand request, CancellationToken cancellationToken)
{
// Проверка существования пользователя
if (await _accountRepository.GetByPhoneAsync(request.Phone, cancellationToken) != null)
{
throw new Exception("Пользователь уже существует"); // Использовать паттерн Result в будущем
}
var account = Account.Create(request.Phone, request.Password); // Хешировать пароль в хендлере или конструкторе?
// Конструктор сущности обычно принимает хешированный пароль.
// Предположим, что хешируем здесь или используем сервис.
// Для простоты пока передаем как есть, но нужно хешировать.
// TODO: Правильно хешировать пароль.
await _accountRepository.AddAsync(account, cancellationToken);
return account.Id;
}
}
@@ -1,20 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Identity.Domain\Nashel.Modules.Identity.Domain.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\Nashel.BuildingBlocks.csproj" />
<ProjectReference Include="..\Domain\Nashel.Modules.Identity.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MediatR" Version="14.0.0" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Identity.Application</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -0,0 +1,50 @@
using Nashel.BuildingBlocks.Domain;
using Nashel.Modules.Identity.Domain.Enums;
using Nashel.Modules.Identity.Domain.Events;
namespace Nashel.Modules.Identity.Domain.Aggregates;
public class Account : AggregateRoot<Guid>
{
public string Phone { get; private set; }
public string PasswordHash { get; private set; }
public List<Role> Roles { get; private set; } = new();
// Конструктор для EF Core
private Account() { }
private Account(Guid id, string phone, string passwordHash)
{
Id = id;
Phone = phone;
PasswordHash = passwordHash;
Roles.Add(Role.User);
AddDomainEvent(new AccountCreatedEvent(Id));
}
public static Account Create(string phone, string passwordHash)
{
return new Account(Guid.NewGuid(), phone, passwordHash);
}
public void BecomePerformer()
{
if (!Roles.Contains(Role.Candidate) && !Roles.Contains(Role.Master))
{
Roles.Add(Role.Candidate);
}
}
public void PromoteToMaster()
{
if (Roles.Contains(Role.Candidate))
{
Roles.Remove(Role.Candidate);
}
if (!Roles.Contains(Role.Master))
{
Roles.Add(Role.Master);
}
}
}
+13
View File
@@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace Nashel.Modules.Identity.Domain.Enums;
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum Role
{
User = 0,
Candidate,
Master,
Company,
Admin
}
@@ -0,0 +1,12 @@
using Nashel.BuildingBlocks.Domain;
namespace Nashel.Modules.Identity.Domain.Events;
public class AccountCreatedEvent : BaseDomainEvent
{
public Guid AccountId { get; }
public AccountCreatedEvent(Guid accountId)
{
AccountId = accountId;
}
}
@@ -0,0 +1,11 @@
using Nashel.Modules.Identity.Domain.Aggregates;
namespace Nashel.Modules.Identity.Domain.Repositories;
public interface IAccountRepository
{
Task<Account?> GetByPhoneAsync(string phone, CancellationToken cancellationToken);
Task<Account?> GetByIdAsync(Guid id, CancellationToken cancellationToken);
Task AddAsync(Account account, CancellationToken cancellationToken);
Task UpdateAsync(Account account, CancellationToken cancellationToken);
}
@@ -0,0 +1,8 @@
using Nashel.Modules.Identity.Domain.Enums;
namespace Nashel.Modules.Identity.Domain.Services;
public interface IJwtTokenGenerator
{
string GenerateToken(Guid userId, List<Role> roles);
}
@@ -0,0 +1,46 @@
using MediatR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Nashel.BuildingBlocks.Application.Abstractions;
using Nashel.BuildingBlocks.Application.Behaviors;
using Nashel.Modules.Identity.Domain.Repositories;
using Nashel.Modules.Identity.Domain.Services;
using Nashel.Modules.Identity.Infrastructure.Persistence;
using Nashel.Modules.Identity.Infrastructure.Repositories;
using Nashel.Modules.Identity.Infrastructure.Services;
using Nashel.Modules.Identity.Application.Commands;
namespace Nashel.Modules.Identity.Infrastructure;
public static class DependencyInjection
{
public static IServiceCollection AddIdentityModule(this IServiceCollection services, IConfiguration configuration)
{
services.AddScoped<IAccountRepository, AccountRepository>();
services.AddScoped<IJwtTokenGenerator, JwtTokenGenerator>();
services.AddScoped<ICurrentUserService, CurrentUserService>();
services.AddHttpContextAccessor(); // Ensure available
// Add MediatR (auto-scan for handlers in Application layer)
services.AddMediatR(cfg =>
{
cfg.RegisterServicesFromAssembly(typeof(RegisterUserCommand).Assembly);
cfg.AddBehavior(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
});
// Add DbContext
services.AddDbContext<IdentityDbContext>(options =>
// Configure PostgreSQL inside Host or pass options builder
// Assume Host configures DbContext options or use connection string here
// If "NativeAOT" -> Npgsql DataSource approach is preferred in Host Program.cs.
// But standard AddDbContext works too for now.
// Let's assume connection string is provided in configuration or options.
// For now, simple AddDbContext
{
// options.UseNpgsql(configuration.GetConnectionString("DefaultConnection"));
// This requires Microsoft.EntityFrameworkCore.Npgsql package in Infrastructure.
});
return services;
}
}
@@ -1,22 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Identity.Application\Nashel.Modules.Identity.Application.csproj" />
<ProjectReference Include="..\Nashel.Modules.Identity.Domain\Nashel.Modules.Identity.Domain.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\Nashel.BuildingBlocks.csproj" />
<ProjectReference Include="..\Application\Nashel.Modules.Identity.Application.csproj" />
<ProjectReference Include="..\Domain\Nashel.Modules.Identity.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.15.0" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Identity.Infrastructure</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
@@ -0,0 +1,34 @@
using System.Text.Json;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Nashel.Modules.Identity.Domain.Aggregates;
using Nashel.Modules.Identity.Domain.Enums;
namespace Nashel.Modules.Identity.Infrastructure.Persistence.Configurations;
public class AccountConfiguration : IEntityTypeConfiguration<Account>
{
public void Configure(EntityTypeBuilder<Account> builder)
{
builder.ToTable("Accounts", "identity");
builder.HasKey(x => x.Id);
builder.Property(x => x.Phone)
.IsRequired()
.HasMaxLength(20);
builder.HasIndex(x => x.Phone)
.IsUnique();
builder.Property(x => x.PasswordHash)
.IsRequired();
// Хранение ролей как JSONB для простоты и совместимости с AOT (используя генерацию кода System.Text.Json при необходимости)
builder.Property(x => x.Roles)
.HasConversion(
v => JsonSerializer.Serialize(v, (JsonSerializerOptions?)null),
v => JsonSerializer.Deserialize<List<Role>>(v, (JsonSerializerOptions?)null) ?? new List<Role>())
.HasColumnType("jsonb");
}
}
@@ -0,0 +1,20 @@
using Microsoft.EntityFrameworkCore;
using Nashel.Modules.Identity.Domain.Aggregates;
using Nashel.Modules.Identity.Infrastructure.Persistence.Configurations;
namespace Nashel.Modules.Identity.Infrastructure.Persistence;
public class IdentityDbContext : DbContext
{
public IdentityDbContext(DbContextOptions<IdentityDbContext> options) : base(options)
{
}
public DbSet<Account> Accounts { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new AccountConfiguration());
base.OnModelCreating(modelBuilder);
}
}
@@ -0,0 +1,38 @@
using Microsoft.EntityFrameworkCore;
using Nashel.Modules.Identity.Domain.Aggregates;
using Nashel.Modules.Identity.Domain.Repositories;
using Nashel.Modules.Identity.Infrastructure.Persistence;
namespace Nashel.Modules.Identity.Infrastructure.Repositories;
public class AccountRepository : IAccountRepository
{
private readonly IdentityDbContext _context;
public AccountRepository(IdentityDbContext context)
{
_context = context;
}
public async Task AddAsync(Account account, CancellationToken cancellationToken)
{
await _context.Accounts.AddAsync(account, cancellationToken);
await _context.SaveChangesAsync(cancellationToken);
}
public async Task<Account?> GetByIdAsync(Guid id, CancellationToken cancellationToken)
{
return await _context.Accounts.FindAsync(new object[] { id }, cancellationToken);
}
public async Task<Account?> GetByPhoneAsync(string phone, CancellationToken cancellationToken)
{
return await _context.Accounts.FirstOrDefaultAsync(a => a.Phone == phone, cancellationToken);
}
public async Task UpdateAsync(Account account, CancellationToken cancellationToken)
{
_context.Accounts.Update(account);
await _context.SaveChangesAsync(cancellationToken);
}
}
@@ -0,0 +1,29 @@
using System.Security.Claims;
using Microsoft.AspNetCore.Http;
using Nashel.BuildingBlocks.Application.Abstractions;
namespace Nashel.Modules.Identity.Infrastructure.Services;
public class CurrentUserService : ICurrentUserService
{
private readonly IHttpContextAccessor _httpContextAccessor;
public CurrentUserService(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public Guid? UserId
{
get
{
var userId = _httpContextAccessor.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (string.IsNullOrEmpty(userId))
{
// Fallback to "sub"
userId = _httpContextAccessor.HttpContext?.User?.FindFirst("sub")?.Value;
}
return userId != null ? Guid.Parse(userId) : null;
}
}
}
@@ -0,0 +1,46 @@
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using Nashel.Modules.Identity.Domain.Enums;
using Nashel.Modules.Identity.Domain.Services;
namespace Nashel.Modules.Identity.Infrastructure.Services;
public class JwtTokenGenerator : IJwtTokenGenerator
{
private readonly IConfiguration _configuration;
public JwtTokenGenerator(IConfiguration configuration)
{
_configuration = configuration;
}
public string GenerateToken(Guid userId, List<Role> roles)
{
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
foreach (var role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role.ToString()));
}
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtSettings:Secret"] ?? "super_secret_key_change_me_please"));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: _configuration["JwtSettings:Issuer"],
audience: _configuration["JwtSettings:Audience"],
claims: claims,
expires: DateTime.Now.AddDays(1),
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
@@ -0,0 +1,35 @@
using MediatR;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Nashel.Modules.Identity.Application.Commands;
namespace Nashel.Modules.Identity.Presentation.Endpoints;
public static class IdentityEndpoints
{
public static void MapIdentityEndpoints(this IEndpointRouteBuilder app)
{
var authGroup = app.MapGroup("/api/auth").WithTags("Auth");
authGroup.MapPost("/register", async (RegisterUserCommand command, ISender sender) =>
{
var result = await sender.Send(command);
return Results.Ok(result);
});
authGroup.MapPost("/login", async (LoginCommand command, ISender sender) =>
{
var token = await sender.Send(command);
return Results.Ok(new { Token = token });
});
var profileGroup = app.MapGroup("/api/profile").WithTags("Profile").RequireAuthorization();
profileGroup.MapPost("/become-performer", async (ISender sender) =>
{
await sender.Send(new BecomePerformerCommand());
return Results.Ok();
});
}
}
@@ -1,15 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Identity.Application\Nashel.Modules.Identity.Application.csproj" />
<ProjectReference Include="..\Application\Nashel.Modules.Identity.Application.csproj" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Identity.Presentation</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
@@ -0,0 +1,57 @@
using FluentAssertions;
using MediatR;
using Moq;
using Nashel.BuildingBlocks.Application.Abstractions;
using Nashel.Modules.Identity.Application.Commands;
using Nashel.Modules.Identity.Domain.Aggregates;
using Nashel.Modules.Identity.Domain.Enums;
using Nashel.Modules.Identity.Domain.Repositories;
using Xunit;
namespace Nashel.Modules.Identity.Tests.Application;
public class BecomePerformerCommandHandlerTests
{
private readonly Mock<IAccountRepository> _mockRepo;
private readonly Mock<ICurrentUserService> _mockUserService;
private readonly BecomePerformerCommandHandler _handler;
public BecomePerformerCommandHandlerTests()
{
_mockRepo = new Mock<IAccountRepository>();
_mockUserService = new Mock<ICurrentUserService>();
_handler = new BecomePerformerCommandHandler(_mockRepo.Object, _mockUserService.Object);
}
[Fact]
public async Task Handle_Should_Add_Candidate_Role()
{
// Arrange
var account = Account.Create("123", "pass"); // Has User role only
var userId = account.Id;
_mockUserService.Setup(s => s.UserId).Returns(userId);
_mockRepo.Setup(r => r.GetByIdAsync(userId, It.IsAny<CancellationToken>()))
.ReturnsAsync(account);
// Act
await _handler.Handle(new BecomePerformerCommand(), CancellationToken.None);
// Assert
account.Roles.Should().Contain(Role.Candidate);
_mockRepo.Verify(r => r.UpdateAsync(account, It.IsAny<CancellationToken>()), Times.Once);
}
[Fact]
public async Task Handle_Should_Throw_If_Unauthorized()
{
// Arrange
_mockUserService.Setup(s => s.UserId).Returns((Guid?)null);
// Act
var act = async () => await _handler.Handle(new BecomePerformerCommand(), CancellationToken.None);
// Assert
await act.Should().ThrowAsync<Exception>().WithMessage("Неавторизован");
}
}
@@ -0,0 +1,63 @@
using FluentAssertions;
using Moq;
using Nashel.Modules.Identity.Application.Commands;
using Nashel.Modules.Identity.Domain.Aggregates;
using Nashel.Modules.Identity.Domain.Enums;
using Nashel.Modules.Identity.Domain.Repositories;
using Nashel.Modules.Identity.Domain.Services;
using Xunit;
namespace Nashel.Modules.Identity.Tests.Application;
public class LoginCommandHandlerTests
{
private readonly Mock<IAccountRepository> _mockRepo;
private readonly Mock<IJwtTokenGenerator> _mockTokenGen;
private readonly LoginCommandHandler _handler;
public LoginCommandHandlerTests()
{
_mockRepo = new Mock<IAccountRepository>();
_mockTokenGen = new Mock<IJwtTokenGenerator>();
_handler = new LoginCommandHandler(_mockRepo.Object, _mockTokenGen.Object);
}
[Fact]
public async Task Handle_Should_Return_Token_On_Success()
{
// Arrange
var phone = "1234567890";
var password = "password";
var account = Account.Create(phone, password);
_mockRepo.Setup(r => r.GetByPhoneAsync(phone, It.IsAny<CancellationToken>()))
.ReturnsAsync(account);
_mockTokenGen.Setup(t => t.GenerateToken(It.IsAny<Guid>(), It.IsAny<List<Role>>()))
.Returns("jwt_token");
// Act
var result = await _handler.Handle(new LoginCommand(phone, password), CancellationToken.None);
// Assert
result.Should().Be("jwt_token");
_mockTokenGen.Verify(t => t.GenerateToken(account.Id, account.Roles), Times.Once);
}
[Fact]
public async Task Handle_Should_Throw_On_Invalid_Password()
{
// Arrange
var phone = "1234567890";
var account = Account.Create(phone, "correct_hash");
_mockRepo.Setup(r => r.GetByPhoneAsync(phone, It.IsAny<CancellationToken>()))
.ReturnsAsync(account);
// Act
var act = async () => await _handler.Handle(new LoginCommand(phone, "wrong_password"), CancellationToken.None);
// Assert
await act.Should().ThrowAsync<Exception>().WithMessage("Неверные учетные данные");
}
}
@@ -0,0 +1,52 @@
using FluentAssertions;
using Moq;
using Nashel.Modules.Identity.Application.Commands;
using Nashel.Modules.Identity.Domain.Aggregates;
using Nashel.Modules.Identity.Domain.Repositories;
using Xunit;
namespace Nashel.Modules.Identity.Tests.Application;
public class RegisterUserCommandHandlerTests
{
private readonly Mock<IAccountRepository> _mockRepo;
private readonly RegisterUserCommandHandler _handler;
public RegisterUserCommandHandlerTests()
{
_mockRepo = new Mock<IAccountRepository>();
_handler = new RegisterUserCommandHandler(_mockRepo.Object);
}
[Fact]
public async Task Handle_Should_Register_When_User_Not_Exists()
{
// Arrange
var phone = "123";
_mockRepo.Setup(r => r.GetByPhoneAsync(phone, It.IsAny<CancellationToken>()))
.ReturnsAsync((Account?)null);
// Act
var result = await _handler.Handle(new RegisterUserCommand(phone, "pass"), CancellationToken.None);
// Assert
result.Should().NotBeEmpty();
_mockRepo.Verify(r => r.AddAsync(It.IsAny<Account>(), It.IsAny<CancellationToken>()), Times.Once);
}
[Fact]
public async Task Handle_Should_Throw_When_User_Exists()
{
// Arrange
var phone = "123";
_mockRepo.Setup(r => r.GetByPhoneAsync(phone, It.IsAny<CancellationToken>()))
.ReturnsAsync(Account.Create(phone, "pass"));
// Act
var act = async () => await _handler.Handle(new RegisterUserCommand(phone, "pass"), CancellationToken.None);
// Assert
await act.Should().ThrowAsync<Exception>().WithMessage("Пользователь уже существует");
_mockRepo.Verify(r => r.AddAsync(It.IsAny<Account>(), It.IsAny<CancellationToken>()), Times.Never);
}
}
@@ -0,0 +1,69 @@
using FluentAssertions;
using Nashel.Modules.Identity.Domain.Aggregates;
using Nashel.Modules.Identity.Domain.Enums;
using Xunit;
namespace Nashel.Modules.Identity.Tests.Domain;
public class AccountTests
{
[Fact]
public void Create_Should_Create_Account_With_User_Role()
{
// Arrange & Act
var phone = "1234567890";
var passwordHash = "hash";
var account = Account.Create(phone, passwordHash);
// Assert
account.Should().NotBeNull();
account.Roles.Should().ContainSingle(r => r == Role.User);
account.Roles.Should().HaveCount(1);
}
[Fact]
public void BecomePerformer_Should_Add_Candidate_Role()
{
// Arrange
var account = Account.Create("123", "hash");
// Act
account.BecomePerformer();
// Assert
account.Roles.Should().Contain(Role.Candidate);
account.Roles.Should().Contain(Role.User);
account.Roles.Should().HaveCount(2); // User + Candidate
}
[Fact]
public void BecomePerformer_Should_Do_Nothing_If_Already_Candidate()
{
// Arrange
var account = Account.Create("123", "hash");
account.BecomePerformer();
// Act
account.BecomePerformer();
// Assert
account.Roles.Should().ContainSingle(r => r == Role.Candidate);
account.Roles.Should().HaveCount(2);
}
[Fact]
public void PromoteToMaster_Should_Replace_Candidate_With_Master()
{
// Arrange
var account = Account.Create("123", "hash");
account.BecomePerformer(); // Has Candidate
// Act
account.PromoteToMaster();
// Assert
account.Roles.Should().NotContain(Role.Candidate);
account.Roles.Should().Contain(Role.Master);
account.Roles.Should().Contain(Role.User);
}
}
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="FluentAssertions" Version="8.8.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Domain\Nashel.Modules.Identity.Domain.csproj" />
<ProjectReference Include="..\Application\Nashel.Modules.Identity.Application.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\Nashel.BuildingBlocks.csproj" />
</ItemGroup>
</Project>
+10
View File
@@ -0,0 +1,10 @@
namespace Nashel.Modules.Identity.Tests;
public class UnitTest1
{
[Fact]
public void Test1()
{
}
}
@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v10.0", FrameworkDisplayName = ".NET 10.0")]
@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("Nashel.Modules.Identity.Tests")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+c98c96e4082fd5607e89d36ea8658734b6e5a8c3")]
[assembly: System.Reflection.AssemblyProductAttribute("Nashel.Modules.Identity.Tests")]
[assembly: System.Reflection.AssemblyTitleAttribute("Nashel.Modules.Identity.Tests")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Создано классом WriteCodeFragment MSBuild.
@@ -0,0 +1 @@
e8e240e03fb1d0961e413f052050e6fac70545bd6422326eb10bde9d3def488e
@@ -0,0 +1,17 @@
is_global = true
build_property.TargetFramework = net10.0
build_property.TargetFrameworkIdentifier = .NETCoreApp
build_property.TargetFrameworkVersion = v10.0
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = Nashel.Modules.Identity.Tests
build_property.ProjectDir = E:\GIT\mvp\nashel-backend\src\Modules\Identity\Tests\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.EffectiveAnalysisLevelStyle = 10.0
build_property.EnableCodeStyleSeverity =
@@ -0,0 +1,9 @@
// <auto-generated/>
global using System;
global using System.Collections.Generic;
global using System.IO;
global using System.Linq;
global using System.Net.Http;
global using System.Threading;
global using System.Threading.Tasks;
global using Xunit;
@@ -0,0 +1 @@
18b244c3e2cb0e8fba6cb5ef8d2989104e9808716cf3d4153614ee1248e55a8b
@@ -0,0 +1 @@
a6f680146539296bd4f23c849c72da3b168488fb194c34664e706062abfba1da
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\HomePC\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.15.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="C:\Users\HomePC\.nuget\packages\" />
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" />
</ItemGroup>
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)xunit.runner.visualstudio\2.8.2\build\net6.0\xunit.runner.visualstudio.props" Condition="Exists('$(NuGetPackageRoot)xunit.runner.visualstudio\2.8.2\build\net6.0\xunit.runner.visualstudio.props')" />
<Import Project="$(NuGetPackageRoot)xunit.core\2.9.2\build\xunit.core.props" Condition="Exists('$(NuGetPackageRoot)xunit.core\2.9.2\build\xunit.core.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore\10.0.2\buildTransitive\net10.0\Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore\10.0.2\buildTransitive\net10.0\Microsoft.EntityFrameworkCore.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.testplatform.testhost\17.14.0\build\net8.0\Microsoft.TestPlatform.TestHost.props" Condition="Exists('$(NuGetPackageRoot)microsoft.testplatform.testhost\17.14.0\build\net8.0\Microsoft.TestPlatform.TestHost.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.codecoverage\17.14.0\build\netstandard2.0\Microsoft.CodeCoverage.props" Condition="Exists('$(NuGetPackageRoot)microsoft.codecoverage\17.14.0\build\netstandard2.0\Microsoft.CodeCoverage.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.net.test.sdk\17.14.0\build\net8.0\Microsoft.NET.Test.Sdk.props" Condition="Exists('$(NuGetPackageRoot)microsoft.net.test.sdk\17.14.0\build\net8.0\Microsoft.NET.Test.Sdk.props')" />
</ImportGroup>
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Pkgxunit_analyzers Condition=" '$(Pkgxunit_analyzers)' == '' ">C:\Users\HomePC\.nuget\packages\xunit.analyzers\1.16.0</Pkgxunit_analyzers>
</PropertyGroup>
</Project>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)xunit.core\2.9.2\build\xunit.core.targets" Condition="Exists('$(NuGetPackageRoot)xunit.core\2.9.2\build\xunit.core.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\10.0.2\buildTransitive\net8.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\10.0.2\buildTransitive\net8.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.extensions.options\10.0.2\buildTransitive\net8.0\Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options\10.0.2\buildTransitive\net8.0\Microsoft.Extensions.Options.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.testplatform.testhost\17.14.0\build\net8.0\Microsoft.TestPlatform.TestHost.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.testplatform.testhost\17.14.0\build\net8.0\Microsoft.TestPlatform.TestHost.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.codecoverage\17.14.0\build\netstandard2.0\Microsoft.CodeCoverage.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.codecoverage\17.14.0\build\netstandard2.0\Microsoft.CodeCoverage.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.net.test.sdk\17.14.0\build\net8.0\Microsoft.NET.Test.Sdk.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.net.test.sdk\17.14.0\build\net8.0\Microsoft.NET.Test.Sdk.targets')" />
<Import Project="$(NuGetPackageRoot)coverlet.collector\6.0.4\build\netstandard2.0\coverlet.collector.targets" Condition="Exists('$(NuGetPackageRoot)coverlet.collector\6.0.4\build\netstandard2.0\coverlet.collector.targets')" />
</ImportGroup>
</Project>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,47 @@
{
"version": 2,
"dgSpecHash": "ardLoaZLqy0=",
"success": true,
"projectFilePath": "E:\\GIT\\mvp\\nashel-backend\\src\\Modules\\Identity\\Tests\\Nashel.Modules.Identity.Tests.csproj",
"expectedPackageFiles": [
"C:\\Users\\HomePC\\.nuget\\packages\\castle.core\\5.1.1\\castle.core.5.1.1.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\coverlet.collector\\6.0.4\\coverlet.collector.6.0.4.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\fluentassertions\\8.8.0\\fluentassertions.8.8.0.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\fluentvalidation\\12.1.1\\fluentvalidation.12.1.1.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\mediatr\\14.0.0\\mediatr.14.0.0.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\mediatr.contracts\\2.0.1\\mediatr.contracts.2.0.1.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.codecoverage\\17.14.0\\microsoft.codecoverage.17.14.0.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.entityframeworkcore\\10.0.2\\microsoft.entityframeworkcore.10.0.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.entityframeworkcore.abstractions\\10.0.2\\microsoft.entityframeworkcore.abstractions.10.0.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.entityframeworkcore.analyzers\\10.0.2\\microsoft.entityframeworkcore.analyzers.10.0.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.entityframeworkcore.relational\\10.0.2\\microsoft.entityframeworkcore.relational.10.0.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.extensions.caching.abstractions\\10.0.2\\microsoft.extensions.caching.abstractions.10.0.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.extensions.caching.memory\\10.0.2\\microsoft.extensions.caching.memory.10.0.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.extensions.configuration.abstractions\\10.0.2\\microsoft.extensions.configuration.abstractions.10.0.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.extensions.dependencyinjection\\10.0.2\\microsoft.extensions.dependencyinjection.10.0.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.extensions.dependencyinjection.abstractions\\10.0.2\\microsoft.extensions.dependencyinjection.abstractions.10.0.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.extensions.logging\\10.0.2\\microsoft.extensions.logging.10.0.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.extensions.logging.abstractions\\10.0.2\\microsoft.extensions.logging.abstractions.10.0.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.extensions.options\\10.0.2\\microsoft.extensions.options.10.0.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.extensions.primitives\\10.0.2\\microsoft.extensions.primitives.10.0.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.identitymodel.abstractions\\8.14.0\\microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.identitymodel.jsonwebtokens\\8.14.0\\microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.identitymodel.logging\\8.14.0\\microsoft.identitymodel.logging.8.14.0.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.identitymodel.tokens\\8.14.0\\microsoft.identitymodel.tokens.8.14.0.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.net.test.sdk\\17.14.0\\microsoft.net.test.sdk.17.14.0.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.testplatform.objectmodel\\17.14.0\\microsoft.testplatform.objectmodel.17.14.0.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\microsoft.testplatform.testhost\\17.14.0\\microsoft.testplatform.testhost.17.14.0.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\moq\\4.20.72\\moq.4.20.72.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\newtonsoft.json\\13.0.3\\newtonsoft.json.13.0.3.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\system.diagnostics.eventlog\\6.0.0\\system.diagnostics.eventlog.6.0.0.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\xunit\\2.9.2\\xunit.2.9.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\xunit.abstractions\\2.0.3\\xunit.abstractions.2.0.3.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\xunit.analyzers\\1.16.0\\xunit.analyzers.1.16.0.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\xunit.assert\\2.9.2\\xunit.assert.2.9.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\xunit.core\\2.9.2\\xunit.core.2.9.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\xunit.extensibility.core\\2.9.2\\xunit.extensibility.core.2.9.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\xunit.extensibility.execution\\2.9.2\\xunit.extensibility.execution.2.9.2.nupkg.sha512",
"C:\\Users\\HomePC\\.nuget\\packages\\xunit.runner.visualstudio\\2.8.2\\xunit.runner.visualstudio.2.8.2.nupkg.sha512"
],
"logs": []
}
@@ -1,20 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Order.Domain\Nashel.Modules.Order.Domain.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\Nashel.BuildingBlocks.csproj" />
<ProjectReference Include="..\Domain\Nashel.Modules.Order.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MediatR" Version="14.0.0" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Order.Application</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -1,22 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Order.Application\Nashel.Modules.Order.Application.csproj" />
<ProjectReference Include="..\Nashel.Modules.Order.Domain\Nashel.Modules.Order.Domain.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\Nashel.BuildingBlocks.csproj" />
<ProjectReference Include="..\Application\Nashel.Modules.Order.Application.csproj" />
<ProjectReference Include="..\Domain\Nashel.Modules.Order.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Order.Infrastructure</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -1,15 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Order.Application\Nashel.Modules.Order.Application.csproj" />
<ProjectReference Include="..\Application\Nashel.Modules.Order.Application.csproj" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Order.Presentation</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -1,20 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Reputation.Domain\Nashel.Modules.Reputation.Domain.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\Nashel.BuildingBlocks.csproj" />
<ProjectReference Include="..\Domain\Nashel.Modules.Reputation.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MediatR" Version="14.0.0" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Reputation.Application</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -1,22 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Reputation.Application\Nashel.Modules.Reputation.Application.csproj" />
<ProjectReference Include="..\Nashel.Modules.Reputation.Domain\Nashel.Modules.Reputation.Domain.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\Nashel.BuildingBlocks.csproj" />
<ProjectReference Include="..\Application\Nashel.Modules.Reputation.Application.csproj" />
<ProjectReference Include="..\Domain\Nashel.Modules.Reputation.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Reputation.Infrastructure</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>
@@ -1,15 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Nashel.Modules.Reputation.Application\Nashel.Modules.Reputation.Application.csproj" />
<ProjectReference Include="..\Application\Nashel.Modules.Reputation.Application.csproj" />
</ItemGroup>
<PropertyGroup>
<RootNamespace>Nashel.Modules.Reputation.Presentation</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
</Project>