diff --git a/.gitignore b/.gitignore
index 69bbe5d..37f801a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -430,4 +430,5 @@ FodyWeavers.xsd
.DS_Store
*/data_source/other
-.fake
\ No newline at end of file
+.fake
+.idea
\ No newline at end of file
diff --git a/BusinessLayer/Services/UserService.cs b/BusinessLayer/Services/UserService.cs
index 1ab5e1a..a923393 100644
--- a/BusinessLayer/Services/UserService.cs
+++ b/BusinessLayer/Services/UserService.cs
@@ -1,5 +1,6 @@
using DataAccessLayer;
using DataAccessLayer.Entities;
+using DataAccessLayer.Repositories;
namespace BusinessLayer.Services
{
diff --git a/DALTests/UserAccountRepositoryTests.cs b/DALTests/UserAccountRepositoryTests.cs
index d02d34f..34e5229 100644
--- a/DALTests/UserAccountRepositoryTests.cs
+++ b/DALTests/UserAccountRepositoryTests.cs
@@ -1,20 +1,12 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
using DataAccessLayer;
using DataAccessLayer.Entities;
-using Xunit;
+using DataAccessLayer.Repositories;
namespace DALTests
{
public class UserAccountRepositoryTests
{
- private readonly IUserAccountRepository _repository;
-
- public UserAccountRepositoryTests()
- {
- _repository = new UserAccountRepository();
- }
+ private readonly IUserAccountRepository _repository = new UserAccountRepository();
[Fact]
public void Add_ShouldInsertUserAccount()
@@ -22,7 +14,7 @@ namespace DALTests
// Arrange
var userAccount = new UserAccount
{
- UserAccountID = Guid.NewGuid(),
+ UserAccountId = Guid.NewGuid(),
Username = "testuser",
FirstName = "Test",
LastName = "User",
@@ -33,7 +25,7 @@ namespace DALTests
// Act
_repository.Add(userAccount);
- var retrievedUser = _repository.GetById(userAccount.UserAccountID);
+ var retrievedUser = _repository.GetById(userAccount.UserAccountId);
// Assert
Assert.NotNull(retrievedUser);
@@ -47,7 +39,7 @@ namespace DALTests
var userId = Guid.NewGuid();
var userAccount = new UserAccount
{
- UserAccountID = userId,
+ UserAccountId = userId,
Username = "existinguser",
FirstName = "Existing",
LastName = "User",
@@ -62,7 +54,7 @@ namespace DALTests
// Assert
Assert.NotNull(retrievedUser);
- Assert.Equal(userId, retrievedUser.UserAccountID);
+ Assert.Equal(userId, retrievedUser.UserAccountId);
}
[Fact]
@@ -71,7 +63,7 @@ namespace DALTests
// Arrange
var userAccount = new UserAccount
{
- UserAccountID = Guid.NewGuid(),
+ UserAccountId = Guid.NewGuid(),
Username = "updatableuser",
FirstName = "Updatable",
LastName = "User",
@@ -84,7 +76,7 @@ namespace DALTests
// Act
userAccount.FirstName = "Updated";
_repository.Update(userAccount);
- var updatedUser = _repository.GetById(userAccount.UserAccountID);
+ var updatedUser = _repository.GetById(userAccount.UserAccountId);
// Assert
Assert.NotNull(updatedUser);
@@ -97,7 +89,7 @@ namespace DALTests
// Arrange
var userAccount = new UserAccount
{
- UserAccountID = Guid.NewGuid(),
+ UserAccountId = Guid.NewGuid(),
Username = "deletableuser",
FirstName = "Deletable",
LastName = "User",
@@ -108,8 +100,8 @@ namespace DALTests
_repository.Add(userAccount);
// Act
- _repository.Delete(userAccount.UserAccountID);
- var deletedUser = _repository.GetById(userAccount.UserAccountID);
+ _repository.Delete(userAccount.UserAccountId);
+ var deletedUser = _repository.GetById(userAccount.UserAccountId);
// Assert
Assert.Null(deletedUser);
@@ -121,7 +113,7 @@ namespace DALTests
// Arrange
var user1 = new UserAccount
{
- UserAccountID = Guid.NewGuid(),
+ UserAccountId = Guid.NewGuid(),
Username = "user1",
FirstName = "User",
LastName = "One",
@@ -131,7 +123,7 @@ namespace DALTests
};
var user2 = new UserAccount
{
- UserAccountID = Guid.NewGuid(),
+ UserAccountId = Guid.NewGuid(),
Username = "user2",
FirstName = "User",
LastName = "Two",
@@ -158,7 +150,7 @@ namespace DALTests
{
new UserAccount
{
- UserAccountID = Guid.NewGuid(),
+ UserAccountId = Guid.NewGuid(),
Username = $"pageuser_{Guid.NewGuid():N}",
FirstName = "Page",
LastName = "User",
@@ -168,7 +160,7 @@ namespace DALTests
},
new UserAccount
{
- UserAccountID = Guid.NewGuid(),
+ UserAccountId = Guid.NewGuid(),
Username = $"pageuser_{Guid.NewGuid():N}",
FirstName = "Page",
LastName = "User",
@@ -178,7 +170,7 @@ namespace DALTests
},
new UserAccount
{
- UserAccountID = Guid.NewGuid(),
+ UserAccountId = Guid.NewGuid(),
Username = $"pageuser_{Guid.NewGuid():N}",
FirstName = "Page",
LastName = "User",
diff --git a/DBSeed/DBSeed.csproj b/DBSeed/DBSeed.csproj
index 958ec61..54b70c3 100644
--- a/DBSeed/DBSeed.csproj
+++ b/DBSeed/DBSeed.csproj
@@ -12,6 +12,10 @@
Include="Konscious.Security.Cryptography.Argon2"
Version="1.3.1"
/>
-
+
+
+
+
+
diff --git a/DBSeed/ISeeder.cs b/DBSeed/ISeeder.cs
index 4624827..1ecf897 100644
--- a/DBSeed/ISeeder.cs
+++ b/DBSeed/ISeeder.cs
@@ -1,6 +1,9 @@
using Microsoft.Data.SqlClient;
-interface ISeeder
+namespace DBSeed
{
- Task SeedAsync(SqlConnection connection);
+ internal interface ISeeder
+ {
+ Task SeedAsync(SqlConnection connection);
+ }
}
\ No newline at end of file
diff --git a/DBSeed/LocationSeeder.cs b/DBSeed/LocationSeeder.cs
index 983921b..52d3d78 100644
--- a/DBSeed/LocationSeeder.cs
+++ b/DBSeed/LocationSeeder.cs
@@ -1,330 +1,328 @@
using System.Data;
using Microsoft.Data.SqlClient;
-namespace DBSeed;
-
-class LocationSeeder : ISeeder
+namespace DBSeed
{
- private static readonly IReadOnlyList<(
- string CountryName,
- string CountryCode
- )> Countries =
- [
- ("Canada", "CA"),
- ("Mexico", "MX"),
- ("United States", "US"),
- ];
- private static readonly IReadOnlyList<(
- string StateProvinceName,
- string StateProvinceCode,
- string CountryCode
- )> States =
- [
- ("Alabama", "US-AL", "US"),
- ("Alaska", "US-AK", "US"),
- ("Arizona", "US-AZ", "US"),
- ("Arkansas", "US-AR", "US"),
- ("California", "US-CA", "US"),
- ("Colorado", "US-CO", "US"),
- ("Connecticut", "US-CT", "US"),
- ("Delaware", "US-DE", "US"),
- ("Florida", "US-FL", "US"),
- ("Georgia", "US-GA", "US"),
- ("Hawaii", "US-HI", "US"),
- ("Idaho", "US-ID", "US"),
- ("Illinois", "US-IL", "US"),
- ("Indiana", "US-IN", "US"),
- ("Iowa", "US-IA", "US"),
- ("Kansas", "US-KS", "US"),
- ("Kentucky", "US-KY", "US"),
- ("Louisiana", "US-LA", "US"),
- ("Maine", "US-ME", "US"),
- ("Maryland", "US-MD", "US"),
- ("Massachusetts", "US-MA", "US"),
- ("Michigan", "US-MI", "US"),
- ("Minnesota", "US-MN", "US"),
- ("Mississippi", "US-MS", "US"),
- ("Missouri", "US-MO", "US"),
- ("Montana", "US-MT", "US"),
- ("Nebraska", "US-NE", "US"),
- ("Nevada", "US-NV", "US"),
- ("New Hampshire", "US-NH", "US"),
- ("New Jersey", "US-NJ", "US"),
- ("New Mexico", "US-NM", "US"),
- ("New York", "US-NY", "US"),
- ("North Carolina", "US-NC", "US"),
- ("North Dakota", "US-ND", "US"),
- ("Ohio", "US-OH", "US"),
- ("Oklahoma", "US-OK", "US"),
- ("Oregon", "US-OR", "US"),
- ("Pennsylvania", "US-PA", "US"),
- ("Rhode Island", "US-RI", "US"),
- ("South Carolina", "US-SC", "US"),
- ("South Dakota", "US-SD", "US"),
- ("Tennessee", "US-TN", "US"),
- ("Texas", "US-TX", "US"),
- ("Utah", "US-UT", "US"),
- ("Vermont", "US-VT", "US"),
- ("Virginia", "US-VA", "US"),
- ("Washington", "US-WA", "US"),
- ("West Virginia", "US-WV", "US"),
- ("Wisconsin", "US-WI", "US"),
- ("Wyoming", "US-WY", "US"),
- ("District of Columbia", "US-DC", "US"),
- ("Puerto Rico", "US-PR", "US"),
- ("U.S. Virgin Islands", "US-VI", "US"),
- ("Guam", "US-GU", "US"),
- ("Northern Mariana Islands", "US-MP", "US"),
- ("American Samoa", "US-AS", "US"),
- ("Ontario", "CA-ON", "CA"),
- ("Québec", "CA-QC", "CA"),
- ("Nova Scotia", "CA-NS", "CA"),
- ("New Brunswick", "CA-NB", "CA"),
- ("Manitoba", "CA-MB", "CA"),
- ("British Columbia", "CA-BC", "CA"),
- ("Prince Edward Island", "CA-PE", "CA"),
- ("Saskatchewan", "CA-SK", "CA"),
- ("Alberta", "CA-AB", "CA"),
- ("Newfoundland and Labrador", "CA-NL", "CA"),
- ("Northwest Territories", "CA-NT", "CA"),
- ("Yukon", "CA-YT", "CA"),
- ("Nunavut", "CA-NU", "CA"),
- ("Aguascalientes", "MX-AGU", "MX"),
- ("Baja California", "MX-BCN", "MX"),
- ("Baja California Sur", "MX-BCS", "MX"),
- ("Campeche", "MX-CAM", "MX"),
- ("Chiapas", "MX-CHP", "MX"),
- ("Chihuahua", "MX-CHH", "MX"),
- ("Coahuila de Zaragoza", "MX-COA", "MX"),
- ("Colima", "MX-COL", "MX"),
- ("Durango", "MX-DUR", "MX"),
- ("Guanajuato", "MX-GUA", "MX"),
- ("Guerrero", "MX-GRO", "MX"),
- ("Hidalgo", "MX-HID", "MX"),
- ("Jalisco", "MX-JAL", "MX"),
- ("México State", "MX-MEX", "MX"),
- ("Michoacán de Ocampo", "MX-MIC", "MX"),
- ("Morelos", "MX-MOR", "MX"),
- ("Nayarit", "MX-NAY", "MX"),
- ("Nuevo León", "MX-NLE", "MX"),
- ("Oaxaca", "MX-OAX", "MX"),
- ("Puebla", "MX-PUE", "MX"),
- ("Querétaro", "MX-QUE", "MX"),
- ("Quintana Roo", "MX-ROO", "MX"),
- ("San Luis Potosí", "MX-SLP", "MX"),
- ("Sinaloa", "MX-SIN", "MX"),
- ("Sonora", "MX-SON", "MX"),
- ("Tabasco", "MX-TAB", "MX"),
- ("Tamaulipas", "MX-TAM", "MX"),
- ("Tlaxcala", "MX-TLA", "MX"),
- ("Veracruz de Ignacio de la Llave", "MX-VER", "MX"),
- ("Yucatán", "MX-YUC", "MX"),
- ("Zacatecas", "MX-ZAC", "MX"),
- ("Ciudad de México", "MX-CMX", "MX"),
- ];
-
- private static readonly IReadOnlyList<(
- string StateProvinceCode,
- string CityName
- )> Cities =
- [
- ("US-CA", "Los Angeles"),
- ("US-CA", "San Diego"),
- ("US-CA", "San Francisco"),
- ("US-CA", "Sacramento"),
- ("US-TX", "Houston"),
- ("US-TX", "Dallas"),
- ("US-TX", "Austin"),
- ("US-TX", "San Antonio"),
- ("US-FL", "Miami"),
- ("US-FL", "Orlando"),
- ("US-FL", "Tampa"),
- ("US-NY", "New York"),
- ("US-NY", "Buffalo"),
- ("US-NY", "Rochester"),
- ("US-IL", "Chicago"),
- ("US-IL", "Springfield"),
- ("US-PA", "Philadelphia"),
- ("US-PA", "Pittsburgh"),
- ("US-AZ", "Phoenix"),
- ("US-AZ", "Tucson"),
- ("US-CO", "Denver"),
- ("US-CO", "Colorado Springs"),
- ("US-MA", "Boston"),
- ("US-MA", "Worcester"),
- ("US-WA", "Seattle"),
- ("US-WA", "Spokane"),
- ("US-GA", "Atlanta"),
- ("US-GA", "Savannah"),
- ("US-NV", "Las Vegas"),
- ("US-NV", "Reno"),
- ("US-MI", "Detroit"),
- ("US-MI", "Grand Rapids"),
- ("US-MN", "Minneapolis"),
- ("US-MN", "Saint Paul"),
- ("US-OH", "Columbus"),
- ("US-OH", "Cleveland"),
- ("US-OR", "Portland"),
- ("US-OR", "Salem"),
- ("US-TN", "Nashville"),
- ("US-TN", "Memphis"),
- ("US-VA", "Richmond"),
- ("US-VA", "Virginia Beach"),
- ("US-MD", "Baltimore"),
- ("US-MD", "Frederick"),
- ("US-DC", "Washington"),
- ("US-UT", "Salt Lake City"),
- ("US-UT", "Provo"),
- ("US-LA", "New Orleans"),
- ("US-LA", "Baton Rouge"),
- ("US-KY", "Louisville"),
- ("US-KY", "Lexington"),
- ("US-IA", "Des Moines"),
- ("US-IA", "Cedar Rapids"),
- ("US-OK", "Oklahoma City"),
- ("US-OK", "Tulsa"),
- ("US-NE", "Omaha"),
- ("US-NE", "Lincoln"),
- ("US-MO", "Kansas City"),
- ("US-MO", "St. Louis"),
- ("US-NC", "Charlotte"),
- ("US-NC", "Raleigh"),
- ("US-SC", "Columbia"),
- ("US-SC", "Charleston"),
- ("US-WI", "Milwaukee"),
- ("US-WI", "Madison"),
- ("US-MN", "Duluth"),
- ("US-AK", "Anchorage"),
- ("US-HI", "Honolulu"),
- ("CA-ON", "Toronto"),
- ("CA-ON", "Ottawa"),
- ("CA-QC", "Montréal"),
- ("CA-QC", "Québec City"),
- ("CA-BC", "Vancouver"),
- ("CA-BC", "Victoria"),
- ("CA-AB", "Calgary"),
- ("CA-AB", "Edmonton"),
- ("CA-MB", "Winnipeg"),
- ("CA-NS", "Halifax"),
- ("CA-SK", "Saskatoon"),
- ("CA-SK", "Regina"),
- ("CA-NB", "Moncton"),
- ("CA-NB", "Saint John"),
- ("CA-PE", "Charlottetown"),
- ("CA-NL", "St. John's"),
- ("CA-ON", "Hamilton"),
- ("CA-ON", "London"),
- ("CA-QC", "Gatineau"),
- ("CA-QC", "Laval"),
- ("CA-BC", "Kelowna"),
- ("CA-AB", "Red Deer"),
- ("CA-MB", "Brandon"),
- ("MX-CMX", "Ciudad de México"),
- ("MX-JAL", "Guadalajara"),
- ("MX-NLE", "Monterrey"),
- ("MX-PUE", "Puebla"),
- ("MX-ROO", "Cancún"),
- ("MX-GUA", "Guanajuato"),
- ("MX-MIC", "Morelia"),
- ("MX-BCN", "Tijuana"),
- ("MX-JAL", "Zapopan"),
- ("MX-NLE", "San Nicolás"),
- ("MX-CAM", "Campeche"),
- ("MX-TAB", "Villahermosa"),
- ("MX-VER", "Veracruz"),
- ("MX-OAX", "Oaxaca"),
- ("MX-SLP", "San Luis Potosí"),
- ("MX-CHH", "Chihuahua"),
- ("MX-AGU", "Aguascalientes"),
- ("MX-MEX", "Toluca"),
- ("MX-COA", "Saltillo"),
- ("MX-BCS", "La Paz"),
- ("MX-NAY", "Tepic"),
- ("MX-ZAC", "Zacatecas"),
- ];
-
- public async Task SeedAsync(SqlConnection connection)
+ internal class LocationSeeder : ISeeder
{
- foreach (var (countryName, countryCode) in Countries)
+ private static readonly IReadOnlyList<(
+ string CountryName,
+ string CountryCode
+ )> Countries =
+ [
+ ("Canada", "CA"),
+ ("Mexico", "MX"),
+ ("United States", "US"),
+ ];
+
+ private static IReadOnlyList<(string StateProvinceName, string StateProvinceCode, string CountryCode)> States
{
- await CreateCountryAsync(connection, countryName, countryCode);
+ get;
+ } =
+ [
+ ("Alabama", "US-AL", "US"),
+ ("Alaska", "US-AK", "US"),
+ ("Arizona", "US-AZ", "US"),
+ ("Arkansas", "US-AR", "US"),
+ ("California", "US-CA", "US"),
+ ("Colorado", "US-CO", "US"),
+ ("Connecticut", "US-CT", "US"),
+ ("Delaware", "US-DE", "US"),
+ ("Florida", "US-FL", "US"),
+ ("Georgia", "US-GA", "US"),
+ ("Hawaii", "US-HI", "US"),
+ ("Idaho", "US-ID", "US"),
+ ("Illinois", "US-IL", "US"),
+ ("Indiana", "US-IN", "US"),
+ ("Iowa", "US-IA", "US"),
+ ("Kansas", "US-KS", "US"),
+ ("Kentucky", "US-KY", "US"),
+ ("Louisiana", "US-LA", "US"),
+ ("Maine", "US-ME", "US"),
+ ("Maryland", "US-MD", "US"),
+ ("Massachusetts", "US-MA", "US"),
+ ("Michigan", "US-MI", "US"),
+ ("Minnesota", "US-MN", "US"),
+ ("Mississippi", "US-MS", "US"),
+ ("Missouri", "US-MO", "US"),
+ ("Montana", "US-MT", "US"),
+ ("Nebraska", "US-NE", "US"),
+ ("Nevada", "US-NV", "US"),
+ ("New Hampshire", "US-NH", "US"),
+ ("New Jersey", "US-NJ", "US"),
+ ("New Mexico", "US-NM", "US"),
+ ("New York", "US-NY", "US"),
+ ("North Carolina", "US-NC", "US"),
+ ("North Dakota", "US-ND", "US"),
+ ("Ohio", "US-OH", "US"),
+ ("Oklahoma", "US-OK", "US"),
+ ("Oregon", "US-OR", "US"),
+ ("Pennsylvania", "US-PA", "US"),
+ ("Rhode Island", "US-RI", "US"),
+ ("South Carolina", "US-SC", "US"),
+ ("South Dakota", "US-SD", "US"),
+ ("Tennessee", "US-TN", "US"),
+ ("Texas", "US-TX", "US"),
+ ("Utah", "US-UT", "US"),
+ ("Vermont", "US-VT", "US"),
+ ("Virginia", "US-VA", "US"),
+ ("Washington", "US-WA", "US"),
+ ("West Virginia", "US-WV", "US"),
+ ("Wisconsin", "US-WI", "US"),
+ ("Wyoming", "US-WY", "US"),
+ ("District of Columbia", "US-DC", "US"),
+ ("Puerto Rico", "US-PR", "US"),
+ ("U.S. Virgin Islands", "US-VI", "US"),
+ ("Guam", "US-GU", "US"),
+ ("Northern Mariana Islands", "US-MP", "US"),
+ ("American Samoa", "US-AS", "US"),
+ ("Ontario", "CA-ON", "CA"),
+ ("Québec", "CA-QC", "CA"),
+ ("Nova Scotia", "CA-NS", "CA"),
+ ("New Brunswick", "CA-NB", "CA"),
+ ("Manitoba", "CA-MB", "CA"),
+ ("British Columbia", "CA-BC", "CA"),
+ ("Prince Edward Island", "CA-PE", "CA"),
+ ("Saskatchewan", "CA-SK", "CA"),
+ ("Alberta", "CA-AB", "CA"),
+ ("Newfoundland and Labrador", "CA-NL", "CA"),
+ ("Northwest Territories", "CA-NT", "CA"),
+ ("Yukon", "CA-YT", "CA"),
+ ("Nunavut", "CA-NU", "CA"),
+ ("Aguascalientes", "MX-AGU", "MX"),
+ ("Baja California", "MX-BCN", "MX"),
+ ("Baja California Sur", "MX-BCS", "MX"),
+ ("Campeche", "MX-CAM", "MX"),
+ ("Chiapas", "MX-CHP", "MX"),
+ ("Chihuahua", "MX-CHH", "MX"),
+ ("Coahuila de Zaragoza", "MX-COA", "MX"),
+ ("Colima", "MX-COL", "MX"),
+ ("Durango", "MX-DUR", "MX"),
+ ("Guanajuato", "MX-GUA", "MX"),
+ ("Guerrero", "MX-GRO", "MX"),
+ ("Hidalgo", "MX-HID", "MX"),
+ ("Jalisco", "MX-JAL", "MX"),
+ ("México State", "MX-MEX", "MX"),
+ ("Michoacán de Ocampo", "MX-MIC", "MX"),
+ ("Morelos", "MX-MOR", "MX"),
+ ("Nayarit", "MX-NAY", "MX"),
+ ("Nuevo León", "MX-NLE", "MX"),
+ ("Oaxaca", "MX-OAX", "MX"),
+ ("Puebla", "MX-PUE", "MX"),
+ ("Querétaro", "MX-QUE", "MX"),
+ ("Quintana Roo", "MX-ROO", "MX"),
+ ("San Luis Potosí", "MX-SLP", "MX"),
+ ("Sinaloa", "MX-SIN", "MX"),
+ ("Sonora", "MX-SON", "MX"),
+ ("Tabasco", "MX-TAB", "MX"),
+ ("Tamaulipas", "MX-TAM", "MX"),
+ ("Tlaxcala", "MX-TLA", "MX"),
+ ("Veracruz de Ignacio de la Llave", "MX-VER", "MX"),
+ ("Yucatán", "MX-YUC", "MX"),
+ ("Zacatecas", "MX-ZAC", "MX"),
+ ("Ciudad de México", "MX-CMX", "MX"),
+ ];
+
+ private static IReadOnlyList<(string StateProvinceCode, string CityName)> Cities { get; } =
+ [
+ ("US-CA", "Los Angeles"),
+ ("US-CA", "San Diego"),
+ ("US-CA", "San Francisco"),
+ ("US-CA", "Sacramento"),
+ ("US-TX", "Houston"),
+ ("US-TX", "Dallas"),
+ ("US-TX", "Austin"),
+ ("US-TX", "San Antonio"),
+ ("US-FL", "Miami"),
+ ("US-FL", "Orlando"),
+ ("US-FL", "Tampa"),
+ ("US-NY", "New York"),
+ ("US-NY", "Buffalo"),
+ ("US-NY", "Rochester"),
+ ("US-IL", "Chicago"),
+ ("US-IL", "Springfield"),
+ ("US-PA", "Philadelphia"),
+ ("US-PA", "Pittsburgh"),
+ ("US-AZ", "Phoenix"),
+ ("US-AZ", "Tucson"),
+ ("US-CO", "Denver"),
+ ("US-CO", "Colorado Springs"),
+ ("US-MA", "Boston"),
+ ("US-MA", "Worcester"),
+ ("US-WA", "Seattle"),
+ ("US-WA", "Spokane"),
+ ("US-GA", "Atlanta"),
+ ("US-GA", "Savannah"),
+ ("US-NV", "Las Vegas"),
+ ("US-NV", "Reno"),
+ ("US-MI", "Detroit"),
+ ("US-MI", "Grand Rapids"),
+ ("US-MN", "Minneapolis"),
+ ("US-MN", "Saint Paul"),
+ ("US-OH", "Columbus"),
+ ("US-OH", "Cleveland"),
+ ("US-OR", "Portland"),
+ ("US-OR", "Salem"),
+ ("US-TN", "Nashville"),
+ ("US-TN", "Memphis"),
+ ("US-VA", "Richmond"),
+ ("US-VA", "Virginia Beach"),
+ ("US-MD", "Baltimore"),
+ ("US-MD", "Frederick"),
+ ("US-DC", "Washington"),
+ ("US-UT", "Salt Lake City"),
+ ("US-UT", "Provo"),
+ ("US-LA", "New Orleans"),
+ ("US-LA", "Baton Rouge"),
+ ("US-KY", "Louisville"),
+ ("US-KY", "Lexington"),
+ ("US-IA", "Des Moines"),
+ ("US-IA", "Cedar Rapids"),
+ ("US-OK", "Oklahoma City"),
+ ("US-OK", "Tulsa"),
+ ("US-NE", "Omaha"),
+ ("US-NE", "Lincoln"),
+ ("US-MO", "Kansas City"),
+ ("US-MO", "St. Louis"),
+ ("US-NC", "Charlotte"),
+ ("US-NC", "Raleigh"),
+ ("US-SC", "Columbia"),
+ ("US-SC", "Charleston"),
+ ("US-WI", "Milwaukee"),
+ ("US-WI", "Madison"),
+ ("US-MN", "Duluth"),
+ ("US-AK", "Anchorage"),
+ ("US-HI", "Honolulu"),
+ ("CA-ON", "Toronto"),
+ ("CA-ON", "Ottawa"),
+ ("CA-QC", "Montréal"),
+ ("CA-QC", "Québec City"),
+ ("CA-BC", "Vancouver"),
+ ("CA-BC", "Victoria"),
+ ("CA-AB", "Calgary"),
+ ("CA-AB", "Edmonton"),
+ ("CA-MB", "Winnipeg"),
+ ("CA-NS", "Halifax"),
+ ("CA-SK", "Saskatoon"),
+ ("CA-SK", "Regina"),
+ ("CA-NB", "Moncton"),
+ ("CA-NB", "Saint John"),
+ ("CA-PE", "Charlottetown"),
+ ("CA-NL", "St. John's"),
+ ("CA-ON", "Hamilton"),
+ ("CA-ON", "London"),
+ ("CA-QC", "Gatineau"),
+ ("CA-QC", "Laval"),
+ ("CA-BC", "Kelowna"),
+ ("CA-AB", "Red Deer"),
+ ("CA-MB", "Brandon"),
+ ("MX-CMX", "Ciudad de México"),
+ ("MX-JAL", "Guadalajara"),
+ ("MX-NLE", "Monterrey"),
+ ("MX-PUE", "Puebla"),
+ ("MX-ROO", "Cancún"),
+ ("MX-GUA", "Guanajuato"),
+ ("MX-MIC", "Morelia"),
+ ("MX-BCN", "Tijuana"),
+ ("MX-JAL", "Zapopan"),
+ ("MX-NLE", "San Nicolás"),
+ ("MX-CAM", "Campeche"),
+ ("MX-TAB", "Villahermosa"),
+ ("MX-VER", "Veracruz"),
+ ("MX-OAX", "Oaxaca"),
+ ("MX-SLP", "San Luis Potosí"),
+ ("MX-CHH", "Chihuahua"),
+ ("MX-AGU", "Aguascalientes"),
+ ("MX-MEX", "Toluca"),
+ ("MX-COA", "Saltillo"),
+ ("MX-BCS", "La Paz"),
+ ("MX-NAY", "Tepic"),
+ ("MX-ZAC", "Zacatecas"),
+ ];
+
+ public async Task SeedAsync(SqlConnection connection)
+ {
+ foreach (var (countryName, countryCode) in Countries)
+ {
+ await CreateCountryAsync(connection, countryName, countryCode);
+ }
+
+ foreach (
+ var (stateProvinceName, stateProvinceCode, countryCode) in States
+ )
+ {
+ await CreateStateProvinceAsync(
+ connection,
+ stateProvinceName,
+ stateProvinceCode,
+ countryCode
+ );
+ }
+
+ foreach (var (stateProvinceCode, cityName) in Cities)
+ {
+ await CreateCityAsync(connection, cityName, stateProvinceCode);
+ }
}
- foreach (
- var (stateProvinceName, stateProvinceCode, countryCode) in States
+ private static async Task CreateCountryAsync(
+ SqlConnection connection,
+ string countryName,
+ string countryCode
)
{
- await CreateStateProvinceAsync(
- connection,
- stateProvinceName,
- stateProvinceCode,
- countryCode
+ await using var command = new SqlCommand(
+ "dbo.USP_CreateCountry",
+ connection
);
+ command.CommandType = CommandType.StoredProcedure;
+ command.Parameters.AddWithValue("@CountryName", countryName);
+ command.Parameters.AddWithValue("@ISO3616_1", countryCode);
+
+ await command.ExecuteNonQueryAsync();
}
- foreach (var (stateProvinceCode, cityName) in Cities)
+ private static async Task CreateStateProvinceAsync(
+ SqlConnection connection,
+ string stateProvinceName,
+ string stateProvinceCode,
+ string countryCode
+ )
{
- await CreateCityAsync(connection, cityName, stateProvinceCode);
+ await using var command = new SqlCommand(
+ "dbo.USP_CreateStateProvince",
+ connection
+ );
+ command.CommandType = CommandType.StoredProcedure;
+ command.Parameters.AddWithValue(
+ "@StateProvinceName",
+ stateProvinceName
+ );
+ command.Parameters.AddWithValue("@ISO3616_2", stateProvinceCode);
+ command.Parameters.AddWithValue("@CountryCode", countryCode);
+
+ await command.ExecuteNonQueryAsync();
+ }
+
+ private static async Task CreateCityAsync(
+ SqlConnection connection,
+ string cityName,
+ string stateProvinceCode
+ )
+ {
+ await using var command = new SqlCommand(
+ "dbo.USP_CreateCity",
+ connection
+ );
+ command.CommandType = CommandType.StoredProcedure;
+ command.Parameters.AddWithValue("@CityName", cityName);
+ command.Parameters.AddWithValue(
+ "@StateProvinceCode",
+ stateProvinceCode
+ );
+
+ await command.ExecuteNonQueryAsync();
}
}
-
- private static async Task CreateCountryAsync(
- SqlConnection connection,
- string countryName,
- string countryCode
- )
- {
- await using var command = new SqlCommand(
- "dbo.USP_CreateCountry",
- connection
- );
- command.CommandType = CommandType.StoredProcedure;
- command.Parameters.AddWithValue("@CountryName", countryName);
- command.Parameters.AddWithValue("@ISO3616_1", countryCode);
-
- await command.ExecuteNonQueryAsync();
- }
-
- private static async Task CreateStateProvinceAsync(
- SqlConnection connection,
- string stateProvinceName,
- string stateProvinceCode,
- string countryCode
- )
- {
- await using var command = new SqlCommand(
- "dbo.USP_CreateStateProvince",
- connection
- );
- command.CommandType = CommandType.StoredProcedure;
- command.Parameters.AddWithValue(
- "@StateProvinceName",
- stateProvinceName
- );
- command.Parameters.AddWithValue("@ISO3616_2", stateProvinceCode);
- command.Parameters.AddWithValue("@CountryCode", countryCode);
-
- await command.ExecuteNonQueryAsync();
- }
-
- private static async Task CreateCityAsync(
- SqlConnection connection,
- string cityName,
- string stateProvinceCode
- )
- {
- await using var command = new SqlCommand(
- "dbo.USP_CreateCity",
- connection
- );
- command.CommandType = CommandType.StoredProcedure;
- command.Parameters.AddWithValue("@CityName", cityName);
- command.Parameters.AddWithValue(
- "@StateProvinceCode",
- stateProvinceCode
- );
-
- await command.ExecuteNonQueryAsync();
- }
-}
+}
\ No newline at end of file
diff --git a/DBSeed/UserSeeder.cs b/DBSeed/UserSeeder.cs
index 2918bff..3fd7f64 100644
--- a/DBSeed/UserSeeder.cs
+++ b/DBSeed/UserSeeder.cs
@@ -1,336 +1,258 @@
using System.Data;
using System.Security.Cryptography;
using System.Text;
+using DataAccessLayer.Entities;
+using DataAccessLayer.Repositories;
using idunno.Password;
using Konscious.Security.Cryptography;
using Microsoft.Data.SqlClient;
-namespace DBSeed;
-
-class UserSeeder : ISeeder
+namespace DBSeed
{
- private static readonly IReadOnlyList<(
- string FirstName,
- string LastName
- )> SeedNames =
- [
- ("Aarya", "Mathews"),
- ("Aiden", "Wells"),
- ("Aleena", "Gonzalez"),
- ("Alessandra", "Nelson"),
- ("Amari", "Tucker"),
- ("Ameer", "Huff"),
- ("Amirah", "Hicks"),
- ("Analia", "Dominguez"),
- ("Anne", "Jenkins"),
- ("Apollo", "Davis"),
- ("Arianna", "White"),
- ("Aubree", "Moore"),
- ("Aubrielle", "Raymond"),
- ("Aydin", "Odom"),
- ("Bowen", "Casey"),
- ("Brock", "Huber"),
- ("Caiden", "Strong"),
- ("Cecilia", "Rosales"),
- ("Celeste", "Barber"),
- ("Chance", "Small"),
- ("Clara", "Roberts"),
- ("Collins", "Brandt"),
- ("Damir", "Wallace"),
- ("Declan", "Crawford"),
- ("Dennis", "Decker"),
- ("Dylan", "Lang"),
- ("Eliza", "Kane"),
- ("Elle", "Poole"),
- ("Elliott", "Miles"),
- ("Emelia", "Lucas"),
- ("Emilia", "Simpson"),
- ("Emmett", "Lugo"),
- ("Ethan", "Stephens"),
- ("Etta", "Woods"),
- ("Gael", "Moran"),
- ("Grant", "Benson"),
- ("Gwen", "James"),
- ("Huxley", "Chen"),
- ("Isabella", "Fisher"),
- ("Ivan", "Mathis"),
- ("Jamir", "McMillan"),
- ("Jaxson", "Shields"),
- ("Jimmy", "Richmond"),
- ("Josiah", "Flores"),
- ("Kaden", "Enriquez"),
- ("Kai", "Lawson"),
- ("Karsyn", "Adkins"),
- ("Karsyn", "Proctor"),
- ("Kayden", "Henson"),
- ("Kaylie", "Spears"),
- ("Kinslee", "Jones"),
- ("Kora", "Guerra"),
- ("Lane", "Skinner"),
- ("Laylani", "Christian"),
- ("Ledger", "Carroll"),
- ("Leilany", "Small"),
- ("Leland", "McCall"),
- ("Leonard", "Calhoun"),
- ("Levi", "Ochoa"),
- ("Lillie", "Vang"),
- ("Lola", "Sheppard"),
- ("Luciana", "Poole"),
- ("Maddox", "Hughes"),
- ("Mara", "Blackwell"),
- ("Marcellus", "Bartlett"),
- ("Margo", "Koch"),
- ("Maurice", "Gibson"),
- ("Maxton", "Dodson"),
- ("Mia", "Parrish"),
- ("Millie", "Fuentes"),
- ("Nellie", "Villanueva"),
- ("Nicolas", "Mata"),
- ("Nicolas", "Miller"),
- ("Oakleigh", "Foster"),
- ("Octavia", "Pierce"),
- ("Paisley", "Allison"),
- ("Quincy", "Andersen"),
- ("Quincy", "Frazier"),
- ("Raiden", "Roberts"),
- ("Raquel", "Lara"),
- ("Rudy", "McIntosh"),
- ("Salvador", "Stein"),
- ("Samantha", "Dickson"),
- ("Solomon", "Richards"),
- ("Sylvia", "Hanna"),
- ("Talia", "Trujillo"),
- ("Thalia", "Farrell"),
- ("Trent", "Mayo"),
- ("Trinity", "Cummings"),
- ("Ty", "Perry"),
- ("Tyler", "Romero"),
- ("Valeria", "Pierce"),
- ("Vance", "Neal"),
- ("Whitney", "Bell"),
- ("Wilder", "Graves"),
- ("William", "Logan"),
- ("Zara", "Wilkinson"),
- ("Zaria", "Gibson"),
- ("Zion", "Watkins"),
- ("Zoie", "Armstrong"),
- ];
- public async Task SeedAsync(SqlConnection connection)
+ internal class UserSeeder : ISeeder
{
- var generator = new PasswordGenerator();
- var random = new Random();
- int createdUsers = 0;
- int createdCredentials = 0;
- int createdVerifications = 0;
+ private UserAccountRepository _userAccountRepository = new UserAccountRepository();
+
+
+ private static readonly IReadOnlyList<(
+ string FirstName,
+ string LastName
+ )> SeedNames =
+ [
+ ("Aarya", "Mathews"),
+ ("Aiden", "Wells"),
+ ("Aleena", "Gonzalez"),
+ ("Alessandra", "Nelson"),
+ ("Amari", "Tucker"),
+ ("Ameer", "Huff"),
+ ("Amirah", "Hicks"),
+ ("Analia", "Dominguez"),
+ ("Anne", "Jenkins"),
+ ("Apollo", "Davis"),
+ ("Arianna", "White"),
+ ("Aubree", "Moore"),
+ ("Aubrielle", "Raymond"),
+ ("Aydin", "Odom"),
+ ("Bowen", "Casey"),
+ ("Brock", "Huber"),
+ ("Caiden", "Strong"),
+ ("Cecilia", "Rosales"),
+ ("Celeste", "Barber"),
+ ("Chance", "Small"),
+ ("Clara", "Roberts"),
+ ("Collins", "Brandt"),
+ ("Damir", "Wallace"),
+ ("Declan", "Crawford"),
+ ("Dennis", "Decker"),
+ ("Dylan", "Lang"),
+ ("Eliza", "Kane"),
+ ("Elle", "Poole"),
+ ("Elliott", "Miles"),
+ ("Emelia", "Lucas"),
+ ("Emilia", "Simpson"),
+ ("Emmett", "Lugo"),
+ ("Ethan", "Stephens"),
+ ("Etta", "Woods"),
+ ("Gael", "Moran"),
+ ("Grant", "Benson"),
+ ("Gwen", "James"),
+ ("Huxley", "Chen"),
+ ("Isabella", "Fisher"),
+ ("Ivan", "Mathis"),
+ ("Jamir", "McMillan"),
+ ("Jaxson", "Shields"),
+ ("Jimmy", "Richmond"),
+ ("Josiah", "Flores"),
+ ("Kaden", "Enriquez"),
+ ("Kai", "Lawson"),
+ ("Karsyn", "Adkins"),
+ ("Karsyn", "Proctor"),
+ ("Kayden", "Henson"),
+ ("Kaylie", "Spears"),
+ ("Kinslee", "Jones"),
+ ("Kora", "Guerra"),
+ ("Lane", "Skinner"),
+ ("Laylani", "Christian"),
+ ("Ledger", "Carroll"),
+ ("Leilany", "Small"),
+ ("Leland", "McCall"),
+ ("Leonard", "Calhoun"),
+ ("Levi", "Ochoa"),
+ ("Lillie", "Vang"),
+ ("Lola", "Sheppard"),
+ ("Luciana", "Poole"),
+ ("Maddox", "Hughes"),
+ ("Mara", "Blackwell"),
+ ("Marcellus", "Bartlett"),
+ ("Margo", "Koch"),
+ ("Maurice", "Gibson"),
+ ("Maxton", "Dodson"),
+ ("Mia", "Parrish"),
+ ("Millie", "Fuentes"),
+ ("Nellie", "Villanueva"),
+ ("Nicolas", "Mata"),
+ ("Nicolas", "Miller"),
+ ("Oakleigh", "Foster"),
+ ("Octavia", "Pierce"),
+ ("Paisley", "Allison"),
+ ("Quincy", "Andersen"),
+ ("Quincy", "Frazier"),
+ ("Raiden", "Roberts"),
+ ("Raquel", "Lara"),
+ ("Rudy", "McIntosh"),
+ ("Salvador", "Stein"),
+ ("Samantha", "Dickson"),
+ ("Solomon", "Richards"),
+ ("Sylvia", "Hanna"),
+ ("Talia", "Trujillo"),
+ ("Thalia", "Farrell"),
+ ("Trent", "Mayo"),
+ ("Trinity", "Cummings"),
+ ("Ty", "Perry"),
+ ("Tyler", "Romero"),
+ ("Valeria", "Pierce"),
+ ("Vance", "Neal"),
+ ("Whitney", "Bell"),
+ ("Wilder", "Graves"),
+ ("William", "Logan"),
+ ("Zara", "Wilkinson"),
+ ("Zaria", "Gibson"),
+ ("Zion", "Watkins"),
+ ("Zoie", "Armstrong"),
+ ];
- foreach (var (firstName, lastName) in SeedNames)
+ public async Task SeedAsync(SqlConnection connection)
{
- string username = BuildUsername(firstName, lastName);
- string email = BuildEmail(firstName, lastName);
- Guid? existingId =
- await GetUserAccountIdByUsernameAsync(connection, username)
- ?? await GetUserAccountIdByEmailAsync(connection, email);
+ var generator = new PasswordGenerator();
+ var rng = new Random();
+ int createdUsers = 0;
+ int createdCredentials = 0;
+ int createdVerifications = 0;
- Guid userAccountId;
- if (existingId.HasValue)
+ foreach (var (firstName, lastName) in SeedNames)
{
- userAccountId = existingId.Value;
- }
- else
- {
- userAccountId = Guid.NewGuid();
- DateTime dateOfBirth = GenerateDateOfBirth(random);
- await CreateUserAccountAsync(
- connection,
- userAccountId,
- username,
- firstName,
- lastName,
- email,
- dateOfBirth
- );
- createdUsers++;
- }
+ // create the user in the database
+ var ua = new UserAccount
+ {
+ FirstName = firstName,
+ LastName = lastName,
+ Email = $"{firstName}.{lastName}@thebiergarten.app",
+ Username = $"{firstName[0]}.{lastName}",
+ DateOfBirth = GenerateDateOfBirth(rng)
+ };
- if (!await HasUserCredentialAsync(connection, userAccountId))
- {
- string pwd = generator.Generate(
- length: 64,
- numberOfDigits: 10,
- numberOfSymbols: 10
- );
- string hash = GeneratePasswordHash(pwd);
- await AddUserCredentialAsync(connection, userAccountId, hash);
- createdCredentials++;
- }
- if (!await HasUserVerificationAsync(connection, userAccountId))
- {
+ // add user credentials
+ if (!await HasUserCredentialAsync(connection, userAccountId))
+ {
+ string pwd = generator.Generate(
+ length: 64,
+ numberOfDigits: 10,
+ numberOfSymbols: 10
+ );
+ string hash = GeneratePasswordHash(pwd);
+ await AddUserCredentialAsync(connection, userAccountId, hash);
+ createdCredentials++;
+ }
+
+ // add user verification
+ if (await HasUserVerificationAsync(connection, userAccountId)) continue;
await AddUserVerificationAsync(connection, userAccountId);
createdVerifications++;
}
+
+ Console.WriteLine($"Created {createdUsers} user accounts.");
+ Console.WriteLine($"Added {createdCredentials} user credentials.");
+ Console.WriteLine($"Added {createdVerifications} user verifications.");
}
- Console.WriteLine($"Created {createdUsers} user accounts.");
- Console.WriteLine($"Added {createdCredentials} user credentials.");
- Console.WriteLine($"Added {createdVerifications} user verifications.");
- }
-
- private static string GeneratePasswordHash(string pwd)
- {
- byte[] salt = RandomNumberGenerator.GetBytes(16);
-
- var argon2 = new Argon2id(Encoding.UTF8.GetBytes(pwd))
+ private static string GeneratePasswordHash(string pwd)
{
- Salt = salt,
- DegreeOfParallelism = Math.Max(Environment.ProcessorCount, 1),
- MemorySize = 65536,
- Iterations = 4,
- };
+ byte[] salt = RandomNumberGenerator.GetBytes(16);
- byte[] hash = argon2.GetBytes(32);
- return $"{Convert.ToBase64String(salt)}:{Convert.ToBase64String(hash)}";
+ var argon2 = new Argon2id(Encoding.UTF8.GetBytes(pwd))
+ {
+ Salt = salt,
+ DegreeOfParallelism = Math.Max(Environment.ProcessorCount, 1),
+ MemorySize = 65536,
+ Iterations = 4,
+ };
+
+ byte[] hash = argon2.GetBytes(32);
+ return $"{Convert.ToBase64String(salt)}:{Convert.ToBase64String(hash)}";
+ }
+
+ private static async Task HasUserCredentialAsync(
+ SqlConnection connection,
+ Guid userAccountId
+ )
+ {
+ const string sql = $"""
+ SELECT 1
+ FROM dbo.UserCredential
+ WHERE UserAccountId = @UserAccountId;
+ """;
+ await using var command = new SqlCommand(sql, connection);
+ command.Parameters.AddWithValue("@UserAccountId", userAccountId);
+ object? result = await command.ExecuteScalarAsync();
+ return result is not null;
+ }
+
+ private static async Task AddUserCredentialAsync(
+ SqlConnection connection,
+ Guid userAccountId,
+ string hash
+ )
+ {
+ await using var command = new SqlCommand(
+ "dbo.USP_AddUserCredential",
+ connection
+ );
+ command.CommandType = CommandType.StoredProcedure;
+ command.Parameters.AddWithValue("@UserAccountId", userAccountId);
+ command.Parameters.AddWithValue("@Hash", hash);
+
+ await command.ExecuteNonQueryAsync();
+ }
+
+ private static async Task HasUserVerificationAsync(
+ SqlConnection connection,
+ Guid userAccountId
+ )
+ {
+ const string sql = """
+ SELECT 1
+ FROM dbo.UserVerification
+ WHERE UserAccountId = @UserAccountId;
+ """;
+ await using var command = new SqlCommand(sql, connection);
+ command.Parameters.AddWithValue("@UserAccountId", userAccountId);
+ var result = await command.ExecuteScalarAsync();
+ return result is not null;
+ }
+
+ private static async Task AddUserVerificationAsync(
+ SqlConnection connection,
+ Guid userAccountId
+ )
+ {
+ await using var command = new SqlCommand(
+ "dbo.USP_CreateUserVerification",
+ connection
+ );
+ command.CommandType = CommandType.StoredProcedure;
+ command.Parameters.AddWithValue("@UserAccountID", userAccountId);
+
+ await command.ExecuteNonQueryAsync();
+ }
+
+ private static DateTime GenerateDateOfBirth(Random random)
+ {
+ int age = 19 + random.Next(0, 30);
+ DateTime baseDate = DateTime.UtcNow.Date.AddYears(-age);
+ int offsetDays = random.Next(0, 365);
+ return baseDate.AddDays(-offsetDays);
+ }
}
-
- private static async Task GetUserAccountIdByUsernameAsync(
- SqlConnection connection,
- string username
- )
- {
- await using var command = new SqlCommand(
- "usp_GetUserAccountByUsername",
- connection
- );
- command.CommandType = CommandType.StoredProcedure;
- command.Parameters.AddWithValue("@Username", username);
-
- await using var reader = await command.ExecuteReaderAsync();
- return await reader.ReadAsync() ? reader.GetGuid(0) : null;
- }
-
- private static async Task GetUserAccountIdByEmailAsync(
- SqlConnection connection,
- string email
- )
- {
- await using var command = new SqlCommand(
- "usp_GetUserAccountByEmail",
- connection
- );
- command.CommandType = CommandType.StoredProcedure;
- command.Parameters.AddWithValue("@Email", email);
-
- await using var reader = await command.ExecuteReaderAsync();
- return await reader.ReadAsync() ? reader.GetGuid(0) : null;
- }
-
- private static async Task CreateUserAccountAsync(
- SqlConnection connection,
- Guid userAccountId,
- string username,
- string firstName,
- string lastName,
- string email,
- DateTime dateOfBirth
- )
- {
- await using var command = new SqlCommand(
- "usp_CreateUserAccount",
- connection
- );
- command.CommandType = CommandType.StoredProcedure;
- command.Parameters.AddWithValue("@UserAccountId", userAccountId);
- command.Parameters.AddWithValue("@Username", username);
- command.Parameters.AddWithValue("@FirstName", firstName);
- command.Parameters.AddWithValue("@LastName", lastName);
- command.Parameters.AddWithValue("@DateOfBirth", dateOfBirth);
- command.Parameters.AddWithValue("@Email", email);
-
- await command.ExecuteNonQueryAsync();
- }
-
- private static async Task HasUserCredentialAsync(
- SqlConnection connection,
- Guid userAccountId
- )
- {
- const string sql = """
-SELECT 1
-FROM dbo.UserCredential
-WHERE UserAccountId = @UserAccountId;
-""";
- await using var command = new SqlCommand(sql, connection);
- command.Parameters.AddWithValue("@UserAccountId", userAccountId);
- object? result = await command.ExecuteScalarAsync();
- return result is not null;
- }
-
- private static async Task AddUserCredentialAsync(
- SqlConnection connection,
- Guid userAccountId,
- string hash
- )
- {
- await using var command = new SqlCommand(
- "dbo.USP_AddUserCredential",
- connection
- );
- command.CommandType = CommandType.StoredProcedure;
- command.Parameters.AddWithValue("@UserAccountId", userAccountId);
- command.Parameters.AddWithValue("@Hash", hash);
-
- await command.ExecuteNonQueryAsync();
- }
-
- private static async Task HasUserVerificationAsync(
- SqlConnection connection,
- Guid userAccountId
- )
- {
- const string sql = """
-SELECT 1
-FROM dbo.UserVerification
-WHERE UserAccountId = @UserAccountId;
-""";
- await using var command = new SqlCommand(sql, connection);
- command.Parameters.AddWithValue("@UserAccountId", userAccountId);
- object? result = await command.ExecuteScalarAsync();
- return result is not null;
- }
-
- private static async Task AddUserVerificationAsync(
- SqlConnection connection,
- Guid userAccountId
- )
- {
- await using var command = new SqlCommand(
- "dbo.USP_CreateUserVerification",
- connection
- );
- command.CommandType = CommandType.StoredProcedure;
- command.Parameters.AddWithValue("@UserAccountID", userAccountId);
-
- await command.ExecuteNonQueryAsync();
- }
-
- private static string BuildUsername(string firstName, string lastName)
- {
- string username = $"{firstName}.{lastName}".ToLowerInvariant();
- return username.Length <= 64 ? username : username[..64];
- }
-
- private static string BuildEmail(string firstName, string lastName)
- {
- string email = $"{firstName}.{lastName}@example.com".ToLowerInvariant();
- return email.Length <= 128 ? email : email[..128];
- }
-
- private static DateTime GenerateDateOfBirth(Random random)
- {
- int age = 19 + random.Next(0, 30);
- DateTime baseDate = DateTime.UtcNow.Date.AddYears(-age);
- int offsetDays = random.Next(0, 365);
- return baseDate.AddDays(-offsetDays);
- }
-}
+}
\ No newline at end of file
diff --git a/DataAccessLayer/Entities/UserAccount.cs b/DataAccessLayer/Entities/UserAccount.cs
index 2b93986..cf9baf5 100644
--- a/DataAccessLayer/Entities/UserAccount.cs
+++ b/DataAccessLayer/Entities/UserAccount.cs
@@ -2,7 +2,7 @@ namespace DataAccessLayer.Entities;
public class UserAccount
{
- public Guid UserAccountID { get; set; }
+ 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;
diff --git a/DataAccessLayer/Entities/UserCredential.cs b/DataAccessLayer/Entities/UserCredential.cs
index 3f4117a..07468ff 100644
--- a/DataAccessLayer/Entities/UserCredential.cs
+++ b/DataAccessLayer/Entities/UserCredential.cs
@@ -2,8 +2,8 @@ namespace DataAccessLayer.Entities;
public class UserCredential
{
- public Guid UserCredentialID { get; set; }
- public Guid UserAccountID { get; set; }
+ 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;
diff --git a/DataAccessLayer/Entities/UserVerification.cs b/DataAccessLayer/Entities/UserVerification.cs
index 3eb0c13..6a503d8 100644
--- a/DataAccessLayer/Entities/UserVerification.cs
+++ b/DataAccessLayer/Entities/UserVerification.cs
@@ -2,8 +2,8 @@ namespace DataAccessLayer.Entities;
public class UserVerification
{
- public Guid UserVerificationID { get; set; }
- public Guid UserAccountID { get; set; }
+ public Guid UserVerificationId { get; set; }
+ public Guid UserAccountId { get; set; }
public DateTime VerificationDateTime { get; set; }
public byte[]? Timer { get; set; }
}
diff --git a/DataAccessLayer/IRepository.cs b/DataAccessLayer/Repositories/IRepository.cs
similarity index 66%
rename from DataAccessLayer/IRepository.cs
rename to DataAccessLayer/Repositories/IRepository.cs
index 5aee600..4b71078 100644
--- a/DataAccessLayer/IRepository.cs
+++ b/DataAccessLayer/Repositories/IRepository.cs
@@ -1,7 +1,8 @@
-using System;
-using System.Collections.Generic;
-namespace DataAccessLayer
+
+using Microsoft.Data.SqlClient;
+
+namespace DataAccessLayer.Repositories
{
public interface IRepository
where T : class
@@ -13,5 +14,7 @@ namespace DataAccessLayer
T? GetById(Guid id);
void Update(T entity);
void Delete(Guid id);
+
+ T MapToEntity(SqlDataReader entity);
}
}
diff --git a/DataAccessLayer/Repositories/IUserAccountRepository.cs b/DataAccessLayer/Repositories/IUserAccountRepository.cs
index 2e880a6..da1efbf 100644
--- a/DataAccessLayer/Repositories/IUserAccountRepository.cs
+++ b/DataAccessLayer/Repositories/IUserAccountRepository.cs
@@ -1,8 +1,6 @@
-using System;
-using System.Collections.Generic;
using DataAccessLayer.Entities;
-namespace DataAccessLayer
+namespace DataAccessLayer.Repositories
{
public interface IUserAccountRepository : IRepository
{
diff --git a/DataAccessLayer/Repositories/UserAccountRepository.cs b/DataAccessLayer/Repositories/UserAccountRepository.cs
index 4790f3e..00103b0 100644
--- a/DataAccessLayer/Repositories/UserAccountRepository.cs
+++ b/DataAccessLayer/Repositories/UserAccountRepository.cs
@@ -1,30 +1,36 @@
-using System;
-using System.Collections.Generic;
using DataAccessLayer.Entities;
using Microsoft.Data.SqlClient;
-namespace DataAccessLayer
+namespace DataAccessLayer.Repositories
{
public class UserAccountRepository : IUserAccountRepository
{
- private readonly string _connectionString;
-
- public UserAccountRepository()
- {
- // Retrieve the connection string from environment variables
- _connectionString =
- Environment.GetEnvironmentVariable("DB_CONNECTION_STRING")
- ?? throw new InvalidOperationException(
- "The connection string is not set in the environment variables."
- );
- }
+ private readonly string _connectionString = Environment.GetEnvironmentVariable("DB_CONNECTION_STRING")
+ ?? throw new InvalidOperationException(
+ "The connection string is not set in the environment variables."
+ );
public void Add(UserAccount userAccount)
{
using SqlConnection connection = new(_connectionString);
using SqlCommand command = new("usp_CreateUserAccount", connection);
command.CommandType = System.Data.CommandType.StoredProcedure;
- AddUserAccountCreateParameters(command, userAccount);
+
+ command.Parameters.AddWithValue(
+ "@UserAccountId",
+ userAccount.UserAccountId
+ );
+ command.Parameters.AddWithValue("@Username", userAccount.Username);
+ command.Parameters.AddWithValue(
+ "@FirstName",
+ userAccount.FirstName
+ );
+ command.Parameters.AddWithValue("@LastName", userAccount.LastName);
+ command.Parameters.AddWithValue("@Email", userAccount.Email);
+ command.Parameters.AddWithValue(
+ "@DateOfBirth",
+ userAccount.DateOfBirth
+ );
connection.Open();
command.ExecuteNonQuery();
}
@@ -41,7 +47,7 @@ namespace DataAccessLayer
connection.Open();
using SqlDataReader reader = command.ExecuteReader();
- return reader.Read() ? MapUserAccount(reader) : null;
+ return reader.Read() ? MapToEntity(reader) : null;
}
public void Update(UserAccount userAccount)
@@ -49,7 +55,25 @@ namespace DataAccessLayer
using SqlConnection connection = new(_connectionString);
using SqlCommand command = new("usp_UpdateUserAccount", connection);
command.CommandType = System.Data.CommandType.StoredProcedure;
- AddUserAccountUpdateParameters(command, userAccount);
+ command.Parameters.AddWithValue(
+ "@UserAccountId",
+ userAccount.UserAccountId
+ );
+ command.Parameters.AddWithValue("@Username", userAccount.Username);
+ command.Parameters.AddWithValue(
+ "@FirstName",
+ userAccount.FirstName
+ );
+ command.Parameters.AddWithValue("@LastName", userAccount.LastName);
+ command.Parameters.AddWithValue("@Email", userAccount.Email);
+ command.Parameters.AddWithValue(
+ "@DateOfBirth",
+ userAccount.DateOfBirth
+ );
+ command.Parameters.AddWithValue(
+ "@UserAccountId",
+ userAccount.UserAccountId
+ );
connection.Open();
command.ExecuteNonQuery();
}
@@ -64,9 +88,10 @@ namespace DataAccessLayer
command.ExecuteNonQuery();
}
+
public IEnumerable GetAll(int? limit, int? offset)
{
- if (limit.HasValue && limit <= 0)
+ if (limit is <= 0)
{
throw new ArgumentOutOfRangeException(
nameof(limit),
@@ -110,7 +135,7 @@ namespace DataAccessLayer
List users = new();
while (reader.Read())
{
- users.Add(MapUserAccount(reader));
+ users.Add(MapToEntity(reader));
}
return users;
@@ -127,8 +152,8 @@ namespace DataAccessLayer
command.Parameters.AddWithValue("@Username", username);
connection.Open();
- using SqlDataReader reader = command.ExecuteReader();
- return reader.Read() ? MapUserAccount(reader) : null;
+ using SqlDataReader? reader = command.ExecuteReader();
+ return reader.Read() ? MapToEntity(reader) : null;
}
public UserAccount? GetByEmail(string email)
@@ -143,48 +168,14 @@ namespace DataAccessLayer
connection.Open();
using SqlDataReader reader = command.ExecuteReader();
- return reader.Read() ? MapUserAccount(reader) : null;
+ return reader.Read() ? MapToEntity(reader) : null;
}
- private static void AddUserAccountCreateParameters(
- SqlCommand command,
- UserAccount userAccount
- )
- {
- command.Parameters.AddWithValue(
- "@UserAccountId",
- userAccount.UserAccountID
- );
- command.Parameters.AddWithValue("@Username", userAccount.Username);
- command.Parameters.AddWithValue(
- "@FirstName",
- userAccount.FirstName
- );
- command.Parameters.AddWithValue("@LastName", userAccount.LastName);
- command.Parameters.AddWithValue("@Email", userAccount.Email);
- command.Parameters.AddWithValue(
- "@DateOfBirth",
- userAccount.DateOfBirth
- );
- }
-
- private static void AddUserAccountUpdateParameters(
- SqlCommand command,
- UserAccount userAccount
- )
- {
- AddUserAccountCreateParameters(command, userAccount);
- command.Parameters.AddWithValue(
- "@UserAccountId",
- userAccount.UserAccountID
- );
- }
-
- private static UserAccount MapUserAccount(SqlDataReader reader)
+ public UserAccount MapToEntity(SqlDataReader reader)
{
return new UserAccount
{
- UserAccountID = reader.GetGuid(0),
+ UserAccountId = reader.GetGuid(0),
Username = reader.GetString(1),
FirstName = reader.GetString(2),
LastName = reader.GetString(3),
diff --git a/DataAccessLayer/Sql/DatabaseHelper.cs b/DataAccessLayer/Sql/DatabaseHelper.cs
index 53171a0..5096a13 100644
--- a/DataAccessLayer/Sql/DatabaseHelper.cs
+++ b/DataAccessLayer/Sql/DatabaseHelper.cs
@@ -4,45 +4,31 @@ using Microsoft.Data.SqlClient;
namespace DataAccessLayer.Sql
{
- public class DatabaseHelper
+ public class DatabaseHelper(string connectionString)
{
- private readonly string _connectionString;
-
- public DatabaseHelper(string connectionString)
- {
- _connectionString = connectionString;
- }
-
public void ExecuteRawSql(string query)
{
try
{
- using (
- SqlConnection connection = new SqlConnection(
- _connectionString
- )
- )
+ using var connection = new SqlConnection(
+ connectionString
+ );
+
+ connection.Open();
+
+ using var command = new SqlCommand(query, connection);
+
+ command.CommandType = CommandType.Text;
+
+ using var reader = command.ExecuteReader();
+
+ while (reader.Read())
{
- connection.Open();
-
- using (
- SqlCommand command = new SqlCommand(query, connection)
- )
+ for (var i = 0; i < reader.FieldCount; i++)
{
- command.CommandType = CommandType.Text;
-
- using (SqlDataReader reader = command.ExecuteReader())
- {
- while (reader.Read())
- {
- for (int i = 0; i < reader.FieldCount; i++)
- {
- Console.WriteLine(
- $"{reader.GetName(i)}: {reader.GetValue(i)}"
- );
- }
- }
- }
+ Console.WriteLine(
+ $"{reader.GetName(i)}: {reader.GetValue(i)}"
+ );
}
}
}
diff --git a/WebAPI/Controllers/UsersController.cs b/WebAPI/Controllers/UsersController.cs
index 18c08b3..1764447 100644
--- a/WebAPI/Controllers/UsersController.cs
+++ b/WebAPI/Controllers/UsersController.cs
@@ -65,15 +65,15 @@ namespace WebAPI.Controllers
[HttpPost]
public IActionResult CreateUser([FromBody] UserAccount userAccount)
{
- if (userAccount.UserAccountID == Guid.Empty)
+ if (userAccount.UserAccountId == Guid.Empty)
{
- userAccount.UserAccountID = Guid.NewGuid();
+ userAccount.UserAccountId = Guid.NewGuid();
}
_userService.Add(userAccount);
return CreatedAtAction(
nameof(GetUserById),
- new { id = userAccount.UserAccountID },
+ new { id = userAccount.UserAccountId },
userAccount
);
}
@@ -85,14 +85,14 @@ namespace WebAPI.Controllers
)
{
if (
- userAccount.UserAccountID != Guid.Empty
- && userAccount.UserAccountID != id
+ userAccount.UserAccountId != Guid.Empty
+ && userAccount.UserAccountId != id
)
{
return BadRequest("UserAccountID does not match route id.");
}
- userAccount.UserAccountID = id;
+ userAccount.UserAccountId = id;
_userService.Update(userAccount);
return NoContent();
}
diff --git a/WebAPI/Program.cs b/WebAPI/Program.cs
index 24618ed..9b595a0 100644
--- a/WebAPI/Program.cs
+++ b/WebAPI/Program.cs
@@ -1,5 +1,6 @@
using BusinessLayer.Services;
using DataAccessLayer;
+using DataAccessLayer.Repositories;
var builder = WebApplication.CreateBuilder(args);