From 5ab977e33591688839d084880739c4dccb358d15 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Thu, 20 Aug 2026 13:37:24 +0200 Subject: [PATCH] Added Invite, Notification and Activity --- .../Configuration/Activity.cs | 56 + .../Configuration/Award.cs | 2 +- .../Configuration/Evidence.cs | 16 +- .../Configuration/Instrument.cs | 9 +- .../Configuration/Invite.cs | 51 + .../Configuration/Issue.cs | 8 + .../Configuration/Milestone.cs | 1 + .../Configuration/Notification.cs | 36 + .../Configuration/Programme.cs | 7 - .../Configuration/Project.cs | 4 +- .../Entities/Activity.cs | 17 + .../Entities/Evidence.cs | 2 + .../Entities/Instrument.cs | 2 +- PostFundManagement.Domain/Entities/Invite.cs | 15 + PostFundManagement.Domain/Entities/Issue.cs | 2 + .../Entities/Notification.cs | 9 + .../Entities/Programme.cs | 2 +- PostFundManagement.Domain/Enums.cs | 79 + .../Extensions/Mappers.cs | 68 +- PostFundManagement.Domain/Models/Activity.cs | 32 + PostFundManagement.Domain/Models/Evidence.cs | 8 +- .../Models/Instrument.cs | 2 + PostFundManagement.Domain/Models/Invite.cs | 24 + PostFundManagement.Domain/Models/Issue.cs | 4 + PostFundManagement.Domain/Models/Milestone.cs | 2 + .../Models/Notification.cs | 28 + PostFundManagement.Domain/Models/Programme.cs | 2 - PostFundManagement.Domain/Models/Project.cs | 4 + .../Database/ApplicationDbContext.cs | 6 + ...3615_AddedActivityNotification.Designer.cs | 1966 +++++++++++++++++ ...0260820113615_AddedActivityNotification.cs | 455 ++++ .../ApplicationDbContextModelSnapshot.cs | 384 +++- pfm.dbml | 349 --- 33 files changed, 3259 insertions(+), 393 deletions(-) create mode 100644 PostFundManagement.Domain/Configuration/Activity.cs create mode 100644 PostFundManagement.Domain/Configuration/Invite.cs create mode 100644 PostFundManagement.Domain/Configuration/Notification.cs create mode 100644 PostFundManagement.Domain/Entities/Activity.cs create mode 100644 PostFundManagement.Domain/Entities/Invite.cs create mode 100644 PostFundManagement.Domain/Entities/Notification.cs create mode 100644 PostFundManagement.Domain/Models/Activity.cs create mode 100644 PostFundManagement.Domain/Models/Invite.cs create mode 100644 PostFundManagement.Domain/Models/Notification.cs create mode 100644 PostFundManagement.Infrastructure/Database/Migrations/20260820113615_AddedActivityNotification.Designer.cs create mode 100644 PostFundManagement.Infrastructure/Database/Migrations/20260820113615_AddedActivityNotification.cs delete mode 100644 pfm.dbml diff --git a/PostFundManagement.Domain/Configuration/Activity.cs b/PostFundManagement.Domain/Configuration/Activity.cs new file mode 100644 index 0000000..63a5194 --- /dev/null +++ b/PostFundManagement.Domain/Configuration/Activity.cs @@ -0,0 +1,56 @@ +using static PostFundManagement.Domain.Extensions.Constants; + +namespace PostFundManagement.Domain.Configuration; + +public sealed class Activity : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable(nameof(Entities.Activity).Pluralize()); + + builder.HasKey(pk => pk.Id); + builder.Property(f => f.ProjectId).IsRequired(); + builder.Property(f => f.MilestoneId).IsRequired(); + builder.Property(f => f.CreatedBy).IsRequired(); + builder.Property(f => f.UpdatedBy).IsRequired(false); + builder.Property(f => f.ApprovedBy).IsRequired(false); + builder.Property(f => f.CreatedAt).IsRequired().HasDefaultValueSql("now()"); + builder.Property(f => f.UpdatedAt).IsRequired(false); + builder.Property(f => f.PerformedAt).IsRequired(false); + builder.Property(f => f.Category).IsRequired().HasMaxLength(LabelLength); + builder.Property(f => f.Status).IsRequired().HasDefaultValueSql("1"); + builder.Property(f => f.Amount).IsRequired().HasPrecision(18, 2); + builder.Property(f => f.Title).IsRequired().HasMaxLength(LabelLength); + builder.Property(f => f.Description).IsRequired().HasMaxLength(TextLength); + + builder.HasOne(f => f.Project) + .WithMany() + .HasForeignKey(fk => fk.ProjectId) + .IsRequired() + .OnDelete(DeleteBehavior.Restrict); + + builder.HasOne(f => f.Milestone) + .WithMany() + .HasForeignKey(fk => fk.MilestoneId) + .IsRequired() + .OnDelete(DeleteBehavior.Restrict); + + builder.HasOne(f => f.Creator) + .WithMany() + .HasForeignKey(fk => fk.CreatedBy) + .IsRequired() + .OnDelete(DeleteBehavior.NoAction); + + builder.HasOne(f => f.Updator) + .WithMany() + .HasForeignKey(fk => fk.UpdatedBy) + .IsRequired(false) + .OnDelete(DeleteBehavior.NoAction); + + builder.HasOne(f => f.Approver) + .WithMany() + .HasForeignKey(fk => fk.ApprovedBy) + .IsRequired(false) + .OnDelete(DeleteBehavior.NoAction); + } +} \ No newline at end of file diff --git a/PostFundManagement.Domain/Configuration/Award.cs b/PostFundManagement.Domain/Configuration/Award.cs index 1c63692..0c68765 100644 --- a/PostFundManagement.Domain/Configuration/Award.cs +++ b/PostFundManagement.Domain/Configuration/Award.cs @@ -1,6 +1,6 @@ namespace PostFundManagement.Domain.Configuration; -public class Award : IEntityTypeConfiguration +public sealed class Award : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { diff --git a/PostFundManagement.Domain/Configuration/Evidence.cs b/PostFundManagement.Domain/Configuration/Evidence.cs index a2aad3a..fc2ff03 100644 --- a/PostFundManagement.Domain/Configuration/Evidence.cs +++ b/PostFundManagement.Domain/Configuration/Evidence.cs @@ -10,6 +10,7 @@ public sealed class Evidence : IEntityTypeConfiguration builder.Property(f => f.ProjectId).IsRequired(); builder.Property(f => f.MilestoneId).IsRequired(); builder.Property(f => f.IndicatorId).IsRequired(); + builder.Property(f => f.ActivityId).IsRequired(); builder.Property(f => f.CreatedBy).IsRequired(); builder.Property(f => f.UpdatedBy).IsRequired(); builder.Property(f => f.CreatedAt).IsRequired().HasDefaultValueSql("now()"); @@ -17,6 +18,7 @@ public sealed class Evidence : IEntityTypeConfiguration builder.Property(f => f.Version).IsRequired().HasDefaultValue(1); builder.Property(f => f.DocumentUrl).IsRequired(); builder.Property(f => f.Status).IsRequired().HasConversion().HasDefaultValueSql("1"); + builder.Property(f => f.Type).IsRequired().HasConversion().HasDefaultValueSql("9"); builder.HasOne(f => f.Project) .WithMany() @@ -27,7 +29,19 @@ public sealed class Evidence : IEntityTypeConfiguration builder.HasOne(f => f.Milestone) .WithMany() .HasForeignKey(fk => fk.MilestoneId) - .IsRequired(false) + .IsRequired() + .OnDelete(DeleteBehavior.Restrict); + + builder.HasOne(f => f.Indicator) + .WithMany() + .HasForeignKey(fk => fk.IndicatorId) + .IsRequired() + .OnDelete(DeleteBehavior.Restrict); + + builder.HasOne(f => f.Activity) + .WithMany(f => f.Evidences) + .HasForeignKey(fk => fk.ActivityId) + .IsRequired() .OnDelete(DeleteBehavior.Restrict); builder.HasOne(f => f.Creator) diff --git a/PostFundManagement.Domain/Configuration/Instrument.cs b/PostFundManagement.Domain/Configuration/Instrument.cs index 28618ec..298f536 100644 --- a/PostFundManagement.Domain/Configuration/Instrument.cs +++ b/PostFundManagement.Domain/Configuration/Instrument.cs @@ -9,13 +9,20 @@ public sealed class Instrument : IEntityTypeConfiguration builder.ToTable(nameof(Entities.Instrument).Pluralize()); builder.HasKey(pk => pk.Id); + builder.Property(f => f.ProgrammeId).IsRequired(); builder.Property(f => f.Code).IsRequired().HasMaxLength(ShortLabelLength); builder.Property(f => f.Name).IsRequired().HasMaxLength(LabelLength); builder.Property(f => f.Description).IsRequired(false).HasMaxLength(TextLength); builder.Property(f => f.Status).IsRequired().HasConversion().HasDefaultValueSql("2"); - builder.Property(f => f.CreatedBy).IsRequired(); + builder.Property(f => f.CreatedBy).IsRequired(); builder.Property(f => f.CreatedAt).IsRequired().HasDefaultValueSql("now()"); + builder.HasOne(f => f.Programme) + .WithMany(f => f.Instruments) + .HasForeignKey(fk => fk.ProgrammeId) + .IsRequired() + .OnDelete(DeleteBehavior.Restrict); + builder.HasOne(f => f.Creator) .WithMany() .HasForeignKey(fk => fk.CreatedBy) diff --git a/PostFundManagement.Domain/Configuration/Invite.cs b/PostFundManagement.Domain/Configuration/Invite.cs new file mode 100644 index 0000000..e76959b --- /dev/null +++ b/PostFundManagement.Domain/Configuration/Invite.cs @@ -0,0 +1,51 @@ + +namespace PostFundManagement.Domain.Configuration; + +public sealed class Invite : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable(nameof(Entities.Invite).Pluralize()); + + builder.HasKey(pk => pk.Id); + builder.Property(f => f.OrganisationId).IsRequired(); + builder.Property(f => f.InvitedOrganisationId).IsRequired(); + builder.Property(f => f.AwardId).IsRequired(); + builder.Property(f => f.ContractId).IsRequired(); + builder.Property(f => f.Recipient).IsRequired(); + builder.Property(f => f.CreatedBy).IsRequired(); + builder.Property(f => f.UpdatedBy).IsRequired(false); + builder.Property(f => f.CreatedAt).IsRequired().HasDefaultValueSql("now()"); + builder.Property(f => f.UpdatedAt).IsRequired(false); + + builder.HasOne(f => f.Organisation) + .WithMany() + .HasForeignKey(fk => fk.OrganisationId) + .IsRequired() + .OnDelete(DeleteBehavior.Restrict); + + builder.HasOne(f => f.InvitedOrganisation) + .WithMany() + .HasForeignKey(fk => fk.InvitedOrganisationId) + .IsRequired() + .OnDelete(DeleteBehavior.Restrict); + + builder.HasOne(f => f.Award) + .WithMany() + .HasForeignKey(fk => fk.AwardId) + .IsRequired() + .OnDelete(DeleteBehavior.Restrict); + + builder.HasOne(f => f.Contract) + .WithMany() + .HasForeignKey(fk => fk.ContractId) + .IsRequired() + .OnDelete(DeleteBehavior.Restrict); + + builder.HasOne(f => f.RecipientUser) + .WithMany() + .HasForeignKey(fk => fk.Recipient) + .IsRequired() + .OnDelete(DeleteBehavior.Restrict); + } +} \ No newline at end of file diff --git a/PostFundManagement.Domain/Configuration/Issue.cs b/PostFundManagement.Domain/Configuration/Issue.cs index 3e42e2d..fd3f4fa 100644 --- a/PostFundManagement.Domain/Configuration/Issue.cs +++ b/PostFundManagement.Domain/Configuration/Issue.cs @@ -13,10 +13,12 @@ public sealed class Issue : IEntityTypeConfiguration builder.Property(f => f.CreatedBy).IsRequired(); builder.Property(f => f.CreatedAt).IsRequired().HasDefaultValueSql("now()"); builder.Property(f => f.ResolvedAt).IsRequired(false); + builder.Property(f => f.AssignedTo).IsRequired(false); builder.Property(f => f.Title).IsRequired().HasMaxLength(LabelLength); builder.Property(f => f.Description).IsRequired().HasMaxLength(TextLength); builder.Property(f => f.Priority).IsRequired().HasConversion().HasDefaultValueSql("1"); builder.Property(f => f.Status).IsRequired().HasConversion().HasDefaultValueSql("1"); + builder.Property(f => f.Resolution).IsRequired(); builder.HasOne(f => f.Project) .WithMany() @@ -29,5 +31,11 @@ public sealed class Issue : IEntityTypeConfiguration .HasForeignKey(fk => fk.CreatedBy) .IsRequired() .OnDelete(DeleteBehavior.NoAction); + + builder.HasOne(f => f.Assignee) + .WithMany() + .HasForeignKey(fk => fk.AssignedTo) + .IsRequired() + .OnDelete(DeleteBehavior.SetNull); } } \ No newline at end of file diff --git a/PostFundManagement.Domain/Configuration/Milestone.cs b/PostFundManagement.Domain/Configuration/Milestone.cs index 5f16428..e38e4ce 100644 --- a/PostFundManagement.Domain/Configuration/Milestone.cs +++ b/PostFundManagement.Domain/Configuration/Milestone.cs @@ -17,6 +17,7 @@ public sealed class Milestone : IEntityTypeConfiguration builder.Property(f => f.DueAt).IsRequired(); builder.Property(f => f.Name).IsRequired().HasMaxLength(LabelLength); builder.Property(f => f.Status).IsRequired().HasConversion().HasDefaultValueSql("1"); + builder.Property(f => f.Priority).IsRequired().HasConversion().HasDefaultValueSql("1"); builder.HasOne(f => f.Project) .WithMany() diff --git a/PostFundManagement.Domain/Configuration/Notification.cs b/PostFundManagement.Domain/Configuration/Notification.cs new file mode 100644 index 0000000..c2fd488 --- /dev/null +++ b/PostFundManagement.Domain/Configuration/Notification.cs @@ -0,0 +1,36 @@ +using static PostFundManagement.Domain.Extensions.Constants; + +namespace PostFundManagement.Domain.Configuration; + +public sealed class Notification : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable(nameof(Entities.Notification).Pluralize()); + + builder.HasKey(pk => pk.Id); + builder.Property(f => f.CreatedAt).IsRequired().HasDefaultValueSql("now()"); + builder.Property(f => f.UpdatedAt).IsRequired(false); + builder.Property(f => f.SentAt).IsRequired(false); + builder.Property(f => f.Recipient).IsRequired(); + builder.Property(f => f.OrganisationId).IsRequired(); + builder.Property(f => f.Platform).IsRequired().HasConversion().HasDefaultValueSql("1"); + builder.Property(f => f.Status).IsRequired().HasConversion().HasDefaultValueSql("1"); + builder.Property(f => f.Subject).IsRequired(false).HasMaxLength(LabelLength); + builder.Property(f => f.Message).IsRequired().HasMaxLength(LargeTextLength); + builder.Property(f => f.Destination).IsRequired().HasMaxLength(LabelLength); + builder.Property(f => f.Error).IsRequired(false); + + builder.HasOne(f => f.Organisation) + .WithMany() + .HasForeignKey(fk => fk.OrganisationId) + .IsRequired() + .OnDelete(DeleteBehavior.Restrict); + + builder.HasOne(f => f.RecipientUser) + .WithMany() + .HasForeignKey(fk => fk.Recipient) + .IsRequired() + .OnDelete(DeleteBehavior.Restrict); + } +} \ No newline at end of file diff --git a/PostFundManagement.Domain/Configuration/Programme.cs b/PostFundManagement.Domain/Configuration/Programme.cs index 8a2f211..a2b79c6 100644 --- a/PostFundManagement.Domain/Configuration/Programme.cs +++ b/PostFundManagement.Domain/Configuration/Programme.cs @@ -10,7 +10,6 @@ public sealed class Programme : IEntityTypeConfiguration builder.HasKey(pk => pk.Id); builder.Property(f => f.PortfolioId).IsRequired(); - builder.Property(f => f.InstrumentId).IsRequired(); builder.Property(f => f.OwnedBy).IsRequired(); builder.Property(f => f.CreatedBy).IsRequired(); builder.Property(f => f.UpdatedBy).IsRequired(false); @@ -25,12 +24,6 @@ public sealed class Programme : IEntityTypeConfiguration .IsRequired() .OnDelete(DeleteBehavior.NoAction); - builder.HasOne(f => f.Instrument) - .WithMany(f => f.Programmes) - .HasForeignKey(fk => fk.InstrumentId) - .IsRequired() - .OnDelete(DeleteBehavior.NoAction); - builder.HasOne(f => f.Creator) .WithMany() .HasForeignKey(fk => fk.CreatedBy) diff --git a/PostFundManagement.Domain/Configuration/Project.cs b/PostFundManagement.Domain/Configuration/Project.cs index 3ea0a79..e3e833d 100644 --- a/PostFundManagement.Domain/Configuration/Project.cs +++ b/PostFundManagement.Domain/Configuration/Project.cs @@ -18,13 +18,15 @@ public sealed class Project : IEntityTypeConfiguration builder.Property(f => f.EndedAt).IsRequired(false); builder.Property(f => f.Name).IsRequired().HasMaxLength(LabelLength); builder.Property(f => f.Description).IsRequired().HasMaxLength(TextLength); + builder.Property(f => f.Sector).IsRequired().HasConversion().HasDefaultValueSql("11"); + builder.Property(f => f.ProjectType).IsRequired().HasConversion().HasDefaultValueSql("10"); builder.Property(f => f.Status).IsRequired().HasConversion().HasDefaultValueSql("1"); builder.HasOne(f => f.Programme) .WithMany(f => f.Projects) .HasForeignKey(fk => fk.ProgrammeId) .IsRequired() - .OnDelete(DeleteBehavior.NoAction); + .OnDelete(DeleteBehavior.Restrict); builder.HasOne(f => f.Creator) .WithMany() diff --git a/PostFundManagement.Domain/Entities/Activity.cs b/PostFundManagement.Domain/Entities/Activity.cs new file mode 100644 index 0000000..07ea73b --- /dev/null +++ b/PostFundManagement.Domain/Entities/Activity.cs @@ -0,0 +1,17 @@ +namespace PostFundManagement.Domain.Entities; + +[EntityTypeConfiguration] +public class Activity : Models.Activity +{ + public virtual User? Creator { get; set; } + + public virtual User? Updator { get; set; } + + public virtual User? Approver { get; set; } + + public virtual Project? Project { get; set; } + + public virtual Milestone? Milestone { get; set; } + + public virtual ICollection Evidences { get; set; } = []; +} \ No newline at end of file diff --git a/PostFundManagement.Domain/Entities/Evidence.cs b/PostFundManagement.Domain/Entities/Evidence.cs index 4e54706..7023532 100644 --- a/PostFundManagement.Domain/Entities/Evidence.cs +++ b/PostFundManagement.Domain/Entities/Evidence.cs @@ -9,6 +9,8 @@ public class Evidence : Models.Evidence public virtual Indicator? Indicator { get; set; } + public virtual Activity? Activity { get; set; } + public virtual User? Creator { get; set; } public virtual User? Updator { get; set; } diff --git a/PostFundManagement.Domain/Entities/Instrument.cs b/PostFundManagement.Domain/Entities/Instrument.cs index b3be8e0..d43f19c 100644 --- a/PostFundManagement.Domain/Entities/Instrument.cs +++ b/PostFundManagement.Domain/Entities/Instrument.cs @@ -5,5 +5,5 @@ public class Instrument : Models.Instrument { public virtual User? Creator { get; set; } - public virtual ICollection Programmes { get; set; } = []; + public virtual Programme? Programme { get; set; } } \ No newline at end of file diff --git a/PostFundManagement.Domain/Entities/Invite.cs b/PostFundManagement.Domain/Entities/Invite.cs new file mode 100644 index 0000000..a444f3c --- /dev/null +++ b/PostFundManagement.Domain/Entities/Invite.cs @@ -0,0 +1,15 @@ +namespace PostFundManagement.Domain.Entities; + +[EntityTypeConfiguration] +public class Invite : Models.Invite +{ + public virtual Organisation? Organisation { get; set; } + + public virtual Organisation? InvitedOrganisation { get; set; } + + public virtual Award? Award { get; set; } + + public virtual Contract? Contract { get; set; } + + public virtual User? RecipientUser { get; set; } +} \ No newline at end of file diff --git a/PostFundManagement.Domain/Entities/Issue.cs b/PostFundManagement.Domain/Entities/Issue.cs index 91a63b8..a3cf5ef 100644 --- a/PostFundManagement.Domain/Entities/Issue.cs +++ b/PostFundManagement.Domain/Entities/Issue.cs @@ -6,4 +6,6 @@ public class Issue : Models.Issue public virtual Project? Project { get; set; } public virtual User? Creator { get; set; } + + public virtual User? Assignee { get; set; } } \ No newline at end of file diff --git a/PostFundManagement.Domain/Entities/Notification.cs b/PostFundManagement.Domain/Entities/Notification.cs new file mode 100644 index 0000000..f14b0fc --- /dev/null +++ b/PostFundManagement.Domain/Entities/Notification.cs @@ -0,0 +1,9 @@ +namespace PostFundManagement.Domain.Entities; + +[EntityTypeConfiguration] +public class Notification : Models.Notification +{ + public virtual Organisation? Organisation { get; set; } + + public virtual User? RecipientUser { get; set; } +} \ No newline at end of file diff --git a/PostFundManagement.Domain/Entities/Programme.cs b/PostFundManagement.Domain/Entities/Programme.cs index fc76353..5c98681 100644 --- a/PostFundManagement.Domain/Entities/Programme.cs +++ b/PostFundManagement.Domain/Entities/Programme.cs @@ -9,7 +9,7 @@ public class Programme : Models.Programme public virtual Portfolio? Portfolio { get; set; } - public virtual Instrument? Instrument { get; set; } + public virtual ICollection Instruments { get; set; } = []; public virtual ICollection Rules { get; set; } = []; diff --git a/PostFundManagement.Domain/Enums.cs b/PostFundManagement.Domain/Enums.cs index 770d556..d251779 100644 --- a/PostFundManagement.Domain/Enums.cs +++ b/PostFundManagement.Domain/Enums.cs @@ -1,5 +1,84 @@ namespace PostFundManagement.Domain; +public enum NotificationStatus : int +{ + Pending = 1, + Queued = 2, + Processing = 3, + Sent = 4, + Delivered = 5, + Read = 6, + Failed = 7, + Cancelled = 8, + Bounced = 9 +} + +public enum NotificationPlatform : int +{ + Email = 1, + SMS = 2, + WhatsApp = 3, + PushNotification = 4, + InApp = 5, + Teams = 6, + Slack = 7, + Webhook = 8, + Other = 99 +} + +public enum EvidenceType : int +{ + AttendanceRegister = 1, + BankStatement = 2, + CompletionCertificate = 3, + FinancialInvoiceOrReceipt = 4, + GeotaggedPhoto = 5, + InspectionReport = 6, + MeetingMinutes = 7, + PayrollOrStipendRegister = 8, + ProcurementDocument = 9, + TechnicalSpecificationOrDesign = 10, + VideoRecording = 11, + Other = 99 +} + +public enum ProjectType : int +{ + CapacityBuildingAndTraining = 1, + CapitalExpenditureAndInfrastructure = 2, + CommercializationAndScaling = 3, + FeasibilityAndTechnicalAssistance = 4, + OperationalGrantAndSubsidy = 5, + ProductDevelopmentAndPrototyping = 6, + ResearchAndDevelopment = 7, + SocialImpactAndCommunityDevelopment = 8, + TechnologyTransferAndAdoption = 9, + Innovation = 10, + Other = 99 +} + +public enum IndustrySector : int +{ + AgricultureAndAgroProcessing = 1, + AutomotiveAndTransportEquipment = 2, + ChemicalsAndPharmaceuticals = 3, + ConstructionAndInfrastructure = 4, + CreativeIndustriesAndMedia = 5, + DefenseAndAerospace = 6, + EducationAndSkillsDevelopment = 7, + EnergyAndUtilities = 8, + FinancialServices = 9, + HealthcareAndLifeSciences = 10, + InformationCommunicationTechnology = 11, + ManufacturingAndIndustrial = 12, + MiningAndMetals = 13, + RealEstateAndHousing = 14, + RetailAndConsumerGoods = 15, + TourismAndHospitality = 16, + WaterAndSanitation = 17, + Other = 99 +} + public enum OrganisationType : int { // Non-Profit & Civil Society diff --git a/PostFundManagement.Domain/Extensions/Mappers.cs b/PostFundManagement.Domain/Extensions/Mappers.cs index fc720d9..d9153cd 100644 --- a/PostFundManagement.Domain/Extensions/Mappers.cs +++ b/PostFundManagement.Domain/Extensions/Mappers.cs @@ -4,6 +4,25 @@ namespace PostFundManagement.Domain.Extensions; public static class Mappers { + public static Activity Map(this Entities.Activity entity) => new() + { + Id = entity.Id, + Amount = entity.Amount, + ApprovedBy = entity.ApprovedBy, + Category = entity.Category, + CreatedAt = entity.CreatedAt, + CreatedBy = entity.CreatedBy, + Description = entity.Description, + MilestoneId = entity.MilestoneId, + PerformedAt = entity.PerformedAt, + ProjectId = entity.ProjectId, + Status = entity.Status, + Title = entity.Title, + UpdatedAt = entity.UpdatedAt, + UpdatedBy = entity.UpdatedBy + }; + + public static AuditLog Map(this Entities.AuditLog entity) => new() { Id = entity.Id, @@ -108,7 +127,9 @@ public static class Mappers Status = entity.Status, UpdatedAt = entity.UpdatedAt, UpdatedBy = entity.UpdatedBy, - Version = entity.Version + Version = entity.Version, + ActivityId = entity.ActivityId, + Type = entity.Type }; public static Indicator Map(this Entities.Indicator entity) => new() @@ -132,7 +153,22 @@ public static class Mappers CreatedBy = entity.CreatedBy, Description = entity.Description, Name = entity.Name, - Status = entity.Status + Status = entity.Status, + ProgrammeId = entity.ProgrammeId + }; + + public static Invite Map(this Entities.Invite entity) => new() + { + Id = entity.Id, + AwardId = entity.AwardId, + ContractId = entity.ContractId, + CreatedAt = entity.CreatedAt, + CreatedBy = entity.CreatedBy, + InvitedOrganisationId = entity.InvitedOrganisationId, + OrganisationId = entity.OrganisationId, + Recipient = entity.Recipient, + UpdatedAt = entity.UpdatedAt, + UpdatedBy = entity.UpdatedBy }; public static Issue Map(this Entities.Issue entity) => new() @@ -145,7 +181,9 @@ public static class Mappers ProjectId = entity.ProjectId, ResolvedAt = entity.ResolvedAt, Status = entity.Status, - Title = entity.Title + Title = entity.Title, + AssignedTo = entity.AssignedTo, + Resolution = entity.Resolution }; public static Milestone Map(this Entities.Milestone entity) => new() @@ -158,7 +196,8 @@ public static class Mappers ProjectId = entity.ProjectId, Status = entity.Status, UpdatedAt = entity.UpdatedAt, - UpdatedBy = entity.UpdatedBy + UpdatedBy = entity.UpdatedBy, + Priority = entity.Priority }; public static Organisation Map(this Entities.Organisation entity) => new() @@ -193,12 +232,27 @@ public static class Mappers OwnedBy = entity.OwnedBy }; + public static Notification Map(this Entities.Notification entity) => new() + { + Id = entity.Id, + CreatedAt = entity.CreatedAt, + Destination = entity.Destination, + Error = entity.Error, + Message = entity.Message, + OrganisationId = entity.OrganisationId, + Platform = entity.Platform, + Recipient = entity.Recipient, + SentAt = entity.SentAt, + Status = entity.Status, + Subject = entity.Subject, + UpdatedAt = entity.UpdatedAt + }; + public static Programme Map(this Entities.Programme entity) => new() { Id = entity.Id, CreatedAt = entity.CreatedAt, CreatedBy = entity.CreatedBy, - InstrumentId = entity.InstrumentId, Name = entity.Name, OwnedBy = entity.OwnedBy, PortfolioId = entity.PortfolioId, @@ -219,7 +273,9 @@ public static class Mappers StartedAt = entity.StartedAt, Status = entity.Status, UpdatedAt = entity.UpdatedAt, - UpdatedBy = entity.UpdatedBy + UpdatedBy = entity.UpdatedBy, + ProjectType = entity.ProjectType, + Sector = entity.Sector }; public static Risk Map(this Entities.Risk entity) => new() diff --git a/PostFundManagement.Domain/Models/Activity.cs b/PostFundManagement.Domain/Models/Activity.cs new file mode 100644 index 0000000..8235199 --- /dev/null +++ b/PostFundManagement.Domain/Models/Activity.cs @@ -0,0 +1,32 @@ +namespace PostFundManagement.Domain.Models; + +public class Activity +{ + public long Id { get; set; } + + public long? ProjectId { get; set; } + + public long? MilestoneId { get; set; } + + public Guid CreatedBy { get; set; } + + public Guid? UpdatedBy { get; set; } + + public Guid? ApprovedBy { get; set; } + + public DateTime CreatedAt { get; set; } + + public DateTime? UpdatedAt { get; set; } + + public string? Category { get; set; } + + public ApprovalStatus Status { get; set; } + + public decimal Amount { get; set; } + + public string? Title { get; set; } + + public string? Description { get; set; } + + public DateTime? PerformedAt { get; set; } +} \ No newline at end of file diff --git a/PostFundManagement.Domain/Models/Evidence.cs b/PostFundManagement.Domain/Models/Evidence.cs index 14c86a9..ac4bd82 100644 --- a/PostFundManagement.Domain/Models/Evidence.cs +++ b/PostFundManagement.Domain/Models/Evidence.cs @@ -6,9 +6,11 @@ public class Evidence public long ProjectId { get; set; } - public long? MilestoneId { get; set; } + public long MilestoneId { get; set; } - public long? IndicatorId { get; set; } + public long IndicatorId { get; set; } + + public long ActivityId { get; set; } public Guid CreatedBy { get; set; } @@ -20,6 +22,8 @@ public class Evidence public int Version { get; set; } + public EvidenceType Type { get; set; } + public string? DocumentUrl { get; set; } public ApprovalStatus Status { get; set; } diff --git a/PostFundManagement.Domain/Models/Instrument.cs b/PostFundManagement.Domain/Models/Instrument.cs index 1ddbfd3..3cd09ab 100644 --- a/PostFundManagement.Domain/Models/Instrument.cs +++ b/PostFundManagement.Domain/Models/Instrument.cs @@ -4,6 +4,8 @@ public class Instrument { public long Id { get; set; } + public long ProgrammeId { get; set; } + public string? Code { get; set; } public string? Name { get; set; } diff --git a/PostFundManagement.Domain/Models/Invite.cs b/PostFundManagement.Domain/Models/Invite.cs new file mode 100644 index 0000000..f78ac27 --- /dev/null +++ b/PostFundManagement.Domain/Models/Invite.cs @@ -0,0 +1,24 @@ +namespace PostFundManagement.Domain.Models; + +public class Invite +{ + public long Id { get; set; } + + public long OrganisationId { get; set; } + + public long InvitedOrganisationId { get; set; } + + public long AwardId { get; set; } + + public long ContractId { get; set; } + + public Guid Recipient { get; set; } + + public Guid CreatedBy { get; set; } + + public Guid? UpdatedBy { get; set; } + + public DateTime CreatedAt { get; set; } + + public DateTime? UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/PostFundManagement.Domain/Models/Issue.cs b/PostFundManagement.Domain/Models/Issue.cs index e9ad515..4bdbf45 100644 --- a/PostFundManagement.Domain/Models/Issue.cs +++ b/PostFundManagement.Domain/Models/Issue.cs @@ -18,5 +18,9 @@ public class Issue public DateTime CreatedAt { get; set; } + public Guid? AssignedTo { get; set; } + public DateTime? ResolvedAt { get; set; } + + public string? Resolution { get; set; } } \ No newline at end of file diff --git a/PostFundManagement.Domain/Models/Milestone.cs b/PostFundManagement.Domain/Models/Milestone.cs index 1da57b7..c42d74e 100644 --- a/PostFundManagement.Domain/Models/Milestone.cs +++ b/PostFundManagement.Domain/Models/Milestone.cs @@ -19,4 +19,6 @@ public class Milestone public string? Name { get; set; } public ApprovalStatus Status { get; set; } + + public Priority Priority { get; set; } } \ No newline at end of file diff --git a/PostFundManagement.Domain/Models/Notification.cs b/PostFundManagement.Domain/Models/Notification.cs new file mode 100644 index 0000000..affa356 --- /dev/null +++ b/PostFundManagement.Domain/Models/Notification.cs @@ -0,0 +1,28 @@ +namespace PostFundManagement.Domain.Models; + +public class Notification +{ + public long Id { get; set; } + + public long OrganisationId { get; set; } + + public Guid Recipient { get; set; } + + public NotificationPlatform Platform { get; set; } + + public NotificationStatus Status { get; set; } + + public string? Subject { get; set; } + + public string? Message { get; set; } + + public string? Destination { get; set; } + + public DateTime CreatedAt { get; set; } + + public DateTime? SentAt { get; set; } + + public DateTime? UpdatedAt { get; set; } + + public string? Error { get; set; } +} \ No newline at end of file diff --git a/PostFundManagement.Domain/Models/Programme.cs b/PostFundManagement.Domain/Models/Programme.cs index d04372d..e05fd15 100644 --- a/PostFundManagement.Domain/Models/Programme.cs +++ b/PostFundManagement.Domain/Models/Programme.cs @@ -6,8 +6,6 @@ public class Programme public long PortfolioId { get; set; } - public long InstrumentId { get; set; } - public Guid OwnedBy { get; set; } public Guid CreatedBy { get; set; } diff --git a/PostFundManagement.Domain/Models/Project.cs b/PostFundManagement.Domain/Models/Project.cs index 4a09337..795f75a 100644 --- a/PostFundManagement.Domain/Models/Project.cs +++ b/PostFundManagement.Domain/Models/Project.cs @@ -18,6 +18,10 @@ public class Project public DateTime? EndedAt { get; set; } + public IndustrySector Sector { get; set; } + + public ProjectType ProjectType { get; set; } + public string? Name { get; set; } public string? Description { get; set; } diff --git a/PostFundManagement.Infrastructure/Database/ApplicationDbContext.cs b/PostFundManagement.Infrastructure/Database/ApplicationDbContext.cs index 044a49f..0f4a87b 100644 --- a/PostFundManagement.Infrastructure/Database/ApplicationDbContext.cs +++ b/PostFundManagement.Infrastructure/Database/ApplicationDbContext.cs @@ -4,6 +4,12 @@ namespace PostFundManagement.Infrastructure.Database; public sealed class ApplicationDbContext(DbContextOptions options) : DbContext(options) { + public DbSet Notifications => Set(); + + public DbSet Invites => Set(); + + public DbSet Activities => Set(); + public DbSet AuditLogs => Set(); public DbSet SiteVisits => Set(); diff --git a/PostFundManagement.Infrastructure/Database/Migrations/20260820113615_AddedActivityNotification.Designer.cs b/PostFundManagement.Infrastructure/Database/Migrations/20260820113615_AddedActivityNotification.Designer.cs new file mode 100644 index 0000000..f683f64 --- /dev/null +++ b/PostFundManagement.Infrastructure/Database/Migrations/20260820113615_AddedActivityNotification.Designer.cs @@ -0,0 +1,1966 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using PostFundManagement.Infrastructure.Database; + +#nullable disable + +namespace PostFundManagement.Infrastructure.Database.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20260820113615_AddedActivityNotification")] + partial class AddedActivityNotification + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.11") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Activity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("ApprovedBy") + .HasColumnType("uuid"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("MilestoneId") + .HasColumnType("bigint"); + + b.Property("PerformedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ProjectId") + .HasColumnType("bigint"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ApprovedBy"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("MilestoneId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Activities", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.PrimitiveCollection("Changes") + .HasColumnType("jsonb"); + + b.Property("EntityId") + .HasColumnType("bigint"); + + b.Property("EntityName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PerformedBy") + .HasColumnType("uuid"); + + b.Property("Timestamp") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("PerformedBy"); + + b.ToTable("AuditLogs", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Award", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("ApprovedBy") + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("OrganisationId") + .HasColumnType("bigint"); + + b.Property("ProgrammeId") + .HasColumnType("bigint"); + + b.Property("ProjectId") + .HasColumnType("bigint"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ApprovedBy"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("OrganisationId"); + + b.HasIndex("ProgrammeId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Awards", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Beneficiary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Category") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Location") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ProjectId") + .HasColumnType("bigint"); + + b.Property("ReachedCount") + .HasColumnType("integer"); + + b.Property("TargetCount") + .HasColumnType("integer"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("ProjectId"); + + b.HasIndex("UserId"); + + b.ToTable("Beneficiaries", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Budget", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("ApprovedBy") + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ProjectId") + .HasColumnType("bigint"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ApprovedBy"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("ProjectId"); + + b.ToTable("Budgets", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.ChangeRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ApprovedBy") + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Justification") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("ProjectId") + .HasColumnType("bigint"); + + b.Property("RevisedBudget") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("RevisedEndedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ApprovedBy"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("ProjectId"); + + b.ToTable("ChangeRequests", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.ComplianceItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("ProjectId") + .HasColumnType("bigint"); + + b.Property("Requirements") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("VerifiedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("ProjectId"); + + b.HasIndex("VerifiedBy"); + + b.ToTable("ComplianceItems", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Contract", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AwardId") + .HasColumnType("bigint"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("EffectiveAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ExternalSignatureId") + .HasColumnType("text"); + + b.Property("SignedDocumentUrl") + .HasColumnType("text"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("TotalValue") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("AwardId") + .IsUnique(); + + b.HasIndex("CreatedBy"); + + b.ToTable("Contracts", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Disbursement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("MilestoneId") + .HasColumnType("bigint"); + + b.Property("ProjectId") + .HasColumnType("bigint"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("MilestoneId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Disbursements", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Evidence", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ActivityId") + .HasColumnType("bigint"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("DocumentUrl") + .IsRequired() + .HasColumnType("text"); + + b.Property("IndicatorId") + .HasColumnType("bigint"); + + b.Property("MilestoneId") + .HasColumnType("bigint"); + + b.Property("ProjectId") + .HasColumnType("bigint"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("Type") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("9"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.Property("Version") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(1); + + b.HasKey("Id"); + + b.HasIndex("ActivityId"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("IndicatorId"); + + b.HasIndex("MilestoneId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Evidences", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Indicator", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ActualAmount") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("BaselineAmount") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ProjectId") + .HasColumnType("bigint"); + + b.Property("TargetAmount") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("UnitOfMeasure") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("2"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("ProjectId"); + + b.ToTable("Indicators", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Instrument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Code") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ProgrammeId") + .HasColumnType("bigint"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("2"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("ProgrammeId"); + + b.ToTable("Instruments", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Invite", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AwardId") + .HasColumnType("bigint"); + + b.Property("ContractId") + .HasColumnType("bigint"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("InvitedOrganisationId") + .HasColumnType("bigint"); + + b.Property("OrganisationId") + .HasColumnType("bigint"); + + b.Property("Recipient") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("AwardId"); + + b.HasIndex("ContractId"); + + b.HasIndex("InvitedOrganisationId"); + + b.HasIndex("OrganisationId"); + + b.HasIndex("Recipient"); + + b.ToTable("Invites", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Issue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AssignedTo") + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("Priority") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("ProjectId") + .HasColumnType("bigint"); + + b.Property("Resolution") + .IsRequired() + .HasColumnType("text"); + + b.Property("ResolvedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("AssignedTo"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("ProjectId"); + + b.ToTable("Issues", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Milestone", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("DueAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Priority") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("ProjectId") + .HasColumnType("bigint"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("ProjectId"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Milestones", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Destination") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Error") + .HasColumnType("text"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)"); + + b.Property("OrganisationId") + .HasColumnType("bigint"); + + b.Property("Platform") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("Recipient") + .HasColumnType("uuid"); + + b.Property("SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("Subject") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("OrganisationId"); + + b.HasIndex("Recipient"); + + b.ToTable("Notifications", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Organisation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("RegistrationNo") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("Type") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("5"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.ToTable("Organisations", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Outcome", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BeneficiaryId") + .HasColumnType("bigint"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("BeneficiaryId"); + + b.HasIndex("CreatedBy"); + + b.ToTable("Outcomes", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Portfolio", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("OwnedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("OwnedBy"); + + b.ToTable("Portfolios", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Programme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("OwnedBy") + .HasColumnType("uuid"); + + b.Property("PortfolioId") + .HasColumnType("bigint"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("OwnedBy"); + + b.HasIndex("PortfolioId"); + + b.ToTable("Programmes", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("EndedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ProgrammeId") + .HasColumnType("bigint"); + + b.Property("ProjectType") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("10"); + + b.Property("Sector") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("11"); + + b.Property("StartedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("ProgrammeId"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Risk", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("Impact") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("Likelihood") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("3"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ProjectId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("ProjectId"); + + b.ToTable("Risks", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Rule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ProgrammeId") + .HasColumnType("bigint"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("2"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.Property("Version") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(1); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("ProgrammeId"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Rules", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.SiteVisit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Findings") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)"); + + b.Property("InspectorName") + .IsRequired() + .HasColumnType("text"); + + b.Property("ProjectId") + .HasColumnType("bigint"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("VisitedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("ProjectId"); + + b.ToTable("SiteVisits", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LastLoginAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("2"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Activity", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Approver") + .WithMany() + .HasForeignKey("ApprovedBy") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Milestone", "Milestone") + .WithMany() + .HasForeignKey("MilestoneId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Updator") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Approver"); + + b.Navigation("Creator"); + + b.Navigation("Milestone"); + + b.Navigation("Project"); + + b.Navigation("Updator"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.AuditLog", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Performer") + .WithMany() + .HasForeignKey("PerformedBy") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Performer"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Award", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Approver") + .WithMany() + .HasForeignKey("ApprovedBy") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Organisation", "Organisation") + .WithMany() + .HasForeignKey("OrganisationId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Programme", "Programme") + .WithMany("Awards") + .HasForeignKey("ProgrammeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") + .WithMany("Awards") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Updator") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Approver"); + + b.Navigation("Creator"); + + b.Navigation("Organisation"); + + b.Navigation("Programme"); + + b.Navigation("Project"); + + b.Navigation("Updator"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Beneficiary", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Creator"); + + b.Navigation("Project"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Budget", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Approver") + .WithMany() + .HasForeignKey("ApprovedBy") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Approver"); + + b.Navigation("Creator"); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.ChangeRequest", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Approver") + .WithMany() + .HasForeignKey("ApprovedBy") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Approver"); + + b.Navigation("Creator"); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.ComplianceItem", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Verifier") + .WithMany() + .HasForeignKey("VerifiedBy") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Creator"); + + b.Navigation("Project"); + + b.Navigation("Verifier"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Contract", b => + { + b.HasOne("PostFundManagement.Domain.Entities.Award", "Award") + .WithOne("Contract") + .HasForeignKey("PostFundManagement.Domain.Entities.Contract", "AwardId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Award"); + + b.Navigation("Creator"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Disbursement", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Milestone", "Milestone") + .WithMany() + .HasForeignKey("MilestoneId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Updator") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Creator"); + + b.Navigation("Milestone"); + + b.Navigation("Project"); + + b.Navigation("Updator"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Evidence", b => + { + b.HasOne("PostFundManagement.Domain.Entities.Activity", "Activity") + .WithMany("Evidences") + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Indicator", "Indicator") + .WithMany() + .HasForeignKey("IndicatorId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Milestone", "Milestone") + .WithMany() + .HasForeignKey("MilestoneId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Updator") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Activity"); + + b.Navigation("Creator"); + + b.Navigation("Indicator"); + + b.Navigation("Milestone"); + + b.Navigation("Project"); + + b.Navigation("Updator"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Indicator", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Creator"); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Instrument", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Programme", "Programme") + .WithMany("Instruments") + .HasForeignKey("ProgrammeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Creator"); + + b.Navigation("Programme"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Invite", b => + { + b.HasOne("PostFundManagement.Domain.Entities.Award", "Award") + .WithMany() + .HasForeignKey("AwardId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Contract", "Contract") + .WithMany() + .HasForeignKey("ContractId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Organisation", "InvitedOrganisation") + .WithMany() + .HasForeignKey("InvitedOrganisationId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Organisation", "Organisation") + .WithMany() + .HasForeignKey("OrganisationId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "RecipientUser") + .WithMany() + .HasForeignKey("Recipient") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Award"); + + b.Navigation("Contract"); + + b.Navigation("InvitedOrganisation"); + + b.Navigation("Organisation"); + + b.Navigation("RecipientUser"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Issue", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Assignee") + .WithMany() + .HasForeignKey("AssignedTo") + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Assignee"); + + b.Navigation("Creator"); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Milestone", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Updator") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Creator"); + + b.Navigation("Project"); + + b.Navigation("Updator"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Notification", b => + { + b.HasOne("PostFundManagement.Domain.Entities.Organisation", "Organisation") + .WithMany() + .HasForeignKey("OrganisationId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "RecipientUser") + .WithMany() + .HasForeignKey("Recipient") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Organisation"); + + b.Navigation("RecipientUser"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Organisation", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Creator"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Outcome", b => + { + b.HasOne("PostFundManagement.Domain.Entities.Beneficiary", "Beneficiary") + .WithMany() + .HasForeignKey("BeneficiaryId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Beneficiary"); + + b.Navigation("Creator"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Portfolio", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Creator"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Programme", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Portfolio", "Portfolio") + .WithMany("Programmes") + .HasForeignKey("PortfolioId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Creator"); + + b.Navigation("Owner"); + + b.Navigation("Portfolio"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Project", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Programme", "Programme") + .WithMany("Projects") + .HasForeignKey("ProgrammeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Updator") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Creator"); + + b.Navigation("Programme"); + + b.Navigation("Updator"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Risk", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Creator"); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Rule", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Programme", "Programme") + .WithMany("Rules") + .HasForeignKey("ProgrammeId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Updator") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Creator"); + + b.Navigation("Programme"); + + b.Navigation("Updator"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.SiteVisit", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Creator"); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Activity", b => + { + b.Navigation("Evidences"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Award", b => + { + b.Navigation("Contract"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Portfolio", b => + { + b.Navigation("Programmes"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Programme", b => + { + b.Navigation("Awards"); + + b.Navigation("Instruments"); + + b.Navigation("Projects"); + + b.Navigation("Rules"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Project", b => + { + b.Navigation("Awards"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/PostFundManagement.Infrastructure/Database/Migrations/20260820113615_AddedActivityNotification.cs b/PostFundManagement.Infrastructure/Database/Migrations/20260820113615_AddedActivityNotification.cs new file mode 100644 index 0000000..d7cd6db --- /dev/null +++ b/PostFundManagement.Infrastructure/Database/Migrations/20260820113615_AddedActivityNotification.cs @@ -0,0 +1,455 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace PostFundManagement.Infrastructure.Database.Migrations +{ + /// + public partial class AddedActivityNotification : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Evidences_Indicators_IndicatorId", + table: "Evidences"); + + migrationBuilder.DropForeignKey( + name: "FK_Programmes_Instruments_InstrumentId", + table: "Programmes"); + + migrationBuilder.DropForeignKey( + name: "FK_Projects_Programmes_ProgrammeId", + table: "Projects"); + + migrationBuilder.DropIndex( + name: "IX_Programmes_InstrumentId", + table: "Programmes"); + + migrationBuilder.DropColumn( + name: "InstrumentId", + table: "Programmes"); + + migrationBuilder.AddColumn( + name: "ProjectType", + table: "Projects", + type: "integer", + nullable: false, + defaultValueSql: "10"); + + migrationBuilder.AddColumn( + name: "Sector", + table: "Projects", + type: "integer", + nullable: false, + defaultValueSql: "11"); + + migrationBuilder.AddColumn( + name: "Priority", + table: "Milestones", + type: "integer", + nullable: false, + defaultValueSql: "1"); + + migrationBuilder.AddColumn( + name: "AssignedTo", + table: "Issues", + type: "uuid", + nullable: true); + + migrationBuilder.AddColumn( + name: "Resolution", + table: "Issues", + type: "text", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "ProgrammeId", + table: "Instruments", + type: "bigint", + nullable: false, + defaultValue: 0L); + + migrationBuilder.AddColumn( + name: "ActivityId", + table: "Evidences", + type: "bigint", + nullable: false, + defaultValue: 0L); + + migrationBuilder.AddColumn( + name: "Type", + table: "Evidences", + type: "integer", + nullable: false, + defaultValueSql: "9"); + + migrationBuilder.CreateTable( + name: "Activities", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + ProjectId = table.Column(type: "bigint", nullable: false), + MilestoneId = table.Column(type: "bigint", nullable: false), + CreatedBy = table.Column(type: "uuid", nullable: false), + UpdatedBy = table.Column(type: "uuid", nullable: true), + ApprovedBy = table.Column(type: "uuid", nullable: true), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true), + Category = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), + Status = table.Column(type: "integer", nullable: false, defaultValueSql: "1"), + Amount = table.Column(type: "numeric(18,2)", precision: 18, scale: 2, nullable: false), + Title = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), + Description = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: false), + PerformedAt = table.Column(type: "timestamp with time zone", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Activities", x => x.Id); + table.ForeignKey( + name: "FK_Activities_Milestones_MilestoneId", + column: x => x.MilestoneId, + principalTable: "Milestones", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Activities_Projects_ProjectId", + column: x => x.ProjectId, + principalTable: "Projects", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Activities_Users_ApprovedBy", + column: x => x.ApprovedBy, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_Activities_Users_CreatedBy", + column: x => x.CreatedBy, + principalTable: "Users", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_Activities_Users_UpdatedBy", + column: x => x.UpdatedBy, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "Invites", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + OrganisationId = table.Column(type: "bigint", nullable: false), + InvitedOrganisationId = table.Column(type: "bigint", nullable: false), + AwardId = table.Column(type: "bigint", nullable: false), + ContractId = table.Column(type: "bigint", nullable: false), + Recipient = table.Column(type: "uuid", nullable: false), + CreatedBy = table.Column(type: "uuid", nullable: false), + UpdatedBy = table.Column(type: "uuid", nullable: true), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Invites", x => x.Id); + table.ForeignKey( + name: "FK_Invites_Awards_AwardId", + column: x => x.AwardId, + principalTable: "Awards", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Invites_Contracts_ContractId", + column: x => x.ContractId, + principalTable: "Contracts", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Invites_Organisations_InvitedOrganisationId", + column: x => x.InvitedOrganisationId, + principalTable: "Organisations", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Invites_Organisations_OrganisationId", + column: x => x.OrganisationId, + principalTable: "Organisations", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Invites_Users_Recipient", + column: x => x.Recipient, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "Notifications", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + OrganisationId = table.Column(type: "bigint", nullable: false), + Recipient = table.Column(type: "uuid", nullable: false), + Platform = table.Column(type: "integer", nullable: false, defaultValueSql: "1"), + Status = table.Column(type: "integer", nullable: false, defaultValueSql: "1"), + Subject = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + Message = table.Column(type: "character varying(4096)", maxLength: 4096, nullable: false), + Destination = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + SentAt = table.Column(type: "timestamp with time zone", nullable: true), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true), + Error = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Notifications", x => x.Id); + table.ForeignKey( + name: "FK_Notifications_Organisations_OrganisationId", + column: x => x.OrganisationId, + principalTable: "Organisations", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Notifications_Users_Recipient", + column: x => x.Recipient, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_Issues_AssignedTo", + table: "Issues", + column: "AssignedTo"); + + migrationBuilder.CreateIndex( + name: "IX_Instruments_ProgrammeId", + table: "Instruments", + column: "ProgrammeId"); + + migrationBuilder.CreateIndex( + name: "IX_Evidences_ActivityId", + table: "Evidences", + column: "ActivityId"); + + migrationBuilder.CreateIndex( + name: "IX_Activities_ApprovedBy", + table: "Activities", + column: "ApprovedBy"); + + migrationBuilder.CreateIndex( + name: "IX_Activities_CreatedBy", + table: "Activities", + column: "CreatedBy"); + + migrationBuilder.CreateIndex( + name: "IX_Activities_MilestoneId", + table: "Activities", + column: "MilestoneId"); + + migrationBuilder.CreateIndex( + name: "IX_Activities_ProjectId", + table: "Activities", + column: "ProjectId"); + + migrationBuilder.CreateIndex( + name: "IX_Activities_UpdatedBy", + table: "Activities", + column: "UpdatedBy"); + + migrationBuilder.CreateIndex( + name: "IX_Invites_AwardId", + table: "Invites", + column: "AwardId"); + + migrationBuilder.CreateIndex( + name: "IX_Invites_ContractId", + table: "Invites", + column: "ContractId"); + + migrationBuilder.CreateIndex( + name: "IX_Invites_InvitedOrganisationId", + table: "Invites", + column: "InvitedOrganisationId"); + + migrationBuilder.CreateIndex( + name: "IX_Invites_OrganisationId", + table: "Invites", + column: "OrganisationId"); + + migrationBuilder.CreateIndex( + name: "IX_Invites_Recipient", + table: "Invites", + column: "Recipient"); + + migrationBuilder.CreateIndex( + name: "IX_Notifications_OrganisationId", + table: "Notifications", + column: "OrganisationId"); + + migrationBuilder.CreateIndex( + name: "IX_Notifications_Recipient", + table: "Notifications", + column: "Recipient"); + + migrationBuilder.AddForeignKey( + name: "FK_Evidences_Activities_ActivityId", + table: "Evidences", + column: "ActivityId", + principalTable: "Activities", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "FK_Evidences_Indicators_IndicatorId", + table: "Evidences", + column: "IndicatorId", + principalTable: "Indicators", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "FK_Instruments_Programmes_ProgrammeId", + table: "Instruments", + column: "ProgrammeId", + principalTable: "Programmes", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "FK_Issues_Users_AssignedTo", + table: "Issues", + column: "AssignedTo", + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.SetNull); + + migrationBuilder.AddForeignKey( + name: "FK_Projects_Programmes_ProgrammeId", + table: "Projects", + column: "ProgrammeId", + principalTable: "Programmes", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Evidences_Activities_ActivityId", + table: "Evidences"); + + migrationBuilder.DropForeignKey( + name: "FK_Evidences_Indicators_IndicatorId", + table: "Evidences"); + + migrationBuilder.DropForeignKey( + name: "FK_Instruments_Programmes_ProgrammeId", + table: "Instruments"); + + migrationBuilder.DropForeignKey( + name: "FK_Issues_Users_AssignedTo", + table: "Issues"); + + migrationBuilder.DropForeignKey( + name: "FK_Projects_Programmes_ProgrammeId", + table: "Projects"); + + migrationBuilder.DropTable( + name: "Activities"); + + migrationBuilder.DropTable( + name: "Invites"); + + migrationBuilder.DropTable( + name: "Notifications"); + + migrationBuilder.DropIndex( + name: "IX_Issues_AssignedTo", + table: "Issues"); + + migrationBuilder.DropIndex( + name: "IX_Instruments_ProgrammeId", + table: "Instruments"); + + migrationBuilder.DropIndex( + name: "IX_Evidences_ActivityId", + table: "Evidences"); + + migrationBuilder.DropColumn( + name: "ProjectType", + table: "Projects"); + + migrationBuilder.DropColumn( + name: "Sector", + table: "Projects"); + + migrationBuilder.DropColumn( + name: "Priority", + table: "Milestones"); + + migrationBuilder.DropColumn( + name: "AssignedTo", + table: "Issues"); + + migrationBuilder.DropColumn( + name: "Resolution", + table: "Issues"); + + migrationBuilder.DropColumn( + name: "ProgrammeId", + table: "Instruments"); + + migrationBuilder.DropColumn( + name: "ActivityId", + table: "Evidences"); + + migrationBuilder.DropColumn( + name: "Type", + table: "Evidences"); + + migrationBuilder.AddColumn( + name: "InstrumentId", + table: "Programmes", + type: "bigint", + nullable: false, + defaultValue: 0L); + + migrationBuilder.CreateIndex( + name: "IX_Programmes_InstrumentId", + table: "Programmes", + column: "InstrumentId"); + + migrationBuilder.AddForeignKey( + name: "FK_Evidences_Indicators_IndicatorId", + table: "Evidences", + column: "IndicatorId", + principalTable: "Indicators", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Programmes_Instruments_InstrumentId", + table: "Programmes", + column: "InstrumentId", + principalTable: "Instruments", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Projects_Programmes_ProgrammeId", + table: "Projects", + column: "ProgrammeId", + principalTable: "Programmes", + principalColumn: "Id"); + } + } +} diff --git a/PostFundManagement.Infrastructure/Database/Migrations/ApplicationDbContextModelSnapshot.cs b/PostFundManagement.Infrastructure/Database/Migrations/ApplicationDbContextModelSnapshot.cs index b90e527..a739df6 100644 --- a/PostFundManagement.Infrastructure/Database/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/PostFundManagement.Infrastructure/Database/Migrations/ApplicationDbContextModelSnapshot.cs @@ -22,6 +22,79 @@ namespace PostFundManagement.Infrastructure.Database.Migrations NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + modelBuilder.Entity("PostFundManagement.Domain.Entities.Activity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("numeric(18,2)"); + + b.Property("ApprovedBy") + .HasColumnType("uuid"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("MilestoneId") + .HasColumnType("bigint"); + + b.Property("PerformedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ProjectId") + .HasColumnType("bigint"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ApprovedBy"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("MilestoneId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Activities", (string)null); + }); + modelBuilder.Entity("PostFundManagement.Domain.Entities.AuditLog", b => { b.Property("Id") @@ -436,6 +509,9 @@ namespace PostFundManagement.Infrastructure.Database.Migrations NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + b.Property("ActivityId") + .HasColumnType("bigint"); + b.Property("CreatedAt") .ValueGeneratedOnAdd() .HasColumnType("timestamp with time zone") @@ -462,6 +538,11 @@ namespace PostFundManagement.Infrastructure.Database.Migrations .HasColumnType("integer") .HasDefaultValueSql("1"); + b.Property("Type") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("9"); + b.Property("UpdatedAt") .HasColumnType("timestamp with time zone"); @@ -475,6 +556,8 @@ namespace PostFundManagement.Infrastructure.Database.Migrations b.HasKey("Id"); + b.HasIndex("ActivityId"); + b.HasIndex("CreatedBy"); b.HasIndex("IndicatorId"); @@ -568,6 +651,9 @@ namespace PostFundManagement.Infrastructure.Database.Migrations .HasMaxLength(256) .HasColumnType("character varying(256)"); + b.Property("ProgrammeId") + .HasColumnType("bigint"); + b.Property("Status") .ValueGeneratedOnAdd() .HasColumnType("integer") @@ -577,9 +663,63 @@ namespace PostFundManagement.Infrastructure.Database.Migrations b.HasIndex("CreatedBy"); + b.HasIndex("ProgrammeId"); + b.ToTable("Instruments", (string)null); }); + modelBuilder.Entity("PostFundManagement.Domain.Entities.Invite", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AwardId") + .HasColumnType("bigint"); + + b.Property("ContractId") + .HasColumnType("bigint"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("InvitedOrganisationId") + .HasColumnType("bigint"); + + b.Property("OrganisationId") + .HasColumnType("bigint"); + + b.Property("Recipient") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("AwardId"); + + b.HasIndex("ContractId"); + + b.HasIndex("InvitedOrganisationId"); + + b.HasIndex("OrganisationId"); + + b.HasIndex("Recipient"); + + b.ToTable("Invites", (string)null); + }); + modelBuilder.Entity("PostFundManagement.Domain.Entities.Issue", b => { b.Property("Id") @@ -588,6 +728,9 @@ namespace PostFundManagement.Infrastructure.Database.Migrations NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + b.Property("AssignedTo") + .HasColumnType("uuid"); + b.Property("CreatedAt") .ValueGeneratedOnAdd() .HasColumnType("timestamp with time zone") @@ -609,6 +752,10 @@ namespace PostFundManagement.Infrastructure.Database.Migrations b.Property("ProjectId") .HasColumnType("bigint"); + b.Property("Resolution") + .IsRequired() + .HasColumnType("text"); + b.Property("ResolvedAt") .HasColumnType("timestamp with time zone"); @@ -624,6 +771,8 @@ namespace PostFundManagement.Infrastructure.Database.Migrations b.HasKey("Id"); + b.HasIndex("AssignedTo"); + b.HasIndex("CreatedBy"); b.HasIndex("ProjectId"); @@ -655,6 +804,11 @@ namespace PostFundManagement.Infrastructure.Database.Migrations .HasMaxLength(256) .HasColumnType("character varying(256)"); + b.Property("Priority") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + b.Property("ProjectId") .HasColumnType("bigint"); @@ -680,6 +834,67 @@ namespace PostFundManagement.Infrastructure.Database.Migrations b.ToTable("Milestones", (string)null); }); + modelBuilder.Entity("PostFundManagement.Domain.Entities.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Destination") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Error") + .HasColumnType("text"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)"); + + b.Property("OrganisationId") + .HasColumnType("bigint"); + + b.Property("Platform") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("Recipient") + .HasColumnType("uuid"); + + b.Property("SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("1"); + + b.Property("Subject") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("OrganisationId"); + + b.HasIndex("Recipient"); + + b.ToTable("Notifications", (string)null); + }); + modelBuilder.Entity("PostFundManagement.Domain.Entities.Organisation", b => { b.Property("Id") @@ -819,9 +1034,6 @@ namespace PostFundManagement.Infrastructure.Database.Migrations b.Property("CreatedBy") .HasColumnType("uuid"); - b.Property("InstrumentId") - .HasColumnType("bigint"); - b.Property("Name") .IsRequired() .HasMaxLength(256) @@ -848,8 +1060,6 @@ namespace PostFundManagement.Infrastructure.Database.Migrations b.HasIndex("CreatedBy"); - b.HasIndex("InstrumentId"); - b.HasIndex("OwnedBy"); b.HasIndex("PortfolioId"); @@ -889,6 +1099,16 @@ namespace PostFundManagement.Infrastructure.Database.Migrations b.Property("ProgrammeId") .HasColumnType("bigint"); + b.Property("ProjectType") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("10"); + + b.Property("Sector") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("11"); + b.Property("StartedAt") .HasColumnType("timestamp with time zone"); @@ -1081,6 +1301,47 @@ namespace PostFundManagement.Infrastructure.Database.Migrations b.ToTable("Users", (string)null); }); + modelBuilder.Entity("PostFundManagement.Domain.Entities.Activity", b => + { + b.HasOne("PostFundManagement.Domain.Entities.User", "Approver") + .WithMany() + .HasForeignKey("ApprovedBy") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Milestone", "Milestone") + .WithMany() + .HasForeignKey("MilestoneId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "Updator") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Approver"); + + b.Navigation("Creator"); + + b.Navigation("Milestone"); + + b.Navigation("Project"); + + b.Navigation("Updator"); + }); + modelBuilder.Entity("PostFundManagement.Domain.Entities.AuditLog", b => { b.HasOne("PostFundManagement.Domain.Entities.User", "Performer") @@ -1299,6 +1560,12 @@ namespace PostFundManagement.Infrastructure.Database.Migrations modelBuilder.Entity("PostFundManagement.Domain.Entities.Evidence", b => { + b.HasOne("PostFundManagement.Domain.Entities.Activity", "Activity") + .WithMany("Evidences") + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") .WithMany() .HasForeignKey("CreatedBy") @@ -1308,13 +1575,14 @@ namespace PostFundManagement.Infrastructure.Database.Migrations b.HasOne("PostFundManagement.Domain.Entities.Indicator", "Indicator") .WithMany() .HasForeignKey("IndicatorId") - .OnDelete(DeleteBehavior.Cascade) + .OnDelete(DeleteBehavior.Restrict) .IsRequired(); b.HasOne("PostFundManagement.Domain.Entities.Milestone", "Milestone") .WithMany() .HasForeignKey("MilestoneId") - .OnDelete(DeleteBehavior.Restrict); + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); b.HasOne("PostFundManagement.Domain.Entities.Project", "Project") .WithMany() @@ -1327,6 +1595,8 @@ namespace PostFundManagement.Infrastructure.Database.Migrations .HasForeignKey("UpdatedBy") .OnDelete(DeleteBehavior.NoAction); + b.Navigation("Activity"); + b.Navigation("Creator"); b.Navigation("Indicator"); @@ -1365,11 +1635,68 @@ namespace PostFundManagement.Infrastructure.Database.Migrations .OnDelete(DeleteBehavior.NoAction) .IsRequired(); + b.HasOne("PostFundManagement.Domain.Entities.Programme", "Programme") + .WithMany("Instruments") + .HasForeignKey("ProgrammeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + b.Navigation("Creator"); + + b.Navigation("Programme"); + }); + + modelBuilder.Entity("PostFundManagement.Domain.Entities.Invite", b => + { + b.HasOne("PostFundManagement.Domain.Entities.Award", "Award") + .WithMany() + .HasForeignKey("AwardId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Contract", "Contract") + .WithMany() + .HasForeignKey("ContractId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Organisation", "InvitedOrganisation") + .WithMany() + .HasForeignKey("InvitedOrganisationId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.Organisation", "Organisation") + .WithMany() + .HasForeignKey("OrganisationId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "RecipientUser") + .WithMany() + .HasForeignKey("Recipient") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Award"); + + b.Navigation("Contract"); + + b.Navigation("InvitedOrganisation"); + + b.Navigation("Organisation"); + + b.Navigation("RecipientUser"); }); modelBuilder.Entity("PostFundManagement.Domain.Entities.Issue", b => { + b.HasOne("PostFundManagement.Domain.Entities.User", "Assignee") + .WithMany() + .HasForeignKey("AssignedTo") + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(); + b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") .WithMany() .HasForeignKey("CreatedBy") @@ -1382,6 +1709,8 @@ namespace PostFundManagement.Infrastructure.Database.Migrations .OnDelete(DeleteBehavior.Restrict) .IsRequired(); + b.Navigation("Assignee"); + b.Navigation("Creator"); b.Navigation("Project"); @@ -1413,6 +1742,25 @@ namespace PostFundManagement.Infrastructure.Database.Migrations b.Navigation("Updator"); }); + modelBuilder.Entity("PostFundManagement.Domain.Entities.Notification", b => + { + b.HasOne("PostFundManagement.Domain.Entities.Organisation", "Organisation") + .WithMany() + .HasForeignKey("OrganisationId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("PostFundManagement.Domain.Entities.User", "RecipientUser") + .WithMany() + .HasForeignKey("Recipient") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Organisation"); + + b.Navigation("RecipientUser"); + }); + modelBuilder.Entity("PostFundManagement.Domain.Entities.Organisation", b => { b.HasOne("PostFundManagement.Domain.Entities.User", "Creator") @@ -1470,12 +1818,6 @@ namespace PostFundManagement.Infrastructure.Database.Migrations .OnDelete(DeleteBehavior.NoAction) .IsRequired(); - b.HasOne("PostFundManagement.Domain.Entities.Instrument", "Instrument") - .WithMany("Programmes") - .HasForeignKey("InstrumentId") - .OnDelete(DeleteBehavior.NoAction) - .IsRequired(); - b.HasOne("PostFundManagement.Domain.Entities.User", "Owner") .WithMany() .HasForeignKey("OwnedBy") @@ -1490,8 +1832,6 @@ namespace PostFundManagement.Infrastructure.Database.Migrations b.Navigation("Creator"); - b.Navigation("Instrument"); - b.Navigation("Owner"); b.Navigation("Portfolio"); @@ -1508,7 +1848,7 @@ namespace PostFundManagement.Infrastructure.Database.Migrations b.HasOne("PostFundManagement.Domain.Entities.Programme", "Programme") .WithMany("Projects") .HasForeignKey("ProgrammeId") - .OnDelete(DeleteBehavior.NoAction) + .OnDelete(DeleteBehavior.Restrict) .IsRequired(); b.HasOne("PostFundManagement.Domain.Entities.User", "Updator") @@ -1587,16 +1927,16 @@ namespace PostFundManagement.Infrastructure.Database.Migrations b.Navigation("Project"); }); + modelBuilder.Entity("PostFundManagement.Domain.Entities.Activity", b => + { + b.Navigation("Evidences"); + }); + modelBuilder.Entity("PostFundManagement.Domain.Entities.Award", b => { b.Navigation("Contract"); }); - modelBuilder.Entity("PostFundManagement.Domain.Entities.Instrument", b => - { - b.Navigation("Programmes"); - }); - modelBuilder.Entity("PostFundManagement.Domain.Entities.Portfolio", b => { b.Navigation("Programmes"); @@ -1606,6 +1946,8 @@ namespace PostFundManagement.Infrastructure.Database.Migrations { b.Navigation("Awards"); + b.Navigation("Instruments"); + b.Navigation("Projects"); b.Navigation("Rules"); diff --git a/pfm.dbml b/pfm.dbml deleted file mode 100644 index 7df0882..0000000 --- a/pfm.dbml +++ /dev/null @@ -1,349 +0,0 @@ -Table "AuditLogs" { - "Id" int8 [not null] - "EntityName" varchar(128) [not null] - "EntityId" int8 [not null] - "Action" varchar(64) [not null] - "Changes" jsonb - "PerformedBy" uuid [not null] - "Timestamp" timestamptz [not null] -} - -Table "Awards" { - "Id" int8 [not null] - "OrganisationId" int8 [not null] - "ProgrammeId" int8 [not null] - "ProjectId" int8 - "CreatedBy" uuid [not null] - "UpdatedBy" uuid - "ApprovedBy" uuid - "CreatedAt" timestamptz [not null] - "UpdatedAt" timestamptz - "Status" int4 [not null] - "Amount" numeric(18,2) [not null] -} - -Table "Beneficiaries" { - "Id" int8 [not null] - "AwardId" int8 [not null] - "CreatedBy" uuid [not null] - "CreatedAt" timestamptz [not null] - "Name" varchar(256) [not null] - "Category" varchar(128) [not null] - "TargetCount" int4 [not null] - "ReachedCount" int4 [not null] - "Location" varchar(256) [not null] -} - -Table "ChangeRequests" { - "Id" int8 [not null] - "ProjectId" int8 [not null] - "Title" varchar(256) [not null] - "Justification" text [not null] - "RevisedBudget" numeric(18,2) - "RevisedEndDate" timestamptz - "Status" int4 [not null] - "CreatedBy" uuid [not null] - "ApprovedBy" uuid - "CreatedAt" timestamptz [not null] - "UpdatedAt" timestamptz -} - -Table "ComplianceItems" { - "Id" int8 [not null] - "ProjectId" int8 [not null] - "Title" varchar(256) [not null] - "Requirements" text [not null] - "Status" int4 [not null] - "CreatedBy" uuid [not null] - "VerifiedBy" uuid - "CreatedAt" timestamptz [not null] - "UpdatedBy" uuid -} - -Table "Contracts" { - "Id" int8 [not null] - "AwardId" int8 [not null] - "ExternalSignatureId" varchar(256) - "SignedDocumentUrl" varchar(2048) - "EffectiveAt" timestamptz - "ExpiresAt" timestamptz - "TotalValue" numeric(18,2) [not null] - "Status" int4 [not null] - "CreatedBy" uuid [not null] - "CreatedAt" timestamptz [not null] -} - -Table "Disbursements" { - "Id" int8 [not null] - "ProjectId" int8 [not null] - "CreatedBy" uuid [not null] - "ApprovedBy" uuid - "CreatedOn" timestamptz [not null] - "UpdatedBy" uuid - "Amount" numeric(18,2) [not null] -} - -Table "Evidences" { - "Id" int8 [not null] - "ProjectId" int8 [not null] - "MilestoneId" int8 - "IndicatorId" int8 - "CreatedBy" uuid [not null] - "UpdatedBy" uuid - "CreatedAt" timestamptz [not null] - "UpdatedAt" timestamptz - "Version" int4 [not null] - "DocumentUrl" text [not null] - "Status" int4 [not null] -} - -Table "Indicators" { - "Id" int8 [not null] - "ProjectId" int8 [not null] - "CreatedBy" uuid [not null] - "CreatedAt" timestamptz [not null] - "Name" varchar(256) [not null] - "UnitOfMeasure" varchar(64) [not null] - "BaselineAmount" numeric(18,2) [not null] - "TargetAmount" numeric(18,2) [not null] - "ActualAmount" numeric(18,2) [not null] -} - -Table "Instruments" { - "Id" int8 [not null] - "Code" varchar(32) [not null] - "Name" varchar(256) [not null] - "Description" text - "Status" int4 [not null] - "CreatedBy" uuid [not null] - "CreatedAt" timestamptz [not null] -} - -Table "Issues" { - "Id" int8 [not null] - "ProjectId" int8 [not null] - "Title" varchar(256) [not null] - "Description" varchar(1024) [not null] - "Priority" int4 [not null] - "Status" int4 [not null] - "CreatedBy" uuid [not null] - "CreatedAt" timestamptz [not null] - "ResolvedAt" timestamptz -} - -Table "Milestones" { - "Id" int8 [not null] - "ProjectId" int8 [not null] - "CreatedBy" uuid [not null] - "UpdatedBy" uuid - "CreatedAt" timestamptz [not null] - "UpdatedAt" timestamptz - "DueDate" timestamptz [not null] - "Name" varchar(256) [not null] - "Status" int4 [not null] -} - -Table "Organisations" { - "Id" int8 [not null] - "CreatedBy" uuid [not null] - "CreatedAt" timestamptz [not null] - "RegistrationNo" varchar(128) [not null] - "Name" varchar(256) [not null] - "Email" varchar(256) [not null] - "Type" int4 [not null] - "Status" int4 [not null] -} - -Table "Outcomes" { - "Id" int8 [not null] - "BeneficiaryId" int8 [not null] - "CreatedBy" uuid [not null] - "CreatedAt" timestamptz [not null] - "Name" varchar(256) [not null] - "Description" text [not null] -} - -Table "Portfolios" { - "Id" int8 [not null] - "CreatedBy" uuid [not null] - "OwnedBy" uuid - "CreatedAt" timestamptz [not null] - "Name" varchar(256) [not null] - "Description" varchar(1024) -} - -Table "Programmes" { - "Id" int8 [not null] - "PortfolioId" int8 [not null] - "InstrumentId" int8 [not null] - "OwnedBy" uuid [not null] - "CreatedBy" uuid [not null] - "UpdatedBy" uuid - "CreatedAt" timestamptz [not null] - "UpdatedAt" timestamptz - "Name" varchar(256) [not null] - "Status" int4 [not null] -} - -Table "Projects" { - "Id" int8 [not null] - "ProgrammeId" int8 [not null] - "CreatedBy" uuid [not null] - "UpdatedBy" uuid - "CreatedAt" timestamptz [not null] - "UpdatedAt" timestamptz - "Name" varchar(256) [not null] - "Description" varchar(1024) - "Status" int4 [not null] -} - -Table "Risks" { - "Id" int8 [not null] - "ProjectId" int8 [not null] - "CreatedBy" uuid [not null] - "CreatedAt" timestamptz [not null] - "Likelihood" int4 [not null] - "Impact" int4 [not null] - "Name" varchar(256) [not null] - "Description" varchar(1024) [not null] -} - -Table "Rules" { - "Id" int8 [not null] - "ProgrammeId" int8 [not null] - "CreatedBy" uuid [not null] - "ApprovedBy" uuid - "CreatedAt" timestamptz [not null] - "UpdatedBy" uuid - "Name" varchar(256) [not null] - "Notes" text [not null] - "Status" int4 [not null] -} - -Table "SiteVisits" { - "Id" int8 [not null] - "ProjectId" int8 [not null] - "VisitedAt" timestamptz [not null] - "InspectorName" varchar(256) [not null] - "Findings" text [not null] - "Status" int4 [not null] - "CreatedBy" uuid [not null] - "CreatedAt" timestamptz [not null] -} - -Table "Users" { - "Id" uuid [not null] - "Firstnames" text [not null] - "Surname" text [not null] - "Status" int4 [not null] -} - -Ref "FK_AuditLogs_Users_PerformedBy":"Users"."Id" < "AuditLogs"."PerformedBy" [delete: restrict] - -Ref "FK_Awards_Organisations_OrganisationId":"Organisations"."Id" < "Awards"."OrganisationId" [delete: restrict] - -Ref "FK_Awards_Programmes_ProgrammeId":"Programmes"."Id" < "Awards"."ProgrammeId" [delete: restrict] - -Ref "FK_Awards_Projects_ProjectId":"Projects"."Id" < "Awards"."ProjectId" [delete: set null] - -Ref "FK_Awards_Users_ApprovedBy":"Users"."Id" < "Awards"."ApprovedBy" - -Ref "FK_Awards_Users_CreatedBy":"Users"."Id" < "Awards"."CreatedBy" - -Ref "FK_Awards_Users_UpdatedBy":"Users"."Id" < "Awards"."UpdatedBy" - -Ref "FK_Beneficiaries_Awards_AwardId":"Awards"."Id" < "Beneficiaries"."AwardId" [delete: restrict] - -Ref "FK_Beneficiaries_Users_CreatedBy":"Users"."Id" < "Beneficiaries"."CreatedBy" - -Ref "FK_ChangeRequests_Projects_ProjectId":"Projects"."Id" < "ChangeRequests"."ProjectId" [delete: restrict] - -Ref "FK_ChangeRequests_Users_ApprovedBy":"Users"."Id" < "ChangeRequests"."ApprovedBy" - -Ref "FK_ChangeRequests_Users_CreatedBy":"Users"."Id" < "ChangeRequests"."CreatedBy" - -Ref "FK_ComplianceItems_Projects_ProjectId":"Projects"."Id" < "ComplianceItems"."ProjectId" [delete: restrict] - -Ref "FK_ComplianceItems_Users_CreatedBy":"Users"."Id" < "ComplianceItems"."CreatedBy" - -Ref "FK_ComplianceItems_Users_VerifiedBy":"Users"."Id" < "ComplianceItems"."VerifiedBy" - -Ref "FK_Contracts_Awards_AwardId":"Awards"."Id" < "Contracts"."AwardId" [delete: restrict] - -Ref "FK_Contracts_Users_CreatedBy":"Users"."Id" < "Contracts"."CreatedBy" - -Ref "FK_Disbursements_Projects_ProjectId":"Projects"."Id" < "Disbursements"."ProjectId" [delete: restrict] - -Ref "FK_Disbursements_Users_ApprovedBy":"Users"."Id" < "Disbursements"."ApprovedBy" - -Ref "FK_Disbursements_Users_CreatedBy":"Users"."Id" < "Disbursements"."CreatedBy" - -Ref "FK_Disbursements_Users_UpdatedBy":"Users"."Id" < "Disbursements"."UpdatedBy" - -Ref "FK_Evidences_Indicators_IndicatorId":"Indicators"."Id" < "Evidences"."IndicatorId" - -Ref "FK_Evidences_Milestones_MilestoneId":"Milestones"."Id" < "Evidences"."MilestoneId" - -Ref "FK_Evidences_Projects_ProjectId":"Projects"."Id" < "Evidences"."ProjectId" [delete: restrict] - -Ref "FK_Evidences_Users_CreatedBy":"Users"."Id" < "Evidences"."CreatedBy" - -Ref "FK_Evidences_Users_UpdatedBy":"Users"."Id" < "Evidences"."UpdatedBy" - -Ref "FK_Indicators_Projects_ProjectId":"Projects"."Id" < "Indicators"."ProjectId" [delete: restrict] - -Ref "FK_Indicators_Users_CreatedBy":"Users"."Id" < "Indicators"."CreatedBy" - -Ref "FK_Instruments_Users_CreatedBy":"Users"."Id" < "Instruments"."CreatedBy" - -Ref "FK_Issues_Projects_ProjectId":"Projects"."Id" < "Issues"."ProjectId" [delete: restrict] - -Ref "FK_Issues_Users_CreatedBy":"Users"."Id" < "Issues"."CreatedBy" - -Ref "FK_Milestones_Projects_ProjectId":"Projects"."Id" < "Milestones"."ProjectId" [delete: restrict] - -Ref "FK_Milestones_Users_CreatedBy":"Users"."Id" < "Milestones"."CreatedBy" - -Ref "FK_Milestones_Users_UpdatedBy":"Users"."Id" < "Milestones"."UpdatedBy" - -Ref "FK_Organisations_Users_CreatedBy":"Users"."Id" < "Organisations"."CreatedBy" - -Ref "FK_Outcomes_Beneficiaries_BeneficiaryId":"Beneficiaries"."Id" < "Outcomes"."BeneficiaryId" [delete: restrict] - -Ref "FK_Outcomes_Users_CreatedBy":"Users"."Id" < "Outcomes"."CreatedBy" - -Ref "FK_Portfolios_Users_CreatedBy":"Users"."Id" < "Portfolios"."CreatedBy" - -Ref "FK_Portfolios_Users_OwnedBy":"Users"."Id" < "Portfolios"."OwnedBy" - -Ref "FK_Programmes_Instruments_InstrumentId":"Instruments"."Id" < "Programmes"."InstrumentId" [delete: restrict] - -Ref "FK_Programmes_Portfolios_PortfolioId":"Portfolios"."Id" < "Programmes"."PortfolioId" [delete: restrict] - -Ref "FK_Programmes_Users_CreatedBy":"Users"."Id" < "Programmes"."CreatedBy" - -Ref "FK_Programmes_Users_OwnedBy":"Users"."Id" < "Programmes"."OwnedBy" [delete: restrict] - -Ref "FK_Programmes_Users_UpdatedBy":"Users"."Id" < "Programmes"."UpdatedBy" - -Ref "FK_Projects_Programmes_ProgrammeId":"Programmes"."Id" < "Projects"."ProgrammeId" [delete: restrict] - -Ref "FK_Projects_Users_CreatedBy":"Users"."Id" < "Projects"."CreatedBy" - -Ref "FK_Projects_Users_UpdatedBy":"Users"."Id" < "Projects"."UpdatedBy" - -Ref "FK_Risks_Projects_ProjectId":"Projects"."Id" < "Risks"."ProjectId" [delete: restrict] - -Ref "FK_Risks_Users_CreatedBy":"Users"."Id" < "Risks"."CreatedBy" - -Ref "FK_Rules_Programmes_ProgrammeId":"Programmes"."Id" < "Rules"."ProgrammeId" [delete: restrict] - -Ref "FK_Rules_Users_ApprovedBy":"Users"."Id" < "Rules"."ApprovedBy" - -Ref "FK_Rules_Users_CreatedBy":"Users"."Id" < "Rules"."CreatedBy" - -Ref "FK_Rules_Users_UpdatedBy":"Users"."Id" < "Rules"."UpdatedBy" - -Ref "FK_SiteVisits_Projects_ProjectId":"Projects"."Id" < "SiteVisits"."ProjectId" [delete: restrict] - -Ref "FK_SiteVisits_Users_CreatedBy":"Users"."Id" < "SiteVisits"."CreatedBy"