diff --git a/src/api/src/domain/Yoma.Core.Domain/ActionLink/Services/LinkService.cs b/src/api/src/domain/Yoma.Core.Domain/ActionLink/Services/LinkService.cs
index b126beffa..a83c85045 100644
--- a/src/api/src/domain/Yoma.Core.Domain/ActionLink/Services/LinkService.cs
+++ b/src/api/src/domain/Yoma.Core.Domain/ActionLink/Services/LinkService.cs
@@ -112,18 +112,22 @@ public async Task Create(LinkRequestCreate request, bool ensureOrganizatio
ModifiedByUserId = user.Id,
};
+ Link? itemExisting = null;
+ IQueryable? queryItemExisting = null;
switch (request.EntityType)
{
case LinkEntityType.Opportunity:
item.OpportunityId = request.EntityId;
+ queryItemExisting = _linkRepository.Query().Where(o => o.EntityType == item.EntityType && o.Action == item.Action && o.OpportunityId == item.OpportunityId);
+
switch (request.Action)
{
case LinkAction.Share:
if (request.UsagesLimit.HasValue || request.DateEnd.HasValue)
throw new ValidationException($"Neither a usage limit nor an end date is supported by the link with action '{request.Action}'.");
- var itemExisting = _linkRepository.Query().SingleOrDefault(o => o.EntityType == item.EntityType && o.Action == item.Action && o.OpportunityId == item.OpportunityId);
+ itemExisting = queryItemExisting.SingleOrDefault();
if (itemExisting == null) break;
if (!string.Equals(itemExisting.URL, item.URL))
@@ -138,6 +142,12 @@ public async Task Create(LinkRequestCreate request, bool ensureOrganizatio
if (!request.UsagesLimit.HasValue && !request.DateEnd.HasValue)
throw new ValidationException($"Either a usage limit or an end date is required for the link with action '{request.Action}'.");
+#pragma warning disable CA1862 // Use the 'StringComparison' method overloads to perform case-insensitive string comparisons
+ itemExisting = queryItemExisting.Where(o => o.Name.ToLower() == item.Name.ToLower()).SingleOrDefault();
+#pragma warning restore CA1862 // Use the 'StringComparison' method overloads to perform case-insensitive string comparisons
+ if (itemExisting != null)
+ throw new ValidationException($"Link with name '{item.Name}' already exists for the opportunity");
+
item.URL = item.URL.AppendPathSegment(item.Id.ToString());
break;
diff --git a/src/api/src/domain/Yoma.Core.Domain/Opportunity/Services/OpportunityService.cs b/src/api/src/domain/Yoma.Core.Domain/Opportunity/Services/OpportunityService.cs
index 893fd4d1b..2734a6c8d 100644
--- a/src/api/src/domain/Yoma.Core.Domain/Opportunity/Services/OpportunityService.cs
+++ b/src/api/src/domain/Yoma.Core.Domain/Opportunity/Services/OpportunityService.cs
@@ -1425,12 +1425,15 @@ public async Task CreateLinkInstantVerify(Guid id, OpportunityRequestL
{
ArgumentNullException.ThrowIfNull(request, nameof(request));
- var opportunity = GetById(id, false, false, ensureOrganizationAuthorization);
+ var opportunity = GetById(id, false, true, ensureOrganizationAuthorization);
await _opportunityRequestLinkInstantVerifyValidator.ValidateAndThrowAsync(request);
- if (opportunity.Status != Status.Active)
- throw new ValidationException($"Link cannot be created as the opportunity '{opportunity.Title}' is not active");
+ if (!opportunity.VerificationEnabled || opportunity.VerificationMethod != VerificationMethod.Manual)
+ throw new ValidationException($"Link cannot be created as the opportunity '{opportunity.Title}' does not support manual verification");
+
+ if (!opportunity.Published)
+ throw new ValidationException($"Link cannot be created as the opportunity '{opportunity.Title}' has not been published");
if (string.IsNullOrEmpty(request.Name)) request.Name = opportunity.Title.RemoveSpecialCharacters();
diff --git a/src/api/src/infrastructure/Yoma.Core.Infrastructure.Database/ActionLink/Entities/Link.cs b/src/api/src/infrastructure/Yoma.Core.Infrastructure.Database/ActionLink/Entities/Link.cs
index 401631ab0..1861ad8d2 100644
--- a/src/api/src/infrastructure/Yoma.Core.Infrastructure.Database/ActionLink/Entities/Link.cs
+++ b/src/api/src/infrastructure/Yoma.Core.Infrastructure.Database/ActionLink/Entities/Link.cs
@@ -9,7 +9,7 @@ namespace Yoma.Core.Infrastructure.Database.ActionLink.Entities
[Table("Link", Schema = "ActionLink")]
[Index(nameof(URL), IsUnique = true)]
[Index(nameof(ShortURL), IsUnique = true)]
- [Index(nameof(EntityType), nameof(Action), nameof(StatusId), nameof(OpportunityId), nameof(DateEnd), nameof(DateCreated))]
+ [Index(nameof(Name), nameof(EntityType), nameof(Action), nameof(StatusId), nameof(OpportunityId), nameof(DateEnd), nameof(DateCreated))]
public class Link : BaseEntity
{
[Required]
diff --git a/src/api/src/infrastructure/Yoma.Core.Infrastructure.Database/Migrations/20240425123152_ApplicationDb_ActionLink_Name.Designer.cs b/src/api/src/infrastructure/Yoma.Core.Infrastructure.Database/Migrations/20240425123152_ApplicationDb_ActionLink_Name.Designer.cs
new file mode 100644
index 000000000..419761dbb
--- /dev/null
+++ b/src/api/src/infrastructure/Yoma.Core.Infrastructure.Database/Migrations/20240425123152_ApplicationDb_ActionLink_Name.Designer.cs
@@ -0,0 +1,2318 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using Yoma.Core.Infrastructure.Database.Context;
+
+#nullable disable
+
+namespace Yoma.Core.Infrastructure.Database.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("20240425123152_ApplicationDb_ActionLink_Name")]
+ partial class ApplicationDb_ActionLink_Name
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.3")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.ActionLink.Entities.Link", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("varchar(25)");
+
+ b.Property("CreatedByUserId")
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateEnd")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateModified")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Description")
+ .HasColumnType("varchar(500)");
+
+ b.Property("EntityType")
+ .IsRequired()
+ .HasColumnType("varchar(25)");
+
+ b.Property("ModifiedByUserId")
+ .HasColumnType("uuid");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.Property("OpportunityId")
+ .HasColumnType("uuid");
+
+ b.Property("ShortURL")
+ .IsRequired()
+ .HasColumnType("varchar(2048)");
+
+ b.Property("StatusId")
+ .HasColumnType("uuid");
+
+ b.Property("URL")
+ .IsRequired()
+ .HasColumnType("varchar(2048)");
+
+ b.Property("UsagesLimit")
+ .HasColumnType("integer");
+
+ b.Property("UsagesTotal")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatedByUserId");
+
+ b.HasIndex("ModifiedByUserId");
+
+ b.HasIndex("OpportunityId");
+
+ b.HasIndex("ShortURL")
+ .IsUnique();
+
+ b.HasIndex("StatusId");
+
+ b.HasIndex("URL")
+ .IsUnique();
+
+ b.HasIndex("Name", "EntityType", "Action", "StatusId", "OpportunityId", "DateEnd", "DateCreated");
+
+ b.ToTable("Link", "ActionLink");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.ActionLink.Entities.LinkUsageLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("LinkId")
+ .HasColumnType("uuid");
+
+ b.Property("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DateCreated");
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("LinkId", "UserId")
+ .IsUnique();
+
+ b.ToTable("UsageLog", "ActionLink");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.ActionLink.Entities.Lookups.LinkStatus", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("Status", "ActionLink");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Core.Entities.BlobObject", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("ContentType")
+ .IsRequired()
+ .HasColumnType("varchar(127)");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("FileType")
+ .IsRequired()
+ .HasColumnType("varchar(25)");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("varchar(125)");
+
+ b.Property("OriginalFileName")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.Property("ParentId")
+ .HasColumnType("uuid");
+
+ b.Property("StorageType")
+ .IsRequired()
+ .HasColumnType("varchar(25)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Key")
+ .IsUnique();
+
+ b.HasIndex("ParentId");
+
+ b.HasIndex("StorageType", "FileType", "ParentId");
+
+ b.ToTable("Blob", "Object");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Entity.Entities.Lookups.OrganizationProviderType", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("OrganizationProviderType", "Entity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Entity.Entities.Lookups.OrganizationStatus", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("OrganizationStatus", "Entity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Entity.Entities.Organization", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("Biography")
+ .HasColumnType("text");
+
+ b.Property("City")
+ .HasColumnType("varchar(50)");
+
+ b.Property("CommentApproval")
+ .HasColumnType("varchar(500)");
+
+ b.Property("CountryId")
+ .HasColumnType("uuid");
+
+ b.Property("CreatedByUserId")
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateModified")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateStatusModified")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("LogoId")
+ .HasColumnType("uuid");
+
+ b.Property("ModifiedByUserId")
+ .HasColumnType("uuid");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.Property("NameHashValue")
+ .IsRequired()
+ .HasColumnType("varchar(128)");
+
+ b.Property("PostalCode")
+ .HasColumnType("varchar(10)");
+
+ b.Property("PrimaryContactEmail")
+ .HasColumnType("varchar(320)");
+
+ b.Property("PrimaryContactName")
+ .HasColumnType("varchar(255)");
+
+ b.Property("PrimaryContactPhone")
+ .HasColumnType("varchar(50)");
+
+ b.Property("Province")
+ .HasColumnType("varchar(255)");
+
+ b.Property("RegistrationNumber")
+ .HasColumnType("varchar(255)");
+
+ b.Property("StatusId")
+ .HasColumnType("uuid");
+
+ b.Property("StreetAddress")
+ .HasColumnType("varchar(500)");
+
+ b.Property("Tagline")
+ .HasColumnType("text");
+
+ b.Property("TaxNumber")
+ .HasColumnType("varchar(255)");
+
+ b.Property("VATIN")
+ .HasColumnType("varchar(255)");
+
+ b.Property("WebsiteURL")
+ .HasColumnType("varchar(2048)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CountryId");
+
+ b.HasIndex("CreatedByUserId");
+
+ b.HasIndex("LogoId");
+
+ b.HasIndex("ModifiedByUserId");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.HasIndex("NameHashValue")
+ .IsUnique();
+
+ b.HasIndex("StatusId", "DateStatusModified", "DateCreated", "CreatedByUserId", "DateModified", "ModifiedByUserId");
+
+ b.ToTable("Organization", "Entity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Entity.Entities.OrganizationDocument", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("FileId")
+ .HasColumnType("uuid");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("varchar(50)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("FileId")
+ .IsUnique();
+
+ b.HasIndex("OrganizationId", "Type", "DateCreated");
+
+ b.ToTable("OrganizationDocuments", "Entity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Entity.Entities.OrganizationProviderType", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("ProviderTypeId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ProviderTypeId");
+
+ b.HasIndex("OrganizationId", "ProviderTypeId")
+ .IsUnique();
+
+ b.ToTable("OrganizationProviderTypes", "Entity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Entity.Entities.OrganizationUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("OrganizationId", "UserId")
+ .IsUnique();
+
+ b.ToTable("OrganizationUsers", "Entity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Entity.Entities.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CountryId")
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateLastLogin")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateModified")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateOfBirth")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateYoIDOnboarded")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.Property("EducationId")
+ .HasColumnType("uuid");
+
+ b.Property("Email")
+ .IsRequired()
+ .HasColumnType("varchar(320)");
+
+ b.Property("EmailConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property("ExternalId")
+ .HasColumnType("uuid");
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasColumnType("varchar(125)");
+
+ b.Property("GenderId")
+ .HasColumnType("uuid");
+
+ b.Property("PhoneNumber")
+ .HasColumnType("varchar(50)");
+
+ b.Property("PhotoId")
+ .HasColumnType("uuid");
+
+ b.Property("Surname")
+ .IsRequired()
+ .HasColumnType("varchar(125)");
+
+ b.Property("YoIDOnboarded")
+ .HasColumnType("boolean");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CountryId");
+
+ b.HasIndex("EducationId");
+
+ b.HasIndex("Email")
+ .IsUnique();
+
+ b.HasIndex("GenderId");
+
+ b.HasIndex("PhotoId");
+
+ b.HasIndex("FirstName", "Surname", "EmailConfirmed", "PhoneNumber", "ExternalId", "YoIDOnboarded", "DateYoIDOnboarded", "DateCreated", "DateModified");
+
+ b.ToTable("User", "Entity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Entity.Entities.UserSkill", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("SkillId")
+ .HasColumnType("uuid");
+
+ b.Property("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SkillId");
+
+ b.HasIndex("UserId", "SkillId")
+ .IsUnique();
+
+ b.ToTable("UserSkills", "Entity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Entity.Entities.UserSkillOrganization", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("UserSkillId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.HasIndex("UserSkillId", "OrganizationId")
+ .IsUnique();
+
+ b.ToTable("UserSkillOrganizations", "Entity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Lookups.Entities.Country", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CodeAlpha2")
+ .IsRequired()
+ .HasColumnType("varchar(2)");
+
+ b.Property("CodeAlpha3")
+ .IsRequired()
+ .HasColumnType("varchar(3)");
+
+ b.Property("CodeNumeric")
+ .IsRequired()
+ .HasColumnType("varchar(3)");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(125)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CodeAlpha2")
+ .IsUnique();
+
+ b.HasIndex("CodeAlpha3")
+ .IsUnique();
+
+ b.HasIndex("CodeNumeric")
+ .IsUnique();
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("Country", "Lookup");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Lookups.Entities.Education", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("Education", "Lookup");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Lookups.Entities.Gender", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("Gender", "Lookup");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Lookups.Entities.Language", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CodeAlpha2")
+ .IsRequired()
+ .HasColumnType("varchar(2)");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(125)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CodeAlpha2")
+ .IsUnique();
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("Language", "Lookup");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Lookups.Entities.Skill", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateModified")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("ExternalId")
+ .IsRequired()
+ .HasColumnType("varchar(100)");
+
+ b.Property("InfoURL")
+ .HasColumnType("varchar(2048)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ExternalId")
+ .IsUnique();
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("Skill", "Lookup");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Lookups.Entities.TimeInterval", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("TimeInterval", "Lookup");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Marketplace.Entities.Lookups.TransactionStatus", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(30)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("TransactionStatus", "Marketplace");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Marketplace.Entities.TransactionLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("Amount")
+ .HasColumnType("decimal(8,2)");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateModified")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("ItemCategoryId")
+ .IsRequired()
+ .HasColumnType("varchar(50)");
+
+ b.Property("ItemId")
+ .IsRequired()
+ .HasColumnType("varchar(50)");
+
+ b.Property("StatusId")
+ .HasColumnType("uuid");
+
+ b.Property("TransactionId")
+ .IsRequired()
+ .HasColumnType("varchar(50)");
+
+ b.Property("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("StatusId");
+
+ b.HasIndex("UserId", "ItemCategoryId", "ItemId", "StatusId", "DateCreated", "DateModified");
+
+ b.ToTable("TransactionLog", "Marketplace");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.MyOpportunity.Entities.Lookups.MyOpportunityAction", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(125)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("MyOpportunityAction", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.MyOpportunity.Entities.Lookups.MyOpportunityVerificationStatus", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(125)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("MyOpportunityVerificationStatus", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.MyOpportunity.Entities.MyOpportunity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("ActionId")
+ .HasColumnType("uuid");
+
+ b.Property("CommentVerification")
+ .HasColumnType("varchar(500)");
+
+ b.Property("DateCompleted")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateEnd")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateModified")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateStart")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("OpportunityId")
+ .HasColumnType("uuid");
+
+ b.Property("UserId")
+ .HasColumnType("uuid");
+
+ b.Property("VerificationStatusId")
+ .HasColumnType("uuid");
+
+ b.Property("YomaReward")
+ .HasColumnType("decimal(8,2)");
+
+ b.Property("ZltoReward")
+ .HasColumnType("decimal(8,2)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ActionId");
+
+ b.HasIndex("OpportunityId");
+
+ b.HasIndex("UserId", "OpportunityId", "ActionId")
+ .IsUnique();
+
+ b.HasIndex("VerificationStatusId", "DateCompleted", "ZltoReward", "YomaReward", "DateCreated", "DateModified");
+
+ b.ToTable("MyOpportunity", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.MyOpportunity.Entities.MyOpportunityVerification", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("FileId")
+ .HasColumnType("uuid");
+
+ b.Property("GeometryProperties")
+ .HasColumnType("text");
+
+ b.Property("MyOpportunityId")
+ .HasColumnType("uuid");
+
+ b.Property("VerificationTypeId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("FileId");
+
+ b.HasIndex("VerificationTypeId");
+
+ b.HasIndex("MyOpportunityId", "VerificationTypeId")
+ .IsUnique();
+
+ b.ToTable("MyOpportunityVerifications", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Opportunity.Entities.Lookups.OpportunityCategory", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("ImageURL")
+ .IsRequired()
+ .HasColumnType("varchar(2048)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(125)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("OpportunityCategory", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Opportunity.Entities.Lookups.OpportunityDifficulty", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("OpportunityDifficulty", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Opportunity.Entities.Lookups.OpportunityStatus", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("OpportunityStatus", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Opportunity.Entities.Lookups.OpportunityType", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("OpportunityType", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Opportunity.Entities.Lookups.OpportunityVerificationType", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasColumnType("varchar(125)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(125)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("OpportunityVerificationType", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Opportunity.Entities.Opportunity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CommitmentIntervalCount")
+ .HasColumnType("smallint");
+
+ b.Property("CommitmentIntervalId")
+ .HasColumnType("uuid");
+
+ b.Property("CreatedByUserId")
+ .HasColumnType("uuid");
+
+ b.Property("CredentialIssuanceEnabled")
+ .HasColumnType("boolean");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateEnd")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateModified")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateStart")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("DifficultyId")
+ .HasColumnType("uuid");
+
+ b.Property("Instructions")
+ .HasColumnType("text");
+
+ b.Property("Keywords")
+ .HasColumnType("varchar(500)");
+
+ b.Property("ModifiedByUserId")
+ .HasColumnType("uuid");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("ParticipantCount")
+ .HasColumnType("integer");
+
+ b.Property("ParticipantLimit")
+ .HasColumnType("integer");
+
+ b.Property("SSISchemaName")
+ .HasColumnType("varchar(255)");
+
+ b.Property("StatusId")
+ .HasColumnType("uuid");
+
+ b.Property("Summary")
+ .HasColumnType("varchar(500)");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.Property("TypeId")
+ .HasColumnType("uuid");
+
+ b.Property("URL")
+ .HasColumnType("varchar(2048)");
+
+ b.Property("VerificationEnabled")
+ .HasColumnType("boolean");
+
+ b.Property("VerificationMethod")
+ .HasColumnType("varchar(20)");
+
+ b.Property("YomaReward")
+ .HasColumnType("decimal(8,2)");
+
+ b.Property("YomaRewardCumulative")
+ .HasColumnType("decimal(12,2)");
+
+ b.Property("YomaRewardPool")
+ .HasColumnType("decimal(12,2)");
+
+ b.Property("ZltoReward")
+ .HasColumnType("decimal(8,2)");
+
+ b.Property("ZltoRewardCumulative")
+ .HasColumnType("decimal(12,2)");
+
+ b.Property("ZltoRewardPool")
+ .HasColumnType("decimal(12,2)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CommitmentIntervalId");
+
+ b.HasIndex("CreatedByUserId");
+
+ b.HasIndex("Description")
+ .HasAnnotation("Npgsql:TsVectorConfig", "english");
+
+ NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("Description"), "GIN");
+
+ b.HasIndex("DifficultyId");
+
+ b.HasIndex("ModifiedByUserId");
+
+ b.HasIndex("OrganizationId");
+
+ b.HasIndex("StatusId");
+
+ b.HasIndex("Title")
+ .IsUnique();
+
+ b.HasIndex("TypeId", "OrganizationId", "ZltoReward", "DifficultyId", "CommitmentIntervalId", "CommitmentIntervalCount", "StatusId", "Keywords", "DateStart", "DateEnd", "CredentialIssuanceEnabled", "DateCreated", "CreatedByUserId", "DateModified", "ModifiedByUserId");
+
+ b.ToTable("Opportunity", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Opportunity.Entities.OpportunityCategory", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CategoryId")
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("OpportunityId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CategoryId");
+
+ b.HasIndex("OpportunityId", "CategoryId")
+ .IsUnique();
+
+ b.ToTable("OpportunityCategories", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Opportunity.Entities.OpportunityCountry", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CountryId")
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("OpportunityId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CountryId");
+
+ b.HasIndex("OpportunityId", "CountryId")
+ .IsUnique();
+
+ b.ToTable("OpportunityCountries", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Opportunity.Entities.OpportunityLanguage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("LanguageId")
+ .HasColumnType("uuid");
+
+ b.Property("OpportunityId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("LanguageId");
+
+ b.HasIndex("OpportunityId", "LanguageId")
+ .IsUnique();
+
+ b.ToTable("OpportunityLanguages", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Opportunity.Entities.OpportunitySkill", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("OpportunityId")
+ .HasColumnType("uuid");
+
+ b.Property("SkillId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SkillId");
+
+ b.HasIndex("OpportunityId", "SkillId")
+ .IsUnique();
+
+ b.ToTable("OpportunitySkills", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Opportunity.Entities.OpportunityVerificationType", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateModified")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Description")
+ .HasColumnType("varchar(255)");
+
+ b.Property("OpportunityId")
+ .HasColumnType("uuid");
+
+ b.Property("VerificationTypeId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("VerificationTypeId");
+
+ b.HasIndex("OpportunityId", "VerificationTypeId")
+ .IsUnique();
+
+ b.ToTable("OpportunityVerificationTypes", "Opportunity");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Reward.Entities.Lookups.RewardTransactionStatus", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(30)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique()
+ .HasDatabaseName("IX_TransactionStatus_Name1");
+
+ b.ToTable("TransactionStatus", "Reward");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Reward.Entities.Lookups.WalletCreationStatus", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("WalletCreationStatus", "Reward");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Reward.Entities.RewardTransaction", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("Amount")
+ .HasColumnType("decimal(8,2)");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateModified")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("ErrorReason")
+ .HasColumnType("text");
+
+ b.Property("MyOpportunityId")
+ .HasColumnType("uuid");
+
+ b.Property("RetryCount")
+ .HasColumnType("smallint");
+
+ b.Property("SourceEntityType")
+ .IsRequired()
+ .HasColumnType("varchar(25)");
+
+ b.Property("StatusId")
+ .HasColumnType("uuid");
+
+ b.Property("TransactionId")
+ .HasColumnType("varchar(50)");
+
+ b.Property("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MyOpportunityId");
+
+ b.HasIndex("StatusId", "DateCreated", "DateModified");
+
+ b.HasIndex("UserId", "SourceEntityType", "MyOpportunityId")
+ .IsUnique();
+
+ b.ToTable("Transaction", "Reward");
+ });
+
+ modelBuilder.Entity("Yoma.Core.Infrastructure.Database.Reward.Entities.WalletCreation", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property