diff --git a/backend/api/Controllers/InspectionFindingsController.cs b/backend/api/Controllers/InspectionFindingsController.cs
index 59f88b4f2..76db364f2 100644
--- a/backend/api/Controllers/InspectionFindingsController.cs
+++ b/backend/api/Controllers/InspectionFindingsController.cs
@@ -27,15 +27,15 @@ IInspectionService inspectionService
///
///
///
- /* [HttpPost("add-findings")]
+ [HttpPost("add-findings")]
[Authorize(Roles = Role.Admin)]
- [ProducesResponseType(typeof(InspectionFindings), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(InspectionFinding), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status409Conflict)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
- public async Task> AddFindings([FromBody] InspectionFindingsQuery inspectionFinding)
+ public async Task> AddFindings([FromBody] InspectionFindingsQuery inspectionFinding)
{
_logger.LogInformation("Updating inspection findings for inspection with isarStepId '{Id}'", inspectionFinding.IsarStepId);
try
@@ -89,7 +89,7 @@ public async Task> GetInspections([FromRoute] string id
}
return NotFound("Could not find any inspection with the provided '{id}'");
}
-*/
+
}
diff --git a/backend/api/Database/Context/FlotillaDbContext.cs b/backend/api/Database/Context/FlotillaDbContext.cs
index 9e9cfd318..1de4f96ac 100644
--- a/backend/api/Database/Context/FlotillaDbContext.cs
+++ b/backend/api/Database/Context/FlotillaDbContext.cs
@@ -49,12 +49,12 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
}
);
});
- /*modelBuilder.Entity(inspectionEntity =>
+ modelBuilder.Entity(inspectionEntity =>
{
if (isSqlLite) { AddConverterForDateTimeOffsets(ref inspectionEntity); }
inspectionEntity.OwnsMany(i => i.InspectionFindings);
});
- */
+
modelBuilder.Entity()
.Property(m => m.InspectionFrequency)
.HasConversion(new TimeSpanToTicksConverter());
diff --git a/backend/api/Database/Models/Inspection.cs b/backend/api/Database/Models/Inspection.cs
index da2229618..ccaeacf67 100644
--- a/backend/api/Database/Models/Inspection.cs
+++ b/backend/api/Database/Models/Inspection.cs
@@ -94,7 +94,7 @@ or InspectionStatus.Successful
public DateTime? EndTime { get; private set; }
- //public List InspectionFindings { get; set; }
+ public List InspectionFindings { get; set; }
public void UpdateWithIsarInfo(IsarStep isarStep)
{
diff --git a/backend/api/Database/Models/InspectionFinding.cs b/backend/api/Database/Models/InspectionFinding.cs
new file mode 100644
index 000000000..d5fcbaa20
--- /dev/null
+++ b/backend/api/Database/Models/InspectionFinding.cs
@@ -0,0 +1,38 @@
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Api.Controllers.Models;
+#pragma warning disable CS8618
+namespace Api.Database.Models
+{
+ public class InspectionFinding
+ {
+ [Key]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public string Id { get; set; }
+
+ public DateTime InspectionDate { get; set; }
+
+ public string Area { get; set; }
+
+ public string IsarStepId { get; set; }
+
+ public string Findings { get; set; }
+
+ public InspectionFinding(InspectionFindingsQuery createInspectionFindingQuery)
+ {
+ InspectionDate = createInspectionFindingQuery.InspectionDate;
+ Area = createInspectionFindingQuery.Area;
+ IsarStepId = createInspectionFindingQuery.IsarStepId;
+ Findings = createInspectionFindingQuery.Findings;
+ }
+
+ public InspectionFinding()
+ {
+ InspectionDate = DateTime.UtcNow;
+ Area = "string";
+ IsarStepId = "string";
+ Findings = "string";
+ }
+ }
+
+}
diff --git a/backend/api/Migrations/20231115130240_AddInspectionFindingsTable.Designer.cs b/backend/api/Migrations/20231115130240_AddInspectionFindingsTable.Designer.cs
new file mode 100644
index 000000000..3ce6a9912
--- /dev/null
+++ b/backend/api/Migrations/20231115130240_AddInspectionFindingsTable.Designer.cs
@@ -0,0 +1,1311 @@
+//
+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("20231115130240_AddInspectionFindingsTable")]
+ partial class AddInspectionFindingsTable
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.11")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("Api.Database.Models.Area", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("text");
+
+ b.Property("DeckId")
+ .HasColumnType("text");
+
+ b.Property("DefaultLocalizationPoseId")
+ .HasColumnType("text");
+
+ b.Property("InstallationId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("PlantId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DeckId");
+
+ b.HasIndex("DefaultLocalizationPoseId");
+
+ b.HasIndex("InstallationId");
+
+ b.HasIndex("PlantId");
+
+ b.ToTable("Areas");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.Deck", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("text");
+
+ b.Property("DefaultLocalizationPoseId")
+ .HasColumnType("text");
+
+ b.Property("InstallationId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("PlantId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DefaultLocalizationPoseId");
+
+ b.HasIndex("InstallationId");
+
+ b.HasIndex("PlantId");
+
+ b.ToTable("Decks");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.DefaultLocalizationPose", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("DefaultLocalizationPoses");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.Inspection", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("text");
+
+ b.Property("AnalysisType")
+ .HasColumnType("text");
+
+ b.Property("EndTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("InspectionType")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("InspectionUrl")
+ .HasMaxLength(250)
+ .HasColumnType("character varying(250)");
+
+ b.Property("IsarStepId")
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("MissionTaskId")
+ .HasColumnType("text");
+
+ b.Property("StartTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("VideoDuration")
+ .HasColumnType("real");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MissionTaskId");
+
+ b.ToTable("Inspections");
+ });
+
+ 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("AreaId")
+ .HasColumnType("text");
+
+ b.Property("Comment")
+ .HasMaxLength(1000)
+ .HasColumnType("character varying(1000)");
+
+ b.Property("InspectionFrequency")
+ .HasColumnType("bigint");
+
+ 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.Property("SourceId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AreaId");
+
+ b.HasIndex("LastSuccessfulRunId");
+
+ b.HasIndex("SourceId");
+
+ b.ToTable("MissionDefinitions");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.MissionRun", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("text");
+
+ b.Property("AreaId")
+ .HasColumnType("text");
+
+ b.Property("Comment")
+ .HasMaxLength(1000)
+ .HasColumnType("character varying(1000)");
+
+ b.Property("Description")
+ .HasMaxLength(450)
+ .HasColumnType("character varying(450)");
+
+ b.Property("DesiredStartTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("EndTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("EstimatedDuration")
+ .HasColumnType("bigint");
+
+ b.Property("InstallationCode")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("IsarMissionId")
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("MissionId")
+ .HasColumnType("text");
+
+ b.Property("MissionRunPriority")
+ .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("AreaId");
+
+ b.HasIndex("RobotId");
+
+ b.ToTable("MissionRuns");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.MissionTask", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("text");
+
+ b.Property("Description")
+ .HasMaxLength(500)
+ .HasColumnType("character varying(500)");
+
+ b.Property("EchoPoseId")
+ .HasColumnType("integer");
+
+ b.Property("EchoTagLink")
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("EndTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("IsarTaskId")
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("MissionRunId")
+ .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.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("BatteryLevel")
+ .HasColumnType("real");
+
+ b.Property("CurrentAreaId")
+ .HasColumnType("text");
+
+ b.Property("CurrentInstallation")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("CurrentMissionId")
+ .HasColumnType("text");
+
+ b.Property("Enabled")
+ .HasColumnType("boolean");
+
+ b.Property("Host")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("IsarId")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("MissionQueueFrozen")
+ .HasColumnType("boolean");
+
+ b.Property("ModelId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("Port")
+ .HasColumnType("integer");
+
+ b.Property("PressureLevel")
+ .HasColumnType("real");
+
+ b.Property("SerialNumber")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CurrentAreaId");
+
+ b.HasIndex("ModelId");
+
+ b.ToTable("Robots");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.RobotBatteryTimeseries", b =>
+ {
+ b.Property("BatteryLevel")
+ .HasColumnType("real");
+
+ b.Property("MissionId")
+ .HasColumnType("text");
+
+ b.Property("RobotId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Time")
+ .HasColumnType("timestamp with time zone");
+
+ b.ToTable("RobotBatteryTimeseries");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.RobotModel", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("text");
+
+ b.Property("AverageDurationPerTag")
+ .HasColumnType("real");
+
+ b.Property("BatteryWarningThreshold")
+ .HasColumnType("real");
+
+ b.Property("LowerPressureWarningThreshold")
+ .HasColumnType("real");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("UpperPressureWarningThreshold")
+ .HasColumnType("real");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Type")
+ .IsUnique();
+
+ b.ToTable("RobotModels");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.RobotPoseTimeseries", b =>
+ {
+ b.Property("MissionId")
+ .HasColumnType("text");
+
+ b.Property("OrientationW")
+ .HasColumnType("real");
+
+ b.Property("OrientationX")
+ .HasColumnType("real");
+
+ b.Property("OrientationY")
+ .HasColumnType("real");
+
+ b.Property("OrientationZ")
+ .HasColumnType("real");
+
+ b.Property("PositionX")
+ .HasColumnType("real");
+
+ b.Property("PositionY")
+ .HasColumnType("real");
+
+ b.Property("PositionZ")
+ .HasColumnType("real");
+
+ b.Property("RobotId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Time")
+ .HasColumnType("timestamp with time zone");
+
+ b.ToTable("RobotPoseTimeseries");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.RobotPressureTimeseries", b =>
+ {
+ b.Property("MissionId")
+ .HasColumnType("text");
+
+ b.Property("Pressure")
+ .HasColumnType("real");
+
+ b.Property("RobotId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Time")
+ .HasColumnType("timestamp with time zone");
+
+ b.ToTable("RobotPressureTimeseries");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.SafePosition", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("text");
+
+ b.Property("AreaId")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AreaId");
+
+ b.ToTable("SafePositions");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.Source", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("text");
+
+ b.Property("SourceId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Sources");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.Area", b =>
+ {
+ b.HasOne("Api.Database.Models.Deck", "Deck")
+ .WithMany()
+ .HasForeignKey("DeckId")
+ .OnDelete(DeleteBehavior.Restrict);
+
+ b.HasOne("Api.Database.Models.DefaultLocalizationPose", "DefaultLocalizationPose")
+ .WithMany()
+ .HasForeignKey("DefaultLocalizationPoseId");
+
+ 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.MapMetadata", "MapMetadata", b1 =>
+ {
+ b1.Property("AreaId")
+ .HasColumnType("text");
+
+ b1.Property("MapName")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b1.HasKey("AreaId");
+
+ b1.ToTable("Areas");
+
+ b1.WithOwner()
+ .HasForeignKey("AreaId");
+
+ b1.OwnsOne("Api.Database.Models.Boundary", "Boundary", b2 =>
+ {
+ b2.Property("MapMetadataAreaId")
+ .HasColumnType("text");
+
+ b2.Property("X1")
+ .HasColumnType("double precision");
+
+ b2.Property("X2")
+ .HasColumnType("double precision");
+
+ b2.Property("Y1")
+ .HasColumnType("double precision");
+
+ b2.Property("Y2")
+ .HasColumnType("double precision");
+
+ b2.Property("Z1")
+ .HasColumnType("double precision");
+
+ b2.Property("Z2")
+ .HasColumnType("double precision");
+
+ b2.HasKey("MapMetadataAreaId");
+
+ b2.ToTable("Areas");
+
+ b2.WithOwner()
+ .HasForeignKey("MapMetadataAreaId");
+ });
+
+ b1.OwnsOne("Api.Database.Models.TransformationMatrices", "TransformationMatrices", b2 =>
+ {
+ b2.Property("MapMetadataAreaId")
+ .HasColumnType("text");
+
+ b2.Property("C1")
+ .HasColumnType("double precision");
+
+ b2.Property("C2")
+ .HasColumnType("double precision");
+
+ b2.Property("D1")
+ .HasColumnType("double precision");
+
+ b2.Property("D2")
+ .HasColumnType("double precision");
+
+ b2.HasKey("MapMetadataAreaId");
+
+ b2.ToTable("Areas");
+
+ b2.WithOwner()
+ .HasForeignKey("MapMetadataAreaId");
+ });
+
+ b1.Navigation("Boundary")
+ .IsRequired();
+
+ b1.Navigation("TransformationMatrices")
+ .IsRequired();
+ });
+
+ b.Navigation("Deck");
+
+ b.Navigation("DefaultLocalizationPose");
+
+ b.Navigation("Installation");
+
+ b.Navigation("MapMetadata")
+ .IsRequired();
+
+ b.Navigation("Plant");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.Deck", b =>
+ {
+ b.HasOne("Api.Database.Models.DefaultLocalizationPose", "DefaultLocalizationPose")
+ .WithMany()
+ .HasForeignKey("DefaultLocalizationPoseId");
+
+ 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.Navigation("DefaultLocalizationPose");
+
+ b.Navigation("Installation");
+
+ b.Navigation("Plant");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.DefaultLocalizationPose", b =>
+ {
+ b.OwnsOne("Api.Database.Models.Pose", "Pose", b1 =>
+ {
+ b1.Property("DefaultLocalizationPoseId")
+ .HasColumnType("text");
+
+ b1.HasKey("DefaultLocalizationPoseId");
+
+ b1.ToTable("DefaultLocalizationPoses");
+
+ b1.WithOwner()
+ .HasForeignKey("DefaultLocalizationPoseId");
+
+ b1.OwnsOne("Api.Database.Models.Orientation", "Orientation", b2 =>
+ {
+ b2.Property("PoseDefaultLocalizationPoseId")
+ .HasColumnType("text");
+
+ b2.Property("W")
+ .HasColumnType("real");
+
+ b2.Property("X")
+ .HasColumnType("real");
+
+ b2.Property("Y")
+ .HasColumnType("real");
+
+ b2.Property("Z")
+ .HasColumnType("real");
+
+ b2.HasKey("PoseDefaultLocalizationPoseId");
+
+ b2.ToTable("DefaultLocalizationPoses");
+
+ b2.WithOwner()
+ .HasForeignKey("PoseDefaultLocalizationPoseId");
+ });
+
+ b1.OwnsOne("Api.Database.Models.Position", "Position", b2 =>
+ {
+ b2.Property("PoseDefaultLocalizationPoseId")
+ .HasColumnType("text");
+
+ b2.Property("X")
+ .HasColumnType("real");
+
+ b2.Property("Y")
+ .HasColumnType("real");
+
+ b2.Property("Z")
+ .HasColumnType("real");
+
+ b2.HasKey("PoseDefaultLocalizationPoseId");
+
+ b2.ToTable("DefaultLocalizationPoses");
+
+ b2.WithOwner()
+ .HasForeignKey("PoseDefaultLocalizationPoseId");
+ });
+
+ b1.Navigation("Orientation")
+ .IsRequired();
+
+ b1.Navigation("Position")
+ .IsRequired();
+ });
+
+ b.Navigation("Pose")
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Api.Database.Models.Inspection", b =>
+ {
+ b.HasOne("Api.Database.Models.MissionTask", null)
+ .WithMany("Inspections")
+ .HasForeignKey("MissionTaskId");
+
+ b.OwnsOne("Api.Database.Models.Position", "InspectionTarget", b1 =>
+ {
+ b1.Property("InspectionId")
+ .HasColumnType("text");
+
+ b1.Property("X")
+ .HasColumnType("real");
+
+ b1.Property("Y")
+ .HasColumnType("real");
+
+ b1.Property("Z")
+ .HasColumnType("real");
+
+ b1.HasKey("InspectionId");
+
+ b1.ToTable("Inspections");
+
+ b1.WithOwner()
+ .HasForeignKey("InspectionId");
+ });
+
+ b.OwnsMany("Api.Database.Models.InspectionFinding", "InspectionFindings", b1 =>
+ {
+ b1.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("text");
+
+ b1.Property("Area")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b1.Property("Findings")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b1.Property("InspectionDate")
+ .HasColumnType("timestamp with time zone");
+
+ b1.Property("InspectionId")
+ .HasColumnType("text");
+
+ b1.Property("IsarStepId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b1.HasKey("Id");
+
+ b1.HasIndex("InspectionId");
+
+ b1.ToTable("InspectionFinding");
+
+ b1.WithOwner()
+ .HasForeignKey("InspectionId");
+ });
+
+ b.Navigation("InspectionFindings");
+
+ b.Navigation("InspectionTarget")
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Api.Database.Models.MissionDefinition", b =>
+ {
+ b.HasOne("Api.Database.Models.Area", "Area")
+ .WithMany()
+ .HasForeignKey("AreaId");
+
+ b.HasOne("Api.Database.Models.MissionRun", "LastSuccessfulRun")
+ .WithMany()
+ .HasForeignKey("LastSuccessfulRunId");
+
+ b.HasOne("Api.Database.Models.Source", "Source")
+ .WithMany()
+ .HasForeignKey("SourceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Area");
+
+ b.Navigation("LastSuccessfulRun");
+
+ b.Navigation("Source");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.MissionRun", b =>
+ {
+ b.HasOne("Api.Database.Models.Area", "Area")
+ .WithMany()
+ .HasForeignKey("AreaId");
+
+ b.HasOne("Api.Database.Models.Robot", "Robot")
+ .WithMany()
+ .HasForeignKey("RobotId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.OwnsOne("Api.Database.Models.MapMetadata", "Map", b1 =>
+ {
+ b1.Property("MissionRunId")
+ .HasColumnType("text");
+
+ b1.Property("MapName")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b1.HasKey("MissionRunId");
+
+ b1.ToTable("MissionRuns");
+
+ b1.WithOwner()
+ .HasForeignKey("MissionRunId");
+
+ b1.OwnsOne("Api.Database.Models.Boundary", "Boundary", b2 =>
+ {
+ b2.Property("MapMetadataMissionRunId")
+ .HasColumnType("text");
+
+ b2.Property("X1")
+ .HasColumnType("double precision");
+
+ b2.Property("X2")
+ .HasColumnType("double precision");
+
+ b2.Property("Y1")
+ .HasColumnType("double precision");
+
+ b2.Property("Y2")
+ .HasColumnType("double precision");
+
+ b2.Property("Z1")
+ .HasColumnType("double precision");
+
+ b2.Property("Z2")
+ .HasColumnType("double precision");
+
+ b2.HasKey("MapMetadataMissionRunId");
+
+ b2.ToTable("MissionRuns");
+
+ b2.WithOwner()
+ .HasForeignKey("MapMetadataMissionRunId");
+ });
+
+ b1.OwnsOne("Api.Database.Models.TransformationMatrices", "TransformationMatrices", b2 =>
+ {
+ b2.Property("MapMetadataMissionRunId")
+ .HasColumnType("text");
+
+ b2.Property("C1")
+ .HasColumnType("double precision");
+
+ b2.Property("C2")
+ .HasColumnType("double precision");
+
+ b2.Property("D1")
+ .HasColumnType("double precision");
+
+ b2.Property("D2")
+ .HasColumnType("double precision");
+
+ b2.HasKey("MapMetadataMissionRunId");
+
+ b2.ToTable("MissionRuns");
+
+ b2.WithOwner()
+ .HasForeignKey("MapMetadataMissionRunId");
+ });
+
+ b1.Navigation("Boundary")
+ .IsRequired();
+
+ b1.Navigation("TransformationMatrices")
+ .IsRequired();
+ });
+
+ b.Navigation("Area");
+
+ b.Navigation("Map");
+
+ 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.Position", "InspectionTarget", 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.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.Navigation("InspectionTarget")
+ .IsRequired();
+
+ b.Navigation("RobotPose")
+ .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.Area", "CurrentArea")
+ .WithMany()
+ .HasForeignKey("CurrentAreaId");
+
+ b.HasOne("Api.Database.Models.RobotModel", "Model")
+ .WithMany()
+ .HasForeignKey("ModelId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.OwnsOne("Api.Database.Models.Pose", "Pose", b1 =>
+ {
+ b1.Property("RobotId")
+ .HasColumnType("text");
+
+ b1.HasKey("RobotId");
+
+ b1.ToTable("Robots");
+
+ b1.WithOwner()
+ .HasForeignKey("RobotId");
+
+ b1.OwnsOne("Api.Database.Models.Orientation", "Orientation", b2 =>
+ {
+ b2.Property("PoseRobotId")
+ .HasColumnType("text");
+
+ b2.Property("W")
+ .HasColumnType("real");
+
+ b2.Property("X")
+ .HasColumnType("real");
+
+ b2.Property("Y")
+ .HasColumnType("real");
+
+ b2.Property("Z")
+ .HasColumnType("real");
+
+ b2.HasKey("PoseRobotId");
+
+ b2.ToTable("Robots");
+
+ b2.WithOwner()
+ .HasForeignKey("PoseRobotId");
+ });
+
+ b1.OwnsOne("Api.Database.Models.Position", "Position", b2 =>
+ {
+ b2.Property("PoseRobotId")
+ .HasColumnType("text");
+
+ b2.Property("X")
+ .HasColumnType("real");
+
+ b2.Property("Y")
+ .HasColumnType("real");
+
+ b2.Property("Z")
+ .HasColumnType("real");
+
+ b2.HasKey("PoseRobotId");
+
+ b2.ToTable("Robots");
+
+ b2.WithOwner()
+ .HasForeignKey("PoseRobotId");
+ });
+
+ b1.Navigation("Orientation")
+ .IsRequired();
+
+ b1.Navigation("Position")
+ .IsRequired();
+ });
+
+ b.OwnsMany("Api.Database.Models.VideoStream", "VideoStreams", 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("ShouldRotate270Clockwise")
+ .HasColumnType("boolean");
+
+ b1.Property("Type")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b1.Property("Url")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b1.HasKey("Id");
+
+ b1.HasIndex("RobotId");
+
+ b1.ToTable("VideoStream");
+
+ b1.WithOwner()
+ .HasForeignKey("RobotId");
+ });
+
+ b.Navigation("CurrentArea");
+
+ b.Navigation("Model");
+
+ b.Navigation("Pose")
+ .IsRequired();
+
+ b.Navigation("VideoStreams");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.SafePosition", b =>
+ {
+ b.HasOne("Api.Database.Models.Area", null)
+ .WithMany("SafePositions")
+ .HasForeignKey("AreaId");
+
+ b.OwnsOne("Api.Database.Models.Pose", "Pose", b1 =>
+ {
+ b1.Property("SafePositionId")
+ .HasColumnType("text");
+
+ b1.HasKey("SafePositionId");
+
+ b1.ToTable("SafePositions");
+
+ b1.WithOwner()
+ .HasForeignKey("SafePositionId");
+
+ b1.OwnsOne("Api.Database.Models.Orientation", "Orientation", b2 =>
+ {
+ b2.Property("PoseSafePositionId")
+ .HasColumnType("text");
+
+ b2.Property("W")
+ .HasColumnType("real");
+
+ b2.Property("X")
+ .HasColumnType("real");
+
+ b2.Property("Y")
+ .HasColumnType("real");
+
+ b2.Property("Z")
+ .HasColumnType("real");
+
+ b2.HasKey("PoseSafePositionId");
+
+ b2.ToTable("SafePositions");
+
+ b2.WithOwner()
+ .HasForeignKey("PoseSafePositionId");
+ });
+
+ b1.OwnsOne("Api.Database.Models.Position", "Position", b2 =>
+ {
+ b2.Property("PoseSafePositionId")
+ .HasColumnType("text");
+
+ b2.Property("X")
+ .HasColumnType("real");
+
+ b2.Property("Y")
+ .HasColumnType("real");
+
+ b2.Property("Z")
+ .HasColumnType("real");
+
+ b2.HasKey("PoseSafePositionId");
+
+ b2.ToTable("SafePositions");
+
+ b2.WithOwner()
+ .HasForeignKey("PoseSafePositionId");
+ });
+
+ b1.Navigation("Orientation")
+ .IsRequired();
+
+ b1.Navigation("Position")
+ .IsRequired();
+ });
+
+ b.Navigation("Pose")
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Api.Database.Models.Area", b =>
+ {
+ b.Navigation("SafePositions");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.MissionRun", b =>
+ {
+ b.Navigation("Tasks");
+ });
+
+ modelBuilder.Entity("Api.Database.Models.MissionTask", b =>
+ {
+ b.Navigation("Inspections");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/backend/api/Migrations/20231115130240_AddInspectionFindingsTable.cs b/backend/api/Migrations/20231115130240_AddInspectionFindingsTable.cs
new file mode 100644
index 000000000..c41c3fc31
--- /dev/null
+++ b/backend/api/Migrations/20231115130240_AddInspectionFindingsTable.cs
@@ -0,0 +1,49 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Api.Migrations
+{
+ ///
+ public partial class AddInspectionFindingsTable : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "InspectionFinding",
+ columns: table => new
+ {
+ Id = table.Column(type: "text", nullable: false),
+ InspectionDate = table.Column(type: "timestamp with time zone", nullable: false),
+ Area = table.Column(type: "text", nullable: false),
+ IsarStepId = table.Column(type: "text", nullable: false),
+ Findings = table.Column(type: "text", nullable: false),
+ InspectionId = table.Column(type: "text", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_InspectionFinding", x => x.Id);
+ table.ForeignKey(
+ name: "FK_InspectionFinding_Inspections_InspectionId",
+ column: x => x.InspectionId,
+ principalTable: "Inspections",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_InspectionFinding_InspectionId",
+ table: "InspectionFinding",
+ column: "InspectionId");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "InspectionFinding");
+ }
+ }
+}
diff --git a/backend/api/Migrations/FlotillaDbContextModelSnapshot.cs b/backend/api/Migrations/FlotillaDbContextModelSnapshot.cs
index 3be74aa85..020d540e6 100644
--- a/backend/api/Migrations/FlotillaDbContextModelSnapshot.cs
+++ b/backend/api/Migrations/FlotillaDbContextModelSnapshot.cs
@@ -812,6 +812,42 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasForeignKey("InspectionId");
});
+ b.OwnsMany("Api.Database.Models.InspectionFinding", "InspectionFindings", b1 =>
+ {
+ b1.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("text");
+
+ b1.Property("Area")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b1.Property("Findings")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b1.Property("InspectionDate")
+ .HasColumnType("timestamp with time zone");
+
+ b1.Property("InspectionId")
+ .HasColumnType("text");
+
+ b1.Property("IsarStepId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b1.HasKey("Id");
+
+ b1.HasIndex("InspectionId");
+
+ b1.ToTable("InspectionFinding");
+
+ b1.WithOwner()
+ .HasForeignKey("InspectionId");
+ });
+
+ b.Navigation("InspectionFindings");
+
b.Navigation("InspectionTarget")
.IsRequired();
});
diff --git a/backend/api/Services/InspectionService.cs b/backend/api/Services/InspectionService.cs
index 60d786b71..c7598ec05 100644
--- a/backend/api/Services/InspectionService.cs
+++ b/backend/api/Services/InspectionService.cs
@@ -11,8 +11,7 @@ public interface IInspectionService
{
public Task UpdateInspectionStatus(string isarStepId, IsarStepStatus isarStepStatus);
public Task ReadByIsarStepId(string id);
-
- //public Task AddFindings(InspectionFindingsQuery inspectionFindingsQuery);
+ public Task AddFindings(InspectionFindingsQuery inspectionFindingsQuery);
}
@@ -64,31 +63,31 @@ private async Task Update(Inspection inspection)
private IQueryable GetInspections()
{
- return _context.Inspections.Include(inspection => inspection);
+ return _context.Inspections.Include(inspection => inspection.InspectionFindings);
}
- /* public async Task AddFindings(InspectionFindingsQuery inspectionFindingsQuery)
- {
+ public async Task AddFindings(InspectionFindingsQuery inspectionFindingsQuery)
+ {
- var inspection = await ReadByIsarStepId(inspectionFindingsQuery.IsarStepId);
+ var inspection = await ReadByIsarStepId(inspectionFindingsQuery.IsarStepId);
- if (inspection is null)
- {
- return null;
- }
+ if (inspection is null)
+ {
+ return null;
+ }
- var inspectionFindings = new InspectionFindings
- {
- InspectionDate = inspectionFindingsQuery.InspectionDate,
- Area = inspectionFindingsQuery.Area,
- IsarStepId = inspectionFindingsQuery.IsarStepId,
- Findings = inspectionFindingsQuery.Findings
- };
+ var inspectionFindings = new InspectionFinding
+ {
+ InspectionDate = inspectionFindingsQuery.InspectionDate,
+ Area = inspectionFindingsQuery.Area,
+ IsarStepId = inspectionFindingsQuery.IsarStepId,
+ Findings = inspectionFindingsQuery.Findings
+ };
- inspection.InspectionFindings.Add(inspectionFindings);
- inspection = await Update(inspection);
- _ = _signalRService.SendMessageAsync("Inspection findings added", inspection);
- return inspection;
- } */
+ inspection.InspectionFindings.Add(inspectionFindings);
+ inspection = await Update(inspection);
+ _ = _signalRService.SendMessageAsync("Inspection findings added", inspection);
+ return inspection;
+ }
}
}
diff --git a/backend/api/Services/MissionDefinitionService.cs b/backend/api/Services/MissionDefinitionService.cs
index 0f548100d..c753d4369 100644
--- a/backend/api/Services/MissionDefinitionService.cs
+++ b/backend/api/Services/MissionDefinitionService.cs
@@ -189,7 +189,7 @@ private IQueryable GetMissionDefinitionsWithSubModels()
.Include(missionDefinition => missionDefinition.LastSuccessfulRun)
.ThenInclude(missionRun => missionRun != null ? missionRun.Tasks : null)!
.ThenInclude(missionTask => missionTask.Inspections)
- .ThenInclude(inspection => inspection);
+ .ThenInclude(inspection => inspection.InspectionFindings);
}
private static void SearchByName(ref IQueryable missionDefinitions, string? name)
diff --git a/backend/api/Services/MissionTaskService.cs b/backend/api/Services/MissionTaskService.cs
index be25c288a..5b497236c 100644
--- a/backend/api/Services/MissionTaskService.cs
+++ b/backend/api/Services/MissionTaskService.cs
@@ -57,7 +57,7 @@ private async Task Update(MissionTask missionTask)
private IQueryable GetMissionTasks()
{
- return _context.MissionTasks.Include(missionTask => missionTask.Inspections).ThenInclude(inspection => inspection);
+ return _context.MissionTasks.Include(missionTask => missionTask.Inspections).ThenInclude(inspection => inspection.InspectionFindings);
}
}
}