Initial commit carried over from private repo. This is V2.
All checks were successful
Build and Push Docker Image / build (push) Successful in 1m3s
Build and Push Docker Image / docker (push) Successful in 43s

This commit is contained in:
2025-07-04 21:24:12 +02:00
parent 7715816029
commit 4393977389
96 changed files with 3223 additions and 0 deletions

View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MessengerApi.Db\MessengerApi.Db.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,31 @@
using MessengerApi.Db.Entities;
using Microsoft.EntityFrameworkCore;
namespace MessengerApi.Db.Npg
{
public class MessengerNpgDbContext : MessengerDbContext
{
private readonly string connectionString;
public MessengerNpgDbContext(string connectionString)
{
this.connectionString = connectionString;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseNpgsql(this.connectionString);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// https://stackoverflow.com/questions/26464357/what-is-the-purpose-of-non-unique-indexes-in-a-database
// https://stackoverflow.com/questions/40767980/generate-a-composite-unique-constraint-index-in-ef-core
// https://www.geeksforgeeks.org/difference-between-clustered-and-non-clustered-index/
modelBuilder.Entity<Message>().HasIndex(e => new { e.ToId, e.IsDelivered }).IsUnique(false);
}
}
}

View File

@ -0,0 +1,123 @@
// <auto-generated />
using System;
using MessengerApi.Db.Npg;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MessengerApi.Db.Npg.Migrations
{
[DbContext(typeof(MessengerNpgDbContext))]
[Migration("20250704170425_Initial")]
partial class Initial
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.6")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("MessengerApi.Db.Entities.Message", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<DateTime>("CreatedUtc")
.HasColumnType("timestamp with time zone");
b.Property<Guid>("FromId")
.HasColumnType("uuid");
b.Property<bool>("IsAcknowledged")
.HasColumnType("boolean");
b.Property<bool>("IsDelivered")
.HasColumnType("boolean");
b.Property<string>("Payload")
.HasColumnType("text");
b.Property<int>("PayloadLifespanInSeconds")
.HasColumnType("integer");
b.Property<string>("PayloadType")
.HasColumnType("text");
b.Property<Guid>("ToId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("ToId", "IsDelivered");
b.ToTable("Messages");
});
modelBuilder.Entity("MessengerApi.Db.Entities.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("ApiKey")
.HasColumnType("uuid");
b.Property<bool>("IsEnabled")
.HasColumnType("boolean");
b.Property<string>("Name")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("MessengerApi.Db.Entities.UserRoute", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid?>("FromId")
.HasColumnType("uuid");
b.Property<Guid?>("ToId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("FromId");
b.HasIndex("ToId");
b.ToTable("UserRoutes");
});
modelBuilder.Entity("MessengerApi.Db.Entities.UserRoute", b =>
{
b.HasOne("MessengerApi.Db.Entities.User", "From")
.WithMany()
.HasForeignKey("FromId");
b.HasOne("MessengerApi.Db.Entities.User", "To")
.WithMany()
.HasForeignKey("ToId");
b.Navigation("From");
b.Navigation("To");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,99 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MessengerApi.Db.Npg.Migrations
{
/// <inheritdoc />
public partial class Initial : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Messages",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
CreatedUtc = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
FromId = table.Column<Guid>(type: "uuid", nullable: false),
ToId = table.Column<Guid>(type: "uuid", nullable: false),
IsDelivered = table.Column<bool>(type: "boolean", nullable: false),
IsAcknowledged = table.Column<bool>(type: "boolean", nullable: false),
PayloadType = table.Column<string>(type: "text", nullable: true),
Payload = table.Column<string>(type: "text", nullable: true),
PayloadLifespanInSeconds = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Messages", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
ApiKey = table.Column<Guid>(type: "uuid", nullable: false),
Name = table.Column<string>(type: "text", nullable: true),
IsEnabled = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
});
migrationBuilder.CreateTable(
name: "UserRoutes",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
FromId = table.Column<Guid>(type: "uuid", nullable: true),
ToId = table.Column<Guid>(type: "uuid", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_UserRoutes", x => x.Id);
table.ForeignKey(
name: "FK_UserRoutes_Users_FromId",
column: x => x.FromId,
principalTable: "Users",
principalColumn: "Id");
table.ForeignKey(
name: "FK_UserRoutes_Users_ToId",
column: x => x.ToId,
principalTable: "Users",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_Messages_ToId_IsDelivered",
table: "Messages",
columns: new[] { "ToId", "IsDelivered" });
migrationBuilder.CreateIndex(
name: "IX_UserRoutes_FromId",
table: "UserRoutes",
column: "FromId");
migrationBuilder.CreateIndex(
name: "IX_UserRoutes_ToId",
table: "UserRoutes",
column: "ToId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Messages");
migrationBuilder.DropTable(
name: "UserRoutes");
migrationBuilder.DropTable(
name: "Users");
}
}
}

View File

@ -0,0 +1,120 @@
// <auto-generated />
using System;
using MessengerApi.Db.Npg;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MessengerApi.Db.Npg.Migrations
{
[DbContext(typeof(MessengerNpgDbContext))]
partial class MessengerNpgDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.6")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("MessengerApi.Db.Entities.Message", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<DateTime>("CreatedUtc")
.HasColumnType("timestamp with time zone");
b.Property<Guid>("FromId")
.HasColumnType("uuid");
b.Property<bool>("IsAcknowledged")
.HasColumnType("boolean");
b.Property<bool>("IsDelivered")
.HasColumnType("boolean");
b.Property<string>("Payload")
.HasColumnType("text");
b.Property<int>("PayloadLifespanInSeconds")
.HasColumnType("integer");
b.Property<string>("PayloadType")
.HasColumnType("text");
b.Property<Guid>("ToId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("ToId", "IsDelivered");
b.ToTable("Messages");
});
modelBuilder.Entity("MessengerApi.Db.Entities.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("ApiKey")
.HasColumnType("uuid");
b.Property<bool>("IsEnabled")
.HasColumnType("boolean");
b.Property<string>("Name")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("MessengerApi.Db.Entities.UserRoute", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid?>("FromId")
.HasColumnType("uuid");
b.Property<Guid?>("ToId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("FromId");
b.HasIndex("ToId");
b.ToTable("UserRoutes");
});
modelBuilder.Entity("MessengerApi.Db.Entities.UserRoute", b =>
{
b.HasOne("MessengerApi.Db.Entities.User", "From")
.WithMany()
.HasForeignKey("FromId");
b.HasOne("MessengerApi.Db.Entities.User", "To")
.WithMany()
.HasForeignKey("ToId");
b.Navigation("From");
b.Navigation("To");
});
#pragma warning restore 612, 618
}
}
}