Реализован модуль каталога, миграции, сваггер
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
using System.Text.Json;
|
||||
using MediatR;
|
||||
using Nashel.Modules.Catalog.Domain.Aggregates;
|
||||
using Nashel.Modules.Catalog.Domain.Repositories;
|
||||
|
||||
namespace Nashel.Modules.Catalog.Application.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Команда создания категории.
|
||||
/// </summary>
|
||||
public record CreateCategoryCommand : IRequest<Guid>
|
||||
{
|
||||
/// <summary>
|
||||
/// Название категории.
|
||||
/// </summary>
|
||||
public string Title { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// URL-friendly идентификатор (слаг).
|
||||
/// </summary>
|
||||
public string Slug { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// ID родительской категории (null для корневых).
|
||||
/// </summary>
|
||||
public Guid? ParentId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Шаблон характеристик (JSON).
|
||||
/// </summary>
|
||||
public JsonDocument? AttributeSchema { get; init; }
|
||||
|
||||
public CreateCategoryCommand(string title, string slug, Guid? parentId, JsonDocument? attributeSchema)
|
||||
{
|
||||
Title = title;
|
||||
Slug = slug;
|
||||
ParentId = parentId;
|
||||
AttributeSchema = attributeSchema;
|
||||
}
|
||||
|
||||
public CreateCategoryCommand() { } // For deserialization
|
||||
}
|
||||
|
||||
public class CreateCategoryCommandHandler : IRequestHandler<CreateCategoryCommand, Guid>
|
||||
{
|
||||
private readonly ICategoryRepository _repository;
|
||||
|
||||
public CreateCategoryCommandHandler(ICategoryRepository repository)
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
public async Task<Guid> Handle(CreateCategoryCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (request.ParentId.HasValue)
|
||||
{
|
||||
var parentCategory = await _repository.GetByIdAsync(request.ParentId.Value, cancellationToken);
|
||||
if (parentCategory == null)
|
||||
{
|
||||
throw new ApplicationException($"Родительская категория с ID {request.ParentId} не найдена.");
|
||||
}
|
||||
}
|
||||
|
||||
var category = new Category(
|
||||
request.Title,
|
||||
request.Slug,
|
||||
request.ParentId,
|
||||
request.AttributeSchema
|
||||
);
|
||||
|
||||
await _repository.AddAsync(category, cancellationToken);
|
||||
|
||||
return category.Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System.Text.Json;
|
||||
using MediatR;
|
||||
using Nashel.Modules.Catalog.Domain.Aggregates;
|
||||
using Nashel.Modules.Catalog.Domain.Repositories;
|
||||
using Nashel.Modules.Catalog.Domain.ValueObjects;
|
||||
|
||||
namespace Nashel.Modules.Catalog.Application.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Команда создания услуги (оффера).
|
||||
/// </summary>
|
||||
public record CreateOfferCommand : IRequest<Guid>
|
||||
{
|
||||
/// <summary>
|
||||
/// ID владельца (пользователя/исполнителя).
|
||||
/// </summary>
|
||||
public Guid OwnerId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// ID категории услуги.
|
||||
/// </summary>
|
||||
public Guid CategoryId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Заголовок объявления.
|
||||
/// </summary>
|
||||
public string Title { get; init; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Полное описание услуги.
|
||||
/// </summary>
|
||||
public string Description { get; init; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Цена услуги.
|
||||
/// </summary>
|
||||
public Price Price { get; init; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Характеристики услуги (JSON).
|
||||
/// </summary>
|
||||
public JsonDocument? Attributes { get; init; }
|
||||
|
||||
public CreateOfferCommand(Guid ownerId, Guid categoryId, string title, string description, Price price, JsonDocument? attributes)
|
||||
{
|
||||
OwnerId = ownerId;
|
||||
CategoryId = categoryId;
|
||||
Title = title;
|
||||
Description = description;
|
||||
Price = price;
|
||||
Attributes = attributes;
|
||||
}
|
||||
|
||||
public CreateOfferCommand() { }
|
||||
}
|
||||
|
||||
public class CreateOfferCommandHandler : IRequestHandler<CreateOfferCommand, Guid>
|
||||
{
|
||||
private readonly IOfferRepository _repository;
|
||||
|
||||
public CreateOfferCommandHandler(IOfferRepository repository)
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
public async Task<Guid> Handle(CreateOfferCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var offer = new Offer(
|
||||
request.OwnerId,
|
||||
request.CategoryId,
|
||||
request.Title,
|
||||
request.Description,
|
||||
request.Price,
|
||||
request.Attributes
|
||||
);
|
||||
|
||||
await _repository.AddAsync(offer, cancellationToken);
|
||||
|
||||
return offer.Id;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user