diff --git a/web/backend/.config/dotnet-tools.json b/web/backend/.config/dotnet-tools.json
new file mode 100644
index 00000000..6e2e244c
--- /dev/null
+++ b/web/backend/.config/dotnet-tools.json
@@ -0,0 +1,13 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "csharpier": {
+ "version": "1.3.0",
+ "commands": [
+ "csharpier"
+ ],
+ "rollForward": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/web/backend/Core.slnx b/web/backend/Core.slnx
index 7c93c7ae..44d81d53 100644
--- a/web/backend/Core.slnx
+++ b/web/backend/Core.slnx
@@ -1,37 +1,35 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/web/backend/Database/Database.Migrations/Program.cs b/web/backend/Database/Database.Migrations/Program.cs
index 5ce63a50..b3d973ec 100644
--- a/web/backend/Database/Database.Migrations/Program.cs
+++ b/web/backend/Database/Database.Migrations/Program.cs
@@ -180,8 +180,7 @@ public static class Program
!bool.TryParse(
Environment.GetEnvironmentVariable("DB_TRUST_SERVER_CERTIFICATE"),
out bool parsedTrust
- )
- || parsedTrust;
+ ) || parsedTrust;
bool clearDatabase = string.Equals(
Environment.GetEnvironmentVariable("CLEAR_DATABASE"),
@@ -204,7 +203,7 @@ public static class Program
UserID = user,
Password = password,
Encrypt = true,
- TrustServerCertificate = trustServerCertificate
+ TrustServerCertificate = trustServerCertificate,
}.ConnectionString;
}
@@ -214,4 +213,4 @@ public static class Program
$"The {variableName} environment variable is not set."
);
}
-}
\ No newline at end of file
+}
diff --git a/web/backend/Database/Database.Seed/Database.Seed.csproj b/web/backend/Database/Database.Seed/Database.Seed.csproj
index 7764cd68..1235ce07 100644
--- a/web/backend/Database/Database.Seed/Database.Seed.csproj
+++ b/web/backend/Database/Database.Seed/Database.Seed.csproj
@@ -21,8 +21,7 @@
-
+
@@ -30,7 +29,9 @@
-
+
diff --git a/web/backend/Database/Database.Seed/DatabaseHelpers/ConnectionStrings.cs b/web/backend/Database/Database.Seed/DatabaseHelpers/ConnectionStrings.cs
index 9cd535d8..8a798d59 100644
--- a/web/backend/Database/Database.Seed/DatabaseHelpers/ConnectionStrings.cs
+++ b/web/backend/Database/Database.Seed/DatabaseHelpers/ConnectionStrings.cs
@@ -9,7 +9,8 @@ namespace Database.Seed.DatabaseHelpers;
public class ConnectionStrings
{
public static string SqlServerConnectionString => GetSqlServerConnectionString();
- public static string SqliteConnectionString => "Data Source=SeedData/biergarten_seed_2026-07-20T05-46-02.993511Z.sqlite";
+ public static string SqliteConnectionString =>
+ "Data Source=SeedData/biergarten_seed_2026-07-20T05-46-02.993511Z.sqlite";
private static string GetSqlServerConnectionString()
{
@@ -39,7 +40,7 @@ public class ConnectionStrings
UserID = user,
Password = password,
TrustServerCertificate = bool.Parse(trustServerCertificate),
- Encrypt = true
+ Encrypt = true,
};
return builder.ConnectionString;
diff --git a/web/backend/Database/Database.Seed/PipelineData/BreweryAddress.cs b/web/backend/Database/Database.Seed/PipelineData/BreweryAddress.cs
index 7e3628fa..b6902bb1 100644
--- a/web/backend/Database/Database.Seed/PipelineData/BreweryAddress.cs
+++ b/web/backend/Database/Database.Seed/PipelineData/BreweryAddress.cs
@@ -5,4 +5,4 @@ public sealed record BreweryAddress
public required City City { get; init; }
public required string PostalCode { get; init; }
-}
\ No newline at end of file
+}
diff --git a/web/backend/Database/Database.Seed/PipelineData/BreweryRecord.cs b/web/backend/Database/Database.Seed/PipelineData/BreweryRecord.cs
index 04245a9a..93c67e9a 100644
--- a/web/backend/Database/Database.Seed/PipelineData/BreweryRecord.cs
+++ b/web/backend/Database/Database.Seed/PipelineData/BreweryRecord.cs
@@ -5,4 +5,4 @@ public sealed record BreweryRecord
public required BreweryAddress Address { get; init; }
public required BreweryResult Brewery { get; init; }
-}
\ No newline at end of file
+}
diff --git a/web/backend/Database/Database.Seed/PipelineData/BreweryResult.cs b/web/backend/Database/Database.Seed/PipelineData/BreweryResult.cs
index 0b10b48b..13d42f5f 100644
--- a/web/backend/Database/Database.Seed/PipelineData/BreweryResult.cs
+++ b/web/backend/Database/Database.Seed/PipelineData/BreweryResult.cs
@@ -9,4 +9,4 @@ public sealed record BreweryResult
public required string NameLocal { get; init; }
public required string DescriptionLocal { get; init; }
-}
\ No newline at end of file
+}
diff --git a/web/backend/Database/Database.Seed/PipelineData/City.cs b/web/backend/Database/Database.Seed/PipelineData/City.cs
index e8d3cf04..88de9e2e 100644
--- a/web/backend/Database/Database.Seed/PipelineData/City.cs
+++ b/web/backend/Database/Database.Seed/PipelineData/City.cs
@@ -15,4 +15,4 @@ public sealed record City
public IReadOnlyList LocalLanguages { get; init; } = [];
public required PostalCodeSpec PostalCode { get; init; }
-}
\ No newline at end of file
+}
diff --git a/web/backend/Database/Database.Seed/PipelineData/PostalCodeSpec.cs b/web/backend/Database/Database.Seed/PipelineData/PostalCodeSpec.cs
index d5581e31..d367da6b 100644
--- a/web/backend/Database/Database.Seed/PipelineData/PostalCodeSpec.cs
+++ b/web/backend/Database/Database.Seed/PipelineData/PostalCodeSpec.cs
@@ -7,4 +7,4 @@ public sealed record PostalCodeSpec
public IReadOnlyList CityRegexes { get; init; } = [];
public IReadOnlyList Examples { get; init; } = [];
-}
\ No newline at end of file
+}
diff --git a/web/backend/Database/Database.Seed/PipelineData/UserAddress.cs b/web/backend/Database/Database.Seed/PipelineData/UserAddress.cs
index 090a130f..6b63a17c 100644
--- a/web/backend/Database/Database.Seed/PipelineData/UserAddress.cs
+++ b/web/backend/Database/Database.Seed/PipelineData/UserAddress.cs
@@ -5,4 +5,4 @@ public sealed record UserAddress
public required City City { get; init; }
public required string PostalCode { get; init; }
-}
\ No newline at end of file
+}
diff --git a/web/backend/Database/Database.Seed/PipelineData/UserRecord.cs b/web/backend/Database/Database.Seed/PipelineData/UserRecord.cs
index 7d04f8be..fa8f0dc2 100644
--- a/web/backend/Database/Database.Seed/PipelineData/UserRecord.cs
+++ b/web/backend/Database/Database.Seed/PipelineData/UserRecord.cs
@@ -9,4 +9,4 @@ public sealed record UserRecord
public required string Email { get; init; }
public required string DateOfBirth { get; init; }
-}
\ No newline at end of file
+}
diff --git a/web/backend/Database/Database.Seed/PipelineData/UserResult.cs b/web/backend/Database/Database.Seed/PipelineData/UserResult.cs
index 4aee2333..0e53881d 100644
--- a/web/backend/Database/Database.Seed/PipelineData/UserResult.cs
+++ b/web/backend/Database/Database.Seed/PipelineData/UserResult.cs
@@ -13,4 +13,4 @@ public sealed record UserResult
public required string Bio { get; init; }
public required float ActivityWeight { get; init; }
-}
\ No newline at end of file
+}
diff --git a/web/backend/Database/Database.Seed/Program.cs b/web/backend/Database/Database.Seed/Program.cs
index 8d06ae88..dc6b9e88 100644
--- a/web/backend/Database/Database.Seed/Program.cs
+++ b/web/backend/Database/Database.Seed/Program.cs
@@ -1,23 +1,20 @@
-
-
using Database.Seed.DatabaseHelpers;
using Database.Seed.PipelineData;
using Database.Seed.Sqlite;
+using Domain.Entities;
using Features.Auth.DependencyInjection;
using Features.Auth.Dtos;
using Features.Auth.Repository;
using Features.Breweries.DependencyInjection;
using Features.Breweries.Repository;
+using idunno.Password;
+using Infrastructure.PasswordHashing;
using Infrastructure.Sql;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
-using idunno.Password;
-using Infrastructure.PasswordHashing;
-using Domain.Entities;
-
-async static Task main()
+static async Task main()
{
IReadOnlyList breweries;
IReadOnlyList users;
@@ -61,16 +58,15 @@ async static Task main()
}
Console.ForegroundColor = ConsoleColor.Green;
- Console.WriteLine(
- $"Loaded {breweries.Count} breweries."
- );
+ Console.WriteLine($"Loaded {breweries.Count} breweries.");
Console.ResetColor();
for (int i = 0; i < breweries.Count; i++)
{
BreweryRecord brewery = breweries[i];
Console.WriteLine(
- $"{i + 1}:\t{brewery.Brewery.NameEn}\t({brewery.Address.City.CityName}, {brewery.Address.City.Country})");
+ $"{i + 1}:\t{brewery.Brewery.NameEn}\t({brewery.Address.City.CityName}, {brewery.Address.City.Country})"
+ );
}
Console.ForegroundColor = ConsoleColor.Green;
@@ -87,7 +83,11 @@ async static Task main()
// Generate a password that is 64 characters long with 10 digits, 10 symbols,
// allowing upper and lower case letters, disallowing repeat characters.
- string generatedPassword = PasswordGenerator.Generate(length: 64, numberOfDigits: 10, numberOfSymbols: 10);
+ string generatedPassword = PasswordGenerator.Generate(
+ length: 64,
+ numberOfDigits: 10,
+ numberOfSymbols: 10
+ );
string hashedPassword = passwordInfrastructure.Hash(generatedPassword);
UserRegistrationDto registrationDto = new(
@@ -102,7 +102,9 @@ async static Task main()
try
{
UserAccount createdUser = await authRepository.RegisterUserAsync(registrationDto);
- Console.WriteLine($"Created user: {createdUser.Username} ({createdUser.UserAccountId})");
+ Console.WriteLine(
+ $"Created user: {createdUser.Username} ({createdUser.UserAccountId})"
+ );
}
catch (Exception ex)
{
@@ -110,11 +112,9 @@ async static Task main()
Console.WriteLine($"Error creating user {username}: {ex.Message}");
Console.ResetColor();
}
-
}
return 0;
}
-
return await main();
diff --git a/web/backend/Database/Database.Seed/Sqlite/PipelineSeedDataReader.cs b/web/backend/Database/Database.Seed/Sqlite/PipelineSeedDataReader.cs
index d7b16939..050e416b 100644
--- a/web/backend/Database/Database.Seed/Sqlite/PipelineSeedDataReader.cs
+++ b/web/backend/Database/Database.Seed/Sqlite/PipelineSeedDataReader.cs
@@ -25,11 +25,11 @@ public sealed class PipelineSeedDataReader
IReadOnlyDictionary cities = ReadCities(connection);
const string sql = """
- SELECT b.name_en, b.description_en, b.name_local, b.description_local,
- ba.city_id, ba.postal_code
- FROM breweries b
- JOIN brewery_addresses ba ON ba.brewery_id = b.id;
- """;
+ SELECT b.name_en, b.description_en, b.name_local, b.description_local,
+ ba.city_id, ba.postal_code
+ FROM breweries b
+ JOIN brewery_addresses ba ON ba.brewery_id = b.id;
+ """;
using SqliteCommand command = new(sql, connection);
using SqliteDataReader reader = command.ExecuteReader();
@@ -44,13 +44,13 @@ public sealed class PipelineSeedDataReader
NameEn = reader.GetString(0),
DescriptionEn = reader.GetString(1),
NameLocal = reader.GetString(2),
- DescriptionLocal = reader.GetString(3)
+ DescriptionLocal = reader.GetString(3),
},
Address = new BreweryAddress
{
City = cities[reader.GetInt64(4)],
- PostalCode = reader.GetString(5)
- }
+ PostalCode = reader.GetString(5),
+ },
}
);
@@ -65,12 +65,12 @@ public sealed class PipelineSeedDataReader
IReadOnlyDictionary cities = ReadCities(connection);
const string sql = """
- SELECT u.first_name, u.last_name, u.gender, u.username, u.bio,
- u.activity_weight, u.email, u.date_of_birth,
- ua.city_id, ua.postal_code
- FROM users u
- JOIN user_addresses ua ON ua.user_id = u.id;
- """;
+ SELECT u.first_name, u.last_name, u.gender, u.username, u.bio,
+ u.activity_weight, u.email, u.date_of_birth,
+ ua.city_id, ua.postal_code
+ FROM users u
+ JOIN user_addresses ua ON ua.user_id = u.id;
+ """;
using SqliteCommand command = new(sql, connection);
using SqliteDataReader reader = command.ExecuteReader();
@@ -87,15 +87,15 @@ public sealed class PipelineSeedDataReader
Gender = reader.GetString(2),
Username = reader.GetString(3),
Bio = reader.GetString(4),
- ActivityWeight = (float)reader.GetDouble(5)
+ ActivityWeight = (float)reader.GetDouble(5),
},
Email = reader.GetString(6),
DateOfBirth = reader.GetString(7),
Address = new UserAddress
{
City = cities[reader.GetInt64(8)],
- PostalCode = reader.GetString(9)
- }
+ PostalCode = reader.GetString(9),
+ },
}
);
@@ -105,18 +105,18 @@ public sealed class PipelineSeedDataReader
private static IReadOnlyDictionary ReadCities(SqliteConnection connection)
{
const string sql = """
- SELECT
- id,
- city,
- state_province,
- iso3166_2,
- country,
- iso3166_1,
- local_languages_json,
- postal_code_country_format_regex,
- postal_code_city_regex_json
- FROM cities;
- """;
+ SELECT
+ id,
+ city,
+ state_province,
+ iso3166_2,
+ country,
+ iso3166_1,
+ local_languages_json,
+ postal_code_country_format_regex,
+ postal_code_city_regex_json
+ FROM cities;
+ """;
using SqliteCommand command = new(sql, connection);
using SqliteDataReader reader = command.ExecuteReader();
@@ -144,14 +144,13 @@ public sealed class PipelineSeedDataReader
PostalCode = new PostalCodeSpec
{
CountryFormatRegex = reader.GetString(countryFormatRegexBindIndex),
- CityRegexes = DeserializeStringArray(reader.GetString(cityRegexesBindIndex))
- }
+ CityRegexes = DeserializeStringArray(reader.GetString(cityRegexesBindIndex)),
+ },
};
return cities;
}
-
private static IReadOnlyList DeserializeStringArray(string json)
{
return JsonSerializer.Deserialize>(json) ?? [];
diff --git a/web/backend/Database/Program.cs b/web/backend/Database/Program.cs
index f486b067..1eff3e2c 100644
--- a/web/backend/Database/Program.cs
+++ b/web/backend/Database/Program.cs
@@ -1,18 +1,17 @@
namespace Database.Seed;
-
public interface IExportDatabase
{
- void SeedLocations(IEnumerable locations);
- void SeedUsers(IEnumerable users);
+ void SeedLocations(IEnumerable locations);
+ void SeedUsers(IEnumerable users);
- void SeedBreweries(IEnumerable breweries);
+ void SeedBreweries(IEnumerable breweries);
}
public interface IImportDatabase
{
- IEnumerable GetLocations();
- IEnumerable GetUsers();
+ IEnumerable GetLocations();
+ IEnumerable GetUsers();
- IEnumerable GetBreweries();
+ IEnumerable GetBreweries();
}
diff --git a/web/backend/Features/Features.Auth/Commands/RegisterUser/RegisterUserHandler.cs b/web/backend/Features/Features.Auth/Commands/RegisterUser/RegisterUserHandler.cs
index 2663a5ef..cf475383 100644
--- a/web/backend/Features/Features.Auth/Commands/RegisterUser/RegisterUserHandler.cs
+++ b/web/backend/Features/Features.Auth/Commands/RegisterUser/RegisterUserHandler.cs
@@ -34,12 +34,14 @@ public class RegisterUserHandler(
string hashed = passwordInfrastructure.Hash(request.Password);
UserAccount createdUser = await authRepo.RegisterUserAsync(
- new UserRegistrationDto(request.Username,
- request.FirstName,
- request.LastName,
- request.Email,
- request.DateOfBirth,
- hashed)
+ new UserRegistrationDto(
+ request.Username,
+ request.FirstName,
+ request.LastName,
+ request.Email,
+ request.DateOfBirth,
+ hashed
+ )
);
string accessToken = tokenService.GenerateAccessToken(createdUser);
diff --git a/web/backend/Features/Features.Auth/Repository/AuthRepository.cs b/web/backend/Features/Features.Auth/Repository/AuthRepository.cs
index 020c2458..ba6a9725 100644
--- a/web/backend/Features/Features.Auth/Repository/AuthRepository.cs
+++ b/web/backend/Features/Features.Auth/Repository/AuthRepository.cs
@@ -26,9 +26,7 @@ public class AuthRepository(ISqlConnectionFactory connectionFactory)
/// subsequent lookup to fail.
///
/// Thrown when the newly registered user cannot be retrieved after registration.
- public async Task RegisterUserAsync(
- UserRegistrationDto userRegistrationDto
- )
+ public async Task RegisterUserAsync(UserRegistrationDto userRegistrationDto)
{
await using DbConnection connection = await CreateConnection();
await using DbCommand command = connection.CreateCommand();
@@ -36,8 +34,7 @@ public class AuthRepository(ISqlConnectionFactory connectionFactory)
command.CommandText = "USP_RegisterUser";
command.CommandType = CommandType.StoredProcedure;
- var (username, firstName, lastName, email, dateOfBirth, passwordHash) =
- userRegistrationDto;
+ var (username, firstName, lastName, email, dateOfBirth, passwordHash) = userRegistrationDto;
AddParameter(command, "@Username", username);
AddParameter(command, "@FirstName", firstName);
diff --git a/web/backend/Features/Features.Auth/Repository/IAuthRepository.cs b/web/backend/Features/Features.Auth/Repository/IAuthRepository.cs
index 092cfd59..c5ac13a0 100644
--- a/web/backend/Features/Features.Auth/Repository/IAuthRepository.cs
+++ b/web/backend/Features/Features.Auth/Repository/IAuthRepository.cs
@@ -2,14 +2,13 @@ using Domain.Entities;
using Features.Auth.Dtos;
namespace Features.Auth.Repository;
+
///
/// Repository for authentication-related database operations including user registration and credential management.
///
public interface IAuthRepository
{
- Task RegisterUserAsync(
- UserRegistrationDto userRegistrationDto
- );
+ Task RegisterUserAsync(UserRegistrationDto userRegistrationDto);
Task GetUserByEmailAsync(string email);