diff --git a/src/Geopilot.Api/Migrations/20250107090507_EnableOptionalDeliveryAttributes.Designer.cs b/src/Geopilot.Api/Migrations/20250107090507_EnableOptionalDeliveryAttributes.Designer.cs new file mode 100644 index 00000000..3cc9708b --- /dev/null +++ b/src/Geopilot.Api/Migrations/20250107090507_EnableOptionalDeliveryAttributes.Designer.cs @@ -0,0 +1,301 @@ +// +using System; +using Geopilot.Api; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NetTopologySuite.Geometries; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Geopilot.Api.Migrations +{ + [DbContext(typeof(Context))] + [Migration("20250107090507_EnableOptionalDeliveryAttributes")] + partial class EnableOptionalDeliveryAttributes + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Geopilot.Api.Models.Asset", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AssetType") + .IsRequired() + .HasColumnType("varchar(24)"); + + b.Property("Deleted") + .HasColumnType("boolean"); + + b.Property("DeliveryId") + .HasColumnType("integer"); + + b.Property("FileHash") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("OriginalFilename") + .IsRequired() + .HasColumnType("text"); + + b.Property("SanitizedFilename") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("DeliveryId"); + + b.ToTable("Assets"); + }); + + modelBuilder.Entity("Geopilot.Api.Models.Delivery", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Comment") + .HasColumnType("text"); + + b.Property("Date") + .HasColumnType("timestamp with time zone"); + + b.Property("DeclaringUserId") + .HasColumnType("integer"); + + b.Property("Deleted") + .HasColumnType("boolean"); + + b.Property("JobId") + .HasColumnType("uuid"); + + b.Property("MandateId") + .HasColumnType("integer"); + + b.Property("Partial") + .HasColumnType("boolean"); + + b.Property("PrecursorDeliveryId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("DeclaringUserId"); + + b.HasIndex("MandateId"); + + b.HasIndex("PrecursorDeliveryId"); + + b.ToTable("Deliveries"); + }); + + modelBuilder.Entity("Geopilot.Api.Models.Mandate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("EvaluateComment") + .IsRequired() + .HasColumnType("varchar(24)"); + + b.Property("EvaluatePartial") + .IsRequired() + .HasColumnType("varchar(24)"); + + b.Property("EvaluatePrecursorDelivery") + .IsRequired() + .HasColumnType("varchar(24)"); + + b.Property("FileTypes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("SpatialExtent") + .IsRequired() + .HasColumnType("geometry"); + + b.HasKey("Id"); + + b.ToTable("Mandates"); + }); + + modelBuilder.Entity("Geopilot.Api.Models.Organisation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Organisations"); + }); + + modelBuilder.Entity("Geopilot.Api.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AuthIdentifier") + .IsRequired() + .HasColumnType("text"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("FullName") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsAdmin") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("MandateOrganisation", b => + { + b.Property("MandatesId") + .HasColumnType("integer"); + + b.Property("OrganisationsId") + .HasColumnType("integer"); + + b.HasKey("MandatesId", "OrganisationsId"); + + b.HasIndex("OrganisationsId"); + + b.ToTable("MandateOrganisation"); + }); + + modelBuilder.Entity("OrganisationUser", b => + { + b.Property("OrganisationsId") + .HasColumnType("integer"); + + b.Property("UsersId") + .HasColumnType("integer"); + + b.HasKey("OrganisationsId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("OrganisationUser"); + }); + + modelBuilder.Entity("Geopilot.Api.Models.Asset", b => + { + b.HasOne("Geopilot.Api.Models.Delivery", "Delivery") + .WithMany("Assets") + .HasForeignKey("DeliveryId"); + + b.Navigation("Delivery"); + }); + + modelBuilder.Entity("Geopilot.Api.Models.Delivery", b => + { + b.HasOne("Geopilot.Api.Models.User", "DeclaringUser") + .WithMany("Deliveries") + .HasForeignKey("DeclaringUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Geopilot.Api.Models.Mandate", "Mandate") + .WithMany("Deliveries") + .HasForeignKey("MandateId"); + + b.HasOne("Geopilot.Api.Models.Delivery", "PrecursorDelivery") + .WithMany() + .HasForeignKey("PrecursorDeliveryId"); + + b.Navigation("DeclaringUser"); + + b.Navigation("Mandate"); + + b.Navigation("PrecursorDelivery"); + }); + + modelBuilder.Entity("MandateOrganisation", b => + { + b.HasOne("Geopilot.Api.Models.Mandate", null) + .WithMany() + .HasForeignKey("MandatesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Geopilot.Api.Models.Organisation", null) + .WithMany() + .HasForeignKey("OrganisationsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OrganisationUser", b => + { + b.HasOne("Geopilot.Api.Models.Organisation", null) + .WithMany() + .HasForeignKey("OrganisationsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Geopilot.Api.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Geopilot.Api.Models.Delivery", b => + { + b.Navigation("Assets"); + }); + + modelBuilder.Entity("Geopilot.Api.Models.Mandate", b => + { + b.Navigation("Deliveries"); + }); + + modelBuilder.Entity("Geopilot.Api.Models.User", b => + { + b.Navigation("Deliveries"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Geopilot.Api/Migrations/20250107090507_EnableOptionalDeliveryAttributes.cs b/src/Geopilot.Api/Migrations/20250107090507_EnableOptionalDeliveryAttributes.cs new file mode 100644 index 00000000..99d83b51 --- /dev/null +++ b/src/Geopilot.Api/Migrations/20250107090507_EnableOptionalDeliveryAttributes.cs @@ -0,0 +1,169 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Geopilot.Api.Migrations +{ + /// + public partial class EnableOptionalDeliveryAttributes : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Assets_Deliveries_DeliveryId", + table: "Assets"); + + migrationBuilder.DropForeignKey( + name: "FK_Deliveries_Mandates_MandateId", + table: "Deliveries"); + + migrationBuilder.AddColumn( + name: "EvaluateComment", + table: "Mandates", + type: "varchar(24)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "EvaluatePartial", + table: "Mandates", + type: "varchar(24)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "EvaluatePrecursorDelivery", + table: "Mandates", + type: "varchar(24)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AlterColumn( + name: "Partial", + table: "Deliveries", + type: "boolean", + nullable: true, + oldClrType: typeof(bool), + oldType: "boolean"); + + migrationBuilder.AlterColumn( + name: "MandateId", + table: "Deliveries", + type: "integer", + nullable: true, + oldClrType: typeof(int), + oldType: "integer"); + + migrationBuilder.AlterColumn( + name: "Comment", + table: "Deliveries", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "DeliveryId", + table: "Assets", + type: "integer", + nullable: true, + oldClrType: typeof(int), + oldType: "integer"); + + migrationBuilder.AddForeignKey( + name: "FK_Assets_Deliveries_DeliveryId", + table: "Assets", + column: "DeliveryId", + principalTable: "Deliveries", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Deliveries_Mandates_MandateId", + table: "Deliveries", + column: "MandateId", + principalTable: "Mandates", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Assets_Deliveries_DeliveryId", + table: "Assets"); + + migrationBuilder.DropForeignKey( + name: "FK_Deliveries_Mandates_MandateId", + table: "Deliveries"); + + migrationBuilder.DropColumn( + name: "EvaluateComment", + table: "Mandates"); + + migrationBuilder.DropColumn( + name: "EvaluatePartial", + table: "Mandates"); + + migrationBuilder.DropColumn( + name: "EvaluatePrecursorDelivery", + table: "Mandates"); + + migrationBuilder.AlterColumn( + name: "Partial", + table: "Deliveries", + type: "boolean", + nullable: false, + defaultValue: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "MandateId", + table: "Deliveries", + type: "integer", + nullable: false, + defaultValue: 0, + oldClrType: typeof(int), + oldType: "integer", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Comment", + table: "Deliveries", + type: "text", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "DeliveryId", + table: "Assets", + type: "integer", + nullable: false, + defaultValue: 0, + oldClrType: typeof(int), + oldType: "integer", + oldNullable: true); + + migrationBuilder.AddForeignKey( + name: "FK_Assets_Deliveries_DeliveryId", + table: "Assets", + column: "DeliveryId", + principalTable: "Deliveries", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Deliveries_Mandates_MandateId", + table: "Deliveries", + column: "MandateId", + principalTable: "Mandates", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/src/Geopilot.Api/Migrations/ContextModelSnapshot.cs b/src/Geopilot.Api/Migrations/ContextModelSnapshot.cs index b72df553..2d647220 100644 --- a/src/Geopilot.Api/Migrations/ContextModelSnapshot.cs +++ b/src/Geopilot.Api/Migrations/ContextModelSnapshot.cs @@ -18,7 +18,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "7.0.11") + .HasAnnotation("ProductVersion", "8.0.8") .HasAnnotation("Relational:MaxIdentifierLength", 63); NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis"); @@ -39,7 +39,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Deleted") .HasColumnType("boolean"); - b.Property("DeliveryId") + b.Property("DeliveryId") .HasColumnType("integer"); b.Property("FileHash") @@ -70,7 +70,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("Comment") - .IsRequired() .HasColumnType("text"); b.Property("Date") @@ -85,10 +84,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("JobId") .HasColumnType("uuid"); - b.Property("MandateId") + b.Property("MandateId") .HasColumnType("integer"); - b.Property("Partial") + b.Property("Partial") .HasColumnType("boolean"); b.Property("PrecursorDeliveryId") @@ -113,6 +112,18 @@ protected override void BuildModel(ModelBuilder modelBuilder) NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + b.Property("EvaluateComment") + .IsRequired() + .HasColumnType("varchar(24)"); + + b.Property("EvaluatePartial") + .IsRequired() + .HasColumnType("varchar(24)"); + + b.Property("EvaluatePrecursorDelivery") + .IsRequired() + .HasColumnType("varchar(24)"); + b.Property("FileTypes") .IsRequired() .HasColumnType("text[]"); @@ -209,9 +220,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.HasOne("Geopilot.Api.Models.Delivery", "Delivery") .WithMany("Assets") - .HasForeignKey("DeliveryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + .HasForeignKey("DeliveryId"); b.Navigation("Delivery"); }); @@ -226,9 +235,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("Geopilot.Api.Models.Mandate", "Mandate") .WithMany("Deliveries") - .HasForeignKey("MandateId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + .HasForeignKey("MandateId"); b.HasOne("Geopilot.Api.Models.Delivery", "PrecursorDelivery") .WithMany() diff --git a/src/Geopilot.Api/Models/Delivery.cs b/src/Geopilot.Api/Models/Delivery.cs index f53fb189..35629fe0 100644 --- a/src/Geopilot.Api/Models/Delivery.cs +++ b/src/Geopilot.Api/Models/Delivery.cs @@ -38,7 +38,7 @@ public class Delivery /// /// Indicate whether the delivery contains partial data. /// - public bool Partial { get; set; } + public bool? Partial { get; set; } /// /// The previous delivery on the same . @@ -48,7 +48,7 @@ public class Delivery /// /// Comment to describe the delivery. /// - public string Comment { get; set; } = string.Empty; + public string? Comment { get; set; } = string.Empty; /// /// The deletion status of the delivery. diff --git a/src/Geopilot.Api/Models/FieldEvaluationType.cs b/src/Geopilot.Api/Models/FieldEvaluationType.cs new file mode 100644 index 00000000..a2f17abf --- /dev/null +++ b/src/Geopilot.Api/Models/FieldEvaluationType.cs @@ -0,0 +1,23 @@ +namespace Geopilot.Api.Models +{ + /// + /// Defines how fileds have to be evaluated. + /// + public enum FieldEvaluationType + { + /// + /// Field must not contain any value. + /// + NotEvaluated, + + /// + /// Field may contain a value but must not. + /// + Optional, + + /// + /// Field must contan a value. + /// + Required, + } +} diff --git a/src/Geopilot.Api/Models/Mandate.cs b/src/Geopilot.Api/Models/Mandate.cs index 582dbfdf..7cb7e41b 100644 --- a/src/Geopilot.Api/Models/Mandate.cs +++ b/src/Geopilot.Api/Models/Mandate.cs @@ -1,4 +1,5 @@ -using NetTopologySuite.Geometries; +using Microsoft.VisualBasic.FileIO; +using NetTopologySuite.Geometries; using System.ComponentModel.DataAnnotations.Schema; using System.Text.Json.Serialization; @@ -40,6 +41,24 @@ public class Mandate [NotMapped] public List Coordinates { get; set; } = new List(); + /// + /// Defines how is evaluated. + /// + [Column(TypeName = "varchar(24)")] + public FieldEvaluationType EvaluatePrecursorDelivery { get; set; } + + /// + /// Defines how is evaluated. + /// + [Column(TypeName = "varchar(24)")] + public FieldEvaluationType EvaluatePartial { get; set; } + + /// + /// Defines how is evaluated. + /// + [Column(TypeName = "varchar(24)")] + public FieldEvaluationType EvaluateComment { get; set; } + /// /// Organisations allowed to deliver data fulfilling the mandate. ///