From 9b75ddca8a1bcfd9a68d297288e378e7bf311007 Mon Sep 17 00:00:00 2001 From: HosseinJavadi Date: Fri, 5 Sep 2025 20:16:58 +0430 Subject: [PATCH] media --- .../TypeIdValueBase.cs | 12 +- .../EF/Helpers/Extensions.cs | 3 +- .../CommandHandlers/LanguageCommandHandler.cs | 6 +- .../VizhTalk.Learning.Application.csproj | 1 + .../Entities/FileGroup.cs | 33 ++++ VizhTalk.Learning.Domain/Entities/Language.cs | 11 +- VizhTalk.Learning.Domain/Entities/Media.cs | 14 ++ .../TypeIds/FileGroupId.cs | 10 + .../TypeIds/LanguageId.cs | 4 +- VizhTalk.Learning.Domain/TypeIds/MediaId.cs | 10 + .../ValueObjects/EntityType.cs | 18 ++ .../ValueObjects/FileGroupKey.cs | 25 +++ .../ValueObjects/FileGroupTitle.cs | 14 ++ .../Configurations/FileGroupConfiguration.cs | 28 +++ .../EF/Configurations/MediaConfiguration.cs | 33 ++++ VizhTalk.Learning.Infrastructure/EF/Schema.cs | 2 +- .../LearningStartup.cs | 6 + .../20250902200044_Inital.Designer.cs | 54 ------ .../Migrations/20250902200044_Inital.cs | 41 ---- .../20250905153842_initial.Designer.cs | 183 ++++++++++++++++++ .../Migrations/20250905153842_initial.cs | 111 +++++++++++ .../LearningDbContextModelSnapshot.cs | 137 ++++++++++++- .../VizhTalk.Learning.Infrastructure.csproj | 3 +- .../VizhTalk.Learning.Presentation.csproj | 1 - VizhTalk.Services.Grpc.Learning/Id.cs | 5 + .../Proto/Languages/Commands.proto | 4 +- .../Properties/launchSettings.json | 6 +- Vizhtalk.CDN.Presentation/TypeIds/ClientId.cs | 2 +- .../TypeIds/MediaClientId.cs | 2 +- .../TypeIds/MediaGroupId.cs | 2 +- .../TypeIds/MediaGroupMediaId.cs | 2 +- Vizhtalk.CDN.Presentation/TypeIds/MediaId.cs | 2 +- 32 files changed, 660 insertions(+), 125 deletions(-) create mode 100644 VizhTalk.Learning.Domain/Entities/FileGroup.cs create mode 100644 VizhTalk.Learning.Domain/Entities/Media.cs create mode 100644 VizhTalk.Learning.Domain/TypeIds/FileGroupId.cs create mode 100644 VizhTalk.Learning.Domain/TypeIds/MediaId.cs create mode 100644 VizhTalk.Learning.Domain/ValueObjects/EntityType.cs create mode 100644 VizhTalk.Learning.Domain/ValueObjects/FileGroupKey.cs create mode 100644 VizhTalk.Learning.Domain/ValueObjects/FileGroupTitle.cs create mode 100644 VizhTalk.Learning.Infrastructure/EF/Configurations/FileGroupConfiguration.cs create mode 100644 VizhTalk.Learning.Infrastructure/EF/Configurations/MediaConfiguration.cs delete mode 100644 VizhTalk.Learning.Infrastructure/Migrations/20250902200044_Inital.Designer.cs delete mode 100644 VizhTalk.Learning.Infrastructure/Migrations/20250902200044_Inital.cs create mode 100644 VizhTalk.Learning.Infrastructure/Migrations/20250905153842_initial.Designer.cs create mode 100644 VizhTalk.Learning.Infrastructure/Migrations/20250905153842_initial.cs diff --git a/VizhTalk.BuildingBlocks.Domain/TypeIdValueBase.cs b/VizhTalk.BuildingBlocks.Domain/TypeIdValueBase.cs index e1cd925..8368ab9 100644 --- a/VizhTalk.BuildingBlocks.Domain/TypeIdValueBase.cs +++ b/VizhTalk.BuildingBlocks.Domain/TypeIdValueBase.cs @@ -2,11 +2,11 @@ namespace VizhTalk.BuildingBlocks.Domain; -public abstract class TypedIdValueBase : IEquatable>, ITypeIdValueBase +public abstract class TypeIdValueBase : IEquatable>, ITypeIdValueBase { public T Value { get; } - protected TypedIdValueBase(T value) + protected TypeIdValueBase(T value) { if (EqualityComparer.Default.Equals(value, default(T))) @@ -22,7 +22,7 @@ public abstract class TypedIdValueBase : IEquatable>, ITy if (ReferenceEquals(null, obj)) return false; - return obj is TypedIdValueBase other && Equals(other); + return obj is TypeIdValueBase other && Equals(other); } public override int GetHashCode() @@ -30,7 +30,7 @@ public abstract class TypedIdValueBase : IEquatable>, ITy return Value!.GetHashCode(); } - public bool Equals(TypedIdValueBase? other) + public bool Equals(TypeIdValueBase? other) { if (other == null) return false; @@ -39,7 +39,7 @@ public abstract class TypedIdValueBase : IEquatable>, ITy } - public static bool operator ==(TypedIdValueBase? obj1, TypedIdValueBase? obj2) + public static bool operator ==(TypeIdValueBase? obj1, TypeIdValueBase? obj2) { if (object.Equals(obj1, null)) { @@ -54,7 +54,7 @@ public abstract class TypedIdValueBase : IEquatable>, ITy return obj1.Equals(obj2); } - public static bool operator !=(TypedIdValueBase? x, TypedIdValueBase? y) + public static bool operator !=(TypeIdValueBase? x, TypeIdValueBase? y) { return !(x == y); } diff --git a/VizhTalk.BuildingBlocks.Infrastructure/EF/Helpers/Extensions.cs b/VizhTalk.BuildingBlocks.Infrastructure/EF/Helpers/Extensions.cs index 0455ab2..0705954 100644 --- a/VizhTalk.BuildingBlocks.Infrastructure/EF/Helpers/Extensions.cs +++ b/VizhTalk.BuildingBlocks.Infrastructure/EF/Helpers/Extensions.cs @@ -26,7 +26,8 @@ namespace VizhTalk.BuildingBlocks.Infrastructure.EF.Helpers } public static ModelBuilder PluralizeEntities(this ModelBuilder modelBuilder) { - foreach (var entityType in modelBuilder.Model.GetEntityTypes()) + var entities = modelBuilder.Model.GetEntityTypes().Where(x => !x.IsKeyless && !x.IsOwned()); + foreach (var entityType in entities) { entityType.SetTableName(entityType.DisplayName().Pluralize()); } diff --git a/VizhTalk.Learning.Application/CommandHandlers/LanguageCommandHandler.cs b/VizhTalk.Learning.Application/CommandHandlers/LanguageCommandHandler.cs index 7bd78ed..bff4cd2 100644 --- a/VizhTalk.Learning.Application/CommandHandlers/LanguageCommandHandler.cs +++ b/VizhTalk.Learning.Application/CommandHandlers/LanguageCommandHandler.cs @@ -2,6 +2,7 @@ using VizhTalk.BuildingBlocks.Application.Configuration.Commnad; using VizhTalk.BuildingBlocks.Application.Exceptions; using VizhTalk.BuildingBlocks.Domain.Contract; +using VizhTalk.Grpc.CDN; using VizhTalk.Grpc.Learning; using VizhTalk.Grpc.Learning.Language; using VizhTalk.Learning.Application.Exceptions; @@ -11,15 +12,16 @@ using VizhTalk.Learning.Domain.ValueObjects; namespace VizhTalk.Learning.Application.CommandHandlers; -public class CreateLanguageCommandHandler(IUnitOfWork unitOfWork) : ICommandHandler +public class CreateLanguageCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNGrpcClient cdnClient) : ICommandHandler { public async Task Handle(CreateLanguageCommand request, CancellationToken cancellationToken) { var title = request.Title.Trim(); if (await unitOfWork.Language.Exists(x => x.Title == title)) throw new LanguageTitleAlreadyExistsException(); + - var language = Language.CreateNew(new LanguageTitle(title)); + var language = Language.CreateNew(new LanguageTitle(title), null); await unitOfWork.Language.AddAsync(language, cancellationToken); await unitOfWork.SaveChangeAsync(cancellationToken); return language.Adapt(); diff --git a/VizhTalk.Learning.Application/VizhTalk.Learning.Application.csproj b/VizhTalk.Learning.Application/VizhTalk.Learning.Application.csproj index 2d76b47..caa7dff 100644 --- a/VizhTalk.Learning.Application/VizhTalk.Learning.Application.csproj +++ b/VizhTalk.Learning.Application/VizhTalk.Learning.Application.csproj @@ -8,6 +8,7 @@ + diff --git a/VizhTalk.Learning.Domain/Entities/FileGroup.cs b/VizhTalk.Learning.Domain/Entities/FileGroup.cs new file mode 100644 index 0000000..18e5272 --- /dev/null +++ b/VizhTalk.Learning.Domain/Entities/FileGroup.cs @@ -0,0 +1,33 @@ +using VizhTalk.BuildingBlocks.Domain; +using VizhTalk.Learning.Domain.TypeIds; +using VizhTalk.Learning.Domain.ValueObjects; + +namespace VizhTalk.Learning.Domain.Entities; + +public class FileGroup : Entity +{ + public FileGroup() + { + + } + private FileGroup(FileGroupKey key, + FileGroupTitle title, + bool isSecure, + long mediaGroupId) + { + Title = title; + MediaGroupId = mediaGroupId; + Key = key; + IsSecure = isSecure; + } + public FileGroupTitle Title { get; set; } + public FileGroupKey Key { get; private set; } + public long MediaGroupId { get; private set; } + public bool IsSecure { get; set; } + + public static FileGroup CreateNew(FileGroupKey key, + FileGroupTitle title, + bool isSecure, + long mediaGroupId) + => new(key,title, isSecure, mediaGroupId); +} diff --git a/VizhTalk.Learning.Domain/Entities/Language.cs b/VizhTalk.Learning.Domain/Entities/Language.cs index 613d0db..ec64425 100644 --- a/VizhTalk.Learning.Domain/Entities/Language.cs +++ b/VizhTalk.Learning.Domain/Entities/Language.cs @@ -10,15 +10,20 @@ public class Language : Entity, IAggregateRoot { // only EF } - private Language(LanguageTitle title) + private Language(LanguageTitle title, Media icon) { Title = title; + Icon = icon; + } public LanguageTitle Title { get; private set; } + public Media Icon { get; private set; } - public static Language CreateNew(LanguageTitle title) - => new(title); + public static Language CreateNew(LanguageTitle title,Media icon) + => new(title, icon); public void SetTitle(LanguageTitle title) => Title = title; + public void SetIcon(Media icon) + => Icon = icon; } diff --git a/VizhTalk.Learning.Domain/Entities/Media.cs b/VizhTalk.Learning.Domain/Entities/Media.cs new file mode 100644 index 0000000..9fb8277 --- /dev/null +++ b/VizhTalk.Learning.Domain/Entities/Media.cs @@ -0,0 +1,14 @@ +using VizhTalk.BuildingBlocks.Domain; +using VizhTalk.Learning.Domain.TypeIds; +using VizhTalk.Learning.Domain.ValueObjects; + +namespace VizhTalk.Learning.Domain.Entities; + +public class Media : Entity +{ + public string Name { get; private set; } + public string ContentType { get; private set; } + public int Size { get; private set; } + public EntityType EntityType { get; private set; } + +} diff --git a/VizhTalk.Learning.Domain/TypeIds/FileGroupId.cs b/VizhTalk.Learning.Domain/TypeIds/FileGroupId.cs new file mode 100644 index 0000000..58cacb0 --- /dev/null +++ b/VizhTalk.Learning.Domain/TypeIds/FileGroupId.cs @@ -0,0 +1,10 @@ +using VizhTalk.BuildingBlocks.Domain; + +namespace VizhTalk.Learning.Domain.TypeIds; + +public class FileGroupId : TypeIdValueBase +{ + public FileGroupId(long value) : base(value) + { + } +} diff --git a/VizhTalk.Learning.Domain/TypeIds/LanguageId.cs b/VizhTalk.Learning.Domain/TypeIds/LanguageId.cs index a8f4c31..124dd1e 100644 --- a/VizhTalk.Learning.Domain/TypeIds/LanguageId.cs +++ b/VizhTalk.Learning.Domain/TypeIds/LanguageId.cs @@ -7,9 +7,9 @@ using VizhTalk.BuildingBlocks.Domain; namespace VizhTalk.Learning.Domain.TypeIds { - public class LanguageId : TypedIdValueBase + public class LanguageId : TypeIdValueBase { - public LanguageId(int value) : base(value) + public LanguageId(short value) : base(value) { } } diff --git a/VizhTalk.Learning.Domain/TypeIds/MediaId.cs b/VizhTalk.Learning.Domain/TypeIds/MediaId.cs new file mode 100644 index 0000000..06abcaf --- /dev/null +++ b/VizhTalk.Learning.Domain/TypeIds/MediaId.cs @@ -0,0 +1,10 @@ +using VizhTalk.BuildingBlocks.Domain; + +namespace VizhTalk.Learning.Domain.TypeIds; + +public class MediaId : TypeIdValueBase +{ + public MediaId(Guid value) : base(value) + { + } +} diff --git a/VizhTalk.Learning.Domain/ValueObjects/EntityType.cs b/VizhTalk.Learning.Domain/ValueObjects/EntityType.cs new file mode 100644 index 0000000..bc825a5 --- /dev/null +++ b/VizhTalk.Learning.Domain/ValueObjects/EntityType.cs @@ -0,0 +1,18 @@ +using VizhTalk.BuildingBlocks.Domain; + +namespace VizhTalk.Learning.Domain.ValueObjects; + +public class EntityType : ValueObject +{ + public EntityType(string entityId, EntityTypeEnum type) + { + EntityId = entityId; + Type = type; + } + public string EntityId { get; private set; } + public EntityTypeEnum Type { get; private set; } +} +public enum EntityTypeEnum +{ + Language = 0 +} diff --git a/VizhTalk.Learning.Domain/ValueObjects/FileGroupKey.cs b/VizhTalk.Learning.Domain/ValueObjects/FileGroupKey.cs new file mode 100644 index 0000000..ad793ec --- /dev/null +++ b/VizhTalk.Learning.Domain/ValueObjects/FileGroupKey.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VizhTalk.BuildingBlocks.Domain; +using VizhTalk.BuildingBlocks.Domain.Guards; + +namespace VizhTalk.Learning.Domain.ValueObjects +{ + public class FileGroupKey : ValueObject + { + public static FileGroupKey LanguageIcon = new("Language"); + public FileGroupKey(string entityName, string? entityId = null) + { + Guard.NullOrEmpty(entityName, entityName); + Guard.MaxLength(entityName, entityName, 30); + if (entityId != null) + Value = $"VizhTalk.Learning.{entityName}.{entityId}"; + else + Value = $"VizhTalk.Learning.{entityName}"; + } + public string Value { get; private set; } + } +} diff --git a/VizhTalk.Learning.Domain/ValueObjects/FileGroupTitle.cs b/VizhTalk.Learning.Domain/ValueObjects/FileGroupTitle.cs new file mode 100644 index 0000000..8bcf126 --- /dev/null +++ b/VizhTalk.Learning.Domain/ValueObjects/FileGroupTitle.cs @@ -0,0 +1,14 @@ +using VizhTalk.BuildingBlocks.Domain.Guards; +using VizhTalk.BuildingBlocks.Domain; + +namespace VizhTalk.Learning.Domain.ValueObjects; + +public class FileGroupTitle : ValueObject +{ + public FileGroupTitle(string value) + { + Guard.NullOrEmpty(value, nameof(FileGroupTitle)); + Guard.MaxLength(value, nameof(FileGroupTitle), 50); + } + public string Value { get; set; } +} diff --git a/VizhTalk.Learning.Infrastructure/EF/Configurations/FileGroupConfiguration.cs b/VizhTalk.Learning.Infrastructure/EF/Configurations/FileGroupConfiguration.cs new file mode 100644 index 0000000..2bdfea2 --- /dev/null +++ b/VizhTalk.Learning.Infrastructure/EF/Configurations/FileGroupConfiguration.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using VizhTalk.Learning.Domain.Entities; +using VizhTalk.Learning.Domain.ValueObjects; + +namespace VizhTalk.Learning.Infrastructure.EF.Configurations; + +internal class FileGroupConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable(nameof(FileGroup), Schema.Attachment); + builder.HasKey(x => x.Id); + + builder.Property(x => x.Id) + .ValueGeneratedOnAdd() + .HasConversion(x => x.Value, x => new Domain.TypeIds.FileGroupId(x)); + builder.Property(x => x.Title) + .HasColumnName("Title") + .HasConversion(x => x.Value, x => new FileGroupTitle(x)); + + builder.Property(x => x.Key) + .HasColumnName("Key") + .HasMaxLength(150) + .HasConversion(x => x.Value, x => new FileGroupKey(x, null)); + + } +} diff --git a/VizhTalk.Learning.Infrastructure/EF/Configurations/MediaConfiguration.cs b/VizhTalk.Learning.Infrastructure/EF/Configurations/MediaConfiguration.cs new file mode 100644 index 0000000..e9e54e5 --- /dev/null +++ b/VizhTalk.Learning.Infrastructure/EF/Configurations/MediaConfiguration.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using VizhTalk.Learning.Domain.Entities; + +namespace VizhTalk.Learning.Infrastructure.EF.Configurations; + +internal class MediaConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable(nameof(Media), Schema.Learning); + builder.HasKey(x => x.Id); + + builder.Property(x => x.Id) + .HasConversion(x => x.Value, x => new Domain.TypeIds.MediaId(x)); + + builder.Property(x => x.Name) + .HasMaxLength(150); + + builder.OwnsOne(x => x.EntityType, op => + { + op.WithOwner(); + + op.Property(x => x.Type) + .HasColumnName("EntityType") + .HasMaxLength(200); + + op.Property(x => x.EntityId) + .HasColumnName("EntityId") + .HasMaxLength(50); + }); + } +} diff --git a/VizhTalk.Learning.Infrastructure/EF/Schema.cs b/VizhTalk.Learning.Infrastructure/EF/Schema.cs index 899e808..b13b565 100644 --- a/VizhTalk.Learning.Infrastructure/EF/Schema.cs +++ b/VizhTalk.Learning.Infrastructure/EF/Schema.cs @@ -9,6 +9,6 @@ namespace VizhTalk.Learning.Infrastructure.EF public class Schema { public const string Learning = "Learning"; - + public const string Attachment = "Attachment"; } } diff --git a/VizhTalk.Learning.Infrastructure/LearningStartup.cs b/VizhTalk.Learning.Infrastructure/LearningStartup.cs index 759224f..14ecd89 100644 --- a/VizhTalk.Learning.Infrastructure/LearningStartup.cs +++ b/VizhTalk.Learning.Infrastructure/LearningStartup.cs @@ -9,6 +9,7 @@ using VizhTalk.BuildingBlocks.Application.Events; using VizhTalk.BuildingBlocks.Application.Outbox; using VizhTalk.BuildingBlocks.Infrastructure; using VizhTalk.BuildingBlocks.Infrastructure.DomainEventsDispatching; +using VizhTalk.Grpc.CDN; using VizhTalk.Learning.Application; using VizhTalk.Learning.Application.Mappers; using VizhTalk.Learning.Infrastructure.Configuration; @@ -57,6 +58,11 @@ public static class LearningStartup MapperConfig.Process(); + services.AddGrpcClient(op => + { + op.Address = new Uri("https://localhost:5001"); + }); + services.AddScoped(sa => { var notifications = sa.GetServices(); diff --git a/VizhTalk.Learning.Infrastructure/Migrations/20250902200044_Inital.Designer.cs b/VizhTalk.Learning.Infrastructure/Migrations/20250902200044_Inital.Designer.cs deleted file mode 100644 index c5345e0..0000000 --- a/VizhTalk.Learning.Infrastructure/Migrations/20250902200044_Inital.Designer.cs +++ /dev/null @@ -1,54 +0,0 @@ -// -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using VizhTalk.Learning.Infrastructure.EF; - -#nullable disable - -namespace VizhTalk.Learning.Infrastructure.Migrations -{ - [DbContext(typeof(LearningDbContext))] - [Migration("20250902200044_Inital")] - partial class Inital - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasDefaultSchema("Learning") - .HasAnnotation("ProductVersion", "8.0.19") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("VizhTalk.Learning.Domain.Entities.Language", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("IsActive") - .HasColumnType("bit"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(60) - .HasColumnType("nvarchar(60)"); - - b.HasKey("Id"); - - b.ToTable("Languages", "Learning"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/VizhTalk.Learning.Infrastructure/Migrations/20250902200044_Inital.cs b/VizhTalk.Learning.Infrastructure/Migrations/20250902200044_Inital.cs deleted file mode 100644 index 8045348..0000000 --- a/VizhTalk.Learning.Infrastructure/Migrations/20250902200044_Inital.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace VizhTalk.Learning.Infrastructure.Migrations -{ - /// - public partial class Inital : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.EnsureSchema( - name: "Learning"); - - migrationBuilder.CreateTable( - name: "Languages", - schema: "Learning", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - Title = table.Column(type: "nvarchar(60)", maxLength: 60, nullable: false), - IsDeleted = table.Column(type: "bit", nullable: false), - IsActive = table.Column(type: "bit", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Languages", x => x.Id); - }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Languages", - schema: "Learning"); - } - } -} diff --git a/VizhTalk.Learning.Infrastructure/Migrations/20250905153842_initial.Designer.cs b/VizhTalk.Learning.Infrastructure/Migrations/20250905153842_initial.Designer.cs new file mode 100644 index 0000000..9ee075e --- /dev/null +++ b/VizhTalk.Learning.Infrastructure/Migrations/20250905153842_initial.Designer.cs @@ -0,0 +1,183 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using VizhTalk.Learning.Infrastructure.EF; + +#nullable disable + +namespace VizhTalk.Learning.Infrastructure.Migrations +{ + [DbContext(typeof(LearningDbContext))] + [Migration("20250905153842_initial")] + partial class initial + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("Learning") + .HasAnnotation("ProductVersion", "8.0.19") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("VizhTalk.Learning.Domain.Entities.FileGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreateOn") + .HasColumnType("datetime2"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsSecure") + .HasColumnType("bit"); + + b.Property("Key") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("nvarchar(150)") + .HasColumnName("Key"); + + b.Property("LastUpdate") + .HasColumnType("datetime2"); + + b.Property("MediaGroupId") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("Title"); + + b.HasKey("Id"); + + b.ToTable("FileGroups", "Attachment"); + }); + + modelBuilder.Entity("VizhTalk.Learning.Domain.Entities.Language", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreateOn") + .HasColumnType("datetime2"); + + b.Property("IconId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastUpdate") + .HasColumnType("datetime2"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("nvarchar(60)"); + + b.HasKey("Id"); + + b.HasIndex("IconId"); + + b.ToTable("Languages", "Learning"); + }); + + modelBuilder.Entity("VizhTalk.Learning.Domain.Entities.Media", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ContentType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreateOn") + .HasColumnType("datetime2"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastUpdate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("Size") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Medias", "Learning"); + }); + + modelBuilder.Entity("VizhTalk.Learning.Domain.Entities.Language", b => + { + b.HasOne("VizhTalk.Learning.Domain.Entities.Media", "Icon") + .WithMany() + .HasForeignKey("IconId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Icon"); + }); + + modelBuilder.Entity("VizhTalk.Learning.Domain.Entities.Media", b => + { + b.OwnsOne("VizhTalk.Learning.Domain.ValueObjects.EntityType", "EntityType", b1 => + { + b1.Property("MediaId") + .HasColumnType("uniqueidentifier"); + + b1.Property("EntityId") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)") + .HasColumnName("EntityId"); + + b1.Property("Type") + .HasMaxLength(200) + .HasColumnType("int") + .HasColumnName("EntityType"); + + b1.HasKey("MediaId"); + + b1.ToTable("Medias", "Learning"); + + b1.WithOwner() + .HasForeignKey("MediaId"); + }); + + b.Navigation("EntityType") + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/VizhTalk.Learning.Infrastructure/Migrations/20250905153842_initial.cs b/VizhTalk.Learning.Infrastructure/Migrations/20250905153842_initial.cs new file mode 100644 index 0000000..5187e50 --- /dev/null +++ b/VizhTalk.Learning.Infrastructure/Migrations/20250905153842_initial.cs @@ -0,0 +1,111 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace VizhTalk.Learning.Infrastructure.Migrations +{ + /// + public partial class initial : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.EnsureSchema( + name: "Attachment"); + + migrationBuilder.EnsureSchema( + name: "Learning"); + + migrationBuilder.CreateTable( + name: "FileGroups", + schema: "Attachment", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Title = table.Column(type: "nvarchar(max)", nullable: false), + Key = table.Column(type: "nvarchar(150)", maxLength: 150, nullable: false), + MediaGroupId = table.Column(type: "bigint", nullable: false), + IsSecure = table.Column(type: "bit", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false), + IsActive = table.Column(type: "bit", nullable: false), + CreateOn = table.Column(type: "datetime2", nullable: false), + LastUpdate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_FileGroups", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Medias", + schema: "Learning", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(150)", maxLength: 150, nullable: false), + ContentType = table.Column(type: "nvarchar(max)", nullable: false), + Size = table.Column(type: "int", nullable: false), + EntityId = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + EntityType = table.Column(type: "int", maxLength: 200, nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false), + IsActive = table.Column(type: "bit", nullable: false), + CreateOn = table.Column(type: "datetime2", nullable: false), + LastUpdate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Medias", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Languages", + schema: "Learning", + columns: table => new + { + Id = table.Column(type: "smallint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Title = table.Column(type: "nvarchar(60)", maxLength: 60, nullable: false), + IconId = table.Column(type: "uniqueidentifier", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false), + IsActive = table.Column(type: "bit", nullable: false), + CreateOn = table.Column(type: "datetime2", nullable: false), + LastUpdate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Languages", x => x.Id); + table.ForeignKey( + name: "FK_Languages_Medias_IconId", + column: x => x.IconId, + principalSchema: "Learning", + principalTable: "Medias", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Languages_IconId", + schema: "Learning", + table: "Languages", + column: "IconId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "FileGroups", + schema: "Attachment"); + + migrationBuilder.DropTable( + name: "Languages", + schema: "Learning"); + + migrationBuilder.DropTable( + name: "Medias", + schema: "Learning"); + } + } +} diff --git a/VizhTalk.Learning.Infrastructure/Migrations/LearningDbContextModelSnapshot.cs b/VizhTalk.Learning.Infrastructure/Migrations/LearningDbContextModelSnapshot.cs index 68bf99c..7d6f536 100644 --- a/VizhTalk.Learning.Infrastructure/Migrations/LearningDbContextModelSnapshot.cs +++ b/VizhTalk.Learning.Infrastructure/Migrations/LearningDbContextModelSnapshot.cs @@ -1,4 +1,5 @@ // +using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; @@ -22,13 +23,16 @@ namespace VizhTalk.Learning.Infrastructure.Migrations SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - modelBuilder.Entity("VizhTalk.Learning.Domain.Entities.Language", b => + modelBuilder.Entity("VizhTalk.Learning.Domain.Entities.FileGroup", b => { - b.Property("Id") + b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("bigint"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreateOn") + .HasColumnType("datetime2"); b.Property("IsActive") .HasColumnType("bit"); @@ -36,6 +40,54 @@ namespace VizhTalk.Learning.Infrastructure.Migrations b.Property("IsDeleted") .HasColumnType("bit"); + b.Property("IsSecure") + .HasColumnType("bit"); + + b.Property("Key") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("nvarchar(150)") + .HasColumnName("Key"); + + b.Property("LastUpdate") + .HasColumnType("datetime2"); + + b.Property("MediaGroupId") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("Title"); + + b.HasKey("Id"); + + b.ToTable("FileGroups", "Attachment"); + }); + + modelBuilder.Entity("VizhTalk.Learning.Domain.Entities.Language", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreateOn") + .HasColumnType("datetime2"); + + b.Property("IconId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastUpdate") + .HasColumnType("datetime2"); + b.Property("Title") .IsRequired() .HasMaxLength(60) @@ -43,8 +95,85 @@ namespace VizhTalk.Learning.Infrastructure.Migrations b.HasKey("Id"); + b.HasIndex("IconId"); + b.ToTable("Languages", "Learning"); }); + + modelBuilder.Entity("VizhTalk.Learning.Domain.Entities.Media", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ContentType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreateOn") + .HasColumnType("datetime2"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastUpdate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("Size") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Medias", "Learning"); + }); + + modelBuilder.Entity("VizhTalk.Learning.Domain.Entities.Language", b => + { + b.HasOne("VizhTalk.Learning.Domain.Entities.Media", "Icon") + .WithMany() + .HasForeignKey("IconId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Icon"); + }); + + modelBuilder.Entity("VizhTalk.Learning.Domain.Entities.Media", b => + { + b.OwnsOne("VizhTalk.Learning.Domain.ValueObjects.EntityType", "EntityType", b1 => + { + b1.Property("MediaId") + .HasColumnType("uniqueidentifier"); + + b1.Property("EntityId") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)") + .HasColumnName("EntityId"); + + b1.Property("Type") + .HasMaxLength(200) + .HasColumnType("int") + .HasColumnName("EntityType"); + + b1.HasKey("MediaId"); + + b1.ToTable("Medias", "Learning"); + + b1.WithOwner() + .HasForeignKey("MediaId"); + }); + + b.Navigation("EntityType") + .IsRequired(); + }); #pragma warning restore 612, 618 } } diff --git a/VizhTalk.Learning.Infrastructure/VizhTalk.Learning.Infrastructure.csproj b/VizhTalk.Learning.Infrastructure/VizhTalk.Learning.Infrastructure.csproj index edb8a5e..2e68ccc 100644 --- a/VizhTalk.Learning.Infrastructure/VizhTalk.Learning.Infrastructure.csproj +++ b/VizhTalk.Learning.Infrastructure/VizhTalk.Learning.Infrastructure.csproj @@ -7,7 +7,8 @@ - + + all diff --git a/VizhTalk.Learning.Presentation/VizhTalk.Learning.Presentation.csproj b/VizhTalk.Learning.Presentation/VizhTalk.Learning.Presentation.csproj index 8f7a649..a261ecc 100644 --- a/VizhTalk.Learning.Presentation/VizhTalk.Learning.Presentation.csproj +++ b/VizhTalk.Learning.Presentation/VizhTalk.Learning.Presentation.csproj @@ -7,7 +7,6 @@ - all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/VizhTalk.Services.Grpc.Learning/Id.cs b/VizhTalk.Services.Grpc.Learning/Id.cs index 05152ca..d77574f 100644 --- a/VizhTalk.Services.Grpc.Learning/Id.cs +++ b/VizhTalk.Services.Grpc.Learning/Id.cs @@ -22,10 +22,15 @@ public sealed partial class Id public static implicit operator long(Id id) => long.Parse(EncryptionIdHelper.Decrypt(id.Value)); + public static implicit operator short(Id id) + => short.Parse(EncryptionIdHelper.Decrypt(id.Value)); public static implicit operator Id(int id) => (Id)id.ToString(); + public static implicit operator Id(short id) + => (Id)id.ToString(); + public static implicit operator Id(long id) => (Id)id.ToString(); diff --git a/VizhTalk.Services.Grpc.Learning/Proto/Languages/Commands.proto b/VizhTalk.Services.Grpc.Learning/Proto/Languages/Commands.proto index aad1b83..8ed7bde 100644 --- a/VizhTalk.Services.Grpc.Learning/Proto/Languages/Commands.proto +++ b/VizhTalk.Services.Grpc.Learning/Proto/Languages/Commands.proto @@ -7,10 +7,12 @@ import "Proto/Shared.proto"; message CreateLanguageCommand{ - string title = 2; + string title = 1; + bytes icon = 2; } message UpdateLanguageCommand{ Id Id = 1; string title = 2; + bytes icon = 3; } \ No newline at end of file diff --git a/Vizhtalk.CDN.Presentation/Properties/launchSettings.json b/Vizhtalk.CDN.Presentation/Properties/launchSettings.json index f47485d..648cf03 100644 --- a/Vizhtalk.CDN.Presentation/Properties/launchSettings.json +++ b/Vizhtalk.CDN.Presentation/Properties/launchSettings.json @@ -4,7 +4,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:11814", + "applicationUrl": "http://localhost:5001", "sslPort": 44357 } }, @@ -13,7 +13,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "http://localhost:5041", + "applicationUrl": "http://localhost:5001", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } @@ -22,7 +22,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "https://localhost:7109;http://localhost:5041", + "applicationUrl": "https://localhost:5001", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/Vizhtalk.CDN.Presentation/TypeIds/ClientId.cs b/Vizhtalk.CDN.Presentation/TypeIds/ClientId.cs index 332c195..b847ed7 100644 --- a/Vizhtalk.CDN.Presentation/TypeIds/ClientId.cs +++ b/Vizhtalk.CDN.Presentation/TypeIds/ClientId.cs @@ -2,7 +2,7 @@ namespace Vizhtalk.CDN.Presentation.TypeIds { - public class ClientId : TypedIdValueBase + public class ClientId : TypeIdValueBase { public ClientId(string value) : base(value) { diff --git a/Vizhtalk.CDN.Presentation/TypeIds/MediaClientId.cs b/Vizhtalk.CDN.Presentation/TypeIds/MediaClientId.cs index 84f1fce..1062439 100644 --- a/Vizhtalk.CDN.Presentation/TypeIds/MediaClientId.cs +++ b/Vizhtalk.CDN.Presentation/TypeIds/MediaClientId.cs @@ -2,7 +2,7 @@ namespace Vizhtalk.CDN.Presentation.TypeIds { - public class MediaClientId : TypedIdValueBase + public class MediaClientId : TypeIdValueBase { public MediaClientId(long value) : base(value) { diff --git a/Vizhtalk.CDN.Presentation/TypeIds/MediaGroupId.cs b/Vizhtalk.CDN.Presentation/TypeIds/MediaGroupId.cs index a64914e..dbc118c 100644 --- a/Vizhtalk.CDN.Presentation/TypeIds/MediaGroupId.cs +++ b/Vizhtalk.CDN.Presentation/TypeIds/MediaGroupId.cs @@ -2,7 +2,7 @@ namespace Vizhtalk.CDN.Presentation.TypeIds { - public class MediaGroupId : TypedIdValueBase + public class MediaGroupId : TypeIdValueBase { public MediaGroupId(long value) : base(value) { diff --git a/Vizhtalk.CDN.Presentation/TypeIds/MediaGroupMediaId.cs b/Vizhtalk.CDN.Presentation/TypeIds/MediaGroupMediaId.cs index 5ed43ec..4471b04 100644 --- a/Vizhtalk.CDN.Presentation/TypeIds/MediaGroupMediaId.cs +++ b/Vizhtalk.CDN.Presentation/TypeIds/MediaGroupMediaId.cs @@ -2,7 +2,7 @@ namespace Vizhtalk.CDN.Presentation.TypeIds { - public class MediaGroupMediaId : TypedIdValueBase + public class MediaGroupMediaId : TypeIdValueBase { public MediaGroupMediaId(Guid value) : base(value) { diff --git a/Vizhtalk.CDN.Presentation/TypeIds/MediaId.cs b/Vizhtalk.CDN.Presentation/TypeIds/MediaId.cs index 5e4e85a..0c095de 100644 --- a/Vizhtalk.CDN.Presentation/TypeIds/MediaId.cs +++ b/Vizhtalk.CDN.Presentation/TypeIds/MediaId.cs @@ -2,7 +2,7 @@ namespace Vizhtalk.CDN.Presentation.TypeIds { - public class MediaId : TypedIdValueBase + public class MediaId : TypeIdValueBase { public MediaId(long value) : base(value) {