diff --git a/Raytha.sln b/Raytha.sln index 7d71f27b..2d83304b 100644 --- a/Raytha.sln +++ b/Raytha.sln @@ -11,11 +11,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Raytha.Infrastructure", "sr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Raytha.Application", "src\Raytha.Application\Raytha.Application.csproj", "{FC2608C8-0532-4548-AD82-1E51E9F972B6}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Raytha.Migrations.SqlServer", "src\Raytha.Migrations.SqlServer\Raytha.Migrations.SqlServer.csproj", "{A2A0EDB9-B9B4-48F1-A2E9-DF84B248DBBA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Raytha.Migrations.Postgres", "src\Raytha.Migrations.Postgres\Raytha.Migrations.Postgres.csproj", "{62B716C9-90EB-4A0F-8447-F7910703A8ED}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5BD14A0C-0528-49ED-8FB8-88A3231A842C}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{736D110C-2DEA-4E2D-A164-5BAFCB0865C6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raytha.Domain.UnitTests", "tests\Raytha.Domain.UnitTests\Raytha.Domain.UnitTests.csproj", "{8AE80E8A-C677-410E-BF24-17C9E8F7B94C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Raytha.Domain.UnitTests", "tests\Raytha.Domain.UnitTests\Raytha.Domain.UnitTests.csproj", "{8AE80E8A-C677-410E-BF24-17C9E8F7B94C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -48,6 +52,18 @@ Global {FC2608C8-0532-4548-AD82-1E51E9F972B6}.Debug|Any CPU.Build.0 = Debug|Any CPU {FC2608C8-0532-4548-AD82-1E51E9F972B6}.Release|Any CPU.ActiveCfg = Release|Any CPU {FC2608C8-0532-4548-AD82-1E51E9F972B6}.Release|Any CPU.Build.0 = Release|Any CPU + {A2A0EDB9-B9B4-48F1-A2E9-DF84B248DBBA}.Debug without JS|Any CPU.ActiveCfg = Debug|Any CPU + {A2A0EDB9-B9B4-48F1-A2E9-DF84B248DBBA}.Debug without JS|Any CPU.Build.0 = Debug|Any CPU + {A2A0EDB9-B9B4-48F1-A2E9-DF84B248DBBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A2A0EDB9-B9B4-48F1-A2E9-DF84B248DBBA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A2A0EDB9-B9B4-48F1-A2E9-DF84B248DBBA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A2A0EDB9-B9B4-48F1-A2E9-DF84B248DBBA}.Release|Any CPU.Build.0 = Release|Any CPU + {62B716C9-90EB-4A0F-8447-F7910703A8ED}.Debug without JS|Any CPU.ActiveCfg = Debug|Any CPU + {62B716C9-90EB-4A0F-8447-F7910703A8ED}.Debug without JS|Any CPU.Build.0 = Debug|Any CPU + {62B716C9-90EB-4A0F-8447-F7910703A8ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62B716C9-90EB-4A0F-8447-F7910703A8ED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62B716C9-90EB-4A0F-8447-F7910703A8ED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62B716C9-90EB-4A0F-8447-F7910703A8ED}.Release|Any CPU.Build.0 = Release|Any CPU {8AE80E8A-C677-410E-BF24-17C9E8F7B94C}.Debug without JS|Any CPU.ActiveCfg = Debug|Any CPU {8AE80E8A-C677-410E-BF24-17C9E8F7B94C}.Debug without JS|Any CPU.Build.0 = Debug|Any CPU {8AE80E8A-C677-410E-BF24-17C9E8F7B94C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -63,6 +79,8 @@ Global {A51C9862-86A1-4EB9-800E-0CDDEDBCAF6B} = {5BD14A0C-0528-49ED-8FB8-88A3231A842C} {C429E709-CA75-4927-96BD-F34863D0ECC6} = {5BD14A0C-0528-49ED-8FB8-88A3231A842C} {FC2608C8-0532-4548-AD82-1E51E9F972B6} = {5BD14A0C-0528-49ED-8FB8-88A3231A842C} + {A2A0EDB9-B9B4-48F1-A2E9-DF84B248DBBA} = {5BD14A0C-0528-49ED-8FB8-88A3231A842C} + {62B716C9-90EB-4A0F-8447-F7910703A8ED} = {5BD14A0C-0528-49ED-8FB8-88A3231A842C} {8AE80E8A-C677-410E-BF24-17C9E8F7B94C} = {736D110C-2DEA-4E2D-A164-5BAFCB0865C6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/db/Postgres/FreshCreateOnLatestVersion.sql b/db/Postgres/FreshCreateOnLatestVersion.sql new file mode 100644 index 00000000..2e4d06fa --- /dev/null +++ b/db/Postgres/FreshCreateOnLatestVersion.sql @@ -0,0 +1,786 @@ +CREATE TABLE IF NOT EXISTS "__EFMigrationsHistory" ( + "MigrationId" character varying(150) NOT NULL, + "ProductVersion" character varying(32) NOT NULL, + CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY ("MigrationId") +); + +START TRANSACTION; + +CREATE TABLE "AuditLogs" ( + "Id" uuid NOT NULL, + "EntityId" uuid, + "Category" text NOT NULL, + "Request" text NOT NULL, + "UserEmail" text NOT NULL, + "IpAddress" text NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + CONSTRAINT "PK_AuditLogs" PRIMARY KEY ("Id") +); + +CREATE TABLE "BackgroundTasks" ( + "Id" uuid NOT NULL, + "Name" text NOT NULL, + "Args" text, + "ErrorMessage" text, + "Status" text NOT NULL, + "StatusInfo" text, + "PercentComplete" integer NOT NULL, + "NumberOfRetries" integer NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CompletionTime" timestamp with time zone, + "TaskStep" integer NOT NULL, + CONSTRAINT "PK_BackgroundTasks" PRIMARY KEY ("Id") +); + +CREATE TABLE "DataProtectionKeys" ( + "Id" integer GENERATED BY DEFAULT AS IDENTITY, + "FriendlyName" text, + "Xml" text, + CONSTRAINT "PK_DataProtectionKeys" PRIMARY KEY ("Id") +); + +CREATE TABLE "JwtLogins" ( + "Id" uuid NOT NULL, + "Jti" text, + "CreationTime" timestamp with time zone NOT NULL, + CONSTRAINT "PK_JwtLogins" PRIMARY KEY ("Id") +); + +CREATE TABLE "OrganizationSettings" ( + "Id" uuid NOT NULL, + "OrganizationName" text, + "WebsiteUrl" text, + "TimeZone" text, + "DateFormat" text, + "SmtpOverrideSystem" boolean NOT NULL, + "SmtpHost" text, + "SmtpPort" integer, + "SmtpUsername" text, + "SmtpPassword" text, + "SmtpDefaultFromAddress" text, + "SmtpDefaultFromName" text, + "HomePageId" uuid, + "HomePageType" text NOT NULL, + "ActiveThemeId" uuid NOT NULL, + CONSTRAINT "PK_OrganizationSettings" PRIMARY KEY ("Id") +); + +CREATE TABLE "Routes" ( + "Id" uuid NOT NULL, + "Path" text NOT NULL, + "ContentItemId" uuid NOT NULL, + "ViewId" uuid NOT NULL, + CONSTRAINT "PK_Routes" PRIMARY KEY ("Id") +); + +CREATE TABLE "ApiKeys" ( + "Id" uuid NOT NULL, + "ApiKeyHash" bytea NOT NULL, + "UserId" uuid NOT NULL, + "CreatorUserId" uuid, + "CreationTime" timestamp with time zone NOT NULL, + CONSTRAINT "PK_ApiKeys" PRIMARY KEY ("Id") +); + +CREATE TABLE "AuthenticationSchemes" ( + "Id" uuid NOT NULL, + "IsBuiltInAuth" boolean NOT NULL, + "IsEnabledForUsers" boolean NOT NULL, + "IsEnabledForAdmins" boolean NOT NULL, + "AuthenticationSchemeType" text, + "Label" text, + "DeveloperName" text, + "MagicLinkExpiresInSeconds" integer NOT NULL, + "SamlCertificate" text, + "SamlIdpEntityId" text, + "JwtSecretKey" text, + "JwtUseHighSecurity" boolean NOT NULL, + "SignInUrl" text, + "LoginButtonText" text, + "SignOutUrl" text, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_AuthenticationSchemes" PRIMARY KEY ("Id") +); + +CREATE TABLE "Users" ( + "Id" uuid NOT NULL, + "IsAdmin" boolean NOT NULL, + "IsActive" boolean NOT NULL, + "LastLoggedInTime" timestamp with time zone, + "Salt" bytea NOT NULL, + "PasswordHash" bytea NOT NULL, + "SsoId" text, + "AuthenticationSchemeId" uuid, + "FirstName" text NOT NULL, + "LastName" text NOT NULL, + "EmailAddress" text NOT NULL, + "IsEmailAddressConfirmed" boolean NOT NULL, + "_RecentlyAccessedViews" text, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_Users" PRIMARY KEY ("Id"), + CONSTRAINT "FK_Users_AuthenticationSchemes_AuthenticationSchemeId" FOREIGN KEY ("AuthenticationSchemeId") REFERENCES "AuthenticationSchemes" ("Id"), + CONSTRAINT "FK_Users_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_Users_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "ContentTypes" ( + "Id" uuid NOT NULL, + "IsActive" boolean NOT NULL, + "LabelPlural" text, + "LabelSingular" text, + "DeveloperName" text, + "Description" text, + "DefaultRouteTemplate" text, + "PrimaryFieldId" uuid NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + "DeleterUserId" uuid, + "DeletionTime" timestamp with time zone, + "IsDeleted" boolean NOT NULL, + CONSTRAINT "PK_ContentTypes" PRIMARY KEY ("Id"), + CONSTRAINT "FK_ContentTypes_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_ContentTypes_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "EmailTemplates" ( + "Id" uuid NOT NULL, + "Subject" text, + "DeveloperName" text, + "Cc" text, + "Bcc" text, + "Content" text, + "IsBuiltInTemplate" boolean NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_EmailTemplates" PRIMARY KEY ("Id"), + CONSTRAINT "FK_EmailTemplates_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_EmailTemplates_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "MediaItems" ( + "Id" uuid NOT NULL, + "Length" bigint NOT NULL, + "FileName" text NOT NULL, + "ContentType" text NOT NULL, + "FileStorageProvider" text NOT NULL, + "ObjectKey" text NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_MediaItems" PRIMARY KEY ("Id"), + CONSTRAINT "FK_MediaItems_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_MediaItems_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "NavigationMenus" ( + "Id" uuid NOT NULL, + "Label" text NOT NULL, + "DeveloperName" text NOT NULL, + "IsMainMenu" boolean NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_NavigationMenus" PRIMARY KEY ("Id"), + CONSTRAINT "FK_NavigationMenus_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_NavigationMenus_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "OneTimePasswords" ( + "Id" bytea NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "ExpiresAt" timestamp with time zone NOT NULL, + "IsUsed" boolean NOT NULL, + "UserId" uuid NOT NULL, + CONSTRAINT "PK_OneTimePasswords" PRIMARY KEY ("Id"), + CONSTRAINT "FK_OneTimePasswords_Users_UserId" FOREIGN KEY ("UserId") REFERENCES "Users" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "RaythaFunctions" ( + "Id" uuid NOT NULL, + "Name" text NOT NULL, + "DeveloperName" text NOT NULL, + "TriggerType" text NOT NULL, + "Code" text NOT NULL, + "IsActive" boolean NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_RaythaFunctions" PRIMARY KEY ("Id"), + CONSTRAINT "FK_RaythaFunctions_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_RaythaFunctions_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "Roles" ( + "Id" uuid NOT NULL, + "Label" text NOT NULL, + "DeveloperName" text NOT NULL, + "SystemPermissions" integer NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_Roles" PRIMARY KEY ("Id"), + CONSTRAINT "FK_Roles_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_Roles_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "Themes" ( + "Id" uuid NOT NULL, + "Title" text NOT NULL, + "DeveloperName" text NOT NULL, + "Description" text NOT NULL, + "IsExportable" boolean NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_Themes" PRIMARY KEY ("Id"), + CONSTRAINT "FK_Themes_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_Themes_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "UserGroups" ( + "Id" uuid NOT NULL, + "Label" text NOT NULL, + "DeveloperName" text NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_UserGroups" PRIMARY KEY ("Id"), + CONSTRAINT "FK_UserGroups_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_UserGroups_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "VerificationCodes" ( + "Id" uuid NOT NULL, + "Code" uuid NOT NULL, + "ExpiresAt" timestamp with time zone NOT NULL, + "Completed" boolean NOT NULL, + "EmailAddress" text, + "VerificationCodeType" text NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_VerificationCodes" PRIMARY KEY ("Id"), + CONSTRAINT "FK_VerificationCodes_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_VerificationCodes_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "ContentItems" ( + "Id" uuid NOT NULL, + "IsPublished" boolean NOT NULL, + "IsDraft" boolean NOT NULL, + "_DraftContent" text, + "_PublishedContent" jsonb, + "ContentTypeId" uuid NOT NULL, + "RouteId" uuid NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_ContentItems" PRIMARY KEY ("Id"), + CONSTRAINT "FK_ContentItems_ContentTypes_ContentTypeId" FOREIGN KEY ("ContentTypeId") REFERENCES "ContentTypes" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_ContentItems_Routes_RouteId" FOREIGN KEY ("RouteId") REFERENCES "Routes" ("Id"), + CONSTRAINT "FK_ContentItems_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_ContentItems_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "ContentTypeFields" ( + "Id" uuid NOT NULL, + "Label" text, + "DeveloperName" text, + "Description" text, + "FieldOrder" integer NOT NULL, + "IsRequired" boolean NOT NULL, + "RelatedContentTypeId" uuid, + "ContentTypeId" uuid NOT NULL, + "FieldType" text NOT NULL, + "_Choices" text NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + "DeleterUserId" uuid, + "DeletionTime" timestamp with time zone, + "IsDeleted" boolean NOT NULL, + CONSTRAINT "PK_ContentTypeFields" PRIMARY KEY ("Id"), + CONSTRAINT "FK_ContentTypeFields_ContentTypes_ContentTypeId" FOREIGN KEY ("ContentTypeId") REFERENCES "ContentTypes" ("Id"), + CONSTRAINT "FK_ContentTypeFields_ContentTypes_RelatedContentTypeId" FOREIGN KEY ("RelatedContentTypeId") REFERENCES "ContentTypes" ("Id"), + CONSTRAINT "FK_ContentTypeFields_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_ContentTypeFields_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "DeletedContentItems" ( + "Id" uuid NOT NULL, + "_PublishedContent" text, + "PrimaryField" text, + "ContentTypeId" uuid NOT NULL, + "OriginalContentItemId" uuid NOT NULL, + "RoutePath" text NOT NULL, + "WebTemplateIdsJson" text NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_DeletedContentItems" PRIMARY KEY ("Id"), + CONSTRAINT "FK_DeletedContentItems_ContentTypes_ContentTypeId" FOREIGN KEY ("ContentTypeId") REFERENCES "ContentTypes" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_DeletedContentItems_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_DeletedContentItems_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "Views" ( + "Id" uuid NOT NULL, + "Label" text, + "DeveloperName" text, + "Description" text, + "ContentTypeId" uuid NOT NULL, + "RouteId" uuid NOT NULL, + "IsPublished" boolean NOT NULL, + "DefaultNumberOfItemsPerPage" integer NOT NULL, + "MaxNumberOfItemsPerPage" integer NOT NULL, + "IgnoreClientFilterAndSortQueryParams" boolean NOT NULL, + "_Columns" text, + "_Filter" text, + "_Sort" text, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_Views" PRIMARY KEY ("Id"), + CONSTRAINT "FK_Views_ContentTypes_ContentTypeId" FOREIGN KEY ("ContentTypeId") REFERENCES "ContentTypes" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_Views_Routes_RouteId" FOREIGN KEY ("RouteId") REFERENCES "Routes" ("Id"), + CONSTRAINT "FK_Views_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_Views_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "EmailTemplateRevisions" ( + "Id" uuid NOT NULL, + "Subject" text, + "Content" text, + "Cc" text, + "Bcc" text, + "EmailTemplateId" uuid NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_EmailTemplateRevisions" PRIMARY KEY ("Id"), + CONSTRAINT "FK_EmailTemplateRevisions_EmailTemplates_EmailTemplateId" FOREIGN KEY ("EmailTemplateId") REFERENCES "EmailTemplates" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_EmailTemplateRevisions_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_EmailTemplateRevisions_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "NavigationMenuItems" ( + "Id" uuid NOT NULL, + "Label" text NOT NULL, + "Url" text NOT NULL, + "IsDisabled" boolean NOT NULL, + "OpenInNewTab" boolean NOT NULL, + "CssClassName" text, + "Ordinal" integer NOT NULL, + "ParentNavigationMenuItemId" uuid, + "NavigationMenuId" uuid NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_NavigationMenuItems" PRIMARY KEY ("Id"), + CONSTRAINT "FK_NavigationMenuItems_NavigationMenuItems_ParentNavigationMen~" FOREIGN KEY ("ParentNavigationMenuItemId") REFERENCES "NavigationMenuItems" ("Id"), + CONSTRAINT "FK_NavigationMenuItems_NavigationMenus_NavigationMenuId" FOREIGN KEY ("NavigationMenuId") REFERENCES "NavigationMenus" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_NavigationMenuItems_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_NavigationMenuItems_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "NavigationMenuRevisions" ( + "Id" uuid NOT NULL, + "NavigationMenuItemsJson" text NOT NULL, + "NavigationMenuId" uuid NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_NavigationMenuRevisions" PRIMARY KEY ("Id"), + CONSTRAINT "FK_NavigationMenuRevisions_NavigationMenus_NavigationMenuId" FOREIGN KEY ("NavigationMenuId") REFERENCES "NavigationMenus" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_NavigationMenuRevisions_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_NavigationMenuRevisions_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "RaythaFunctionRevisions" ( + "Id" uuid NOT NULL, + "Code" text NOT NULL, + "RaythaFunctionId" uuid NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_RaythaFunctionRevisions" PRIMARY KEY ("Id"), + CONSTRAINT "FK_RaythaFunctionRevisions_RaythaFunctions_RaythaFunctionId" FOREIGN KEY ("RaythaFunctionId") REFERENCES "RaythaFunctions" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_RaythaFunctionRevisions_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_RaythaFunctionRevisions_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "ContentTypeRolePermission" ( + "Id" uuid NOT NULL, + "ContentTypeId" uuid NOT NULL, + "ContentTypePermissions" integer NOT NULL, + "RoleId" uuid NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_ContentTypeRolePermission" PRIMARY KEY ("Id"), + CONSTRAINT "FK_ContentTypeRolePermission_ContentTypes_ContentTypeId" FOREIGN KEY ("ContentTypeId") REFERENCES "ContentTypes" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_ContentTypeRolePermission_Roles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "Roles" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_ContentTypeRolePermission_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_ContentTypeRolePermission_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "RoleUser" ( + "RolesId" uuid NOT NULL, + "UsersId" uuid NOT NULL, + CONSTRAINT "PK_RoleUser" PRIMARY KEY ("RolesId", "UsersId"), + CONSTRAINT "FK_RoleUser_Roles_RolesId" FOREIGN KEY ("RolesId") REFERENCES "Roles" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_RoleUser_Users_UsersId" FOREIGN KEY ("UsersId") REFERENCES "Users" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "ThemeAccessToMediaItems" ( + "Id" uuid NOT NULL, + "ThemeId" uuid NOT NULL, + "MediaItemId" uuid NOT NULL, + CONSTRAINT "PK_ThemeAccessToMediaItems" PRIMARY KEY ("Id"), + CONSTRAINT "FK_ThemeAccessToMediaItems_MediaItems_MediaItemId" FOREIGN KEY ("MediaItemId") REFERENCES "MediaItems" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_ThemeAccessToMediaItems_Themes_ThemeId" FOREIGN KEY ("ThemeId") REFERENCES "Themes" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "WebTemplates" ( + "Id" uuid NOT NULL, + "ThemeId" uuid NOT NULL, + "IsBaseLayout" boolean NOT NULL, + "Label" text, + "DeveloperName" text, + "Content" text, + "IsBuiltInTemplate" boolean NOT NULL, + "ParentTemplateId" uuid, + "AllowAccessForNewContentTypes" boolean NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_WebTemplates" PRIMARY KEY ("Id"), + CONSTRAINT "FK_WebTemplates_Themes_ThemeId" FOREIGN KEY ("ThemeId") REFERENCES "Themes" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_WebTemplates_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_WebTemplates_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_WebTemplates_WebTemplates_ParentTemplateId" FOREIGN KEY ("ParentTemplateId") REFERENCES "WebTemplates" ("Id") +); + +CREATE TABLE "UserUserGroup" ( + "UserGroupsId" uuid NOT NULL, + "UsersId" uuid NOT NULL, + CONSTRAINT "PK_UserUserGroup" PRIMARY KEY ("UserGroupsId", "UsersId"), + CONSTRAINT "FK_UserUserGroup_UserGroups_UserGroupsId" FOREIGN KEY ("UserGroupsId") REFERENCES "UserGroups" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_UserUserGroup_Users_UsersId" FOREIGN KEY ("UsersId") REFERENCES "Users" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "ContentItemRevisions" ( + "Id" uuid NOT NULL, + "_PublishedContent" text, + "ContentItemId" uuid NOT NULL, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_ContentItemRevisions" PRIMARY KEY ("Id"), + CONSTRAINT "FK_ContentItemRevisions_ContentItems_ContentItemId" FOREIGN KEY ("ContentItemId") REFERENCES "ContentItems" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_ContentItemRevisions_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_ContentItemRevisions_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id") +); + +CREATE TABLE "UserView" ( + "FavoriteViewsId" uuid NOT NULL, + "UserFavoritesId" uuid NOT NULL, + CONSTRAINT "PK_UserView" PRIMARY KEY ("FavoriteViewsId", "UserFavoritesId"), + CONSTRAINT "FK_UserView_Users_UserFavoritesId" FOREIGN KEY ("UserFavoritesId") REFERENCES "Users" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_UserView_Views_FavoriteViewsId" FOREIGN KEY ("FavoriteViewsId") REFERENCES "Views" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "WebTemplateAccessToModelDefinitions" ( + "Id" uuid NOT NULL, + "WebTemplateId" uuid NOT NULL, + "ContentTypeId" uuid NOT NULL, + CONSTRAINT "PK_WebTemplateAccessToModelDefinitions" PRIMARY KEY ("Id"), + CONSTRAINT "FK_WebTemplateAccessToModelDefinitions_ContentTypes_ContentTyp~" FOREIGN KEY ("ContentTypeId") REFERENCES "ContentTypes" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_WebTemplateAccessToModelDefinitions_WebTemplates_WebTemplat~" FOREIGN KEY ("WebTemplateId") REFERENCES "WebTemplates" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "WebTemplateContentItemRelations" ( + "Id" uuid NOT NULL, + "WebTemplateId" uuid NOT NULL, + "ContentItemId" uuid NOT NULL, + CONSTRAINT "PK_WebTemplateContentItemRelations" PRIMARY KEY ("Id"), + CONSTRAINT "FK_WebTemplateContentItemRelations_ContentItems_ContentItemId" FOREIGN KEY ("ContentItemId") REFERENCES "ContentItems" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_WebTemplateContentItemRelations_WebTemplates_WebTemplateId" FOREIGN KEY ("WebTemplateId") REFERENCES "WebTemplates" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "WebTemplateRevisions" ( + "Id" uuid NOT NULL, + "Label" text, + "Content" text, + "WebTemplateId" uuid NOT NULL, + "AllowAccessForNewContentTypes" boolean NOT NULL, + "EmailTemplateId" uuid, + "CreationTime" timestamp with time zone NOT NULL, + "LastModificationTime" timestamp with time zone, + "CreatorUserId" uuid, + "LastModifierUserId" uuid, + CONSTRAINT "PK_WebTemplateRevisions" PRIMARY KEY ("Id"), + CONSTRAINT "FK_WebTemplateRevisions_EmailTemplates_EmailTemplateId" FOREIGN KEY ("EmailTemplateId") REFERENCES "EmailTemplates" ("Id"), + CONSTRAINT "FK_WebTemplateRevisions_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_WebTemplateRevisions_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id"), + CONSTRAINT "FK_WebTemplateRevisions_WebTemplates_WebTemplateId" FOREIGN KEY ("WebTemplateId") REFERENCES "WebTemplates" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "WebTemplateViewRelations" ( + "Id" uuid NOT NULL, + "WebTemplateId" uuid NOT NULL, + "ViewId" uuid NOT NULL, + CONSTRAINT "PK_WebTemplateViewRelations" PRIMARY KEY ("Id"), + CONSTRAINT "FK_WebTemplateViewRelations_Views_ViewId" FOREIGN KEY ("ViewId") REFERENCES "Views" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_WebTemplateViewRelations_WebTemplates_WebTemplateId" FOREIGN KEY ("WebTemplateId") REFERENCES "WebTemplates" ("Id") ON DELETE CASCADE +); + +CREATE UNIQUE INDEX "IX_ApiKeys_ApiKeyHash" ON "ApiKeys" ("ApiKeyHash"); + +CREATE INDEX "IX_ApiKeys_CreatorUserId" ON "ApiKeys" ("CreatorUserId"); + +CREATE INDEX "IX_ApiKeys_UserId" ON "ApiKeys" ("UserId"); + +CREATE INDEX "IX_AuditLogs_Category" ON "AuditLogs" ("Category"); + +CREATE INDEX "IX_AuditLogs_CreationTime" ON "AuditLogs" ("CreationTime"); + +CREATE INDEX "IX_AuditLogs_EntityId" ON "AuditLogs" ("EntityId"); + +CREATE INDEX "IX_AuthenticationSchemes_CreatorUserId" ON "AuthenticationSchemes" ("CreatorUserId"); + +CREATE UNIQUE INDEX "IX_AuthenticationSchemes_DeveloperName" ON "AuthenticationSchemes" ("DeveloperName"); + +CREATE INDEX "IX_AuthenticationSchemes_LastModifierUserId" ON "AuthenticationSchemes" ("LastModifierUserId"); + +CREATE INDEX "IX_ContentItemRevisions_ContentItemId" ON "ContentItemRevisions" ("ContentItemId"); + +CREATE INDEX "IX_ContentItemRevisions_CreatorUserId" ON "ContentItemRevisions" ("CreatorUserId"); + +CREATE INDEX "IX_ContentItemRevisions_LastModifierUserId" ON "ContentItemRevisions" ("LastModifierUserId"); + +CREATE INDEX "IX_ContentItems_ContentTypeId" ON "ContentItems" ("ContentTypeId"); + +CREATE INDEX "IX_ContentItems_CreatorUserId" ON "ContentItems" ("CreatorUserId"); + +CREATE INDEX "IX_ContentItems_LastModifierUserId" ON "ContentItems" ("LastModifierUserId"); + +CREATE UNIQUE INDEX "IX_ContentItems_RouteId" ON "ContentItems" ("RouteId"); + +CREATE INDEX "IX_ContentTypeFields_ContentTypeId" ON "ContentTypeFields" ("ContentTypeId"); + +CREATE INDEX "IX_ContentTypeFields_CreatorUserId" ON "ContentTypeFields" ("CreatorUserId"); + +CREATE INDEX "IX_ContentTypeFields_LastModifierUserId" ON "ContentTypeFields" ("LastModifierUserId"); + +CREATE INDEX "IX_ContentTypeFields_RelatedContentTypeId" ON "ContentTypeFields" ("RelatedContentTypeId"); + +CREATE INDEX "IX_ContentTypeRolePermission_ContentTypeId" ON "ContentTypeRolePermission" ("ContentTypeId"); + +CREATE INDEX "IX_ContentTypeRolePermission_CreatorUserId" ON "ContentTypeRolePermission" ("CreatorUserId"); + +CREATE INDEX "IX_ContentTypeRolePermission_LastModifierUserId" ON "ContentTypeRolePermission" ("LastModifierUserId"); + +CREATE INDEX "IX_ContentTypeRolePermission_RoleId" ON "ContentTypeRolePermission" ("RoleId"); + +CREATE INDEX "IX_ContentTypes_CreatorUserId" ON "ContentTypes" ("CreatorUserId"); + +CREATE INDEX "IX_ContentTypes_LastModifierUserId" ON "ContentTypes" ("LastModifierUserId"); + +CREATE INDEX "IX_DeletedContentItems_ContentTypeId" ON "DeletedContentItems" ("ContentTypeId"); + +CREATE INDEX "IX_DeletedContentItems_CreatorUserId" ON "DeletedContentItems" ("CreatorUserId"); + +CREATE INDEX "IX_DeletedContentItems_LastModifierUserId" ON "DeletedContentItems" ("LastModifierUserId"); + +CREATE INDEX "IX_EmailTemplateRevisions_CreatorUserId" ON "EmailTemplateRevisions" ("CreatorUserId"); + +CREATE INDEX "IX_EmailTemplateRevisions_EmailTemplateId" ON "EmailTemplateRevisions" ("EmailTemplateId"); + +CREATE INDEX "IX_EmailTemplateRevisions_LastModifierUserId" ON "EmailTemplateRevisions" ("LastModifierUserId"); + +CREATE INDEX "IX_EmailTemplates_CreatorUserId" ON "EmailTemplates" ("CreatorUserId"); + +CREATE UNIQUE INDEX "IX_EmailTemplates_DeveloperName" ON "EmailTemplates" ("DeveloperName"); + +CREATE INDEX "IX_EmailTemplates_LastModifierUserId" ON "EmailTemplates" ("LastModifierUserId"); + +CREATE UNIQUE INDEX "IX_JwtLogins_Jti" ON "JwtLogins" ("Jti"); + +CREATE INDEX "IX_MediaItems_CreatorUserId" ON "MediaItems" ("CreatorUserId"); + +CREATE INDEX "IX_MediaItems_LastModifierUserId" ON "MediaItems" ("LastModifierUserId"); + +CREATE INDEX "IX_MediaItems_ObjectKey" ON "MediaItems" ("ObjectKey"); + +CREATE INDEX "IX_NavigationMenuItems_CreatorUserId" ON "NavigationMenuItems" ("CreatorUserId"); + +CREATE INDEX "IX_NavigationMenuItems_LastModifierUserId" ON "NavigationMenuItems" ("LastModifierUserId"); + +CREATE INDEX "IX_NavigationMenuItems_NavigationMenuId" ON "NavigationMenuItems" ("NavigationMenuId"); + +CREATE INDEX "IX_NavigationMenuItems_ParentNavigationMenuItemId" ON "NavigationMenuItems" ("ParentNavigationMenuItemId"); + +CREATE INDEX "IX_NavigationMenuRevisions_CreatorUserId" ON "NavigationMenuRevisions" ("CreatorUserId"); + +CREATE INDEX "IX_NavigationMenuRevisions_LastModifierUserId" ON "NavigationMenuRevisions" ("LastModifierUserId"); + +CREATE INDEX "IX_NavigationMenuRevisions_NavigationMenuId" ON "NavigationMenuRevisions" ("NavigationMenuId"); + +CREATE INDEX "IX_NavigationMenus_CreatorUserId" ON "NavigationMenus" ("CreatorUserId"); + +CREATE UNIQUE INDEX "IX_NavigationMenus_DeveloperName" ON "NavigationMenus" ("DeveloperName"); + +CREATE INDEX "IX_NavigationMenus_LastModifierUserId" ON "NavigationMenus" ("LastModifierUserId"); + +CREATE INDEX "IX_OneTimePasswords_UserId" ON "OneTimePasswords" ("UserId"); + +CREATE INDEX "IX_RaythaFunctionRevisions_CreatorUserId" ON "RaythaFunctionRevisions" ("CreatorUserId"); + +CREATE INDEX "IX_RaythaFunctionRevisions_LastModifierUserId" ON "RaythaFunctionRevisions" ("LastModifierUserId"); + +CREATE INDEX "IX_RaythaFunctionRevisions_RaythaFunctionId" ON "RaythaFunctionRevisions" ("RaythaFunctionId"); + +CREATE INDEX "IX_RaythaFunctions_CreatorUserId" ON "RaythaFunctions" ("CreatorUserId"); + +CREATE UNIQUE INDEX "IX_RaythaFunctions_DeveloperName" ON "RaythaFunctions" ("DeveloperName"); + +CREATE INDEX "IX_RaythaFunctions_LastModifierUserId" ON "RaythaFunctions" ("LastModifierUserId"); + +CREATE INDEX "IX_Roles_CreatorUserId" ON "Roles" ("CreatorUserId"); + +CREATE UNIQUE INDEX "IX_Roles_DeveloperName" ON "Roles" ("DeveloperName"); + +CREATE INDEX "IX_Roles_LastModifierUserId" ON "Roles" ("LastModifierUserId"); + +CREATE INDEX "IX_RoleUser_UsersId" ON "RoleUser" ("UsersId"); + +CREATE UNIQUE INDEX "IX_Routes_Path" ON "Routes" ("Path"); + +CREATE INDEX "IX_ThemeAccessToMediaItems_MediaItemId" ON "ThemeAccessToMediaItems" ("MediaItemId"); + +CREATE INDEX "IX_ThemeAccessToMediaItems_ThemeId" ON "ThemeAccessToMediaItems" ("ThemeId"); + +CREATE INDEX "IX_Themes_CreatorUserId" ON "Themes" ("CreatorUserId"); + +CREATE UNIQUE INDEX "IX_Themes_DeveloperName" ON "Themes" ("DeveloperName"); + +CREATE INDEX "IX_Themes_LastModifierUserId" ON "Themes" ("LastModifierUserId"); + +CREATE INDEX "IX_UserGroups_CreatorUserId" ON "UserGroups" ("CreatorUserId"); + +CREATE UNIQUE INDEX "IX_UserGroups_DeveloperName" ON "UserGroups" ("DeveloperName"); + +CREATE INDEX "IX_UserGroups_LastModifierUserId" ON "UserGroups" ("LastModifierUserId"); + +CREATE INDEX "IX_Users_AuthenticationSchemeId" ON "Users" ("AuthenticationSchemeId"); + +CREATE INDEX "IX_Users_CreatorUserId" ON "Users" ("CreatorUserId"); + +CREATE UNIQUE INDEX "IX_Users_EmailAddress" ON "Users" ("EmailAddress"); + +CREATE INDEX "IX_Users_LastModifierUserId" ON "Users" ("LastModifierUserId"); + +CREATE UNIQUE INDEX "IX_Users_SsoId_AuthenticationSchemeId" ON "Users" ("SsoId", "AuthenticationSchemeId"); + +CREATE INDEX "IX_UserUserGroup_UsersId" ON "UserUserGroup" ("UsersId"); + +CREATE INDEX "IX_UserView_UserFavoritesId" ON "UserView" ("UserFavoritesId"); + +CREATE INDEX "IX_VerificationCodes_CreatorUserId" ON "VerificationCodes" ("CreatorUserId"); + +CREATE INDEX "IX_VerificationCodes_LastModifierUserId" ON "VerificationCodes" ("LastModifierUserId"); + +CREATE INDEX "IX_Views_ContentTypeId" ON "Views" ("ContentTypeId"); + +CREATE INDEX "IX_Views_CreatorUserId" ON "Views" ("CreatorUserId"); + +CREATE INDEX "IX_Views_LastModifierUserId" ON "Views" ("LastModifierUserId"); + +CREATE UNIQUE INDEX "IX_Views_RouteId" ON "Views" ("RouteId"); + +CREATE INDEX "IX_WebTemplateAccessToModelDefinitions_ContentTypeId" ON "WebTemplateAccessToModelDefinitions" ("ContentTypeId"); + +CREATE INDEX "IX_WebTemplateAccessToModelDefinitions_WebTemplateId" ON "WebTemplateAccessToModelDefinitions" ("WebTemplateId"); + +CREATE INDEX "IX_WebTemplateContentItemRelations_ContentItemId" ON "WebTemplateContentItemRelations" ("ContentItemId"); + +CREATE UNIQUE INDEX "IX_WebTemplateContentItemRelations_WebTemplateId_ContentItemId" ON "WebTemplateContentItemRelations" ("WebTemplateId", "ContentItemId"); + +CREATE INDEX "IX_WebTemplateRevisions_CreatorUserId" ON "WebTemplateRevisions" ("CreatorUserId"); + +CREATE INDEX "IX_WebTemplateRevisions_EmailTemplateId" ON "WebTemplateRevisions" ("EmailTemplateId"); + +CREATE INDEX "IX_WebTemplateRevisions_LastModifierUserId" ON "WebTemplateRevisions" ("LastModifierUserId"); + +CREATE INDEX "IX_WebTemplateRevisions_WebTemplateId" ON "WebTemplateRevisions" ("WebTemplateId"); + +CREATE INDEX "IX_WebTemplates_CreatorUserId" ON "WebTemplates" ("CreatorUserId"); + +CREATE UNIQUE INDEX "IX_WebTemplates_DeveloperName_ThemeId" ON "WebTemplates" ("DeveloperName", "ThemeId"); + +CREATE INDEX "IX_WebTemplates_LastModifierUserId" ON "WebTemplates" ("LastModifierUserId"); + +CREATE INDEX "IX_WebTemplates_ParentTemplateId" ON "WebTemplates" ("ParentTemplateId"); + +CREATE INDEX "IX_WebTemplates_ThemeId" ON "WebTemplates" ("ThemeId"); + +CREATE UNIQUE INDEX "IX_WebTemplateViewRelations_ViewId_WebTemplateId" ON "WebTemplateViewRelations" ("ViewId", "WebTemplateId"); + +CREATE INDEX "IX_WebTemplateViewRelations_WebTemplateId" ON "WebTemplateViewRelations" ("WebTemplateId"); + +ALTER TABLE "ApiKeys" ADD CONSTRAINT "FK_ApiKeys_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"); + +ALTER TABLE "ApiKeys" ADD CONSTRAINT "FK_ApiKeys_Users_UserId" FOREIGN KEY ("UserId") REFERENCES "Users" ("Id") ON DELETE CASCADE; + +ALTER TABLE "AuthenticationSchemes" ADD CONSTRAINT "FK_AuthenticationSchemes_Users_CreatorUserId" FOREIGN KEY ("CreatorUserId") REFERENCES "Users" ("Id"); + +ALTER TABLE "AuthenticationSchemes" ADD CONSTRAINT "FK_AuthenticationSchemes_Users_LastModifierUserId" FOREIGN KEY ("LastModifierUserId") REFERENCES "Users" ("Id"); + +INSERT INTO "NavigationMenus" ("Id", "Label", "DeveloperName", "IsMainMenu", "CreationTime") +VALUES ('ba0ccdb4-8fa5-4e83-86bd-cfcf083e09b1', 'Main menu', 'mainmenu', TRUE, TIMESTAMPTZ '2024-11-16T19:40:17.781995Z'); + +INSERT INTO "NavigationMenuItems" ("Id", "Label", "Url", "IsDisabled", "OpenInNewTab", "CssClassName", "Ordinal", "NavigationMenuId", "CreationTime") +VALUES ('29aea7ee-1df9-4516-87ea-2d13d51b77a8', 'Home', '/home', FALSE, FALSE, 'nav-link', 1, 'ba0ccdb4-8fa5-4e83-86bd-cfcf083e09b1', TIMESTAMPTZ '2024-11-16T19:40:17.782483Z'); +INSERT INTO "NavigationMenuItems" ("Id", "Label", "Url", "IsDisabled", "OpenInNewTab", "CssClassName", "Ordinal", "NavigationMenuId", "CreationTime") +VALUES ('02a9a0e4-8859-48de-b439-b4f893643a40', 'About', '/about', FALSE, FALSE, 'nav-link', 2, 'ba0ccdb4-8fa5-4e83-86bd-cfcf083e09b1', TIMESTAMPTZ '2024-11-16T19:40:17.782483Z'); +INSERT INTO "NavigationMenuItems" ("Id", "Label", "Url", "IsDisabled", "OpenInNewTab", "CssClassName", "Ordinal", "NavigationMenuId", "CreationTime") +VALUES ('70115076-6bff-4303-a876-8573b60d9210', 'Posts', '/posts', FALSE, FALSE, 'nav-link', 3, 'ba0ccdb4-8fa5-4e83-86bd-cfcf083e09b1', TIMESTAMPTZ '2024-11-16T19:40:17.782484Z'); + +INSERT INTO "Themes" ("Id", "Title", "DeveloperName", "IsExportable", "Description", "CreationTime") +VALUES ('e567f9ce-089f-403f-a399-211ac60cf2d1', 'Raytha default theme', 'raytha_default_theme', FALSE, 'Raytha default theme', TIMESTAMPTZ '2024-11-16T19:40:17.782485Z'); + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20241110181505_v1_4_0', '8.0.10'); + +COMMIT; + diff --git a/db/FreshCreateOnLatestVersion.sql b/db/SqlServer/FreshCreateOnLatestVersion.sql similarity index 92% rename from db/FreshCreateOnLatestVersion.sql rename to db/SqlServer/FreshCreateOnLatestVersion.sql index cf51f3eb..e18e606d 100644 --- a/db/FreshCreateOnLatestVersion.sql +++ b/db/SqlServer/FreshCreateOnLatestVersion.sql @@ -653,7 +653,7 @@ ALTER TABLE [AuthenticationSchemes] ADD CONSTRAINT [FK_AuthenticationSchemes_Use GO INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'20221230221303_v0_9_0', N'7.0.1'); +VALUES (N'20221230221303_v0_9_0', N'8.0.10'); GO COMMIT; @@ -704,7 +704,7 @@ CREATE INDEX [IX_ApiKeys_UserId] ON [ApiKeys] ([UserId]); GO INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'20230211205159_v1_0_0', N'7.0.1'); +VALUES (N'20230211205159_v1_0_0', N'8.0.10'); GO COMMIT; @@ -730,10 +730,6 @@ CREATE TABLE [BackgroundTasks] ( ); GO -INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'20230521175706_v1_1_0', N'7.0.1'); -GO - COMMIT; GO @@ -743,6 +739,16 @@ GO BEGIN TRANSACTION; GO +INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) +VALUES (N'20230521175706_v1_1_0', N'8.0.10'); +GO + +COMMIT; +GO + +BEGIN TRANSACTION; +GO + CREATE TABLE [RaythaFunctions] ( [Id] uniqueidentifier NOT NULL, [Name] nvarchar(max) NOT NULL, @@ -794,7 +800,7 @@ CREATE INDEX [IX_RaythaFunctions_LastModifierUserId] ON [RaythaFunctions] ([Last GO INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'20240314124844_v1_2_0', N'8.0.0'); +VALUES (N'20240314124844_v1_2_0', N'8.0.10'); GO COMMIT; @@ -888,7 +894,7 @@ GO IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'Label', N'DeveloperName', N'IsMainMenu', N'CreationTime') AND [object_id] = OBJECT_ID(N'[NavigationMenus]')) SET IDENTITY_INSERT [NavigationMenus] ON; INSERT INTO [NavigationMenus] ([Id], [Label], [DeveloperName], [IsMainMenu], [CreationTime]) -VALUES ('b49f9abf-8e2c-4c25-950c-0ced2f378a37', N'Main menu', N'mainmenu', CAST(1 AS bit), '2024-09-03T09:38:27.0216661Z'); +VALUES ('03ed3a83-d30d-4785-a882-eaac824b4cf5', N'Main menu', N'mainmenu', CAST(1 AS bit), '2024-11-16T19:33:33.8478785Z'); IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'Label', N'DeveloperName', N'IsMainMenu', N'CreationTime') AND [object_id] = OBJECT_ID(N'[NavigationMenus]')) SET IDENTITY_INSERT [NavigationMenus] OFF; GO @@ -896,9 +902,9 @@ GO IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'Label', N'Url', N'IsDisabled', N'OpenInNewTab', N'CssClassName', N'Ordinal', N'NavigationMenuId', N'CreationTime') AND [object_id] = OBJECT_ID(N'[NavigationMenuItems]')) SET IDENTITY_INSERT [NavigationMenuItems] ON; INSERT INTO [NavigationMenuItems] ([Id], [Label], [Url], [IsDisabled], [OpenInNewTab], [CssClassName], [Ordinal], [NavigationMenuId], [CreationTime]) -VALUES ('5982c677-5f8e-4134-8870-84227258f6e0', N'Home', N'/home', CAST(0 AS bit), CAST(0 AS bit), N'nav-link', 1, 'b49f9abf-8e2c-4c25-950c-0ced2f378a37', '2024-09-03T09:38:27.0222388Z'), -('ed7dfb20-e443-4212-8c24-4365d0d5f1e3', N'About', N'/about', CAST(0 AS bit), CAST(0 AS bit), N'nav-link', 2, 'b49f9abf-8e2c-4c25-950c-0ced2f378a37', '2024-09-03T09:38:27.0222392Z'), -('ac03cd99-5fb8-452d-9aa1-8047c040fcb2', N'Posts', N'/posts', CAST(0 AS bit), CAST(0 AS bit), N'nav-link', 3, 'b49f9abf-8e2c-4c25-950c-0ced2f378a37', '2024-09-03T09:38:27.0222398Z'); +VALUES ('b55bd326-8bc7-4210-af6e-9ed6cc85ca79', N'Home', N'/home', CAST(0 AS bit), CAST(0 AS bit), N'nav-link', 1, '03ed3a83-d30d-4785-a882-eaac824b4cf5', '2024-11-16T19:33:33.8484313Z'), +('aa4627f0-c3b6-4631-b097-913648fdc44b', N'About', N'/about', CAST(0 AS bit), CAST(0 AS bit), N'nav-link', 2, '03ed3a83-d30d-4785-a882-eaac824b4cf5', '2024-11-16T19:33:33.8484332Z'), +('b25bd839-95d6-45f4-b817-e14e3b64e048', N'Posts', N'/posts', CAST(0 AS bit), CAST(0 AS bit), N'nav-link', 3, '03ed3a83-d30d-4785-a882-eaac824b4cf5', '2024-11-16T19:33:33.8484335Z'); IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'Label', N'Url', N'IsDisabled', N'OpenInNewTab', N'CssClassName', N'Ordinal', N'NavigationMenuId', N'CreationTime') AND [object_id] = OBJECT_ID(N'[NavigationMenuItems]')) SET IDENTITY_INSERT [NavigationMenuItems] OFF; GO @@ -943,15 +949,15 @@ GO IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'Title', N'DeveloperName', N'IsExportable', N'Description', N'CreationTime') AND [object_id] = OBJECT_ID(N'[Themes]')) SET IDENTITY_INSERT [Themes] ON; INSERT INTO [Themes] ([Id], [Title], [DeveloperName], [IsExportable], [Description], [CreationTime]) -VALUES ('944ca79b-1ce5-47c4-8557-c8e6172df1dd', N'Raytha default theme', N'raytha_default_theme', CAST(0 AS bit), N'Raytha default theme', '2024-09-03T09:38:27.0238368Z'); +VALUES ('ee7046a6-4bba-40d6-a545-ebdb972167c6', N'Raytha default theme', N'raytha_default_theme', CAST(0 AS bit), N'Raytha default theme', '2024-11-16T19:33:33.8495914Z'); IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'Title', N'DeveloperName', N'IsExportable', N'Description', N'CreationTime') AND [object_id] = OBJECT_ID(N'[Themes]')) SET IDENTITY_INSERT [Themes] OFF; GO -ALTER TABLE [WebTemplates] ADD [ThemeId] uniqueidentifier NOT NULL DEFAULT '944ca79b-1ce5-47c4-8557-c8e6172df1dd'; +ALTER TABLE [WebTemplates] ADD [ThemeId] uniqueidentifier NOT NULL DEFAULT 'ee7046a6-4bba-40d6-a545-ebdb972167c6'; GO -ALTER TABLE [OrganizationSettings] ADD [ActiveThemeId] uniqueidentifier NOT NULL DEFAULT '944ca79b-1ce5-47c4-8557-c8e6172df1dd'; +ALTER TABLE [OrganizationSettings] ADD [ActiveThemeId] uniqueidentifier NOT NULL DEFAULT 'ee7046a6-4bba-40d6-a545-ebdb972167c6'; GO ALTER TABLE [ContentItems] DROP CONSTRAINT [FK_ContentItems_WebTemplates_WebTemplateId]; @@ -1064,13 +1070,84 @@ GO ALTER TABLE [WebTemplates] ADD CONSTRAINT [FK_WebTemplates_Themes_ThemeId] FOREIGN KEY ([ThemeId]) REFERENCES [Themes] ([Id]) ON DELETE CASCADE; GO +INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) +VALUES (N'20240502121207_v1_3_0', N'8.0.10'); +GO + +COMMIT; +GO + +BEGIN TRANSACTION; +GO + +DROP INDEX [IX_WebTemplates_DeveloperName_ThemeId] ON [WebTemplates]; +GO + +DROP INDEX [IX_Users_EmailAddress] ON [Users]; +GO + +DROP INDEX [IX_Users_SsoId_AuthenticationSchemeId] ON [Users]; +GO + +DROP INDEX [IX_UserGroups_DeveloperName] ON [UserGroups]; +GO + +DROP INDEX [IX_Routes_Path] ON [Routes]; +GO + +DROP INDEX [IX_Roles_DeveloperName] ON [Roles]; +GO + +DROP INDEX [IX_JwtLogins_Jti] ON [JwtLogins]; +GO + +DROP INDEX [IX_AuthenticationSchemes_DeveloperName] ON [AuthenticationSchemes]; +GO + +DECLARE @var3 sysname; +SELECT @var3 = [d].[name] +FROM [sys].[default_constraints] [d] +INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] +WHERE ([d].[parent_object_id] = OBJECT_ID(N'[EmailTemplates]') AND [c].[name] = N'DeveloperName'); +IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [EmailTemplates] DROP CONSTRAINT [' + @var3 + '];'); +ALTER TABLE [EmailTemplates] ALTER COLUMN [DeveloperName] nvarchar(450) NULL; +GO + +CREATE UNIQUE INDEX [IX_WebTemplates_DeveloperName_ThemeId] ON [WebTemplates] ([DeveloperName], [ThemeId]) WHERE [DeveloperName] IS NOT NULL; +GO + +CREATE UNIQUE INDEX [IX_Users_EmailAddress] ON [Users] ([EmailAddress]); +GO + +CREATE UNIQUE INDEX [IX_Users_SsoId_AuthenticationSchemeId] ON [Users] ([SsoId], [AuthenticationSchemeId]) WHERE [SsoId] IS NOT NULL AND [AuthenticationSchemeId] IS NOT NULL; +GO + +CREATE UNIQUE INDEX [IX_UserGroups_DeveloperName] ON [UserGroups] ([DeveloperName]); +GO + +CREATE UNIQUE INDEX [IX_Routes_Path] ON [Routes] ([Path]); +GO + +CREATE UNIQUE INDEX [IX_Roles_DeveloperName] ON [Roles] ([DeveloperName]); +GO + +CREATE UNIQUE INDEX [IX_JwtLogins_Jti] ON [JwtLogins] ([Jti]) WHERE [Jti] IS NOT NULL; +GO + +CREATE UNIQUE INDEX [IX_EmailTemplates_DeveloperName] ON [EmailTemplates] ([DeveloperName]) WHERE [DeveloperName] IS NOT NULL; +GO + +CREATE UNIQUE INDEX [IX_AuthenticationSchemes_DeveloperName] ON [AuthenticationSchemes] ([DeveloperName]) WHERE [DeveloperName] IS NOT NULL; +GO + INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) VALUES ('20221230221303_v0_9_0', 'FreshCreateOnLatestVersion'), ('20230211205159_v1_0_0', 'FreshCreateOnLatestVersion'), ('20230521175706_v1_1_0', 'FreshCreateOnLatestVersion'), ('20240314124844_v1_2_0', 'FreshCreateOnLatestVersion'), -('20240502121207_v1_3_0', 'FreshCreateOnLatestVersion'); +('20240502121207_v1_3_0', 'FreshCreateOnLatestVersion'), +('20241116192521_v1_4_0', 'FreshCreateOnLatestVersion'); GO COMMIT; diff --git a/db/v0_0_0_to_v0_9_0.sql b/db/SqlServer/v0_0_0_to_v0_9_0.sql similarity index 100% rename from db/v0_0_0_to_v0_9_0.sql rename to db/SqlServer/v0_0_0_to_v0_9_0.sql diff --git a/db/v0_9_0_to_v1_0_0.sql b/db/SqlServer/v0_9_0_to_v1_0_0.sql similarity index 100% rename from db/v0_9_0_to_v1_0_0.sql rename to db/SqlServer/v0_9_0_to_v1_0_0.sql diff --git a/db/v1_0_0_to_v1_1_0.sql b/db/SqlServer/v1_0_0_to_v1_1_0.sql similarity index 100% rename from db/v1_0_0_to_v1_1_0.sql rename to db/SqlServer/v1_0_0_to_v1_1_0.sql diff --git a/db/v1_1_0_to_v1_2_0.sql b/db/SqlServer/v1_1_0_to_v1_2_0.sql similarity index 100% rename from db/v1_1_0_to_v1_2_0.sql rename to db/SqlServer/v1_1_0_to_v1_2_0.sql diff --git a/db/v1_2_0_to_v1_3_0.sql b/db/SqlServer/v1_2_0_to_v1_3_0.sql similarity index 100% rename from db/v1_2_0_to_v1_3_0.sql rename to db/SqlServer/v1_2_0_to_v1_3_0.sql diff --git a/db/SqlServer/v1_3_0_to_v1_4_0.sql b/db/SqlServer/v1_3_0_to_v1_4_0.sql new file mode 100644 index 00000000..81f35125 --- /dev/null +++ b/db/SqlServer/v1_3_0_to_v1_4_0.sql @@ -0,0 +1,70 @@ +BEGIN TRANSACTION; +GO + +DROP INDEX [IX_WebTemplates_DeveloperName_ThemeId] ON [WebTemplates]; +GO + +DROP INDEX [IX_Users_EmailAddress] ON [Users]; +GO + +DROP INDEX [IX_Users_SsoId_AuthenticationSchemeId] ON [Users]; +GO + +DROP INDEX [IX_UserGroups_DeveloperName] ON [UserGroups]; +GO + +DROP INDEX [IX_Routes_Path] ON [Routes]; +GO + +DROP INDEX [IX_Roles_DeveloperName] ON [Roles]; +GO + +DROP INDEX [IX_JwtLogins_Jti] ON [JwtLogins]; +GO + +DROP INDEX [IX_AuthenticationSchemes_DeveloperName] ON [AuthenticationSchemes]; +GO + +DECLARE @var0 sysname; +SELECT @var0 = [d].[name] +FROM [sys].[default_constraints] [d] +INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] +WHERE ([d].[parent_object_id] = OBJECT_ID(N'[EmailTemplates]') AND [c].[name] = N'DeveloperName'); +IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [EmailTemplates] DROP CONSTRAINT [' + @var0 + '];'); +ALTER TABLE [EmailTemplates] ALTER COLUMN [DeveloperName] nvarchar(450) NULL; +GO + +CREATE UNIQUE INDEX [IX_WebTemplates_DeveloperName_ThemeId] ON [WebTemplates] ([DeveloperName], [ThemeId]) WHERE [DeveloperName] IS NOT NULL; +GO + +CREATE UNIQUE INDEX [IX_Users_EmailAddress] ON [Users] ([EmailAddress]); +GO + +CREATE UNIQUE INDEX [IX_Users_SsoId_AuthenticationSchemeId] ON [Users] ([SsoId], [AuthenticationSchemeId]) WHERE [SsoId] IS NOT NULL AND [AuthenticationSchemeId] IS NOT NULL; +GO + +CREATE UNIQUE INDEX [IX_UserGroups_DeveloperName] ON [UserGroups] ([DeveloperName]); +GO + +CREATE UNIQUE INDEX [IX_Routes_Path] ON [Routes] ([Path]); +GO + +CREATE UNIQUE INDEX [IX_Roles_DeveloperName] ON [Roles] ([DeveloperName]); +GO + +CREATE UNIQUE INDEX [IX_JwtLogins_Jti] ON [JwtLogins] ([Jti]) WHERE [Jti] IS NOT NULL; +GO + +CREATE UNIQUE INDEX [IX_EmailTemplates_DeveloperName] ON [EmailTemplates] ([DeveloperName]) WHERE [DeveloperName] IS NOT NULL; +GO + +CREATE UNIQUE INDEX [IX_AuthenticationSchemes_DeveloperName] ON [AuthenticationSchemes] ([DeveloperName]) WHERE [DeveloperName] IS NOT NULL; +GO + +INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) +VALUES (N'20241116192521_v1_4_0', N'8.0.10'); +GO + +COMMIT; +GO + diff --git a/src/Raytha.Application/Common/Interfaces/IRaythaDbContext.cs b/src/Raytha.Application/Common/Interfaces/IRaythaDbContext.cs index 6cd2f403..146ccfe4 100644 --- a/src/Raytha.Application/Common/Interfaces/IRaythaDbContext.cs +++ b/src/Raytha.Application/Common/Interfaces/IRaythaDbContext.cs @@ -3,7 +3,7 @@ namespace Raytha.Application.Common.Interfaces; -public interface IRaythaDbContext +public interface IRaythaDbContext { public DbSet Users { get; } public DbSet Roles { get; } diff --git a/src/Raytha.Application/Common/Utils/FilterConditionToODataUtility.cs b/src/Raytha.Application/Common/Utils/FilterConditionToODataUtility.cs index 3c037b59..3695d705 100644 --- a/src/Raytha.Application/Common/Utils/FilterConditionToODataUtility.cs +++ b/src/Raytha.Application/Common/Utils/FilterConditionToODataUtility.cs @@ -66,6 +66,14 @@ private string TranslateToODataExpression(FilterCondition condition) { expression.Append($"{condition.Field} {ConditionOperator.EQUALS} null"); } + else if (chosenColumnAsCustomField != null && chosenColumnAsCustomField.FieldType.DeveloperName == BaseFieldType.Date) + { + expression.Append($"{condition.Field} {ConditionOperator.EQUALS} null"); + } + else if (condition.Field == BuiltInContentTypeField.CreationTime || condition.Field == BuiltInContentTypeField.LastModificationTime) + { + expression.Append($"{condition.Field} {ConditionOperator.EQUALS} null"); + } else { expression.Append($"{condition.Field} {ConditionOperator.EQUALS} '' {BooleanOperator.OR} {condition.Field} {ConditionOperator.EQUALS} null"); @@ -81,6 +89,14 @@ private string TranslateToODataExpression(FilterCondition condition) { expression.Append($"{condition.Field} {ConditionOperator.NOT_EQUALS} null"); } + else if (chosenColumnAsCustomField != null && chosenColumnAsCustomField.FieldType.DeveloperName == BaseFieldType.Date) + { + expression.Append($"{condition.Field} {ConditionOperator.NOT_EQUALS} null"); + } + else if (condition.Field == BuiltInContentTypeField.CreationTime || condition.Field == BuiltInContentTypeField.LastModificationTime) + { + expression.Append($"{condition.Field} {ConditionOperator.NOT_EQUALS} null"); + } else { expression.Append($"({condition.Field} {ConditionOperator.NOT_EQUALS} '' {BooleanOperator.AND} {condition.Field} {ConditionOperator.NOT_EQUALS} null)"); diff --git a/src/Raytha.Domain/ValueObjects/FieldTypes/BaseFieldType.cs b/src/Raytha.Domain/ValueObjects/FieldTypes/BaseFieldType.cs index 86c56afc..8058bc85 100644 --- a/src/Raytha.Domain/ValueObjects/FieldTypes/BaseFieldType.cs +++ b/src/Raytha.Domain/ValueObjects/FieldTypes/BaseFieldType.cs @@ -113,6 +113,21 @@ public virtual string SqlServerLikeJsonValue(params string[] args) { return $" COALESCE(JSON_VALUE({args[0]}.{args[1]}, '$.{args[2]}'), '') COLLATE Latin1_General_CI_AS LIKE '{args[3]}' "; } + + public virtual string PostgresOrderByExpression(params string[] args) + { + return $" COALESCE({args[0]}.\"{args[1]}\"->>'{args[2]}', '') {args[3]} "; + } + + public virtual string PostgresSingleJsonValue(params string[] args) + { + return $" COALESCE({args[0]}.\"{args[1]}\"->>'{args[2]}', '')"; + } + + public virtual string PostgresLikeJsonValue(params string[] args) + { + return $" COALESCE({args[0]}.\"{args[1]}\"->>'{args[2]}', '') ILIKE '{args[3]}' "; + } } public abstract class EqualsOrNotEqualsFieldType : BaseFieldType @@ -189,14 +204,21 @@ public override IEnumerable SupportedConditionOperators public override string SqlServerOrderByExpression(params string[] args) { - return $" CASE WHEN ISNUMERIC(JSON_VALUE({args[0]}.{args[1]}, '$.{args[2]}')) = 1 THEN CAST(JSON_VALUE({args[0]}.{args[1]}, '$.{args[2]}') AS decimal) ELSE NULL END {args[3]}, JSON_VALUE({args[0]}.{args[1]}, '$.{args[2]}') {args[3]} "; + return $" CASE WHEN ISNUMERIC(JSON_VALUE({args[0]}.{args[1]}, '$.{args[2]}')) = 1 THEN CAST(JSON_VALUE({args[0]}.{args[1]}, '$.{args[2]}') AS decimal) ELSE NULL END {args[3]}, JSON_VALUE({args[0]}.{args[1]}, '$.{args[2]}') {args[3]} "; } public override string SqlServerSingleJsonValue(params string[] args) { - return $" TRY_CONVERT(decimal(18, 2), JSON_VALUE({args[0]}.{args[1]}, '$.{args[2]}')) "; + return $" TRY_CONVERT(decimal(18, 2), JSON_VALUE({args[0]}.{args[1]}, '$.{args[2]}')) "; } -} - + public override string PostgresOrderByExpression(params string[] args) + { + return $" CASE WHEN ({args[0]}.\"{args[1]}\"->>'{args[2]}') ~ '^[0-9]+(\\.[0-9]+)?$' THEN ({args[0]}.\"{args[1]}\"->> '{args[2]}')::decimal ELSE NULL END {args[3]}, {args[0]}.\"{args[1]}\"->>'{args[2]}' {args[3]} "; + } + public override string PostgresSingleJsonValue(params string[] args) + { + return $" CASE WHEN ({args[0]}.\"{args[1]}\"->>'{args[2]}') ~ '^[0-9]+(\\.[0-9]+)?$' THEN ({args[0]}.\"{args[1]}\"->> '{args[2]}')::decimal(18, 2) ELSE NULL END"; + } +} diff --git a/src/Raytha.Domain/ValueObjects/FieldTypes/CheckboxFieldType.cs b/src/Raytha.Domain/ValueObjects/FieldTypes/CheckboxFieldType.cs index 4bf721a6..5ad688d6 100644 --- a/src/Raytha.Domain/ValueObjects/FieldTypes/CheckboxFieldType.cs +++ b/src/Raytha.Domain/ValueObjects/FieldTypes/CheckboxFieldType.cs @@ -19,9 +19,4 @@ public override BaseFieldValue FieldValueFrom(dynamic value) { return new BooleanFieldValue(value); } - - public override string SqlServerOrderByExpression(params string[] args) - { - return $"JSON_VALUE({args[0]}.{args[1]}, '$.{args[2]}') {args[3]}"; - } } diff --git a/src/Raytha.Domain/ValueObjects/FieldTypes/DateFieldType.cs b/src/Raytha.Domain/ValueObjects/FieldTypes/DateFieldType.cs index 062c0eb6..b4996a6f 100644 --- a/src/Raytha.Domain/ValueObjects/FieldTypes/DateFieldType.cs +++ b/src/Raytha.Domain/ValueObjects/FieldTypes/DateFieldType.cs @@ -26,8 +26,43 @@ public override BaseFieldValue FieldValueFrom(dynamic value) return new DateTimeFieldValue(value); } + public override string SqlServerSingleJsonValue(params string[] args) + { + int sqlDateOutput = args[3] switch { + "MM/dd/yyyy" => 101, + "dd/MM/yyyy" => 103, + _ => 0 + }; + return $" TRY_CONVERT(datetime, JSON_VALUE({args[0]}.{args[1]}, '$.{args[2]}'), {sqlDateOutput}) "; + } + public override string SqlServerOrderByExpression(params string[] args) { - return $"TRY_CONVERT(datetime, JSON_VALUE({args[0]}.{args[1]}, '$.{args[2]}') {args[3]}) {args[4]}"; + int sqlDateOutput = args[3] switch { + "MM/dd/yyyy" => 101, + "dd/MM/yyyy" => 103, + _ => 0 + }; + return $" TRY_CONVERT(datetime, JSON_VALUE({args[0]}.{args[1]}, '$.{args[2]}'), {sqlDateOutput}) {args[4]} "; + } + + public override string PostgresSingleJsonValue(params string[] args) + { + string dateFormat = args[3].ToUpper(); //US or UK format + return $@" + TO_DATE( + NULLIF({args[0]}.""{args[1]}""->>'{args[2]}', ''), + '{dateFormat}' + )"; + } + public override string PostgresOrderByExpression(params string[] args) + { + string dateFormat = args[3].ToUpper(); //US or UK format + string sortOrder = args[4]?.ToUpper() == "DESC" ? "DESC" : "ASC"; // Default to ASC if not provided + return $@" + TO_DATE( + NULLIF({args[0]}.""{args[1]}""->>'{args[2]}', ''), + '{dateFormat}' + ) {sortOrder}"; } } diff --git a/src/Raytha.Domain/ValueObjects/FieldTypes/MultipleSelectFieldType.cs b/src/Raytha.Domain/ValueObjects/FieldTypes/MultipleSelectFieldType.cs index 16452ad6..b4ce296b 100644 --- a/src/Raytha.Domain/ValueObjects/FieldTypes/MultipleSelectFieldType.cs +++ b/src/Raytha.Domain/ValueObjects/FieldTypes/MultipleSelectFieldType.cs @@ -37,4 +37,21 @@ public override string SqlServerLikeJsonValue(params string[] args) return $" ((ISJSON(JSON_QUERY({args[0]}.{args[1]}, '$.{args[2]}'))) = 1 AND EXISTS (SELECT * FROM OPENJSON({args[0]}.{args[1]}, '$.{args[2]}') as temp WHERE temp.value = '{args[3]}'))"; } } + + public override string PostgresOrderByExpression(params string[] args) + { + return $" COALESCE((SELECT value from jsonb_array_elements_text({args[0]}.\"{args[1]}\"->'{args[2]}') AS value LIMIT 1), '') {args[3]} "; + } + + public override string PostgresLikeJsonValue(params string[] args) + { + if (args[3] == "[]") + { + return $"(({args[0]}.\"{args[1]}\"->'{args[2]}') IS NULL OR NOT EXISTS (SELECT 1 FROM jsonb_array_elements_text({args[0]}.\"{args[1]}\"->'{args[2]}')))"; + } + else + { + return $"(({args[0]}.\"{args[1]}\"->'{args[2]}') IS NOT NULL AND EXISTS (SELECT 1 FROM jsonb_array_elements_text({args[0]}.\"{args[1]}\"->'{args[2]}') AS item WHERE item = '{args[3]}'))"; + } + } } \ No newline at end of file diff --git a/src/Raytha.Infrastructure/BackgroundTasks/BackgroundTaskDb.cs b/src/Raytha.Infrastructure/BackgroundTasks/BackgroundTaskDb.cs index bacd5eaa..7d056f80 100644 --- a/src/Raytha.Infrastructure/BackgroundTasks/BackgroundTaskDb.cs +++ b/src/Raytha.Infrastructure/BackgroundTasks/BackgroundTaskDb.cs @@ -1,6 +1,8 @@ using Dapper; +using Microsoft.Extensions.Configuration; using Raytha.Application.Common.Interfaces; using Raytha.Domain.Entities; +using Raytha.Infrastructure.Persistence; using System.Data; namespace Raytha.Infrastructure.BackgroundTasks; @@ -8,13 +10,16 @@ namespace Raytha.Infrastructure.BackgroundTasks; public class BackgroundTaskDb : IBackgroundTaskDb { private readonly IDbConnection _db; - public BackgroundTaskDb(IDbConnection db) + private readonly IConfiguration _configuration; + public BackgroundTaskDb(IDbConnection db, IConfiguration configuration) { _db = db; + _configuration = configuration; } public BackgroundTask DequeueBackgroundTask() { + var dbProvider = DbProviderHelper.GetDatabaseProviderTypeFromConnectionString(_configuration.GetConnectionString("DefaultConnection")); BackgroundTask bgTask; if (_db.State == ConnectionState.Closed) { @@ -22,10 +27,21 @@ public BackgroundTask DequeueBackgroundTask() } using (var transaction = _db.BeginTransaction()) { - bgTask = _db.QueryFirstOrDefault("SELECT * FROM BackgroundTasks WITH (readpast, updlock) WHERE Status = @status ORDER BY CreationTime ASC", new { status = BackgroundTaskStatus.Enqueued.DeveloperName }, transaction: transaction); - if (bgTask != null) + if (dbProvider == DatabaseProviderType.Postgres) { - _db.Execute("UPDATE BackgroundTasks SET Status = @status WHERE Id = @id", new { status = BackgroundTaskStatus.Processing.DeveloperName, id = bgTask.Id }, transaction: transaction); + bgTask = _db.QueryFirstOrDefault("SELECT * FROM \"BackgroundTasks\" WHERE \"Status\" = @status ORDER BY \"CreationTime\" ASC FOR UPDATE SKIP LOCKED", new { status = BackgroundTaskStatus.Enqueued.DeveloperName }, transaction: transaction); + if (bgTask != null) + { + _db.Execute("UPDATE \"BackgroundTasks\" SET \"Status\" = @status WHERE \"Id\" = @id", new { status = BackgroundTaskStatus.Processing.DeveloperName, id = bgTask.Id }, transaction: transaction); + } + } + else + { + bgTask = _db.QueryFirstOrDefault("SELECT * FROM BackgroundTasks WITH (readpast, updlock) WHERE Status = @status ORDER BY CreationTime ASC", new { status = BackgroundTaskStatus.Enqueued.DeveloperName }, transaction: transaction); + if (bgTask != null) + { + _db.Execute("UPDATE BackgroundTasks SET Status = @status WHERE Id = @id", new { status = BackgroundTaskStatus.Processing.DeveloperName, id = bgTask.Id }, transaction: transaction); + } } transaction.Commit(); } diff --git a/src/Raytha.Infrastructure/ConfigureServices.cs b/src/Raytha.Infrastructure/ConfigureServices.cs index cc57a726..ae391fa1 100644 --- a/src/Raytha.Infrastructure/ConfigureServices.cs +++ b/src/Raytha.Infrastructure/ConfigureServices.cs @@ -13,6 +13,8 @@ using Raytha.Infrastructure.Configurations; using Raytha.Infrastructure.RaythaFunctions; using Raytha.Infrastructure.JsonQueryEngine.SqlServer; +using Npgsql; +using Raytha.Infrastructure.JsonQueryEngine.Postgres; namespace Microsoft.Extensions.DependencyInjection; @@ -22,29 +24,44 @@ public static IServiceCollection AddInfrastructureServices(this IServiceCollecti { var dbConnectionString = configuration.GetConnectionString("DefaultConnection"); - //entity framework + var dbProviderType = DbProviderHelper.GetDatabaseProviderTypeFromConnectionString(dbConnectionString); + services.AddScoped(); - services.AddDbContext(options => + + if (dbProviderType == DatabaseProviderType.Postgres) { - options.UseSqlServer(dbConnectionString, sqlServerOptions => + services.AddDbContext(options => { - sqlServerOptions.EnableRetryOnFailure( - maxRetryCount: 5 - ); + options.UseNpgsql(dbConnectionString, npgsqlOptions => + { + npgsqlOptions.EnableRetryOnFailure(maxRetryCount: 5); + npgsqlOptions.MigrationsAssembly("Raytha.Migrations.Postgres"); + }); }); - }); - - services.AddScoped(provider => provider.GetRequiredService()); - - //direct to db - services.AddTransient((sp) => new SqlConnection(dbConnectionString)); + services.AddTransient(); + services.AddTransient(_ => new NpgsqlConnection(dbConnectionString)); + services.AddScoped(provider => provider.GetRequiredService()); + } + else + { + services.AddDbContext(options => + { + options.UseSqlServer(dbConnectionString, sqlServerOptions => + { + sqlServerOptions.EnableRetryOnFailure(maxRetryCount: 5); + sqlServerOptions.MigrationsAssembly("Raytha.Migrations.SqlServer"); + }); + }); + services.AddTransient(); + services.AddTransient(_ => new SqlConnection(dbConnectionString)); + services.AddScoped(provider => provider.GetRequiredService()); + } services.AddSingleton(); services.AddSingleton(); services.AddScoped(); services.AddScoped(); - services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -78,6 +95,7 @@ public static IServiceCollection AddInfrastructureServices(this IServiceCollecti services.AddScoped(); services.AddSingleton(); + return services; } } \ No newline at end of file diff --git a/src/Raytha.Infrastructure/JsonQueryEngine/AbstractODataFilterToSql.cs b/src/Raytha.Infrastructure/JsonQueryEngine/AbstractODataFilterToSql.cs index 506686d5..9fb19c57 100644 --- a/src/Raytha.Infrastructure/JsonQueryEngine/AbstractODataFilterToSql.cs +++ b/src/Raytha.Infrastructure/JsonQueryEngine/AbstractODataFilterToSql.cs @@ -14,6 +14,7 @@ internal abstract class AbstractODataFilterToSql protected ContentType _contentType; protected string _primaryFieldName; protected IEnumerable _relatedObjectFields; + protected string _dateTimeFormat; protected string placeholderClassName = typeof(PlaceholderClass).Name; @@ -38,6 +39,7 @@ protected abstract class AbstractODataFilterToSqlVisitor : QueryNodeVis protected StringBuilder whereClause = new StringBuilder(); protected ContentType _contentType; protected string _primaryFieldName; + protected string _dateTimeFormat; protected IEnumerable _relatedObjectFields; protected abstract void HandleSingleValueProperty(string realFieldName); diff --git a/src/Raytha.Infrastructure/JsonQueryEngine/AbstractRaythaDbJsonQueryEngine.cs b/src/Raytha.Infrastructure/JsonQueryEngine/AbstractRaythaDbJsonQueryEngine.cs index 4beefdb2..9c20468f 100644 --- a/src/Raytha.Infrastructure/JsonQueryEngine/AbstractRaythaDbJsonQueryEngine.cs +++ b/src/Raytha.Infrastructure/JsonQueryEngine/AbstractRaythaDbJsonQueryEngine.cs @@ -2,6 +2,7 @@ using Raytha.Application.ContentItems; using Raytha.Domain.Entities; using Raytha.Domain.ValueObjects.FieldTypes; +using System.Data; using System.Text.Json; namespace Raytha.Infrastructure.JsonQueryEngine; @@ -12,40 +13,14 @@ internal abstract class AbstractRaythaDbJsonQueryEngine protected List OneToOneRelationshipFields => ContentType.ContentTypeFields.Where(p => p.FieldType.DeveloperName == BaseFieldType.OneToOneRelationship && p.RelatedContentTypeId.HasValue).ToList(); protected string PrimaryFieldDeveloperName => ContentType.ContentTypeFields.First(p => p.Id == ContentType.PrimaryFieldId).DeveloperName; - protected virtual SqlQueryBuilder PrepareContentItemsDataSelect(SqlQueryBuilder sqlBuilder) - { - sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.ContentItemColumns(), RawSqlColumn.SOURCE_ITEM_COLUMN_NAME).ToArray()); - sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.RouteColumns(), RawSqlColumn.ROUTE_COLUMN_NAME).ToArray()); - sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.UserColumns(), RawSqlColumn.SOURCE_CREATED_BY_COLUMN_NAME).ToArray()); - sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.UserColumns(), RawSqlColumn.SOURCE_MODIFIED_BY_COLUMN_NAME).ToArray()); - foreach (var item in OneToOneRelationshipFields) - { - int index = OneToOneRelationshipFields.IndexOf(item); - sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.ContentItemColumns(), $"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}").ToArray()); - sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.RouteColumns(), $"{RawSqlColumn.RELATED_ROUTE_COLUMN_NAME}_{index}").ToArray()); - sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.UserColumns(), $"{RawSqlColumn.RELATED_CREATED_BY_COLUMN_NAME}_{index}").ToArray()); - sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.UserColumns(), $"{RawSqlColumn.RELATED_MODIFIED_BY_COLUMN_NAME}_{index}").ToArray()); - } - return sqlBuilder; - } - - protected virtual SqlQueryBuilder PrepareFrom(SqlQueryBuilder sqlBuilder) - { - sqlBuilder.From($"{RawSqlColumn.CONTENT_ITEM_TABLE_NAME} AS {RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}"); - foreach (var item in OneToOneRelationshipFields) - { - int index = OneToOneRelationshipFields.IndexOf(item); - sqlBuilder.Join($"{RawSqlColumn.CONTENT_ITEM_TABLE_NAME} AS {RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}", $"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}.{RawSqlColumn.Id.Name} = JSON_VALUE({RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.{RawSqlColumn.PublishedContent.Name}, '$.{item.DeveloperName?.ToDeveloperName()}')", joinType: "LEFT"); - sqlBuilder.Join($"{RawSqlColumn.USERS_TABLE_NAME} AS {RawSqlColumn.RELATED_CREATED_BY_COLUMN_NAME}_{index}", $"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}.{RawSqlColumn.CreatorUserId.Name} = {RawSqlColumn.RELATED_CREATED_BY_COLUMN_NAME}_{index}.{RawSqlColumn.Id.Name}", joinType: "LEFT"); - sqlBuilder.Join($"{RawSqlColumn.USERS_TABLE_NAME} AS {RawSqlColumn.RELATED_MODIFIED_BY_COLUMN_NAME}_{index}", $"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}.{RawSqlColumn.LastModifierUserId.Name} = {RawSqlColumn.RELATED_MODIFIED_BY_COLUMN_NAME}_{index}.{RawSqlColumn.Id.Name}", joinType: "LEFT"); - sqlBuilder.Join($"{RawSqlColumn.ROUTES_TABLE_NAME} AS {RawSqlColumn.RELATED_ROUTE_COLUMN_NAME}_{index}", $"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}.{RawSqlColumn.RouteId.Name} = {RawSqlColumn.RELATED_ROUTE_COLUMN_NAME}_{index}.{RawSqlColumn.Id.Name}", joinType: "LEFT"); - } - sqlBuilder.Join($"{RawSqlColumn.ROUTES_TABLE_NAME} AS {RawSqlColumn.ROUTE_COLUMN_NAME} ", $"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.{RawSqlColumn.RouteId.Name} = {RawSqlColumn.ROUTE_COLUMN_NAME}.{RawSqlColumn.Id.Name}", joinType: "LEFT"); - sqlBuilder.Join($"{RawSqlColumn.USERS_TABLE_NAME} AS {RawSqlColumn.SOURCE_CREATED_BY_COLUMN_NAME}", $"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.{RawSqlColumn.CreatorUserId.Name} = {RawSqlColumn.SOURCE_CREATED_BY_COLUMN_NAME}.{RawSqlColumn.Id.Name}", joinType: "LEFT"); - sqlBuilder.Join($"{RawSqlColumn.USERS_TABLE_NAME} AS {RawSqlColumn.SOURCE_MODIFIED_BY_COLUMN_NAME}", $"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.{RawSqlColumn.LastModifierUserId.Name} = {RawSqlColumn.SOURCE_MODIFIED_BY_COLUMN_NAME}.{RawSqlColumn.Id.Name}", joinType: "LEFT"); - - return sqlBuilder; - } + public abstract ContentItem FirstOrDefault(Guid entityId); + public abstract IEnumerable QueryContentItems(Guid contentTypeId, string[] searchOnColumns, string search, string[] filters, int pageSize, int pageNumber, string orderBy, IDbTransaction transaction = null); + public abstract IEnumerable QueryAllContentItemsAsTransaction(Guid contentTypeId, string[] searchOnColumns, string search, string[] filters, string orderBy); + public abstract int CountContentItems(Guid contentTypeId, string[] searchOnColumns, string search, string[] filters, IDbTransaction transaction = null); + protected abstract SqlQueryBuilder PrepareContentItemsDataSelect(SqlQueryBuilder sqlBuilder); + protected abstract SqlQueryBuilder PrepareFrom(SqlQueryBuilder sqlBuilder); + protected abstract SqlQueryBuilder PrepareSearch(SqlQueryBuilder sqlBuilder, string search, string[] searchOnColumns = null); + protected abstract SqlQueryBuilder PrepareOrderBy(SqlQueryBuilder sqlBuilder, string orderBy); protected ContentItem MapQueryItemToContentItem(IDictionary resultFromQuery) { diff --git a/src/Raytha.Infrastructure/JsonQueryEngine/Postgres/ODataFilterToPostgres.cs b/src/Raytha.Infrastructure/JsonQueryEngine/Postgres/ODataFilterToPostgres.cs new file mode 100644 index 00000000..8cab8df6 --- /dev/null +++ b/src/Raytha.Infrastructure/JsonQueryEngine/Postgres/ODataFilterToPostgres.cs @@ -0,0 +1,120 @@ +using Microsoft.OData.Edm; +using Microsoft.OData.UriParser; +using Raytha.Application.Common.Utils; +using Raytha.Domain.Entities; +using Raytha.Domain.ValueObjects.FieldTypes; + +namespace Raytha.Infrastructure.JsonQueryEngine.Postgres; + +internal class ODataFilterToPostgres : AbstractODataFilterToSql +{ + public ODataFilterToPostgres(ContentType contentType, string primaryFieldName, IEnumerable relatedObjectFields, string dateTimeFormat) + { + _contentType = contentType; + _primaryFieldName = primaryFieldName; + _relatedObjectFields = relatedObjectFields; + _dateTimeFormat = dateTimeFormat; + } + + public override string GenerateSql(string filterExpression) + { + if (string.IsNullOrEmpty(filterExpression)) + return string.Empty; + + Dictionary odataOptionsAsDictionary = new Dictionary + { + {"$filter", filterExpression } + }; + + IEdmModel edmModel = GetEdmModel(); + IEdmNavigationSource edmNavigationSource = edmModel.FindDeclaredEntitySet(placeholderClassName); + IEdmType edmType = edmNavigationSource.Type; + + ODataQueryOptionParser parser = new ODataQueryOptionParser(edmModel, edmType, edmNavigationSource, odataOptionsAsDictionary); + + FilterClause parsedODataFilterClause = parser.ParseFilter(); + + ODataFilterToSqlVisitor visitor = new ODataFilterToSqlVisitor(_contentType, _primaryFieldName, _relatedObjectFields, _dateTimeFormat); + parsedODataFilterClause.Expression.Accept(visitor); + + string whereClause = visitor.GetWhereClause(); + return whereClause; + } + + private class ODataFilterToSqlVisitor : AbstractODataFilterToSqlVisitor where TSource : class + { + public ODataFilterToSqlVisitor(ContentType contentType, string primaryFieldName, IEnumerable relatedObjectFields, string dateTimeFormat) + { + _contentType = contentType; + _primaryFieldName = primaryFieldName; + _relatedObjectFields = relatedObjectFields; + _dateTimeFormat = dateTimeFormat; + } + + public override TSource Visit(SingleValueFunctionCallNode nodeIn) + { + string functionName = nodeIn.Name; + SingleValueOpenPropertyAccessNode fieldName = ((ConvertNode)nodeIn.Parameters.ToArray()[0]).Source as SingleValueOpenPropertyAccessNode; + ConstantNode value = nodeIn.Parameters.ToArray()[1] as ConstantNode; + + var realFieldName = UseDeveloperNameForPrimaryField(fieldName.Name); + + if (BuiltInContentTypeField.ReservedContentTypeFields.Any(p => p.DeveloperName == realFieldName)) + { + string prefix = $"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.\"{realFieldName}\" ILIKE"; + whereClause.Append($"{prefix} {value.Value.ToString().ApplySqlStringLikeOperator}"); + } + else + { + var chosenColumnAsCustomField = _contentType.ContentTypeFields.FirstOrDefault(p => p.DeveloperName == realFieldName); + if (chosenColumnAsCustomField.FieldType.DeveloperName == BaseFieldType.OneToOneRelationship) + { + var relatedObjectField = _relatedObjectFields.First(p => p.DeveloperName == chosenColumnAsCustomField.DeveloperName); + int indexOfRelatedObject = _relatedObjectFields.ToList().IndexOf(relatedObjectField); + string relatedObjPrimaryFieldName = relatedObjectField.ContentType.ContentTypeFields.First(p => p.Id == relatedObjectField.ContentType.PrimaryFieldId).DeveloperName; + whereClause.Append(chosenColumnAsCustomField.FieldType.PostgresLikeJsonValue($"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{indexOfRelatedObject}", RawSqlColumn.PublishedContent.Name, relatedObjPrimaryFieldName, value.Value.ToString().ApplySqlStringLikeOperator(functionName))); + } + else if (chosenColumnAsCustomField.FieldType.DeveloperName == BaseFieldType.MultipleSelect) + { + if (functionName != "contains") + throw new NotImplementedException($"{functionName} is not an implemented function call."); + + whereClause.Append(chosenColumnAsCustomField.FieldType.PostgresLikeJsonValue(RawSqlColumn.SOURCE_ITEM_COLUMN_NAME, RawSqlColumn.PublishedContent.Name, realFieldName, value.Value.ToString())); + } + else + { + whereClause.Append(chosenColumnAsCustomField.FieldType.PostgresLikeJsonValue(RawSqlColumn.SOURCE_ITEM_COLUMN_NAME, RawSqlColumn.PublishedContent.Name, realFieldName, value.Value.ToString().ApplySqlStringLikeOperator(functionName))); + } + } + + return null; + } + + protected override void HandleSingleValueProperty(string realFieldName) + { + if (BuiltInContentTypeField.ReservedContentTypeFields.Any(p => p.DeveloperName == realFieldName)) + { + whereClause.Append($" {RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.\"{realFieldName}\" "); + } + else + { + var chosenColumnAsCustomField = _contentType.ContentTypeFields.FirstOrDefault(p => p.DeveloperName == realFieldName); + if (chosenColumnAsCustomField.FieldType.DeveloperName == BaseFieldType.OneToOneRelationship) + { + var relatedObjectField = _relatedObjectFields.First(p => p.DeveloperName == chosenColumnAsCustomField.DeveloperName); + int indexOfRelatedObject = _relatedObjectFields.ToList().IndexOf(relatedObjectField); + string relatedObjPrimaryFieldName = relatedObjectField.ContentType.ContentTypeFields.First(p => p.Id == relatedObjectField.ContentType.PrimaryFieldId).DeveloperName; + whereClause.Append(chosenColumnAsCustomField.FieldType.PostgresSingleJsonValue($"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{indexOfRelatedObject}", RawSqlColumn.PublishedContent.Name, relatedObjPrimaryFieldName)); + } + else if (chosenColumnAsCustomField.FieldType.DeveloperName == BaseFieldType.Date) + { + whereClause.Append(chosenColumnAsCustomField.FieldType.PostgresSingleJsonValue(RawSqlColumn.SOURCE_ITEM_COLUMN_NAME, RawSqlColumn.PublishedContent.Name, realFieldName, _dateTimeFormat)); + } + else + { + whereClause.Append(chosenColumnAsCustomField.FieldType.PostgresSingleJsonValue(RawSqlColumn.SOURCE_ITEM_COLUMN_NAME, RawSqlColumn.PublishedContent.Name, realFieldName)); + } + } + } + } +} diff --git a/src/Raytha.Infrastructure/JsonQueryEngine/Postgres/RaythaDbPostgresJsonQueryEngine.cs b/src/Raytha.Infrastructure/JsonQueryEngine/Postgres/RaythaDbPostgresJsonQueryEngine.cs new file mode 100644 index 00000000..65003aec --- /dev/null +++ b/src/Raytha.Infrastructure/JsonQueryEngine/Postgres/RaythaDbPostgresJsonQueryEngine.cs @@ -0,0 +1,393 @@ +using CSharpVitamins; +using Dapper; +using Microsoft.EntityFrameworkCore; +using Raytha.Application.Common.Interfaces; +using Raytha.Application.Common.Utils; +using Raytha.Domain.Entities; +using Raytha.Domain.ValueObjects.FieldTypes; +using System.Data; + +namespace Raytha.Infrastructure.JsonQueryEngine.Postgres; + +internal class RaythaDbPostgresJsonQueryEngine : AbstractRaythaDbJsonQueryEngine, IRaythaDbJsonQueryEngine +{ + public readonly IRaythaDbContext _entityFramework; + public readonly IDbConnection _db; + public readonly ICurrentOrganization _currentOrganization; + + public RaythaDbPostgresJsonQueryEngine(IRaythaDbContext entityFramework, IDbConnection db, ICurrentOrganization currentOrganization) + { + _entityFramework = entityFramework; + _db = db; + _currentOrganization = currentOrganization; + } + + public override ContentItem FirstOrDefault(Guid entityId) + { + //Check if it exists at all, and if so, get the ContentType + var entity = _entityFramework.ContentItems + .Include(p => p.ContentType) + .ThenInclude(p => p.ContentTypeFields) + .ThenInclude(p => p.RelatedContentType) + .ThenInclude(p => p.ContentTypeFields) + .FirstOrDefault(p => p.Id == entityId); + + if (entity == null) + return null; + + ContentType = entity.ContentType; + + //Assemble the SQL select and from statements + var sqlBuilder = PrepareFrom(PrepareContentItemsDataSelect(new SqlQueryBuilder())); + + //Attach the where clause to get just this specific item + sqlBuilder.AndWhere($"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.\"{RawSqlColumn.Id.Name}\" = '{entityId}'"); + + var sqlStatement = sqlBuilder.Build(); + + IDictionary resultFromQuery = _db.QuerySingle(sqlStatement); + if (resultFromQuery == null) + return null; + + var contentItem = MapQueryItemToContentItem(resultFromQuery); + return contentItem; + } + + public override IEnumerable QueryContentItems(Guid contentTypeId, string[] searchOnColumns, string search, string[] filters, int pageSize, int pageNumber, string orderBy, IDbTransaction transaction = null) + { + //get the content type being queried + var contentType = _entityFramework.ContentTypes + .Include(p => p.ContentTypeFields) + .ThenInclude(p => p.RelatedContentType) + .ThenInclude(p => p.ContentTypeFields) + .First(p => p.Id == contentTypeId); + + ContentType = contentType; + + //Assemble the SQL select and from statements + var sqlBuilder = PrepareFrom(PrepareContentItemsDataSelect(new SqlQueryBuilder())); + + //Attach the where clause to filter by this content type + sqlBuilder.AndWhere($"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.\"{RawSqlColumn.ContentTypeId.Name}\" = '{contentTypeId}'"); + + //Attach where clauses to that filter by a search query + sqlBuilder = PrepareSearch(sqlBuilder, search, searchOnColumns); + + //Attach where clauses for odata filters + sqlBuilder = PrepareODataFilters(sqlBuilder, filters); + + //Attach order by clauses + sqlBuilder = PrepareOrderBy(sqlBuilder, orderBy); + + //Attach pagination + pageNumber = pageNumber <= 1 ? 0 : pageNumber - 1; + int skip = pageNumber * pageSize; + + var rawSql = $"{sqlBuilder.Build()} LIMIT {pageSize} OFFSET {skip}"; + + var resultFromQuery = (IEnumerable>)_db.Query(rawSql, new { search = $"%{search}%", exactsearch = $"{search}" }, transaction: transaction); + + var items = new List(); + if (resultFromQuery == null) + return items; + + foreach (var rawResultItem in resultFromQuery) + { + var contentItem = MapQueryItemToContentItem(rawResultItem); + items.Add(contentItem); + } + + return items; + } + + public override IEnumerable QueryAllContentItemsAsTransaction(Guid contentTypeId, string[] searchOnColumns, string search, string[] filters, string orderBy) + { + if (_db.State == ConnectionState.Closed) + { + _db.Open(); + } + using (IDbTransaction transaction = _db.BeginTransaction(IsolationLevel.Snapshot)) + { + int count = CountContentItems(contentTypeId, searchOnColumns, search, filters, transaction: transaction); + + int totalPages = (int)Math.Ceiling((double)count / View.DEFAULT_MAX_ITEMS_PER_PAGE); + for (int pageIndex = 1; pageIndex <= totalPages; pageIndex++) + { + foreach (var item in QueryContentItems(contentTypeId, searchOnColumns, search, filters, View.DEFAULT_MAX_ITEMS_PER_PAGE, pageIndex, orderBy, transaction: transaction)) + { + yield return item; + } + } + + transaction.Commit(); + } + } + + public override int CountContentItems(Guid contentTypeId, string[] searchOnColumns, string search, string[] filters, IDbTransaction transaction = null) + { + //get the content type for what we are filtering by + var contentType = _entityFramework.ContentTypes + .Include(p => p.ContentTypeFields) + .ThenInclude(p => p.RelatedContentType) + .First(p => p.Id == contentTypeId); + + ContentType = contentType; + + //Assemble the sql select and from clauses + var sqlBuilder = new SqlQueryBuilder(); + sqlBuilder = PrepareFrom(sqlBuilder.Select("COUNT(*) as \"Count\"")); + + //Attach the where clause to filter by this content type + sqlBuilder.AndWhere($"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.\"{RawSqlColumn.ContentTypeId.Name}\" = '{contentTypeId}'"); + + //Attach the where clause if we are filtering by a search query + sqlBuilder = PrepareSearch(sqlBuilder, search, searchOnColumns); + + //Attach where clauses for odata filters + sqlBuilder = PrepareODataFilters(sqlBuilder, filters); + + var rawSql = sqlBuilder.Build(); + + var numResults = _db.Query(rawSql, new { search = $"%{search}%", exactsearch = $"{search}" }, transaction: transaction).First().Count; + return (int)numResults; + } + + private SqlQueryBuilder PrepareODataFilters(SqlQueryBuilder sqlBuilder, string[] filters) + { + if (filters == null || !filters.Any()) + return sqlBuilder; + + var oDataToSql = new ODataFilterToPostgres(ContentType, PrimaryFieldDeveloperName, OneToOneRelationshipFields, _currentOrganization.DateFormat); + foreach (var filter in filters.Where(p => !string.IsNullOrEmpty(p))) + { + string whereStatement = oDataToSql.GenerateSql(filter); + if (!string.IsNullOrWhiteSpace(whereStatement)) + sqlBuilder.AndWhere($"({whereStatement})"); + } + return sqlBuilder; + } + + protected override SqlQueryBuilder PrepareContentItemsDataSelect(SqlQueryBuilder sqlBuilder) + { + foreach (var column in RawSqlColumn.ContentItemColumns()) + { + sqlBuilder.Select($"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.\"{column.Name}\" as \"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}_{column.Name}\""); + } + foreach (var column in RawSqlColumn.RouteColumns()) + { + sqlBuilder.Select($"{RawSqlColumn.ROUTE_COLUMN_NAME}.\"{column.Name}\" as \"{RawSqlColumn.ROUTE_COLUMN_NAME}_{column.Name}\""); + } + foreach (var column in RawSqlColumn.UserColumns()) + { + sqlBuilder.Select($"{RawSqlColumn.SOURCE_CREATED_BY_COLUMN_NAME}.\"{column.Name}\" as \"{RawSqlColumn.SOURCE_CREATED_BY_COLUMN_NAME}_{column.Name}\""); + } + foreach (var column in RawSqlColumn.UserColumns()) + { + sqlBuilder.Select($"{RawSqlColumn.SOURCE_MODIFIED_BY_COLUMN_NAME}.\"{column.Name}\" as \"{RawSqlColumn.SOURCE_MODIFIED_BY_COLUMN_NAME}_{column.Name}\""); + } + + foreach (var item in OneToOneRelationshipFields) + { + int index = OneToOneRelationshipFields.IndexOf(item); + foreach (var column in RawSqlColumn.ContentItemColumns()) + { + sqlBuilder.Select($"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}.\"{column.Name}\" as \"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}_{column.Name}\""); + } + foreach (var column in RawSqlColumn.RouteColumns()) + { + sqlBuilder.Select($"{RawSqlColumn.RELATED_ROUTE_COLUMN_NAME}_{index}.\"{column.Name}\" as \"{RawSqlColumn.RELATED_ROUTE_COLUMN_NAME}_{index}_{column.Name}\""); + } + foreach (var column in RawSqlColumn.UserColumns()) + { + sqlBuilder.Select($"{RawSqlColumn.RELATED_CREATED_BY_COLUMN_NAME}_{index}.\"{column.Name}\" as \"{RawSqlColumn.RELATED_CREATED_BY_COLUMN_NAME}_{index}_{column.Name}\""); + } + foreach (var column in RawSqlColumn.UserColumns()) + { + sqlBuilder.Select($"{RawSqlColumn.RELATED_MODIFIED_BY_COLUMN_NAME}_{index}.\"{column.Name}\" as \"{RawSqlColumn.RELATED_MODIFIED_BY_COLUMN_NAME}_{index}_{column.Name}\""); + } + } + + return sqlBuilder; + } + + protected override SqlQueryBuilder PrepareFrom(SqlQueryBuilder sqlBuilder) + { + sqlBuilder.From($"\"{RawSqlColumn.CONTENT_ITEM_TABLE_NAME}\" AS {RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}"); + + foreach (var item in OneToOneRelationshipFields) + { + int index = OneToOneRelationshipFields.IndexOf(item); + sqlBuilder.Join($"\"{RawSqlColumn.CONTENT_ITEM_TABLE_NAME}\" AS {RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}", + $"({RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}.\"{RawSqlColumn.Id.Name}\" = ({RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.\"{RawSqlColumn.PublishedContent.Name}\"->>'{item.DeveloperName?.ToDeveloperName()}')::uuid)", + joinType: "LEFT"); + sqlBuilder.Join($"\"{RawSqlColumn.USERS_TABLE_NAME}\" AS {RawSqlColumn.RELATED_CREATED_BY_COLUMN_NAME}_{index}", + $"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}.\"{RawSqlColumn.CreatorUserId.Name}\" = {RawSqlColumn.RELATED_CREATED_BY_COLUMN_NAME}_{index}.\"{RawSqlColumn.Id.Name}\"", + joinType: "LEFT"); + sqlBuilder.Join($"\"{RawSqlColumn.USERS_TABLE_NAME}\" AS {RawSqlColumn.RELATED_MODIFIED_BY_COLUMN_NAME}_{index}", + $"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}.\"{RawSqlColumn.LastModifierUserId.Name}\" = {RawSqlColumn.RELATED_MODIFIED_BY_COLUMN_NAME}_{index}.\"{RawSqlColumn.Id.Name}\"", + joinType: "LEFT"); + sqlBuilder.Join($"\"{RawSqlColumn.ROUTES_TABLE_NAME}\" AS {RawSqlColumn.RELATED_ROUTE_COLUMN_NAME}_{index}", + $"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}.\"{RawSqlColumn.RouteId.Name}\" = {RawSqlColumn.RELATED_ROUTE_COLUMN_NAME}_{index}.\"{RawSqlColumn.Id.Name}\"", + joinType: "LEFT"); + } + + sqlBuilder.Join($"\"{RawSqlColumn.ROUTES_TABLE_NAME}\" AS {RawSqlColumn.ROUTE_COLUMN_NAME}", + $"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.\"{RawSqlColumn.RouteId.Name}\" = {RawSqlColumn.ROUTE_COLUMN_NAME}.\"{RawSqlColumn.Id.Name}\"", + joinType: "LEFT"); + + sqlBuilder.Join($"\"{RawSqlColumn.USERS_TABLE_NAME}\" AS {RawSqlColumn.SOURCE_CREATED_BY_COLUMN_NAME}", + $"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.\"{RawSqlColumn.CreatorUserId.Name}\" = {RawSqlColumn.SOURCE_CREATED_BY_COLUMN_NAME}.\"{RawSqlColumn.Id.Name}\"", + joinType: "LEFT"); + + sqlBuilder.Join($"\"{RawSqlColumn.USERS_TABLE_NAME}\" AS {RawSqlColumn.SOURCE_MODIFIED_BY_COLUMN_NAME}", + $"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.\"{RawSqlColumn.LastModifierUserId.Name}\" = {RawSqlColumn.SOURCE_MODIFIED_BY_COLUMN_NAME}.\"{RawSqlColumn.Id.Name}\"", + joinType: "LEFT"); + + return sqlBuilder; + } + + protected override SqlQueryBuilder PrepareSearch(SqlQueryBuilder sqlBuilder, string search, string[] searchOnColumns = null) + { + if (string.IsNullOrWhiteSpace(search)) + return sqlBuilder; + + var oDataToSql = new ODataFilterToPostgres(ContentType, PrimaryFieldDeveloperName, OneToOneRelationshipFields, _currentOrganization.DateFormat); + + //If no columns specified, just search on Primary Field only + if (searchOnColumns == null || !searchOnColumns.Any()) + return sqlBuilder.AndWhere(oDataToSql.GenerateSql($"contains({BuiltInContentTypeField.PrimaryField.DeveloperName}, '{search}')")); + + string originalSearch = search; + search = search.ToLower(); + + var searchFilters = new List(); + + //For each column specified, generate the appropriate OData filter or Raw Sql search clause + foreach (var column in searchOnColumns) + { + var columnAsContentTypeField = ContentType.ContentTypeFields.FirstOrDefault(p => p.DeveloperName == column); + if (columnAsContentTypeField != null) + { + string columnAsContentTypeFieldDeveloperName = columnAsContentTypeField.DeveloperName.ToDeveloperName(); + + if (columnAsContentTypeField.FieldType.DeveloperName == BaseFieldType.Number && decimal.TryParse(search, out var searchAsDecimal)) + { + searchFilters.Add(oDataToSql.GenerateSql($"{columnAsContentTypeFieldDeveloperName} eq '{search}'")); + } + else if (columnAsContentTypeField.FieldType.DeveloperName == BaseFieldType.Checkbox && bool.TryParse(search, out var searchAsBool)) + { + searchFilters.Add(oDataToSql.GenerateSql($"{columnAsContentTypeFieldDeveloperName} eq '{search}'")); + } + else + { + searchFilters.Add(oDataToSql.GenerateSql($"contains({columnAsContentTypeFieldDeveloperName}, '{search}')")); + } + } + else + { + var reservedField = BuiltInContentTypeField.ReservedContentTypeFields.FirstOrDefault(p => p.DeveloperName == column); + if (reservedField != null) + { + if (reservedField.DeveloperName == BuiltInContentTypeField.Id && ShortGuid.TryParse(originalSearch.Trim(), out ShortGuid searchAsShortGuid)) + { + searchFilters.Add(oDataToSql.GenerateSql($"{reservedField.DeveloperName} eq 'guid_{originalSearch.Trim()}'")); + } + else if (reservedField.DeveloperName == BuiltInContentTypeField.CreatorUser.DeveloperName) + { + searchFilters.Add($"{RawSqlColumn.SOURCE_CREATED_BY_COLUMN_NAME}.\"{RawSqlColumn.FirstName.Name}\" ILIKE @search"); + searchFilters.Add($"{RawSqlColumn.SOURCE_CREATED_BY_COLUMN_NAME}.\"{RawSqlColumn.LastName.Name}\" ILIKE @search"); + } + else if (reservedField.DeveloperName == BuiltInContentTypeField.LastModifierUser.DeveloperName) + { + searchFilters.Add($"{RawSqlColumn.SOURCE_MODIFIED_BY_COLUMN_NAME}.\"{RawSqlColumn.FirstName.Name}\" ILIKE @search"); + searchFilters.Add($"{RawSqlColumn.SOURCE_MODIFIED_BY_COLUMN_NAME}.\"{RawSqlColumn.LastName.Name}\" ILIKE @search"); + } + else if (reservedField.DeveloperName == BuiltInContentTypeField.PrimaryField.DeveloperName) + { + searchFilters.Add(oDataToSql.GenerateSql($"contains({reservedField.DeveloperName}, '{search}')")); + } + } + } + } + + //Combine everything by OR operator + string oDataSearchWhereFilterClause = string.Join(" OR ", searchFilters.Where(p => !string.IsNullOrWhiteSpace(p))); + if (!string.IsNullOrEmpty(oDataSearchWhereFilterClause)) + { + sqlBuilder.AndWhere($"({oDataSearchWhereFilterClause})"); + } + + return sqlBuilder; + } + + protected override SqlQueryBuilder PrepareOrderBy(SqlQueryBuilder sqlBuilder, string orderBy) + { + if (string.IsNullOrEmpty(orderBy)) + return sqlBuilder; + + var orderBySplit = orderBy.Split(","); + List orderByClauses = new List(); + + //orderBy comes in form like "PrimaryField asc, CreationTime desc" + //Need to assemble SQL on each one separately + foreach (var orderByElement in orderBySplit) + { + try + { + //orderByElement comes in form like 'PrimaryField asc' + //Need to split this up into column and direction + (var column, var direction) = orderByElement.SplitIntoColumnAndSortOrder(); + + var columnAsContentTypeField = ContentType.ContentTypeFields.FirstOrDefault(p => p.DeveloperName == column); + if (columnAsContentTypeField != null) + { + string columnAsContentTypeFieldDeveloperName = columnAsContentTypeField.DeveloperName; + if (columnAsContentTypeField.FieldType.DeveloperName == BaseFieldType.OneToOneRelationship) + { + var relatedObjectField = OneToOneRelationshipFields.First(p => p.DeveloperName == columnAsContentTypeField.DeveloperName); + int indexOfRelatedObject = OneToOneRelationshipFields.ToList().IndexOf(relatedObjectField); + string relatedObjPrimaryFieldName = relatedObjectField.ContentType.ContentTypeFields.First(p => p.Id == relatedObjectField.ContentType.PrimaryFieldId).DeveloperName.ToDeveloperName(); + sqlBuilder.OrderBy(columnAsContentTypeField.FieldType.PostgresOrderByExpression($"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{indexOfRelatedObject}", RawSqlColumn.PublishedContent.Name, relatedObjPrimaryFieldName, direction.DeveloperName)); + } + else if (columnAsContentTypeField.FieldType.DeveloperName == BaseFieldType.Date) + { + sqlBuilder.OrderBy(columnAsContentTypeField.FieldType.PostgresOrderByExpression(RawSqlColumn.SOURCE_ITEM_COLUMN_NAME, RawSqlColumn.PublishedContent.Name, columnAsContentTypeField.DeveloperName, _currentOrganization.DateFormat, direction.DeveloperName)); + } + else + { + sqlBuilder.OrderBy(columnAsContentTypeField.FieldType.PostgresOrderByExpression(RawSqlColumn.SOURCE_ITEM_COLUMN_NAME, RawSqlColumn.PublishedContent.Name, columnAsContentTypeField.DeveloperName, direction.DeveloperName)); + } + } + else + { + var reservedField = BuiltInContentTypeField.ReservedContentTypeFields.FirstOrDefault(p => p.DeveloperName == column); + if (reservedField != null) + { + if (reservedField.DeveloperName == BuiltInContentTypeField.PrimaryField) + { + sqlBuilder.OrderBy(reservedField.FieldType.PostgresOrderByExpression(RawSqlColumn.SOURCE_ITEM_COLUMN_NAME, RawSqlColumn.PublishedContent.Name, PrimaryFieldDeveloperName, direction.DeveloperName)); + } + else if (reservedField.DeveloperName == BuiltInContentTypeField.CreatorUser) + { + sqlBuilder.OrderBy($"{RawSqlColumn.SOURCE_CREATED_BY_COLUMN_NAME}.\"{RawSqlColumn.FirstName.Name}\" {direction.DeveloperName}"); + } + else if (reservedField.DeveloperName == BuiltInContentTypeField.LastModifierUser) + { + sqlBuilder.OrderBy($"{RawSqlColumn.SOURCE_MODIFIED_BY_COLUMN_NAME}.\"{RawSqlColumn.FirstName.Name}\" {direction.DeveloperName}"); + } + else + { + sqlBuilder.OrderBy($"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.\"{reservedField.DeveloperName}\" {direction.DeveloperName}"); + } + } + } + } + catch + { + } + } + + return sqlBuilder; + } +} + diff --git a/src/Raytha.Infrastructure/JsonQueryEngine/SqlServer/ODataFilterToSqlServer.cs b/src/Raytha.Infrastructure/JsonQueryEngine/SqlServer/ODataFilterToSqlServer.cs index 6e16a229..9ae894ff 100644 --- a/src/Raytha.Infrastructure/JsonQueryEngine/SqlServer/ODataFilterToSqlServer.cs +++ b/src/Raytha.Infrastructure/JsonQueryEngine/SqlServer/ODataFilterToSqlServer.cs @@ -8,11 +8,12 @@ namespace Raytha.Infrastructure.JsonQueryEngine.SqlServer; internal class ODataFilterToSqlServer : AbstractODataFilterToSql { - public ODataFilterToSqlServer(ContentType contentType, string primaryFieldName, IEnumerable relatedObjectFields) + public ODataFilterToSqlServer(ContentType contentType, string primaryFieldName, IEnumerable relatedObjectFields, string dateTimeFormat) { _contentType = contentType; _primaryFieldName = primaryFieldName; _relatedObjectFields = relatedObjectFields; + _dateTimeFormat = dateTimeFormat; } public override string GenerateSql(string filterExpression) @@ -33,7 +34,7 @@ public override string GenerateSql(string filterExpression) FilterClause parsedODataFilterClause = parser.ParseFilter(); - ODataFilterToSqlVisitor visitor = new ODataFilterToSqlVisitor(_contentType, _primaryFieldName, _relatedObjectFields); + ODataFilterToSqlVisitor visitor = new ODataFilterToSqlVisitor(_contentType, _primaryFieldName, _relatedObjectFields, _dateTimeFormat); parsedODataFilterClause.Expression.Accept(visitor); string whereClause = visitor.GetWhereClause(); @@ -42,11 +43,12 @@ public override string GenerateSql(string filterExpression) private class ODataFilterToSqlVisitor : AbstractODataFilterToSqlVisitor where TSource : class { - public ODataFilterToSqlVisitor(ContentType contentType, string primaryFieldName, IEnumerable relatedObjectFields) + public ODataFilterToSqlVisitor(ContentType contentType, string primaryFieldName, IEnumerable relatedObjectFields, string dateTimeFormat) { _contentType = contentType; _primaryFieldName = primaryFieldName; _relatedObjectFields = relatedObjectFields; + _dateTimeFormat = dateTimeFormat; } public override TSource Visit(SingleValueFunctionCallNode nodeIn) @@ -104,6 +106,10 @@ protected override void HandleSingleValueProperty(string realFieldName) string relatedObjPrimaryFieldName = relatedObjectField.ContentType.ContentTypeFields.First(p => p.Id == relatedObjectField.ContentType.PrimaryFieldId).DeveloperName; whereClause.Append(chosenColumnAsCustomField.FieldType.SqlServerSingleJsonValue($"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{indexOfRelatedObject}", RawSqlColumn.PublishedContent.Name, relatedObjPrimaryFieldName)); } + else if (chosenColumnAsCustomField.FieldType.DeveloperName == BaseFieldType.Date) + { + whereClause.Append(chosenColumnAsCustomField.FieldType.SqlServerSingleJsonValue(RawSqlColumn.SOURCE_ITEM_COLUMN_NAME, RawSqlColumn.PublishedContent.Name, realFieldName, _dateTimeFormat)); + } else { whereClause.Append(chosenColumnAsCustomField.FieldType.SqlServerSingleJsonValue(RawSqlColumn.SOURCE_ITEM_COLUMN_NAME, RawSqlColumn.PublishedContent.Name, realFieldName)); diff --git a/src/Raytha.Infrastructure/JsonQueryEngine/SqlServer/RaythaDbSqlServerJsonQueryEngine.cs b/src/Raytha.Infrastructure/JsonQueryEngine/SqlServer/RaythaDbSqlServerJsonQueryEngine.cs index 5e2b9b20..0cd27b9f 100644 --- a/src/Raytha.Infrastructure/JsonQueryEngine/SqlServer/RaythaDbSqlServerJsonQueryEngine.cs +++ b/src/Raytha.Infrastructure/JsonQueryEngine/SqlServer/RaythaDbSqlServerJsonQueryEngine.cs @@ -22,7 +22,7 @@ public RaythaDbSqlServerJsonQueryEngine(IRaythaDbContext entityFramework, IDbCon _currentOrganization = currentOrganization; } - public ContentItem FirstOrDefault(Guid entityId) + public override ContentItem FirstOrDefault(Guid entityId) { //Check if it exists at all, and if so, get the ContentType var entity = _entityFramework.ContentItems @@ -53,7 +53,7 @@ public ContentItem FirstOrDefault(Guid entityId) return contentItem; } - public IEnumerable QueryContentItems(Guid contentTypeId, string[] searchOnColumns, string search, string[] filters, int pageSize, int pageNumber, string orderBy, IDbTransaction transaction = null) + public override IEnumerable QueryContentItems(Guid contentTypeId, string[] searchOnColumns, string search, string[] filters, int pageSize, int pageNumber, string orderBy, IDbTransaction transaction = null) { //get the content type being queried var contentType = _entityFramework.ContentTypes @@ -100,7 +100,7 @@ public IEnumerable QueryContentItems(Guid contentTypeId, string[] s return items; } - public IEnumerable QueryAllContentItemsAsTransaction(Guid contentTypeId, string[] searchOnColumns, string search, string[] filters, string orderBy) + public override IEnumerable QueryAllContentItemsAsTransaction(Guid contentTypeId, string[] searchOnColumns, string search, string[] filters, string orderBy) { if (_db.State == ConnectionState.Closed) { @@ -123,7 +123,7 @@ public IEnumerable QueryAllContentItemsAsTransaction(Guid contentTy } } - public int CountContentItems(Guid contentTypeId, string[] searchOnColumns, string search, string[] filters, IDbTransaction transaction = null) + public override int CountContentItems(Guid contentTypeId, string[] searchOnColumns, string search, string[] filters, IDbTransaction transaction = null) { //get the content type for what we are filtering by var contentType = _entityFramework.ContentTypes @@ -157,7 +157,7 @@ private SqlQueryBuilder PrepareODataFilters(SqlQueryBuilder sqlBuilder, string[] if (filters == null || !filters.Any()) return sqlBuilder; - var oDataToSql = new ODataFilterToSqlServer(ContentType, PrimaryFieldDeveloperName, OneToOneRelationshipFields); + var oDataToSql = new ODataFilterToSqlServer(ContentType, PrimaryFieldDeveloperName, OneToOneRelationshipFields, _currentOrganization.DateFormat); foreach (var filter in filters.Where(p => !string.IsNullOrEmpty(p))) { string whereStatement = oDataToSql.GenerateSql(filter); @@ -167,12 +167,47 @@ private SqlQueryBuilder PrepareODataFilters(SqlQueryBuilder sqlBuilder, string[] return sqlBuilder; } - private SqlQueryBuilder PrepareSearch(SqlQueryBuilder sqlBuilder, string search, string[] searchOnColumns = null) + protected override SqlQueryBuilder PrepareContentItemsDataSelect(SqlQueryBuilder sqlBuilder) + { + sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.ContentItemColumns(), RawSqlColumn.SOURCE_ITEM_COLUMN_NAME).ToArray()); + sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.RouteColumns(), RawSqlColumn.ROUTE_COLUMN_NAME).ToArray()); + sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.UserColumns(), RawSqlColumn.SOURCE_CREATED_BY_COLUMN_NAME).ToArray()); + sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.UserColumns(), RawSqlColumn.SOURCE_MODIFIED_BY_COLUMN_NAME).ToArray()); + foreach (var item in OneToOneRelationshipFields) + { + int index = OneToOneRelationshipFields.IndexOf(item); + sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.ContentItemColumns(), $"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}").ToArray()); + sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.RouteColumns(), $"{RawSqlColumn.RELATED_ROUTE_COLUMN_NAME}_{index}").ToArray()); + sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.UserColumns(), $"{RawSqlColumn.RELATED_CREATED_BY_COLUMN_NAME}_{index}").ToArray()); + sqlBuilder.Select(RawSqlColumn.NameAsFullColumnLabelForEnumerable(RawSqlColumn.UserColumns(), $"{RawSqlColumn.RELATED_MODIFIED_BY_COLUMN_NAME}_{index}").ToArray()); + } + return sqlBuilder; + } + + protected override SqlQueryBuilder PrepareFrom(SqlQueryBuilder sqlBuilder) + { + sqlBuilder.From($"{RawSqlColumn.CONTENT_ITEM_TABLE_NAME} AS {RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}"); + foreach (var item in OneToOneRelationshipFields) + { + int index = OneToOneRelationshipFields.IndexOf(item); + sqlBuilder.Join($"{RawSqlColumn.CONTENT_ITEM_TABLE_NAME} AS {RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}", $"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}.{RawSqlColumn.Id.Name} = JSON_VALUE({RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.{RawSqlColumn.PublishedContent.Name}, '$.{item.DeveloperName?.ToDeveloperName()}')", joinType: "LEFT"); + sqlBuilder.Join($"{RawSqlColumn.USERS_TABLE_NAME} AS {RawSqlColumn.RELATED_CREATED_BY_COLUMN_NAME}_{index}", $"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}.{RawSqlColumn.CreatorUserId.Name} = {RawSqlColumn.RELATED_CREATED_BY_COLUMN_NAME}_{index}.{RawSqlColumn.Id.Name}", joinType: "LEFT"); + sqlBuilder.Join($"{RawSqlColumn.USERS_TABLE_NAME} AS {RawSqlColumn.RELATED_MODIFIED_BY_COLUMN_NAME}_{index}", $"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}.{RawSqlColumn.LastModifierUserId.Name} = {RawSqlColumn.RELATED_MODIFIED_BY_COLUMN_NAME}_{index}.{RawSqlColumn.Id.Name}", joinType: "LEFT"); + sqlBuilder.Join($"{RawSqlColumn.ROUTES_TABLE_NAME} AS {RawSqlColumn.RELATED_ROUTE_COLUMN_NAME}_{index}", $"{RawSqlColumn.RELATED_ITEM_COLUMN_NAME}_{index}.{RawSqlColumn.RouteId.Name} = {RawSqlColumn.RELATED_ROUTE_COLUMN_NAME}_{index}.{RawSqlColumn.Id.Name}", joinType: "LEFT"); + } + sqlBuilder.Join($"{RawSqlColumn.ROUTES_TABLE_NAME} AS {RawSqlColumn.ROUTE_COLUMN_NAME} ", $"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.{RawSqlColumn.RouteId.Name} = {RawSqlColumn.ROUTE_COLUMN_NAME}.{RawSqlColumn.Id.Name}", joinType: "LEFT"); + sqlBuilder.Join($"{RawSqlColumn.USERS_TABLE_NAME} AS {RawSqlColumn.SOURCE_CREATED_BY_COLUMN_NAME}", $"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.{RawSqlColumn.CreatorUserId.Name} = {RawSqlColumn.SOURCE_CREATED_BY_COLUMN_NAME}.{RawSqlColumn.Id.Name}", joinType: "LEFT"); + sqlBuilder.Join($"{RawSqlColumn.USERS_TABLE_NAME} AS {RawSqlColumn.SOURCE_MODIFIED_BY_COLUMN_NAME}", $"{RawSqlColumn.SOURCE_ITEM_COLUMN_NAME}.{RawSqlColumn.LastModifierUserId.Name} = {RawSqlColumn.SOURCE_MODIFIED_BY_COLUMN_NAME}.{RawSqlColumn.Id.Name}", joinType: "LEFT"); + + return sqlBuilder; + } + + protected override SqlQueryBuilder PrepareSearch(SqlQueryBuilder sqlBuilder, string search, string[] searchOnColumns = null) { if (string.IsNullOrWhiteSpace(search)) return sqlBuilder; - var oDataToSql = new ODataFilterToSqlServer(ContentType, PrimaryFieldDeveloperName, OneToOneRelationshipFields); + var oDataToSql = new ODataFilterToSqlServer(ContentType, PrimaryFieldDeveloperName, OneToOneRelationshipFields, _currentOrganization.DateFormat); //If no columns specified, just search on Primary Field only if (searchOnColumns == null || !searchOnColumns.Any()) @@ -241,7 +276,7 @@ private SqlQueryBuilder PrepareSearch(SqlQueryBuilder sqlBuilder, string search, return sqlBuilder; } - private SqlQueryBuilder PrepareOrderBy(SqlQueryBuilder sqlBuilder, string orderBy) + protected override SqlQueryBuilder PrepareOrderBy(SqlQueryBuilder sqlBuilder, string orderBy) { if (string.IsNullOrEmpty(orderBy)) return sqlBuilder; @@ -272,14 +307,8 @@ private SqlQueryBuilder PrepareOrderBy(SqlQueryBuilder sqlBuilder, string orderB } else if (columnAsContentTypeField.FieldType.DeveloperName == BaseFieldType.Date) { - int sqlDateOutput = _currentOrganization.DateFormat switch - { - DateTimeExtensions.MM_dd_yyyy => 101, - DateTimeExtensions.dd_MM_yyyy => 103, - _ => 0 - }; - sqlBuilder.OrderBy(columnAsContentTypeField.FieldType.SqlServerOrderByExpression(RawSqlColumn.SOURCE_ITEM_COLUMN_NAME, RawSqlColumn.PublishedContent.Name, columnAsContentTypeField.DeveloperName, sqlDateOutput.ToString(), direction.DeveloperName)); + sqlBuilder.OrderBy(columnAsContentTypeField.FieldType.SqlServerOrderByExpression(RawSqlColumn.SOURCE_ITEM_COLUMN_NAME, RawSqlColumn.PublishedContent.Name, columnAsContentTypeField.DeveloperName, _currentOrganization.DateFormat, direction.DeveloperName)); } else { diff --git a/src/Raytha.Infrastructure/Persistence/Configurations/AuthenticationSchemeConfiguration.cs b/src/Raytha.Infrastructure/Persistence/Configurations/AuthenticationSchemeConfiguration.cs index e47274ea..a613d0ae 100644 --- a/src/Raytha.Infrastructure/Persistence/Configurations/AuthenticationSchemeConfiguration.cs +++ b/src/Raytha.Infrastructure/Persistence/Configurations/AuthenticationSchemeConfiguration.cs @@ -9,11 +9,6 @@ public class AuthenticationSchemeConfiguration : IEntityTypeConfiguration builder) { - builder - .HasIndex(b => b.DeveloperName) - .IsUnique() - .IncludeProperties(p => new { p.Id, p.Label }); - builder .HasOne(b => b.CreatorUser) .WithMany() @@ -27,5 +22,7 @@ public void Configure(EntityTypeBuilder builder) builder .Property(b => b.AuthenticationSchemeType) .HasConversion(v => v.DeveloperName, v => AuthenticationSchemeType.From(v)); + + builder.HasIndex(b => b.DeveloperName).IsUnique(); } } diff --git a/src/Raytha.Infrastructure/Persistence/Configurations/ContentItemConfiguration.cs b/src/Raytha.Infrastructure/Persistence/Configurations/ContentItemConfiguration.cs index 439990cb..036f02ee 100644 --- a/src/Raytha.Infrastructure/Persistence/Configurations/ContentItemConfiguration.cs +++ b/src/Raytha.Infrastructure/Persistence/Configurations/ContentItemConfiguration.cs @@ -16,6 +16,16 @@ public void Configure(EntityTypeBuilder builder) builder .HasOne(b => b.LastModifierUser) .WithMany() - .HasForeignKey(b => b.LastModifierUserId); + .HasForeignKey(b => b.LastModifierUserId); + } +} + +public class ContentItemPostgresConfiguration : IEntityTypeConfiguration, IPostgresConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder + .Property(b => b._PublishedContent) + .HasColumnType("jsonb"); } } diff --git a/src/Raytha.Infrastructure/Persistence/Configurations/EmailTemplateConfiguration.cs b/src/Raytha.Infrastructure/Persistence/Configurations/EmailTemplateConfiguration.cs index 7cb4f4fb..48d83a90 100644 --- a/src/Raytha.Infrastructure/Persistence/Configurations/EmailTemplateConfiguration.cs +++ b/src/Raytha.Infrastructure/Persistence/Configurations/EmailTemplateConfiguration.cs @@ -1,19 +1,13 @@ using Raytha.Domain.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Raytha.Domain.ValueObjects; namespace Raytha.Infrastructure.Persistence.Configurations; -public class EmailTemplateConfiguration : IEntityTypeConfiguration +public class EmailTemplateConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public void Configure(EntityTypeBuilder builder) { - builder - .HasIndex(b => b.DeveloperName) - .IsUnique() - .IncludeProperties(p => new { p.Id, p.Label }); - builder .HasOne(b => b.CreatorUser) .WithMany() @@ -23,5 +17,7 @@ public void Configure(EntityTypeBuilder builder) .HasOne(b => b.LastModifierUser) .WithMany() .HasForeignKey(b => b.LastModifierUserId); + + builder.HasIndex(b => b.DeveloperName).IsUnique(); } } diff --git a/src/Raytha.Infrastructure/Persistence/Configurations/JwtLoginConfiguration.cs b/src/Raytha.Infrastructure/Persistence/Configurations/JwtLoginConfiguration.cs index 975c12b1..8451a551 100644 --- a/src/Raytha.Infrastructure/Persistence/Configurations/JwtLoginConfiguration.cs +++ b/src/Raytha.Infrastructure/Persistence/Configurations/JwtLoginConfiguration.cs @@ -8,9 +8,6 @@ public class JwtLoginConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { - builder - .HasIndex(b => b.Jti) - .IsUnique() - .IncludeProperties(p => new { p.Id }); + builder.HasIndex(b => b.Jti).IsUnique(); } } diff --git a/src/Raytha.Infrastructure/Persistence/Configurations/RoleConfiguration.cs b/src/Raytha.Infrastructure/Persistence/Configurations/RoleConfiguration.cs index 35a07cda..befd0bad 100644 --- a/src/Raytha.Infrastructure/Persistence/Configurations/RoleConfiguration.cs +++ b/src/Raytha.Infrastructure/Persistence/Configurations/RoleConfiguration.cs @@ -8,11 +8,6 @@ public class RoleConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { - builder - .HasIndex(b => b.DeveloperName) - .IsUnique() - .IncludeProperties(p => new { p.Id, p.Label }); - builder .HasOne(b => b.CreatorUser) .WithMany() @@ -22,5 +17,7 @@ public void Configure(EntityTypeBuilder builder) .HasOne(b => b.LastModifierUser) .WithMany() .HasForeignKey(b => b.LastModifierUserId); + + builder.HasIndex(b => b.DeveloperName).IsUnique(); } -} +} \ No newline at end of file diff --git a/src/Raytha.Infrastructure/Persistence/Configurations/RouteConfiguration.cs b/src/Raytha.Infrastructure/Persistence/Configurations/RouteConfiguration.cs index a48759ba..c9a91d93 100644 --- a/src/Raytha.Infrastructure/Persistence/Configurations/RouteConfiguration.cs +++ b/src/Raytha.Infrastructure/Persistence/Configurations/RouteConfiguration.cs @@ -8,11 +8,6 @@ public class RouteConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { - builder - .HasIndex(b => b.Path) - .IsUnique() - .IncludeProperties(p => new { p.Id, p.ViewId, p.ContentItemId }); - builder .HasOne(p => p.View) .WithOne(p => p.Route) @@ -24,5 +19,7 @@ public void Configure(EntityTypeBuilder builder) .WithOne(p => p.Route) .HasForeignKey(b => b.RouteId) .OnDelete(DeleteBehavior.ClientCascade); + + builder.HasIndex(b => b.Path).IsUnique(); } -} +} \ No newline at end of file diff --git a/src/Raytha.Infrastructure/Persistence/Configurations/UserConfiguration.cs b/src/Raytha.Infrastructure/Persistence/Configurations/UserConfiguration.cs index 9c07c543..2092b1e0 100644 --- a/src/Raytha.Infrastructure/Persistence/Configurations/UserConfiguration.cs +++ b/src/Raytha.Infrastructure/Persistence/Configurations/UserConfiguration.cs @@ -8,16 +8,6 @@ public class UserConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { - builder - .HasIndex(b => b.EmailAddress) - .IsUnique() - .IncludeProperties(p => new { p.Id, p.FirstName, p.LastName, p.SsoId, p.AuthenticationSchemeId }); - - builder - .HasIndex(b => new { b.SsoId, b.AuthenticationSchemeId }) - .IsUnique() - .IncludeProperties(p => new { p.Id, p.EmailAddress, p.FirstName, p.LastName }); - builder .HasOne(p => p.AuthenticationScheme) .WithMany() @@ -33,5 +23,8 @@ public void Configure(EntityTypeBuilder builder) .HasOne(b => b.LastModifierUser) .WithMany() .HasForeignKey(b => b.LastModifierUserId); + + builder.HasIndex(b => b.EmailAddress).IsUnique(); + builder.HasIndex(b => new { b.SsoId, b.AuthenticationSchemeId }).IsUnique(); } } diff --git a/src/Raytha.Infrastructure/Persistence/Configurations/UserGroupConfiguration.cs b/src/Raytha.Infrastructure/Persistence/Configurations/UserGroupConfiguration.cs index ce3a406f..92dafab4 100644 --- a/src/Raytha.Infrastructure/Persistence/Configurations/UserGroupConfiguration.cs +++ b/src/Raytha.Infrastructure/Persistence/Configurations/UserGroupConfiguration.cs @@ -8,11 +8,6 @@ public class UserGroupConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { - builder - .HasIndex(b => b.DeveloperName) - .IsUnique() - .IncludeProperties(p => new { p.Id, p.Label }); - builder .HasOne(b => b.CreatorUser) .WithMany() @@ -22,5 +17,7 @@ public void Configure(EntityTypeBuilder builder) .HasOne(b => b.LastModifierUser) .WithMany() .HasForeignKey(b => b.LastModifierUserId); + + builder.HasIndex(b => b.DeveloperName).IsUnique(); } } diff --git a/src/Raytha.Infrastructure/Persistence/DbProviderHelper.cs b/src/Raytha.Infrastructure/Persistence/DbProviderHelper.cs new file mode 100644 index 00000000..2ced3007 --- /dev/null +++ b/src/Raytha.Infrastructure/Persistence/DbProviderHelper.cs @@ -0,0 +1,33 @@ +namespace Raytha.Infrastructure.Persistence; + +interface IPostgresConfiguration { } +interface ISqlServerConfiguration { } + +public enum DatabaseProviderType +{ + Postgres, + SqlServer +} + +public static class DbProviderHelper +{ + public static DatabaseProviderType GetDatabaseProviderTypeFromConnectionString(string connectionString) + { + bool isPostgres = connectionString.Contains("Host=", StringComparison.OrdinalIgnoreCase); + bool isSqlServer = connectionString.Contains("Server=", StringComparison.OrdinalIgnoreCase) || + connectionString.Contains("Data Source=", StringComparison.OrdinalIgnoreCase); + + if (isPostgres) + { + return DatabaseProviderType.Postgres; + } + else if (isSqlServer) + { + return DatabaseProviderType.SqlServer; + } + else + { + throw new NotSupportedException("Database provider not supported"); + } + } +} diff --git a/src/Raytha.Infrastructure/Persistence/RaythaDbContext.cs b/src/Raytha.Infrastructure/Persistence/RaythaDbContext.cs index 884a802b..148d1192 100644 --- a/src/Raytha.Infrastructure/Persistence/RaythaDbContext.cs +++ b/src/Raytha.Infrastructure/Persistence/RaythaDbContext.cs @@ -5,6 +5,7 @@ using Raytha.Domain.Entities; using Raytha.Infrastructure.Persistence.Interceptors; using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; namespace Raytha.Infrastructure.Persistence; @@ -12,6 +13,7 @@ public class RaythaDbContext : DbContext, IRaythaDbContext, IDataProtectionKeyCo { private readonly IMediator _mediator; private readonly AuditableEntitySaveChangesInterceptor _auditableEntitySaveChangesInterceptor; + private readonly IConfiguration _configuration; public RaythaDbContext( DbContextOptions options) @@ -21,10 +23,12 @@ public RaythaDbContext( public RaythaDbContext( DbContextOptions options, + IConfiguration configuration, IMediator mediator, AuditableEntitySaveChangesInterceptor auditableEntitySaveChangesInterceptor) : base(options) { + _configuration = configuration; _mediator = mediator; _auditableEntitySaveChangesInterceptor = auditableEntitySaveChangesInterceptor; } @@ -66,11 +70,18 @@ public RaythaDbContext( public DbContext DbContext => DbContext; - protected override void OnModelCreating(ModelBuilder builder) { - builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); - + builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly(), p => p.GetInterfaces().All(c => c.Name != typeof(ISqlServerConfiguration).Name && c.Name != typeof(IPostgresConfiguration).Name)); + var dbProvider = DbProviderHelper.GetDatabaseProviderTypeFromConnectionString(_configuration.GetConnectionString("DefaultConnection")); + if (dbProvider == DatabaseProviderType.Postgres) + { + builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly(), p => p.GetInterfaces().Any(c => c.Name == typeof(IPostgresConfiguration).Name)); + } + else + { + builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly(), p => p.GetInterfaces().Any(c => c.Name == typeof(ISqlServerConfiguration).Name)); + } base.OnModelCreating(builder); } diff --git a/src/Raytha.Infrastructure/Persistence/RaythaRawDbInfo.cs b/src/Raytha.Infrastructure/Persistence/RaythaRawDbInfo.cs index 3351c1f4..fef17e10 100644 --- a/src/Raytha.Infrastructure/Persistence/RaythaRawDbInfo.cs +++ b/src/Raytha.Infrastructure/Persistence/RaythaRawDbInfo.cs @@ -1,6 +1,6 @@ using Dapper; +using Microsoft.Extensions.Configuration; using Raytha.Application.Common.Interfaces; -using Raytha.Domain.Entities; using System.Data; namespace Raytha.Infrastructure.Persistence; @@ -8,14 +8,26 @@ namespace Raytha.Infrastructure.Persistence; public class RaythaRawDbInfo : IRaythaRawDbInfo { private readonly IDbConnection _db; - public RaythaRawDbInfo(IDbConnection db) + private readonly IConfiguration _configuration; + public RaythaRawDbInfo(IDbConnection db, IConfiguration configuration) { _db = db; + _configuration = configuration; } public DbSpaceUsed GetDatabaseSize() { - DbSpaceUsed dbSizeInfo = _db.QueryFirst("EXEC sp_spaceused @oneresultset = 1"); + var dbProvider = DbProviderHelper.GetDatabaseProviderTypeFromConnectionString(_configuration.GetConnectionString("DefaultConnection")); + string query = string.Empty; + if (dbProvider == DatabaseProviderType.Postgres) + { + query = "SELECT pg_size_pretty(pg_database_size(current_database())) AS reserved FROM pg_class LIMIT 1;"; + } + else + { + query = "EXEC sp_spaceused @oneresultset = 1"; + } + DbSpaceUsed dbSizeInfo = _db.QueryFirst(query); return dbSizeInfo; } } diff --git a/src/Raytha.Infrastructure/Raytha.Infrastructure.csproj b/src/Raytha.Infrastructure/Raytha.Infrastructure.csproj index 6a0a50c0..cd516b1e 100644 --- a/src/Raytha.Infrastructure/Raytha.Infrastructure.csproj +++ b/src/Raytha.Infrastructure/Raytha.Infrastructure.csproj @@ -26,10 +26,8 @@ - - - - + + diff --git a/src/Raytha.Migrations.Postgres/20241110181505_v1_4_0.Designer.cs b/src/Raytha.Migrations.Postgres/20241110181505_v1_4_0.Designer.cs new file mode 100644 index 00000000..f3d1d56b --- /dev/null +++ b/src/Raytha.Migrations.Postgres/20241110181505_v1_4_0.Designer.cs @@ -0,0 +1,2271 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Raytha.Infrastructure.Persistence; + +#nullable disable + +namespace Raytha.Migrations.Postgres +{ + [DbContext(typeof(RaythaDbContext))] + [Migration("20241110181505_v1_4_0")] + partial class v1_4_0 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FriendlyName") + .HasColumnType("text"); + + b.Property("Xml") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("DataProtectionKeys"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ApiKeyHash") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ApiKeyHash") + .IsUnique(); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKeys"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Category") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("EntityId") + .HasColumnType("uuid"); + + b.Property("IpAddress") + .IsRequired() + .HasColumnType("text"); + + b.Property("Request") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserEmail") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("CreationTime"); + + b.HasIndex("EntityId"); + + b.ToTable("AuditLogs"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.AuthenticationScheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuthenticationSchemeType") + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeveloperName") + .HasColumnType("text"); + + b.Property("IsBuiltInAuth") + .HasColumnType("boolean"); + + b.Property("IsEnabledForAdmins") + .HasColumnType("boolean"); + + b.Property("IsEnabledForUsers") + .HasColumnType("boolean"); + + b.Property("JwtSecretKey") + .HasColumnType("text"); + + b.Property("JwtUseHighSecurity") + .HasColumnType("boolean"); + + b.Property("Label") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("LoginButtonText") + .HasColumnType("text"); + + b.Property("MagicLinkExpiresInSeconds") + .HasColumnType("integer"); + + b.Property("SamlCertificate") + .HasColumnType("text"); + + b.Property("SamlIdpEntityId") + .HasColumnType("text"); + + b.Property("SignInUrl") + .HasColumnType("text"); + + b.Property("SignOutUrl") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("AuthenticationSchemes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.BackgroundTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Args") + .HasColumnType("text"); + + b.Property("CompletionTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ErrorMessage") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("NumberOfRetries") + .HasColumnType("integer"); + + b.Property("PercentComplete") + .HasColumnType("integer"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("StatusInfo") + .HasColumnType("text"); + + b.Property("TaskStep") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("BackgroundTasks"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentTypeId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("IsDraft") + .HasColumnType("boolean"); + + b.Property("IsPublished") + .HasColumnType("boolean"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("RouteId") + .HasColumnType("uuid"); + + b.Property("_DraftContent") + .HasColumnType("text"); + + b.Property("_PublishedContent") + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RouteId") + .IsUnique(); + + b.ToTable("ContentItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItemRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentItemId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("_PublishedContent") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ContentItemId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("ContentItemRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DefaultRouteTemplate") + .HasColumnType("text"); + + b.Property("DeleterUserId") + .HasColumnType("uuid"); + + b.Property("DeletionTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("DeveloperName") + .HasColumnType("text"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LabelPlural") + .HasColumnType("text"); + + b.Property("LabelSingular") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("PrimaryFieldId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("ContentTypes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentTypeField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentTypeId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeleterUserId") + .HasColumnType("uuid"); + + b.Property("DeletionTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("DeveloperName") + .HasColumnType("text"); + + b.Property("FieldOrder") + .HasColumnType("integer"); + + b.Property("FieldType") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsRequired") + .HasColumnType("boolean"); + + b.Property("Label") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("RelatedContentTypeId") + .HasColumnType("uuid"); + + b.Property("_Choices") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RelatedContentTypeId"); + + b.ToTable("ContentTypeFields"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentTypeRolePermission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentTypeId") + .HasColumnType("uuid"); + + b.Property("ContentTypePermissions") + .HasColumnType("integer"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RoleId"); + + b.ToTable("ContentTypeRolePermission"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.DeletedContentItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentTypeId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("OriginalContentItemId") + .HasColumnType("uuid"); + + b.Property("PrimaryField") + .HasColumnType("text"); + + b.Property("RoutePath") + .IsRequired() + .HasColumnType("text"); + + b.Property("WebTemplateIdsJson") + .IsRequired() + .HasColumnType("text"); + + b.Property("_PublishedContent") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("DeletedContentItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Bcc") + .HasColumnType("text"); + + b.Property("Cc") + .HasColumnType("text"); + + b.Property("Content") + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeveloperName") + .HasColumnType("text"); + + b.Property("IsBuiltInTemplate") + .HasColumnType("boolean"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("Subject") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("EmailTemplates"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplateRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Bcc") + .HasColumnType("text"); + + b.Property("Cc") + .HasColumnType("text"); + + b.Property("Content") + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("EmailTemplateId") + .HasColumnType("uuid"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("Subject") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("EmailTemplateId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("EmailTemplateRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.JwtLogin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Jti") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Jti") + .IsUnique(); + + b.ToTable("JwtLogins"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.MediaItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentType") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasColumnType("text"); + + b.Property("FileStorageProvider") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("Length") + .HasColumnType("bigint"); + + b.Property("ObjectKey") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("ObjectKey"); + + b.ToTable("MediaItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenu", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsMainMenu") + .HasColumnType("boolean"); + + b.Property("Label") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("NavigationMenus"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenuItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("CssClassName") + .HasColumnType("text"); + + b.Property("IsDisabled") + .HasColumnType("boolean"); + + b.Property("Label") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("NavigationMenuId") + .HasColumnType("uuid"); + + b.Property("OpenInNewTab") + .HasColumnType("boolean"); + + b.Property("Ordinal") + .HasColumnType("integer"); + + b.Property("ParentNavigationMenuItemId") + .HasColumnType("uuid"); + + b.Property("Url") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("NavigationMenuId"); + + b.HasIndex("ParentNavigationMenuItemId"); + + b.ToTable("NavigationMenuItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenuRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("NavigationMenuId") + .HasColumnType("uuid"); + + b.Property("NavigationMenuItemsJson") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("NavigationMenuId"); + + b.ToTable("NavigationMenuRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.OneTimePassword", b => + { + b.Property("Id") + .HasColumnType("bytea"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IsUsed") + .HasColumnType("boolean"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("OneTimePasswords"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.OrganizationSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ActiveThemeId") + .HasColumnType("uuid"); + + b.Property("DateFormat") + .HasColumnType("text"); + + b.Property("HomePageId") + .HasColumnType("uuid"); + + b.Property("HomePageType") + .IsRequired() + .HasColumnType("text"); + + b.Property("OrganizationName") + .HasColumnType("text"); + + b.Property("SmtpDefaultFromAddress") + .HasColumnType("text"); + + b.Property("SmtpDefaultFromName") + .HasColumnType("text"); + + b.Property("SmtpHost") + .HasColumnType("text"); + + b.Property("SmtpOverrideSystem") + .HasColumnType("boolean"); + + b.Property("SmtpPassword") + .HasColumnType("text"); + + b.Property("SmtpPort") + .HasColumnType("integer"); + + b.Property("SmtpUsername") + .HasColumnType("text"); + + b.Property("TimeZone") + .HasColumnType("text"); + + b.Property("WebsiteUrl") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("OrganizationSettings"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("TriggerType") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("RaythaFunctions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunctionRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("RaythaFunctionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RaythaFunctionId"); + + b.ToTable("RaythaFunctionRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Label") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("SystemPermissions") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Route", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentItemId") + .HasColumnType("uuid"); + + b.Property("Path") + .IsRequired() + .HasColumnType("text"); + + b.Property("ViewId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("Path") + .IsUnique(); + + b.ToTable("Routes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Theme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsExportable") + .HasColumnType("boolean"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("Themes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ThemeAccessToMediaItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MediaItemId") + .HasColumnType("uuid"); + + b.Property("ThemeId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("ThemeId"); + + b.ToTable("ThemeAccessToMediaItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuthenticationSchemeId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("EmailAddress") + .IsRequired() + .HasColumnType("text"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsAdmin") + .HasColumnType("boolean"); + + b.Property("IsEmailAddressConfirmed") + .HasColumnType("boolean"); + + b.Property("LastLoggedInTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("text"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("Salt") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("SsoId") + .HasColumnType("text"); + + b.Property("_RecentlyAccessedViews") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("AuthenticationSchemeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("EmailAddress") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("SsoId", "AuthenticationSchemeId") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.UserGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Label") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("UserGroups"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.VerificationCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .HasColumnType("uuid"); + + b.Property("Completed") + .HasColumnType("boolean"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("EmailAddress") + .HasColumnType("text"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("VerificationCodeType") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("VerificationCodes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.View", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentTypeId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DefaultNumberOfItemsPerPage") + .HasColumnType("integer"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("DeveloperName") + .HasColumnType("text"); + + b.Property("IgnoreClientFilterAndSortQueryParams") + .HasColumnType("boolean"); + + b.Property("IsPublished") + .HasColumnType("boolean"); + + b.Property("Label") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("MaxNumberOfItemsPerPage") + .HasColumnType("integer"); + + b.Property("RouteId") + .HasColumnType("uuid"); + + b.Property("_Columns") + .HasColumnType("text"); + + b.Property("_Filter") + .HasColumnType("text"); + + b.Property("_Sort") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RouteId") + .IsUnique(); + + b.ToTable("Views"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AllowAccessForNewContentTypes") + .HasColumnType("boolean"); + + b.Property("Content") + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeveloperName") + .HasColumnType("text"); + + b.Property("IsBaseLayout") + .HasColumnType("boolean"); + + b.Property("IsBuiltInTemplate") + .HasColumnType("boolean"); + + b.Property("Label") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("ParentTemplateId") + .HasColumnType("uuid"); + + b.Property("ThemeId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("ParentTemplateId"); + + b.HasIndex("ThemeId"); + + b.HasIndex("DeveloperName", "ThemeId") + .IsUnique(); + + b.ToTable("WebTemplates"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateAccessToModelDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentTypeId") + .HasColumnType("uuid"); + + b.Property("WebTemplateId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("WebTemplateId"); + + b.ToTable("WebTemplateAccessToModelDefinitions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateContentItemRelation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentItemId") + .HasColumnType("uuid"); + + b.Property("WebTemplateId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ContentItemId"); + + b.HasIndex("WebTemplateId", "ContentItemId") + .IsUnique(); + + b.ToTable("WebTemplateContentItemRelations"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AllowAccessForNewContentTypes") + .HasColumnType("boolean"); + + b.Property("Content") + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("EmailTemplateId") + .HasColumnType("uuid"); + + b.Property("Label") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("WebTemplateId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("EmailTemplateId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("WebTemplateId"); + + b.ToTable("WebTemplateRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateViewRelation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ViewId") + .HasColumnType("uuid"); + + b.Property("WebTemplateId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("WebTemplateId"); + + b.HasIndex("ViewId", "WebTemplateId") + .IsUnique(); + + b.ToTable("WebTemplateViewRelations"); + }); + + modelBuilder.Entity("RoleUser", b => + { + b.Property("RolesId") + .HasColumnType("uuid"); + + b.Property("UsersId") + .HasColumnType("uuid"); + + b.HasKey("RolesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("RoleUser"); + }); + + modelBuilder.Entity("UserUserGroup", b => + { + b.Property("UserGroupsId") + .HasColumnType("uuid"); + + b.Property("UsersId") + .HasColumnType("uuid"); + + b.HasKey("UserGroupsId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("UserUserGroup"); + }); + + modelBuilder.Entity("UserView", b => + { + b.Property("FavoriteViewsId") + .HasColumnType("uuid"); + + b.Property("UserFavoritesId") + .HasColumnType("uuid"); + + b.HasKey("FavoriteViewsId", "UserFavoritesId"); + + b.HasIndex("UserFavoritesId"); + + b.ToTable("UserView"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ApiKey", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "User") + .WithMany("ApiKeys") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.AuthenticationScheme", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItem", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany() + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.Route", "Route") + .WithOne("ContentItem") + .HasForeignKey("Raytha.Domain.Entities.ContentItem", "RouteId") + .OnDelete(DeleteBehavior.ClientCascade) + .IsRequired(); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("Route"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItemRevision", b => + { + b.HasOne("Raytha.Domain.Entities.ContentItem", "ContentItem") + .WithMany("ContentItemRevisions") + .HasForeignKey("ContentItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("ContentItem"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentType", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentTypeField", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany("ContentTypeFields") + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.ContentType", "RelatedContentType") + .WithMany() + .HasForeignKey("RelatedContentTypeId"); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("RelatedContentType"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentTypeRolePermission", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany() + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.Role", "Role") + .WithMany("ContentTypeRolePermissions") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.DeletedContentItem", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany() + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplate", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplateRevision", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.EmailTemplate", "EmailTemplate") + .WithMany() + .HasForeignKey("EmailTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("EmailTemplate"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.MediaItem", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenu", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenuItem", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.NavigationMenu", "NavigationMenu") + .WithMany("NavigationMenuItems") + .HasForeignKey("NavigationMenuId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.NavigationMenuItem", "ParentNavigationMenuItem") + .WithMany() + .HasForeignKey("ParentNavigationMenuItemId") + .OnDelete(DeleteBehavior.ClientCascade); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("NavigationMenu"); + + b.Navigation("ParentNavigationMenuItem"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenuRevision", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.NavigationMenu", "NavigationMenu") + .WithMany("NavigationMenuRevisions") + .HasForeignKey("NavigationMenuId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("NavigationMenu"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.OneTimePassword", b => + { + b.HasOne("Raytha.Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunction", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunctionRevision", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.RaythaFunction", "RaythaFunction") + .WithMany("Revisions") + .HasForeignKey("RaythaFunctionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("RaythaFunction"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Role", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Theme", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ThemeAccessToMediaItem", b => + { + b.HasOne("Raytha.Domain.Entities.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.Theme", "Theme") + .WithMany("ThemeAccessToMediaItems") + .HasForeignKey("ThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaItem"); + + b.Navigation("Theme"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.User", b => + { + b.HasOne("Raytha.Domain.Entities.AuthenticationScheme", "AuthenticationScheme") + .WithMany() + .HasForeignKey("AuthenticationSchemeId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("AuthenticationScheme"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.UserGroup", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.VerificationCode", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.View", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany("Views") + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("Raytha.Domain.Entities.Route", "Route") + .WithOne("View") + .HasForeignKey("Raytha.Domain.Entities.View", "RouteId") + .OnDelete(DeleteBehavior.ClientCascade) + .IsRequired(); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("Route"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplate", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "ParentTemplate") + .WithMany() + .HasForeignKey("ParentTemplateId"); + + b.HasOne("Raytha.Domain.Entities.Theme", "Theme") + .WithMany("WebTemplates") + .HasForeignKey("ThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("ParentTemplate"); + + b.Navigation("Theme"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateAccessToModelDefinition", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany() + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "WebTemplate") + .WithMany("TemplateAccessToModelDefinitions") + .HasForeignKey("WebTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ContentType"); + + b.Navigation("WebTemplate"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateContentItemRelation", b => + { + b.HasOne("Raytha.Domain.Entities.ContentItem", "ContentItem") + .WithMany() + .HasForeignKey("ContentItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "WebTemplate") + .WithMany() + .HasForeignKey("WebTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ContentItem"); + + b.Navigation("WebTemplate"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateRevision", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.EmailTemplate", null) + .WithMany("Revisions") + .HasForeignKey("EmailTemplateId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "WebTemplate") + .WithMany("Revisions") + .HasForeignKey("WebTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("WebTemplate"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateViewRelation", b => + { + b.HasOne("Raytha.Domain.Entities.View", "View") + .WithMany() + .HasForeignKey("ViewId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "WebTemplate") + .WithMany() + .HasForeignKey("WebTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("View"); + + b.Navigation("WebTemplate"); + }); + + modelBuilder.Entity("RoleUser", b => + { + b.HasOne("Raytha.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RolesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("UserUserGroup", b => + { + b.HasOne("Raytha.Domain.Entities.UserGroup", null) + .WithMany() + .HasForeignKey("UserGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("UserView", b => + { + b.HasOne("Raytha.Domain.Entities.View", null) + .WithMany() + .HasForeignKey("FavoriteViewsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserFavoritesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItem", b => + { + b.Navigation("ContentItemRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentType", b => + { + b.Navigation("ContentTypeFields"); + + b.Navigation("Views"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplate", b => + { + b.Navigation("Revisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenu", b => + { + b.Navigation("NavigationMenuItems"); + + b.Navigation("NavigationMenuRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunction", b => + { + b.Navigation("Revisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Role", b => + { + b.Navigation("ContentTypeRolePermissions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Route", b => + { + b.Navigation("ContentItem") + .IsRequired(); + + b.Navigation("View") + .IsRequired(); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Theme", b => + { + b.Navigation("ThemeAccessToMediaItems"); + + b.Navigation("WebTemplates"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.User", b => + { + b.Navigation("ApiKeys"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplate", b => + { + b.Navigation("Revisions"); + + b.Navigation("TemplateAccessToModelDefinitions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Raytha.Migrations.Postgres/20241110181505_v1_4_0.cs b/src/Raytha.Migrations.Postgres/20241110181505_v1_4_0.cs new file mode 100644 index 00000000..8c1f26d0 --- /dev/null +++ b/src/Raytha.Migrations.Postgres/20241110181505_v1_4_0.cs @@ -0,0 +1,1830 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Raytha.Domain.Entities; + +#nullable disable + +namespace Raytha.Migrations.Postgres +{ + /// + public partial class v1_4_0 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AuditLogs", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + EntityId = table.Column(type: "uuid", nullable: true), + Category = table.Column(type: "text", nullable: false), + Request = table.Column(type: "text", nullable: false), + UserEmail = table.Column(type: "text", nullable: false), + IpAddress = table.Column(type: "text", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AuditLogs", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "BackgroundTasks", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Name = table.Column(type: "text", nullable: false), + Args = table.Column(type: "text", nullable: true), + ErrorMessage = table.Column(type: "text", nullable: true), + Status = table.Column(type: "text", nullable: false), + StatusInfo = table.Column(type: "text", nullable: true), + PercentComplete = table.Column(type: "integer", nullable: false), + NumberOfRetries = table.Column(type: "integer", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CompletionTime = table.Column(type: "timestamp with time zone", nullable: true), + TaskStep = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_BackgroundTasks", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "DataProtectionKeys", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + FriendlyName = table.Column(type: "text", nullable: true), + Xml = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_DataProtectionKeys", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "JwtLogins", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Jti = table.Column(type: "text", nullable: true), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_JwtLogins", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "OrganizationSettings", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + OrganizationName = table.Column(type: "text", nullable: true), + WebsiteUrl = table.Column(type: "text", nullable: true), + TimeZone = table.Column(type: "text", nullable: true), + DateFormat = table.Column(type: "text", nullable: true), + SmtpOverrideSystem = table.Column(type: "boolean", nullable: false), + SmtpHost = table.Column(type: "text", nullable: true), + SmtpPort = table.Column(type: "integer", nullable: true), + SmtpUsername = table.Column(type: "text", nullable: true), + SmtpPassword = table.Column(type: "text", nullable: true), + SmtpDefaultFromAddress = table.Column(type: "text", nullable: true), + SmtpDefaultFromName = table.Column(type: "text", nullable: true), + HomePageId = table.Column(type: "uuid", nullable: true), + HomePageType = table.Column(type: "text", nullable: false), + ActiveThemeId = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_OrganizationSettings", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Routes", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Path = table.Column(type: "text", nullable: false), + ContentItemId = table.Column(type: "uuid", nullable: false), + ViewId = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Routes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ApiKeys", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + ApiKeyHash = table.Column(type: "bytea", nullable: false), + UserId = table.Column(type: "uuid", nullable: false), + CreatorUserId = table.Column(type: "uuid", nullable: true), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiKeys", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AuthenticationSchemes", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + IsBuiltInAuth = table.Column(type: "boolean", nullable: false), + IsEnabledForUsers = table.Column(type: "boolean", nullable: false), + IsEnabledForAdmins = table.Column(type: "boolean", nullable: false), + AuthenticationSchemeType = table.Column(type: "text", nullable: true), + Label = table.Column(type: "text", nullable: true), + DeveloperName = table.Column(type: "text", nullable: true), + MagicLinkExpiresInSeconds = table.Column(type: "integer", nullable: false), + SamlCertificate = table.Column(type: "text", nullable: true), + SamlIdpEntityId = table.Column(type: "text", nullable: true), + JwtSecretKey = table.Column(type: "text", nullable: true), + JwtUseHighSecurity = table.Column(type: "boolean", nullable: false), + SignInUrl = table.Column(type: "text", nullable: true), + LoginButtonText = table.Column(type: "text", nullable: true), + SignOutUrl = table.Column(type: "text", nullable: true), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AuthenticationSchemes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + IsAdmin = table.Column(type: "boolean", nullable: false), + IsActive = table.Column(type: "boolean", nullable: false), + LastLoggedInTime = table.Column(type: "timestamp with time zone", nullable: true), + Salt = table.Column(type: "bytea", nullable: false), + PasswordHash = table.Column(type: "bytea", nullable: false), + SsoId = table.Column(type: "text", nullable: true), + AuthenticationSchemeId = table.Column(type: "uuid", nullable: true), + FirstName = table.Column(type: "text", nullable: false), + LastName = table.Column(type: "text", nullable: false), + EmailAddress = table.Column(type: "text", nullable: false), + IsEmailAddressConfirmed = table.Column(type: "boolean", nullable: false), + _RecentlyAccessedViews = table.Column(type: "text", nullable: true), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + table.ForeignKey( + name: "FK_Users_AuthenticationSchemes_AuthenticationSchemeId", + column: x => x.AuthenticationSchemeId, + principalTable: "AuthenticationSchemes", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_Users_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_Users_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "ContentTypes", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + IsActive = table.Column(type: "boolean", nullable: false), + LabelPlural = table.Column(type: "text", nullable: true), + LabelSingular = table.Column(type: "text", nullable: true), + DeveloperName = table.Column(type: "text", nullable: true), + Description = table.Column(type: "text", nullable: true), + DefaultRouteTemplate = table.Column(type: "text", nullable: true), + PrimaryFieldId = table.Column(type: "uuid", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true), + DeleterUserId = table.Column(type: "uuid", nullable: true), + DeletionTime = table.Column(type: "timestamp with time zone", nullable: true), + IsDeleted = table.Column(type: "boolean", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ContentTypes", x => x.Id); + table.ForeignKey( + name: "FK_ContentTypes_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_ContentTypes_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "EmailTemplates", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Subject = table.Column(type: "text", nullable: true), + DeveloperName = table.Column(type: "text", nullable: true), + Cc = table.Column(type: "text", nullable: true), + Bcc = table.Column(type: "text", nullable: true), + Content = table.Column(type: "text", nullable: true), + IsBuiltInTemplate = table.Column(type: "boolean", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EmailTemplates", x => x.Id); + table.ForeignKey( + name: "FK_EmailTemplates_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_EmailTemplates_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "MediaItems", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Length = table.Column(type: "bigint", nullable: false), + FileName = table.Column(type: "text", nullable: false), + ContentType = table.Column(type: "text", nullable: false), + FileStorageProvider = table.Column(type: "text", nullable: false), + ObjectKey = table.Column(type: "text", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_MediaItems", x => x.Id); + table.ForeignKey( + name: "FK_MediaItems_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_MediaItems_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "NavigationMenus", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Label = table.Column(type: "text", nullable: false), + DeveloperName = table.Column(type: "text", nullable: false), + IsMainMenu = table.Column(type: "boolean", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_NavigationMenus", x => x.Id); + table.ForeignKey( + name: "FK_NavigationMenus_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_NavigationMenus_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "OneTimePasswords", + columns: table => new + { + Id = table.Column(type: "bytea", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + ExpiresAt = table.Column(type: "timestamp with time zone", nullable: false), + IsUsed = table.Column(type: "boolean", nullable: false), + UserId = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_OneTimePasswords", x => x.Id); + table.ForeignKey( + name: "FK_OneTimePasswords_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "RaythaFunctions", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Name = table.Column(type: "text", nullable: false), + DeveloperName = table.Column(type: "text", nullable: false), + TriggerType = table.Column(type: "text", nullable: false), + Code = table.Column(type: "text", nullable: false), + IsActive = table.Column(type: "boolean", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_RaythaFunctions", x => x.Id); + table.ForeignKey( + name: "FK_RaythaFunctions_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_RaythaFunctions_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "Roles", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Label = table.Column(type: "text", nullable: false), + DeveloperName = table.Column(type: "text", nullable: false), + SystemPermissions = table.Column(type: "integer", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Roles", x => x.Id); + table.ForeignKey( + name: "FK_Roles_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_Roles_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "Themes", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Title = table.Column(type: "text", nullable: false), + DeveloperName = table.Column(type: "text", nullable: false), + Description = table.Column(type: "text", nullable: false), + IsExportable = table.Column(type: "boolean", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Themes", x => x.Id); + table.ForeignKey( + name: "FK_Themes_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_Themes_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "UserGroups", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Label = table.Column(type: "text", nullable: false), + DeveloperName = table.Column(type: "text", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserGroups", x => x.Id); + table.ForeignKey( + name: "FK_UserGroups_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_UserGroups_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "VerificationCodes", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Code = table.Column(type: "uuid", nullable: false), + ExpiresAt = table.Column(type: "timestamp with time zone", nullable: false), + Completed = table.Column(type: "boolean", nullable: false), + EmailAddress = table.Column(type: "text", nullable: true), + VerificationCodeType = table.Column(type: "text", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_VerificationCodes", x => x.Id); + table.ForeignKey( + name: "FK_VerificationCodes_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_VerificationCodes_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "ContentItems", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + IsPublished = table.Column(type: "boolean", nullable: false), + IsDraft = table.Column(type: "boolean", nullable: false), + _DraftContent = table.Column(type: "text", nullable: true), + _PublishedContent = table.Column(type: "jsonb", nullable: true), + ContentTypeId = table.Column(type: "uuid", nullable: false), + RouteId = table.Column(type: "uuid", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ContentItems", x => x.Id); + table.ForeignKey( + name: "FK_ContentItems_ContentTypes_ContentTypeId", + column: x => x.ContentTypeId, + principalTable: "ContentTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ContentItems_Routes_RouteId", + column: x => x.RouteId, + principalTable: "Routes", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_ContentItems_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_ContentItems_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "ContentTypeFields", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Label = table.Column(type: "text", nullable: true), + DeveloperName = table.Column(type: "text", nullable: true), + Description = table.Column(type: "text", nullable: true), + FieldOrder = table.Column(type: "integer", nullable: false), + IsRequired = table.Column(type: "boolean", nullable: false), + RelatedContentTypeId = table.Column(type: "uuid", nullable: true), + ContentTypeId = table.Column(type: "uuid", nullable: false), + FieldType = table.Column(type: "text", nullable: false), + _Choices = table.Column(type: "text", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true), + DeleterUserId = table.Column(type: "uuid", nullable: true), + DeletionTime = table.Column(type: "timestamp with time zone", nullable: true), + IsDeleted = table.Column(type: "boolean", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ContentTypeFields", x => x.Id); + table.ForeignKey( + name: "FK_ContentTypeFields_ContentTypes_ContentTypeId", + column: x => x.ContentTypeId, + principalTable: "ContentTypes", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_ContentTypeFields_ContentTypes_RelatedContentTypeId", + column: x => x.RelatedContentTypeId, + principalTable: "ContentTypes", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_ContentTypeFields_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_ContentTypeFields_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "DeletedContentItems", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + _PublishedContent = table.Column(type: "text", nullable: true), + PrimaryField = table.Column(type: "text", nullable: true), + ContentTypeId = table.Column(type: "uuid", nullable: false), + OriginalContentItemId = table.Column(type: "uuid", nullable: false), + RoutePath = table.Column(type: "text", nullable: false), + WebTemplateIdsJson = table.Column(type: "text", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_DeletedContentItems", x => x.Id); + table.ForeignKey( + name: "FK_DeletedContentItems_ContentTypes_ContentTypeId", + column: x => x.ContentTypeId, + principalTable: "ContentTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_DeletedContentItems_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_DeletedContentItems_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "Views", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Label = table.Column(type: "text", nullable: true), + DeveloperName = table.Column(type: "text", nullable: true), + Description = table.Column(type: "text", nullable: true), + ContentTypeId = table.Column(type: "uuid", nullable: false), + RouteId = table.Column(type: "uuid", nullable: false), + IsPublished = table.Column(type: "boolean", nullable: false), + DefaultNumberOfItemsPerPage = table.Column(type: "integer", nullable: false), + MaxNumberOfItemsPerPage = table.Column(type: "integer", nullable: false), + IgnoreClientFilterAndSortQueryParams = table.Column(type: "boolean", nullable: false), + _Columns = table.Column(type: "text", nullable: true), + _Filter = table.Column(type: "text", nullable: true), + _Sort = table.Column(type: "text", nullable: true), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Views", x => x.Id); + table.ForeignKey( + name: "FK_Views_ContentTypes_ContentTypeId", + column: x => x.ContentTypeId, + principalTable: "ContentTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Views_Routes_RouteId", + column: x => x.RouteId, + principalTable: "Routes", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_Views_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_Views_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "EmailTemplateRevisions", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Subject = table.Column(type: "text", nullable: true), + Content = table.Column(type: "text", nullable: true), + Cc = table.Column(type: "text", nullable: true), + Bcc = table.Column(type: "text", nullable: true), + EmailTemplateId = table.Column(type: "uuid", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EmailTemplateRevisions", x => x.Id); + table.ForeignKey( + name: "FK_EmailTemplateRevisions_EmailTemplates_EmailTemplateId", + column: x => x.EmailTemplateId, + principalTable: "EmailTemplates", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_EmailTemplateRevisions_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_EmailTemplateRevisions_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "NavigationMenuItems", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Label = table.Column(type: "text", nullable: false), + Url = table.Column(type: "text", nullable: false), + IsDisabled = table.Column(type: "boolean", nullable: false), + OpenInNewTab = table.Column(type: "boolean", nullable: false), + CssClassName = table.Column(type: "text", nullable: true), + Ordinal = table.Column(type: "integer", nullable: false), + ParentNavigationMenuItemId = table.Column(type: "uuid", nullable: true), + NavigationMenuId = table.Column(type: "uuid", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_NavigationMenuItems", x => x.Id); + table.ForeignKey( + name: "FK_NavigationMenuItems_NavigationMenuItems_ParentNavigationMen~", + column: x => x.ParentNavigationMenuItemId, + principalTable: "NavigationMenuItems", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_NavigationMenuItems_NavigationMenus_NavigationMenuId", + column: x => x.NavigationMenuId, + principalTable: "NavigationMenus", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_NavigationMenuItems_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_NavigationMenuItems_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "NavigationMenuRevisions", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + NavigationMenuItemsJson = table.Column(type: "text", nullable: false), + NavigationMenuId = table.Column(type: "uuid", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_NavigationMenuRevisions", x => x.Id); + table.ForeignKey( + name: "FK_NavigationMenuRevisions_NavigationMenus_NavigationMenuId", + column: x => x.NavigationMenuId, + principalTable: "NavigationMenus", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_NavigationMenuRevisions_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_NavigationMenuRevisions_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "RaythaFunctionRevisions", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Code = table.Column(type: "text", nullable: false), + RaythaFunctionId = table.Column(type: "uuid", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_RaythaFunctionRevisions", x => x.Id); + table.ForeignKey( + name: "FK_RaythaFunctionRevisions_RaythaFunctions_RaythaFunctionId", + column: x => x.RaythaFunctionId, + principalTable: "RaythaFunctions", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_RaythaFunctionRevisions_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_RaythaFunctionRevisions_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "ContentTypeRolePermission", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + ContentTypeId = table.Column(type: "uuid", nullable: false), + ContentTypePermissions = table.Column(type: "integer", nullable: false), + RoleId = table.Column(type: "uuid", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ContentTypeRolePermission", x => x.Id); + table.ForeignKey( + name: "FK_ContentTypeRolePermission_ContentTypes_ContentTypeId", + column: x => x.ContentTypeId, + principalTable: "ContentTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ContentTypeRolePermission_Roles_RoleId", + column: x => x.RoleId, + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ContentTypeRolePermission_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_ContentTypeRolePermission_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "RoleUser", + columns: table => new + { + RolesId = table.Column(type: "uuid", nullable: false), + UsersId = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RoleUser", x => new { x.RolesId, x.UsersId }); + table.ForeignKey( + name: "FK_RoleUser_Roles_RolesId", + column: x => x.RolesId, + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_RoleUser_Users_UsersId", + column: x => x.UsersId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ThemeAccessToMediaItems", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + ThemeId = table.Column(type: "uuid", nullable: false), + MediaItemId = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ThemeAccessToMediaItems", x => x.Id); + table.ForeignKey( + name: "FK_ThemeAccessToMediaItems_MediaItems_MediaItemId", + column: x => x.MediaItemId, + principalTable: "MediaItems", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ThemeAccessToMediaItems_Themes_ThemeId", + column: x => x.ThemeId, + principalTable: "Themes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "WebTemplates", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + ThemeId = table.Column(type: "uuid", nullable: false), + IsBaseLayout = table.Column(type: "boolean", nullable: false), + Label = table.Column(type: "text", nullable: true), + DeveloperName = table.Column(type: "text", nullable: true), + Content = table.Column(type: "text", nullable: true), + IsBuiltInTemplate = table.Column(type: "boolean", nullable: false), + ParentTemplateId = table.Column(type: "uuid", nullable: true), + AllowAccessForNewContentTypes = table.Column(type: "boolean", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_WebTemplates", x => x.Id); + table.ForeignKey( + name: "FK_WebTemplates_Themes_ThemeId", + column: x => x.ThemeId, + principalTable: "Themes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_WebTemplates_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_WebTemplates_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_WebTemplates_WebTemplates_ParentTemplateId", + column: x => x.ParentTemplateId, + principalTable: "WebTemplates", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "UserUserGroup", + columns: table => new + { + UserGroupsId = table.Column(type: "uuid", nullable: false), + UsersId = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserUserGroup", x => new { x.UserGroupsId, x.UsersId }); + table.ForeignKey( + name: "FK_UserUserGroup_UserGroups_UserGroupsId", + column: x => x.UserGroupsId, + principalTable: "UserGroups", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_UserUserGroup_Users_UsersId", + column: x => x.UsersId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ContentItemRevisions", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + _PublishedContent = table.Column(type: "text", nullable: true), + ContentItemId = table.Column(type: "uuid", nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ContentItemRevisions", x => x.Id); + table.ForeignKey( + name: "FK_ContentItemRevisions_ContentItems_ContentItemId", + column: x => x.ContentItemId, + principalTable: "ContentItems", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ContentItemRevisions_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_ContentItemRevisions_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "UserView", + columns: table => new + { + FavoriteViewsId = table.Column(type: "uuid", nullable: false), + UserFavoritesId = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserView", x => new { x.FavoriteViewsId, x.UserFavoritesId }); + table.ForeignKey( + name: "FK_UserView_Users_UserFavoritesId", + column: x => x.UserFavoritesId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_UserView_Views_FavoriteViewsId", + column: x => x.FavoriteViewsId, + principalTable: "Views", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "WebTemplateAccessToModelDefinitions", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + WebTemplateId = table.Column(type: "uuid", nullable: false), + ContentTypeId = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_WebTemplateAccessToModelDefinitions", x => x.Id); + table.ForeignKey( + name: "FK_WebTemplateAccessToModelDefinitions_ContentTypes_ContentTyp~", + column: x => x.ContentTypeId, + principalTable: "ContentTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_WebTemplateAccessToModelDefinitions_WebTemplates_WebTemplat~", + column: x => x.WebTemplateId, + principalTable: "WebTemplates", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "WebTemplateContentItemRelations", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + WebTemplateId = table.Column(type: "uuid", nullable: false), + ContentItemId = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_WebTemplateContentItemRelations", x => x.Id); + table.ForeignKey( + name: "FK_WebTemplateContentItemRelations_ContentItems_ContentItemId", + column: x => x.ContentItemId, + principalTable: "ContentItems", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_WebTemplateContentItemRelations_WebTemplates_WebTemplateId", + column: x => x.WebTemplateId, + principalTable: "WebTemplates", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "WebTemplateRevisions", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Label = table.Column(type: "text", nullable: true), + Content = table.Column(type: "text", nullable: true), + WebTemplateId = table.Column(type: "uuid", nullable: false), + AllowAccessForNewContentTypes = table.Column(type: "boolean", nullable: false), + EmailTemplateId = table.Column(type: "uuid", nullable: true), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false), + LastModificationTime = table.Column(type: "timestamp with time zone", nullable: true), + CreatorUserId = table.Column(type: "uuid", nullable: true), + LastModifierUserId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_WebTemplateRevisions", x => x.Id); + table.ForeignKey( + name: "FK_WebTemplateRevisions_EmailTemplates_EmailTemplateId", + column: x => x.EmailTemplateId, + principalTable: "EmailTemplates", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_WebTemplateRevisions_Users_CreatorUserId", + column: x => x.CreatorUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_WebTemplateRevisions_Users_LastModifierUserId", + column: x => x.LastModifierUserId, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_WebTemplateRevisions_WebTemplates_WebTemplateId", + column: x => x.WebTemplateId, + principalTable: "WebTemplates", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "WebTemplateViewRelations", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + WebTemplateId = table.Column(type: "uuid", nullable: false), + ViewId = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_WebTemplateViewRelations", x => x.Id); + table.ForeignKey( + name: "FK_WebTemplateViewRelations_Views_ViewId", + column: x => x.ViewId, + principalTable: "Views", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_WebTemplateViewRelations_WebTemplates_WebTemplateId", + column: x => x.WebTemplateId, + principalTable: "WebTemplates", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ApiKeys_ApiKeyHash", + table: "ApiKeys", + column: "ApiKeyHash", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ApiKeys_CreatorUserId", + table: "ApiKeys", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiKeys_UserId", + table: "ApiKeys", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AuditLogs_Category", + table: "AuditLogs", + column: "Category"); + + migrationBuilder.CreateIndex( + name: "IX_AuditLogs_CreationTime", + table: "AuditLogs", + column: "CreationTime"); + + migrationBuilder.CreateIndex( + name: "IX_AuditLogs_EntityId", + table: "AuditLogs", + column: "EntityId"); + + migrationBuilder.CreateIndex( + name: "IX_AuthenticationSchemes_CreatorUserId", + table: "AuthenticationSchemes", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_AuthenticationSchemes_DeveloperName", + table: "AuthenticationSchemes", + column: "DeveloperName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AuthenticationSchemes_LastModifierUserId", + table: "AuthenticationSchemes", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentItemRevisions_ContentItemId", + table: "ContentItemRevisions", + column: "ContentItemId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentItemRevisions_CreatorUserId", + table: "ContentItemRevisions", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentItemRevisions_LastModifierUserId", + table: "ContentItemRevisions", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentItems_ContentTypeId", + table: "ContentItems", + column: "ContentTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentItems_CreatorUserId", + table: "ContentItems", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentItems_LastModifierUserId", + table: "ContentItems", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentItems_RouteId", + table: "ContentItems", + column: "RouteId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ContentTypeFields_ContentTypeId", + table: "ContentTypeFields", + column: "ContentTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentTypeFields_CreatorUserId", + table: "ContentTypeFields", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentTypeFields_LastModifierUserId", + table: "ContentTypeFields", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentTypeFields_RelatedContentTypeId", + table: "ContentTypeFields", + column: "RelatedContentTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentTypeRolePermission_ContentTypeId", + table: "ContentTypeRolePermission", + column: "ContentTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentTypeRolePermission_CreatorUserId", + table: "ContentTypeRolePermission", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentTypeRolePermission_LastModifierUserId", + table: "ContentTypeRolePermission", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentTypeRolePermission_RoleId", + table: "ContentTypeRolePermission", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentTypes_CreatorUserId", + table: "ContentTypes", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_ContentTypes_LastModifierUserId", + table: "ContentTypes", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_DeletedContentItems_ContentTypeId", + table: "DeletedContentItems", + column: "ContentTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_DeletedContentItems_CreatorUserId", + table: "DeletedContentItems", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_DeletedContentItems_LastModifierUserId", + table: "DeletedContentItems", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_EmailTemplateRevisions_CreatorUserId", + table: "EmailTemplateRevisions", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_EmailTemplateRevisions_EmailTemplateId", + table: "EmailTemplateRevisions", + column: "EmailTemplateId"); + + migrationBuilder.CreateIndex( + name: "IX_EmailTemplateRevisions_LastModifierUserId", + table: "EmailTemplateRevisions", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_EmailTemplates_CreatorUserId", + table: "EmailTemplates", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_EmailTemplates_DeveloperName", + table: "EmailTemplates", + column: "DeveloperName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_EmailTemplates_LastModifierUserId", + table: "EmailTemplates", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_JwtLogins_Jti", + table: "JwtLogins", + column: "Jti", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_MediaItems_CreatorUserId", + table: "MediaItems", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_MediaItems_LastModifierUserId", + table: "MediaItems", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_MediaItems_ObjectKey", + table: "MediaItems", + column: "ObjectKey"); + + migrationBuilder.CreateIndex( + name: "IX_NavigationMenuItems_CreatorUserId", + table: "NavigationMenuItems", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_NavigationMenuItems_LastModifierUserId", + table: "NavigationMenuItems", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_NavigationMenuItems_NavigationMenuId", + table: "NavigationMenuItems", + column: "NavigationMenuId"); + + migrationBuilder.CreateIndex( + name: "IX_NavigationMenuItems_ParentNavigationMenuItemId", + table: "NavigationMenuItems", + column: "ParentNavigationMenuItemId"); + + migrationBuilder.CreateIndex( + name: "IX_NavigationMenuRevisions_CreatorUserId", + table: "NavigationMenuRevisions", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_NavigationMenuRevisions_LastModifierUserId", + table: "NavigationMenuRevisions", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_NavigationMenuRevisions_NavigationMenuId", + table: "NavigationMenuRevisions", + column: "NavigationMenuId"); + + migrationBuilder.CreateIndex( + name: "IX_NavigationMenus_CreatorUserId", + table: "NavigationMenus", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_NavigationMenus_DeveloperName", + table: "NavigationMenus", + column: "DeveloperName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_NavigationMenus_LastModifierUserId", + table: "NavigationMenus", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_OneTimePasswords_UserId", + table: "OneTimePasswords", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_RaythaFunctionRevisions_CreatorUserId", + table: "RaythaFunctionRevisions", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_RaythaFunctionRevisions_LastModifierUserId", + table: "RaythaFunctionRevisions", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_RaythaFunctionRevisions_RaythaFunctionId", + table: "RaythaFunctionRevisions", + column: "RaythaFunctionId"); + + migrationBuilder.CreateIndex( + name: "IX_RaythaFunctions_CreatorUserId", + table: "RaythaFunctions", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_RaythaFunctions_DeveloperName", + table: "RaythaFunctions", + column: "DeveloperName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_RaythaFunctions_LastModifierUserId", + table: "RaythaFunctions", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_Roles_CreatorUserId", + table: "Roles", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_Roles_DeveloperName", + table: "Roles", + column: "DeveloperName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Roles_LastModifierUserId", + table: "Roles", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_RoleUser_UsersId", + table: "RoleUser", + column: "UsersId"); + + migrationBuilder.CreateIndex( + name: "IX_Routes_Path", + table: "Routes", + column: "Path", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ThemeAccessToMediaItems_MediaItemId", + table: "ThemeAccessToMediaItems", + column: "MediaItemId"); + + migrationBuilder.CreateIndex( + name: "IX_ThemeAccessToMediaItems_ThemeId", + table: "ThemeAccessToMediaItems", + column: "ThemeId"); + + migrationBuilder.CreateIndex( + name: "IX_Themes_CreatorUserId", + table: "Themes", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_Themes_DeveloperName", + table: "Themes", + column: "DeveloperName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Themes_LastModifierUserId", + table: "Themes", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_UserGroups_CreatorUserId", + table: "UserGroups", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_UserGroups_DeveloperName", + table: "UserGroups", + column: "DeveloperName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_UserGroups_LastModifierUserId", + table: "UserGroups", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_Users_AuthenticationSchemeId", + table: "Users", + column: "AuthenticationSchemeId"); + + migrationBuilder.CreateIndex( + name: "IX_Users_CreatorUserId", + table: "Users", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_Users_EmailAddress", + table: "Users", + column: "EmailAddress", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Users_LastModifierUserId", + table: "Users", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_Users_SsoId_AuthenticationSchemeId", + table: "Users", + columns: new[] { "SsoId", "AuthenticationSchemeId" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_UserUserGroup_UsersId", + table: "UserUserGroup", + column: "UsersId"); + + migrationBuilder.CreateIndex( + name: "IX_UserView_UserFavoritesId", + table: "UserView", + column: "UserFavoritesId"); + + migrationBuilder.CreateIndex( + name: "IX_VerificationCodes_CreatorUserId", + table: "VerificationCodes", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_VerificationCodes_LastModifierUserId", + table: "VerificationCodes", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_Views_ContentTypeId", + table: "Views", + column: "ContentTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_Views_CreatorUserId", + table: "Views", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_Views_LastModifierUserId", + table: "Views", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_Views_RouteId", + table: "Views", + column: "RouteId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplateAccessToModelDefinitions_ContentTypeId", + table: "WebTemplateAccessToModelDefinitions", + column: "ContentTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplateAccessToModelDefinitions_WebTemplateId", + table: "WebTemplateAccessToModelDefinitions", + column: "WebTemplateId"); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplateContentItemRelations_ContentItemId", + table: "WebTemplateContentItemRelations", + column: "ContentItemId"); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplateContentItemRelations_WebTemplateId_ContentItemId", + table: "WebTemplateContentItemRelations", + columns: new[] { "WebTemplateId", "ContentItemId" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplateRevisions_CreatorUserId", + table: "WebTemplateRevisions", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplateRevisions_EmailTemplateId", + table: "WebTemplateRevisions", + column: "EmailTemplateId"); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplateRevisions_LastModifierUserId", + table: "WebTemplateRevisions", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplateRevisions_WebTemplateId", + table: "WebTemplateRevisions", + column: "WebTemplateId"); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplates_CreatorUserId", + table: "WebTemplates", + column: "CreatorUserId"); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplates_DeveloperName_ThemeId", + table: "WebTemplates", + columns: new[] { "DeveloperName", "ThemeId" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplates_LastModifierUserId", + table: "WebTemplates", + column: "LastModifierUserId"); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplates_ParentTemplateId", + table: "WebTemplates", + column: "ParentTemplateId"); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplates_ThemeId", + table: "WebTemplates", + column: "ThemeId"); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplateViewRelations_ViewId_WebTemplateId", + table: "WebTemplateViewRelations", + columns: new[] { "ViewId", "WebTemplateId" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplateViewRelations_WebTemplateId", + table: "WebTemplateViewRelations", + column: "WebTemplateId"); + + migrationBuilder.AddForeignKey( + name: "FK_ApiKeys_Users_CreatorUserId", + table: "ApiKeys", + column: "CreatorUserId", + principalTable: "Users", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_ApiKeys_Users_UserId", + table: "ApiKeys", + column: "UserId", + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_AuthenticationSchemes_Users_CreatorUserId", + table: "AuthenticationSchemes", + column: "CreatorUserId", + principalTable: "Users", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_AuthenticationSchemes_Users_LastModifierUserId", + table: "AuthenticationSchemes", + column: "LastModifierUserId", + principalTable: "Users", + principalColumn: "Id"); + + var navigationMenuId = Guid.NewGuid(); + migrationBuilder.InsertData( + table: "NavigationMenus", + columns: new[] { "Id", "Label", "DeveloperName", "IsMainMenu", "CreationTime" }, + values: new object[] { navigationMenuId, "Main menu", "mainmenu", true, DateTime.UtcNow }); + + migrationBuilder.InsertData( + table: "NavigationMenuItems", + columns: new[] { "Id", "Label", "Url", "IsDisabled", "OpenInNewTab", "CssClassName", "Ordinal", "NavigationMenuId", "CreationTime" }, + values: new object[,] + { + {Guid.NewGuid(), "Home", "/home", false, false, "nav-link", 1, navigationMenuId, DateTime.UtcNow }, + {Guid.NewGuid(), "About", "/about", false, false, "nav-link", 2, navigationMenuId, DateTime.UtcNow }, + {Guid.NewGuid(), "Posts", "/posts", false, false, "nav-link", 3, navigationMenuId, DateTime.UtcNow }, + }); + + var defaultThemeId = Guid.NewGuid(); + + migrationBuilder.InsertData( + table: "Themes", + columns: new[] { "Id", "Title", "DeveloperName", "IsExportable", "Description", "CreationTime" }, + values: new object[,] + { + { defaultThemeId, "Raytha default theme", Theme.DEFAULT_THEME_DEVELOPER_NAME, false, "Raytha default theme", DateTime.UtcNow }, + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_AuthenticationSchemes_Users_CreatorUserId", + table: "AuthenticationSchemes"); + + migrationBuilder.DropForeignKey( + name: "FK_AuthenticationSchemes_Users_LastModifierUserId", + table: "AuthenticationSchemes"); + + migrationBuilder.DropTable( + name: "ApiKeys"); + + migrationBuilder.DropTable( + name: "AuditLogs"); + + migrationBuilder.DropTable( + name: "BackgroundTasks"); + + migrationBuilder.DropTable( + name: "ContentItemRevisions"); + + migrationBuilder.DropTable( + name: "ContentTypeFields"); + + migrationBuilder.DropTable( + name: "ContentTypeRolePermission"); + + migrationBuilder.DropTable( + name: "DataProtectionKeys"); + + migrationBuilder.DropTable( + name: "DeletedContentItems"); + + migrationBuilder.DropTable( + name: "EmailTemplateRevisions"); + + migrationBuilder.DropTable( + name: "JwtLogins"); + + migrationBuilder.DropTable( + name: "NavigationMenuItems"); + + migrationBuilder.DropTable( + name: "NavigationMenuRevisions"); + + migrationBuilder.DropTable( + name: "OneTimePasswords"); + + migrationBuilder.DropTable( + name: "OrganizationSettings"); + + migrationBuilder.DropTable( + name: "RaythaFunctionRevisions"); + + migrationBuilder.DropTable( + name: "RoleUser"); + + migrationBuilder.DropTable( + name: "ThemeAccessToMediaItems"); + + migrationBuilder.DropTable( + name: "UserUserGroup"); + + migrationBuilder.DropTable( + name: "UserView"); + + migrationBuilder.DropTable( + name: "VerificationCodes"); + + migrationBuilder.DropTable( + name: "WebTemplateAccessToModelDefinitions"); + + migrationBuilder.DropTable( + name: "WebTemplateContentItemRelations"); + + migrationBuilder.DropTable( + name: "WebTemplateRevisions"); + + migrationBuilder.DropTable( + name: "WebTemplateViewRelations"); + + migrationBuilder.DropTable( + name: "NavigationMenus"); + + migrationBuilder.DropTable( + name: "RaythaFunctions"); + + migrationBuilder.DropTable( + name: "Roles"); + + migrationBuilder.DropTable( + name: "MediaItems"); + + migrationBuilder.DropTable( + name: "UserGroups"); + + migrationBuilder.DropTable( + name: "ContentItems"); + + migrationBuilder.DropTable( + name: "EmailTemplates"); + + migrationBuilder.DropTable( + name: "Views"); + + migrationBuilder.DropTable( + name: "WebTemplates"); + + migrationBuilder.DropTable( + name: "ContentTypes"); + + migrationBuilder.DropTable( + name: "Routes"); + + migrationBuilder.DropTable( + name: "Themes"); + + migrationBuilder.DropTable( + name: "Users"); + + migrationBuilder.DropTable( + name: "AuthenticationSchemes"); + } + } +} diff --git a/src/Raytha.Migrations.Postgres/Raytha.Migrations.Postgres.csproj b/src/Raytha.Migrations.Postgres/Raytha.Migrations.Postgres.csproj new file mode 100644 index 00000000..35a39f42 --- /dev/null +++ b/src/Raytha.Migrations.Postgres/Raytha.Migrations.Postgres.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/src/Raytha.Migrations.Postgres/RaythaDbContextModelSnapshot.cs b/src/Raytha.Migrations.Postgres/RaythaDbContextModelSnapshot.cs new file mode 100644 index 00000000..60abf572 --- /dev/null +++ b/src/Raytha.Migrations.Postgres/RaythaDbContextModelSnapshot.cs @@ -0,0 +1,2268 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Raytha.Infrastructure.Persistence; + +#nullable disable + +namespace Raytha.Migrations.Postgres +{ + [DbContext(typeof(RaythaDbContext))] + partial class RaythaDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FriendlyName") + .HasColumnType("text"); + + b.Property("Xml") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("DataProtectionKeys"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ApiKeyHash") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ApiKeyHash") + .IsUnique(); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKeys"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Category") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("EntityId") + .HasColumnType("uuid"); + + b.Property("IpAddress") + .IsRequired() + .HasColumnType("text"); + + b.Property("Request") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserEmail") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("CreationTime"); + + b.HasIndex("EntityId"); + + b.ToTable("AuditLogs"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.AuthenticationScheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuthenticationSchemeType") + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeveloperName") + .HasColumnType("text"); + + b.Property("IsBuiltInAuth") + .HasColumnType("boolean"); + + b.Property("IsEnabledForAdmins") + .HasColumnType("boolean"); + + b.Property("IsEnabledForUsers") + .HasColumnType("boolean"); + + b.Property("JwtSecretKey") + .HasColumnType("text"); + + b.Property("JwtUseHighSecurity") + .HasColumnType("boolean"); + + b.Property("Label") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("LoginButtonText") + .HasColumnType("text"); + + b.Property("MagicLinkExpiresInSeconds") + .HasColumnType("integer"); + + b.Property("SamlCertificate") + .HasColumnType("text"); + + b.Property("SamlIdpEntityId") + .HasColumnType("text"); + + b.Property("SignInUrl") + .HasColumnType("text"); + + b.Property("SignOutUrl") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("AuthenticationSchemes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.BackgroundTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Args") + .HasColumnType("text"); + + b.Property("CompletionTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ErrorMessage") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("NumberOfRetries") + .HasColumnType("integer"); + + b.Property("PercentComplete") + .HasColumnType("integer"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("StatusInfo") + .HasColumnType("text"); + + b.Property("TaskStep") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("BackgroundTasks"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentTypeId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("IsDraft") + .HasColumnType("boolean"); + + b.Property("IsPublished") + .HasColumnType("boolean"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("RouteId") + .HasColumnType("uuid"); + + b.Property("_DraftContent") + .HasColumnType("text"); + + b.Property("_PublishedContent") + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RouteId") + .IsUnique(); + + b.ToTable("ContentItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItemRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentItemId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("_PublishedContent") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ContentItemId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("ContentItemRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DefaultRouteTemplate") + .HasColumnType("text"); + + b.Property("DeleterUserId") + .HasColumnType("uuid"); + + b.Property("DeletionTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("DeveloperName") + .HasColumnType("text"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LabelPlural") + .HasColumnType("text"); + + b.Property("LabelSingular") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("PrimaryFieldId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("ContentTypes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentTypeField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentTypeId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeleterUserId") + .HasColumnType("uuid"); + + b.Property("DeletionTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("DeveloperName") + .HasColumnType("text"); + + b.Property("FieldOrder") + .HasColumnType("integer"); + + b.Property("FieldType") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsRequired") + .HasColumnType("boolean"); + + b.Property("Label") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("RelatedContentTypeId") + .HasColumnType("uuid"); + + b.Property("_Choices") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RelatedContentTypeId"); + + b.ToTable("ContentTypeFields"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentTypeRolePermission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentTypeId") + .HasColumnType("uuid"); + + b.Property("ContentTypePermissions") + .HasColumnType("integer"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RoleId"); + + b.ToTable("ContentTypeRolePermission"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.DeletedContentItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentTypeId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("OriginalContentItemId") + .HasColumnType("uuid"); + + b.Property("PrimaryField") + .HasColumnType("text"); + + b.Property("RoutePath") + .IsRequired() + .HasColumnType("text"); + + b.Property("WebTemplateIdsJson") + .IsRequired() + .HasColumnType("text"); + + b.Property("_PublishedContent") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("DeletedContentItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Bcc") + .HasColumnType("text"); + + b.Property("Cc") + .HasColumnType("text"); + + b.Property("Content") + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeveloperName") + .HasColumnType("text"); + + b.Property("IsBuiltInTemplate") + .HasColumnType("boolean"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("Subject") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("EmailTemplates"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplateRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Bcc") + .HasColumnType("text"); + + b.Property("Cc") + .HasColumnType("text"); + + b.Property("Content") + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("EmailTemplateId") + .HasColumnType("uuid"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("Subject") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("EmailTemplateId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("EmailTemplateRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.JwtLogin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Jti") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Jti") + .IsUnique(); + + b.ToTable("JwtLogins"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.MediaItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentType") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasColumnType("text"); + + b.Property("FileStorageProvider") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("Length") + .HasColumnType("bigint"); + + b.Property("ObjectKey") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("ObjectKey"); + + b.ToTable("MediaItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenu", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsMainMenu") + .HasColumnType("boolean"); + + b.Property("Label") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("NavigationMenus"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenuItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("CssClassName") + .HasColumnType("text"); + + b.Property("IsDisabled") + .HasColumnType("boolean"); + + b.Property("Label") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("NavigationMenuId") + .HasColumnType("uuid"); + + b.Property("OpenInNewTab") + .HasColumnType("boolean"); + + b.Property("Ordinal") + .HasColumnType("integer"); + + b.Property("ParentNavigationMenuItemId") + .HasColumnType("uuid"); + + b.Property("Url") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("NavigationMenuId"); + + b.HasIndex("ParentNavigationMenuItemId"); + + b.ToTable("NavigationMenuItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenuRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("NavigationMenuId") + .HasColumnType("uuid"); + + b.Property("NavigationMenuItemsJson") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("NavigationMenuId"); + + b.ToTable("NavigationMenuRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.OneTimePassword", b => + { + b.Property("Id") + .HasColumnType("bytea"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IsUsed") + .HasColumnType("boolean"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("OneTimePasswords"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.OrganizationSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ActiveThemeId") + .HasColumnType("uuid"); + + b.Property("DateFormat") + .HasColumnType("text"); + + b.Property("HomePageId") + .HasColumnType("uuid"); + + b.Property("HomePageType") + .IsRequired() + .HasColumnType("text"); + + b.Property("OrganizationName") + .HasColumnType("text"); + + b.Property("SmtpDefaultFromAddress") + .HasColumnType("text"); + + b.Property("SmtpDefaultFromName") + .HasColumnType("text"); + + b.Property("SmtpHost") + .HasColumnType("text"); + + b.Property("SmtpOverrideSystem") + .HasColumnType("boolean"); + + b.Property("SmtpPassword") + .HasColumnType("text"); + + b.Property("SmtpPort") + .HasColumnType("integer"); + + b.Property("SmtpUsername") + .HasColumnType("text"); + + b.Property("TimeZone") + .HasColumnType("text"); + + b.Property("WebsiteUrl") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("OrganizationSettings"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("TriggerType") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("RaythaFunctions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunctionRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("RaythaFunctionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RaythaFunctionId"); + + b.ToTable("RaythaFunctionRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Label") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("SystemPermissions") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Route", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentItemId") + .HasColumnType("uuid"); + + b.Property("Path") + .IsRequired() + .HasColumnType("text"); + + b.Property("ViewId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("Path") + .IsUnique(); + + b.ToTable("Routes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Theme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsExportable") + .HasColumnType("boolean"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("Themes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ThemeAccessToMediaItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MediaItemId") + .HasColumnType("uuid"); + + b.Property("ThemeId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("ThemeId"); + + b.ToTable("ThemeAccessToMediaItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuthenticationSchemeId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("EmailAddress") + .IsRequired() + .HasColumnType("text"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsAdmin") + .HasColumnType("boolean"); + + b.Property("IsEmailAddressConfirmed") + .HasColumnType("boolean"); + + b.Property("LastLoggedInTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("text"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("Salt") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("SsoId") + .HasColumnType("text"); + + b.Property("_RecentlyAccessedViews") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("AuthenticationSchemeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("EmailAddress") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("SsoId", "AuthenticationSchemeId") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.UserGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Label") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("UserGroups"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.VerificationCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .HasColumnType("uuid"); + + b.Property("Completed") + .HasColumnType("boolean"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("EmailAddress") + .HasColumnType("text"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("VerificationCodeType") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("VerificationCodes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.View", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentTypeId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DefaultNumberOfItemsPerPage") + .HasColumnType("integer"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("DeveloperName") + .HasColumnType("text"); + + b.Property("IgnoreClientFilterAndSortQueryParams") + .HasColumnType("boolean"); + + b.Property("IsPublished") + .HasColumnType("boolean"); + + b.Property("Label") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("MaxNumberOfItemsPerPage") + .HasColumnType("integer"); + + b.Property("RouteId") + .HasColumnType("uuid"); + + b.Property("_Columns") + .HasColumnType("text"); + + b.Property("_Filter") + .HasColumnType("text"); + + b.Property("_Sort") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RouteId") + .IsUnique(); + + b.ToTable("Views"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AllowAccessForNewContentTypes") + .HasColumnType("boolean"); + + b.Property("Content") + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("DeveloperName") + .HasColumnType("text"); + + b.Property("IsBaseLayout") + .HasColumnType("boolean"); + + b.Property("IsBuiltInTemplate") + .HasColumnType("boolean"); + + b.Property("Label") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("ParentTemplateId") + .HasColumnType("uuid"); + + b.Property("ThemeId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("ParentTemplateId"); + + b.HasIndex("ThemeId"); + + b.HasIndex("DeveloperName", "ThemeId") + .IsUnique(); + + b.ToTable("WebTemplates"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateAccessToModelDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentTypeId") + .HasColumnType("uuid"); + + b.Property("WebTemplateId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("WebTemplateId"); + + b.ToTable("WebTemplateAccessToModelDefinitions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateContentItemRelation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ContentItemId") + .HasColumnType("uuid"); + + b.Property("WebTemplateId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ContentItemId"); + + b.HasIndex("WebTemplateId", "ContentItemId") + .IsUnique(); + + b.ToTable("WebTemplateContentItemRelations"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AllowAccessForNewContentTypes") + .HasColumnType("boolean"); + + b.Property("Content") + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorUserId") + .HasColumnType("uuid"); + + b.Property("EmailTemplateId") + .HasColumnType("uuid"); + + b.Property("Label") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifierUserId") + .HasColumnType("uuid"); + + b.Property("WebTemplateId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("EmailTemplateId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("WebTemplateId"); + + b.ToTable("WebTemplateRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateViewRelation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ViewId") + .HasColumnType("uuid"); + + b.Property("WebTemplateId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("WebTemplateId"); + + b.HasIndex("ViewId", "WebTemplateId") + .IsUnique(); + + b.ToTable("WebTemplateViewRelations"); + }); + + modelBuilder.Entity("RoleUser", b => + { + b.Property("RolesId") + .HasColumnType("uuid"); + + b.Property("UsersId") + .HasColumnType("uuid"); + + b.HasKey("RolesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("RoleUser"); + }); + + modelBuilder.Entity("UserUserGroup", b => + { + b.Property("UserGroupsId") + .HasColumnType("uuid"); + + b.Property("UsersId") + .HasColumnType("uuid"); + + b.HasKey("UserGroupsId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("UserUserGroup"); + }); + + modelBuilder.Entity("UserView", b => + { + b.Property("FavoriteViewsId") + .HasColumnType("uuid"); + + b.Property("UserFavoritesId") + .HasColumnType("uuid"); + + b.HasKey("FavoriteViewsId", "UserFavoritesId"); + + b.HasIndex("UserFavoritesId"); + + b.ToTable("UserView"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ApiKey", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "User") + .WithMany("ApiKeys") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.AuthenticationScheme", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItem", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany() + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.Route", "Route") + .WithOne("ContentItem") + .HasForeignKey("Raytha.Domain.Entities.ContentItem", "RouteId") + .OnDelete(DeleteBehavior.ClientCascade) + .IsRequired(); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("Route"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItemRevision", b => + { + b.HasOne("Raytha.Domain.Entities.ContentItem", "ContentItem") + .WithMany("ContentItemRevisions") + .HasForeignKey("ContentItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("ContentItem"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentType", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentTypeField", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany("ContentTypeFields") + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.ContentType", "RelatedContentType") + .WithMany() + .HasForeignKey("RelatedContentTypeId"); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("RelatedContentType"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentTypeRolePermission", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany() + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.Role", "Role") + .WithMany("ContentTypeRolePermissions") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.DeletedContentItem", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany() + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplate", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplateRevision", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.EmailTemplate", "EmailTemplate") + .WithMany() + .HasForeignKey("EmailTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("EmailTemplate"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.MediaItem", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenu", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenuItem", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.NavigationMenu", "NavigationMenu") + .WithMany("NavigationMenuItems") + .HasForeignKey("NavigationMenuId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.NavigationMenuItem", "ParentNavigationMenuItem") + .WithMany() + .HasForeignKey("ParentNavigationMenuItemId") + .OnDelete(DeleteBehavior.ClientCascade); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("NavigationMenu"); + + b.Navigation("ParentNavigationMenuItem"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenuRevision", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.NavigationMenu", "NavigationMenu") + .WithMany("NavigationMenuRevisions") + .HasForeignKey("NavigationMenuId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("NavigationMenu"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.OneTimePassword", b => + { + b.HasOne("Raytha.Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunction", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunctionRevision", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.RaythaFunction", "RaythaFunction") + .WithMany("Revisions") + .HasForeignKey("RaythaFunctionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("RaythaFunction"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Role", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Theme", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ThemeAccessToMediaItem", b => + { + b.HasOne("Raytha.Domain.Entities.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.Theme", "Theme") + .WithMany("ThemeAccessToMediaItems") + .HasForeignKey("ThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaItem"); + + b.Navigation("Theme"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.User", b => + { + b.HasOne("Raytha.Domain.Entities.AuthenticationScheme", "AuthenticationScheme") + .WithMany() + .HasForeignKey("AuthenticationSchemeId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("AuthenticationScheme"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.UserGroup", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.VerificationCode", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.View", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany("Views") + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("Raytha.Domain.Entities.Route", "Route") + .WithOne("View") + .HasForeignKey("Raytha.Domain.Entities.View", "RouteId") + .OnDelete(DeleteBehavior.ClientCascade) + .IsRequired(); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("Route"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplate", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "ParentTemplate") + .WithMany() + .HasForeignKey("ParentTemplateId"); + + b.HasOne("Raytha.Domain.Entities.Theme", "Theme") + .WithMany("WebTemplates") + .HasForeignKey("ThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("ParentTemplate"); + + b.Navigation("Theme"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateAccessToModelDefinition", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany() + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "WebTemplate") + .WithMany("TemplateAccessToModelDefinitions") + .HasForeignKey("WebTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ContentType"); + + b.Navigation("WebTemplate"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateContentItemRelation", b => + { + b.HasOne("Raytha.Domain.Entities.ContentItem", "ContentItem") + .WithMany() + .HasForeignKey("ContentItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "WebTemplate") + .WithMany() + .HasForeignKey("WebTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ContentItem"); + + b.Navigation("WebTemplate"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateRevision", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.EmailTemplate", null) + .WithMany("Revisions") + .HasForeignKey("EmailTemplateId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "WebTemplate") + .WithMany("Revisions") + .HasForeignKey("WebTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("WebTemplate"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateViewRelation", b => + { + b.HasOne("Raytha.Domain.Entities.View", "View") + .WithMany() + .HasForeignKey("ViewId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "WebTemplate") + .WithMany() + .HasForeignKey("WebTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("View"); + + b.Navigation("WebTemplate"); + }); + + modelBuilder.Entity("RoleUser", b => + { + b.HasOne("Raytha.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RolesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("UserUserGroup", b => + { + b.HasOne("Raytha.Domain.Entities.UserGroup", null) + .WithMany() + .HasForeignKey("UserGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("UserView", b => + { + b.HasOne("Raytha.Domain.Entities.View", null) + .WithMany() + .HasForeignKey("FavoriteViewsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserFavoritesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItem", b => + { + b.Navigation("ContentItemRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentType", b => + { + b.Navigation("ContentTypeFields"); + + b.Navigation("Views"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplate", b => + { + b.Navigation("Revisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenu", b => + { + b.Navigation("NavigationMenuItems"); + + b.Navigation("NavigationMenuRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunction", b => + { + b.Navigation("Revisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Role", b => + { + b.Navigation("ContentTypeRolePermissions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Route", b => + { + b.Navigation("ContentItem") + .IsRequired(); + + b.Navigation("View") + .IsRequired(); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Theme", b => + { + b.Navigation("ThemeAccessToMediaItems"); + + b.Navigation("WebTemplates"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.User", b => + { + b.Navigation("ApiKeys"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplate", b => + { + b.Navigation("Revisions"); + + b.Navigation("TemplateAccessToModelDefinitions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Raytha.Infrastructure/Migrations/20221230221303_v0_9_0.Designer.cs b/src/Raytha.Migrations.SqlServer/20221230221303_v0_9_0.Designer.cs similarity index 99% rename from src/Raytha.Infrastructure/Migrations/20221230221303_v0_9_0.Designer.cs rename to src/Raytha.Migrations.SqlServer/20221230221303_v0_9_0.Designer.cs index f74ef22b..355a4b92 100644 --- a/src/Raytha.Infrastructure/Migrations/20221230221303_v0_9_0.Designer.cs +++ b/src/Raytha.Migrations.SqlServer/20221230221303_v0_9_0.Designer.cs @@ -9,7 +9,7 @@ #nullable disable -namespace Raytha.Infrastructure.Migrations +namespace Raytha.Migrations.SqlServer { [DbContext(typeof(RaythaDbContext))] [Migration("20221230221303_v0_9_0")] diff --git a/src/Raytha.Infrastructure/Migrations/20221230221303_v0_9_0.cs b/src/Raytha.Migrations.SqlServer/20221230221303_v0_9_0.cs similarity index 99% rename from src/Raytha.Infrastructure/Migrations/20221230221303_v0_9_0.cs rename to src/Raytha.Migrations.SqlServer/20221230221303_v0_9_0.cs index fd2c9c86..65859aae 100644 --- a/src/Raytha.Infrastructure/Migrations/20221230221303_v0_9_0.cs +++ b/src/Raytha.Migrations.SqlServer/20221230221303_v0_9_0.cs @@ -3,7 +3,7 @@ #nullable disable -namespace Raytha.Infrastructure.Migrations +namespace Raytha.Migrations.SqlServer { /// public partial class v090 : Migration diff --git a/src/Raytha.Infrastructure/Migrations/20230211205159_v1_0_0.Designer.cs b/src/Raytha.Migrations.SqlServer/20230211205159_v1_0_0.Designer.cs similarity index 99% rename from src/Raytha.Infrastructure/Migrations/20230211205159_v1_0_0.Designer.cs rename to src/Raytha.Migrations.SqlServer/20230211205159_v1_0_0.Designer.cs index e0bd5f19..14a14a8c 100644 --- a/src/Raytha.Infrastructure/Migrations/20230211205159_v1_0_0.Designer.cs +++ b/src/Raytha.Migrations.SqlServer/20230211205159_v1_0_0.Designer.cs @@ -9,7 +9,7 @@ #nullable disable -namespace Raytha.Infrastructure.Migrations +namespace Raytha.Migrations.SqlServer { [DbContext(typeof(RaythaDbContext))] [Migration("20230211205159_v1_0_0")] diff --git a/src/Raytha.Infrastructure/Migrations/20230211205159_v1_0_0.cs b/src/Raytha.Migrations.SqlServer/20230211205159_v1_0_0.cs similarity index 99% rename from src/Raytha.Infrastructure/Migrations/20230211205159_v1_0_0.cs rename to src/Raytha.Migrations.SqlServer/20230211205159_v1_0_0.cs index 0e5bde50..a8f23e8c 100644 --- a/src/Raytha.Infrastructure/Migrations/20230211205159_v1_0_0.cs +++ b/src/Raytha.Migrations.SqlServer/20230211205159_v1_0_0.cs @@ -3,7 +3,7 @@ #nullable disable -namespace Raytha.Infrastructure.Migrations +namespace Raytha.Migrations.SqlServer { /// public partial class v100 : Migration diff --git a/src/Raytha.Infrastructure/Migrations/20230521175706_v1_1_0.Designer.cs b/src/Raytha.Migrations.SqlServer/20230521175706_v1_1_0.Designer.cs similarity index 99% rename from src/Raytha.Infrastructure/Migrations/20230521175706_v1_1_0.Designer.cs rename to src/Raytha.Migrations.SqlServer/20230521175706_v1_1_0.Designer.cs index 824e05e1..dac4b4ae 100644 --- a/src/Raytha.Infrastructure/Migrations/20230521175706_v1_1_0.Designer.cs +++ b/src/Raytha.Migrations.SqlServer/20230521175706_v1_1_0.Designer.cs @@ -9,7 +9,7 @@ #nullable disable -namespace Raytha.Infrastructure.Migrations +namespace Raytha.Migrations.SqlServer { [DbContext(typeof(RaythaDbContext))] [Migration("20230521175706_v1_1_0")] diff --git a/src/Raytha.Infrastructure/Migrations/20230521175706_v1_1_0.cs b/src/Raytha.Migrations.SqlServer/20230521175706_v1_1_0.cs similarity index 97% rename from src/Raytha.Infrastructure/Migrations/20230521175706_v1_1_0.cs rename to src/Raytha.Migrations.SqlServer/20230521175706_v1_1_0.cs index 44b710c7..86e64563 100644 --- a/src/Raytha.Infrastructure/Migrations/20230521175706_v1_1_0.cs +++ b/src/Raytha.Migrations.SqlServer/20230521175706_v1_1_0.cs @@ -3,7 +3,7 @@ #nullable disable -namespace Raytha.Infrastructure.Migrations +namespace Raytha.Migrations.SqlServer { /// public partial class v110 : Migration diff --git a/src/Raytha.Infrastructure/Migrations/20240314124844_v1_2_0.Designer.cs b/src/Raytha.Migrations.SqlServer/20240314124844_v1_2_0.Designer.cs similarity index 99% rename from src/Raytha.Infrastructure/Migrations/20240314124844_v1_2_0.Designer.cs rename to src/Raytha.Migrations.SqlServer/20240314124844_v1_2_0.Designer.cs index ff601656..edeb3b26 100644 --- a/src/Raytha.Infrastructure/Migrations/20240314124844_v1_2_0.Designer.cs +++ b/src/Raytha.Migrations.SqlServer/20240314124844_v1_2_0.Designer.cs @@ -9,7 +9,7 @@ #nullable disable -namespace Raytha.Infrastructure.Migrations +namespace Raytha.Migrations.SqlServer { [DbContext(typeof(RaythaDbContext))] [Migration("20240314124844_v1_2_0")] diff --git a/src/Raytha.Infrastructure/Migrations/20240314124844_v1_2_0.cs b/src/Raytha.Migrations.SqlServer/20240314124844_v1_2_0.cs similarity index 99% rename from src/Raytha.Infrastructure/Migrations/20240314124844_v1_2_0.cs rename to src/Raytha.Migrations.SqlServer/20240314124844_v1_2_0.cs index f77752b4..4708ee77 100644 --- a/src/Raytha.Infrastructure/Migrations/20240314124844_v1_2_0.cs +++ b/src/Raytha.Migrations.SqlServer/20240314124844_v1_2_0.cs @@ -3,7 +3,7 @@ #nullable disable -namespace Raytha.Infrastructure.Migrations +namespace Raytha.Migrations.SqlServer { /// public partial class v1_2_0 : Migration diff --git a/src/Raytha.Infrastructure/Migrations/20240502121207_v1_3_0.Designer.cs b/src/Raytha.Migrations.SqlServer/20240502121207_v1_3_0.Designer.cs similarity index 99% rename from src/Raytha.Infrastructure/Migrations/20240502121207_v1_3_0.Designer.cs rename to src/Raytha.Migrations.SqlServer/20240502121207_v1_3_0.Designer.cs index 047221b5..b0fa372f 100644 --- a/src/Raytha.Infrastructure/Migrations/20240502121207_v1_3_0.Designer.cs +++ b/src/Raytha.Migrations.SqlServer/20240502121207_v1_3_0.Designer.cs @@ -9,7 +9,7 @@ #nullable disable -namespace Raytha.Infrastructure.Migrations +namespace Raytha.Migrations.SqlServer { [DbContext(typeof(RaythaDbContext))] [Migration("20240502121207_v1_3_0")] diff --git a/src/Raytha.Infrastructure/Migrations/20240502121207_v1_3_0.cs b/src/Raytha.Migrations.SqlServer/20240502121207_v1_3_0.cs similarity index 99% rename from src/Raytha.Infrastructure/Migrations/20240502121207_v1_3_0.cs rename to src/Raytha.Migrations.SqlServer/20240502121207_v1_3_0.cs index eea186fe..22477307 100644 --- a/src/Raytha.Infrastructure/Migrations/20240502121207_v1_3_0.cs +++ b/src/Raytha.Migrations.SqlServer/20240502121207_v1_3_0.cs @@ -4,7 +4,7 @@ #nullable disable -namespace Raytha.Infrastructure.Migrations +namespace Raytha.Migrations.SqlServer { /// public partial class v1_3_0 : Migration diff --git a/src/Raytha.Migrations.SqlServer/20241116192521_v1_4_0.Designer.cs b/src/Raytha.Migrations.SqlServer/20241116192521_v1_4_0.Designer.cs new file mode 100644 index 00000000..85ce3f5f --- /dev/null +++ b/src/Raytha.Migrations.SqlServer/20241116192521_v1_4_0.Designer.cs @@ -0,0 +1,2276 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Raytha.Infrastructure.Persistence; + +#nullable disable + +namespace Raytha.Migrations.SqlServer +{ + [DbContext(typeof(RaythaDbContext))] + [Migration("20241116192521_v1_4_0")] + partial class v1_4_0 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("FriendlyName") + .HasColumnType("nvarchar(max)"); + + b.Property("Xml") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("DataProtectionKeys"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApiKeyHash") + .IsRequired() + .HasColumnType("varbinary(900)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ApiKeyHash") + .IsUnique(); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKeys"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Category") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("EntityId") + .HasColumnType("uniqueidentifier"); + + b.Property("IpAddress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Request") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserEmail") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("CreationTime"); + + b.HasIndex("EntityId"); + + b.ToTable("AuditLogs"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.AuthenticationScheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuthenticationSchemeType") + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeveloperName") + .HasColumnType("nvarchar(450)"); + + b.Property("IsBuiltInAuth") + .HasColumnType("bit"); + + b.Property("IsEnabledForAdmins") + .HasColumnType("bit"); + + b.Property("IsEnabledForUsers") + .HasColumnType("bit"); + + b.Property("JwtSecretKey") + .HasColumnType("nvarchar(max)"); + + b.Property("JwtUseHighSecurity") + .HasColumnType("bit"); + + b.Property("Label") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginButtonText") + .HasColumnType("nvarchar(max)"); + + b.Property("MagicLinkExpiresInSeconds") + .HasColumnType("int"); + + b.Property("SamlCertificate") + .HasColumnType("nvarchar(max)"); + + b.Property("SamlIdpEntityId") + .HasColumnType("nvarchar(max)"); + + b.Property("SignInUrl") + .HasColumnType("nvarchar(max)"); + + b.Property("SignOutUrl") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique() + .HasFilter("[DeveloperName] IS NOT NULL"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("AuthenticationSchemes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.BackgroundTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Args") + .HasColumnType("nvarchar(max)"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("ErrorMessage") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NumberOfRetries") + .HasColumnType("int"); + + b.Property("PercentComplete") + .HasColumnType("int"); + + b.Property("Status") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("StatusInfo") + .HasColumnType("nvarchar(max)"); + + b.Property("TaskStep") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("BackgroundTasks"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContentTypeId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDraft") + .HasColumnType("bit"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RouteId") + .HasColumnType("uniqueidentifier"); + + b.Property("_DraftContent") + .HasColumnType("nvarchar(max)"); + + b.Property("_PublishedContent") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RouteId") + .IsUnique(); + + b.ToTable("ContentItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItemRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContentItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("_PublishedContent") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ContentItemId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("ContentItemRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DefaultRouteTemplate") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DeveloperName") + .HasColumnType("nvarchar(max)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LabelPlural") + .HasColumnType("nvarchar(max)"); + + b.Property("LabelSingular") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("PrimaryFieldId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("ContentTypes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentTypeField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContentTypeId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeleterUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DeveloperName") + .HasColumnType("nvarchar(max)"); + + b.Property("FieldOrder") + .HasColumnType("int"); + + b.Property("FieldType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsRequired") + .HasColumnType("bit"); + + b.Property("Label") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RelatedContentTypeId") + .HasColumnType("uniqueidentifier"); + + b.Property("_Choices") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RelatedContentTypeId"); + + b.ToTable("ContentTypeFields"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentTypeRolePermission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContentTypeId") + .HasColumnType("uniqueidentifier"); + + b.Property("ContentTypePermissions") + .HasColumnType("int"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RoleId"); + + b.ToTable("ContentTypeRolePermission"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.DeletedContentItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContentTypeId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("OriginalContentItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("PrimaryField") + .HasColumnType("nvarchar(max)"); + + b.Property("RoutePath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("WebTemplateIdsJson") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("_PublishedContent") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("DeletedContentItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Bcc") + .HasColumnType("nvarchar(max)"); + + b.Property("Cc") + .HasColumnType("nvarchar(max)"); + + b.Property("Content") + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeveloperName") + .HasColumnType("nvarchar(450)"); + + b.Property("IsBuiltInTemplate") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Subject") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique() + .HasFilter("[DeveloperName] IS NOT NULL"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("EmailTemplates"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplateRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Bcc") + .HasColumnType("nvarchar(max)"); + + b.Property("Cc") + .HasColumnType("nvarchar(max)"); + + b.Property("Content") + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("EmailTemplateId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Subject") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("EmailTemplateId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("EmailTemplateRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.JwtLogin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Jti") + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("Jti") + .IsUnique() + .HasFilter("[Jti] IS NOT NULL"); + + b.ToTable("JwtLogins"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.MediaItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContentType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("FileName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FileStorageProvider") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Length") + .HasColumnType("bigint"); + + b.Property("ObjectKey") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("ObjectKey"); + + b.ToTable("MediaItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenu", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("IsMainMenu") + .HasColumnType("bit"); + + b.Property("Label") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("NavigationMenus"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenuItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("CssClassName") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDisabled") + .HasColumnType("bit"); + + b.Property("Label") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("NavigationMenuId") + .HasColumnType("uniqueidentifier"); + + b.Property("OpenInNewTab") + .HasColumnType("bit"); + + b.Property("Ordinal") + .HasColumnType("int"); + + b.Property("ParentNavigationMenuItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("Url") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("NavigationMenuId"); + + b.HasIndex("ParentNavigationMenuItemId"); + + b.ToTable("NavigationMenuItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenuRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("NavigationMenuId") + .HasColumnType("uniqueidentifier"); + + b.Property("NavigationMenuItemsJson") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("NavigationMenuId"); + + b.ToTable("NavigationMenuRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.OneTimePassword", b => + { + b.Property("Id") + .HasColumnType("varbinary(900)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("ExpiresAt") + .HasColumnType("datetime2"); + + b.Property("IsUsed") + .HasColumnType("bit"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("OneTimePasswords"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.OrganizationSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActiveThemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("DateFormat") + .HasColumnType("nvarchar(max)"); + + b.Property("HomePageId") + .HasColumnType("uniqueidentifier"); + + b.Property("HomePageType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OrganizationName") + .HasColumnType("nvarchar(max)"); + + b.Property("SmtpDefaultFromAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("SmtpDefaultFromName") + .HasColumnType("nvarchar(max)"); + + b.Property("SmtpHost") + .HasColumnType("nvarchar(max)"); + + b.Property("SmtpOverrideSystem") + .HasColumnType("bit"); + + b.Property("SmtpPassword") + .HasColumnType("nvarchar(max)"); + + b.Property("SmtpPort") + .HasColumnType("int"); + + b.Property("SmtpUsername") + .HasColumnType("nvarchar(max)"); + + b.Property("TimeZone") + .HasColumnType("nvarchar(max)"); + + b.Property("WebsiteUrl") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("OrganizationSettings"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TriggerType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("RaythaFunctions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunctionRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RaythaFunctionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RaythaFunctionId"); + + b.ToTable("RaythaFunctionRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("Label") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("SystemPermissions") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Route", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContentItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("Path") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("ViewId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Path") + .IsUnique(); + + b.ToTable("Routes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Theme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("IsExportable") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("Themes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ThemeAccessToMediaItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("MediaItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("ThemeId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("ThemeId"); + + b.ToTable("ThemeAccessToMediaItems"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuthenticationSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsAdmin") + .HasColumnType("bit"); + + b.Property("IsEmailAddressConfirmed") + .HasColumnType("bit"); + + b.Property("LastLoggedInTime") + .HasColumnType("datetime2"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("varbinary(max)"); + + b.Property("Salt") + .IsRequired() + .HasColumnType("varbinary(max)"); + + b.Property("SsoId") + .HasColumnType("nvarchar(450)"); + + b.Property("_RecentlyAccessedViews") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AuthenticationSchemeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("EmailAddress") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("SsoId", "AuthenticationSchemeId") + .IsUnique() + .HasFilter("[SsoId] IS NOT NULL AND [AuthenticationSchemeId] IS NOT NULL"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.UserGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeveloperName") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("Label") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("DeveloperName") + .IsUnique(); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("UserGroups"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.VerificationCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .HasColumnType("uniqueidentifier"); + + b.Property("Completed") + .HasColumnType("bit"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("EmailAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("ExpiresAt") + .HasColumnType("datetime2"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("VerificationCodeType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.ToTable("VerificationCodes"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.View", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContentTypeId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DefaultNumberOfItemsPerPage") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DeveloperName") + .HasColumnType("nvarchar(max)"); + + b.Property("IgnoreClientFilterAndSortQueryParams") + .HasColumnType("bit"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("Label") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("MaxNumberOfItemsPerPage") + .HasColumnType("int"); + + b.Property("RouteId") + .HasColumnType("uniqueidentifier"); + + b.Property("_Columns") + .HasColumnType("nvarchar(max)"); + + b.Property("_Filter") + .HasColumnType("nvarchar(max)"); + + b.Property("_Sort") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("RouteId") + .IsUnique(); + + b.ToTable("Views"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AllowAccessForNewContentTypes") + .HasColumnType("bit"); + + b.Property("Content") + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeveloperName") + .HasColumnType("nvarchar(450)"); + + b.Property("IsBaseLayout") + .HasColumnType("bit"); + + b.Property("IsBuiltInTemplate") + .HasColumnType("bit"); + + b.Property("Label") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("ParentTemplateId") + .HasColumnType("uniqueidentifier"); + + b.Property("ThemeId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("ParentTemplateId"); + + b.HasIndex("ThemeId"); + + b.HasIndex("DeveloperName", "ThemeId") + .IsUnique() + .HasFilter("[DeveloperName] IS NOT NULL"); + + b.ToTable("WebTemplates"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateAccessToModelDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContentTypeId") + .HasColumnType("uniqueidentifier"); + + b.Property("WebTemplateId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ContentTypeId"); + + b.HasIndex("WebTemplateId"); + + b.ToTable("WebTemplateAccessToModelDefinitions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateContentItemRelation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContentItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("WebTemplateId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ContentItemId"); + + b.HasIndex("WebTemplateId", "ContentItemId") + .IsUnique(); + + b.ToTable("WebTemplateContentItemRelations"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateRevision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AllowAccessForNewContentTypes") + .HasColumnType("bit"); + + b.Property("Content") + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("EmailTemplateId") + .HasColumnType("uniqueidentifier"); + + b.Property("Label") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("WebTemplateId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CreatorUserId"); + + b.HasIndex("EmailTemplateId"); + + b.HasIndex("LastModifierUserId"); + + b.HasIndex("WebTemplateId"); + + b.ToTable("WebTemplateRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateViewRelation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ViewId") + .HasColumnType("uniqueidentifier"); + + b.Property("WebTemplateId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("WebTemplateId"); + + b.HasIndex("ViewId", "WebTemplateId") + .IsUnique(); + + b.ToTable("WebTemplateViewRelations"); + }); + + modelBuilder.Entity("RoleUser", b => + { + b.Property("RolesId") + .HasColumnType("uniqueidentifier"); + + b.Property("UsersId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("RolesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("RoleUser"); + }); + + modelBuilder.Entity("UserUserGroup", b => + { + b.Property("UserGroupsId") + .HasColumnType("uniqueidentifier"); + + b.Property("UsersId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("UserGroupsId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("UserUserGroup"); + }); + + modelBuilder.Entity("UserView", b => + { + b.Property("FavoriteViewsId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserFavoritesId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("FavoriteViewsId", "UserFavoritesId"); + + b.HasIndex("UserFavoritesId"); + + b.ToTable("UserView"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ApiKey", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "User") + .WithMany("ApiKeys") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.AuthenticationScheme", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItem", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany() + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.Route", "Route") + .WithOne("ContentItem") + .HasForeignKey("Raytha.Domain.Entities.ContentItem", "RouteId") + .OnDelete(DeleteBehavior.ClientCascade) + .IsRequired(); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("Route"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItemRevision", b => + { + b.HasOne("Raytha.Domain.Entities.ContentItem", "ContentItem") + .WithMany("ContentItemRevisions") + .HasForeignKey("ContentItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("ContentItem"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentType", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentTypeField", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany("ContentTypeFields") + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.ContentType", "RelatedContentType") + .WithMany() + .HasForeignKey("RelatedContentTypeId"); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("RelatedContentType"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentTypeRolePermission", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany() + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.Role", "Role") + .WithMany("ContentTypeRolePermissions") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.DeletedContentItem", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany() + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplate", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplateRevision", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.EmailTemplate", "EmailTemplate") + .WithMany() + .HasForeignKey("EmailTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("EmailTemplate"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.MediaItem", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenu", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenuItem", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.NavigationMenu", "NavigationMenu") + .WithMany("NavigationMenuItems") + .HasForeignKey("NavigationMenuId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.NavigationMenuItem", "ParentNavigationMenuItem") + .WithMany() + .HasForeignKey("ParentNavigationMenuItemId") + .OnDelete(DeleteBehavior.ClientCascade); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("NavigationMenu"); + + b.Navigation("ParentNavigationMenuItem"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenuRevision", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.NavigationMenu", "NavigationMenu") + .WithMany("NavigationMenuRevisions") + .HasForeignKey("NavigationMenuId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("NavigationMenu"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.OneTimePassword", b => + { + b.HasOne("Raytha.Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunction", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunctionRevision", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.RaythaFunction", "RaythaFunction") + .WithMany("Revisions") + .HasForeignKey("RaythaFunctionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("RaythaFunction"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Role", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Theme", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ThemeAccessToMediaItem", b => + { + b.HasOne("Raytha.Domain.Entities.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.Theme", "Theme") + .WithMany("ThemeAccessToMediaItems") + .HasForeignKey("ThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaItem"); + + b.Navigation("Theme"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.User", b => + { + b.HasOne("Raytha.Domain.Entities.AuthenticationScheme", "AuthenticationScheme") + .WithMany() + .HasForeignKey("AuthenticationSchemeId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("AuthenticationScheme"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.UserGroup", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.VerificationCode", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.View", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany("Views") + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("Raytha.Domain.Entities.Route", "Route") + .WithOne("View") + .HasForeignKey("Raytha.Domain.Entities.View", "RouteId") + .OnDelete(DeleteBehavior.ClientCascade) + .IsRequired(); + + b.Navigation("ContentType"); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("Route"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplate", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "ParentTemplate") + .WithMany() + .HasForeignKey("ParentTemplateId"); + + b.HasOne("Raytha.Domain.Entities.Theme", "Theme") + .WithMany("WebTemplates") + .HasForeignKey("ThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("ParentTemplate"); + + b.Navigation("Theme"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateAccessToModelDefinition", b => + { + b.HasOne("Raytha.Domain.Entities.ContentType", "ContentType") + .WithMany() + .HasForeignKey("ContentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "WebTemplate") + .WithMany("TemplateAccessToModelDefinitions") + .HasForeignKey("WebTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ContentType"); + + b.Navigation("WebTemplate"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateContentItemRelation", b => + { + b.HasOne("Raytha.Domain.Entities.ContentItem", "ContentItem") + .WithMany() + .HasForeignKey("ContentItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "WebTemplate") + .WithMany() + .HasForeignKey("WebTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ContentItem"); + + b.Navigation("WebTemplate"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateRevision", b => + { + b.HasOne("Raytha.Domain.Entities.User", "CreatorUser") + .WithMany() + .HasForeignKey("CreatorUserId"); + + b.HasOne("Raytha.Domain.Entities.EmailTemplate", null) + .WithMany("Revisions") + .HasForeignKey("EmailTemplateId"); + + b.HasOne("Raytha.Domain.Entities.User", "LastModifierUser") + .WithMany() + .HasForeignKey("LastModifierUserId"); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "WebTemplate") + .WithMany("Revisions") + .HasForeignKey("WebTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorUser"); + + b.Navigation("LastModifierUser"); + + b.Navigation("WebTemplate"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplateViewRelation", b => + { + b.HasOne("Raytha.Domain.Entities.View", "View") + .WithMany() + .HasForeignKey("ViewId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.WebTemplate", "WebTemplate") + .WithMany() + .HasForeignKey("WebTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("View"); + + b.Navigation("WebTemplate"); + }); + + modelBuilder.Entity("RoleUser", b => + { + b.HasOne("Raytha.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RolesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("UserUserGroup", b => + { + b.HasOne("Raytha.Domain.Entities.UserGroup", null) + .WithMany() + .HasForeignKey("UserGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("UserView", b => + { + b.HasOne("Raytha.Domain.Entities.View", null) + .WithMany() + .HasForeignKey("FavoriteViewsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Raytha.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserFavoritesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentItem", b => + { + b.Navigation("ContentItemRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.ContentType", b => + { + b.Navigation("ContentTypeFields"); + + b.Navigation("Views"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.EmailTemplate", b => + { + b.Navigation("Revisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.NavigationMenu", b => + { + b.Navigation("NavigationMenuItems"); + + b.Navigation("NavigationMenuRevisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.RaythaFunction", b => + { + b.Navigation("Revisions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Role", b => + { + b.Navigation("ContentTypeRolePermissions"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Route", b => + { + b.Navigation("ContentItem") + .IsRequired(); + + b.Navigation("View") + .IsRequired(); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.Theme", b => + { + b.Navigation("ThemeAccessToMediaItems"); + + b.Navigation("WebTemplates"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.User", b => + { + b.Navigation("ApiKeys"); + }); + + modelBuilder.Entity("Raytha.Domain.Entities.WebTemplate", b => + { + b.Navigation("Revisions"); + + b.Navigation("TemplateAccessToModelDefinitions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Raytha.Migrations.SqlServer/20241116192521_v1_4_0.cs b/src/Raytha.Migrations.SqlServer/20241116192521_v1_4_0.cs new file mode 100644 index 00000000..76e5934a --- /dev/null +++ b/src/Raytha.Migrations.SqlServer/20241116192521_v1_4_0.cs @@ -0,0 +1,221 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Raytha.Migrations.SqlServer +{ + /// + public partial class v1_4_0 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_WebTemplates_DeveloperName_ThemeId", + table: "WebTemplates"); + + migrationBuilder.DropIndex( + name: "IX_Users_EmailAddress", + table: "Users"); + + migrationBuilder.DropIndex( + name: "IX_Users_SsoId_AuthenticationSchemeId", + table: "Users"); + + migrationBuilder.DropIndex( + name: "IX_UserGroups_DeveloperName", + table: "UserGroups"); + + migrationBuilder.DropIndex( + name: "IX_Routes_Path", + table: "Routes"); + + migrationBuilder.DropIndex( + name: "IX_Roles_DeveloperName", + table: "Roles"); + + migrationBuilder.DropIndex( + name: "IX_JwtLogins_Jti", + table: "JwtLogins"); + + migrationBuilder.DropIndex( + name: "IX_AuthenticationSchemes_DeveloperName", + table: "AuthenticationSchemes"); + + migrationBuilder.AlterColumn( + name: "DeveloperName", + table: "EmailTemplates", + type: "nvarchar(450)", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplates_DeveloperName_ThemeId", + table: "WebTemplates", + columns: new[] { "DeveloperName", "ThemeId" }, + unique: true, + filter: "[DeveloperName] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_Users_EmailAddress", + table: "Users", + column: "EmailAddress", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Users_SsoId_AuthenticationSchemeId", + table: "Users", + columns: new[] { "SsoId", "AuthenticationSchemeId" }, + unique: true, + filter: "[SsoId] IS NOT NULL AND [AuthenticationSchemeId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_UserGroups_DeveloperName", + table: "UserGroups", + column: "DeveloperName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Routes_Path", + table: "Routes", + column: "Path", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Roles_DeveloperName", + table: "Roles", + column: "DeveloperName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_JwtLogins_Jti", + table: "JwtLogins", + column: "Jti", + unique: true, + filter: "[Jti] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_EmailTemplates_DeveloperName", + table: "EmailTemplates", + column: "DeveloperName", + unique: true, + filter: "[DeveloperName] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_AuthenticationSchemes_DeveloperName", + table: "AuthenticationSchemes", + column: "DeveloperName", + unique: true, + filter: "[DeveloperName] IS NOT NULL"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_WebTemplates_DeveloperName_ThemeId", + table: "WebTemplates"); + + migrationBuilder.DropIndex( + name: "IX_Users_EmailAddress", + table: "Users"); + + migrationBuilder.DropIndex( + name: "IX_Users_SsoId_AuthenticationSchemeId", + table: "Users"); + + migrationBuilder.DropIndex( + name: "IX_UserGroups_DeveloperName", + table: "UserGroups"); + + migrationBuilder.DropIndex( + name: "IX_Routes_Path", + table: "Routes"); + + migrationBuilder.DropIndex( + name: "IX_Roles_DeveloperName", + table: "Roles"); + + migrationBuilder.DropIndex( + name: "IX_JwtLogins_Jti", + table: "JwtLogins"); + + migrationBuilder.DropIndex( + name: "IX_EmailTemplates_DeveloperName", + table: "EmailTemplates"); + + migrationBuilder.DropIndex( + name: "IX_AuthenticationSchemes_DeveloperName", + table: "AuthenticationSchemes"); + + migrationBuilder.AlterColumn( + name: "DeveloperName", + table: "EmailTemplates", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(450)", + oldNullable: true); + + migrationBuilder.CreateIndex( + name: "IX_WebTemplates_DeveloperName_ThemeId", + table: "WebTemplates", + columns: new[] { "DeveloperName", "ThemeId" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Users_EmailAddress", + table: "Users", + column: "EmailAddress", + unique: true) + .Annotation("SqlServer:Include", new[] { "Id", "FirstName", "LastName", "SsoId", "AuthenticationSchemeId" }); + + migrationBuilder.CreateIndex( + name: "IX_Users_SsoId_AuthenticationSchemeId", + table: "Users", + columns: new[] { "SsoId", "AuthenticationSchemeId" }, + unique: true, + filter: "[SsoId] IS NOT NULL AND [AuthenticationSchemeId] IS NOT NULL") + .Annotation("SqlServer:Include", new[] { "Id", "EmailAddress", "FirstName", "LastName" }); + + migrationBuilder.CreateIndex( + name: "IX_UserGroups_DeveloperName", + table: "UserGroups", + column: "DeveloperName", + unique: true) + .Annotation("SqlServer:Include", new[] { "Id", "Label" }); + + migrationBuilder.CreateIndex( + name: "IX_Routes_Path", + table: "Routes", + column: "Path", + unique: true) + .Annotation("SqlServer:Include", new[] { "Id", "ViewId", "ContentItemId" }); + + migrationBuilder.CreateIndex( + name: "IX_Roles_DeveloperName", + table: "Roles", + column: "DeveloperName", + unique: true) + .Annotation("SqlServer:Include", new[] { "Id", "Label" }); + + migrationBuilder.CreateIndex( + name: "IX_JwtLogins_Jti", + table: "JwtLogins", + column: "Jti", + unique: true, + filter: "[Jti] IS NOT NULL") + .Annotation("SqlServer:Include", new[] { "Id" }); + + migrationBuilder.CreateIndex( + name: "IX_AuthenticationSchemes_DeveloperName", + table: "AuthenticationSchemes", + column: "DeveloperName", + unique: true, + filter: "[DeveloperName] IS NOT NULL") + .Annotation("SqlServer:Include", new[] { "Id", "Label" }); + } + } +} diff --git a/src/Raytha.Migrations.SqlServer/Raytha.Migrations.SqlServer.csproj b/src/Raytha.Migrations.SqlServer/Raytha.Migrations.SqlServer.csproj new file mode 100644 index 00000000..35a39f42 --- /dev/null +++ b/src/Raytha.Migrations.SqlServer/Raytha.Migrations.SqlServer.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/src/Raytha.Infrastructure/Migrations/RaythaDbContextModelSnapshot.cs b/src/Raytha.Migrations.SqlServer/RaythaDbContextModelSnapshot.cs similarity index 98% rename from src/Raytha.Infrastructure/Migrations/RaythaDbContextModelSnapshot.cs rename to src/Raytha.Migrations.SqlServer/RaythaDbContextModelSnapshot.cs index bc15b488..f2c76447 100644 --- a/src/Raytha.Infrastructure/Migrations/RaythaDbContextModelSnapshot.cs +++ b/src/Raytha.Migrations.SqlServer/RaythaDbContextModelSnapshot.cs @@ -8,7 +8,7 @@ #nullable disable -namespace Raytha.Infrastructure.Migrations +namespace Raytha.Migrations.SqlServer { [DbContext(typeof(RaythaDbContext))] partial class RaythaDbContextModelSnapshot : ModelSnapshot @@ -17,7 +17,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "8.0.0") + .HasAnnotation("ProductVersion", "8.0.10") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); @@ -179,8 +179,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsUnique() .HasFilter("[DeveloperName] IS NOT NULL"); - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("DeveloperName"), new[] { "Id", "Label" }); - b.HasIndex("LastModifierUserId"); b.ToTable("AuthenticationSchemes"); @@ -554,7 +552,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("uniqueidentifier"); b.Property("DeveloperName") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(450)"); b.Property("IsBuiltInTemplate") .HasColumnType("bit"); @@ -572,6 +570,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("CreatorUserId"); + b.HasIndex("DeveloperName") + .IsUnique() + .HasFilter("[DeveloperName] IS NOT NULL"); + b.HasIndex("LastModifierUserId"); b.ToTable("EmailTemplates"); @@ -639,8 +641,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsUnique() .HasFilter("[Jti] IS NOT NULL"); - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("Jti"), new[] { "Id" }); - b.ToTable("JwtLogins"); }); @@ -1025,8 +1025,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("DeveloperName") .IsUnique(); - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("DeveloperName"), new[] { "Id", "Label" }); - b.HasIndex("LastModifierUserId"); b.ToTable("Roles"); @@ -1053,8 +1051,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Path") .IsUnique(); - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("Path"), new[] { "Id", "ViewId", "ContentItemId" }); - b.ToTable("Routes"); }); @@ -1192,16 +1188,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("EmailAddress") .IsUnique(); - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("EmailAddress"), new[] { "Id", "FirstName", "LastName", "SsoId", "AuthenticationSchemeId" }); - b.HasIndex("LastModifierUserId"); b.HasIndex("SsoId", "AuthenticationSchemeId") .IsUnique() .HasFilter("[SsoId] IS NOT NULL AND [AuthenticationSchemeId] IS NOT NULL"); - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("SsoId", "AuthenticationSchemeId"), new[] { "Id", "EmailAddress", "FirstName", "LastName" }); - b.ToTable("Users"); }); @@ -1238,8 +1230,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("DeveloperName") .IsUnique(); - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("DeveloperName"), new[] { "Id", "Label" }); - b.HasIndex("LastModifierUserId"); b.ToTable("UserGroups"); @@ -1409,7 +1399,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("ThemeId"); b.HasIndex("DeveloperName", "ThemeId") - .IsUnique(); + .IsUnique() + .HasFilter("[DeveloperName] IS NOT NULL"); b.ToTable("WebTemplates"); }); diff --git a/src/Raytha.Web/Raytha.Web.csproj b/src/Raytha.Web/Raytha.Web.csproj index cb7e050c..e34bc457 100644 --- a/src/Raytha.Web/Raytha.Web.csproj +++ b/src/Raytha.Web/Raytha.Web.csproj @@ -24,6 +24,8 @@ + + diff --git a/src/Raytha.Web/Startup.cs b/src/Raytha.Web/Startup.cs index c652498d..183084cc 100644 --- a/src/Raytha.Web/Startup.cs +++ b/src/Raytha.Web/Startup.cs @@ -1,15 +1,14 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.HttpLogging; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; using Raytha.Application; +using Raytha.Application.Common.Interfaces; using Raytha.Application.Common.Utils; using Raytha.Infrastructure.Persistence; using Raytha.Web.Middlewares; diff --git a/src/Raytha.Web/appsettings.json b/src/Raytha.Web/appsettings.json index f3e4b6ef..17306e12 100644 --- a/src/Raytha.Web/appsettings.json +++ b/src/Raytha.Web/appsettings.json @@ -8,8 +8,9 @@ }, "AllowedHosts": "*", "ConnectionStrings": { - "DefaultConnection": "Server=.\\sqlexpress;Database=Raytha;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" + //"DefaultConnection": "Server=.\\sqlexpress;Database=Raytha;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" //"DefaultConnection": "Server=localhost;User Id=sa;Password=Password1234!;Database=Raytha;TrustServerCertificate=True" //local mac development + "DefaultConnection": "Host=localhost;Port=5432;Username=postgres;Password=changeme;Database=raytha" //postgres }, //Path base, set a value if you want to run raytha at a path such as mydomain.com/mywebsite instead of just mydomain.com //if you plan to run raytha along side other applications behind a reverse proxy such as nginx