diff --git a/backend/api/Controllers/Models/MissionTaskResponse.cs b/backend/api/Controllers/Models/MissionTaskResponse.cs index f07da6eeb..77f9beb86 100644 --- a/backend/api/Controllers/Models/MissionTaskResponse.cs +++ b/backend/api/Controllers/Models/MissionTaskResponse.cs @@ -19,7 +19,7 @@ public class MissionTaskResponse public bool IsCompleted { get; set; } - public IList? AnalysisTypes { get; set; } + public IList AnalysisTypes { get; set; } public DateTime? StartTime { get; set; } diff --git a/backend/api/Database/Models/MissionTask.cs b/backend/api/Database/Models/MissionTask.cs index 13038167e..e12b7cf18 100644 --- a/backend/api/Database/Models/MissionTask.cs +++ b/backend/api/Database/Models/MissionTask.cs @@ -43,7 +43,7 @@ public MissionTask(MissionTask copy) [Required] public Pose RobotPose { get; set; } - public IList? AnalysisTypes { get; set; } = []; + public IList AnalysisTypes { get; set; } = []; private TaskStatus _status; diff --git a/backend/api/Migrations/20260819121426_MakeAnalysisTypeNonNullable.Designer.cs b/backend/api/Migrations/20260819121426_MakeAnalysisTypeNonNullable.Designer.cs new file mode 100644 index 000000000..e7749da90 --- /dev/null +++ b/backend/api/Migrations/20260819121426_MakeAnalysisTypeNonNullable.Designer.cs @@ -0,0 +1,1069 @@ +// +using System; +using Api.Database.Context; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Api.Migrations +{ + [DbContext(typeof(FlotillaDbContext))] + [Migration("20260819121426_MakeAnalysisTypeNonNullable")] + partial class MakeAnalysisTypeNonNullable + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Api.Database.Models.AccessRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("AccessLevel") + .IsRequired() + .HasColumnType("text"); + + b.Property("InstallationId") + .HasColumnType("text"); + + b.Property("RoleName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("InstallationId"); + + b.ToTable("AccessRoles"); + }); + + modelBuilder.Entity("Api.Database.Models.AutoScheduleFrequency", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("AutoScheduledJobs") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("AutoScheduleFrequency"); + }); + + modelBuilder.Entity("Api.Database.Models.ExclusionArea", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("InstallationId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("PlantId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("InstallationId"); + + b.HasIndex("PlantId"); + + b.ToTable("ExclusionAreas"); + }); + + modelBuilder.Entity("Api.Database.Models.InspectionArea", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("InstallationId") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeprecated") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("PlantId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("InstallationId"); + + b.HasIndex("PlantId"); + + b.ToTable("InspectionAreas"); + }); + + modelBuilder.Entity("Api.Database.Models.Installation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("InstallationCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.HasKey("Id"); + + b.HasIndex("InstallationCode") + .IsUnique(); + + b.ToTable("Installations"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("AutoScheduleFrequencyId") + .HasColumnType("text"); + + b.Property("Comment") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("InspectionAreaId") + .IsRequired() + .HasColumnType("text"); + + b.Property("InstallationCode") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeprecated") + .HasColumnType("boolean"); + + b.Property("LastSuccessfulRunId") + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.HasKey("Id"); + + b.HasIndex("AutoScheduleFrequencyId"); + + b.HasIndex("InspectionAreaId"); + + b.HasIndex("LastSuccessfulRunId"); + + b.ToTable("MissionDefinitions"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionRun", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("Comment") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasMaxLength(450) + .HasColumnType("character varying(450)"); + + b.Property("EndTime") + .HasColumnType("timestamp with time zone"); + + b.Property("EstimatedTaskDuration") + .HasColumnType("bigint"); + + b.Property("InspectionAreaId") + .IsRequired() + .HasColumnType("text"); + + b.Property("InstallationCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("IsDeprecated") + .HasColumnType("boolean"); + + b.Property("MissionId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("RobotId") + .IsRequired() + .HasColumnType("text"); + + b.Property("StartTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("StatusReason") + .HasMaxLength(450) + .HasColumnType("character varying(450)"); + + b.HasKey("Id"); + + b.HasIndex("InspectionAreaId"); + + b.HasIndex("RobotId"); + + b.ToTable("MissionRuns"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.PrimitiveCollection("AnalysisTypes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("EndTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ErrorDescription") + .HasColumnType("text"); + + b.Property("MissionRunId") + .HasColumnType("text"); + + b.Property("SensorType") + .IsRequired() + .HasColumnType("text"); + + b.Property("StartTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("TagId") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("TaskOrder") + .HasColumnType("integer"); + + b.Property("VideoDuration") + .HasColumnType("real"); + + b.HasKey("Id"); + + b.HasIndex("MissionRunId"); + + b.ToTable("MissionTasks"); + }); + + modelBuilder.Entity("Api.Database.Models.Plant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("InstallationId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("PlantCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("Id"); + + b.HasIndex("InstallationId"); + + b.HasIndex("PlantCode") + .IsUnique(); + + b.ToTable("Plants"); + }); + + modelBuilder.Entity("Api.Database.Models.Robot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("AverageDurationPerTag") + .HasColumnType("real"); + + b.Property("CurrentInspectionAreaId") + .HasColumnType("text"); + + b.Property("CurrentInstallationId") + .IsRequired() + .HasColumnType("text"); + + b.Property("CurrentMissionId") + .HasColumnType("text"); + + b.Property("Deprecated") + .HasColumnType("boolean"); + + b.Property("Host") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("IsarId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Port") + .HasColumnType("integer"); + + b.PrimitiveCollection("RobotCapabilities") + .HasColumnType("text[]"); + + b.Property("SerialNumber") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("Type") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CurrentInstallationId"); + + b.ToTable("Robots"); + }); + + modelBuilder.Entity("Api.Database.Models.UserInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("Oid") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("UserInfos"); + }); + + modelBuilder.Entity("Api.Database.Models.AccessRole", b => + { + b.HasOne("Api.Database.Models.Installation", "Installation") + .WithMany() + .HasForeignKey("InstallationId"); + + b.Navigation("Installation"); + }); + + modelBuilder.Entity("Api.Database.Models.AutoScheduleFrequency", b => + { + b.OwnsMany("Api.Database.Models.TimeAndDay", "SchedulingTimesCETperWeek", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b1.Property("AutoScheduleFrequencyId") + .IsRequired() + .HasColumnType("text"); + + b1.Property("DayOfWeek") + .IsRequired() + .HasColumnType("text"); + + b1.Property("TimeOfDay") + .HasColumnType("time without time zone"); + + b1.HasKey("Id"); + + b1.HasIndex("AutoScheduleFrequencyId"); + + b1.ToTable("TimeAndDay"); + + b1.WithOwner() + .HasForeignKey("AutoScheduleFrequencyId"); + }); + + b.Navigation("SchedulingTimesCETperWeek"); + }); + + modelBuilder.Entity("Api.Database.Models.ExclusionArea", b => + { + b.HasOne("Api.Database.Models.Installation", "Installation") + .WithMany() + .HasForeignKey("InstallationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Api.Database.Models.Plant", "Plant") + .WithMany() + .HasForeignKey("PlantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("Api.Database.Models.AreaPolygon", "AreaPolygon", b1 => + { + b1.Property("ExclusionAreaId") + .HasColumnType("text"); + + b1.Property("Positions") + .IsRequired() + .HasColumnType("text") + .HasJsonPropertyName("positions"); + + b1.Property("ZMax") + .HasColumnType("double precision") + .HasJsonPropertyName("zmax"); + + b1.Property("ZMin") + .HasColumnType("double precision") + .HasJsonPropertyName("zmin"); + + b1.HasKey("ExclusionAreaId"); + + b1.ToTable("ExclusionAreas"); + + b1.WithOwner() + .HasForeignKey("ExclusionAreaId"); + }); + + b.Navigation("AreaPolygon") + .IsRequired(); + + b.Navigation("Installation"); + + b.Navigation("Plant"); + }); + + modelBuilder.Entity("Api.Database.Models.InspectionArea", b => + { + b.HasOne("Api.Database.Models.Installation", "Installation") + .WithMany() + .HasForeignKey("InstallationId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Api.Database.Models.Plant", "Plant") + .WithMany() + .HasForeignKey("PlantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.OwnsOne("Api.Database.Models.AreaPolygon", "AreaPolygon", b1 => + { + b1.Property("InspectionAreaId") + .HasColumnType("text"); + + b1.Property("Positions") + .IsRequired() + .HasColumnType("text") + .HasJsonPropertyName("positions"); + + b1.Property("ZMax") + .HasColumnType("double precision") + .HasJsonPropertyName("zmax"); + + b1.Property("ZMin") + .HasColumnType("double precision") + .HasJsonPropertyName("zmin"); + + b1.HasKey("InspectionAreaId"); + + b1.ToTable("InspectionAreas"); + + b1.WithOwner() + .HasForeignKey("InspectionAreaId"); + }); + + b.Navigation("AreaPolygon"); + + b.Navigation("Installation"); + + b.Navigation("Plant"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionDefinition", b => + { + b.HasOne("Api.Database.Models.AutoScheduleFrequency", "AutoScheduleFrequency") + .WithMany() + .HasForeignKey("AutoScheduleFrequencyId"); + + b.HasOne("Api.Database.Models.InspectionArea", "InspectionArea") + .WithMany() + .HasForeignKey("InspectionAreaId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Api.Database.Models.MissionRun", "LastSuccessfulRun") + .WithMany() + .HasForeignKey("LastSuccessfulRunId"); + + b.OwnsMany("Api.Database.Models.TaskDefinition", "Tasks", b1 => + { + b1.Property("MissionDefinitionId") + .HasColumnType("text"); + + b1.Property("Index") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b1.Property("Index")); + + b1.PrimitiveCollection("AnalysisTypes") + .IsRequired() + .HasColumnType("text[]"); + + b1.Property("Description") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b1.Property("SensorType") + .IsRequired() + .HasColumnType("text"); + + b1.Property("TagId") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b1.Property("VideoDuration") + .HasColumnType("real"); + + b1.HasKey("MissionDefinitionId", "Index"); + + b1.ToTable("TaskDefinition"); + + b1.WithOwner() + .HasForeignKey("MissionDefinitionId"); + + b1.OwnsOne("Api.Database.Models.AcousticInspectionMetadata", "AcousticInspectionMetadata", b2 => + { + b2.Property("TaskDefinitionMissionDefinitionId") + .HasColumnType("text"); + + b2.Property("TaskDefinitionIndex") + .HasColumnType("integer"); + + b2.Property("DetectionType") + .IsRequired() + .HasColumnType("text"); + + b2.Property("FrequencyFrom") + .HasColumnType("real"); + + b2.Property("FrequencyTo") + .HasColumnType("real"); + + b2.Property("SnrValueThreshold") + .HasColumnType("real"); + + b2.HasKey("TaskDefinitionMissionDefinitionId", "TaskDefinitionIndex"); + + b2.ToTable("TaskDefinition"); + + b2.WithOwner() + .HasForeignKey("TaskDefinitionMissionDefinitionId", "TaskDefinitionIndex"); + + b2.OwnsOne("Api.Database.Models.Roi", "Roi", b3 => + { + b3.Property("AcousticInspectionMetadataTaskDefinitionMissionDefinitionId") + .HasColumnType("text"); + + b3.Property("AcousticInspectionMetadataTaskDefinitionIndex") + .HasColumnType("integer"); + + b3.Property("Height") + .HasColumnType("integer"); + + b3.Property("Width") + .HasColumnType("integer"); + + b3.Property("X") + .HasColumnType("integer"); + + b3.Property("Y") + .HasColumnType("integer"); + + b3.HasKey("AcousticInspectionMetadataTaskDefinitionMissionDefinitionId", "AcousticInspectionMetadataTaskDefinitionIndex"); + + b3.ToTable("TaskDefinition"); + + b3.WithOwner() + .HasForeignKey("AcousticInspectionMetadataTaskDefinitionMissionDefinitionId", "AcousticInspectionMetadataTaskDefinitionIndex"); + }); + + b2.Navigation("Roi"); + }); + + b1.OwnsOne("Api.Database.Models.Pose", "RobotPose", b2 => + { + b2.Property("TaskDefinitionMissionDefinitionId") + .HasColumnType("text"); + + b2.Property("TaskDefinitionIndex") + .HasColumnType("integer"); + + b2.HasKey("TaskDefinitionMissionDefinitionId", "TaskDefinitionIndex"); + + b2.ToTable("TaskDefinition"); + + b2.WithOwner() + .HasForeignKey("TaskDefinitionMissionDefinitionId", "TaskDefinitionIndex"); + + b2.OwnsOne("Api.Database.Models.Orientation", "Orientation", b3 => + { + b3.Property("PoseTaskDefinitionMissionDefinitionId") + .HasColumnType("text"); + + b3.Property("PoseTaskDefinitionIndex") + .HasColumnType("integer"); + + b3.Property("W") + .HasColumnType("real"); + + b3.Property("X") + .HasColumnType("real"); + + b3.Property("Y") + .HasColumnType("real"); + + b3.Property("Z") + .HasColumnType("real"); + + b3.HasKey("PoseTaskDefinitionMissionDefinitionId", "PoseTaskDefinitionIndex"); + + b3.ToTable("TaskDefinition"); + + b3.WithOwner() + .HasForeignKey("PoseTaskDefinitionMissionDefinitionId", "PoseTaskDefinitionIndex"); + }); + + b2.OwnsOne("Api.Database.Models.Position", "Position", b3 => + { + b3.Property("PoseTaskDefinitionMissionDefinitionId") + .HasColumnType("text"); + + b3.Property("PoseTaskDefinitionIndex") + .HasColumnType("integer"); + + b3.Property("X") + .HasColumnType("real"); + + b3.Property("Y") + .HasColumnType("real"); + + b3.Property("Z") + .HasColumnType("real"); + + b3.HasKey("PoseTaskDefinitionMissionDefinitionId", "PoseTaskDefinitionIndex"); + + b3.ToTable("TaskDefinition"); + + b3.WithOwner() + .HasForeignKey("PoseTaskDefinitionMissionDefinitionId", "PoseTaskDefinitionIndex"); + }); + + b2.Navigation("Orientation") + .IsRequired(); + + b2.Navigation("Position") + .IsRequired(); + }); + + b1.OwnsOne("Api.Database.Models.Position", "TargetPosition", b2 => + { + b2.Property("TaskDefinitionMissionDefinitionId") + .HasColumnType("text"); + + b2.Property("TaskDefinitionIndex") + .HasColumnType("integer"); + + b2.Property("X") + .HasColumnType("real"); + + b2.Property("Y") + .HasColumnType("real"); + + b2.Property("Z") + .HasColumnType("real"); + + b2.HasKey("TaskDefinitionMissionDefinitionId", "TaskDefinitionIndex"); + + b2.ToTable("TaskDefinition"); + + b2.WithOwner() + .HasForeignKey("TaskDefinitionMissionDefinitionId", "TaskDefinitionIndex"); + }); + + b1.OwnsOne("Api.Services.Models.IsarZoomDescription", "ZoomDescription", b2 => + { + b2.Property("TaskDefinitionMissionDefinitionId") + .HasColumnType("text"); + + b2.Property("TaskDefinitionIndex") + .HasColumnType("integer"); + + b2.Property("ObjectHeight") + .HasColumnType("double precision") + .HasJsonPropertyName("objectHeight"); + + b2.Property("ObjectWidth") + .HasColumnType("double precision") + .HasJsonPropertyName("objectWidth"); + + b2.HasKey("TaskDefinitionMissionDefinitionId", "TaskDefinitionIndex"); + + b2.ToTable("TaskDefinition"); + + b2.WithOwner() + .HasForeignKey("TaskDefinitionMissionDefinitionId", "TaskDefinitionIndex"); + }); + + b1.Navigation("AcousticInspectionMetadata"); + + b1.Navigation("RobotPose") + .IsRequired(); + + b1.Navigation("TargetPosition") + .IsRequired(); + + b1.Navigation("ZoomDescription"); + }); + + b.Navigation("AutoScheduleFrequency"); + + b.Navigation("InspectionArea"); + + b.Navigation("LastSuccessfulRun"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionRun", b => + { + b.HasOne("Api.Database.Models.InspectionArea", "InspectionArea") + .WithMany() + .HasForeignKey("InspectionAreaId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Api.Database.Models.Robot", "Robot") + .WithMany() + .HasForeignKey("RobotId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("InspectionArea"); + + b.Navigation("Robot"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionTask", b => + { + b.HasOne("Api.Database.Models.MissionRun", null) + .WithMany("Tasks") + .HasForeignKey("MissionRunId"); + + b.OwnsOne("Api.Database.Models.AcousticInspectionMetadata", "AcousticInspectionMetadata", b1 => + { + b1.Property("MissionTaskId") + .HasColumnType("text"); + + b1.Property("DetectionType") + .IsRequired() + .HasColumnType("text"); + + b1.Property("FrequencyFrom") + .HasColumnType("real"); + + b1.Property("FrequencyTo") + .HasColumnType("real"); + + b1.Property("SnrValueThreshold") + .HasColumnType("real"); + + b1.HasKey("MissionTaskId"); + + b1.ToTable("MissionTasks"); + + b1.WithOwner() + .HasForeignKey("MissionTaskId"); + + b1.OwnsOne("Api.Database.Models.Roi", "Roi", b2 => + { + b2.Property("AcousticInspectionMetadataMissionTaskId") + .HasColumnType("text"); + + b2.Property("Height") + .HasColumnType("integer"); + + b2.Property("Width") + .HasColumnType("integer"); + + b2.Property("X") + .HasColumnType("integer"); + + b2.Property("Y") + .HasColumnType("integer"); + + b2.HasKey("AcousticInspectionMetadataMissionTaskId"); + + b2.ToTable("MissionTasks"); + + b2.WithOwner() + .HasForeignKey("AcousticInspectionMetadataMissionTaskId"); + }); + + b1.Navigation("Roi"); + }); + + b.OwnsOne("Api.Services.Models.IsarZoomDescription", "IsarZoomDescription", b1 => + { + b1.Property("MissionTaskId") + .HasColumnType("text"); + + b1.Property("ObjectHeight") + .HasColumnType("double precision") + .HasJsonPropertyName("objectHeight"); + + b1.Property("ObjectWidth") + .HasColumnType("double precision") + .HasJsonPropertyName("objectWidth"); + + b1.HasKey("MissionTaskId"); + + b1.ToTable("MissionTasks"); + + b1.WithOwner() + .HasForeignKey("MissionTaskId"); + }); + + b.OwnsOne("Api.Database.Models.Pose", "RobotPose", b1 => + { + b1.Property("MissionTaskId") + .HasColumnType("text"); + + b1.HasKey("MissionTaskId"); + + b1.ToTable("MissionTasks"); + + b1.WithOwner() + .HasForeignKey("MissionTaskId"); + + b1.OwnsOne("Api.Database.Models.Orientation", "Orientation", b2 => + { + b2.Property("PoseMissionTaskId") + .HasColumnType("text"); + + b2.Property("W") + .HasColumnType("real"); + + b2.Property("X") + .HasColumnType("real"); + + b2.Property("Y") + .HasColumnType("real"); + + b2.Property("Z") + .HasColumnType("real"); + + b2.HasKey("PoseMissionTaskId"); + + b2.ToTable("MissionTasks"); + + b2.WithOwner() + .HasForeignKey("PoseMissionTaskId"); + }); + + b1.OwnsOne("Api.Database.Models.Position", "Position", b2 => + { + b2.Property("PoseMissionTaskId") + .HasColumnType("text"); + + b2.Property("X") + .HasColumnType("real"); + + b2.Property("Y") + .HasColumnType("real"); + + b2.Property("Z") + .HasColumnType("real"); + + b2.HasKey("PoseMissionTaskId"); + + b2.ToTable("MissionTasks"); + + b2.WithOwner() + .HasForeignKey("PoseMissionTaskId"); + }); + + b1.Navigation("Orientation") + .IsRequired(); + + b1.Navigation("Position") + .IsRequired(); + }); + + b.OwnsOne("Api.Database.Models.Position", "TargetPosition", b1 => + { + b1.Property("MissionTaskId") + .HasColumnType("text"); + + b1.Property("X") + .HasColumnType("real"); + + b1.Property("Y") + .HasColumnType("real"); + + b1.Property("Z") + .HasColumnType("real"); + + b1.HasKey("MissionTaskId"); + + b1.ToTable("MissionTasks"); + + b1.WithOwner() + .HasForeignKey("MissionTaskId"); + }); + + b.Navigation("AcousticInspectionMetadata"); + + b.Navigation("IsarZoomDescription"); + + b.Navigation("RobotPose") + .IsRequired(); + + b.Navigation("TargetPosition") + .IsRequired(); + }); + + modelBuilder.Entity("Api.Database.Models.Plant", b => + { + b.HasOne("Api.Database.Models.Installation", "Installation") + .WithMany() + .HasForeignKey("InstallationId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Installation"); + }); + + modelBuilder.Entity("Api.Database.Models.Robot", b => + { + b.HasOne("Api.Database.Models.Installation", "CurrentInstallation") + .WithMany() + .HasForeignKey("CurrentInstallationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsMany("Api.Database.Models.DocumentInfo", "Documentation", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b1.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b1.Property("RobotId") + .IsRequired() + .HasColumnType("text"); + + b1.Property("Url") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b1.HasKey("Id"); + + b1.HasIndex("RobotId"); + + b1.ToTable("DocumentInfo"); + + b1.WithOwner() + .HasForeignKey("RobotId"); + }); + + b.Navigation("CurrentInstallation"); + + b.Navigation("Documentation"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionRun", b => + { + b.Navigation("Tasks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/backend/api/Migrations/20260819121426_MakeAnalysisTypeNonNullable.cs b/backend/api/Migrations/20260819121426_MakeAnalysisTypeNonNullable.cs new file mode 100644 index 000000000..acd933094 --- /dev/null +++ b/backend/api/Migrations/20260819121426_MakeAnalysisTypeNonNullable.cs @@ -0,0 +1,39 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Api.Migrations +{ + /// + public partial class MakeAnalysisTypeNonNullable : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql( + "UPDATE \"MissionTasks\" SET \"AnalysisTypes\" = '{}' WHERE \"AnalysisTypes\" IS NULL;"); + + migrationBuilder.AlterColumn( + name: "AnalysisTypes", + table: "MissionTasks", + type: "text[]", + nullable: false, + defaultValue: new string[0], + oldClrType: typeof(string[]), + oldType: "text[]", + oldNullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "AnalysisTypes", + table: "MissionTasks", + type: "text[]", + nullable: true, + oldClrType: typeof(string[]), + oldType: "text[]"); + } + } +} diff --git a/backend/api/Migrations/FlotillaDbContextModelSnapshot.cs b/backend/api/Migrations/FlotillaDbContextModelSnapshot.cs index 56453caf2..59335402f 100644 --- a/backend/api/Migrations/FlotillaDbContextModelSnapshot.cs +++ b/backend/api/Migrations/FlotillaDbContextModelSnapshot.cs @@ -260,6 +260,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("text"); b.PrimitiveCollection("AnalysisTypes") + .IsRequired() .HasColumnType("text[]"); b.Property("Description") diff --git a/backend/api/Services/Models/IsarMissionDefinition.cs b/backend/api/Services/Models/IsarMissionDefinition.cs index ac25ecd39..64c35e23b 100644 --- a/backend/api/Services/Models/IsarMissionDefinition.cs +++ b/backend/api/Services/Models/IsarMissionDefinition.cs @@ -126,7 +126,7 @@ public IsarInspectionDefinition(MissionTask missionTask) : null; } - private static List? ToSaraAnalysisKeys(IList? types) + private static List? ToSaraAnalysisKeys(IList types) { if (types is null || types.Count == 0) return null;