using Projects.APP.Domain;
using CORE.APP.Features;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
namespace Projects.APP.Features.Projects
{
/// <summary>
/// Represents a request to create a new project.
/// Implements validation using data annotations.
/// </summary>
public class ProjectCreateRequest : Request, IRequest<CommandResponse>
{
[JsonIgnore]
public override int Id { get => base.Id; set => base.Id = value; }
/// <summary>
/// Name of the project (required, must be between 5 and 200 characters).
/// </summary>
[Required, Length(5, 200)]
public string Name { get; set; }
/// <summary>
/// Description of the project (optional, maximum length 1000 characters).
/// </summary>
[StringLength(1000)]
public string Description { get; set; }
/// <summary>
/// URL associated with the project (optional, maximum length 400 characters).
/// </summary>
[StringLength(400)]
public string Url { get; set; }
/// <summary>
/// Version of the project (optional, must be a positive number).
/// </summary>
[Range(0, double.MaxValue)]
public double? Version { get; set; }
/// <summary>
/// List of tag IDs associated with the project.
/// </summary>
//[Required] // Uncomment to enforce that at least one tag ID must be present.
public List<int> TagIds { get; set; }
}
/// <summary>
/// Handles the creation of a new project.
/// </summary>
public class ProjectCreateHandler : ProjectsDbHandler, IRequestHandler<ProjectCreateRequest, CommandResponse>
{
/// <summary>
/// Initializes a new instance of the <see cref="ProjectCreateHandler"/> class.
/// </summary>
/// <param name="projectsDb">Database context for projects.</param>
public ProjectCreateHandler(ProjectsDb projectsDb) : base(projectsDb)
{
}
/// <summary>
/// Handles the request to create a new project.
/// </summary>
/// <param name="request">The project creation request.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>A command response indicating success or failure.</returns>
public async Task<CommandResponse> Handle(ProjectCreateRequest request, CancellationToken cancellationToken)
{
// Check if a project with the same name already exists
if (await _projectsDb.Projects.AnyAsync(p => p.Name.ToUpper() == request.Name.ToUpper().Trim(), cancellationToken))
return Error("Project with the same name exists!");
// Construct the new project entity
var entity = new Project()
{
Name = request.Name.Trim(),
Description = request.Description?.Trim(),
Url = request.Url?.Trim(),
Version = request.Version,
TagIds = request.TagIds
};
// Add the new project to the database and save changes
_projectsDb.Projects.Add(entity);
await _projectsDb.SaveChangesAsync(cancellationToken);
return Success("Project created successfully.", entity.Id);
}
}
}