From 196547e50f395083e1d97e741a7c6e6b8d929371 Mon Sep 17 00:00:00 2001
From: LittleSheep <littlesheep.code@hotmail.com>
Date: Sat, 3 May 2025 13:16:18 +0800
Subject: [PATCH] :card_file_box: Add nonce column to chat messages and fix
 column typo

This migration adds a new "nonce" column to the "chat_messages" table to ensure message uniqueness or integrity. Additionally, it corrects a typo in the "members_mentioned" column name to improve consistency and clarity.
---
 DysonNetwork.Sphere/Chat/ChatController.cs    |   87 +-
 DysonNetwork.Sphere/Chat/ChatService.cs       |    4 +-
 DysonNetwork.Sphere/Chat/Message.cs           |   31 +-
 ...0503032932_AddChatMessageNonce.Designer.cs | 2364 +++++++++++++++++
 .../20250503032932_AddChatMessageNonce.cs     |   39 +
 ...040922_DontKnowHowToNameThing2.Designer.cs | 2359 ++++++++++++++++
 .../20250503040922_DontKnowHowToNameThing2.cs |   48 +
 .../Migrations/AppDatabaseModelSnapshot.cs    |   16 +-
 8 files changed, 4927 insertions(+), 21 deletions(-)
 create mode 100644 DysonNetwork.Sphere/Migrations/20250503032932_AddChatMessageNonce.Designer.cs
 create mode 100644 DysonNetwork.Sphere/Migrations/20250503032932_AddChatMessageNonce.cs
 create mode 100644 DysonNetwork.Sphere/Migrations/20250503040922_DontKnowHowToNameThing2.Designer.cs
 create mode 100644 DysonNetwork.Sphere/Migrations/20250503040922_DontKnowHowToNameThing2.cs

diff --git a/DysonNetwork.Sphere/Chat/ChatController.cs b/DysonNetwork.Sphere/Chat/ChatController.cs
index 8b8d1f3..7f25783 100644
--- a/DysonNetwork.Sphere/Chat/ChatController.cs
+++ b/DysonNetwork.Sphere/Chat/ChatController.cs
@@ -1,6 +1,7 @@
 using System.ComponentModel.DataAnnotations;
 using System.Text.RegularExpressions;
 using DysonNetwork.Sphere.Storage;
+using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.EntityFrameworkCore;
 
@@ -19,17 +20,75 @@ public partial class ChatController(AppDatabase db, ChatService cs) : Controller
     public class SendMessageRequest
     {
         [MaxLength(4096)] public string? Content { get; set; }
-        public List<CloudFile>? Attachments { get; set; }
+        [MaxLength(36)] public string? Nonce { get; set; }
+        public List<string>? AttachmentsId { get; set; }
+        public Dictionary<string, object>? Meta { get; set; }
+    }
+
+    [HttpGet("{roomId:long}/members/me")]
+    [Authorize]
+    public async Task<ActionResult<ChatMember>> GetCurrentIdentity(long roomId)
+    {
+        if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
+            return Unauthorized();
+
+        var member = await db.ChatMembers
+            .Where(m => m.AccountId == currentUser.Id && m.ChatRoomId == roomId)
+            .Include(m => m.Account)
+            .FirstOrDefaultAsync();
+
+        if (member == null)
+            return NotFound();
+
+        return Ok(member);
+    }
+
+    [HttpGet("{roomId:long}/messages")]
+    public async Task<ActionResult<List<Message>>> ListMessages(long roomId, [FromQuery] int offset, [FromQuery] int take = 20)
+    {
+        var currentUser = HttpContext.Items["CurrentUser"] as Account.Account;
+
+        var room = await db.ChatRooms.FirstOrDefaultAsync(r => r.Id == roomId);
+        if (room is null) return NotFound();
+
+        if (!room.IsPublic)
+        {
+            if (currentUser is null) return Unauthorized();
+
+            var member = await db.ChatMembers
+                .Where(m => m.AccountId == currentUser.Id && m.ChatRoomId == roomId)
+                .FirstOrDefaultAsync();
+            if (member == null || member.Role < ChatMemberRole.Normal)
+                return StatusCode(403, "You are not a member of this chat room.");
+        }
+
+        var totalCount = await db.ChatMessages
+            .Where(m => m.ChatRoomId == roomId)
+            .CountAsync();
+        var messages = await db.ChatMessages
+            .Where(m => m.ChatRoomId == roomId)
+            .OrderByDescending(m => m.CreatedAt)
+            .Include(m => m.Sender)
+            .Include(m => m.Sender.Account)
+            .Include(m => m.Attachments)
+            .Skip(offset)
+            .Take(take)
+            .ToListAsync();
+
+        Response.Headers["X-Total"] = totalCount.ToString();
+
+        return Ok(messages);
     }
 
     [GeneratedRegex(@"@([A-Za-z0-9_-]+)")]
     private static partial Regex MentionRegex();
 
     [HttpPost("{roomId:long}/messages")]
+    [Authorize]
     public async Task<ActionResult> SendMessage([FromBody] SendMessageRequest request, long roomId)
     {
         if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
-        if (string.IsNullOrWhiteSpace(request.Content) && (request.Attachments == null || request.Attachments.Count == 0))
+        if (string.IsNullOrWhiteSpace(request.Content) && (request.AttachmentsId == null || request.AttachmentsId.Count == 0))
             return BadRequest("You cannot send an empty message.");
 
         var member = await db.ChatMembers
@@ -38,16 +97,27 @@ public partial class ChatController(AppDatabase db, ChatService cs) : Controller
             .Include(m => m.ChatRoom.Realm)
             .FirstOrDefaultAsync();
         if (member == null || member.Role < ChatMemberRole.Normal) return StatusCode(403, "You need to be a normal member to send messages here.");
+        currentUser.Profile = null;
+        member.Account = currentUser;
 
         var message = new Message
         {
             SenderId = member.Id,
             ChatRoomId = roomId,
+            Nonce = request.Nonce ?? Guid.NewGuid().ToString(),
+            Meta = request.Meta ?? new Dictionary<string, object>(),
         };
         if (request.Content is not null)
             message.Content = request.Content;
-        if (request.Attachments is not null)
-            message.Attachments = request.Attachments;
+        if (request.AttachmentsId is not null)
+        {
+            var attachments = await db.Files
+                .Where(f => request.AttachmentsId.Contains(f.Id))
+                .ToListAsync();
+            message.Attachments = attachments
+                .OrderBy(f => request.AttachmentsId.IndexOf(f.Id))
+                .ToList();
+        }
 
         if (request.Content is not null)
         {
@@ -55,17 +125,16 @@ public partial class ChatController(AppDatabase db, ChatService cs) : Controller
                 .Matches(request.Content)
                 .Select(m => m.Groups[1].Value)
                 .ToList();
-            if (mentioned is not null && mentioned.Count > 0)
+            if (mentioned.Count > 0)
             {
                 var mentionedMembers = await db.ChatMembers
                    .Where(m => mentioned.Contains(m.Account.Name))
                    .Select(m => m.Id)
                    .ToListAsync();
-                message.MembersMetioned = mentionedMembers;
+                message.MembersMentioned = mentionedMembers;
             }
         }
 
-        member.Account = currentUser;
         var result = await cs.SendMessageAsync(message, member, member.ChatRoom);
 
         return Ok(result);
@@ -78,9 +147,9 @@ public partial class ChatController(AppDatabase db, ChatService cs) : Controller
     }
 
     [HttpGet("{roomId:long}/sync")]
-    public async Task<ActionResult<SyncResponse>> GetSyncData([FromQuery] SyncRequest request, long roomId)
+    public async Task<ActionResult<SyncResponse>> GetSyncData([FromBody] SyncRequest request, long roomId)
     {
-        if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) 
+        if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
             return Unauthorized();
 
         var isMember = await db.ChatMembers
diff --git a/DysonNetwork.Sphere/Chat/ChatService.cs b/DysonNetwork.Sphere/Chat/ChatService.cs
index e876c2e..c22dd7c 100644
--- a/DysonNetwork.Sphere/Chat/ChatService.cs
+++ b/DysonNetwork.Sphere/Chat/ChatService.cs
@@ -23,7 +23,7 @@ public class ChatService(AppDatabase db, NotificationService nty, WebSocketServi
             var member in db.ChatMembers
                    .Where(m => m.ChatRoomId == message.ChatRoomId && m.AccountId != message.Sender.AccountId)
                    .Where(m => m.Notify != ChatMemberNotify.None)
-                   .Where(m => m.Notify != ChatMemberNotify.Mentions || (message.MembersMetioned != null && message.MembersMetioned.Contains(m.Id)))
+                   .Where(m => m.Notify != ChatMemberNotify.Mentions || (message.MembersMentioned != null && message.MembersMentioned.Contains(m.Id)))
                    .AsAsyncEnumerable()
         )
         {
@@ -94,7 +94,7 @@ public class ChatService(AppDatabase db, NotificationService nty, WebSocketServi
             .Select(m => new MessageChange
             {
                 MessageId = m.Id,
-                Action = m.DeletedAt != null ? "delete" : (m.EditedAt == null ? "create" : "update"),
+                Action = m.DeletedAt != null ? "delete" : (m.UpdatedAt == null ? "create" : "update"),
                 Message = m.DeletedAt != null ? null : m,
                 Timestamp = m.DeletedAt != null ? m.DeletedAt.Value : m.UpdatedAt
             })
diff --git a/DysonNetwork.Sphere/Chat/Message.cs b/DysonNetwork.Sphere/Chat/Message.cs
index c35b36d..9751c79 100644
--- a/DysonNetwork.Sphere/Chat/Message.cs
+++ b/DysonNetwork.Sphere/Chat/Message.cs
@@ -9,10 +9,10 @@ namespace DysonNetwork.Sphere.Chat;
 public class Message : ModelBase
 {
     public Guid Id { get; set; } = Guid.NewGuid();
-    [MaxLength(1024)] public string Type { get; set; } = null!;
     [MaxLength(4096)] public string Content { get; set; } = string.Empty;
     [Column(TypeName = "jsonb")] public Dictionary<string, object>? Meta { get; set; }
-    [Column(TypeName = "jsonb")] public List<Guid>? MembersMetioned { get; set; }
+    [Column(TypeName = "jsonb")] public List<Guid>? MembersMentioned { get; set; }
+    [MaxLength(36)] public string Nonce { get; set; } = null!;
     public Instant? EditedAt { get; set; }
 
     public ICollection<CloudFile> Attachments { get; set; } = new List<CloudFile>();
@@ -28,6 +28,33 @@ public class Message : ModelBase
     public ChatMember Sender { get; set; } = null!;
     public long ChatRoomId { get; set; }
     [JsonIgnore] public ChatRoom ChatRoom { get; set; } = null!;
+    
+    public Message Clone()
+    {
+        return new Message
+        {
+            Id = Id,
+            Content = Content,
+            Meta = Meta?.ToDictionary(entry => entry.Key, entry => entry.Value),
+            MembersMentioned = MembersMentioned?.ToList(),
+            Nonce = Nonce,
+            EditedAt = EditedAt,
+            Attachments = new List<CloudFile>(Attachments),
+            Reactions = new List<MessageReaction>(Reactions),
+            Statuses = new List<MessageStatus>(Statuses),
+            RepliedMessageId = RepliedMessageId,
+            RepliedMessage = RepliedMessage?.Clone() as Message,
+            ForwardedMessageId = ForwardedMessageId,
+            ForwardedMessage = ForwardedMessage?.Clone() as Message,
+            SenderId = SenderId,
+            Sender = Sender,
+            ChatRoomId = ChatRoomId,
+            ChatRoom = ChatRoom,
+            CreatedAt = CreatedAt,
+            UpdatedAt = UpdatedAt,
+            DeletedAt = DeletedAt
+        };
+    }
 }
 
 public enum MessageReactionAttitude
diff --git a/DysonNetwork.Sphere/Migrations/20250503032932_AddChatMessageNonce.Designer.cs b/DysonNetwork.Sphere/Migrations/20250503032932_AddChatMessageNonce.Designer.cs
new file mode 100644
index 0000000..0a444a1
--- /dev/null
+++ b/DysonNetwork.Sphere/Migrations/20250503032932_AddChatMessageNonce.Designer.cs
@@ -0,0 +1,2364 @@
+// <auto-generated />
+using System;
+using System.Collections.Generic;
+using System.Text.Json;
+using DysonNetwork.Sphere;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using NodaTime;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using NpgsqlTypes;
+
+#nullable disable
+
+namespace DysonNetwork.Sphere.Migrations
+{
+    [DbContext(typeof(AppDatabase))]
+    [Migration("20250503032932_AddChatMessageNonce")]
+    partial class AddChatMessageNonce
+    {
+        /// <inheritdoc />
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("ProductVersion", "9.0.3")
+                .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+            NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Account", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<Instant?>("ActivatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("activated_at");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<bool>("IsSuperuser")
+                        .HasColumnType("boolean")
+                        .HasColumnName("is_superuser");
+
+                    b.Property<string>("Language")
+                        .IsRequired()
+                        .HasMaxLength(32)
+                        .HasColumnType("character varying(32)")
+                        .HasColumnName("language");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("name");
+
+                    b.Property<string>("Nick")
+                        .IsRequired()
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("nick");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_accounts");
+
+                    b.HasIndex("Name")
+                        .IsUnique()
+                        .HasDatabaseName("ix_accounts_name");
+
+                    b.ToTable("accounts", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.AccountAuthFactor", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Secret")
+                        .HasColumnType("text")
+                        .HasColumnName("secret");
+
+                    b.Property<int>("Type")
+                        .HasColumnType("integer")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_account_auth_factors");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_account_auth_factors_account_id");
+
+                    b.ToTable("account_auth_factors", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.AccountContact", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<string>("Content")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("content");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<int>("Type")
+                        .HasColumnType("integer")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<Instant?>("VerifiedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("verified_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_account_contacts");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_account_contacts_account_id");
+
+                    b.ToTable("account_contacts", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.MagicSpell", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long?>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Instant?>("AffectedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("affected_at");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("ExpiresAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("expires_at");
+
+                    b.Property<Dictionary<string, object>>("Meta")
+                        .IsRequired()
+                        .HasColumnType("jsonb")
+                        .HasColumnName("meta");
+
+                    b.Property<string>("Spell")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("spell");
+
+                    b.Property<int>("Type")
+                        .HasColumnType("integer")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_magic_spells");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_magic_spells_account_id");
+
+                    b.HasIndex("Spell")
+                        .IsUnique()
+                        .HasDatabaseName("ix_magic_spells_spell");
+
+                    b.ToTable("magic_spells", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Notification", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("content");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Dictionary<string, object>>("Meta")
+                        .HasColumnType("jsonb")
+                        .HasColumnName("meta");
+
+                    b.Property<int>("Priority")
+                        .HasColumnType("integer")
+                        .HasColumnName("priority");
+
+                    b.Property<string>("Subtitle")
+                        .HasMaxLength(2048)
+                        .HasColumnType("character varying(2048)")
+                        .HasColumnName("subtitle");
+
+                    b.Property<string>("Title")
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("title");
+
+                    b.Property<string>("Topic")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("topic");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<Instant?>("ViewedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("viewed_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_notifications");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_notifications_account_id");
+
+                    b.ToTable("notifications", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.NotificationPushSubscription", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("DeviceId")
+                        .IsRequired()
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("device_id");
+
+                    b.Property<string>("DeviceToken")
+                        .IsRequired()
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("device_token");
+
+                    b.Property<Instant?>("LastUsedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("last_used_at");
+
+                    b.Property<int>("Provider")
+                        .HasColumnType("integer")
+                        .HasColumnName("provider");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_notification_push_subscriptions");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_notification_push_subscriptions_account_id");
+
+                    b.HasIndex("DeviceId")
+                        .IsUnique()
+                        .HasDatabaseName("ix_notification_push_subscriptions_device_id");
+
+                    b.HasIndex("DeviceToken")
+                        .IsUnique()
+                        .HasDatabaseName("ix_notification_push_subscriptions_device_token");
+
+                    b.ToTable("notification_push_subscriptions", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Profile", b =>
+                {
+                    b.Property<long>("Id")
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    b.Property<string>("BackgroundId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("background_id");
+
+                    b.Property<string>("Bio")
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("bio");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("FirstName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("first_name");
+
+                    b.Property<string>("LastName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("last_name");
+
+                    b.Property<string>("MiddleName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("middle_name");
+
+                    b.Property<string>("PictureId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("picture_id");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_account_profiles");
+
+                    b.HasIndex("BackgroundId")
+                        .HasDatabaseName("ix_account_profiles_background_id");
+
+                    b.HasIndex("PictureId")
+                        .HasDatabaseName("ix_account_profiles_picture_id");
+
+                    b.ToTable("account_profiles", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Relationship", b =>
+                {
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<long>("RelatedId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("related_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("ExpiredAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("expired_at");
+
+                    b.Property<int>("Status")
+                        .HasColumnType("integer")
+                        .HasColumnName("status");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("AccountId", "RelatedId")
+                        .HasName("pk_account_relationships");
+
+                    b.HasIndex("RelatedId")
+                        .HasDatabaseName("ix_account_relationships_related_id");
+
+                    b.ToTable("account_relationships", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Activity.Activity", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("ResourceIdentifier")
+                        .IsRequired()
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("resource_identifier");
+
+                    b.Property<string>("Type")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<int>("Visibility")
+                        .HasColumnType("integer")
+                        .HasColumnName("visibility");
+
+                    b.HasKey("Id")
+                        .HasName("pk_activities");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_activities_account_id");
+
+                    b.ToTable("activities", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Auth.Challenge", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<List<string>>("Audiences")
+                        .IsRequired()
+                        .HasColumnType("jsonb")
+                        .HasColumnName("audiences");
+
+                    b.Property<List<long>>("BlacklistFactors")
+                        .IsRequired()
+                        .HasColumnType("jsonb")
+                        .HasColumnName("blacklist_factors");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("DeviceId")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("device_id");
+
+                    b.Property<Instant?>("ExpiredAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("expired_at");
+
+                    b.Property<int>("FailedAttempts")
+                        .HasColumnType("integer")
+                        .HasColumnName("failed_attempts");
+
+                    b.Property<string>("IpAddress")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("ip_address");
+
+                    b.Property<string>("Nonce")
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("nonce");
+
+                    b.Property<int>("Platform")
+                        .HasColumnType("integer")
+                        .HasColumnName("platform");
+
+                    b.Property<List<string>>("Scopes")
+                        .IsRequired()
+                        .HasColumnType("jsonb")
+                        .HasColumnName("scopes");
+
+                    b.Property<int>("StepRemain")
+                        .HasColumnType("integer")
+                        .HasColumnName("step_remain");
+
+                    b.Property<int>("StepTotal")
+                        .HasColumnType("integer")
+                        .HasColumnName("step_total");
+
+                    b.Property<int>("Type")
+                        .HasColumnType("integer")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<string>("UserAgent")
+                        .HasMaxLength(512)
+                        .HasColumnType("character varying(512)")
+                        .HasColumnName("user_agent");
+
+                    b.HasKey("Id")
+                        .HasName("pk_auth_challenges");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_auth_challenges_account_id");
+
+                    b.ToTable("auth_challenges", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Auth.Session", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Guid>("ChallengeId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("challenge_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("ExpiredAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("expired_at");
+
+                    b.Property<string>("Label")
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("label");
+
+                    b.Property<Instant?>("LastGrantedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("last_granted_at");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_auth_sessions");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_auth_sessions_account_id");
+
+                    b.HasIndex("ChallengeId")
+                        .HasDatabaseName("ix_auth_sessions_challenge_id");
+
+                    b.ToTable("auth_sessions", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.ChatMember", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<long>("ChatRoomId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("chat_room_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<bool>("IsBot")
+                        .HasColumnType("boolean")
+                        .HasColumnName("is_bot");
+
+                    b.Property<Instant?>("JoinedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("joined_at");
+
+                    b.Property<string>("Nick")
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("nick");
+
+                    b.Property<int>("Notify")
+                        .HasColumnType("integer")
+                        .HasColumnName("notify");
+
+                    b.Property<int>("Role")
+                        .HasColumnType("integer")
+                        .HasColumnName("role");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_chat_members");
+
+                    b.HasAlternateKey("ChatRoomId", "AccountId")
+                        .HasName("ak_chat_members_chat_room_id_account_id");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_chat_members_account_id");
+
+                    b.ToTable("chat_members", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.ChatRoom", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<string>("BackgroundId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("background_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Description")
+                        .IsRequired()
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("description");
+
+                    b.Property<bool>("IsPublic")
+                        .HasColumnType("boolean")
+                        .HasColumnName("is_public");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("name");
+
+                    b.Property<string>("PictureId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("picture_id");
+
+                    b.Property<long?>("RealmId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("realm_id");
+
+                    b.Property<int>("Type")
+                        .HasColumnType("integer")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_chat_rooms");
+
+                    b.HasIndex("BackgroundId")
+                        .HasDatabaseName("ix_chat_rooms_background_id");
+
+                    b.HasIndex("PictureId")
+                        .HasDatabaseName("ix_chat_rooms_picture_id");
+
+                    b.HasIndex("RealmId")
+                        .HasDatabaseName("ix_chat_rooms_realm_id");
+
+                    b.ToTable("chat_rooms", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.Message", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long>("ChatRoomId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("chat_room_id");
+
+                    b.Property<string>("Content")
+                        .IsRequired()
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("content");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("EditedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("edited_at");
+
+                    b.Property<Guid?>("ForwardedMessageId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("forwarded_message_id");
+
+                    b.Property<List<Guid>>("MembersMentioned")
+                        .HasColumnType("jsonb")
+                        .HasColumnName("members_mentioned");
+
+                    b.Property<Dictionary<string, object>>("Meta")
+                        .HasColumnType("jsonb")
+                        .HasColumnName("meta");
+
+                    b.Property<string>("Nonce")
+                        .IsRequired()
+                        .HasColumnType("text")
+                        .HasColumnName("nonce");
+
+                    b.Property<Guid?>("RepliedMessageId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("replied_message_id");
+
+                    b.Property<Guid>("SenderId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("sender_id");
+
+                    b.Property<string>("Type")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_chat_messages");
+
+                    b.HasIndex("ChatRoomId")
+                        .HasDatabaseName("ix_chat_messages_chat_room_id");
+
+                    b.HasIndex("ForwardedMessageId")
+                        .HasDatabaseName("ix_chat_messages_forwarded_message_id");
+
+                    b.HasIndex("RepliedMessageId")
+                        .HasDatabaseName("ix_chat_messages_replied_message_id");
+
+                    b.HasIndex("SenderId")
+                        .HasDatabaseName("ix_chat_messages_sender_id");
+
+                    b.ToTable("chat_messages", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.MessageReaction", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<int>("Attitude")
+                        .HasColumnType("integer")
+                        .HasColumnName("attitude");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Guid>("MessageId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("message_id");
+
+                    b.Property<Guid>("SenderId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("sender_id");
+
+                    b.Property<string>("Symbol")
+                        .IsRequired()
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("symbol");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_message_reaction");
+
+                    b.HasIndex("MessageId")
+                        .HasDatabaseName("ix_message_reaction_message_id");
+
+                    b.HasIndex("SenderId")
+                        .HasDatabaseName("ix_message_reaction_sender_id");
+
+                    b.ToTable("message_reaction", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.MessageStatus", b =>
+                {
+                    b.Property<Guid>("MessageId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("message_id");
+
+                    b.Property<Guid>("SenderId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("sender_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant>("ReadAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("read_at");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("MessageId", "SenderId")
+                        .HasName("pk_chat_statuses");
+
+                    b.HasIndex("SenderId")
+                        .HasDatabaseName("ix_chat_statuses_sender_id");
+
+                    b.ToTable("chat_statuses", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Permission.PermissionGroup", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Key")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("key");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_permission_groups");
+
+                    b.ToTable("permission_groups", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Permission.PermissionGroupMember", b =>
+                {
+                    b.Property<Guid>("GroupId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("group_id");
+
+                    b.Property<string>("Actor")
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("actor");
+
+                    b.Property<Instant?>("AffectedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("affected_at");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("ExpiredAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("expired_at");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("GroupId", "Actor")
+                        .HasName("pk_permission_group_members");
+
+                    b.ToTable("permission_group_members", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Permission.PermissionNode", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<string>("Actor")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("actor");
+
+                    b.Property<Instant?>("AffectedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("affected_at");
+
+                    b.Property<string>("Area")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("area");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("ExpiredAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("expired_at");
+
+                    b.Property<Guid?>("GroupId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("group_id");
+
+                    b.Property<string>("Key")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("key");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<JsonDocument>("Value")
+                        .IsRequired()
+                        .HasColumnType("jsonb")
+                        .HasColumnName("value");
+
+                    b.HasKey("Id")
+                        .HasName("pk_permission_nodes");
+
+                    b.HasIndex("GroupId")
+                        .HasDatabaseName("ix_permission_nodes_group_id");
+
+                    b.HasIndex("Key", "Area", "Actor")
+                        .HasDatabaseName("ix_permission_nodes_key_area_actor");
+
+                    b.ToTable("permission_nodes", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.Post", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<JsonDocument>("Content")
+                        .HasColumnType("jsonb")
+                        .HasColumnName("content");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Description")
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("description");
+
+                    b.Property<int>("Downvotes")
+                        .HasColumnType("integer")
+                        .HasColumnName("downvotes");
+
+                    b.Property<Instant?>("EditedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("edited_at");
+
+                    b.Property<long?>("ForwardedPostId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("forwarded_post_id");
+
+                    b.Property<string>("Language")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("language");
+
+                    b.Property<Dictionary<string, object>>("Meta")
+                        .HasColumnType("jsonb")
+                        .HasColumnName("meta");
+
+                    b.Property<Instant?>("PublishedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("published_at");
+
+                    b.Property<long>("PublisherId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("publisher_id");
+
+                    b.Property<long?>("RepliedPostId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("replied_post_id");
+
+                    b.Property<NpgsqlTsVector>("SearchVector")
+                        .HasColumnType("tsvector")
+                        .HasColumnName("search_vector");
+
+                    b.Property<long?>("ThreadedPostId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("threaded_post_id");
+
+                    b.Property<string>("Title")
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("title");
+
+                    b.Property<int>("Type")
+                        .HasColumnType("integer")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<int>("Upvotes")
+                        .HasColumnType("integer")
+                        .HasColumnName("upvotes");
+
+                    b.Property<int>("ViewsTotal")
+                        .HasColumnType("integer")
+                        .HasColumnName("views_total");
+
+                    b.Property<int>("ViewsUnique")
+                        .HasColumnType("integer")
+                        .HasColumnName("views_unique");
+
+                    b.Property<int>("Visibility")
+                        .HasColumnType("integer")
+                        .HasColumnName("visibility");
+
+                    b.HasKey("Id")
+                        .HasName("pk_posts");
+
+                    b.HasIndex("ForwardedPostId")
+                        .HasDatabaseName("ix_posts_forwarded_post_id");
+
+                    b.HasIndex("PublisherId")
+                        .HasDatabaseName("ix_posts_publisher_id");
+
+                    b.HasIndex("RepliedPostId")
+                        .HasDatabaseName("ix_posts_replied_post_id");
+
+                    b.HasIndex("SearchVector")
+                        .HasDatabaseName("ix_posts_search_vector");
+
+                    NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("SearchVector"), "GIN");
+
+                    b.HasIndex("ThreadedPostId")
+                        .IsUnique()
+                        .HasDatabaseName("ix_posts_threaded_post_id");
+
+                    b.ToTable("posts", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PostCategory", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Name")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("name");
+
+                    b.Property<string>("Slug")
+                        .IsRequired()
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("slug");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_post_categories");
+
+                    b.ToTable("post_categories", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PostCollection", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Description")
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("description");
+
+                    b.Property<string>("Name")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("name");
+
+                    b.Property<long>("PublisherId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("publisher_id");
+
+                    b.Property<string>("Slug")
+                        .IsRequired()
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("slug");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_post_collections");
+
+                    b.HasIndex("PublisherId")
+                        .HasDatabaseName("ix_post_collections_publisher_id");
+
+                    b.ToTable("post_collections", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PostReaction", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<int>("Attitude")
+                        .HasColumnType("integer")
+                        .HasColumnName("attitude");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<long>("PostId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("post_id");
+
+                    b.Property<string>("Symbol")
+                        .IsRequired()
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("symbol");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_post_reactions");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_post_reactions_account_id");
+
+                    b.HasIndex("PostId")
+                        .HasDatabaseName("ix_post_reactions_post_id");
+
+                    b.ToTable("post_reactions", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PostTag", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Name")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("name");
+
+                    b.Property<string>("Slug")
+                        .IsRequired()
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("slug");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_post_tags");
+
+                    b.ToTable("post_tags", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.Publisher", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<long?>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<string>("BackgroundId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("background_id");
+
+                    b.Property<string>("Bio")
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("bio");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("name");
+
+                    b.Property<string>("Nick")
+                        .IsRequired()
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("nick");
+
+                    b.Property<string>("PictureId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("picture_id");
+
+                    b.Property<int>("PublisherType")
+                        .HasColumnType("integer")
+                        .HasColumnName("publisher_type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_publishers");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_publishers_account_id");
+
+                    b.HasIndex("BackgroundId")
+                        .HasDatabaseName("ix_publishers_background_id");
+
+                    b.HasIndex("Name")
+                        .IsUnique()
+                        .HasDatabaseName("ix_publishers_name");
+
+                    b.HasIndex("PictureId")
+                        .HasDatabaseName("ix_publishers_picture_id");
+
+                    b.ToTable("publishers", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PublisherMember", b =>
+                {
+                    b.Property<long>("PublisherId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("publisher_id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("JoinedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("joined_at");
+
+                    b.Property<int>("Role")
+                        .HasColumnType("integer")
+                        .HasColumnName("role");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("PublisherId", "AccountId")
+                        .HasName("pk_publisher_members");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_publisher_members_account_id");
+
+                    b.ToTable("publisher_members", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Realm.Realm", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<string>("BackgroundId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("background_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Description")
+                        .IsRequired()
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("description");
+
+                    b.Property<bool>("IsCommunity")
+                        .HasColumnType("boolean")
+                        .HasColumnName("is_community");
+
+                    b.Property<bool>("IsPublic")
+                        .HasColumnType("boolean")
+                        .HasColumnName("is_public");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("name");
+
+                    b.Property<string>("PictureId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("picture_id");
+
+                    b.Property<string>("Slug")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("slug");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<string>("VerifiedAs")
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("verified_as");
+
+                    b.Property<Instant?>("VerifiedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("verified_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_realms");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_realms_account_id");
+
+                    b.HasIndex("BackgroundId")
+                        .HasDatabaseName("ix_realms_background_id");
+
+                    b.HasIndex("PictureId")
+                        .HasDatabaseName("ix_realms_picture_id");
+
+                    b.HasIndex("Slug")
+                        .IsUnique()
+                        .HasDatabaseName("ix_realms_slug");
+
+                    b.ToTable("realms", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Realm.RealmMember", b =>
+                {
+                    b.Property<long>("RealmId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("realm_id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("JoinedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("joined_at");
+
+                    b.Property<int>("Role")
+                        .HasColumnType("integer")
+                        .HasColumnName("role");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("RealmId", "AccountId")
+                        .HasName("pk_realm_members");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_realm_members_account_id");
+
+                    b.ToTable("realm_members", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Storage.CloudFile", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Description")
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("description");
+
+                    b.Property<Instant?>("ExpiredAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("expired_at");
+
+                    b.Property<Dictionary<string, object>>("FileMeta")
+                        .HasColumnType("jsonb")
+                        .HasColumnName("file_meta");
+
+                    b.Property<bool>("HasCompression")
+                        .HasColumnType("boolean")
+                        .HasColumnName("has_compression");
+
+                    b.Property<string>("Hash")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("hash");
+
+                    b.Property<Guid?>("MessageId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("message_id");
+
+                    b.Property<string>("MimeType")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("mime_type");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("name");
+
+                    b.Property<long?>("PostId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("post_id");
+
+                    b.Property<long>("Size")
+                        .HasColumnType("bigint")
+                        .HasColumnName("size");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<Instant?>("UploadedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("uploaded_at");
+
+                    b.Property<string>("UploadedTo")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("uploaded_to");
+
+                    b.Property<int>("UsedCount")
+                        .HasColumnType("integer")
+                        .HasColumnName("used_count");
+
+                    b.Property<Dictionary<string, object>>("UserMeta")
+                        .HasColumnType("jsonb")
+                        .HasColumnName("user_meta");
+
+                    b.HasKey("Id")
+                        .HasName("pk_files");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_files_account_id");
+
+                    b.HasIndex("MessageId")
+                        .HasDatabaseName("ix_files_message_id");
+
+                    b.HasIndex("PostId")
+                        .HasDatabaseName("ix_files_post_id");
+
+                    b.ToTable("files", (string)null);
+                });
+
+            modelBuilder.Entity("PostPostCategory", b =>
+                {
+                    b.Property<long>("CategoriesId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("categories_id");
+
+                    b.Property<long>("PostsId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("posts_id");
+
+                    b.HasKey("CategoriesId", "PostsId")
+                        .HasName("pk_post_category_links");
+
+                    b.HasIndex("PostsId")
+                        .HasDatabaseName("ix_post_category_links_posts_id");
+
+                    b.ToTable("post_category_links", (string)null);
+                });
+
+            modelBuilder.Entity("PostPostCollection", b =>
+                {
+                    b.Property<long>("CollectionsId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("collections_id");
+
+                    b.Property<long>("PostsId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("posts_id");
+
+                    b.HasKey("CollectionsId", "PostsId")
+                        .HasName("pk_post_collection_links");
+
+                    b.HasIndex("PostsId")
+                        .HasDatabaseName("ix_post_collection_links_posts_id");
+
+                    b.ToTable("post_collection_links", (string)null);
+                });
+
+            modelBuilder.Entity("PostPostTag", b =>
+                {
+                    b.Property<long>("PostsId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("posts_id");
+
+                    b.Property<long>("TagsId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("tags_id");
+
+                    b.HasKey("PostsId", "TagsId")
+                        .HasName("pk_post_tag_links");
+
+                    b.HasIndex("TagsId")
+                        .HasDatabaseName("ix_post_tag_links_tags_id");
+
+                    b.ToTable("post_tag_links", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.AccountAuthFactor", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany("AuthFactors")
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_account_auth_factors_accounts_account_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.AccountContact", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany("Contacts")
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_account_contacts_accounts_account_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.MagicSpell", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .HasConstraintName("fk_magic_spells_accounts_account_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Notification", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_notifications_accounts_account_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.NotificationPushSubscription", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_notification_push_subscriptions_accounts_account_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Profile", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Background")
+                        .WithMany()
+                        .HasForeignKey("BackgroundId")
+                        .HasConstraintName("fk_account_profiles_files_background_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithOne("Profile")
+                        .HasForeignKey("DysonNetwork.Sphere.Account.Profile", "Id")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_account_profiles_accounts_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Picture")
+                        .WithMany()
+                        .HasForeignKey("PictureId")
+                        .HasConstraintName("fk_account_profiles_files_picture_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Background");
+
+                    b.Navigation("Picture");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Relationship", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany("OutgoingRelationships")
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_account_relationships_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Related")
+                        .WithMany("IncomingRelationships")
+                        .HasForeignKey("RelatedId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_account_relationships_accounts_related_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Related");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Activity.Activity", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_activities_accounts_account_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Auth.Challenge", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany("Challenges")
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_auth_challenges_accounts_account_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Auth.Session", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany("Sessions")
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_auth_sessions_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Auth.Challenge", "Challenge")
+                        .WithMany()
+                        .HasForeignKey("ChallengeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_auth_sessions_auth_challenges_challenge_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Challenge");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.ChatMember", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_chat_members_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Chat.ChatRoom", "ChatRoom")
+                        .WithMany("Members")
+                        .HasForeignKey("ChatRoomId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_chat_members_chat_rooms_chat_room_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("ChatRoom");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.ChatRoom", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Background")
+                        .WithMany()
+                        .HasForeignKey("BackgroundId")
+                        .HasConstraintName("fk_chat_rooms_files_background_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Picture")
+                        .WithMany()
+                        .HasForeignKey("PictureId")
+                        .HasConstraintName("fk_chat_rooms_files_picture_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Realm.Realm", "Realm")
+                        .WithMany("ChatRooms")
+                        .HasForeignKey("RealmId")
+                        .HasConstraintName("fk_chat_rooms_realms_realm_id");
+
+                    b.Navigation("Background");
+
+                    b.Navigation("Picture");
+
+                    b.Navigation("Realm");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.Message", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Chat.ChatRoom", "ChatRoom")
+                        .WithMany()
+                        .HasForeignKey("ChatRoomId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_chat_messages_chat_rooms_chat_room_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Chat.Message", "ForwardedMessage")
+                        .WithMany()
+                        .HasForeignKey("ForwardedMessageId")
+                        .OnDelete(DeleteBehavior.Restrict)
+                        .HasConstraintName("fk_chat_messages_chat_messages_forwarded_message_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Chat.Message", "RepliedMessage")
+                        .WithMany()
+                        .HasForeignKey("RepliedMessageId")
+                        .OnDelete(DeleteBehavior.Restrict)
+                        .HasConstraintName("fk_chat_messages_chat_messages_replied_message_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Chat.ChatMember", "Sender")
+                        .WithMany()
+                        .HasForeignKey("SenderId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_chat_messages_chat_members_sender_id");
+
+                    b.Navigation("ChatRoom");
+
+                    b.Navigation("ForwardedMessage");
+
+                    b.Navigation("RepliedMessage");
+
+                    b.Navigation("Sender");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.MessageReaction", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Chat.Message", "Message")
+                        .WithMany("Reactions")
+                        .HasForeignKey("MessageId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_message_reaction_chat_messages_message_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Chat.ChatMember", "Sender")
+                        .WithMany()
+                        .HasForeignKey("SenderId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_message_reaction_chat_members_sender_id");
+
+                    b.Navigation("Message");
+
+                    b.Navigation("Sender");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.MessageStatus", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Chat.Message", "Message")
+                        .WithMany("Statuses")
+                        .HasForeignKey("MessageId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_chat_statuses_chat_messages_message_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Chat.ChatMember", "Sender")
+                        .WithMany()
+                        .HasForeignKey("SenderId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_chat_statuses_chat_members_sender_id");
+
+                    b.Navigation("Message");
+
+                    b.Navigation("Sender");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Permission.PermissionGroupMember", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Permission.PermissionGroup", "Group")
+                        .WithMany("Members")
+                        .HasForeignKey("GroupId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_permission_group_members_permission_groups_group_id");
+
+                    b.Navigation("Group");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Permission.PermissionNode", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Permission.PermissionGroup", "Group")
+                        .WithMany("Nodes")
+                        .HasForeignKey("GroupId")
+                        .HasConstraintName("fk_permission_nodes_permission_groups_group_id");
+
+                    b.Navigation("Group");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.Post", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", "ForwardedPost")
+                        .WithMany()
+                        .HasForeignKey("ForwardedPostId")
+                        .OnDelete(DeleteBehavior.Restrict)
+                        .HasConstraintName("fk_posts_posts_forwarded_post_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Publisher", "Publisher")
+                        .WithMany("Posts")
+                        .HasForeignKey("PublisherId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_posts_publishers_publisher_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", "RepliedPost")
+                        .WithMany()
+                        .HasForeignKey("RepliedPostId")
+                        .OnDelete(DeleteBehavior.Restrict)
+                        .HasConstraintName("fk_posts_posts_replied_post_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", "ThreadedPost")
+                        .WithOne()
+                        .HasForeignKey("DysonNetwork.Sphere.Post.Post", "ThreadedPostId")
+                        .HasConstraintName("fk_posts_posts_threaded_post_id");
+
+                    b.Navigation("ForwardedPost");
+
+                    b.Navigation("Publisher");
+
+                    b.Navigation("RepliedPost");
+
+                    b.Navigation("ThreadedPost");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PostCollection", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Post.Publisher", "Publisher")
+                        .WithMany("Collections")
+                        .HasForeignKey("PublisherId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_collections_publishers_publisher_id");
+
+                    b.Navigation("Publisher");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PostReaction", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_reactions_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", "Post")
+                        .WithMany("Reactions")
+                        .HasForeignKey("PostId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_reactions_posts_post_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Post");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.Publisher", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .HasConstraintName("fk_publishers_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Background")
+                        .WithMany()
+                        .HasForeignKey("BackgroundId")
+                        .HasConstraintName("fk_publishers_files_background_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Picture")
+                        .WithMany()
+                        .HasForeignKey("PictureId")
+                        .HasConstraintName("fk_publishers_files_picture_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Background");
+
+                    b.Navigation("Picture");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PublisherMember", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_publisher_members_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Publisher", "Publisher")
+                        .WithMany("Members")
+                        .HasForeignKey("PublisherId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_publisher_members_publishers_publisher_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Publisher");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Realm.Realm", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_realms_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Background")
+                        .WithMany()
+                        .HasForeignKey("BackgroundId")
+                        .HasConstraintName("fk_realms_files_background_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Picture")
+                        .WithMany()
+                        .HasForeignKey("PictureId")
+                        .HasConstraintName("fk_realms_files_picture_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Background");
+
+                    b.Navigation("Picture");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Realm.RealmMember", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_realm_members_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Realm.Realm", "Realm")
+                        .WithMany("Members")
+                        .HasForeignKey("RealmId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_realm_members_realms_realm_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Realm");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Storage.CloudFile", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_files_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Chat.Message", null)
+                        .WithMany("Attachments")
+                        .HasForeignKey("MessageId")
+                        .HasConstraintName("fk_files_chat_messages_message_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", null)
+                        .WithMany("Attachments")
+                        .HasForeignKey("PostId")
+                        .HasConstraintName("fk_files_posts_post_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("PostPostCategory", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Post.PostCategory", null)
+                        .WithMany()
+                        .HasForeignKey("CategoriesId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_category_links_post_categories_categories_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", null)
+                        .WithMany()
+                        .HasForeignKey("PostsId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_category_links_posts_posts_id");
+                });
+
+            modelBuilder.Entity("PostPostCollection", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Post.PostCollection", null)
+                        .WithMany()
+                        .HasForeignKey("CollectionsId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_collection_links_post_collections_collections_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", null)
+                        .WithMany()
+                        .HasForeignKey("PostsId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_collection_links_posts_posts_id");
+                });
+
+            modelBuilder.Entity("PostPostTag", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", null)
+                        .WithMany()
+                        .HasForeignKey("PostsId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_tag_links_posts_posts_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.PostTag", null)
+                        .WithMany()
+                        .HasForeignKey("TagsId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_tag_links_post_tags_tags_id");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Account", b =>
+                {
+                    b.Navigation("AuthFactors");
+
+                    b.Navigation("Challenges");
+
+                    b.Navigation("Contacts");
+
+                    b.Navigation("IncomingRelationships");
+
+                    b.Navigation("OutgoingRelationships");
+
+                    b.Navigation("Profile")
+                        .IsRequired();
+
+                    b.Navigation("Sessions");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.ChatRoom", b =>
+                {
+                    b.Navigation("Members");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.Message", b =>
+                {
+                    b.Navigation("Attachments");
+
+                    b.Navigation("Reactions");
+
+                    b.Navigation("Statuses");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Permission.PermissionGroup", b =>
+                {
+                    b.Navigation("Members");
+
+                    b.Navigation("Nodes");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.Post", b =>
+                {
+                    b.Navigation("Attachments");
+
+                    b.Navigation("Reactions");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.Publisher", b =>
+                {
+                    b.Navigation("Collections");
+
+                    b.Navigation("Members");
+
+                    b.Navigation("Posts");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Realm.Realm", b =>
+                {
+                    b.Navigation("ChatRooms");
+
+                    b.Navigation("Members");
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}
diff --git a/DysonNetwork.Sphere/Migrations/20250503032932_AddChatMessageNonce.cs b/DysonNetwork.Sphere/Migrations/20250503032932_AddChatMessageNonce.cs
new file mode 100644
index 0000000..6ed6661
--- /dev/null
+++ b/DysonNetwork.Sphere/Migrations/20250503032932_AddChatMessageNonce.cs
@@ -0,0 +1,39 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace DysonNetwork.Sphere.Migrations
+{
+    /// <inheritdoc />
+    public partial class AddChatMessageNonce : Migration
+    {
+        /// <inheritdoc />
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.RenameColumn(
+                name: "members_metioned",
+                table: "chat_messages",
+                newName: "members_mentioned");
+
+            migrationBuilder.AddColumn<string>(
+                name: "nonce",
+                table: "chat_messages",
+                type: "text",
+                nullable: false,
+                defaultValue: "");
+        }
+
+        /// <inheritdoc />
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropColumn(
+                name: "nonce",
+                table: "chat_messages");
+
+            migrationBuilder.RenameColumn(
+                name: "members_mentioned",
+                table: "chat_messages",
+                newName: "members_metioned");
+        }
+    }
+}
diff --git a/DysonNetwork.Sphere/Migrations/20250503040922_DontKnowHowToNameThing2.Designer.cs b/DysonNetwork.Sphere/Migrations/20250503040922_DontKnowHowToNameThing2.Designer.cs
new file mode 100644
index 0000000..037d0dc
--- /dev/null
+++ b/DysonNetwork.Sphere/Migrations/20250503040922_DontKnowHowToNameThing2.Designer.cs
@@ -0,0 +1,2359 @@
+// <auto-generated />
+using System;
+using System.Collections.Generic;
+using System.Text.Json;
+using DysonNetwork.Sphere;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using NodaTime;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using NpgsqlTypes;
+
+#nullable disable
+
+namespace DysonNetwork.Sphere.Migrations
+{
+    [DbContext(typeof(AppDatabase))]
+    [Migration("20250503040922_DontKnowHowToNameThing2")]
+    partial class DontKnowHowToNameThing2
+    {
+        /// <inheritdoc />
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("ProductVersion", "9.0.3")
+                .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+            NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Account", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<Instant?>("ActivatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("activated_at");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<bool>("IsSuperuser")
+                        .HasColumnType("boolean")
+                        .HasColumnName("is_superuser");
+
+                    b.Property<string>("Language")
+                        .IsRequired()
+                        .HasMaxLength(32)
+                        .HasColumnType("character varying(32)")
+                        .HasColumnName("language");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("name");
+
+                    b.Property<string>("Nick")
+                        .IsRequired()
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("nick");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_accounts");
+
+                    b.HasIndex("Name")
+                        .IsUnique()
+                        .HasDatabaseName("ix_accounts_name");
+
+                    b.ToTable("accounts", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.AccountAuthFactor", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Secret")
+                        .HasColumnType("text")
+                        .HasColumnName("secret");
+
+                    b.Property<int>("Type")
+                        .HasColumnType("integer")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_account_auth_factors");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_account_auth_factors_account_id");
+
+                    b.ToTable("account_auth_factors", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.AccountContact", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<string>("Content")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("content");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<int>("Type")
+                        .HasColumnType("integer")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<Instant?>("VerifiedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("verified_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_account_contacts");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_account_contacts_account_id");
+
+                    b.ToTable("account_contacts", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.MagicSpell", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long?>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Instant?>("AffectedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("affected_at");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("ExpiresAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("expires_at");
+
+                    b.Property<Dictionary<string, object>>("Meta")
+                        .IsRequired()
+                        .HasColumnType("jsonb")
+                        .HasColumnName("meta");
+
+                    b.Property<string>("Spell")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("spell");
+
+                    b.Property<int>("Type")
+                        .HasColumnType("integer")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_magic_spells");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_magic_spells_account_id");
+
+                    b.HasIndex("Spell")
+                        .IsUnique()
+                        .HasDatabaseName("ix_magic_spells_spell");
+
+                    b.ToTable("magic_spells", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Notification", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("content");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Dictionary<string, object>>("Meta")
+                        .HasColumnType("jsonb")
+                        .HasColumnName("meta");
+
+                    b.Property<int>("Priority")
+                        .HasColumnType("integer")
+                        .HasColumnName("priority");
+
+                    b.Property<string>("Subtitle")
+                        .HasMaxLength(2048)
+                        .HasColumnType("character varying(2048)")
+                        .HasColumnName("subtitle");
+
+                    b.Property<string>("Title")
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("title");
+
+                    b.Property<string>("Topic")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("topic");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<Instant?>("ViewedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("viewed_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_notifications");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_notifications_account_id");
+
+                    b.ToTable("notifications", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.NotificationPushSubscription", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("DeviceId")
+                        .IsRequired()
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("device_id");
+
+                    b.Property<string>("DeviceToken")
+                        .IsRequired()
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("device_token");
+
+                    b.Property<Instant?>("LastUsedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("last_used_at");
+
+                    b.Property<int>("Provider")
+                        .HasColumnType("integer")
+                        .HasColumnName("provider");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_notification_push_subscriptions");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_notification_push_subscriptions_account_id");
+
+                    b.HasIndex("DeviceId")
+                        .IsUnique()
+                        .HasDatabaseName("ix_notification_push_subscriptions_device_id");
+
+                    b.HasIndex("DeviceToken")
+                        .IsUnique()
+                        .HasDatabaseName("ix_notification_push_subscriptions_device_token");
+
+                    b.ToTable("notification_push_subscriptions", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Profile", b =>
+                {
+                    b.Property<long>("Id")
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    b.Property<string>("BackgroundId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("background_id");
+
+                    b.Property<string>("Bio")
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("bio");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("FirstName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("first_name");
+
+                    b.Property<string>("LastName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("last_name");
+
+                    b.Property<string>("MiddleName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("middle_name");
+
+                    b.Property<string>("PictureId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("picture_id");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_account_profiles");
+
+                    b.HasIndex("BackgroundId")
+                        .HasDatabaseName("ix_account_profiles_background_id");
+
+                    b.HasIndex("PictureId")
+                        .HasDatabaseName("ix_account_profiles_picture_id");
+
+                    b.ToTable("account_profiles", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Relationship", b =>
+                {
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<long>("RelatedId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("related_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("ExpiredAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("expired_at");
+
+                    b.Property<int>("Status")
+                        .HasColumnType("integer")
+                        .HasColumnName("status");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("AccountId", "RelatedId")
+                        .HasName("pk_account_relationships");
+
+                    b.HasIndex("RelatedId")
+                        .HasDatabaseName("ix_account_relationships_related_id");
+
+                    b.ToTable("account_relationships", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Activity.Activity", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("ResourceIdentifier")
+                        .IsRequired()
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("resource_identifier");
+
+                    b.Property<string>("Type")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<int>("Visibility")
+                        .HasColumnType("integer")
+                        .HasColumnName("visibility");
+
+                    b.HasKey("Id")
+                        .HasName("pk_activities");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_activities_account_id");
+
+                    b.ToTable("activities", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Auth.Challenge", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<List<string>>("Audiences")
+                        .IsRequired()
+                        .HasColumnType("jsonb")
+                        .HasColumnName("audiences");
+
+                    b.Property<List<long>>("BlacklistFactors")
+                        .IsRequired()
+                        .HasColumnType("jsonb")
+                        .HasColumnName("blacklist_factors");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("DeviceId")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("device_id");
+
+                    b.Property<Instant?>("ExpiredAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("expired_at");
+
+                    b.Property<int>("FailedAttempts")
+                        .HasColumnType("integer")
+                        .HasColumnName("failed_attempts");
+
+                    b.Property<string>("IpAddress")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("ip_address");
+
+                    b.Property<string>("Nonce")
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("nonce");
+
+                    b.Property<int>("Platform")
+                        .HasColumnType("integer")
+                        .HasColumnName("platform");
+
+                    b.Property<List<string>>("Scopes")
+                        .IsRequired()
+                        .HasColumnType("jsonb")
+                        .HasColumnName("scopes");
+
+                    b.Property<int>("StepRemain")
+                        .HasColumnType("integer")
+                        .HasColumnName("step_remain");
+
+                    b.Property<int>("StepTotal")
+                        .HasColumnType("integer")
+                        .HasColumnName("step_total");
+
+                    b.Property<int>("Type")
+                        .HasColumnType("integer")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<string>("UserAgent")
+                        .HasMaxLength(512)
+                        .HasColumnType("character varying(512)")
+                        .HasColumnName("user_agent");
+
+                    b.HasKey("Id")
+                        .HasName("pk_auth_challenges");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_auth_challenges_account_id");
+
+                    b.ToTable("auth_challenges", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Auth.Session", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Guid>("ChallengeId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("challenge_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("ExpiredAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("expired_at");
+
+                    b.Property<string>("Label")
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("label");
+
+                    b.Property<Instant?>("LastGrantedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("last_granted_at");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_auth_sessions");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_auth_sessions_account_id");
+
+                    b.HasIndex("ChallengeId")
+                        .HasDatabaseName("ix_auth_sessions_challenge_id");
+
+                    b.ToTable("auth_sessions", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.ChatMember", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<long>("ChatRoomId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("chat_room_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<bool>("IsBot")
+                        .HasColumnType("boolean")
+                        .HasColumnName("is_bot");
+
+                    b.Property<Instant?>("JoinedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("joined_at");
+
+                    b.Property<string>("Nick")
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("nick");
+
+                    b.Property<int>("Notify")
+                        .HasColumnType("integer")
+                        .HasColumnName("notify");
+
+                    b.Property<int>("Role")
+                        .HasColumnType("integer")
+                        .HasColumnName("role");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_chat_members");
+
+                    b.HasAlternateKey("ChatRoomId", "AccountId")
+                        .HasName("ak_chat_members_chat_room_id_account_id");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_chat_members_account_id");
+
+                    b.ToTable("chat_members", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.ChatRoom", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<string>("BackgroundId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("background_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Description")
+                        .IsRequired()
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("description");
+
+                    b.Property<bool>("IsPublic")
+                        .HasColumnType("boolean")
+                        .HasColumnName("is_public");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("name");
+
+                    b.Property<string>("PictureId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("picture_id");
+
+                    b.Property<long?>("RealmId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("realm_id");
+
+                    b.Property<int>("Type")
+                        .HasColumnType("integer")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_chat_rooms");
+
+                    b.HasIndex("BackgroundId")
+                        .HasDatabaseName("ix_chat_rooms_background_id");
+
+                    b.HasIndex("PictureId")
+                        .HasDatabaseName("ix_chat_rooms_picture_id");
+
+                    b.HasIndex("RealmId")
+                        .HasDatabaseName("ix_chat_rooms_realm_id");
+
+                    b.ToTable("chat_rooms", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.Message", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<long>("ChatRoomId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("chat_room_id");
+
+                    b.Property<string>("Content")
+                        .IsRequired()
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("content");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("EditedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("edited_at");
+
+                    b.Property<Guid?>("ForwardedMessageId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("forwarded_message_id");
+
+                    b.Property<List<Guid>>("MembersMentioned")
+                        .HasColumnType("jsonb")
+                        .HasColumnName("members_mentioned");
+
+                    b.Property<Dictionary<string, object>>("Meta")
+                        .HasColumnType("jsonb")
+                        .HasColumnName("meta");
+
+                    b.Property<string>("Nonce")
+                        .IsRequired()
+                        .HasMaxLength(36)
+                        .HasColumnType("character varying(36)")
+                        .HasColumnName("nonce");
+
+                    b.Property<Guid?>("RepliedMessageId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("replied_message_id");
+
+                    b.Property<Guid>("SenderId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("sender_id");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_chat_messages");
+
+                    b.HasIndex("ChatRoomId")
+                        .HasDatabaseName("ix_chat_messages_chat_room_id");
+
+                    b.HasIndex("ForwardedMessageId")
+                        .HasDatabaseName("ix_chat_messages_forwarded_message_id");
+
+                    b.HasIndex("RepliedMessageId")
+                        .HasDatabaseName("ix_chat_messages_replied_message_id");
+
+                    b.HasIndex("SenderId")
+                        .HasDatabaseName("ix_chat_messages_sender_id");
+
+                    b.ToTable("chat_messages", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.MessageReaction", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<int>("Attitude")
+                        .HasColumnType("integer")
+                        .HasColumnName("attitude");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Guid>("MessageId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("message_id");
+
+                    b.Property<Guid>("SenderId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("sender_id");
+
+                    b.Property<string>("Symbol")
+                        .IsRequired()
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("symbol");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_message_reaction");
+
+                    b.HasIndex("MessageId")
+                        .HasDatabaseName("ix_message_reaction_message_id");
+
+                    b.HasIndex("SenderId")
+                        .HasDatabaseName("ix_message_reaction_sender_id");
+
+                    b.ToTable("message_reaction", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.MessageStatus", b =>
+                {
+                    b.Property<Guid>("MessageId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("message_id");
+
+                    b.Property<Guid>("SenderId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("sender_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant>("ReadAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("read_at");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("MessageId", "SenderId")
+                        .HasName("pk_chat_statuses");
+
+                    b.HasIndex("SenderId")
+                        .HasDatabaseName("ix_chat_statuses_sender_id");
+
+                    b.ToTable("chat_statuses", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Permission.PermissionGroup", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Key")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("key");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_permission_groups");
+
+                    b.ToTable("permission_groups", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Permission.PermissionGroupMember", b =>
+                {
+                    b.Property<Guid>("GroupId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("group_id");
+
+                    b.Property<string>("Actor")
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("actor");
+
+                    b.Property<Instant?>("AffectedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("affected_at");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("ExpiredAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("expired_at");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("GroupId", "Actor")
+                        .HasName("pk_permission_group_members");
+
+                    b.ToTable("permission_group_members", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Permission.PermissionNode", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("id");
+
+                    b.Property<string>("Actor")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("actor");
+
+                    b.Property<Instant?>("AffectedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("affected_at");
+
+                    b.Property<string>("Area")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("area");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("ExpiredAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("expired_at");
+
+                    b.Property<Guid?>("GroupId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("group_id");
+
+                    b.Property<string>("Key")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("key");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<JsonDocument>("Value")
+                        .IsRequired()
+                        .HasColumnType("jsonb")
+                        .HasColumnName("value");
+
+                    b.HasKey("Id")
+                        .HasName("pk_permission_nodes");
+
+                    b.HasIndex("GroupId")
+                        .HasDatabaseName("ix_permission_nodes_group_id");
+
+                    b.HasIndex("Key", "Area", "Actor")
+                        .HasDatabaseName("ix_permission_nodes_key_area_actor");
+
+                    b.ToTable("permission_nodes", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.Post", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<JsonDocument>("Content")
+                        .HasColumnType("jsonb")
+                        .HasColumnName("content");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Description")
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("description");
+
+                    b.Property<int>("Downvotes")
+                        .HasColumnType("integer")
+                        .HasColumnName("downvotes");
+
+                    b.Property<Instant?>("EditedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("edited_at");
+
+                    b.Property<long?>("ForwardedPostId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("forwarded_post_id");
+
+                    b.Property<string>("Language")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("language");
+
+                    b.Property<Dictionary<string, object>>("Meta")
+                        .HasColumnType("jsonb")
+                        .HasColumnName("meta");
+
+                    b.Property<Instant?>("PublishedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("published_at");
+
+                    b.Property<long>("PublisherId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("publisher_id");
+
+                    b.Property<long?>("RepliedPostId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("replied_post_id");
+
+                    b.Property<NpgsqlTsVector>("SearchVector")
+                        .HasColumnType("tsvector")
+                        .HasColumnName("search_vector");
+
+                    b.Property<long?>("ThreadedPostId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("threaded_post_id");
+
+                    b.Property<string>("Title")
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("title");
+
+                    b.Property<int>("Type")
+                        .HasColumnType("integer")
+                        .HasColumnName("type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<int>("Upvotes")
+                        .HasColumnType("integer")
+                        .HasColumnName("upvotes");
+
+                    b.Property<int>("ViewsTotal")
+                        .HasColumnType("integer")
+                        .HasColumnName("views_total");
+
+                    b.Property<int>("ViewsUnique")
+                        .HasColumnType("integer")
+                        .HasColumnName("views_unique");
+
+                    b.Property<int>("Visibility")
+                        .HasColumnType("integer")
+                        .HasColumnName("visibility");
+
+                    b.HasKey("Id")
+                        .HasName("pk_posts");
+
+                    b.HasIndex("ForwardedPostId")
+                        .HasDatabaseName("ix_posts_forwarded_post_id");
+
+                    b.HasIndex("PublisherId")
+                        .HasDatabaseName("ix_posts_publisher_id");
+
+                    b.HasIndex("RepliedPostId")
+                        .HasDatabaseName("ix_posts_replied_post_id");
+
+                    b.HasIndex("SearchVector")
+                        .HasDatabaseName("ix_posts_search_vector");
+
+                    NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("SearchVector"), "GIN");
+
+                    b.HasIndex("ThreadedPostId")
+                        .IsUnique()
+                        .HasDatabaseName("ix_posts_threaded_post_id");
+
+                    b.ToTable("posts", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PostCategory", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Name")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("name");
+
+                    b.Property<string>("Slug")
+                        .IsRequired()
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("slug");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_post_categories");
+
+                    b.ToTable("post_categories", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PostCollection", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Description")
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("description");
+
+                    b.Property<string>("Name")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("name");
+
+                    b.Property<long>("PublisherId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("publisher_id");
+
+                    b.Property<string>("Slug")
+                        .IsRequired()
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("slug");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_post_collections");
+
+                    b.HasIndex("PublisherId")
+                        .HasDatabaseName("ix_post_collections_publisher_id");
+
+                    b.ToTable("post_collections", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PostReaction", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<int>("Attitude")
+                        .HasColumnType("integer")
+                        .HasColumnName("attitude");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<long>("PostId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("post_id");
+
+                    b.Property<string>("Symbol")
+                        .IsRequired()
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("symbol");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_post_reactions");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_post_reactions_account_id");
+
+                    b.HasIndex("PostId")
+                        .HasDatabaseName("ix_post_reactions_post_id");
+
+                    b.ToTable("post_reactions", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PostTag", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Name")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("name");
+
+                    b.Property<string>("Slug")
+                        .IsRequired()
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("slug");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_post_tags");
+
+                    b.ToTable("post_tags", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.Publisher", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<long?>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<string>("BackgroundId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("background_id");
+
+                    b.Property<string>("Bio")
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("bio");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("name");
+
+                    b.Property<string>("Nick")
+                        .IsRequired()
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("nick");
+
+                    b.Property<string>("PictureId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("picture_id");
+
+                    b.Property<int>("PublisherType")
+                        .HasColumnType("integer")
+                        .HasColumnName("publisher_type");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_publishers");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_publishers_account_id");
+
+                    b.HasIndex("BackgroundId")
+                        .HasDatabaseName("ix_publishers_background_id");
+
+                    b.HasIndex("Name")
+                        .IsUnique()
+                        .HasDatabaseName("ix_publishers_name");
+
+                    b.HasIndex("PictureId")
+                        .HasDatabaseName("ix_publishers_picture_id");
+
+                    b.ToTable("publishers", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PublisherMember", b =>
+                {
+                    b.Property<long>("PublisherId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("publisher_id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("JoinedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("joined_at");
+
+                    b.Property<int>("Role")
+                        .HasColumnType("integer")
+                        .HasColumnName("role");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("PublisherId", "AccountId")
+                        .HasName("pk_publisher_members");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_publisher_members_account_id");
+
+                    b.ToTable("publisher_members", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Realm.Realm", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<string>("BackgroundId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("background_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Description")
+                        .IsRequired()
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("description");
+
+                    b.Property<bool>("IsCommunity")
+                        .HasColumnType("boolean")
+                        .HasColumnName("is_community");
+
+                    b.Property<bool>("IsPublic")
+                        .HasColumnType("boolean")
+                        .HasColumnName("is_public");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("name");
+
+                    b.Property<string>("PictureId")
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("picture_id");
+
+                    b.Property<string>("Slug")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("slug");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<string>("VerifiedAs")
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("verified_as");
+
+                    b.Property<Instant?>("VerifiedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("verified_at");
+
+                    b.HasKey("Id")
+                        .HasName("pk_realms");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_realms_account_id");
+
+                    b.HasIndex("BackgroundId")
+                        .HasDatabaseName("ix_realms_background_id");
+
+                    b.HasIndex("PictureId")
+                        .HasDatabaseName("ix_realms_picture_id");
+
+                    b.HasIndex("Slug")
+                        .IsUnique()
+                        .HasDatabaseName("ix_realms_slug");
+
+                    b.ToTable("realms", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Realm.RealmMember", b =>
+                {
+                    b.Property<long>("RealmId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("realm_id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<Instant?>("JoinedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("joined_at");
+
+                    b.Property<int>("Role")
+                        .HasColumnType("integer")
+                        .HasColumnName("role");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.HasKey("RealmId", "AccountId")
+                        .HasName("pk_realm_members");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_realm_members_account_id");
+
+                    b.ToTable("realm_members", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Storage.CloudFile", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("id");
+
+                    b.Property<long>("AccountId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("account_id");
+
+                    b.Property<Instant>("CreatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_at");
+
+                    b.Property<Instant?>("DeletedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("deleted_at");
+
+                    b.Property<string>("Description")
+                        .HasMaxLength(4096)
+                        .HasColumnType("character varying(4096)")
+                        .HasColumnName("description");
+
+                    b.Property<Instant?>("ExpiredAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("expired_at");
+
+                    b.Property<Dictionary<string, object>>("FileMeta")
+                        .HasColumnType("jsonb")
+                        .HasColumnName("file_meta");
+
+                    b.Property<bool>("HasCompression")
+                        .HasColumnType("boolean")
+                        .HasColumnName("has_compression");
+
+                    b.Property<string>("Hash")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("hash");
+
+                    b.Property<Guid?>("MessageId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("message_id");
+
+                    b.Property<string>("MimeType")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)")
+                        .HasColumnName("mime_type");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(1024)
+                        .HasColumnType("character varying(1024)")
+                        .HasColumnName("name");
+
+                    b.Property<long?>("PostId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("post_id");
+
+                    b.Property<long>("Size")
+                        .HasColumnType("bigint")
+                        .HasColumnName("size");
+
+                    b.Property<Instant>("UpdatedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("updated_at");
+
+                    b.Property<Instant?>("UploadedAt")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("uploaded_at");
+
+                    b.Property<string>("UploadedTo")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)")
+                        .HasColumnName("uploaded_to");
+
+                    b.Property<int>("UsedCount")
+                        .HasColumnType("integer")
+                        .HasColumnName("used_count");
+
+                    b.Property<Dictionary<string, object>>("UserMeta")
+                        .HasColumnType("jsonb")
+                        .HasColumnName("user_meta");
+
+                    b.HasKey("Id")
+                        .HasName("pk_files");
+
+                    b.HasIndex("AccountId")
+                        .HasDatabaseName("ix_files_account_id");
+
+                    b.HasIndex("MessageId")
+                        .HasDatabaseName("ix_files_message_id");
+
+                    b.HasIndex("PostId")
+                        .HasDatabaseName("ix_files_post_id");
+
+                    b.ToTable("files", (string)null);
+                });
+
+            modelBuilder.Entity("PostPostCategory", b =>
+                {
+                    b.Property<long>("CategoriesId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("categories_id");
+
+                    b.Property<long>("PostsId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("posts_id");
+
+                    b.HasKey("CategoriesId", "PostsId")
+                        .HasName("pk_post_category_links");
+
+                    b.HasIndex("PostsId")
+                        .HasDatabaseName("ix_post_category_links_posts_id");
+
+                    b.ToTable("post_category_links", (string)null);
+                });
+
+            modelBuilder.Entity("PostPostCollection", b =>
+                {
+                    b.Property<long>("CollectionsId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("collections_id");
+
+                    b.Property<long>("PostsId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("posts_id");
+
+                    b.HasKey("CollectionsId", "PostsId")
+                        .HasName("pk_post_collection_links");
+
+                    b.HasIndex("PostsId")
+                        .HasDatabaseName("ix_post_collection_links_posts_id");
+
+                    b.ToTable("post_collection_links", (string)null);
+                });
+
+            modelBuilder.Entity("PostPostTag", b =>
+                {
+                    b.Property<long>("PostsId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("posts_id");
+
+                    b.Property<long>("TagsId")
+                        .HasColumnType("bigint")
+                        .HasColumnName("tags_id");
+
+                    b.HasKey("PostsId", "TagsId")
+                        .HasName("pk_post_tag_links");
+
+                    b.HasIndex("TagsId")
+                        .HasDatabaseName("ix_post_tag_links_tags_id");
+
+                    b.ToTable("post_tag_links", (string)null);
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.AccountAuthFactor", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany("AuthFactors")
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_account_auth_factors_accounts_account_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.AccountContact", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany("Contacts")
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_account_contacts_accounts_account_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.MagicSpell", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .HasConstraintName("fk_magic_spells_accounts_account_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Notification", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_notifications_accounts_account_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.NotificationPushSubscription", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_notification_push_subscriptions_accounts_account_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Profile", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Background")
+                        .WithMany()
+                        .HasForeignKey("BackgroundId")
+                        .HasConstraintName("fk_account_profiles_files_background_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithOne("Profile")
+                        .HasForeignKey("DysonNetwork.Sphere.Account.Profile", "Id")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_account_profiles_accounts_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Picture")
+                        .WithMany()
+                        .HasForeignKey("PictureId")
+                        .HasConstraintName("fk_account_profiles_files_picture_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Background");
+
+                    b.Navigation("Picture");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Relationship", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany("OutgoingRelationships")
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_account_relationships_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Related")
+                        .WithMany("IncomingRelationships")
+                        .HasForeignKey("RelatedId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_account_relationships_accounts_related_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Related");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Activity.Activity", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_activities_accounts_account_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Auth.Challenge", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany("Challenges")
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_auth_challenges_accounts_account_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Auth.Session", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany("Sessions")
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_auth_sessions_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Auth.Challenge", "Challenge")
+                        .WithMany()
+                        .HasForeignKey("ChallengeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_auth_sessions_auth_challenges_challenge_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Challenge");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.ChatMember", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_chat_members_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Chat.ChatRoom", "ChatRoom")
+                        .WithMany("Members")
+                        .HasForeignKey("ChatRoomId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_chat_members_chat_rooms_chat_room_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("ChatRoom");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.ChatRoom", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Background")
+                        .WithMany()
+                        .HasForeignKey("BackgroundId")
+                        .HasConstraintName("fk_chat_rooms_files_background_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Picture")
+                        .WithMany()
+                        .HasForeignKey("PictureId")
+                        .HasConstraintName("fk_chat_rooms_files_picture_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Realm.Realm", "Realm")
+                        .WithMany("ChatRooms")
+                        .HasForeignKey("RealmId")
+                        .HasConstraintName("fk_chat_rooms_realms_realm_id");
+
+                    b.Navigation("Background");
+
+                    b.Navigation("Picture");
+
+                    b.Navigation("Realm");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.Message", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Chat.ChatRoom", "ChatRoom")
+                        .WithMany()
+                        .HasForeignKey("ChatRoomId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_chat_messages_chat_rooms_chat_room_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Chat.Message", "ForwardedMessage")
+                        .WithMany()
+                        .HasForeignKey("ForwardedMessageId")
+                        .OnDelete(DeleteBehavior.Restrict)
+                        .HasConstraintName("fk_chat_messages_chat_messages_forwarded_message_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Chat.Message", "RepliedMessage")
+                        .WithMany()
+                        .HasForeignKey("RepliedMessageId")
+                        .OnDelete(DeleteBehavior.Restrict)
+                        .HasConstraintName("fk_chat_messages_chat_messages_replied_message_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Chat.ChatMember", "Sender")
+                        .WithMany()
+                        .HasForeignKey("SenderId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_chat_messages_chat_members_sender_id");
+
+                    b.Navigation("ChatRoom");
+
+                    b.Navigation("ForwardedMessage");
+
+                    b.Navigation("RepliedMessage");
+
+                    b.Navigation("Sender");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.MessageReaction", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Chat.Message", "Message")
+                        .WithMany("Reactions")
+                        .HasForeignKey("MessageId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_message_reaction_chat_messages_message_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Chat.ChatMember", "Sender")
+                        .WithMany()
+                        .HasForeignKey("SenderId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_message_reaction_chat_members_sender_id");
+
+                    b.Navigation("Message");
+
+                    b.Navigation("Sender");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.MessageStatus", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Chat.Message", "Message")
+                        .WithMany("Statuses")
+                        .HasForeignKey("MessageId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_chat_statuses_chat_messages_message_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Chat.ChatMember", "Sender")
+                        .WithMany()
+                        .HasForeignKey("SenderId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_chat_statuses_chat_members_sender_id");
+
+                    b.Navigation("Message");
+
+                    b.Navigation("Sender");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Permission.PermissionGroupMember", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Permission.PermissionGroup", "Group")
+                        .WithMany("Members")
+                        .HasForeignKey("GroupId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_permission_group_members_permission_groups_group_id");
+
+                    b.Navigation("Group");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Permission.PermissionNode", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Permission.PermissionGroup", "Group")
+                        .WithMany("Nodes")
+                        .HasForeignKey("GroupId")
+                        .HasConstraintName("fk_permission_nodes_permission_groups_group_id");
+
+                    b.Navigation("Group");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.Post", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", "ForwardedPost")
+                        .WithMany()
+                        .HasForeignKey("ForwardedPostId")
+                        .OnDelete(DeleteBehavior.Restrict)
+                        .HasConstraintName("fk_posts_posts_forwarded_post_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Publisher", "Publisher")
+                        .WithMany("Posts")
+                        .HasForeignKey("PublisherId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_posts_publishers_publisher_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", "RepliedPost")
+                        .WithMany()
+                        .HasForeignKey("RepliedPostId")
+                        .OnDelete(DeleteBehavior.Restrict)
+                        .HasConstraintName("fk_posts_posts_replied_post_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", "ThreadedPost")
+                        .WithOne()
+                        .HasForeignKey("DysonNetwork.Sphere.Post.Post", "ThreadedPostId")
+                        .HasConstraintName("fk_posts_posts_threaded_post_id");
+
+                    b.Navigation("ForwardedPost");
+
+                    b.Navigation("Publisher");
+
+                    b.Navigation("RepliedPost");
+
+                    b.Navigation("ThreadedPost");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PostCollection", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Post.Publisher", "Publisher")
+                        .WithMany("Collections")
+                        .HasForeignKey("PublisherId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_collections_publishers_publisher_id");
+
+                    b.Navigation("Publisher");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PostReaction", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_reactions_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", "Post")
+                        .WithMany("Reactions")
+                        .HasForeignKey("PostId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_reactions_posts_post_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Post");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.Publisher", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .HasConstraintName("fk_publishers_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Background")
+                        .WithMany()
+                        .HasForeignKey("BackgroundId")
+                        .HasConstraintName("fk_publishers_files_background_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Picture")
+                        .WithMany()
+                        .HasForeignKey("PictureId")
+                        .HasConstraintName("fk_publishers_files_picture_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Background");
+
+                    b.Navigation("Picture");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.PublisherMember", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_publisher_members_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Publisher", "Publisher")
+                        .WithMany("Members")
+                        .HasForeignKey("PublisherId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_publisher_members_publishers_publisher_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Publisher");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Realm.Realm", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_realms_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Background")
+                        .WithMany()
+                        .HasForeignKey("BackgroundId")
+                        .HasConstraintName("fk_realms_files_background_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Storage.CloudFile", "Picture")
+                        .WithMany()
+                        .HasForeignKey("PictureId")
+                        .HasConstraintName("fk_realms_files_picture_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Background");
+
+                    b.Navigation("Picture");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Realm.RealmMember", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_realm_members_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Realm.Realm", "Realm")
+                        .WithMany("Members")
+                        .HasForeignKey("RealmId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_realm_members_realms_realm_id");
+
+                    b.Navigation("Account");
+
+                    b.Navigation("Realm");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Storage.CloudFile", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
+                        .WithMany()
+                        .HasForeignKey("AccountId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_files_accounts_account_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Chat.Message", null)
+                        .WithMany("Attachments")
+                        .HasForeignKey("MessageId")
+                        .HasConstraintName("fk_files_chat_messages_message_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", null)
+                        .WithMany("Attachments")
+                        .HasForeignKey("PostId")
+                        .HasConstraintName("fk_files_posts_post_id");
+
+                    b.Navigation("Account");
+                });
+
+            modelBuilder.Entity("PostPostCategory", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Post.PostCategory", null)
+                        .WithMany()
+                        .HasForeignKey("CategoriesId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_category_links_post_categories_categories_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", null)
+                        .WithMany()
+                        .HasForeignKey("PostsId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_category_links_posts_posts_id");
+                });
+
+            modelBuilder.Entity("PostPostCollection", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Post.PostCollection", null)
+                        .WithMany()
+                        .HasForeignKey("CollectionsId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_collection_links_post_collections_collections_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", null)
+                        .WithMany()
+                        .HasForeignKey("PostsId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_collection_links_posts_posts_id");
+                });
+
+            modelBuilder.Entity("PostPostTag", b =>
+                {
+                    b.HasOne("DysonNetwork.Sphere.Post.Post", null)
+                        .WithMany()
+                        .HasForeignKey("PostsId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_tag_links_posts_posts_id");
+
+                    b.HasOne("DysonNetwork.Sphere.Post.PostTag", null)
+                        .WithMany()
+                        .HasForeignKey("TagsId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired()
+                        .HasConstraintName("fk_post_tag_links_post_tags_tags_id");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Account.Account", b =>
+                {
+                    b.Navigation("AuthFactors");
+
+                    b.Navigation("Challenges");
+
+                    b.Navigation("Contacts");
+
+                    b.Navigation("IncomingRelationships");
+
+                    b.Navigation("OutgoingRelationships");
+
+                    b.Navigation("Profile")
+                        .IsRequired();
+
+                    b.Navigation("Sessions");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.ChatRoom", b =>
+                {
+                    b.Navigation("Members");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Chat.Message", b =>
+                {
+                    b.Navigation("Attachments");
+
+                    b.Navigation("Reactions");
+
+                    b.Navigation("Statuses");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Permission.PermissionGroup", b =>
+                {
+                    b.Navigation("Members");
+
+                    b.Navigation("Nodes");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.Post", b =>
+                {
+                    b.Navigation("Attachments");
+
+                    b.Navigation("Reactions");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Post.Publisher", b =>
+                {
+                    b.Navigation("Collections");
+
+                    b.Navigation("Members");
+
+                    b.Navigation("Posts");
+                });
+
+            modelBuilder.Entity("DysonNetwork.Sphere.Realm.Realm", b =>
+                {
+                    b.Navigation("ChatRooms");
+
+                    b.Navigation("Members");
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}
diff --git a/DysonNetwork.Sphere/Migrations/20250503040922_DontKnowHowToNameThing2.cs b/DysonNetwork.Sphere/Migrations/20250503040922_DontKnowHowToNameThing2.cs
new file mode 100644
index 0000000..e94b23b
--- /dev/null
+++ b/DysonNetwork.Sphere/Migrations/20250503040922_DontKnowHowToNameThing2.cs
@@ -0,0 +1,48 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace DysonNetwork.Sphere.Migrations
+{
+    /// <inheritdoc />
+    public partial class DontKnowHowToNameThing2 : Migration
+    {
+        /// <inheritdoc />
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropColumn(
+                name: "type",
+                table: "chat_messages");
+
+            migrationBuilder.AlterColumn<string>(
+                name: "nonce",
+                table: "chat_messages",
+                type: "character varying(36)",
+                maxLength: 36,
+                nullable: false,
+                oldClrType: typeof(string),
+                oldType: "text");
+        }
+
+        /// <inheritdoc />
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.AlterColumn<string>(
+                name: "nonce",
+                table: "chat_messages",
+                type: "text",
+                nullable: false,
+                oldClrType: typeof(string),
+                oldType: "character varying(36)",
+                oldMaxLength: 36);
+
+            migrationBuilder.AddColumn<string>(
+                name: "type",
+                table: "chat_messages",
+                type: "character varying(1024)",
+                maxLength: 1024,
+                nullable: false,
+                defaultValue: "");
+        }
+    }
+}
diff --git a/DysonNetwork.Sphere/Migrations/AppDatabaseModelSnapshot.cs b/DysonNetwork.Sphere/Migrations/AppDatabaseModelSnapshot.cs
index 5e41abf..ce445a2 100644
--- a/DysonNetwork.Sphere/Migrations/AppDatabaseModelSnapshot.cs
+++ b/DysonNetwork.Sphere/Migrations/AppDatabaseModelSnapshot.cs
@@ -806,14 +806,20 @@ namespace DysonNetwork.Sphere.Migrations
                         .HasColumnType("uuid")
                         .HasColumnName("forwarded_message_id");
 
-                    b.Property<List<Guid>>("MembersMetioned")
+                    b.Property<List<Guid>>("MembersMentioned")
                         .HasColumnType("jsonb")
-                        .HasColumnName("members_metioned");
+                        .HasColumnName("members_mentioned");
 
                     b.Property<Dictionary<string, object>>("Meta")
                         .HasColumnType("jsonb")
                         .HasColumnName("meta");
 
+                    b.Property<string>("Nonce")
+                        .IsRequired()
+                        .HasMaxLength(36)
+                        .HasColumnType("character varying(36)")
+                        .HasColumnName("nonce");
+
                     b.Property<Guid?>("RepliedMessageId")
                         .HasColumnType("uuid")
                         .HasColumnName("replied_message_id");
@@ -822,12 +828,6 @@ namespace DysonNetwork.Sphere.Migrations
                         .HasColumnType("uuid")
                         .HasColumnName("sender_id");
 
-                    b.Property<string>("Type")
-                        .IsRequired()
-                        .HasMaxLength(1024)
-                        .HasColumnType("character varying(1024)")
-                        .HasColumnName("type");
-
                     b.Property<Instant>("UpdatedAt")
                         .HasColumnType("timestamp with time zone")
                         .HasColumnName("updated_at");