mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-07-16 17:47:22 +00:00
Migrate Breweries to a vertical slice (Features.Breweries)
Moves brewery CRUD from the Service.Breweries/Infrastructure.Repository layered split into a single Features.Breweries project: MediatR commands/queries replace BreweryService, and the repository moves in alongside its own controller. Extracts Infrastructure.Sql out of Infrastructure.Repository (just the generic ADO.NET connection/base-repo plumbing) since Breweries no longer needs the rest of that project, while Auth and UserAccount repos still do until their own migration. Also fixes the API.Core and Infrastructure.Repository.Tests Dockerfiles, which were restoring against COPY destinations that didn't match the projects' actual relative paths (silently working only because of the COPY . . that followed); both now restore against Core.slnx with correctly nested paths, verified with a real docker build.
This commit is contained in:
@@ -1,59 +0,0 @@
|
||||
using FluentValidation;
|
||||
|
||||
namespace API.Core.Contracts.Breweries;
|
||||
|
||||
/// <summary>
|
||||
/// Validates <see cref="BreweryCreateDto"/> instances before they are processed by the brewery creation endpoint.
|
||||
/// </summary>
|
||||
public class BreweryCreateDtoValidator : AbstractValidator<BreweryCreateDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// Configures validation rules requiring <see cref="BreweryCreateDto.PostedById"/>,
|
||||
/// <see cref="BreweryCreateDto.BreweryName"/>, <see cref="BreweryCreateDto.Description"/>, and
|
||||
/// <see cref="BreweryCreateDto.Location"/> to be present, with length limits on the name, description,
|
||||
/// address line 1, and postal code fields.
|
||||
/// </summary>
|
||||
public BreweryCreateDtoValidator()
|
||||
{
|
||||
RuleFor(x => x.PostedById)
|
||||
.NotEmpty()
|
||||
.WithMessage("PostedById is required.");
|
||||
|
||||
RuleFor(x => x.BreweryName)
|
||||
.NotEmpty()
|
||||
.WithMessage("Brewery name is required.")
|
||||
.MaximumLength(256)
|
||||
.WithMessage("Brewery name cannot exceed 256 characters.");
|
||||
|
||||
RuleFor(x => x.Description)
|
||||
.NotEmpty()
|
||||
.WithMessage("Description is required.")
|
||||
.MaximumLength(512)
|
||||
.WithMessage("Description cannot exceed 512 characters.");
|
||||
|
||||
RuleFor(x => x.Location)
|
||||
.NotNull()
|
||||
.WithMessage("Location is required.");
|
||||
|
||||
RuleFor(x => x.Location.CityId)
|
||||
.NotEmpty()
|
||||
.When(x => x.Location is not null)
|
||||
.WithMessage("CityId is required.");
|
||||
|
||||
RuleFor(x => x.Location.AddressLine1)
|
||||
.NotEmpty()
|
||||
.When(x => x.Location is not null)
|
||||
.WithMessage("Address line 1 is required.")
|
||||
.MaximumLength(256)
|
||||
.When(x => x.Location is not null)
|
||||
.WithMessage("Address line 1 cannot exceed 256 characters.");
|
||||
|
||||
RuleFor(x => x.Location.PostalCode)
|
||||
.NotEmpty()
|
||||
.When(x => x.Location is not null)
|
||||
.WithMessage("Postal code is required.")
|
||||
.MaximumLength(20)
|
||||
.When(x => x.Location is not null)
|
||||
.WithMessage("Postal code cannot exceed 20 characters.");
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
namespace API.Core.Contracts.Breweries;
|
||||
|
||||
/// <summary>
|
||||
/// Request payload describing the location of a brewery to be created, supplied as part of
|
||||
/// <see cref="BreweryCreateDto"/>.
|
||||
/// </summary>
|
||||
public class BreweryLocationCreateDto
|
||||
{
|
||||
/// <summary>
|
||||
/// The unique identifier of the city in which the brewery is located.
|
||||
/// </summary>
|
||||
public Guid CityId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The primary street address line of the brewery.
|
||||
/// </summary>
|
||||
public string AddressLine1 { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// An optional secondary address line (e.g. suite or unit number).
|
||||
/// </summary>
|
||||
public string? AddressLine2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The postal/ZIP code of the brewery's address.
|
||||
/// </summary>
|
||||
public string PostalCode { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The optional geographic coordinates of the brewery, in a raw binary representation.
|
||||
/// </summary>
|
||||
public byte[]? Coordinates { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the location details of an existing brewery, as returned in <see cref="BreweryDto"/>.
|
||||
/// </summary>
|
||||
public class BreweryLocationDto
|
||||
{
|
||||
/// <summary>
|
||||
/// The unique identifier of the brewery's location record.
|
||||
/// </summary>
|
||||
public Guid BreweryPostLocationId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The unique identifier of the brewery post that this location belongs to.
|
||||
/// </summary>
|
||||
public Guid BreweryPostId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The unique identifier of the city in which the brewery is located.
|
||||
/// </summary>
|
||||
public Guid CityId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The primary street address line of the brewery.
|
||||
/// </summary>
|
||||
public string AddressLine1 { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// An optional secondary address line (e.g. suite or unit number).
|
||||
/// </summary>
|
||||
public string? AddressLine2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The postal/ZIP code of the brewery's address.
|
||||
/// </summary>
|
||||
public string PostalCode { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The optional geographic coordinates of the brewery, in a raw binary representation.
|
||||
/// </summary>
|
||||
public byte[]? Coordinates { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request body used by <see cref="Controllers.BreweryController.Create"/> to create a new brewery post.
|
||||
/// </summary>
|
||||
public class BreweryCreateDto
|
||||
{
|
||||
/// <summary>
|
||||
/// The unique identifier of the user account that is creating the brewery post.
|
||||
/// </summary>
|
||||
public Guid PostedById { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the brewery; required and limited to 256 characters.
|
||||
/// </summary>
|
||||
public string BreweryName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// A description of the brewery; required and limited to 512 characters.
|
||||
/// </summary>
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The location details of the brewery being created.
|
||||
/// </summary>
|
||||
public BreweryLocationCreateDto Location { get; set; } = null!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a brewery post as returned by, or submitted to, the brewery endpoints, including its
|
||||
/// metadata and optional location.
|
||||
/// </summary>
|
||||
public class BreweryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// The unique identifier of the brewery post.
|
||||
/// </summary>
|
||||
public Guid BreweryPostId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The unique identifier of the user account that created the brewery post.
|
||||
/// </summary>
|
||||
public Guid PostedById { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the brewery.
|
||||
/// </summary>
|
||||
public string BreweryName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// A description of the brewery.
|
||||
/// </summary>
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The date and time at which the brewery post was created.
|
||||
/// </summary>
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The date and time at which the brewery post was last updated, or <c>null</c> if it has never been updated.
|
||||
/// </summary>
|
||||
public DateTime? UpdatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A row-version/concurrency token used to detect conflicting concurrent updates to the brewery post.
|
||||
/// </summary>
|
||||
public byte[]? Timer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The location details of the brewery, or <c>null</c> if no location is associated with it.
|
||||
/// </summary>
|
||||
public BreweryLocationDto? Location { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user