diff --git a/Backend/src/NexusRMM.Api/NexusRMM.Api.csproj b/Backend/src/NexusRMM.Api/NexusRMM.Api.csproj index 04244d5..b2863d4 100644 --- a/Backend/src/NexusRMM.Api/NexusRMM.Api.csproj +++ b/Backend/src/NexusRMM.Api/NexusRMM.Api.csproj @@ -18,6 +18,7 @@ + diff --git a/Backend/src/NexusRMM.Api/appsettings.json b/Backend/src/NexusRMM.Api/appsettings.json index b0f7a70..9720bbd 100644 --- a/Backend/src/NexusRMM.Api/appsettings.json +++ b/Backend/src/NexusRMM.Api/appsettings.json @@ -1,6 +1,6 @@ { "ConnectionStrings": { - "DefaultConnection": "Host=localhost;Port=5432;Database=nexusrmm;Username=nexusrmm;Password=nexusrmm_dev" + "DefaultConnection": "Host=localhost;Port=5433;Database=nexusrmm;Username=nexusrmm;Password=nexusrmm_dev" }, "Cors": { "Origins": ["http://localhost:5173"] diff --git a/Backend/src/NexusRMM.Infrastructure/Migrations/20260319104027_InitialCreate.Designer.cs b/Backend/src/NexusRMM.Infrastructure/Migrations/20260319104027_InitialCreate.Designer.cs new file mode 100644 index 0000000..1f986f4 --- /dev/null +++ b/Backend/src/NexusRMM.Infrastructure/Migrations/20260319104027_InitialCreate.Designer.cs @@ -0,0 +1,321 @@ +// +using System; +using System.Text.Json; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NexusRMM.Infrastructure.Data; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace NexusRMM.Infrastructure.Migrations +{ + [DbContext(typeof(RmmDbContext))] + [Migration("20260319104027_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("NexusRMM.Core.Models.Agent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AgentVersion") + .IsRequired() + .HasColumnType("text"); + + b.Property("EnrolledAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Hostname") + .IsRequired() + .HasColumnType("text"); + + b.Property("IpAddress") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastSeen") + .HasColumnType("timestamp with time zone"); + + b.Property("MacAddress") + .IsRequired() + .HasColumnType("text"); + + b.Property("MeshAgentId") + .HasColumnType("text"); + + b.Property("OsType") + .HasColumnType("integer"); + + b.Property("OsVersion") + .IsRequired() + .HasColumnType("text"); + + b.Property("Status") + .HasColumnType("integer"); + + b.PrimitiveCollection("Tags") + .IsRequired() + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("Hostname"); + + b.HasIndex("MacAddress"); + + b.ToTable("Agents"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.AgentMetric", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("uuid"); + + b.Property("Metrics") + .HasColumnType("jsonb"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("Timestamp"); + + b.ToTable("AgentMetrics"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.Alert", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Acknowledged") + .HasColumnType("boolean"); + + b.Property("AgentId") + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("RuleId") + .HasColumnType("integer"); + + b.Property("Severity") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("CreatedAt"); + + b.HasIndex("RuleId"); + + b.ToTable("Alerts"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.AlertRule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("MetricPath") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Operator") + .IsRequired() + .HasColumnType("text"); + + b.Property("Severity") + .HasColumnType("integer"); + + b.Property("Threshold") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.ToTable("AlertRules"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.TaskItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AgentId") + .HasColumnType("uuid"); + + b.Property("CompletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Payload") + .HasColumnType("jsonb"); + + b.Property("Result") + .HasColumnType("jsonb"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.ToTable("Tasks"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.Ticket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.ToTable("Tickets"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.AgentMetric", b => + { + b.HasOne("NexusRMM.Core.Models.Agent", "Agent") + .WithMany("Metrics") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.Alert", b => + { + b.HasOne("NexusRMM.Core.Models.Agent", "Agent") + .WithMany("Alerts") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("NexusRMM.Core.Models.AlertRule", "Rule") + .WithMany("Alerts") + .HasForeignKey("RuleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Rule"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.TaskItem", b => + { + b.HasOne("NexusRMM.Core.Models.Agent", "Agent") + .WithMany("Tasks") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.Ticket", b => + { + b.HasOne("NexusRMM.Core.Models.Agent", "Agent") + .WithMany("Tickets") + .HasForeignKey("AgentId"); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.Agent", b => + { + b.Navigation("Alerts"); + + b.Navigation("Metrics"); + + b.Navigation("Tasks"); + + b.Navigation("Tickets"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.AlertRule", b => + { + b.Navigation("Alerts"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Backend/src/NexusRMM.Infrastructure/Migrations/20260319104027_InitialCreate.cs b/Backend/src/NexusRMM.Infrastructure/Migrations/20260319104027_InitialCreate.cs new file mode 100644 index 0000000..75f296b --- /dev/null +++ b/Backend/src/NexusRMM.Infrastructure/Migrations/20260319104027_InitialCreate.cs @@ -0,0 +1,223 @@ +using System; +using System.Text.Json; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace NexusRMM.Infrastructure.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Agents", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Hostname = table.Column(type: "text", nullable: false), + OsType = table.Column(type: "integer", nullable: false), + OsVersion = table.Column(type: "text", nullable: false), + IpAddress = table.Column(type: "text", nullable: false), + MacAddress = table.Column(type: "text", nullable: false), + AgentVersion = table.Column(type: "text", nullable: false), + Status = table.Column(type: "integer", nullable: false), + Tags = table.Column(type: "jsonb", nullable: false), + LastSeen = table.Column(type: "timestamp with time zone", nullable: false), + EnrolledAt = table.Column(type: "timestamp with time zone", nullable: false), + MeshAgentId = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Agents", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AlertRules", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Name = table.Column(type: "text", nullable: false), + MetricPath = table.Column(type: "text", nullable: false), + Operator = table.Column(type: "text", nullable: false), + Threshold = table.Column(type: "double precision", nullable: false), + Severity = table.Column(type: "integer", nullable: false), + Enabled = table.Column(type: "boolean", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AlertRules", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AgentMetrics", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + AgentId = table.Column(type: "uuid", nullable: false), + Timestamp = table.Column(type: "timestamp with time zone", nullable: false), + Metrics = table.Column(type: "jsonb", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AgentMetrics", x => x.Id); + table.ForeignKey( + name: "FK_AgentMetrics_Agents_AgentId", + column: x => x.AgentId, + principalTable: "Agents", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Tasks", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + AgentId = table.Column(type: "uuid", nullable: false), + Type = table.Column(type: "integer", nullable: false), + Payload = table.Column(type: "jsonb", nullable: true), + Status = table.Column(type: "integer", nullable: false), + Result = table.Column(type: "jsonb", nullable: true), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), + CompletedAt = table.Column(type: "timestamp with time zone", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Tasks", x => x.Id); + table.ForeignKey( + name: "FK_Tasks_Agents_AgentId", + column: x => x.AgentId, + principalTable: "Agents", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Tickets", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Title = table.Column(type: "text", nullable: false), + Description = table.Column(type: "text", nullable: false), + Status = table.Column(type: "integer", nullable: false), + Priority = table.Column(type: "integer", nullable: false), + AgentId = table.Column(type: "uuid", nullable: true), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Tickets", x => x.Id); + table.ForeignKey( + name: "FK_Tickets_Agents_AgentId", + column: x => x.AgentId, + principalTable: "Agents", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "Alerts", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + RuleId = table.Column(type: "integer", nullable: false), + AgentId = table.Column(type: "uuid", nullable: false), + Message = table.Column(type: "text", nullable: false), + Severity = table.Column(type: "integer", nullable: false), + Acknowledged = table.Column(type: "boolean", nullable: false), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Alerts", x => x.Id); + table.ForeignKey( + name: "FK_Alerts_Agents_AgentId", + column: x => x.AgentId, + principalTable: "Agents", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Alerts_AlertRules_RuleId", + column: x => x.RuleId, + principalTable: "AlertRules", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AgentMetrics_AgentId", + table: "AgentMetrics", + column: "AgentId"); + + migrationBuilder.CreateIndex( + name: "IX_AgentMetrics_Timestamp", + table: "AgentMetrics", + column: "Timestamp"); + + migrationBuilder.CreateIndex( + name: "IX_Agents_Hostname", + table: "Agents", + column: "Hostname"); + + migrationBuilder.CreateIndex( + name: "IX_Agents_MacAddress", + table: "Agents", + column: "MacAddress"); + + migrationBuilder.CreateIndex( + name: "IX_Alerts_AgentId", + table: "Alerts", + column: "AgentId"); + + migrationBuilder.CreateIndex( + name: "IX_Alerts_CreatedAt", + table: "Alerts", + column: "CreatedAt"); + + migrationBuilder.CreateIndex( + name: "IX_Alerts_RuleId", + table: "Alerts", + column: "RuleId"); + + migrationBuilder.CreateIndex( + name: "IX_Tasks_AgentId", + table: "Tasks", + column: "AgentId"); + + migrationBuilder.CreateIndex( + name: "IX_Tickets_AgentId", + table: "Tickets", + column: "AgentId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AgentMetrics"); + + migrationBuilder.DropTable( + name: "Alerts"); + + migrationBuilder.DropTable( + name: "Tasks"); + + migrationBuilder.DropTable( + name: "Tickets"); + + migrationBuilder.DropTable( + name: "AlertRules"); + + migrationBuilder.DropTable( + name: "Agents"); + } + } +} diff --git a/Backend/src/NexusRMM.Infrastructure/Migrations/RmmDbContextModelSnapshot.cs b/Backend/src/NexusRMM.Infrastructure/Migrations/RmmDbContextModelSnapshot.cs new file mode 100644 index 0000000..ac19005 --- /dev/null +++ b/Backend/src/NexusRMM.Infrastructure/Migrations/RmmDbContextModelSnapshot.cs @@ -0,0 +1,318 @@ +// +using System; +using System.Text.Json; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NexusRMM.Infrastructure.Data; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace NexusRMM.Infrastructure.Migrations +{ + [DbContext(typeof(RmmDbContext))] + partial class RmmDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("NexusRMM.Core.Models.Agent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AgentVersion") + .IsRequired() + .HasColumnType("text"); + + b.Property("EnrolledAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Hostname") + .IsRequired() + .HasColumnType("text"); + + b.Property("IpAddress") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastSeen") + .HasColumnType("timestamp with time zone"); + + b.Property("MacAddress") + .IsRequired() + .HasColumnType("text"); + + b.Property("MeshAgentId") + .HasColumnType("text"); + + b.Property("OsType") + .HasColumnType("integer"); + + b.Property("OsVersion") + .IsRequired() + .HasColumnType("text"); + + b.Property("Status") + .HasColumnType("integer"); + + b.PrimitiveCollection("Tags") + .IsRequired() + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("Hostname"); + + b.HasIndex("MacAddress"); + + b.ToTable("Agents"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.AgentMetric", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("uuid"); + + b.Property("Metrics") + .HasColumnType("jsonb"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("Timestamp"); + + b.ToTable("AgentMetrics"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.Alert", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Acknowledged") + .HasColumnType("boolean"); + + b.Property("AgentId") + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("RuleId") + .HasColumnType("integer"); + + b.Property("Severity") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("CreatedAt"); + + b.HasIndex("RuleId"); + + b.ToTable("Alerts"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.AlertRule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("MetricPath") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Operator") + .IsRequired() + .HasColumnType("text"); + + b.Property("Severity") + .HasColumnType("integer"); + + b.Property("Threshold") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.ToTable("AlertRules"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.TaskItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AgentId") + .HasColumnType("uuid"); + + b.Property("CompletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Payload") + .HasColumnType("jsonb"); + + b.Property("Result") + .HasColumnType("jsonb"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.ToTable("Tasks"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.Ticket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.ToTable("Tickets"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.AgentMetric", b => + { + b.HasOne("NexusRMM.Core.Models.Agent", "Agent") + .WithMany("Metrics") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.Alert", b => + { + b.HasOne("NexusRMM.Core.Models.Agent", "Agent") + .WithMany("Alerts") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("NexusRMM.Core.Models.AlertRule", "Rule") + .WithMany("Alerts") + .HasForeignKey("RuleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Rule"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.TaskItem", b => + { + b.HasOne("NexusRMM.Core.Models.Agent", "Agent") + .WithMany("Tasks") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.Ticket", b => + { + b.HasOne("NexusRMM.Core.Models.Agent", "Agent") + .WithMany("Tickets") + .HasForeignKey("AgentId"); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.Agent", b => + { + b.Navigation("Alerts"); + + b.Navigation("Metrics"); + + b.Navigation("Tasks"); + + b.Navigation("Tickets"); + }); + + modelBuilder.Entity("NexusRMM.Core.Models.AlertRule", b => + { + b.Navigation("Alerts"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..29c8b61 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +services: + nexusrmm-postgres: + image: postgres:17 + container_name: nexusrmm-postgres + environment: + POSTGRES_DB: nexusrmm + POSTGRES_USER: nexusrmm + POSTGRES_PASSWORD: nexusrmm_dev + ports: + - "5433:5432" + volumes: + - nexusrmm_pgdata:/var/lib/postgresql/data + restart: unless-stopped + +volumes: + nexusrmm_pgdata: + name: nexusrmm_pgdata