mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 02:39:03 +00:00
Add domain project and update references
This commit is contained in:
@@ -11,16 +11,17 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.11" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Infrastructure\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Domain\Domain.Core\Domain.Core.csproj" />
|
||||
<ProjectReference Include="..\..\Repository\Repository.Core\Repository.Core.csproj" />
|
||||
<ProjectReference Include="..\..\Service\Service.Core\Service.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\..\.dockerignore">
|
||||
<Link>.dockerignore</Link>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using System.Net;
|
||||
using Repository.Core.Entities;
|
||||
using Domain.Core.Entities;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Service.Core.Auth;
|
||||
using Service.Core.Jwt;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Repository.Core.Entities;
|
||||
using Domain.Core.Entities;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Service.Core.User;
|
||||
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
<Project Path="Database/Database.Migrations/Database.Migrations.csproj" />
|
||||
<Project Path="Database/Database.Seed/Database.Seed.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Domain/">
|
||||
<Project Path="Domain/Domain.Core/Domain.Core.csproj" />
|
||||
<Project Path="Domain/Domain.Validation/Domain.Validation.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Repository/">
|
||||
<Project Path="Repository/Repository.Core/Repository.Core.csproj" />
|
||||
<Project Path="Repository/Repository.Tests/Repository.Tests.csproj" />
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Domain\Domain.Core\Domain.Core.csproj" />
|
||||
<ProjectReference Include="..\..\Repository\Repository.Core\Repository.Core.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Data;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Repository.Core.Entities;
|
||||
using Domain.Core.Entities;
|
||||
using Repository.Core.Repositories;
|
||||
using idunno.Password;
|
||||
using Konscious.Security.Cryptography;
|
||||
|
||||
8
src/Core/Domain/Domain.Core/Domain.Core.csproj
Normal file
8
src/Core/Domain/Domain.Core/Domain.Core.csproj
Normal file
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>Domain.Core</RootNamespace>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
14
src/Core/Domain/Domain.Core/Entities/UserAccount.cs
Normal file
14
src/Core/Domain/Domain.Core/Entities/UserAccount.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace Domain.Core.Entities;
|
||||
|
||||
public class UserAccount
|
||||
{
|
||||
public Guid UserAccountId { get; set; }
|
||||
public string Username { get; set; } = string.Empty;
|
||||
public string FirstName { get; set; } = string.Empty;
|
||||
public string LastName { get; set; } = string.Empty;
|
||||
public string Email { get; set; } = string.Empty;
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime? UpdatedAt { get; set; }
|
||||
public DateTime DateOfBirth { get; set; }
|
||||
public byte[]? Timer { get; set; }
|
||||
}
|
||||
11
src/Core/Domain/Domain.Core/Entities/UserCredential.cs
Normal file
11
src/Core/Domain/Domain.Core/Entities/UserCredential.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Domain.Core.Entities;
|
||||
|
||||
public class UserCredential
|
||||
{
|
||||
public Guid UserCredentialId { get; set; }
|
||||
public Guid UserAccountId { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime Expiry { get; set; }
|
||||
public string Hash { get; set; } = string.Empty;
|
||||
public byte[]? Timer { get; set; }
|
||||
}
|
||||
9
src/Core/Domain/Domain.Core/Entities/UserVerification.cs
Normal file
9
src/Core/Domain/Domain.Core/Entities/UserVerification.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Domain.Core.Entities;
|
||||
|
||||
public class UserVerification
|
||||
{
|
||||
public Guid UserVerificationId { get; set; }
|
||||
public Guid UserAccountId { get; set; }
|
||||
public DateTime VerificationDateTime { get; set; }
|
||||
public byte[]? Timer { get; set; }
|
||||
}
|
||||
12
src/Core/Domain/Domain.Validation/Domain.Validation.csproj
Normal file
12
src/Core/Domain/Domain.Validation/Domain.Validation.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>Domain.Validation</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Domain.Core\Domain.Core.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,16 +0,0 @@
|
||||
namespace Repository.Core.Entities;
|
||||
|
||||
public class UserAccount
|
||||
{
|
||||
public Guid UserAccountId { get; set; }
|
||||
public string Username { get; set; } = string.Empty;
|
||||
public string FirstName { get; set; } = string.Empty;
|
||||
public string LastName { get; set; } = string.Empty;
|
||||
public string Email { get; set; } = string.Empty;
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime? UpdatedAt { get; set; }
|
||||
public DateTime DateOfBirth { get; set; }
|
||||
public byte[]? Timer { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
namespace Repository.Core.Entities;
|
||||
|
||||
public class UserCredential
|
||||
{
|
||||
public Guid UserCredentialId { get; set; }
|
||||
public Guid UserAccountId { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime Expiry { get; set; }
|
||||
public string Hash { get; set; } = string.Empty;
|
||||
public byte[]? Timer { get; set; }
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace Repository.Core.Entities;
|
||||
|
||||
public class UserVerification
|
||||
{
|
||||
public Guid UserVerificationId { get; set; }
|
||||
public Guid UserAccountId { get; set; }
|
||||
public DateTime VerificationDateTime { get; set; }
|
||||
public byte[]? Timer { get; set; }
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using Domain.Core.Entities;
|
||||
using Repository.Core.Sql;
|
||||
|
||||
namespace Repository.Core.Repositories.Auth
|
||||
{
|
||||
public class AuthRepository : Repository<Entities.UserAccount>, IAuthRepository
|
||||
public class AuthRepository : Repository<Domain.Core.Entities.UserAccount>, IAuthRepository
|
||||
{
|
||||
public AuthRepository(ISqlConnectionFactory connectionFactory)
|
||||
: base(connectionFactory)
|
||||
@@ -12,7 +13,7 @@ namespace Repository.Core.Repositories.Auth
|
||||
}
|
||||
|
||||
|
||||
public async Task<Entities.UserAccount> RegisterUserAsync(
|
||||
public async Task<Domain.Core.Entities.UserAccount> RegisterUserAsync(
|
||||
string username,
|
||||
string firstName,
|
||||
string lastName,
|
||||
@@ -36,7 +37,7 @@ namespace Repository.Core.Repositories.Auth
|
||||
var result = await command.ExecuteScalarAsync();
|
||||
var userAccountId = result != null ? (Guid)result : Guid.Empty;
|
||||
|
||||
return new Entities.UserAccount
|
||||
return new Domain.Core.Entities.UserAccount
|
||||
{
|
||||
UserAccountId = userAccountId,
|
||||
Username = username,
|
||||
@@ -49,7 +50,7 @@ namespace Repository.Core.Repositories.Auth
|
||||
}
|
||||
|
||||
|
||||
public async Task<Entities.UserAccount?> GetUserByEmailAsync(string email)
|
||||
public async Task<Domain.Core.Entities.UserAccount?> GetUserByEmailAsync(string email)
|
||||
{
|
||||
await using var connection = await CreateConnection();
|
||||
await using var command = connection.CreateCommand();
|
||||
@@ -63,7 +64,7 @@ namespace Repository.Core.Repositories.Auth
|
||||
}
|
||||
|
||||
|
||||
public async Task<Entities.UserAccount?> GetUserByUsernameAsync(string username)
|
||||
public async Task<Domain.Core.Entities.UserAccount?> GetUserByUsernameAsync(string username)
|
||||
{
|
||||
await using var connection = await CreateConnection();
|
||||
await using var command = connection.CreateCommand();
|
||||
@@ -76,7 +77,7 @@ namespace Repository.Core.Repositories.Auth
|
||||
return await reader.ReadAsync() ? MapToEntity(reader) : null;
|
||||
}
|
||||
|
||||
public async Task<Entities.UserCredential?> GetActiveCredentialByUserAccountIdAsync(Guid userAccountId)
|
||||
public async Task<UserCredential?> GetActiveCredentialByUserAccountIdAsync(Guid userAccountId)
|
||||
{
|
||||
await using var connection = await CreateConnection();
|
||||
await using var command = connection.CreateCommand();
|
||||
@@ -105,9 +106,9 @@ namespace Repository.Core.Repositories.Auth
|
||||
/// <summary>
|
||||
/// Maps a data reader row to a UserAccount entity.
|
||||
/// </summary>
|
||||
protected override Entities.UserAccount MapToEntity(DbDataReader reader)
|
||||
protected override Domain.Core.Entities.UserAccount MapToEntity(DbDataReader reader)
|
||||
{
|
||||
return new Entities.UserAccount
|
||||
return new Domain.Core.Entities.UserAccount
|
||||
{
|
||||
UserAccountId = reader.GetGuid(reader.GetOrdinal("UserAccountId")),
|
||||
Username = reader.GetString(reader.GetOrdinal("Username")),
|
||||
@@ -128,9 +129,9 @@ namespace Repository.Core.Repositories.Auth
|
||||
/// <summary>
|
||||
/// Maps a data reader row to a UserCredential entity.
|
||||
/// </summary>
|
||||
private static Entities.UserCredential MapToCredentialEntity(DbDataReader reader)
|
||||
private static UserCredential MapToCredentialEntity(DbDataReader reader)
|
||||
{
|
||||
var entity = new Entities.UserCredential
|
||||
var entity = new UserCredential
|
||||
{
|
||||
UserCredentialId = reader.GetGuid(reader.GetOrdinal("UserCredentialId")),
|
||||
UserAccountId = reader.GetGuid(reader.GetOrdinal("UserAccountId")),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using Domain.Core.Entities;
|
||||
|
||||
namespace Repository.Core.Repositories.Auth
|
||||
{
|
||||
/// <summary>
|
||||
@@ -16,7 +18,7 @@ namespace Repository.Core.Repositories.Auth
|
||||
/// <param name="dateOfBirth">User's date of birth</param>
|
||||
/// <param name="passwordHash">Hashed password</param>
|
||||
/// <returns>The newly created UserAccount with generated ID</returns>
|
||||
Task<Entities.UserAccount> RegisterUserAsync(
|
||||
Task<Domain.Core.Entities.UserAccount> RegisterUserAsync(
|
||||
string username,
|
||||
string firstName,
|
||||
string lastName,
|
||||
@@ -30,7 +32,7 @@ namespace Repository.Core.Repositories.Auth
|
||||
/// </summary>
|
||||
/// <param name="email">Email address to search for</param>
|
||||
/// <returns>UserAccount if found, null otherwise</returns>
|
||||
Task<Entities.UserAccount?> GetUserByEmailAsync(string email);
|
||||
Task<Domain.Core.Entities.UserAccount?> GetUserByEmailAsync(string email);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a user account by username (typically used for login).
|
||||
@@ -38,7 +40,7 @@ namespace Repository.Core.Repositories.Auth
|
||||
/// </summary>
|
||||
/// <param name="username">Username to search for</param>
|
||||
/// <returns>UserAccount if found, null otherwise</returns>
|
||||
Task<Entities.UserAccount?> GetUserByUsernameAsync(string username);
|
||||
Task<Domain.Core.Entities.UserAccount?> GetUserByUsernameAsync(string username);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the active (non-revoked) credential for a user account.
|
||||
@@ -46,7 +48,7 @@ namespace Repository.Core.Repositories.Auth
|
||||
/// </summary>
|
||||
/// <param name="userAccountId">ID of the user account</param>
|
||||
/// <returns>Active UserCredential if found, null otherwise</returns>
|
||||
Task<Entities.UserCredential?> GetActiveCredentialByUserAccountIdAsync(Guid userAccountId);
|
||||
Task<UserCredential?> GetActiveCredentialByUserAccountIdAsync(Guid userAccountId);
|
||||
|
||||
/// <summary>
|
||||
/// Rotates a user's credential by invalidating all existing credentials and creating a new one.
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
using Domain.Core.Entities;
|
||||
|
||||
|
||||
namespace Repository.Core.Repositories.UserAccount
|
||||
{
|
||||
public interface IUserAccountRepository
|
||||
{
|
||||
Task<Entities.UserAccount?> GetByIdAsync(Guid id);
|
||||
Task<IEnumerable<Entities.UserAccount>> GetAllAsync(int? limit, int? offset);
|
||||
Task UpdateAsync(Entities.UserAccount userAccount);
|
||||
Task<Domain.Core.Entities.UserAccount?> GetByIdAsync(Guid id);
|
||||
Task<IEnumerable<Domain.Core.Entities.UserAccount>> GetAllAsync(int? limit, int? offset);
|
||||
Task UpdateAsync(Domain.Core.Entities.UserAccount userAccount);
|
||||
Task DeleteAsync(Guid id);
|
||||
Task<Entities.UserAccount?> GetByUsernameAsync(string username);
|
||||
Task<Entities.UserAccount?> GetByEmailAsync(string email);
|
||||
Task<Domain.Core.Entities.UserAccount?> GetByUsernameAsync(string username);
|
||||
Task<Domain.Core.Entities.UserAccount?> GetByEmailAsync(string email);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using Domain.Core.Entities;
|
||||
using Repository.Core.Sql;
|
||||
|
||||
namespace Repository.Core.Repositories.UserAccount
|
||||
{
|
||||
public class UserAccountRepository(ISqlConnectionFactory connectionFactory)
|
||||
: Repository<Entities.UserAccount>(connectionFactory), IUserAccountRepository
|
||||
: Repository<Domain.Core.Entities.UserAccount>(connectionFactory), IUserAccountRepository
|
||||
{
|
||||
public async Task<Entities.UserAccount?> GetByIdAsync(Guid id)
|
||||
public async Task<Domain.Core.Entities.UserAccount?> GetByIdAsync(Guid id)
|
||||
{
|
||||
await using var connection = await CreateConnection();
|
||||
await using var command = connection.CreateCommand();
|
||||
@@ -20,7 +21,7 @@ namespace Repository.Core.Repositories.UserAccount
|
||||
return await reader.ReadAsync() ? MapToEntity(reader) : null;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Entities.UserAccount>> GetAllAsync(int? limit, int? offset)
|
||||
public async Task<IEnumerable<Domain.Core.Entities.UserAccount>> GetAllAsync(int? limit, int? offset)
|
||||
{
|
||||
await using var connection = await CreateConnection();
|
||||
await using var command = connection.CreateCommand();
|
||||
@@ -34,7 +35,7 @@ namespace Repository.Core.Repositories.UserAccount
|
||||
AddParameter(command, "@Offset", offset.Value);
|
||||
|
||||
await using var reader = await command.ExecuteReaderAsync();
|
||||
var users = new List<Entities.UserAccount>();
|
||||
var users = new List<Domain.Core.Entities.UserAccount>();
|
||||
|
||||
while (await reader.ReadAsync())
|
||||
{
|
||||
@@ -44,7 +45,7 @@ namespace Repository.Core.Repositories.UserAccount
|
||||
return users;
|
||||
}
|
||||
|
||||
public async Task UpdateAsync(Entities.UserAccount userAccount)
|
||||
public async Task UpdateAsync(Domain.Core.Entities.UserAccount userAccount)
|
||||
{
|
||||
await using var connection = await CreateConnection();
|
||||
await using var command = connection.CreateCommand();
|
||||
@@ -72,7 +73,7 @@ namespace Repository.Core.Repositories.UserAccount
|
||||
await command.ExecuteNonQueryAsync();
|
||||
}
|
||||
|
||||
public async Task<Entities.UserAccount?> GetByUsernameAsync(string username)
|
||||
public async Task<Domain.Core.Entities.UserAccount?> GetByUsernameAsync(string username)
|
||||
{
|
||||
await using var connection = await CreateConnection();
|
||||
await using var command = connection.CreateCommand();
|
||||
@@ -85,7 +86,7 @@ namespace Repository.Core.Repositories.UserAccount
|
||||
return await reader.ReadAsync() ? MapToEntity(reader) : null;
|
||||
}
|
||||
|
||||
public async Task<Entities.UserAccount?> GetByEmailAsync(string email)
|
||||
public async Task<Domain.Core.Entities.UserAccount?> GetByEmailAsync(string email)
|
||||
{
|
||||
await using var connection = await CreateConnection();
|
||||
await using var command = connection.CreateCommand();
|
||||
@@ -98,9 +99,9 @@ namespace Repository.Core.Repositories.UserAccount
|
||||
return await reader.ReadAsync() ? MapToEntity(reader) : null;
|
||||
}
|
||||
|
||||
protected override Entities.UserAccount MapToEntity(DbDataReader reader)
|
||||
protected override Domain.Core.Entities.UserAccount MapToEntity(DbDataReader reader)
|
||||
{
|
||||
return new Entities.UserAccount
|
||||
return new Domain.Core.Entities.UserAccount
|
||||
{
|
||||
UserAccountId = reader.GetGuid(reader.GetOrdinal("UserAccountId")),
|
||||
Username = reader.GetString(reader.GetOrdinal("Username")),
|
||||
|
||||
@@ -14,4 +14,7 @@
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.9.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Domain\Domain.Core\Domain.Core.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Repository.Core.Entities;
|
||||
using Domain.Core.Entities;
|
||||
using Repository.Core.Repositories.Auth;
|
||||
using Service.Core.Password;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Repository.Core.Entities;
|
||||
using Domain.Core.Entities;
|
||||
|
||||
namespace Service.Core.Auth;
|
||||
|
||||
@@ -6,4 +6,4 @@ public interface IAuthService
|
||||
{
|
||||
Task<UserAccount> RegisterAsync(UserAccount userAccount, string password);
|
||||
Task<UserAccount?> LoginAsync(string username, string password);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Domain\Domain.Core\Domain.Core.csproj" />
|
||||
<ProjectReference Include="..\..\Repository\Repository.Core\Repository.Core.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Repository.Core.Entities;
|
||||
using Domain.Core.Entities;
|
||||
|
||||
namespace Service.Core.User;
|
||||
|
||||
@@ -8,4 +8,4 @@ public interface IUserService
|
||||
Task<UserAccount?> GetByIdAsync(Guid id);
|
||||
|
||||
Task UpdateAsync(UserAccount userAccount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Repository.Core.Entities;
|
||||
using Domain.Core.Entities;
|
||||
using Repository.Core.Repositories.UserAccount;
|
||||
|
||||
namespace Service.Core.User;
|
||||
@@ -19,4 +19,4 @@ public class UserService(IUserAccountRepository repository) : IUserService
|
||||
{
|
||||
await repository.UpdateAsync(userAccount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user