From e526d25116a078704ed8626efffa7dae0af01a72 Mon Sep 17 00:00:00 2001 From: Veljko Tosic Date: Mon, 9 Feb 2026 00:18:02 +0100 Subject: [PATCH] Added EF entity, Migrations, Whiteboard repository service --- .../DI/PersistenceRegistrationExtensions.cs | 3 + .../Persistence/Db/AipsDbContext.cs | 3 +- ...208220239_AddedBasicWhiteboard.Designer.cs | 75 +++++++++++++++++++ .../20260208220239_AddedBasicWhiteboard.cs | 36 +++++++++ .../Migrations/AipsDbContextModelSnapshot.cs | 24 ++++++ .../Persistence/Whiteboard/Whiteboard.cs | 22 ++++++ .../Whiteboard/WhiteboardRepository.cs | 61 +++++++++++++++ 7 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 dotnet/AipsCore/Infrastructure/Persistence/Db/Migrations/20260208220239_AddedBasicWhiteboard.Designer.cs create mode 100644 dotnet/AipsCore/Infrastructure/Persistence/Db/Migrations/20260208220239_AddedBasicWhiteboard.cs create mode 100644 dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/Whiteboard.cs create mode 100644 dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/WhiteboardRepository.cs diff --git a/dotnet/AipsCore/Infrastructure/DI/PersistenceRegistrationExtensions.cs b/dotnet/AipsCore/Infrastructure/DI/PersistenceRegistrationExtensions.cs index 908959f..80c2909 100644 --- a/dotnet/AipsCore/Infrastructure/DI/PersistenceRegistrationExtensions.cs +++ b/dotnet/AipsCore/Infrastructure/DI/PersistenceRegistrationExtensions.cs @@ -1,8 +1,10 @@ using AipsCore.Domain.Abstract; using AipsCore.Domain.Models.User.External; +using AipsCore.Domain.Models.Whiteboard.External; using AipsCore.Infrastructure.DI.Configuration; using AipsCore.Infrastructure.Persistence.Db; using AipsCore.Infrastructure.Persistence.User; +using AipsCore.Infrastructure.Persistence.Whiteboard; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -23,6 +25,7 @@ public static class PersistenceRegistrationExtensions services.AddTransient(); services.AddTransient(); + services.AddTransient(); return services; } diff --git a/dotnet/AipsCore/Infrastructure/Persistence/Db/AipsDbContext.cs b/dotnet/AipsCore/Infrastructure/Persistence/Db/AipsDbContext.cs index 0e95553..cf01403 100644 --- a/dotnet/AipsCore/Infrastructure/Persistence/Db/AipsDbContext.cs +++ b/dotnet/AipsCore/Infrastructure/Persistence/Db/AipsDbContext.cs @@ -5,8 +5,9 @@ namespace AipsCore.Infrastructure.Persistence.Db; public class AipsDbContext : DbContext { public DbSet Users { get; set; } + public DbSet Whiteboards { get; set; } - public AipsDbContext(DbContextOptions options) + public AipsDbContext(DbContextOptions options) : base(options) { diff --git a/dotnet/AipsCore/Infrastructure/Persistence/Db/Migrations/20260208220239_AddedBasicWhiteboard.Designer.cs b/dotnet/AipsCore/Infrastructure/Persistence/Db/Migrations/20260208220239_AddedBasicWhiteboard.Designer.cs new file mode 100644 index 0000000..38e15ab --- /dev/null +++ b/dotnet/AipsCore/Infrastructure/Persistence/Db/Migrations/20260208220239_AddedBasicWhiteboard.Designer.cs @@ -0,0 +1,75 @@ +// +using System; +using AipsCore.Infrastructure.Persistence.Db; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace AipsCore.Infrastructure.Persistence.Db.Migrations +{ + [DbContext(typeof(AipsDbContext))] + [Migration("20260208220239_AddedBasicWhiteboard")] + partial class AddedBasicWhiteboard + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.2") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AipsCore.Infrastructure.Persistence.User.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("AipsCore.Infrastructure.Persistence.Whiteboard.Whiteboard", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(8) + .HasColumnType("character varying(8)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("WhiteboardOwnerId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("Whiteboards"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/dotnet/AipsCore/Infrastructure/Persistence/Db/Migrations/20260208220239_AddedBasicWhiteboard.cs b/dotnet/AipsCore/Infrastructure/Persistence/Db/Migrations/20260208220239_AddedBasicWhiteboard.cs new file mode 100644 index 0000000..fa4d9db --- /dev/null +++ b/dotnet/AipsCore/Infrastructure/Persistence/Db/Migrations/20260208220239_AddedBasicWhiteboard.cs @@ -0,0 +1,36 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace AipsCore.Infrastructure.Persistence.Db.Migrations +{ + /// + public partial class AddedBasicWhiteboard : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Whiteboards", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + WhiteboardOwnerId = table.Column(type: "uuid", nullable: false), + Code = table.Column(type: "character varying(8)", maxLength: 8, nullable: false), + Title = table.Column(type: "character varying(32)", maxLength: 32, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Whiteboards", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Whiteboards"); + } + } +} diff --git a/dotnet/AipsCore/Infrastructure/Persistence/Db/Migrations/AipsDbContextModelSnapshot.cs b/dotnet/AipsCore/Infrastructure/Persistence/Db/Migrations/AipsDbContextModelSnapshot.cs index fa2c82a..f8c68d1 100644 --- a/dotnet/AipsCore/Infrastructure/Persistence/Db/Migrations/AipsDbContextModelSnapshot.cs +++ b/dotnet/AipsCore/Infrastructure/Persistence/Db/Migrations/AipsDbContextModelSnapshot.cs @@ -42,6 +42,30 @@ namespace AipsCore.Infrastructure.Persistence.Db.Migrations b.ToTable("Users"); }); + + modelBuilder.Entity("AipsCore.Infrastructure.Persistence.Whiteboard.Whiteboard", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(8) + .HasColumnType("character varying(8)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("WhiteboardOwnerId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("Whiteboards"); + }); #pragma warning restore 612, 618 } } diff --git a/dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/Whiteboard.cs b/dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/Whiteboard.cs new file mode 100644 index 0000000..df8a199 --- /dev/null +++ b/dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/Whiteboard.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations; + +namespace AipsCore.Infrastructure.Persistence.Whiteboard; + +public class Whiteboard +{ + [Key] + public Guid Id { get; set; } + + [Required] + public Guid WhiteboardOwnerId { get; set; } + + [Required] + [MaxLength(8)] + [MinLength(8)] + public string Code { get; set; } = null!; + + [Required] + [MaxLength(32)] + [MinLength(3)] + public string Title { get; set; } = null!; +} \ No newline at end of file diff --git a/dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/WhiteboardRepository.cs b/dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/WhiteboardRepository.cs new file mode 100644 index 0000000..0620cd7 --- /dev/null +++ b/dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/WhiteboardRepository.cs @@ -0,0 +1,61 @@ +using AipsCore.Domain.Models.Whiteboard.External; +using AipsCore.Domain.Models.Whiteboard.ValueObjects; +using AipsCore.Infrastructure.Persistence.Db; +using Microsoft.EntityFrameworkCore; + +namespace AipsCore.Infrastructure.Persistence.Whiteboard; + +public class WhiteboardRepository : IWhiteboardRepository +{ + private readonly AipsDbContext _context; + + public WhiteboardRepository(AipsDbContext context) + { + _context = context; + } + + public async Task Get(WhiteboardId whiteboardId, CancellationToken cancellationToken = default) + { + var whiteboardEntity = await _context.Whiteboards.FindAsync([new Guid(whiteboardId.IdValue), cancellationToken], cancellationToken: cancellationToken); + + if (whiteboardEntity is null) return null; + + return Domain.Models.Whiteboard.Whiteboard.Create( + whiteboardEntity.Id.ToString(), + whiteboardEntity.WhiteboardOwnerId.ToString(), + whiteboardEntity.Code, + whiteboardEntity.Title); + } + + public async Task Save(Domain.Models.Whiteboard.Whiteboard whiteboard, CancellationToken cancellationToken = default) + { + var whiteboardEntity = await _context.Whiteboards.FindAsync(new Guid(whiteboard.Id.IdValue)); + + if (whiteboardEntity is not null) + { + whiteboardEntity.WhiteboardOwnerId = new Guid(whiteboard.WhiteboardOwnerId.IdValue); + whiteboardEntity.Code = whiteboard.Code.CodeValue; + whiteboardEntity.Title = whiteboard.Title.TitleValue; + + _context.Whiteboards.Update(whiteboardEntity); + } + else + { + whiteboardEntity = new Whiteboard() + { + Id = new Guid(whiteboard.Id.IdValue), + WhiteboardOwnerId = new Guid(whiteboard.WhiteboardOwnerId.IdValue), + Code = whiteboard.Code.CodeValue, + Title = whiteboard.Title.TitleValue, + }; + + _context.Whiteboards.Add(whiteboardEntity); + } + } + + public async Task WhiteboardCodeExists(WhiteboardCode whiteboardCode) + { + var codeExists = await _context.Whiteboards.AnyAsync(w => w.Code == whiteboardCode.CodeValue); + return codeExists; + } +} \ No newline at end of file