diff --git a/MBS-COMMAND.API/appsettings.json b/MBS-COMMAND.API/appsettings.json index 4f69f9b..5436af7 100644 --- a/MBS-COMMAND.API/appsettings.json +++ b/MBS-COMMAND.API/appsettings.json @@ -69,5 +69,6 @@ "WithThreadId" ] }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "Domain" : "localhost:3000" } diff --git a/MBS_COMMAND.Application/UserCases/Commands/Groups/AcceptGroupInvitationCommandHandler.cs b/MBS_COMMAND.Application/UserCases/Commands/Groups/AcceptGroupInvitationCommandHandler.cs new file mode 100644 index 0000000..0df641c --- /dev/null +++ b/MBS_COMMAND.Application/UserCases/Commands/Groups/AcceptGroupInvitationCommandHandler.cs @@ -0,0 +1,36 @@ +using MBS_COMMAND.Contract.Abstractions.Messages; +using MBS_COMMAND.Contract.Abstractions.Shared; +using MBS_COMMAND.Domain.Abstractions; +using MBS_COMMAND.Domain.Abstractions.Repositories; +using MBS_COMMAND.Domain.Entities; +using MBS_CONTRACT.SHARE.Services.Groups; +using Command = MBS_COMMAND.Contract.Services.Groups.Command; + +namespace MBS_COMMAND.Application.UserCases.Commands.Groups; + +public class AcceptGroupInvitationCommandHandler( + IRepositoryBase userRepository, + IRepositoryBase groupRepository, + IUnitOfWork unitOfWork) + : ICommandHandler +{ + public async Task Handle(Command.AcceptGroupInvitation request, CancellationToken cancellationToken) + { + var u = await userRepository.FindByIdAsync(request.MemberId, cancellationToken); + if (u == null) + return Result.Failure(new Error("404", "User Not Found")); + if (u.Status == 2) + { + return Result.Failure(new Error("403", "User is blocked")); + } + + var g = await groupRepository.FindSingleAsync(x => x.Id == request.GroupId, cancellationToken); + if (g == null) + return Result.Failure(new Error("404", "Group Not Found")); + if (g.Members!.Any(x => x.StudentId == u.Id)) + return Result.Failure(new Error("422", "Member already joined group")); + g.Members!.Add(new Group_Student_Mapping { StudentId = u.Id, GroupId = g.Id }); + unitOfWork.SaveChangesAsync(cancellationToken); + return Result.Success("Member added to group"); + } +} \ No newline at end of file diff --git a/MBS_COMMAND.Application/UserCases/Commands/Groups/AddMemberToGroupCommandHandler.cs b/MBS_COMMAND.Application/UserCases/Commands/Groups/AddMemberToGroupCommandHandler.cs index 4985efb..119571f 100644 --- a/MBS_COMMAND.Application/UserCases/Commands/Groups/AddMemberToGroupCommandHandler.cs +++ b/MBS_COMMAND.Application/UserCases/Commands/Groups/AddMemberToGroupCommandHandler.cs @@ -5,10 +5,15 @@ using MBS_COMMAND.Domain.Abstractions; using MBS_COMMAND.Domain.Abstractions.Repositories; using MBS_COMMAND.Domain.Entities; +using Microsoft.Extensions.Configuration; namespace MBS_COMMAND.Application.UserCases.Commands.Groups; -public sealed class AddMemberToGroupCommandHandler(IRepositoryBase groupRepository, IRepositoryBase userRepository, IUnitOfWork unitOfWork, IMailService mailService) : ICommandHandler +public sealed class AddMemberToGroupCommandHandler( + IRepositoryBase groupRepository, + IRepositoryBase userRepository, + IConfiguration configuration, + IMailService mailService) : ICommandHandler { public async Task Handle(Command.AddMemberToGroup request, CancellationToken cancellationToken) { @@ -20,17 +25,24 @@ public async Task Handle(Command.AddMemberToGroup request, CancellationT return Result.Failure(new Error("404", "Group Not Found")); if (g.Members!.Any(x => x.StudentId == u.Id)) return Result.Failure(new Error("422", "Member already joined group")); - g.Members!.Add(new Group_Student_Mapping { StudentId = u.Id, GroupId = g.Id }); - groupRepository.Update(g); + //g.Members!.Add(new Group_Student_Mapping { StudentId = u.Id, GroupId = g.Id }); + var domain = configuration["Domain"]; await mailService.SendMail(new MailContent { To = u.Email, - Subject = "Join Group", - Body = $"You have been invited to group {g.Name}" + Subject = $"Invitation to group {g.Name}", + Body = $@" +

You have been invited to group {g.Name}

+ + Accept Invitation + + " }); - await unitOfWork.SaveChangesAsync(cancellationToken); + + //send mail to user return Result.Success(); } -} +} \ No newline at end of file diff --git a/MBS_COMMAND.Application/UserCases/Commands/Slots/CreateSlotCommandHandler.cs b/MBS_COMMAND.Application/UserCases/Commands/Slots/CreateSlotCommandHandler.cs index df28a40..0e7bfb1 100644 --- a/MBS_COMMAND.Application/UserCases/Commands/Slots/CreateSlotCommandHandler.cs +++ b/MBS_COMMAND.Application/UserCases/Commands/Slots/CreateSlotCommandHandler.cs @@ -6,10 +6,10 @@ using MBS_COMMAND.Domain.Entities; using static System.DateOnly; namespace MBS_COMMAND.Application.UserCases.Commands.Slots; - //Test v2 public sealed class CreateSlotCommandHandler( IRepositoryBase slotRepository, IRepositoryBase userRepository, + IRepositoryBase semesterRepository, IUnitOfWork unitOfWork) : ICommandHandler { @@ -18,7 +18,9 @@ public async Task Handle(Command.CreateSlot request, CancellationToken c var mentor = await userRepository.FindByIdAsync(request.MentorId, cancellationToken); if (mentor == null) return Result.Failure(new Error("404", "User Not Found")); - + var currentSemester = await semesterRepository.FindSingleAsync(x => x.IsActive, cancellationToken); + if(request.SlotModels.Any(x=>Parse(x.Date) < currentSemester!.From || Parse(x.Date) > currentSemester.From.AddDays(6))) + return Result.Failure(new Error("400", "Slot date must within the current semester and in the 1st week of the semester")); var newSlots = request.SlotModels.Select(slotModel => new Slot { Id = Guid.NewGuid(), @@ -40,12 +42,9 @@ public async Task Handle(Command.CreateSlot request, CancellationToken c var existingSlots = slotRepository.FindAll(x => x.MentorId == mentor.Id); // Check for overlaps with existing slots - foreach (var newSlot in newSlots) + foreach (var newSlot in newSlots.Where(newSlot => HasOverlap(newSlot, existingSlots))) { - if (HasOverlap(newSlot, existingSlots)) - { - return Result.Failure(new Error("409", $"Slot overlaps with existing slot: {newSlot.Date} {newSlot.StartTime}-{newSlot.EndTime}")); - } + return Result.Failure(new Error("409", $"Slot overlaps with existing slot: {newSlot.Date} {newSlot.StartTime}-{newSlot.EndTime}")); } slotRepository.AddRange(newSlots); diff --git a/MBS_COMMAND.Contract/Services/Groups/Command.cs b/MBS_COMMAND.Contract/Services/Groups/Command.cs index 2b07f24..093c211 100644 --- a/MBS_COMMAND.Contract/Services/Groups/Command.cs +++ b/MBS_COMMAND.Contract/Services/Groups/Command.cs @@ -9,4 +9,5 @@ public record AddMemberToGroup(Guid GroupId, Guid MemberId) : ICommand; public record RemoveMemberFromGroup(Guid GroupId, Guid MemberId) : ICommand; public record ChangeLeader(Guid GroupId, Guid NewLeaderId) : ICommand; public record UpdateGroup(Guid GroupId, string Name, string Stacks) : ICommand; + public record AcceptGroupInvitation(Guid GroupId, Guid MemberId) : ICommand; } diff --git a/MBS_COMMAND.Domain/Entities/Semester.cs b/MBS_COMMAND.Domain/Entities/Semester.cs index e194af5..e2d054c 100644 --- a/MBS_COMMAND.Domain/Entities/Semester.cs +++ b/MBS_COMMAND.Domain/Entities/Semester.cs @@ -7,6 +7,7 @@ public class Semester : Entity, IAuditableEntity public string Name { get; set; } public DateOnly From { get; set; } public DateOnly To { get; set; } + public bool IsActive { get; set; } public DateTimeOffset CreatedOnUtc { get; set; } public DateTimeOffset? ModifiedOnUtc { get; set; } } diff --git a/MBS_COMMAND.Persistence/Migrations/20241016074854_fix_semester.Designer.cs b/MBS_COMMAND.Persistence/Migrations/20241016074854_fix_semester.Designer.cs new file mode 100644 index 0000000..a233607 --- /dev/null +++ b/MBS_COMMAND.Persistence/Migrations/20241016074854_fix_semester.Designer.cs @@ -0,0 +1,748 @@ +// +using System; +using MBS_COMMAND.Persistence; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace MBS_COMMAND.Persistence.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20241016074854_fix_semester")] + partial class fix_semester + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true) + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModifiedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Certificate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ImageUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MentorSkillsId") + .HasColumnType("uniqueidentifier"); + + b.Property("ModifiedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("MentorSkillsId"); + + b.ToTable("Certificates"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Config", b => + { + b.Property("Key") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("int"); + + b.HasKey("Key"); + + b.ToTable("Configs"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Feedback", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsMentor") + .HasColumnType("bit"); + + b.Property("ModifiedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Rating") + .HasColumnType("int"); + + b.Property("SlotId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SlotId"); + + b.ToTable("Feedbacks"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LeaderId") + .HasColumnType("uniqueidentifier"); + + b.Property("MentorId") + .HasColumnType("uniqueidentifier"); + + b.Property("ModifiedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("Stack") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("LeaderId"); + + b.HasIndex("MentorId"); + + b.HasIndex("ProjectId"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Group_Student_Mapping", b => + { + b.Property("GroupId") + .HasColumnType("uniqueidentifier"); + + b.Property("StudentId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("GroupId", "StudentId"); + + b.HasIndex("StudentId"); + + b.ToTable("group_Student_Mappings"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.MentorSkills", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModifiedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SkillId"); + + b.HasIndex("UserId"); + + b.ToTable("MentorSkillses"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModifiedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Projects"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Schedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Date") + .HasColumnType("date"); + + b.Property("EndTime") + .HasColumnType("time"); + + b.Property("GroupId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsBooked") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MentorId") + .HasColumnType("uniqueidentifier"); + + b.Property("ModifiedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("StartTime") + .HasColumnType("time"); + + b.Property("SubjectId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("GroupId"); + + b.HasIndex("MentorId"); + + b.HasIndex("SubjectId"); + + b.ToTable("Schedules"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Semester", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("From") + .HasColumnType("date"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModifiedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("To") + .HasColumnType("date"); + + b.HasKey("Id"); + + b.ToTable("Semesters"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Skill", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModifiedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CategoryId"); + + b.ToTable("Skills"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Slot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Date") + .HasColumnType("date"); + + b.Property("EndTime") + .HasColumnType("time"); + + b.Property("IsBook") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsOnline") + .HasColumnType("bit"); + + b.Property("MentorId") + .HasColumnType("uniqueidentifier"); + + b.Property("ModifiedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Month") + .HasColumnType("smallint"); + + b.Property("Note") + .HasColumnType("nvarchar(max)"); + + b.Property("StartTime") + .HasColumnType("time"); + + b.HasKey("Id"); + + b.HasIndex("MentorId"); + + b.ToTable("Slots"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Subject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModifiedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SemesterId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("SemesterId"); + + b.ToTable("Subjects"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Transaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Date") + .HasColumnType("date"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModifiedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("SlotId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SlotId"); + + b.HasIndex("UserId"); + + b.ToTable("Transactions"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FullName") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsFirstLogin") + .HasColumnType("bit"); + + b.Property("MentorId") + .HasColumnType("uniqueidentifier"); + + b.Property("ModifiedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Points") + .HasColumnType("int"); + + b.Property("Role") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("MentorId"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("MBS_COMMAND.Persistence.Outbox.OutboxMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Error") + .HasColumnType("nvarchar(max)"); + + b.Property("OccurredOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("ProcessedOnUtc") + .HasColumnType("datetimeoffset"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("OutboxMessages", (string)null); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Certificate", b => + { + b.HasOne("MBS_COMMAND.Domain.Entities.MentorSkills", "MentorSkills") + .WithMany("CertificateList") + .HasForeignKey("MentorSkillsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MentorSkills"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Feedback", b => + { + b.HasOne("MBS_COMMAND.Domain.Entities.Slot", "Slot") + .WithMany() + .HasForeignKey("SlotId"); + + b.Navigation("Slot"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Group", b => + { + b.HasOne("MBS_COMMAND.Domain.Entities.User", "Leader") + .WithMany() + .HasForeignKey("LeaderId"); + + b.HasOne("MBS_COMMAND.Domain.Entities.User", "Mentor") + .WithMany() + .HasForeignKey("MentorId"); + + b.HasOne("MBS_COMMAND.Domain.Entities.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId"); + + b.Navigation("Leader"); + + b.Navigation("Mentor"); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Group_Student_Mapping", b => + { + b.HasOne("MBS_COMMAND.Domain.Entities.Group", "Group") + .WithMany("Members") + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MBS_COMMAND.Domain.Entities.User", "Student") + .WithMany("Groups") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Group"); + + b.Navigation("Student"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.MentorSkills", b => + { + b.HasOne("MBS_COMMAND.Domain.Entities.Skill", "Skill") + .WithMany("MentorSkillsList") + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MBS_COMMAND.Domain.Entities.User", "User") + .WithMany("MentorSkillsList") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Skill"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Schedule", b => + { + b.HasOne("MBS_COMMAND.Domain.Entities.Group", "Group") + .WithMany() + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MBS_COMMAND.Domain.Entities.User", "Mentor") + .WithMany() + .HasForeignKey("MentorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MBS_COMMAND.Domain.Entities.Subject", "Subject") + .WithMany() + .HasForeignKey("SubjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Group"); + + b.Navigation("Mentor"); + + b.Navigation("Subject"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Skill", b => + { + b.HasOne("MBS_COMMAND.Domain.Entities.Category", "Category") + .WithMany("SkillList") + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Slot", b => + { + b.HasOne("MBS_COMMAND.Domain.Entities.User", "Mentor") + .WithMany() + .HasForeignKey("MentorId"); + + b.Navigation("Mentor"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Subject", b => + { + b.HasOne("MBS_COMMAND.Domain.Entities.Semester", "Semester") + .WithMany() + .HasForeignKey("SemesterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Semester"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Transaction", b => + { + b.HasOne("MBS_COMMAND.Domain.Entities.Slot", "Slot") + .WithMany() + .HasForeignKey("SlotId"); + + b.HasOne("MBS_COMMAND.Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Slot"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.User", b => + { + b.HasOne("MBS_COMMAND.Domain.Entities.User", "Mentor") + .WithMany() + .HasForeignKey("MentorId"); + + b.Navigation("Mentor"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Category", b => + { + b.Navigation("SkillList"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Group", b => + { + b.Navigation("Members"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.MentorSkills", b => + { + b.Navigation("CertificateList"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.Skill", b => + { + b.Navigation("MentorSkillsList"); + }); + + modelBuilder.Entity("MBS_COMMAND.Domain.Entities.User", b => + { + b.Navigation("Groups"); + + b.Navigation("MentorSkillsList"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MBS_COMMAND.Persistence/Migrations/20241016074854_fix_semester.cs b/MBS_COMMAND.Persistence/Migrations/20241016074854_fix_semester.cs new file mode 100644 index 0000000..1f88c23 --- /dev/null +++ b/MBS_COMMAND.Persistence/Migrations/20241016074854_fix_semester.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MBS_COMMAND.Persistence.Migrations +{ + /// + public partial class fix_semester : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "IsActive", + table: "Semesters", + type: "bit", + nullable: false, + defaultValue: false); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "IsActive", + table: "Semesters"); + } + } +} diff --git a/MBS_COMMAND.Persistence/Migrations/ApplicationDbContextModelSnapshot.cs b/MBS_COMMAND.Persistence/Migrations/ApplicationDbContextModelSnapshot.cs index 53621b2..2201192 100644 --- a/MBS_COMMAND.Persistence/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/MBS_COMMAND.Persistence/Migrations/ApplicationDbContextModelSnapshot.cs @@ -17,7 +17,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "8.0.7") + .HasAnnotation("ProductVersion", "8.0.10") .HasAnnotation("Proxies:ChangeTracking", false) .HasAnnotation("Proxies:CheckEquality", false) .HasAnnotation("Proxies:LazyLoading", true) @@ -308,6 +308,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("From") .HasColumnType("date"); + b.Property("IsActive") + .HasColumnType("bit"); + b.Property("IsDeleted") .HasColumnType("bit"); diff --git a/MBS_COMMAND.Presentation/APIs/Groups/GroupApi.cs b/MBS_COMMAND.Presentation/APIs/Groups/GroupApi.cs index ebf4a92..856a9bb 100644 --- a/MBS_COMMAND.Presentation/APIs/Groups/GroupApi.cs +++ b/MBS_COMMAND.Presentation/APIs/Groups/GroupApi.cs @@ -14,8 +14,16 @@ public void AddRoutes(IEndpointRouteBuilder app) gr1.MapDelete("member", RemoveMemberFromGroup); gr1.MapPut("change-leader", ChangeLeader).WithSummary("must login in order to use this api"); gr1.MapPut(string.Empty, UpdateGroup); + gr1.MapGet("accept-invitation/{groupId}/{memberId}", AcceptGroupInvitation); } - public static async Task UpdateGroup(ISender sender, [FromBody] Command.UpdateGroup updateGroup) + + + private static async Task AcceptGroupInvitation(ISender sender, string groupId,string memberId) + { + var result = await sender.Send(new Command.AcceptGroupInvitation(Guid.Parse(groupId), Guid.Parse(memberId))); + return result.IsFailure ? HandlerFailure(result) : Results.Ok(result); + } + private static async Task UpdateGroup(ISender sender, [FromBody] Command.UpdateGroup updateGroup) { var result = await sender.Send(updateGroup); if (result.IsFailure) @@ -23,38 +31,29 @@ public static async Task UpdateGroup(ISender sender, [FromBody] Command return Results.Ok(result); } - public static async Task ChangeLeader(ISender sender, [FromBody] Command.ChangeLeader request) + + private static async Task ChangeLeader(ISender sender, [FromBody] Command.ChangeLeader request) { var result = await sender.Send(request); - if (result.IsFailure) - return HandlerFailure(result); - - return Results.Ok(result); + return result.IsFailure ? HandlerFailure(result) : Results.Ok(result); } - public static async Task CreateGroup(ISender sender, [FromBody] Command.CreateGroupCommand request) + private static async Task CreateGroup(ISender sender, [FromBody] Command.CreateGroupCommand request) { var result = await sender.Send(request); - if (result.IsFailure) - return HandlerFailure(result); - - return Results.Ok(result); + return result.IsFailure ? HandlerFailure(result) : Results.Ok(result); } - public static async Task AddMemberToGroup(ISender sender, [FromBody] Command.AddMemberToGroup request) + + private static async Task AddMemberToGroup(ISender sender, [FromBody] Command.AddMemberToGroup request) { var result = await sender.Send(request); - if (result.IsFailure) - return HandlerFailure(result); - - return Results.Ok(result); + return result.IsFailure ? HandlerFailure(result) : Results.Ok(result); } - public static async Task RemoveMemberFromGroup(ISender sender, [FromBody] Command.RemoveMemberFromGroup request) + + private static async Task RemoveMemberFromGroup(ISender sender, [FromBody] Command.RemoveMemberFromGroup request) { var result = await sender.Send(request); - if (result.IsFailure) - return HandlerFailure(result); - - return Results.Ok(result); + return result.IsFailure ? HandlerFailure(result) : Results.Ok(result); } }