From 8da17a1ace50aaf7fd15e9d5808a21d8419b5883 Mon Sep 17 00:00:00 2001
From: Berkan
Date: Wed, 3 Feb 2021 11:31:40 +0300
Subject: [PATCH 01/13] Send an email when the user registers for the event
---
.../EmailTemplateDefinitionProvider.cs | 19 +++
.../Emailing/EmailTemplates.cs | 7 +
.../Emailing/Templates/EventRegistration.tpl | 157 ++++++++++++++++++
.../EventHub.Application.csproj | 5 +
.../EventHubApplicationModule.cs | 6 +
.../EventRegistrationAppService.cs | 15 +-
.../EventRegistrationNotifier.cs | 47 ++++++
7 files changed, 251 insertions(+), 5 deletions(-)
create mode 100644 src/EventHub.Application/Emailing/EmailTemplateDefinitionProvider.cs
create mode 100644 src/EventHub.Application/Emailing/EmailTemplates.cs
create mode 100644 src/EventHub.Application/Emailing/Templates/EventRegistration.tpl
create mode 100644 src/EventHub.Application/Events/Registrations/EventRegistrationNotifier.cs
diff --git a/src/EventHub.Application/Emailing/EmailTemplateDefinitionProvider.cs b/src/EventHub.Application/Emailing/EmailTemplateDefinitionProvider.cs
new file mode 100644
index 0000000..4b43c8c
--- /dev/null
+++ b/src/EventHub.Application/Emailing/EmailTemplateDefinitionProvider.cs
@@ -0,0 +1,19 @@
+using Volo.Abp.TextTemplating;
+
+namespace EventHub.Emailing
+{
+ public class EmailTemplateDefinitionProvider : TemplateDefinitionProvider
+ {
+ public override void Define(ITemplateDefinitionContext context)
+ {
+ context.Add(
+ new TemplateDefinition(
+ EmailTemplates.EventRegistration
+ ).WithVirtualFilePath(
+ "/Emailing/Templates/EventRegistration.tpl",
+ isInlineLocalized: true
+ )
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/EventHub.Application/Emailing/EmailTemplates.cs b/src/EventHub.Application/Emailing/EmailTemplates.cs
new file mode 100644
index 0000000..f8b6161
--- /dev/null
+++ b/src/EventHub.Application/Emailing/EmailTemplates.cs
@@ -0,0 +1,7 @@
+namespace EventHub.Emailing
+{
+ public static class EmailTemplates
+ {
+ public const string EventRegistration = "EventHub.Event.Registration";
+ }
+}
\ No newline at end of file
diff --git a/src/EventHub.Application/Emailing/Templates/EventRegistration.tpl b/src/EventHub.Application/Emailing/Templates/EventRegistration.tpl
new file mode 100644
index 0000000..1667895
--- /dev/null
+++ b/src/EventHub.Application/Emailing/Templates/EventRegistration.tpl
@@ -0,0 +1,157 @@
+
+
+
+
+
+ Eventhub
+
+
+
+
+
+
+
+
+
+
+
+ EventHub
+
+
+
+
+
+ {{model.title}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+ Hi,
+
+
+ Great news! You attended the {{model.title}} event.
+
+
+
+
+
+ |
+
+ Start Time
+ {{model.start_time}}
+ |
+
+
+ End Time
+ {{model.end_time}}
+ |
+
+
+
+
+
+ Event Details
+
+
+
+
+ Thank you, EventHub
+
+ |
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+ |
+
+ |
+
+
+ |
+
+ |
+
+
+
+
+
+
+ |
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/EventHub.Application/EventHub.Application.csproj b/src/EventHub.Application/EventHub.Application.csproj
index f8a3bb0..7515db7 100644
--- a/src/EventHub.Application/EventHub.Application.csproj
+++ b/src/EventHub.Application/EventHub.Application.csproj
@@ -18,4 +18,9 @@
+
+
+
+
+
diff --git a/src/EventHub.Application/EventHubApplicationModule.cs b/src/EventHub.Application/EventHubApplicationModule.cs
index 088d304..61fa6f3 100644
--- a/src/EventHub.Application/EventHubApplicationModule.cs
+++ b/src/EventHub.Application/EventHubApplicationModule.cs
@@ -3,6 +3,7 @@ using Volo.Abp.AutoMapper;
using Volo.Abp.Identity;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement;
+using Volo.Abp.VirtualFileSystem;
namespace EventHub
{
@@ -21,6 +22,11 @@ namespace EventHub
{
options.AddMaps();
});
+
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded("EventHub");
+ });
}
}
}
diff --git a/src/EventHub.Application/Events/Registrations/EventRegistrationAppService.cs b/src/EventHub.Application/Events/Registrations/EventRegistrationAppService.cs
index d0dc286..1e3321b 100644
--- a/src/EventHub.Application/Events/Registrations/EventRegistrationAppService.cs
+++ b/src/EventHub.Application/Events/Registrations/EventRegistrationAppService.cs
@@ -16,26 +16,31 @@ namespace EventHub.Events.Registrations
private readonly IRepository _userRepository;
private readonly IRepository _eventRepository;
private readonly IRepository _eventRegistrationRepository;
+ private readonly EventRegistrationNotifier _eventRegistrationNotifier;
public EventRegistrationAppService(
EventRegistrationManager eventRegistrationManager,
IRepository userRepository,
IRepository eventRepository,
- IRepository eventRegistrationRepository)
+ IRepository eventRegistrationRepository,
+ EventRegistrationNotifier eventRegistrationNotifier)
{
_eventRegistrationManager = eventRegistrationManager;
_userRepository = userRepository;
_eventRepository = eventRepository;
_eventRegistrationRepository = eventRegistrationRepository;
+ _eventRegistrationNotifier = eventRegistrationNotifier;
}
[Authorize]
public async Task RegisterAsync(Guid eventId)
{
- await _eventRegistrationManager.RegisterAsync(
- await _eventRepository.GetAsync(eventId),
- await _userRepository.GetAsync(CurrentUser.GetId())
- );
+ var @event = await _eventRepository.GetAsync(eventId);
+ var user = await _userRepository.GetAsync(CurrentUser.GetId());
+
+ await _eventRegistrationManager.RegisterAsync(@event, user);
+
+ await _eventRegistrationNotifier.NotifyAsync(@event, user);
}
[Authorize]
diff --git a/src/EventHub.Application/Events/Registrations/EventRegistrationNotifier.cs b/src/EventHub.Application/Events/Registrations/EventRegistrationNotifier.cs
new file mode 100644
index 0000000..7413e96
--- /dev/null
+++ b/src/EventHub.Application/Events/Registrations/EventRegistrationNotifier.cs
@@ -0,0 +1,47 @@
+using System.Threading.Tasks;
+using EventHub.Emailing;
+using EventHub.Users;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Emailing;
+using Volo.Abp.TextTemplating;
+
+namespace EventHub.Events.Registrations
+{
+ public class EventRegistrationNotifier : ITransientDependency
+ {
+ private readonly IEmailSender _emailSender;
+ private readonly ITemplateRenderer _templateRenderer;
+
+ public EventRegistrationNotifier(
+ IEmailSender emailSender,
+ ITemplateRenderer templateRenderer)
+ {
+ _emailSender = emailSender;
+ _templateRenderer = templateRenderer;
+ }
+
+ public async Task NotifyAsync(
+ Event @event,
+ AppUser user)
+ {
+ if (user is null || @event is null)
+ {
+ return;
+ }
+
+ var model = new
+ {
+ Title = @event.Title,
+ StartTime = @event.StartTime,
+ EndTime = @event.EndTime,
+ Url = @event.Url
+ };
+
+ await _emailSender.QueueAsync(
+ user.Email,
+ "Your event registration has been received!",
+ await _templateRenderer.RenderAsync(EmailTemplates.EventRegistration, model)
+ );
+ }
+ }
+}
\ No newline at end of file
From 41e89855e290f04ec63d9ae844d6b02c473264d6 Mon Sep 17 00:00:00 2001
From: Berkan
Date: Wed, 3 Feb 2021 15:40:41 +0300
Subject: [PATCH 02/13] Send an email 30 minutes before the event starts
---
.../EmailTemplateDefinitionProvider.cs | 9 +
.../Emailing/EmailTemplates.cs | 2 +
.../Emailing/Templates/EventRegistration.tpl | 2 +-
.../Emailing/Templates/EventReminder.tpl | 157 ++
.../EventHub.Application.csproj | 1 +
.../EventHubApplicationModule.cs | 13 +-
.../Events/EventReminderNotifier.cs | 52 +
.../Events/EventReminderWorker.cs | 67 +
src/EventHub.Domain/Events/Event.cs | 2 +
src/EventHub.Domain/Users/AppUser.cs | 15 +
..._IsRemindingEmailSent_To_Event.Designer.cs | 2499 +++++++++++++++++
...538_Added_IsRemindingEmailSent_To_Event.cs | 24 +
...ventHubMigrationsDbContextModelSnapshot.cs | 3 +
13 files changed, 2843 insertions(+), 3 deletions(-)
create mode 100644 src/EventHub.Application/Emailing/Templates/EventReminder.tpl
create mode 100644 src/EventHub.Application/Events/EventReminderNotifier.cs
create mode 100644 src/EventHub.Application/Events/EventReminderWorker.cs
create mode 100644 src/EventHub.EntityFrameworkCore.DbMigrations/Migrations/20210203084538_Added_IsRemindingEmailSent_To_Event.Designer.cs
create mode 100644 src/EventHub.EntityFrameworkCore.DbMigrations/Migrations/20210203084538_Added_IsRemindingEmailSent_To_Event.cs
diff --git a/src/EventHub.Application/Emailing/EmailTemplateDefinitionProvider.cs b/src/EventHub.Application/Emailing/EmailTemplateDefinitionProvider.cs
index 4b43c8c..fd55ee8 100644
--- a/src/EventHub.Application/Emailing/EmailTemplateDefinitionProvider.cs
+++ b/src/EventHub.Application/Emailing/EmailTemplateDefinitionProvider.cs
@@ -14,6 +14,15 @@ namespace EventHub.Emailing
isInlineLocalized: true
)
);
+
+ context.Add(
+ new TemplateDefinition(
+ EmailTemplates.EventReminder
+ ).WithVirtualFilePath(
+ "/Emailing/Templates/EventReminder.tpl",
+ isInlineLocalized: true
+ )
+ );
}
}
}
\ No newline at end of file
diff --git a/src/EventHub.Application/Emailing/EmailTemplates.cs b/src/EventHub.Application/Emailing/EmailTemplates.cs
index f8b6161..0e1c4af 100644
--- a/src/EventHub.Application/Emailing/EmailTemplates.cs
+++ b/src/EventHub.Application/Emailing/EmailTemplates.cs
@@ -3,5 +3,7 @@ namespace EventHub.Emailing
public static class EmailTemplates
{
public const string EventRegistration = "EventHub.Event.Registration";
+
+ public const string EventReminder = "EventHub.Event.Reminder";
}
}
\ No newline at end of file
diff --git a/src/EventHub.Application/Emailing/Templates/EventRegistration.tpl b/src/EventHub.Application/Emailing/Templates/EventRegistration.tpl
index 1667895..c126b4a 100644
--- a/src/EventHub.Application/Emailing/Templates/EventRegistration.tpl
+++ b/src/EventHub.Application/Emailing/Templates/EventRegistration.tpl
@@ -79,7 +79,7 @@
Hi,
- Great news! You attended the {{model.title}} event.
+ Great news! You attended the "{{model.title}}" event.
diff --git a/src/EventHub.Application/Emailing/Templates/EventReminder.tpl b/src/EventHub.Application/Emailing/Templates/EventReminder.tpl
new file mode 100644
index 0000000..22f3914
--- /dev/null
+++ b/src/EventHub.Application/Emailing/Templates/EventReminder.tpl
@@ -0,0 +1,157 @@
+
+
+
+
+
+ Eventhub
+
+
+
+
+
+
+
+
+
+
+
+ EventHub
+
+
+
+
+
+ {{model.title}} event will start soon
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+ Hi {{model.user_name}},
+
+
+ See you in 30 minutes at the "{{model.title}}" event
+
+
+
+
+
+ |
+
+ Start Time
+ {{model.start_time}}
+ |
+
+
+ End Time
+ {{model.end_time}}
+ |
+
+
+
+
+
+ Event Details
+
+
+
+
+ Thank you, EventHub
+
+ |
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+ |
+
+ |
+
+
+ |
+
+ |
+
+
+
+
+
+
+ |
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/EventHub.Application/EventHub.Application.csproj b/src/EventHub.Application/EventHub.Application.csproj
index 7515db7..e8620c9 100644
--- a/src/EventHub.Application/EventHub.Application.csproj
+++ b/src/EventHub.Application/EventHub.Application.csproj
@@ -13,6 +13,7 @@
+
diff --git a/src/EventHub.Application/EventHubApplicationModule.cs b/src/EventHub.Application/EventHubApplicationModule.cs
index 61fa6f3..51728de 100644
--- a/src/EventHub.Application/EventHubApplicationModule.cs
+++ b/src/EventHub.Application/EventHubApplicationModule.cs
@@ -1,5 +1,8 @@
-using Volo.Abp.Account;
+using EventHub.Events;
+using Volo.Abp;
+using Volo.Abp.Account;
using Volo.Abp.AutoMapper;
+using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Identity;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement;
@@ -12,10 +15,16 @@ namespace EventHub
typeof(AbpAccountApplicationModule),
typeof(EventHubApplicationContractsModule),
typeof(AbpIdentityApplicationModule),
- typeof(AbpPermissionManagementApplicationModule)
+ typeof(AbpPermissionManagementApplicationModule),
+ typeof(AbpBackgroundWorkersModule)
)]
public class EventHubApplicationModule : AbpModule
{
+ public override void OnApplicationInitialization(ApplicationInitializationContext context)
+ {
+ context.AddBackgroundWorker();
+ }
+
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure(options =>
diff --git a/src/EventHub.Application/Events/EventReminderNotifier.cs b/src/EventHub.Application/Events/EventReminderNotifier.cs
new file mode 100644
index 0000000..297a757
--- /dev/null
+++ b/src/EventHub.Application/Events/EventReminderNotifier.cs
@@ -0,0 +1,52 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using EventHub.Emailing;
+using EventHub.Users;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Emailing;
+using Volo.Abp.TextTemplating;
+
+namespace EventHub.Events
+{
+ public class EventReminderNotifier : ITransientDependency
+ {
+ private readonly IEmailSender _emailSender;
+ private readonly ITemplateRenderer _templateRenderer;
+
+ public EventReminderNotifier(
+ IEmailSender emailSender,
+ ITemplateRenderer templateRenderer)
+ {
+ _emailSender = emailSender;
+ _templateRenderer = templateRenderer;
+ }
+
+ public async Task NotifyAsync(
+ Event @event,
+ IEnumerable users)
+ {
+ if (users is null || @event is null)
+ {
+ return;
+ }
+
+ foreach (var user in users)
+ {
+ var model = new
+ {
+ UserName = user.GetFullNameOrUsername(),
+ Title = @event.Title,
+ StartTime = @event.StartTime,
+ EndTime = @event.EndTime,
+ Url = @event.Url
+ };
+
+ await _emailSender.QueueAsync(
+ user.Email,
+ "The event has last thirty minutes to start!",
+ await _templateRenderer.RenderAsync(EmailTemplates.EventReminder, model)
+ );
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/EventHub.Application/Events/EventReminderWorker.cs b/src/EventHub.Application/Events/EventReminderWorker.cs
new file mode 100644
index 0000000..24b7ca3
--- /dev/null
+++ b/src/EventHub.Application/Events/EventReminderWorker.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using EventHub.Events.Registrations;
+using EventHub.Users;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Volo.Abp.BackgroundWorkers;
+using Volo.Abp.Domain.Repositories;
+using Volo.Abp.Threading;
+using Volo.Abp.Uow;
+
+namespace EventHub.Events
+{
+ public class EventReminderWorker : AsyncPeriodicBackgroundWorkerBase
+ {
+ public EventReminderWorker(AbpAsyncTimer timer, IServiceScopeFactory serviceScopeFactory)
+ : base(timer, serviceScopeFactory)
+ {
+ Timer.Period = 60_000;
+ }
+
+ [UnitOfWork]
+ protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
+ {
+ var eventReminderNotifier = workerContext.ServiceProvider.GetRequiredService();
+
+ var eventRepository = workerContext.ServiceProvider.GetRequiredService>();
+ var userRepository = workerContext.ServiceProvider.GetRequiredService>();
+ var eventRegistrationRepository = workerContext.ServiceProvider.GetRequiredService>();
+
+ var eventQueryable = await eventRepository.GetQueryableAsync();
+ var userQueryable = await userRepository.GetQueryableAsync();
+ var eventRegistrationQueryable = await eventRegistrationRepository.GetQueryableAsync();
+
+ var thirtyOneMinutesAfter = DateTime.Now.AddMinutes(31);
+ var twentyNineMinutesAfter = DateTime.Now.AddMinutes(29);
+
+ var eventsStartingAfterThirtyMinutes = await eventQueryable.Where(x =>
+ x.IsRemindingEmailSent == false &&
+ x.StartTime < thirtyOneMinutesAfter &&
+ x.StartTime > twentyNineMinutesAfter)
+ .ToListAsync();
+
+ foreach (var @event in eventsStartingAfterThirtyMinutes)
+ {
+ var usersToBeNotified = await (from eventRegistration in eventRegistrationQueryable
+ join user in userQueryable on eventRegistration.UserId equals user.Id
+ where eventRegistration.EventId == @event.Id
+ select user).ToListAsync();
+
+ @event.IsRemindingEmailSent = true;
+
+ try
+ {
+ await eventReminderNotifier.NotifyAsync(@event, usersToBeNotified);
+ }
+ catch (Exception e)
+ {
+ @event.IsRemindingEmailSent = false;
+ Logger.LogError($"An error occurred while sending reminder mail for {@event.Id} event. Error message: {e.Message}");
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/EventHub.Domain/Events/Event.cs b/src/EventHub.Domain/Events/Event.cs
index ddf99cb..117bf87 100644
--- a/src/EventHub.Domain/Events/Event.cs
+++ b/src/EventHub.Domain/Events/Event.cs
@@ -24,6 +24,8 @@ namespace EventHub.Events
public int? Capacity { get; set; }
+ public bool IsRemindingEmailSent { get; set; }
+
private Event()
{
diff --git a/src/EventHub.Domain/Users/AppUser.cs b/src/EventHub.Domain/Users/AppUser.cs
index 2310232..8a767e7 100644
--- a/src/EventHub.Domain/Users/AppUser.cs
+++ b/src/EventHub.Domain/Users/AppUser.cs
@@ -59,5 +59,20 @@ namespace EventHub.Users
{
}
+
+ public string GetFullNameOrUsername()
+ {
+ if (!string.IsNullOrWhiteSpace(Name) && !string.IsNullOrWhiteSpace(Surname))
+ {
+ return Name + " " + Surname;
+ }
+
+ if (!string.IsNullOrWhiteSpace(Name))
+ {
+ return Name;
+ }
+
+ return UserName;
+ }
}
}
diff --git a/src/EventHub.EntityFrameworkCore.DbMigrations/Migrations/20210203084538_Added_IsRemindingEmailSent_To_Event.Designer.cs b/src/EventHub.EntityFrameworkCore.DbMigrations/Migrations/20210203084538_Added_IsRemindingEmailSent_To_Event.Designer.cs
new file mode 100644
index 0000000..015771a
--- /dev/null
+++ b/src/EventHub.EntityFrameworkCore.DbMigrations/Migrations/20210203084538_Added_IsRemindingEmailSent_To_Event.Designer.cs
@@ -0,0 +1,2499 @@
+//
+using System;
+using EventHub.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Volo.Abp.EntityFrameworkCore;
+
+namespace EventHub.Migrations
+{
+ [DbContext(typeof(EventHubMigrationsDbContext))]
+ [Migration("20210203084538_Added_IsRemindingEmailSent_To_Event")]
+ partial class Added_IsRemindingEmailSent_To_Event
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .UseIdentityColumns()
+ .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer)
+ .HasAnnotation("Relational:MaxIdentifierLength", 128)
+ .HasAnnotation("ProductVersion", "5.0.2");
+
+ modelBuilder.Entity("EventHub.Events.Event", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Capacity")
+ .HasColumnType("int");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("DeletionTime");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasMaxLength(2000)
+ .HasColumnType("nvarchar(2000)");
+
+ b.Property("EndTime")
+ .HasColumnType("datetime2");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("IsOnline")
+ .HasColumnType("bit");
+
+ b.Property("IsRemindingEmailSent")
+ .HasColumnType("bit");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("LastModifierId");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("StartTime")
+ .HasColumnType("datetime2");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Url")
+ .IsRequired()
+ .HasMaxLength(69)
+ .HasColumnType("nvarchar(69)");
+
+ b.Property("UrlCode")
+ .IsRequired()
+ .HasMaxLength(8)
+ .HasColumnType("nvarchar(8)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("StartTime");
+
+ b.HasIndex("UrlCode");
+
+ b.HasIndex("OrganizationId", "StartTime");
+
+ b.ToTable("AppEvents");
+ });
+
+ modelBuilder.Entity("EventHub.Events.Registrations.EventRegistration", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("EventId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("EventId", "UserId");
+
+ b.ToTable("AppEventRegistrations");
+ });
+
+ modelBuilder.Entity("EventHub.Organizations.Memberships.OrganizationMembership", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("OrganizationId", "UserId");
+
+ b.ToTable("AppOrganizationMemberships");
+ });
+
+ modelBuilder.Entity("EventHub.Organizations.Organization", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("DeletionTime");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("FacebookUsername")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("GitHubUsername")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("InstagramUsername")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("LastModifierId");
+
+ b.Property("MediumUsername")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("OwnerUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TwitterUsername")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Website")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DisplayName");
+
+ b.HasIndex("Name");
+
+ b.HasIndex("OwnerUserId");
+
+ b.ToTable("AppOrganizations");
+ });
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ApplicationName")
+ .HasMaxLength(96)
+ .HasColumnType("nvarchar(96)")
+ .HasColumnName("ApplicationName");
+
+ b.Property("BrowserInfo")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)")
+ .HasColumnName("BrowserInfo");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)")
+ .HasColumnName("ClientId");
+
+ b.Property("ClientIpAddress")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)")
+ .HasColumnName("ClientIpAddress");
+
+ b.Property("ClientName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)")
+ .HasColumnName("ClientName");
+
+ b.Property("Comments")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("Comments");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CorrelationId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)")
+ .HasColumnName("CorrelationId");
+
+ b.Property("Exceptions")
+ .HasMaxLength(4000)
+ .HasColumnType("nvarchar(4000)")
+ .HasColumnName("Exceptions");
+
+ b.Property("ExecutionDuration")
+ .HasColumnType("int")
+ .HasColumnName("ExecutionDuration");
+
+ b.Property("ExecutionTime")
+ .HasColumnType("datetime2");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("HttpMethod")
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)")
+ .HasColumnName("HttpMethod");
+
+ b.Property("HttpStatusCode")
+ .HasColumnType("int")
+ .HasColumnName("HttpStatusCode");
+
+ b.Property("ImpersonatorTenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("ImpersonatorTenantId");
+
+ b.Property("ImpersonatorUserId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("ImpersonatorUserId");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("TenantName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Url")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("Url");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("UserId");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("UserName");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "ExecutionTime");
+
+ b.HasIndex("TenantId", "UserId", "ExecutionTime");
+
+ b.ToTable("AbpAuditLogs");
+ });
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AuditLogId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("AuditLogId");
+
+ b.Property("ExecutionDuration")
+ .HasColumnType("int")
+ .HasColumnName("ExecutionDuration");
+
+ b.Property("ExecutionTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("ExecutionTime");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("MethodName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)")
+ .HasColumnName("MethodName");
+
+ b.Property("Parameters")
+ .HasMaxLength(2000)
+ .HasColumnType("nvarchar(2000)")
+ .HasColumnName("Parameters");
+
+ b.Property("ServiceName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("ServiceName");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AuditLogId");
+
+ b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime");
+
+ b.ToTable("AbpAuditLogActions");
+ });
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AuditLogId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("AuditLogId");
+
+ b.Property("ChangeTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("ChangeTime");
+
+ b.Property("ChangeType")
+ .HasColumnType("tinyint")
+ .HasColumnName("ChangeType");
+
+ b.Property("EntityId")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)")
+ .HasColumnName("EntityId");
+
+ b.Property("EntityTenantId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("EntityTypeFullName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)")
+ .HasColumnName("EntityTypeFullName");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AuditLogId");
+
+ b.HasIndex("TenantId", "EntityTypeFullName", "EntityId");
+
+ b.ToTable("AbpEntityChanges");
+ });
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("EntityChangeId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("NewValue")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)")
+ .HasColumnName("NewValue");
+
+ b.Property("OriginalValue")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)")
+ .HasColumnName("OriginalValue");
+
+ b.Property("PropertyName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)")
+ .HasColumnName("PropertyName");
+
+ b.Property("PropertyTypeFullName")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)")
+ .HasColumnName("PropertyTypeFullName");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("EntityChangeId");
+
+ b.ToTable("AbpEntityPropertyChanges");
+ });
+
+ modelBuilder.Entity("Volo.Abp.BackgroundJobs.BackgroundJobRecord", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsAbandoned")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false);
+
+ b.Property("JobArgs")
+ .IsRequired()
+ .HasMaxLength(1048576)
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("JobName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("LastTryTime")
+ .HasColumnType("datetime2");
+
+ b.Property("NextTryTime")
+ .HasColumnType("datetime2");
+
+ b.Property("Priority")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("tinyint")
+ .HasDefaultValue((byte)15);
+
+ b.Property("TryCount")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("smallint")
+ .HasDefaultValue((short)0);
+
+ b.HasKey("Id");
+
+ b.HasIndex("IsAbandoned", "NextTryTime");
+
+ b.ToTable("AbpBackgroundJobs");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("Description")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsStatic")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("Regex")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("RegexDescription")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Required")
+ .HasColumnType("bit");
+
+ b.Property("ValueType")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("AbpClaimTypes");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("SourceTenantId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("SourceUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TargetTenantId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TargetUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId")
+ .IsUnique()
+ .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL");
+
+ b.ToTable("AbpLinkUsers");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDefault")
+ .HasColumnType("bit")
+ .HasColumnName("IsDefault");
+
+ b.Property("IsPublic")
+ .HasColumnType("bit")
+ .HasColumnName("IsPublic");
+
+ b.Property("IsStatic")
+ .HasColumnType("bit")
+ .HasColumnName("IsStatic");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("NormalizedName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName");
+
+ b.ToTable("AbpRoles");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClaimType")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ClaimValue")
+ .HasMaxLength(1024)
+ .HasColumnType("nvarchar(1024)");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AbpRoleClaims");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Action")
+ .HasMaxLength(96)
+ .HasColumnType("nvarchar(96)");
+
+ b.Property("ApplicationName")
+ .HasMaxLength(96)
+ .HasColumnType("nvarchar(96)");
+
+ b.Property("BrowserInfo")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ClientIpAddress")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CorrelationId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("Identity")
+ .HasMaxLength(96)
+ .HasColumnType("nvarchar(96)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("TenantName")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "Action");
+
+ b.HasIndex("TenantId", "ApplicationName");
+
+ b.HasIndex("TenantId", "Identity");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AbpSecurityLogs");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AccessFailedCount")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasDefaultValue(0)
+ .HasColumnName("AccessFailedCount");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("DeletionTime");
+
+ b.Property("Email")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("Email");
+
+ b.Property("EmailConfirmed")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("EmailConfirmed");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("IsExternal")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("IsExternal");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("LastModifierId");
+
+ b.Property("LockoutEnabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("LockoutEnabled");
+
+ b.Property("LockoutEnd")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("Name")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)")
+ .HasColumnName("Name");
+
+ b.Property("NormalizedEmail")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("NormalizedEmail");
+
+ b.Property("NormalizedUserName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("NormalizedUserName");
+
+ b.Property("PasswordHash")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("PasswordHash");
+
+ b.Property("PhoneNumber")
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)")
+ .HasColumnName("PhoneNumber");
+
+ b.Property("PhoneNumberConfirmed")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("PhoneNumberConfirmed");
+
+ b.Property("SecurityStamp")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("SecurityStamp");
+
+ b.Property("Surname")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)")
+ .HasColumnName("Surname");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("TwoFactorEnabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("TwoFactorEnabled");
+
+ b.Property("UserName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("UserName");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Email");
+
+ b.HasIndex("NormalizedEmail");
+
+ b.HasIndex("NormalizedUserName");
+
+ b.HasIndex("UserName");
+
+ b.ToTable("AbpUsers");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClaimType")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ClaimValue")
+ .HasMaxLength(1024)
+ .HasColumnType("nvarchar(1024)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AbpUserClaims");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("LoginProvider")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ProviderDisplayName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ProviderKey")
+ .IsRequired()
+ .HasMaxLength(196)
+ .HasColumnType("nvarchar(196)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("UserId", "LoginProvider");
+
+ b.HasIndex("LoginProvider", "ProviderKey");
+
+ b.ToTable("AbpUserLogins");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b =>
+ {
+ b.Property("OrganizationUnitId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("OrganizationUnitId", "UserId");
+
+ b.HasIndex("UserId", "OrganizationUnitId");
+
+ b.ToTable("AbpUserOrganizationUnits");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId", "UserId");
+
+ b.ToTable("AbpUserRoles");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("LoginProvider")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Name")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("Value")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AbpUserTokens");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Code")
+ .IsRequired()
+ .HasMaxLength(95)
+ .HasColumnType("nvarchar(95)")
+ .HasColumnName("Code");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("DeletionTime");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)")
+ .HasColumnName("DisplayName");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("LastModifierId");
+
+ b.Property("ParentId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Code");
+
+ b.HasIndex("ParentId");
+
+ b.ToTable("AbpOrganizationUnits");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b =>
+ {
+ b.Property("OrganizationUnitId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("OrganizationUnitId", "RoleId");
+
+ b.HasIndex("RoleId", "OrganizationUnitId");
+
+ b.ToTable("AbpOrganizationUnitRoles");
+ });
+
+ modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResource", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AllowedAccessTokenSigningAlgorithms")
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("DeletionTime");
+
+ b.Property("Description")
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("DisplayName")
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("Enabled")
+ .HasColumnType("bit");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("LastModifierId");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("ShowInDiscoveryDocument")
+ .HasColumnType("bit");
+
+ b.HasKey("Id");
+
+ b.ToTable("IdentityServerApiResources");
+ });
+
+ modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceClaim", b =>
+ {
+ b.Property("ApiResourceId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Type")
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.HasKey("ApiResourceId", "Type");
+
+ b.ToTable("IdentityServerApiResourceClaims");
+ });
+
+ modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceProperty", b =>
+ {
+ b.Property