diff --git a/src/RecNet.Application/Profiles/ProfileDto.cs b/src/RecNet.Application/Profiles/ProfileDto.cs
index c774831..0c762c7 100644
--- a/src/RecNet.Application/Profiles/ProfileDto.cs
+++ b/src/RecNet.Application/Profiles/ProfileDto.cs
@@ -9,4 +9,7 @@ public class ProfileDTO
[JsonPropertyName("Name")]
public required string Name { get; init; }
+
+ [JsonPropertyName("Developer")]
+ public bool IsDeveloper { get; init; }
}
diff --git a/src/RecNet.Domain/Profiles/Profile.cs b/src/RecNet.Domain/Profiles/Profile.cs
index c3d74e8..a1cba2b 100644
--- a/src/RecNet.Domain/Profiles/Profile.cs
+++ b/src/RecNet.Domain/Profiles/Profile.cs
@@ -33,6 +33,7 @@ public class Profile
// EZ
public bool IsBanned { get; private set; }
public bool IsModerator { get; private set; }
+ public bool IsDeveloper { get; private set; }
public DateTimeOffset CreatedAt { get; private set; }
@@ -88,6 +89,12 @@ public class Profile
public void RevokeModerator()
=> IsModerator = false;
+ public void GrantDeveloper()
+ => IsDeveloper = true;
+
+ public void RevokeDeveloper()
+ => IsDeveloper = false;
+
public void SetAvatar(Avatar avatar)
=> Avatar = avatar ?? throw new DomainException("Avatar is required.");
diff --git a/src/RecNet.Infrastructure/Persistence/Migrations/20260626200738_DeveloperBool.Designer.cs b/src/RecNet.Infrastructure/Persistence/Migrations/20260626200738_DeveloperBool.Designer.cs
new file mode 100644
index 0000000..df35b5d
--- /dev/null
+++ b/src/RecNet.Infrastructure/Persistence/Migrations/20260626200738_DeveloperBool.Designer.cs
@@ -0,0 +1,171 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using RecNet.Infrastructure.Persistence;
+
+#nullable disable
+
+namespace RecNet.Infrastructure.Persistence.Migrations
+{
+ [DbContext(typeof(DatabaseContext))]
+ [Migration("20260626200738_DeveloperBool")]
+ partial class DeveloperBool
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "10.0.8")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("RecNet.Domain.Configuration.ServerConfig", b =>
+ {
+ b.Property("Key")
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.HasKey("Key");
+
+ b.ToTable("ServerConfigs");
+ });
+
+ modelBuilder.Entity("RecNet.Domain.GameVersions.GameVersion", b =>
+ {
+ b.Property("Version")
+ .HasMaxLength(32)
+ .HasColumnType("character varying(32)");
+
+ b.Property("IsValid")
+ .HasColumnType("boolean");
+
+ b.HasKey("Version");
+
+ b.ToTable("GameVersions");
+ });
+
+ modelBuilder.Entity("RecNet.Domain.Profiles.PlayerSetting", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("uuid");
+
+ b.Property("Key")
+ .HasMaxLength(100)
+ .HasColumnType("character varying(100)");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("UserId", "Key");
+
+ b.ToTable("PlayerSettings");
+ });
+
+ modelBuilder.Entity("RecNet.Domain.Profiles.Profile", b =>
+ {
+ b.Property("ProfileId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.PrimitiveCollection("DeviceIds")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("IsBanned")
+ .HasColumnType("boolean");
+
+ b.Property("IsDeveloper")
+ .HasColumnType("boolean");
+
+ b.Property("IsModerator")
+ .HasColumnType("boolean");
+
+ b.Property("MetaAuthenticationSecret")
+ .IsRequired()
+ .HasColumnType("bytea");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("character varying(32)");
+
+ b.Property("Platform")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("PlatformId")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.HasKey("ProfileId");
+
+ b.HasIndex("Platform", "PlatformId")
+ .IsUnique();
+
+ b.ToTable("Profiles");
+ });
+
+ modelBuilder.Entity("RecNet.Domain.Profiles.PlayerSetting", b =>
+ {
+ b.HasOne("RecNet.Domain.Profiles.Profile", null)
+ .WithMany("Settings")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("RecNet.Domain.Profiles.Profile", b =>
+ {
+ b.OwnsOne("RecNet.Domain.Profiles.Avatar", "Avatar", b1 =>
+ {
+ b1.Property("ProfileId")
+ .HasColumnType("uuid");
+
+ b1.Property("HairColor")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b1.Property("OutfitSelections")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b1.Property("SkinColor")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b1.HasKey("ProfileId");
+
+ b1.ToTable("Profiles");
+
+ b1.WithOwner()
+ .HasForeignKey("ProfileId");
+ });
+
+ b.Navigation("Avatar")
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("RecNet.Domain.Profiles.Profile", b =>
+ {
+ b.Navigation("Settings");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/RecNet.Infrastructure/Persistence/Migrations/20260626200738_DeveloperBool.cs b/src/RecNet.Infrastructure/Persistence/Migrations/20260626200738_DeveloperBool.cs
new file mode 100644
index 0000000..5acde7b
--- /dev/null
+++ b/src/RecNet.Infrastructure/Persistence/Migrations/20260626200738_DeveloperBool.cs
@@ -0,0 +1,29 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace RecNet.Infrastructure.Persistence.Migrations
+{
+ ///
+ public partial class DeveloperBool : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "IsDeveloper",
+ table: "Profiles",
+ type: "boolean",
+ nullable: false,
+ defaultValue: false);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "IsDeveloper",
+ table: "Profiles");
+ }
+ }
+}
diff --git a/src/RecNet.Infrastructure/Persistence/Migrations/DatabaseContextModelSnapshot.cs b/src/RecNet.Infrastructure/Persistence/Migrations/DatabaseContextModelSnapshot.cs
index 099830c..04fa6b1 100644
--- a/src/RecNet.Infrastructure/Persistence/Migrations/DatabaseContextModelSnapshot.cs
+++ b/src/RecNet.Infrastructure/Persistence/Migrations/DatabaseContextModelSnapshot.cs
@@ -85,6 +85,9 @@ namespace RecNet.Infrastructure.Persistence.Migrations
b.Property("IsBanned")
.HasColumnType("boolean");
+ b.Property("IsDeveloper")
+ .HasColumnType("boolean");
+
b.Property("IsModerator")
.HasColumnType("boolean");