Modify brewery location dto to include denormalized data

This commit is contained in:
Aaron Po
2026-08-19 03:30:30 -04:00
parent 693f74bb5b
commit 81a76c9baf
17 changed files with 261 additions and 133 deletions

View File

@@ -27,6 +27,8 @@ COPY ["Features/Features.Breweries/Features.Breweries.csproj", "Features/Feature
COPY ["Features/Features.Breweries.Tests/Features.Breweries.Tests.csproj", "Features/Features.Breweries.Tests/"] COPY ["Features/Features.Breweries.Tests/Features.Breweries.Tests.csproj", "Features/Features.Breweries.Tests/"]
COPY ["Features/Features.Emails/Features.Emails.csproj", "Features/Features.Emails/"] COPY ["Features/Features.Emails/Features.Emails.csproj", "Features/Features.Emails/"]
COPY ["Features/Features.Emails.Tests/Features.Emails.Tests.csproj", "Features/Features.Emails.Tests/"] COPY ["Features/Features.Emails.Tests/Features.Emails.Tests.csproj", "Features/Features.Emails.Tests/"]
COPY ["Features/Features.Locations/Features.Locations.csproj", "Features/Features.Locations/"]
COPY ["Features/Features.Locations.Tests/Features.Locations.Tests.csproj", "Features/Features.Locations.Tests/"]
COPY ["Features/Features.UserManagement/Features.UserManagement.csproj", "Features/Features.UserManagement/"] COPY ["Features/Features.UserManagement/Features.UserManagement.csproj", "Features/Features.UserManagement/"]
COPY ["Features/Features.UserManagement.Tests/Features.UserManagement.Tests.csproj", "Features/Features.UserManagement.Tests/"] COPY ["Features/Features.UserManagement.Tests/Features.UserManagement.Tests.csproj", "Features/Features.UserManagement.Tests/"]
COPY ["Infrastructure/Infrastructure.Email/Infrastructure.Email.csproj", "Infrastructure/Infrastructure.Email/"] COPY ["Infrastructure/Infrastructure.Email/Infrastructure.Email.csproj", "Infrastructure/Infrastructure.Email/"]

View File

@@ -17,6 +17,8 @@ COPY ["Features/Features.Breweries/Features.Breweries.csproj", "Features/Feature
COPY ["Features/Features.Breweries.Tests/Features.Breweries.Tests.csproj", "Features/Features.Breweries.Tests/"] COPY ["Features/Features.Breweries.Tests/Features.Breweries.Tests.csproj", "Features/Features.Breweries.Tests/"]
COPY ["Features/Features.Emails/Features.Emails.csproj", "Features/Features.Emails/"] COPY ["Features/Features.Emails/Features.Emails.csproj", "Features/Features.Emails/"]
COPY ["Features/Features.Emails.Tests/Features.Emails.Tests.csproj", "Features/Features.Emails.Tests/"] COPY ["Features/Features.Emails.Tests/Features.Emails.Tests.csproj", "Features/Features.Emails.Tests/"]
COPY ["Features/Features.Locations/Features.Locations.csproj", "Features/Features.Locations/"]
COPY ["Features/Features.Locations.Tests/Features.Locations.Tests.csproj", "Features/Features.Locations.Tests/"]
COPY ["Features/Features.UserManagement/Features.UserManagement.csproj", "Features/Features.UserManagement/"] COPY ["Features/Features.UserManagement/Features.UserManagement.csproj", "Features/Features.UserManagement/"]
COPY ["Features/Features.UserManagement.Tests/Features.UserManagement.Tests.csproj", "Features/Features.UserManagement.Tests/"] COPY ["Features/Features.UserManagement.Tests/Features.UserManagement.Tests.csproj", "Features/Features.UserManagement.Tests/"]
COPY ["Infrastructure/Infrastructure.Email/Infrastructure.Email.csproj", "Infrastructure/Infrastructure.Email/"] COPY ["Infrastructure/Infrastructure.Email/Infrastructure.Email.csproj", "Infrastructure/Infrastructure.Email/"]

View File

@@ -2,14 +2,15 @@
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
ARG BUILD_CONFIGURATION=Release ARG BUILD_CONFIGURATION=Release
WORKDIR /src WORKDIR /src
# Copy everything from the context (src/Core/Database) # Copy everything from the context (src/Core), matching Database.Seed/Dockerfile's context so
# ProjectReference paths outside Database/ (e.g. Infrastructure.Sql) resolve.
COPY . . COPY . .
RUN dotnet restore "./Database.Migrations/Database.Migrations.csproj" RUN dotnet restore "./Database/Database.Migrations/Database.Migrations.csproj"
RUN dotnet build "./Database.Migrations/Database.Migrations.csproj" -c $BUILD_CONFIGURATION -o /app/build RUN dotnet build "./Database/Database.Migrations/Database.Migrations.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish FROM build AS publish
ARG BUILD_CONFIGURATION=Release ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./Database.Migrations/Database.Migrations.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false RUN dotnet publish "./Database/Database.Migrations/Database.Migrations.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
FROM mcr.microsoft.com/dotnet/runtime:10.0 AS final FROM mcr.microsoft.com/dotnet/runtime:10.0 AS final
WORKDIR /app WORKDIR /app

View File

@@ -223,7 +223,7 @@ CREATE TABLE UserFollow
CONSTRAINT CK_CannotFollowOwnAccount CONSTRAINT CK_CannotFollowOwnAccount
CHECK (UserAccountID != FollowingID CHECK (UserAccountID != FollowingID
) )
); );
CREATE CREATE
NONCLUSTERED INDEX IX_UserFollow_UserAccount_FollowingID NONCLUSTERED INDEX IX_UserFollow_UserAccount_FollowingID
@@ -324,7 +324,7 @@ CREATE TABLE BreweryPost -- A user cannot be deleted if they have a post
PostedByID UNIQUEIDENTIFIER NOT NULL, PostedByID UNIQUEIDENTIFIER NOT NULL,
Description NVARCHAR(512) NOT NULL, Description NVARCHAR(MAX) NOT NULL,
CreatedAt DATETIME NOT NULL CreatedAt DATETIME NOT NULL
CONSTRAINT DF_BreweryPost_CreatedAt DEFAULT GETDATE(), CONSTRAINT DF_BreweryPost_CreatedAt DEFAULT GETDATE(),

View File

@@ -186,11 +186,13 @@ static async Task LoadBreweriesIntoDatabaseAsync(
await breweryRepository.CreateAsync( await breweryRepository.CreateAsync(
new BreweryPost new BreweryPost
{ {
BreweryPostId = Guid.NewGuid(),
BreweryName = breweryRecord.Brewery.NameEn, BreweryName = breweryRecord.Brewery.NameEn,
Description = breweryRecord.Brewery.DescriptionEn, Description = breweryRecord.Brewery.DescriptionEn,
PostedById = posterUserIds[i % posterUserIds.Count], PostedById = posterUserIds[i % posterUserIds.Count],
Location = new BreweryPostLocation Location = new BreweryPostLocation
{ {
BreweryPostLocationId = Guid.NewGuid(),
CityId = cityId, CityId = cityId,
AddressLine1 = "Address unavailable", AddressLine1 = "Address unavailable",
PostalCode = breweryRecord.Address.PostalCode, PostalCode = breweryRecord.Address.PostalCode,

View File

@@ -1,17 +0,0 @@
namespace Database.Seed;
public interface IExportDatabase
{
void SeedLocations(IEnumerable<Location> locations);
void SeedUsers(IEnumerable<User> users);
void SeedBreweries(IEnumerable<Brewery> breweries);
}
public interface IImportDatabase
{
IEnumerable<Location> GetLocations();
IEnumerable<User> GetUsers();
IEnumerable<Brewery> GetBreweries();
}

View File

@@ -8,6 +8,7 @@ public class BreweryPostLocation
public string? AddressLine2 { get; set; } public string? AddressLine2 { get; set; }
public string PostalCode { get; set; } = string.Empty; public string PostalCode { get; set; } = string.Empty;
public Guid CityId { get; set; } public Guid CityId { get; set; }
public City? City { get; set; }
public byte[]? Coordinates { get; set; } public byte[]? Coordinates { get; set; }
public byte[]? Timer { get; set; } public byte[]? Timer { get; set; }
} }

View File

@@ -5,4 +5,34 @@ public class City
public Guid CityId { get; set; } public Guid CityId { get; set; }
public string CityName { get; set; } = string.Empty; public string CityName { get; set; } = string.Empty;
public Guid StateProvinceId { get; set; } public Guid StateProvinceId { get; set; }
public StateProvince? StateProvince { get; set; }
public byte[]? Timer { get; set; }
}
public class StateProvince
{
public Guid StateProvinceId { get; set; }
public string StateProvinceName { get; set; } = string.Empty;
// this is the iso 3166-2 code for the state/province, e.g. "CA" for California, "ON" for Ontario, etc.
// and is rendered like US-CA for California, CA-ON for Ontario, etc.
public string ISO3166_2 { get; set; } = string.Empty;
public Guid CountryId { get; set; }
public Country? Country { get; set; }
public byte[]? Timer { get; set; }
}
public class Country
{
public Guid CountryId { get; set; }
public string CountryName { get; set; } = string.Empty;
public string ISO3166_1 { get; set; } = string.Empty; // this is the iso 3166-1 alpha-2 code for the country, e.g. "US" for United States, "CA" for Canada, etc.
public byte[]? Timer { get; set; }
} }

View File

@@ -20,8 +20,11 @@ public class BreweryRepositoryTests
MockDbConnection conn = new(); MockDbConnection conn = new();
Guid locationId = Guid.NewGuid(); Guid locationId = Guid.NewGuid();
Guid cityId = Guid.NewGuid();
Guid stateProvinceId = Guid.NewGuid();
Guid countryId = Guid.NewGuid();
conn.Mocks.When(cmd => cmd.CommandText.Contains("INNER JOIN dbo.BreweryPostLocation")) conn.Mocks.When(cmd => cmd.CommandText.Contains("LEFT JOIN dbo.BreweryPostLocation"))
.ReturnsTable( .ReturnsTable(
MockTable MockTable
.WithColumns( .WithColumns(
@@ -37,7 +40,14 @@ public class BreweryRepositoryTests
("AddressLine1", typeof(string)), ("AddressLine1", typeof(string)),
("AddressLine2", typeof(string)), ("AddressLine2", typeof(string)),
("PostalCode", typeof(string)), ("PostalCode", typeof(string)),
("Coordinates", typeof(byte[])) ("Coordinates", typeof(byte[])),
("CityName", typeof(string)),
("StateProvinceId", typeof(Guid)),
("StateProvinceName", typeof(string)),
("ISO3166_2", typeof(string)),
("CountryId", typeof(Guid)),
("CountryName", typeof(string)),
("ISO3166_1", typeof(string))
) )
.AddRow( .AddRow(
breweryId, breweryId,
@@ -48,11 +58,18 @@ public class BreweryRepositoryTests
null, null,
null, null,
locationId, locationId,
Guid.NewGuid(), cityId,
"123 Main St", "123 Main St",
null, null,
"12345", "12345",
null null,
"Portland",
stateProvinceId,
"Oregon",
"US-OR",
countryId,
"United States",
"US"
) )
); );
@@ -62,13 +79,19 @@ public class BreweryRepositoryTests
result!.BreweryPostId.Should().Be(breweryId); result!.BreweryPostId.Should().Be(breweryId);
result.Location.Should().NotBeNull(); result.Location.Should().NotBeNull();
result.Location!.BreweryPostLocationId.Should().Be(locationId); result.Location!.BreweryPostLocationId.Should().Be(locationId);
result.Location.City.Should().NotBeNull();
result.Location.City.CityName.Should().Be("Portland");
result.Location.City.StateProvince.Should().NotBeNull();
result.Location.City.StateProvince.StateProvinceName.Should().Be("Oregon");
result.Location.City.StateProvince.Country.Should().NotBeNull();
result.Location.City.StateProvince.Country.CountryName.Should().Be("United States");
} }
[Fact] [Fact]
public async Task GetByIdAsync_ReturnsNull_WhenNotExists() public async Task GetByIdAsync_ReturnsNull_WhenNotExists()
{ {
MockDbConnection conn = new(); MockDbConnection conn = new();
conn.Mocks.When(cmd => cmd.CommandText.Contains("INNER JOIN dbo.BreweryPostLocation")) conn.Mocks.When(cmd => cmd.CommandText.Contains("LEFT JOIN dbo.BreweryPostLocation"))
.ReturnsTable(MockTable.Empty()); .ReturnsTable(MockTable.Empty());
BreweryRepository repo = CreateRepo(conn); BreweryRepository repo = CreateRepo(conn);
BreweryPost? result = await repo.GetByIdAsync(Guid.NewGuid()); BreweryPost? result = await repo.GetByIdAsync(Guid.NewGuid());
@@ -225,7 +248,7 @@ public class BreweryRepositoryTests
.ReturnsScalar(1); .ReturnsScalar(1);
// Repository re-fetches the row after a successful update to return the new Timer. // Repository re-fetches the row after a successful update to return the new Timer.
conn.Mocks.When(cmd => cmd.CommandText.Contains("INNER JOIN dbo.BreweryPostLocation")) conn.Mocks.When(cmd => cmd.CommandText.Contains("LEFT JOIN dbo.BreweryPostLocation"))
.ReturnsTable( .ReturnsTable(
MockTable MockTable
.WithColumns( .WithColumns(
@@ -241,7 +264,14 @@ public class BreweryRepositoryTests
("AddressLine1", typeof(string)), ("AddressLine1", typeof(string)),
("AddressLine2", typeof(string)), ("AddressLine2", typeof(string)),
("PostalCode", typeof(string)), ("PostalCode", typeof(string)),
("Coordinates", typeof(byte[])) ("Coordinates", typeof(byte[])),
("CityName", typeof(string)),
("StateProvinceId", typeof(Guid)),
("StateProvinceName", typeof(string)),
("ISO3166_2", typeof(string)),
("CountryId", typeof(Guid)),
("CountryName", typeof(string)),
("ISO3166_1", typeof(string))
) )
.AddRow( .AddRow(
breweryId, breweryId,
@@ -256,7 +286,14 @@ public class BreweryRepositoryTests
"123 Main St", "123 Main St",
null, null,
"12345", "12345",
null null,
"Portland",
Guid.NewGuid(),
"Oregon",
"US-OR",
Guid.NewGuid(),
"United States",
"US"
) )
); );

View File

@@ -4,10 +4,16 @@ namespace Features.Breweries.Dtos;
public class BreweryLocationDto public class BreweryLocationDto
{ {
public Guid BreweryPostLocationId { get; set; } public Guid BreweryPostLocationId { get; set; }
public Guid BreweryPostId { get; set; }
public Guid CityId { get; set; } public Guid CityId { get; set; }
public string CityName { get; set; } = string.Empty;
public string StateProvinceName { get; set; } = string.Empty;
public string StateProvinceCode { get; set; } = string.Empty;
public string CountryName { get; set; } = string.Empty;
public string CountryCode { get; set; } = string.Empty;
public string AddressLine1 { get; set; } = string.Empty; public string AddressLine1 { get; set; } = string.Empty;
@@ -41,3 +47,5 @@ public class BreweryDto
/// <summary>Gets or sets the brewery's location, or <see langword="null"/> if none has been set.</summary> /// <summary>Gets or sets the brewery's location, or <see langword="null"/> if none has been set.</summary>
public BreweryLocationDto? Location { get; set; } public BreweryLocationDto? Location { get; set; }
} }

View File

@@ -25,8 +25,12 @@ public static class BreweryDtoMapper
: new BreweryLocationDto : new BreweryLocationDto
{ {
BreweryPostLocationId = brewery.Location.BreweryPostLocationId, BreweryPostLocationId = brewery.Location.BreweryPostLocationId,
BreweryPostId = brewery.Location.BreweryPostId,
CityId = brewery.Location.CityId, CityId = brewery.Location.CityId,
CityName = brewery.Location.City?.CityName ?? string.Empty,
StateProvinceName = brewery.Location.City?.StateProvince?.StateProvinceName ?? string.Empty,
StateProvinceCode = brewery.Location.City?.StateProvince?.ISO3166_2 ?? string.Empty,
CountryName = brewery.Location.City?.StateProvince?.Country?.CountryName ?? string.Empty,
CountryCode = brewery.Location.City?.StateProvince?.Country?.ISO3166_1 ?? string.Empty,
AddressLine1 = brewery.Location.AddressLine1, AddressLine1 = brewery.Location.AddressLine1,
AddressLine2 = brewery.Location.AddressLine2, AddressLine2 = brewery.Location.AddressLine2,
PostalCode = brewery.Location.PostalCode, PostalCode = brewery.Location.PostalCode,

View File

@@ -23,14 +23,45 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
IBreweryRepository IBreweryRepository
{ {
private const string SelectColumns = private const string SelectColumns =
"bp.BreweryPostID, bp.PostedByID, bp.BreweryName, bp.Description, bp.CreatedAt, bp.UpdatedAt, bp.Timer, " """
+ "bpl.BreweryPostLocationID, bpl.CityID, bpl.AddressLine1, bpl.AddressLine2, bpl.PostalCode, bpl.Coordinates"; bp.BreweryPostID,
bp.PostedByID,
bp.BreweryName,
bp.Description,
bp.CreatedAt,
bp.UpdatedAt,
bp.Timer,
bpl.BreweryPostLocationID,
bpl.CityID,
bpl.AddressLine1,
bpl.AddressLine2,
bpl.PostalCode,
bpl.Coordinates,
c.CityName,
c.StateProvinceID,
sp.StateProvinceName,
sp.ISO3166_2,
sp.CountryID,
co.CountryName,
co.ISO3166_1
""";
/// <summary>
/// Joins from <c>dbo.BreweryPost</c> down to <c>dbo.Country</c> so a row carries everything needed
/// to populate <see cref="BreweryPost.Location" />'s full <c>City</c> → <c>StateProvince</c> →
/// <c>Country</c> chain. All joins are <c>LEFT JOIN</c> (matching the previous stored procedure's
/// behavior), since a brewery post may have no location.
/// </summary>
private const string FromJoins =
"""
dbo.BreweryPost bp
LEFT JOIN dbo.BreweryPostLocation bpl ON bp.BreweryPostID = bpl.BreweryPostID
LEFT JOIN dbo.City c ON bpl.CityID = c.CityID
LEFT JOIN dbo.StateProvince sp ON c.StateProvinceID = sp.StateProvinceID
LEFT JOIN dbo.Country co ON sp.CountryID = co.CountryID
""";
/// <inheritdoc/> /// <inheritdoc/>
/// <remarks>
/// Joins to the location table with an <c>INNER JOIN</c> (matching the previous stored procedure's
/// behavior), which is why a brewery with no location row is treated as not found.
/// </remarks>
public async Task<BreweryPost?> GetByIdAsync(Guid id) public async Task<BreweryPost?> GetByIdAsync(Guid id)
{ {
await using DbConnection connection = await CreateConnection(); await using DbConnection connection = await CreateConnection();
@@ -38,8 +69,7 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
command.CommandText = command.CommandText =
$""" $"""
SELECT {SelectColumns} SELECT {SelectColumns}
FROM dbo.BreweryPost bp FROM {FromJoins}
INNER JOIN dbo.BreweryPostLocation bpl ON bp.BreweryPostID = bpl.BreweryPostID
WHERE bp.BreweryPostID = @BreweryPostId WHERE bp.BreweryPostID = @BreweryPostId
"""; """;
AddParameter(command, "@BreweryPostId", id); AddParameter(command, "@BreweryPostId", id);
@@ -56,8 +86,7 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
command.CommandText = command.CommandText =
$""" $"""
SELECT {SelectColumns} SELECT {SelectColumns}
FROM dbo.BreweryPost bp FROM {FromJoins}
LEFT JOIN dbo.BreweryPostLocation bpl ON bp.BreweryPostID = bpl.BreweryPostID
ORDER BY bp.CreatedAt DESC ORDER BY bp.CreatedAt DESC
OFFSET @Offset ROWS FETCH NEXT @Limit ROWS ONLY OFFSET @Offset ROWS FETCH NEXT @Limit ROWS ONLY
"""; """;
@@ -339,6 +368,7 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
BreweryPostLocationId = reader.GetGuid(ordLocationId), BreweryPostLocationId = reader.GetGuid(ordLocationId),
BreweryPostId = brewery.BreweryPostId, BreweryPostId = brewery.BreweryPostId,
CityId = reader.GetGuid(reader.GetOrdinal("CityId")), CityId = reader.GetGuid(reader.GetOrdinal("CityId")),
City = MapCity(reader),
AddressLine1 = reader.GetString(reader.GetOrdinal("AddressLine1")), AddressLine1 = reader.GetString(reader.GetOrdinal("AddressLine1")),
AddressLine2 = reader.IsDBNull(ordAddressLine2) AddressLine2 = reader.IsDBNull(ordAddressLine2)
? null ? null
@@ -353,6 +383,34 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
return brewery; return brewery;
} }
/// <summary>
/// Maps the current row's <c>City</c> → <c>StateProvince</c> → <c>Country</c> columns. The schema
/// enforces <c>NOT NULL</c> foreign keys down this whole chain, so whenever a location row was
/// joined in (the caller only calls this when it was), these columns are always populated too.
/// </summary>
private static City MapCity(DbDataReader reader)
{
return new City
{
CityId = reader.GetGuid(reader.GetOrdinal("CityId")),
CityName = reader.GetString(reader.GetOrdinal("CityName")),
StateProvinceId = reader.GetGuid(reader.GetOrdinal("StateProvinceId")),
StateProvince = new StateProvince
{
StateProvinceId = reader.GetGuid(reader.GetOrdinal("StateProvinceId")),
StateProvinceName = reader.GetString(reader.GetOrdinal("StateProvinceName")),
ISO3166_2 = reader.GetString(reader.GetOrdinal("ISO3166_2")),
CountryId = reader.GetGuid(reader.GetOrdinal("CountryId")),
Country = new Country
{
CountryId = reader.GetGuid(reader.GetOrdinal("CountryId")),
CountryName = reader.GetString(reader.GetOrdinal("CountryName")),
ISO3166_1 = reader.GetString(reader.GetOrdinal("ISO3166_1")),
},
},
};
}
private static void AddParameter(DbCommand command, string name, object? value) private static void AddParameter(DbCommand command, string name, object? value)
{ {
DbParameter p = command.CreateParameter(); DbParameter p = command.CreateParameter();

View File

@@ -32,8 +32,8 @@ services:
sqlserver: sqlserver:
condition: service_healthy condition: service_healthy
build: build:
context: ./backend/Database context: ./backend
dockerfile: Database.Migrations/Dockerfile dockerfile: Database/Database.Migrations/Dockerfile
args: args:
BUILD_CONFIGURATION: Release BUILD_CONFIGURATION: Release
APP_UID: 1000 APP_UID: 1000

View File

@@ -32,8 +32,8 @@ services:
sqlserver: sqlserver:
condition: service_healthy condition: service_healthy
build: build:
context: ./backend/Database context: ./backend
dockerfile: Database.Migrations/Dockerfile dockerfile: Database/Database.Migrations/Dockerfile
args: args:
BUILD_CONFIGURATION: Release BUILD_CONFIGURATION: Release
APP_UID: 1000 APP_UID: 1000

View File

@@ -32,8 +32,8 @@ services:
sqlserver: sqlserver:
condition: service_healthy condition: service_healthy
build: build:
context: ./backend/Database context: ./backend
dockerfile: Database.Migrations/Dockerfile dockerfile: Database/Database.Migrations/Dockerfile
args: args:
BUILD_CONFIGURATION: Release BUILD_CONFIGURATION: Release
APP_UID: 1000 APP_UID: 1000

View File

@@ -31,8 +31,8 @@ services:
sqlserver: sqlserver:
condition: service_healthy condition: service_healthy
build: build:
context: ./backend/Database context: ./backend
dockerfile: Database.Migrations/Dockerfile dockerfile: Database/Database.Migrations/Dockerfile
args: args:
BUILD_CONFIGURATION: Release BUILD_CONFIGURATION: Release
APP_UID: 1000 APP_UID: 1000

View File

@@ -32,8 +32,8 @@ services:
sqlserver: sqlserver:
condition: service_healthy condition: service_healthy
build: build:
context: ./backend/Database context: ./backend
dockerfile: Database.Migrations/Dockerfile dockerfile: Database/Database.Migrations/Dockerfile
args: args:
BUILD_CONFIGURATION: Release BUILD_CONFIGURATION: Release
APP_UID: 1000 APP_UID: 1000