diff --git a/WorkManagementTool/Data/ApplicationDbContext.cs b/WorkManagementTool/Data/ApplicationDbContext.cs index 05d6b89..18e41c8 100644 --- a/WorkManagementTool/Data/ApplicationDbContext.cs +++ b/WorkManagementTool/Data/ApplicationDbContext.cs @@ -8,5 +8,7 @@ namespace WorkManagementTool.Data { public DbSet Homeworks { get; set; } = null!; public DbSet SchoolSubjects { get; set; } = null!; + public DbSet Projects { get; set; } = null!; + public DbSet ProjectTasks { get; set; } = null!; } } diff --git a/WorkManagementTool/Data/Entities/Project.cs b/WorkManagementTool/Data/Entities/Project.cs new file mode 100644 index 0000000..0d66463 --- /dev/null +++ b/WorkManagementTool/Data/Entities/Project.cs @@ -0,0 +1,10 @@ +namespace WorkManagementTool.Data.Entities +{ + public class Project + { + public int Id { get; set; } + public string Name { get; set; } = null!; + public string? Description { get; set; } + public List Tasks { get; set; } = new(); + } +} diff --git a/WorkManagementTool/Data/Entities/ProjectTask.cs b/WorkManagementTool/Data/Entities/ProjectTask.cs new file mode 100644 index 0000000..f55766d --- /dev/null +++ b/WorkManagementTool/Data/Entities/ProjectTask.cs @@ -0,0 +1,13 @@ +namespace WorkManagementTool.Data.Entities +{ + public class ProjectTask + { + public int Id { get; set; } + public string Title { get; set; } = null!; + public string? Description { get; set; } + public DateTime DueDate { get; set; } + public bool IsCompleted { get; set; } + public List? NextTasks { get; set; } + public Project Project { get; set; } = null!; + } +} diff --git a/WorkManagementTool/Migrations/20251227164404_AddProjectAndProjectTask.Designer.cs b/WorkManagementTool/Migrations/20251227164404_AddProjectAndProjectTask.Designer.cs new file mode 100644 index 0000000..59f783b --- /dev/null +++ b/WorkManagementTool/Migrations/20251227164404_AddProjectAndProjectTask.Designer.cs @@ -0,0 +1,522 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using WorkManagementTool.Data; + +#nullable disable + +namespace WorkManagementTool.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20251227164404_AddProjectAndProjectTask")] + partial class AddProjectAndProjectTask + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "10.0.0"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserPasskey", b => + { + b.Property("CredentialId") + .HasMaxLength(1024) + .HasColumnType("BLOB"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("CredentialId"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserPasskeys", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("WorkManagementTool.Data.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("WorkManagementTool.Data.Entities.Homework", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("Deleted") + .HasColumnType("INTEGER"); + + b.Property("DeliveryMethod") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("DueDate") + .HasColumnType("TEXT"); + + b.Property("IsCompleted") + .HasColumnType("INTEGER"); + + b.Property("SchoolSubjectId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("SchoolSubjectId"); + + b.ToTable("Homeworks"); + }); + + modelBuilder.Entity("WorkManagementTool.Data.Entities.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Projects"); + }); + + modelBuilder.Entity("WorkManagementTool.Data.Entities.ProjectTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("DueDate") + .HasColumnType("TEXT"); + + b.Property("IsCompleted") + .HasColumnType("INTEGER"); + + b.Property("ProjectId") + .HasColumnType("INTEGER"); + + b.Property("ProjectTaskId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.HasIndex("ProjectTaskId"); + + b.ToTable("ProjectTasks"); + }); + + modelBuilder.Entity("WorkManagementTool.Data.Entities.SchoolSubject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("Deleted") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.ToTable("SchoolSubjects"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("WorkManagementTool.Data.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("WorkManagementTool.Data.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserPasskey", b => + { + b.HasOne("WorkManagementTool.Data.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("Microsoft.AspNetCore.Identity.IdentityPasskeyData", "Data", b1 => + { + b1.Property("IdentityUserPasskeyCredentialId"); + + b1.Property("AttestationObject") + .IsRequired(); + + b1.Property("ClientDataJson") + .IsRequired(); + + b1.Property("CreatedAt"); + + b1.Property("IsBackedUp"); + + b1.Property("IsBackupEligible"); + + b1.Property("IsUserVerified"); + + b1.Property("Name"); + + b1.Property("PublicKey") + .IsRequired(); + + b1.Property("SignCount"); + + b1.PrimitiveCollection("Transports"); + + b1.HasKey("IdentityUserPasskeyCredentialId"); + + b1.ToTable("AspNetUserPasskeys"); + + b1.ToJson("Data"); + + b1.WithOwner() + .HasForeignKey("IdentityUserPasskeyCredentialId"); + }); + + b.Navigation("Data") + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WorkManagementTool.Data.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("WorkManagementTool.Data.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("WorkManagementTool.Data.Entities.Homework", b => + { + b.HasOne("WorkManagementTool.Data.ApplicationUser", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("WorkManagementTool.Data.Entities.SchoolSubject", "SchoolSubject") + .WithMany("Homeworks") + .HasForeignKey("SchoolSubjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("SchoolSubject"); + }); + + modelBuilder.Entity("WorkManagementTool.Data.Entities.ProjectTask", b => + { + b.HasOne("WorkManagementTool.Data.Entities.Project", "Project") + .WithMany("Tasks") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WorkManagementTool.Data.Entities.ProjectTask", null) + .WithMany("NextTasks") + .HasForeignKey("ProjectTaskId"); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("WorkManagementTool.Data.Entities.SchoolSubject", b => + { + b.HasOne("WorkManagementTool.Data.ApplicationUser", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.Navigation("CreatedBy"); + }); + + modelBuilder.Entity("WorkManagementTool.Data.Entities.Project", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("WorkManagementTool.Data.Entities.ProjectTask", b => + { + b.Navigation("NextTasks"); + }); + + modelBuilder.Entity("WorkManagementTool.Data.Entities.SchoolSubject", b => + { + b.Navigation("Homeworks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/WorkManagementTool/Migrations/20251227164404_AddProjectAndProjectTask.cs b/WorkManagementTool/Migrations/20251227164404_AddProjectAndProjectTask.cs new file mode 100644 index 0000000..51245e8 --- /dev/null +++ b/WorkManagementTool/Migrations/20251227164404_AddProjectAndProjectTask.cs @@ -0,0 +1,78 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace WorkManagementTool.Migrations +{ + /// + public partial class AddProjectAndProjectTask : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Projects", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Name = table.Column(type: "TEXT", nullable: false), + Description = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Projects", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ProjectTasks", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Title = table.Column(type: "TEXT", nullable: false), + Description = table.Column(type: "TEXT", nullable: true), + DueDate = table.Column(type: "TEXT", nullable: false), + IsCompleted = table.Column(type: "INTEGER", nullable: false), + ProjectId = table.Column(type: "INTEGER", nullable: false), + ProjectTaskId = table.Column(type: "INTEGER", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectTasks", x => x.Id); + table.ForeignKey( + name: "FK_ProjectTasks_ProjectTasks_ProjectTaskId", + column: x => x.ProjectTaskId, + principalTable: "ProjectTasks", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_ProjectTasks_Projects_ProjectId", + column: x => x.ProjectId, + principalTable: "Projects", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ProjectTasks_ProjectId", + table: "ProjectTasks", + column: "ProjectId"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectTasks_ProjectTaskId", + table: "ProjectTasks", + column: "ProjectTaskId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ProjectTasks"); + + migrationBuilder.DropTable( + name: "Projects"); + } + } +} diff --git a/WorkManagementTool/Migrations/ApplicationDbContextModelSnapshot.cs b/WorkManagementTool/Migrations/ApplicationDbContextModelSnapshot.cs index 40945cb..4d4db29 100644 --- a/WorkManagementTool/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/WorkManagementTool/Migrations/ApplicationDbContextModelSnapshot.cs @@ -276,6 +276,58 @@ namespace WorkManagementTool.Migrations b.ToTable("Homeworks"); }); + modelBuilder.Entity("WorkManagementTool.Data.Entities.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Projects"); + }); + + modelBuilder.Entity("WorkManagementTool.Data.Entities.ProjectTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("DueDate") + .HasColumnType("TEXT"); + + b.Property("IsCompleted") + .HasColumnType("INTEGER"); + + b.Property("ProjectId") + .HasColumnType("INTEGER"); + + b.Property("ProjectTaskId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.HasIndex("ProjectTaskId"); + + b.ToTable("ProjectTasks"); + }); + modelBuilder.Entity("WorkManagementTool.Data.Entities.SchoolSubject", b => { b.Property("Id") @@ -297,7 +349,6 @@ namespace WorkManagementTool.Migrations b.Property("Name") .IsRequired() - .HasMaxLength(100) .HasColumnType("TEXT"); b.HasKey("Id"); @@ -414,7 +465,7 @@ namespace WorkManagementTool.Migrations .HasForeignKey("CreatedById"); b.HasOne("WorkManagementTool.Data.Entities.SchoolSubject", "SchoolSubject") - .WithMany() + .WithMany("Homeworks") .HasForeignKey("SchoolSubjectId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -424,6 +475,21 @@ namespace WorkManagementTool.Migrations b.Navigation("SchoolSubject"); }); + modelBuilder.Entity("WorkManagementTool.Data.Entities.ProjectTask", b => + { + b.HasOne("WorkManagementTool.Data.Entities.Project", "Project") + .WithMany("Tasks") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WorkManagementTool.Data.Entities.ProjectTask", null) + .WithMany("NextTasks") + .HasForeignKey("ProjectTaskId"); + + b.Navigation("Project"); + }); + modelBuilder.Entity("WorkManagementTool.Data.Entities.SchoolSubject", b => { b.HasOne("WorkManagementTool.Data.ApplicationUser", "CreatedBy") @@ -432,6 +498,21 @@ namespace WorkManagementTool.Migrations b.Navigation("CreatedBy"); }); + + modelBuilder.Entity("WorkManagementTool.Data.Entities.Project", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("WorkManagementTool.Data.Entities.ProjectTask", b => + { + b.Navigation("NextTasks"); + }); + + modelBuilder.Entity("WorkManagementTool.Data.Entities.SchoolSubject", b => + { + b.Navigation("Homeworks"); + }); #pragma warning restore 612, 618 } } diff --git a/WorkManagementTool/Services/ProjectService.cs b/WorkManagementTool/Services/ProjectService.cs new file mode 100644 index 0000000..2c9da0d --- /dev/null +++ b/WorkManagementTool/Services/ProjectService.cs @@ -0,0 +1,50 @@ +using Microsoft.EntityFrameworkCore; +using WorkManagementTool.Data; +using WorkManagementTool.Data.Entities; + +namespace WorkManagementTool.Services +{ + public class ProjectService + { + private readonly ApplicationDbContext _context; + + public ProjectService(ApplicationDbContext context) + { + _context = context; + } + + public async Task> GetAllProjectsAsync() + { + return await _context.Projects.ToListAsync(); + } + + public async Task GetProjectByIdAsync(int projectId) + { + return await _context.Projects + .Include(p => p.Tasks) + .FirstOrDefaultAsync(p => p.Id == projectId); + } + + public async Task AddProjectAsync(Project project) + { + _context.Projects.Add(project); + await _context.SaveChangesAsync(); + } + + public async Task UpdateProjectAsync(Project project) + { + _context.Projects.Update(project); + await _context.SaveChangesAsync(); + } + + public async Task DeleteProjectAsync(int projectId) + { + var project = await _context.Projects.FindAsync(projectId); + if (project != null) + { + _context.Projects.Remove(project); + await _context.SaveChangesAsync(); + } + } + } +} diff --git a/WorkManagementTool/Services/ProjectTaskService.cs b/WorkManagementTool/Services/ProjectTaskService.cs new file mode 100644 index 0000000..aa25233 --- /dev/null +++ b/WorkManagementTool/Services/ProjectTaskService.cs @@ -0,0 +1,55 @@ +using Microsoft.EntityFrameworkCore; +using WorkManagementTool.Data; +using WorkManagementTool.Data.Entities; + +namespace WorkManagementTool.Services +{ + public class ProjectTaskService + { + private readonly ApplicationDbContext _context; + + public ProjectTaskService(ApplicationDbContext context) + { + _context = context; + } + + public async Task> GetAllTasksAsync(int projectId) + { + return await _context.ProjectTasks + .Include(t => t.NextTasks) + .Include(t => t.Project) + .Where(w => w.Project.Id == projectId) + .ToListAsync(); + } + + public async Task GetTaskByIdAsync(int taskId) + { + return await _context.ProjectTasks + .Include(t => t.NextTasks) + .Include(t => t.Project) + .FirstOrDefaultAsync(t => t.Id == taskId); + } + + public async Task AddTaskAsync(ProjectTask task) + { + _context.ProjectTasks.Add(task); + await _context.SaveChangesAsync(); + } + + public async Task UpdateTaskAsync(ProjectTask task) + { + _context.ProjectTasks.Update(task); + await _context.SaveChangesAsync(); + } + + public async Task DeleteTaskAsync(int taskId) + { + var task = await _context.ProjectTasks.FindAsync(taskId); + if (task != null) + { + _context.ProjectTasks.Remove(task); + await _context.SaveChangesAsync(); + } + } + } +} diff --git a/WorkManagementTool/work_management.db b/WorkManagementTool/work_management.db index eb4ffef..5e349f1 100644 Binary files a/WorkManagementTool/work_management.db and b/WorkManagementTool/work_management.db differ diff --git a/WorkManagementTool/work_management.db-shm b/WorkManagementTool/work_management.db-shm deleted file mode 100644 index 8f88064..0000000 Binary files a/WorkManagementTool/work_management.db-shm and /dev/null differ diff --git a/WorkManagementTool/work_management.db-wal b/WorkManagementTool/work_management.db-wal deleted file mode 100644 index ebebe21..0000000 Binary files a/WorkManagementTool/work_management.db-wal and /dev/null differ