From 25c7e8470d8b2d5e60c33daf0bd87e33d5ffbeeb Mon Sep 17 00:00:00 2001 From: Hootan Hemmati Date: Tue, 7 Nov 2023 00:01:46 +0330 Subject: [PATCH] Rename Education to Organization. ab#20103 --- .../Client/Shared/Components/BadgeTree.razor | 17 +- .../Components/OrganizationBadges.razor | 6 +- .../Components/OrganizationBadges.razor.cs | 15 +- .../Shared/Pages/EducationProgramPage.razor | 8 +- .../Pages/EducationProgramPage.razor.cs | 11 +- .../Shared/Pages/OrganizationPage.razor | 2 +- .../Shared/Pages/OrganizationPage.razor.cs | 17 +- .../Api/Controllers/BadgeSystemController.cs | 26 +- .../Api/Controllers/OrganizationController.cs | 45 ++ .../Server/Api/Data/AppDbContext.cs | 2 +- .../IServiceCollectionExtensions.cs | 2 +- .../EducationProgramMapperConfiguration.cs | 4 +- ..._RenameEducationToOrganization.Designer.cs | 424 ++++++++++++++++++ ...106195602_RenameEducationToOrganization.cs | 110 +++++ .../Migrations/AppDbContextModelSnapshot.cs | 19 +- .../Server/Api/Models/Badge.cs | 2 +- .../{EducationProgram.cs => Organization.cs} | 6 +- ...gramService.cs => IOrganizationService.cs} | 13 +- ...ogramService.cs => OrganizationService.cs} | 23 +- .../Shared/Shared/Dtos/AppJsonContext.cs | 4 +- .../OrganizationDto.cs} | 11 +- .../Shared/Shared/Dtos/OrganizationDto.cs | 15 - 22 files changed, 673 insertions(+), 109 deletions(-) create mode 100644 src/CrystallineSociety/Server/Api/Controllers/OrganizationController.cs create mode 100644 src/CrystallineSociety/Server/Api/Migrations/20231106195602_RenameEducationToOrganization.Designer.cs create mode 100644 src/CrystallineSociety/Server/Api/Migrations/20231106195602_RenameEducationToOrganization.cs rename src/CrystallineSociety/Server/Api/Models/{EducationProgram.cs => Organization.cs} (80%) rename src/CrystallineSociety/Server/Api/Services/Contracts/{IEducationProgramService.cs => IOrganizationService.cs} (77%) rename src/CrystallineSociety/Server/Api/Services/Implementations/{EducationProgramService.cs => OrganizationService.cs} (61%) rename src/CrystallineSociety/Shared/Shared/Dtos/{EducationProgram/EducationProgramDto.cs => Organization/OrganizationDto.cs} (59%) delete mode 100644 src/CrystallineSociety/Shared/Shared/Dtos/OrganizationDto.cs diff --git a/src/CrystallineSociety/Client/Shared/Components/BadgeTree.razor b/src/CrystallineSociety/Client/Shared/Components/BadgeTree.razor index 499e5fd..b648b73 100644 --- a/src/CrystallineSociety/Client/Shared/Components/BadgeTree.razor +++ b/src/CrystallineSociety/Client/Shared/Components/BadgeTree.razor @@ -3,14 +3,11 @@ @if (Badges != null) { - - -
-
Name: @badge.Code
-
-
-
+ } diff --git a/src/CrystallineSociety/Client/Shared/Components/OrganizationBadges.razor b/src/CrystallineSociety/Client/Shared/Components/OrganizationBadges.razor index 5d7cb0f..daf4454 100644 --- a/src/CrystallineSociety/Client/Shared/Components/OrganizationBadges.razor +++ b/src/CrystallineSociety/Client/Shared/Components/OrganizationBadges.razor @@ -3,14 +3,14 @@ -Current: @Organization.Title +@* Current: @Organization.Title *@
-









+
-









+
\ No newline at end of file diff --git a/src/CrystallineSociety/Client/Shared/Components/OrganizationBadges.razor.cs b/src/CrystallineSociety/Client/Shared/Components/OrganizationBadges.razor.cs index ef30f98..052049c 100644 --- a/src/CrystallineSociety/Client/Shared/Components/OrganizationBadges.razor.cs +++ b/src/CrystallineSociety/Client/Shared/Components/OrganizationBadges.razor.cs @@ -4,11 +4,24 @@ using System.Text; using System.Threading.Tasks; +using CrystallineSociety.Shared.Dtos.BadgeSystem; +using CrystallineSociety.Shared.Dtos.Organization; + namespace CrystallineSociety.Client.Shared.Components { public partial class OrganizationBadges { [Parameter] - public OrganizationDto Organization { get; set; } + public OrganizationDto Organization { get; set; } = default!; + + [Parameter] + public BadgeBundleDto? Bundle { get; set; } + + private BadgeDto? BadgeDto { get; set; } + + private void GetBadge(BadgeDto badgeDto) + { + BadgeDto = badgeDto; + } } } diff --git a/src/CrystallineSociety/Client/Shared/Pages/EducationProgramPage.razor b/src/CrystallineSociety/Client/Shared/Pages/EducationProgramPage.razor index 2f3ecc2..9081dd7 100644 --- a/src/CrystallineSociety/Client/Shared/Pages/EducationProgramPage.razor +++ b/src/CrystallineSociety/Client/Shared/Pages/EducationProgramPage.razor @@ -1,14 +1,14 @@ @page "/education-program" @using CrystallineSociety.Shared.Dtos.BadgeSystem -@using CrystallineSociety.Shared.Dtos.EducationProgram +@using CrystallineSociety.Shared.Dtos.Organization @inherits AppComponentBase - -
+

Education Program Name: @educationProgram.Title

Sync diff --git a/src/CrystallineSociety/Client/Shared/Pages/EducationProgramPage.razor.cs b/src/CrystallineSociety/Client/Shared/Pages/EducationProgramPage.razor.cs index 3071381..5fa31e3 100644 --- a/src/CrystallineSociety/Client/Shared/Pages/EducationProgramPage.razor.cs +++ b/src/CrystallineSociety/Client/Shared/Pages/EducationProgramPage.razor.cs @@ -3,27 +3,26 @@ using System.Linq; using System.Text; using System.Threading.Tasks; - -using CrystallineSociety.Shared.Dtos.EducationProgram; +using CrystallineSociety.Shared.Dtos.Organization; namespace CrystallineSociety.Client.Shared.Pages; public partial class EducationProgramPage { - private List EducationPrograms = new(); + private List Organizations = new(); private bool IsSyncing = false; protected override async Task OnInitAsync() { // Todo : complete this code to return dto not entity. - EducationPrograms = await HttpClient.GetFromJsonAsync>("BadgeSystem/GetEducationPrograms"); + Organizations = await HttpClient.GetFromJsonAsync>("Organization/GetOrganizations"); await base.OnInitAsync(); } - private async Task HandelSyncAsync(EducationProgramDto educationProgram) + private async Task HandelSyncAsync(OrganizationDto organization) { IsSyncing = true; - await HttpClient.PostAsJsonAsync("BadgeSystem/SyncEducationProgramBadges", educationProgram); + await HttpClient.PostAsJsonAsync("Organization/SyncOrganizationBadges", organization); IsSyncing = false; } } diff --git a/src/CrystallineSociety/Client/Shared/Pages/OrganizationPage.razor b/src/CrystallineSociety/Client/Shared/Pages/OrganizationPage.razor index 38c336f..48826c2 100644 --- a/src/CrystallineSociety/Client/Shared/Pages/OrganizationPage.razor +++ b/src/CrystallineSociety/Client/Shared/Pages/OrganizationPage.razor @@ -31,7 +31,7 @@ - +
// Show organization name diff --git a/src/CrystallineSociety/Client/Shared/Pages/OrganizationPage.razor.cs b/src/CrystallineSociety/Client/Shared/Pages/OrganizationPage.razor.cs index 2eabe36..1828f8c 100644 --- a/src/CrystallineSociety/Client/Shared/Pages/OrganizationPage.razor.cs +++ b/src/CrystallineSociety/Client/Shared/Pages/OrganizationPage.razor.cs @@ -4,24 +4,35 @@ using System.Text; using System.Threading.Tasks; +using CrystallineSociety.Shared.Dtos.BadgeSystem; +using CrystallineSociety.Shared.Dtos.Organization; + namespace CrystallineSociety.Client.Shared.Pages { public partial class OrganizationPage { [Parameter] - public string OrganizationCode { get; set; } + public string? OrganizationCode { get; set; } + + private OrganizationDto Organization { get; set; } = default!; - private OrganizationDto Organization { get; set; } + private BadgeBundleDto? Bundle { get; set; } protected override async Task OnInitAsync() { await LoadOrganizationAsync(); + await LoadBadgeSystem(); await base.OnInitAsync(); } private async Task LoadOrganizationAsync() { - Organization = new OrganizationDto(){Code = "CSI", Title = "CS Internship", Description = "Our first program"}; + Organization = await HttpClient.GetFromJsonAsync($"Organization/GetOrganizationByCode?code={OrganizationCode}", AppJsonContext.Default.OrganizationDto); + } + + private async Task LoadBadgeSystem() + { + Bundle = await HttpClient.GetFromJsonAsync($"BadgeSystem/GetBadgeBundleFromGitHub?url={Organization.BadgeSystemUrl}", AppJsonContext.Default.BadgeBundleDto); } } } diff --git a/src/CrystallineSociety/Server/Api/Controllers/BadgeSystemController.cs b/src/CrystallineSociety/Server/Api/Controllers/BadgeSystemController.cs index 1dd6512..7d306d9 100644 --- a/src/CrystallineSociety/Server/Api/Controllers/BadgeSystemController.cs +++ b/src/CrystallineSociety/Server/Api/Controllers/BadgeSystemController.cs @@ -1,7 +1,7 @@ using CrystallineSociety.Server.Api.Models; using CrystallineSociety.Server.Api.Models.TodoItem; using CrystallineSociety.Shared.Dtos.BadgeSystem; -using CrystallineSociety.Shared.Dtos.EducationProgram; +using CrystallineSociety.Shared.Dtos.Organization; using CrystallineSociety.Shared.Dtos.TodoItem; using CrystallineSociety.Shared.Services.Implementations.BadgeSystem; using Microsoft.VisualBasic; @@ -32,7 +32,7 @@ public partial class BadgeSystemController : AppControllerBase /// Education program service for syncing badge systems with education programs. /// [AutoInject] - public IEducationProgramService EducationProgramService { get; set; } + public IOrganizationService OrganizationService { get; set; } /// /// Live badge system for managing badges. @@ -100,26 +100,4 @@ public async Task> GetEarnedBadgesAsync(string username) { return await LiveBadgeSystemService.GetEarnedBadgesAsync(username); } - - /// - /// Syncs the badge system with an education program. - /// - /// The education program to sync. - /// Cancellation token. - [HttpPost] - public async Task SyncEducationProgramBadgesAsync(EducationProgramDto educationProgram, CancellationToken cancellationToken) - { - await EducationProgramService.SyncBadgeSystemAsync(educationProgram.Code, cancellationToken); - } - - /// - /// Retrieves all education programs. - /// - /// Cancellation token. - /// All education programs. - [HttpGet] - public async Task> GetEducationProgramsAsync(CancellationToken cancellationToken) - { - return Mapper.Map>(await EducationProgramService.GetAllEducationProgramsAsync(cancellationToken)); - } } diff --git a/src/CrystallineSociety/Server/Api/Controllers/OrganizationController.cs b/src/CrystallineSociety/Server/Api/Controllers/OrganizationController.cs new file mode 100644 index 0000000..f4fdd3a --- /dev/null +++ b/src/CrystallineSociety/Server/Api/Controllers/OrganizationController.cs @@ -0,0 +1,45 @@ +using CrystallineSociety.Server.Api.Services.Implementations; +using CrystallineSociety.Shared.Dtos.Organization; + +namespace CrystallineSociety.Server.Api.Controllers; + +[Route("api/[controller]/[action]")] +[ApiController] +[AllowAnonymous] +public partial class OrganizationController : AppControllerBase +{ + + /// + /// Education program service for syncing badge systems with education programs. + /// + [AutoInject] + public IOrganizationService OrganizationService { get; set; } + + /// + /// Syncs the badge system with an education program. + /// + /// The education program to sync. + /// Cancellation token. + [HttpPost] + public async Task SyncOrganizationBadgesAsync(OrganizationDto organization, CancellationToken cancellationToken) + { + await OrganizationService.SyncBadgeSystemAsync(organization.Code, cancellationToken); + } + + /// + /// Retrieves all education programs. + /// + /// Cancellation token. + /// All education programs. + [HttpGet] + public async Task> GetOrganizationsAsync(CancellationToken cancellationToken) + { + return Mapper.Map>(await OrganizationService.GetAllOrganizationAsync(cancellationToken)); + } + + [HttpGet] + public async Task GetOrganizationByCodeAsync(string code, CancellationToken cancellationToken) + { + return Mapper.Map(await OrganizationService.GetOrganizationAsync(code, cancellationToken)); + } +} diff --git a/src/CrystallineSociety/Server/Api/Data/AppDbContext.cs b/src/CrystallineSociety/Server/Api/Data/AppDbContext.cs index 4c0800e..b89a461 100644 --- a/src/CrystallineSociety/Server/Api/Data/AppDbContext.cs +++ b/src/CrystallineSociety/Server/Api/Data/AppDbContext.cs @@ -48,7 +48,7 @@ public override int SaveChanges(bool acceptAllChangesOnSuccess) public DbSet Badges { get; set; } - public DbSet EducationPrograms { get; set; } + public DbSet Organizations { get; set; } private void ConfigIdentityTables(ModelBuilder builder) { diff --git a/src/CrystallineSociety/Server/Api/Extensions/IServiceCollectionExtensions.cs b/src/CrystallineSociety/Server/Api/Extensions/IServiceCollectionExtensions.cs index 9cb8b79..ef44323 100644 --- a/src/CrystallineSociety/Server/Api/Extensions/IServiceCollectionExtensions.cs +++ b/src/CrystallineSociety/Server/Api/Extensions/IServiceCollectionExtensions.cs @@ -24,7 +24,7 @@ public static void AddServerServices(this IServiceCollection services) services.AddTransient(); // ToDo: Complete. services.AddTransient(CreateGitHubClient); - services.AddTransient(); + services.AddTransient(); } public static void AddIdentity(this IServiceCollection services, IConfiguration configuration) diff --git a/src/CrystallineSociety/Server/Api/Mappers/EducationProgramMapperConfiguration.cs b/src/CrystallineSociety/Server/Api/Mappers/EducationProgramMapperConfiguration.cs index b9d631c..d60d84e 100644 --- a/src/CrystallineSociety/Server/Api/Mappers/EducationProgramMapperConfiguration.cs +++ b/src/CrystallineSociety/Server/Api/Mappers/EducationProgramMapperConfiguration.cs @@ -1,6 +1,6 @@ using CrystallineSociety.Server.Api.Models; using CrystallineSociety.Server.Api.Models.TodoItem; -using CrystallineSociety.Shared.Dtos.EducationProgram; +using CrystallineSociety.Shared.Dtos.Organization; using CrystallineSociety.Shared.Dtos.TodoItem; namespace CrystallineSociety.Server.Api.Mappers; @@ -9,6 +9,6 @@ public class EducationProgramMapperConfiguration : Profile { public EducationProgramMapperConfiguration() { - CreateMap().ReverseMap(); + CreateMap().ReverseMap(); } } diff --git a/src/CrystallineSociety/Server/Api/Migrations/20231106195602_RenameEducationToOrganization.Designer.cs b/src/CrystallineSociety/Server/Api/Migrations/20231106195602_RenameEducationToOrganization.Designer.cs new file mode 100644 index 0000000..d0634c8 --- /dev/null +++ b/src/CrystallineSociety/Server/Api/Migrations/20231106195602_RenameEducationToOrganization.Designer.cs @@ -0,0 +1,424 @@ +// +using System; +using CrystallineSociety.Server.Api.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace CrystallineSociety.Server.Api.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20231106195602_RenameEducationToOrganization")] + partial class RenameEducationToOrganization + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.2") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("CrystallineSociety.Server.Api.Models.Account.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("CrystallineSociety.Server.Api.Models.Account.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("BirthDate") + .HasColumnType("datetimeoffset"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("ConfirmationEmailRequestedOn") + .HasColumnType("datetimeoffset"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("FullName") + .HasColumnType("nvarchar(max)"); + + b.Property("Gender") + .HasColumnType("int"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("ProfileImageName") + .HasColumnType("nvarchar(max)"); + + b.Property("ResetPasswordEmailRequestedOn") + .HasColumnType("datetimeoffset"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("CrystallineSociety.Server.Api.Models.Badge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("EducationProgramId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsApprovalRequired") + .HasColumnType("bit"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("OrganizationId") + .HasColumnType("uniqueidentifier"); + + b.Property("SpecJson") + .HasColumnType("nvarchar(max)"); + + b.Property("SpecJsonSourceUrl") + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Badges"); + }); + + modelBuilder.Entity("CrystallineSociety.Server.Api.Models.Organization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BadgeSystemUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Code") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LastCommitHash") + .HasColumnType("nvarchar(max)"); + + b.Property("LastSyncDateTime") + .HasColumnType("datetimeoffset"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Organizations"); + }); + + modelBuilder.Entity("CrystallineSociety.Server.Api.Models.TodoItem.TodoItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("IsDone") + .HasColumnType("bit"); + + b.Property("Title") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("TodoItems"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens", (string)null); + }); + + modelBuilder.Entity("CrystallineSociety.Server.Api.Models.Badge", b => + { + b.HasOne("CrystallineSociety.Server.Api.Models.Organization", null) + .WithMany("Badges") + .HasForeignKey("OrganizationId"); + }); + + modelBuilder.Entity("CrystallineSociety.Server.Api.Models.TodoItem.TodoItem", b => + { + b.HasOne("CrystallineSociety.Server.Api.Models.Account.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("CrystallineSociety.Server.Api.Models.Account.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("CrystallineSociety.Server.Api.Models.Account.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("CrystallineSociety.Server.Api.Models.Account.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("CrystallineSociety.Server.Api.Models.Account.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CrystallineSociety.Server.Api.Models.Account.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("CrystallineSociety.Server.Api.Models.Account.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("CrystallineSociety.Server.Api.Models.Organization", b => + { + b.Navigation("Badges"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/CrystallineSociety/Server/Api/Migrations/20231106195602_RenameEducationToOrganization.cs b/src/CrystallineSociety/Server/Api/Migrations/20231106195602_RenameEducationToOrganization.cs new file mode 100644 index 0000000..0ef6e1e --- /dev/null +++ b/src/CrystallineSociety/Server/Api/Migrations/20231106195602_RenameEducationToOrganization.cs @@ -0,0 +1,110 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace CrystallineSociety.Server.Api.Migrations +{ + /// + public partial class RenameEducationToOrganization : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Badges_EducationPrograms_EducationProgramId", + table: "Badges"); + + migrationBuilder.DropTable( + name: "EducationPrograms"); + + migrationBuilder.DropIndex( + name: "IX_Badges_EducationProgramId", + table: "Badges"); + + migrationBuilder.AddColumn( + name: "OrganizationId", + table: "Badges", + type: "uniqueidentifier", + nullable: true); + + migrationBuilder.CreateTable( + name: "Organizations", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Code = table.Column(type: "nvarchar(max)", nullable: false), + Title = table.Column(type: "nvarchar(max)", nullable: false), + BadgeSystemUrl = table.Column(type: "nvarchar(max)", nullable: false), + LastSyncDateTime = table.Column(type: "datetimeoffset", nullable: false), + LastCommitHash = table.Column(type: "nvarchar(max)", nullable: true), + IsActive = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Organizations", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_Badges_OrganizationId", + table: "Badges", + column: "OrganizationId"); + + migrationBuilder.AddForeignKey( + name: "FK_Badges_Organizations_OrganizationId", + table: "Badges", + column: "OrganizationId", + principalTable: "Organizations", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Badges_Organizations_OrganizationId", + table: "Badges"); + + migrationBuilder.DropTable( + name: "Organizations"); + + migrationBuilder.DropIndex( + name: "IX_Badges_OrganizationId", + table: "Badges"); + + migrationBuilder.DropColumn( + name: "OrganizationId", + table: "Badges"); + + migrationBuilder.CreateTable( + name: "EducationPrograms", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + BadgeSystemUrl = table.Column(type: "nvarchar(max)", nullable: false), + Code = table.Column(type: "nvarchar(max)", nullable: false), + IsActive = table.Column(type: "bit", nullable: false), + LastCommitHash = table.Column(type: "nvarchar(max)", nullable: true), + LastSyncDateTime = table.Column(type: "datetimeoffset", nullable: false), + Title = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EducationPrograms", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_Badges_EducationProgramId", + table: "Badges", + column: "EducationProgramId"); + + migrationBuilder.AddForeignKey( + name: "FK_Badges_EducationPrograms_EducationProgramId", + table: "Badges", + column: "EducationProgramId", + principalTable: "EducationPrograms", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/src/CrystallineSociety/Server/Api/Migrations/AppDbContextModelSnapshot.cs b/src/CrystallineSociety/Server/Api/Migrations/AppDbContextModelSnapshot.cs index 1651658..4ac7685 100644 --- a/src/CrystallineSociety/Server/Api/Migrations/AppDbContextModelSnapshot.cs +++ b/src/CrystallineSociety/Server/Api/Migrations/AppDbContextModelSnapshot.cs @@ -160,6 +160,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Level") .HasColumnType("int"); + b.Property("OrganizationId") + .HasColumnType("uniqueidentifier"); + b.Property("SpecJson") .HasColumnType("nvarchar(max)"); @@ -172,12 +175,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("EducationProgramId"); + b.HasIndex("OrganizationId"); b.ToTable("Badges"); }); - modelBuilder.Entity("CrystallineSociety.Server.Api.Models.EducationProgram", b => + modelBuilder.Entity("CrystallineSociety.Server.Api.Models.Organization", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -206,7 +209,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("EducationPrograms"); + b.ToTable("Organizations"); }); modelBuilder.Entity("CrystallineSociety.Server.Api.Models.TodoItem.TodoItem", b => @@ -341,13 +344,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("CrystallineSociety.Server.Api.Models.Badge", b => { - b.HasOne("CrystallineSociety.Server.Api.Models.EducationProgram", "EducationProgram") + b.HasOne("CrystallineSociety.Server.Api.Models.Organization", null) .WithMany("Badges") - .HasForeignKey("EducationProgramId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("EducationProgram"); + .HasForeignKey("OrganizationId"); }); modelBuilder.Entity("CrystallineSociety.Server.Api.Models.TodoItem.TodoItem", b => @@ -412,7 +411,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired(); }); - modelBuilder.Entity("CrystallineSociety.Server.Api.Models.EducationProgram", b => + modelBuilder.Entity("CrystallineSociety.Server.Api.Models.Organization", b => { b.Navigation("Badges"); }); diff --git a/src/CrystallineSociety/Server/Api/Models/Badge.cs b/src/CrystallineSociety/Server/Api/Models/Badge.cs index 3e2426f..9144435 100644 --- a/src/CrystallineSociety/Server/Api/Models/Badge.cs +++ b/src/CrystallineSociety/Server/Api/Models/Badge.cs @@ -23,7 +23,7 @@ public Badge(bool initialize) : base(initialize) [ForeignKey(nameof(EducationProgramId))] [NotMapped] - public virtual EducationProgram EducationProgram { get; set; } + public virtual Organization Organization { get; set; } public virtual required Guid EducationProgramId { get; set; } } diff --git a/src/CrystallineSociety/Server/Api/Models/EducationProgram.cs b/src/CrystallineSociety/Server/Api/Models/Organization.cs similarity index 80% rename from src/CrystallineSociety/Server/Api/Models/EducationProgram.cs rename to src/CrystallineSociety/Server/Api/Models/Organization.cs index 76fc7af..45a7cc6 100644 --- a/src/CrystallineSociety/Server/Api/Models/EducationProgram.cs +++ b/src/CrystallineSociety/Server/Api/Models/Organization.cs @@ -3,13 +3,13 @@ namespace CrystallineSociety.Server.Api.Models; -public class EducationProgram : EntityBase +public class Organization : EntityBase { - public EducationProgram() + public Organization() { } - public EducationProgram(bool initialize) : base(initialize) + public Organization(bool initialize) : base(initialize) { } diff --git a/src/CrystallineSociety/Server/Api/Services/Contracts/IEducationProgramService.cs b/src/CrystallineSociety/Server/Api/Services/Contracts/IOrganizationService.cs similarity index 77% rename from src/CrystallineSociety/Server/Api/Services/Contracts/IEducationProgramService.cs rename to src/CrystallineSociety/Server/Api/Services/Contracts/IOrganizationService.cs index f752dd6..0d711f1 100644 --- a/src/CrystallineSociety/Server/Api/Services/Contracts/IEducationProgramService.cs +++ b/src/CrystallineSociety/Server/Api/Services/Contracts/IOrganizationService.cs @@ -6,7 +6,7 @@ namespace CrystallineSociety.Server.Api.Services.Contracts; /// /// Interface for managing education programs. /// -public interface IEducationProgramService +public interface IOrganizationService { /// /// Sync current badge system associated with the given education program with source (GitHub) @@ -22,7 +22,7 @@ Task SyncBadgeSystemAsync(string educationProgramCode, /// /// The cancellation token. /// A task representing the asynchronous operation. - Task> GetAllEducationProgramsAsync(CancellationToken cancellationToken); + Task> GetAllOrganizationAsync(CancellationToken cancellationToken); /// /// Determines whether an education program exists with the specified code. @@ -30,15 +30,18 @@ Task SyncBadgeSystemAsync(string educationProgramCode, /// The code of the education program to check. /// The cancellation token. /// A task representing the asynchronous operation. - Task IsEducationExistAsync(string educationProgramCode, + Task IsOrganizationExistAsync(string educationProgramCode, CancellationToken cancellationToken); /// /// Adds an education program. /// - /// The education program to add. + /// The education program to add. /// The cancellation token. /// A task representing the asynchronous operation. - Task AddEducationAsync(EducationProgram educationProgram, + Task AddOrganizationAsync(Organization organization, + CancellationToken cancellationToken); + + Task GetOrganizationAsync(string organizationCode, CancellationToken cancellationToken); } diff --git a/src/CrystallineSociety/Server/Api/Services/Implementations/EducationProgramService.cs b/src/CrystallineSociety/Server/Api/Services/Implementations/OrganizationService.cs similarity index 61% rename from src/CrystallineSociety/Server/Api/Services/Implementations/EducationProgramService.cs rename to src/CrystallineSociety/Server/Api/Services/Implementations/OrganizationService.cs index 510dc01..b895aea 100644 --- a/src/CrystallineSociety/Server/Api/Services/Implementations/EducationProgramService.cs +++ b/src/CrystallineSociety/Server/Api/Services/Implementations/OrganizationService.cs @@ -3,7 +3,7 @@ namespace CrystallineSociety.Server.Api.Services.Implementations; -public partial class EducationProgramService : IEducationProgramService +public partial class OrganizationService : IOrganizationService { [AutoInject] protected AppDbContext AppDbContext = default; @@ -15,14 +15,14 @@ public partial class EducationProgramService : IEducationProgramService public async Task SyncBadgeSystemAsync(string educationProgramCode, CancellationToken cancellationToken) { - var educationProgram = await AppDbContext.EducationPrograms.FirstOrDefaultAsync(ep => ep.Code == educationProgramCode, cancellationToken); + var educationProgram = await AppDbContext.Organizations.FirstOrDefaultAsync(ep => ep.Code == educationProgramCode, cancellationToken); if (educationProgram == null) { throw new Exception($"Education program with code {educationProgramCode} not found!"); } - var oldBadges = AppDbContext.Badges.Where(b => b.EducationProgram.Code == educationProgramCode); + var oldBadges = AppDbContext.Badges.Where(b => b.Organization.Code == educationProgramCode); await AppDbContext.Badges.ExecuteDeleteAsync(cancellationToken); await AppDbContext.SaveChangesAsync(cancellationToken); @@ -48,19 +48,24 @@ public async Task SyncBadgeSystemAsync(string educationProgramCode, Cancellation await AppDbContext.SaveChangesAsync(cancellationToken); } - public async Task> GetAllEducationProgramsAsync(CancellationToken cancellationToken) + public async Task> GetAllOrganizationAsync(CancellationToken cancellationToken) { - return await AppDbContext.EducationPrograms.ToListAsync(cancellationToken); + return await AppDbContext.Organizations.ToListAsync(cancellationToken); } - public async Task IsEducationExistAsync(string educationProgramCode, CancellationToken cancellationToken) + public async Task IsOrganizationExistAsync(string educationProgramCode, CancellationToken cancellationToken) { - return await AppDbContext.EducationPrograms.AnyAsync(ep => ep.Code == educationProgramCode, cancellationToken); + return await AppDbContext.Organizations.AnyAsync(ep => ep.Code == educationProgramCode, cancellationToken); } - public async Task AddEducationAsync(EducationProgram educationProgram, CancellationToken cancellationToken) + public async Task AddOrganizationAsync(Organization organization, CancellationToken cancellationToken) { - await AppDbContext.EducationPrograms.AddAsync(educationProgram, cancellationToken); + await AppDbContext.Organizations.AddAsync(organization, cancellationToken); await AppDbContext.SaveChangesAsync(cancellationToken); } + + public async Task GetOrganizationAsync(string organizationCode,CancellationToken cancellationToken) + { + return await AppDbContext.Organizations.FirstAsync(o=>o.Code == organizationCode, cancellationToken); + } } diff --git a/src/CrystallineSociety/Shared/Shared/Dtos/AppJsonContext.cs b/src/CrystallineSociety/Shared/Shared/Dtos/AppJsonContext.cs index 486a834..86133b2 100644 --- a/src/CrystallineSociety/Shared/Shared/Dtos/AppJsonContext.cs +++ b/src/CrystallineSociety/Shared/Shared/Dtos/AppJsonContext.cs @@ -1,6 +1,6 @@ using CrystallineSociety.Shared.Dtos.Account; using CrystallineSociety.Shared.Dtos.BadgeSystem; -using CrystallineSociety.Shared.Dtos.EducationProgram; +using CrystallineSociety.Shared.Dtos.Organization; using CrystallineSociety.Shared.Dtos.TodoItem; namespace CrystallineSociety.Shared.Dtos; @@ -23,7 +23,7 @@ namespace CrystallineSociety.Shared.Dtos; [JsonSerializable(typeof(SendResetPasswordEmailRequestDto))] [JsonSerializable(typeof(ResetPasswordRequestDto))] [JsonSerializable(typeof(BadgeBundleDto))] -[JsonSerializable(typeof(EducationProgramDto))] +[JsonSerializable(typeof(OrganizationDto))] public partial class AppJsonContext : JsonSerializerContext { } diff --git a/src/CrystallineSociety/Shared/Shared/Dtos/EducationProgram/EducationProgramDto.cs b/src/CrystallineSociety/Shared/Shared/Dtos/Organization/OrganizationDto.cs similarity index 59% rename from src/CrystallineSociety/Shared/Shared/Dtos/EducationProgram/EducationProgramDto.cs rename to src/CrystallineSociety/Shared/Shared/Dtos/Organization/OrganizationDto.cs index 60e1dca..d36bce9 100644 --- a/src/CrystallineSociety/Shared/Shared/Dtos/EducationProgram/EducationProgramDto.cs +++ b/src/CrystallineSociety/Shared/Shared/Dtos/Organization/OrganizationDto.cs @@ -1,16 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace CrystallineSociety.Shared.Dtos.EducationProgram; -public class EducationProgramDto +namespace CrystallineSociety.Shared.Dtos.Organization; +public class OrganizationDto { public string Code { get; set; } = default!; public string Title { get; set; } = default!; public string BadgeSystemUrl { get; set; } = default!; public DateTimeOffset LastSyncDateTime { get; set; } public string? LastCommitHash { get; set; } + public string? Description { get; set; } public bool IsActive { get; set; } } diff --git a/src/CrystallineSociety/Shared/Shared/Dtos/OrganizationDto.cs b/src/CrystallineSociety/Shared/Shared/Dtos/OrganizationDto.cs deleted file mode 100644 index e62188b..0000000 --- a/src/CrystallineSociety/Shared/Shared/Dtos/OrganizationDto.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace CrystallineSociety.Shared.Dtos -{ - public class OrganizationDto - { - public string Title { get; set; } - public string Description { get; set; } - public string Code { get; set; } - } -}