diff --git a/DysonNetwork.Shared/Models/CloudFileReferenceObject.cs b/DysonNetwork.Shared/Models/CloudFileReferenceObject.cs
index dad0421..cdeebbb 100644
--- a/DysonNetwork.Shared/Models/CloudFileReferenceObject.cs
+++ b/DysonNetwork.Shared/Models/CloudFileReferenceObject.cs
@@ -1,3 +1,4 @@
+using System.ComponentModel.DataAnnotations;
using DysonNetwork.Shared.Proto;
namespace DysonNetwork.Shared.Models;
@@ -22,6 +23,7 @@ public enum ContentSensitiveMark
///
/// The class that used in jsonb columns which referenced the cloud file.
/// The aim of this class is to store some properties that won't change to a file to reduce the database load.
+/// Supports both local cloud files (with Id) and external/fediverse files (with Url).
///
public class SnCloudFileReferenceObject : ModelBase, ICloudFile
{
@@ -34,6 +36,11 @@ public class SnCloudFileReferenceObject : ModelBase, ICloudFile
public string? Hash { get; set; }
public long Size { get; set; }
public bool HasCompression { get; set; } = false;
+
+ [MaxLength(2048)] public string? Url { get; set; }
+ public int? Width { get; set; }
+ public int? Height { get; set; }
+ [MaxLength(64)] public string? Blurhash { get; set; }
public static SnCloudFileReferenceObject FromProtoValue(Proto.CloudFile proto)
{
@@ -49,7 +56,11 @@ public class SnCloudFileReferenceObject : ModelBase, ICloudFile
MimeType = proto.MimeType,
Hash = proto.Hash,
Size = proto.Size,
- HasCompression = proto.HasCompression
+ HasCompression = proto.HasCompression,
+ Url = string.IsNullOrEmpty(proto.Url) ? null : proto.Url,
+ Width = proto.HasWidth ? proto.Width : null,
+ Height = proto.HasHeight ? proto.Height : null,
+ Blurhash = proto.HasBlurhash ? proto.Blurhash : null
};
}
@@ -67,10 +78,11 @@ public class SnCloudFileReferenceObject : ModelBase, ICloudFile
Size = Size,
HasCompression = HasCompression,
ContentType = MimeType ?? string.Empty,
- Url = string.Empty,
- // Convert file metadata
+ Url = Url ?? string.Empty,
+ Width = Width ?? 0,
+ Height = Height ?? 0,
+ Blurhash = Blurhash ?? string.Empty,
FileMeta = GrpcTypeHelper.ConvertObjectToByteString(FileMeta),
- // Convert user metadata
UserMeta = GrpcTypeHelper.ConvertObjectToByteString(UserMeta),
SensitiveMarks = GrpcTypeHelper.ConvertObjectToByteString(SensitiveMarks)
};
diff --git a/DysonNetwork.Shared/Models/FediverseActivity.cs b/DysonNetwork.Shared/Models/FediverseActivity.cs
deleted file mode 100644
index d1b53c7..0000000
--- a/DysonNetwork.Shared/Models/FediverseActivity.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-using System.Text.Json.Serialization;
-using Microsoft.EntityFrameworkCore;
-using NodaTime;
-
-namespace DysonNetwork.Shared.Models;
-
-public class SnFediverseActivity : ModelBase
-{
- public Guid Id { get; set; } = Guid.NewGuid();
-
- [MaxLength(2048)]
- public string Uri { get; set; } = null!;
-
- public FediverseActivityType Type { get; set; }
-
- [MaxLength(2048)]
- public string? ObjectUri { get; set; }
-
- [MaxLength(2048)]
- public string? TargetUri { get; set; }
-
- public Instant? PublishedAt { get; set; }
-
- public bool IsLocal { get; set; }
-
- [Column(TypeName = "jsonb")]
- public Dictionary? RawData { get; set; }
-
- public Guid ActorId { get; set; }
- [JsonIgnore]
- public SnFediverseActor Actor { get; set; } = null!;
-
- public Guid? ContentId { get; set; }
- [JsonIgnore]
- public SnFediverseContent? Content { get; set; }
-
- public Guid? TargetActorId { get; set; }
- [JsonIgnore]
- public SnFediverseActor? TargetActor { get; set; }
-
- public Guid? LocalPostId { get; set; }
- public Guid? LocalAccountId { get; set; }
-
- public ActivityStatus Status { get; set; } = ActivityStatus.Pending;
-
- [MaxLength(4096)]
- public string? ErrorMessage { get; set; }
-}
-
-public enum FediverseActivityType
-{
- Create,
- Update,
- Delete,
- Follow,
- Unfollow,
- Like,
- Announce,
- Undo,
- Accept,
- Reject,
- Add,
- Remove,
- Block,
- Unblock,
- Flag,
- Move
-}
-
-public enum ActivityStatus
-{
- Pending,
- Processing,
- Completed,
- Failed
-}
diff --git a/DysonNetwork.Shared/Models/FediverseActor.cs b/DysonNetwork.Shared/Models/FediverseActor.cs
index 3d33ac5..c734a60 100644
--- a/DysonNetwork.Shared/Models/FediverseActor.cs
+++ b/DysonNetwork.Shared/Models/FediverseActor.cs
@@ -34,8 +34,6 @@ public class SnFediverseActor : ModelBase
public Guid InstanceId { get; set; }
public SnFediverseInstance Instance { get; set; } = null!;
- [JsonIgnore] public ICollection Contents { get; set; } = [];
- [JsonIgnore] public ICollection Activities { get; set; } = [];
[JsonIgnore] public ICollection FollowingRelationships { get; set; } = [];
[JsonIgnore] public ICollection FollowerRelationships { get; set; } = [];
diff --git a/DysonNetwork.Shared/Models/FediverseContent.cs b/DysonNetwork.Shared/Models/FediverseContent.cs
deleted file mode 100644
index 61585a8..0000000
--- a/DysonNetwork.Shared/Models/FediverseContent.cs
+++ /dev/null
@@ -1,143 +0,0 @@
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-using System.Text.Json.Serialization;
-using Microsoft.EntityFrameworkCore;
-using NodaTime;
-
-namespace DysonNetwork.Shared.Models;
-
-[Index(nameof(Uri), IsUnique = true)]
-public class SnFediverseContent : ModelBase
-{
- public Guid Id { get; set; } = Guid.NewGuid();
-
- [MaxLength(2048)]
- public string Uri { get; set; } = null!;
-
- public FediverseContentType Type { get; set; }
-
- [MaxLength(1024)]
- public string? Title { get; set; }
-
- [MaxLength(4096)]
- public string? Summary { get; set; }
-
- public string? Content { get; set; }
-
- public string? ContentHtml { get; set; }
-
- [MaxLength(2048)]
- public string? Language { get; set; }
-
- [MaxLength(2048)]
- public string? InReplyTo { get; set; }
-
- [MaxLength(2048)]
- public string? AnnouncedContentUri { get; set; }
-
- public Instant? PublishedAt { get; set; }
- public Instant? EditedAt { get; set; }
-
- public bool IsSensitive { get; set; } = false;
-
- [Column(TypeName = "jsonb")]
- public List? Attachments { get; set; }
-
- [Column(TypeName = "jsonb")]
- public List? Mentions { get; set; }
-
- [Column(TypeName = "jsonb")]
- public List? Tags { get; set; }
-
- [Column(TypeName = "jsonb")]
- public List? Emojis { get; set; }
-
- [Column(TypeName = "jsonb")]
- public Dictionary? Metadata { get; set; }
-
- public Guid ActorId { get; set; }
- [JsonIgnore]
- public SnFediverseActor Actor { get; set; } = null!;
-
- public Guid InstanceId { get; set; }
- [JsonIgnore]
- public SnFediverseInstance Instance { get; set; } = null!;
-
- [JsonIgnore]
- public ICollection Activities { get; set; } = [];
-
- [JsonIgnore]
- public ICollection Reactions { get; set; } = [];
-
- public int ReplyCount { get; set; }
- public int BoostCount { get; set; }
- public int LikeCount { get; set; }
-
- public Guid? LocalPostId { get; set; }
- [NotMapped]
- public SnPost? LocalPost { get; set; }
-}
-
-public enum FediverseContentType
-{
- Note,
- Article,
- Image,
- Video,
- Audio,
- Page,
- Question,
- Event,
- Document
-}
-
-public class ContentAttachment
-{
- [MaxLength(2048)]
- public string? Url { get; set; }
-
- [MaxLength(2048)]
- public string? MediaType { get; set; }
-
- [MaxLength(1024)]
- public string? Name { get; set; }
-
- public int? Width { get; set; }
- public int? Height { get; set; }
-
- [MaxLength(64)]
- public string? Blurhash { get; set; }
-}
-
-public class ContentMention
-{
- [MaxLength(256)]
- public string? Username { get; set; }
-
- [MaxLength(2048)]
- public string? Url { get; set; }
-
- [MaxLength(2048)]
- public string? ActorUri { get; set; }
-}
-
-public class ContentTag
-{
- [MaxLength(256)]
- public string? Name { get; set; }
-
- [MaxLength(2048)]
- public string? Url { get; set; }
-}
-
-public class ContentEmoji
-{
- [MaxLength(64)]
- public string? Shortcode { get; set; }
-
- [MaxLength(2048)]
- public string? StaticUrl { get; set; }
-
- [MaxLength(2048)]
- public string? Url { get; set; }
-}
diff --git a/DysonNetwork.Shared/Models/FediverseInstance.cs b/DysonNetwork.Shared/Models/FediverseInstance.cs
index 0edb8d6..8458ff9 100644
--- a/DysonNetwork.Shared/Models/FediverseInstance.cs
+++ b/DysonNetwork.Shared/Models/FediverseInstance.cs
@@ -28,7 +28,6 @@ public class SnFediverseInstance : ModelBase
[MaxLength(2048)] public string? BlockReason { get; set; }
[JsonIgnore] public ICollection Actors { get; set; } = [];
- [JsonIgnore] public ICollection Contents { get; set; } = [];
public Instant? LastFetchedAt { get; set; }
public Instant? LastActivityAt { get; set; }
diff --git a/DysonNetwork.Shared/Models/FediverseReaction.cs b/DysonNetwork.Shared/Models/FediverseReaction.cs
deleted file mode 100644
index 09a5323..0000000
--- a/DysonNetwork.Shared/Models/FediverseReaction.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-using System.Text.Json.Serialization;
-using Microsoft.EntityFrameworkCore;
-using NodaTime;
-
-namespace DysonNetwork.Shared.Models;
-
-public class SnFediverseReaction : ModelBase
-{
- public Guid Id { get; set; } = Guid.NewGuid();
-
- [MaxLength(2048)]
- public string Uri { get; set; } = null!;
-
- public FediverseReactionType Type { get; set; }
-
- [MaxLength(64)]
- public string? Emoji { get; set; }
-
- public bool IsLocal { get; set; }
-
- public Guid ContentId { get; set; }
- [JsonIgnore]
- public SnFediverseContent Content { get; set; } = null!;
-
- public Guid ActorId { get; set; }
- [JsonIgnore]
- public SnFediverseActor Actor { get; set; } = null!;
-
- public Guid? LocalAccountId { get; set; }
- public Guid? LocalReactionId { get; set; }
-}
-
-public enum FediverseReactionType
-{
- Like,
- Emoji,
- Dislike
-}
diff --git a/DysonNetwork.Shared/Models/Post.cs b/DysonNetwork.Shared/Models/Post.cs
index f0bae12..8f46bdc 100644
--- a/DysonNetwork.Shared/Models/Post.cs
+++ b/DysonNetwork.Shared/Models/Post.cs
@@ -21,6 +21,12 @@ public enum PostVisibility
Private,
}
+public enum PostContentType
+{
+ Markdown,
+ Html,
+}
+
public enum PostPinMode
{
PublisherPage,
@@ -28,6 +34,39 @@ public enum PostPinMode
ReplyPage,
}
+public class ContentMention
+{
+ [MaxLength(256)]
+ public string? Username { get; set; }
+
+ [MaxLength(2048)]
+ public string? Url { get; set; }
+
+ [MaxLength(2048)]
+ public string? ActorUri { get; set; }
+}
+
+public class ContentTag
+{
+ [MaxLength(256)]
+ public string? Name { get; set; }
+
+ [MaxLength(2048)]
+ public string? Url { get; set; }
+}
+
+public class ContentEmoji
+{
+ [MaxLength(64)]
+ public string? Shortcode { get; set; }
+
+ [MaxLength(2048)]
+ public string? StaticUrl { get; set; }
+
+ [MaxLength(2048)]
+ public string? Url { get; set; }
+}
+
public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
{
public Guid Id { get; set; }
@@ -47,11 +86,13 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
// ReSharper disable once EntityFramework.ModelValidation.UnlimitedStringLength
public string? Content { get; set; }
+ public PostContentType ContentType { get; set; } = PostContentType.Markdown;
+
public PostType Type { get; set; }
public PostPinMode? PinMode { get; set; }
[Column(TypeName = "jsonb")]
- public Dictionary? Meta { get; set; }
+ public Dictionary? Metadata { get; set; }
[Column(TypeName = "jsonb")]
public List? SensitiveMarks { get; set; } = [];
@@ -59,17 +100,28 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
[Column(TypeName = "jsonb")]
public PostEmbedView? EmbedView { get; set; }
+ [MaxLength(8192)] public string? FediverseUri { get; set; }
+ public FediverseContentType? FediverseType { get; set; }
+ [MaxLength(2048)] public string? Language { get; set; }
+ [Column(TypeName = "jsonb")]
+ public List? Mentions { get; set; }
+
+ public int BoostCount { get; set; }
+ public int LikeCount { get; set; }
+
+ public Guid? ActorId { get; set; }
+ public SnFediverseActor? Actor { get; set; }
+
public int ViewsUnique { get; set; }
public int ViewsTotal { get; set; }
public int Upvotes { get; set; }
public int Downvotes { get; set; }
public decimal AwardedScore { get; set; }
- [NotMapped]
- public Dictionary ReactionsCount { get; set; } = new();
+ public int RepliesCount { get; set; }
[NotMapped]
- public int RepliesCount { get; set; }
+ public Dictionary ReactionsCount { get; set; } = new();
[NotMapped]
public Dictionary? ReactionsMade { get; set; }
@@ -90,8 +142,8 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
[Column(TypeName = "jsonb")]
public List Attachments { get; set; } = [];
- public Guid PublisherId { get; set; }
- public SnPublisher Publisher { get; set; } = null!;
+ public Guid? PublisherId { get; set; }
+ public SnPublisher? Publisher { get; set; }
public List Awards { get; set; } = [];
@@ -133,7 +185,7 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
RepliedGone = RepliedGone,
ForwardedGone = ForwardedGone,
PublisherId = PublisherId.ToString(),
- Publisher = Publisher.ToProtoValue(),
+ Publisher = Publisher?.ToProtoValue(),
CreatedAt = Timestamp.FromDateTimeOffset(CreatedAt.ToDateTimeOffset()),
UpdatedAt = Timestamp.FromDateTimeOffset(UpdatedAt.ToDateTimeOffset()),
};
@@ -147,11 +199,13 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
if (Content != null)
proto.Content = Content;
+ proto.ContentType = (Proto.PostContentType)((int)ContentType + 1);
+
if (PinMode.HasValue)
proto.PinMode = (Proto.PostPinMode)((int)PinMode.Value + 1);
- if (Meta != null)
- proto.Meta = GrpcTypeHelper.ConvertObjectToByteString(Meta);
+ if (Metadata != null)
+ proto.Meta = GrpcTypeHelper.ConvertObjectToByteString(Metadata);
if (SensitiveMarks != null)
proto.SensitiveMarks = GrpcTypeHelper.ConvertObjectToByteString(SensitiveMarks);
@@ -159,6 +213,30 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
if (EmbedView != null)
proto.EmbedView = EmbedView.ToProtoValue();
+ if (!string.IsNullOrEmpty(FediverseUri))
+ proto.FediverseUri = FediverseUri;
+
+ if (FediverseType.HasValue)
+ proto.FediverseType = (Proto.FediverseContentType)((int)FediverseType.Value + 1);
+
+ if (!string.IsNullOrEmpty(Language))
+ proto.Language = Language;
+
+ if (Mentions != null)
+ proto.Mentions.AddRange(Mentions.Select(m => new Proto.ContentMention
+ {
+ Username = m.Username,
+ Url = m.Url,
+ ActorUri = m.ActorUri
+ }));
+
+ proto.RepliesCount = RepliesCount;
+ proto.BoostCount = BoostCount;
+ proto.LikeCount = LikeCount;
+
+ if (ActorId.HasValue)
+ proto.ActorId = ActorId.Value.ToString();
+
if (RepliedPostId.HasValue)
{
proto.RepliedPostId = RepliedPostId.Value.ToString();
@@ -220,7 +298,7 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
RepliedGone = proto.RepliedGone,
ForwardedGone = proto.ForwardedGone,
PublisherId = Guid.Parse(proto.PublisherId),
- Publisher = SnPublisher.FromProtoValue(proto.Publisher),
+ Publisher = proto.Publisher != null ? SnPublisher.FromProtoValue(proto.Publisher) : null,
CreatedAt = Instant.FromDateTimeOffset(proto.CreatedAt.ToDateTimeOffset()),
UpdatedAt = Instant.FromDateTimeOffset(proto.UpdatedAt.ToDateTimeOffset()),
};
@@ -234,11 +312,13 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
if (!string.IsNullOrEmpty(proto.Content))
post.Content = proto.Content;
+ post.ContentType = (PostContentType)((int)proto.ContentType - 1);
+
if (proto is { HasPinMode: true, PinMode: > 0 })
post.PinMode = (PostPinMode)(proto.PinMode - 1);
if (proto.Meta != null)
- post.Meta = GrpcTypeHelper.ConvertByteStringToObject>(
+ post.Metadata = GrpcTypeHelper.ConvertByteStringToObject>(
proto.Meta
);
@@ -250,6 +330,30 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
if (proto.EmbedView is not null)
post.EmbedView = PostEmbedView.FromProtoValue(proto.EmbedView);
+ if (!string.IsNullOrEmpty(proto.FediverseUri))
+ post.FediverseUri = proto.FediverseUri;
+
+ if (proto.HasFediverseType && proto.FediverseType > 0)
+ post.FediverseType = (FediverseContentType)((int)proto.FediverseType - 1);
+
+ if (!string.IsNullOrEmpty(proto.Language))
+ post.Language = proto.Language;
+
+ if (proto.Mentions != null && proto.Mentions.Count > 0)
+ post.Mentions = proto.Mentions.Select(m => new ContentMention
+ {
+ Username = m.Username,
+ Url = m.Url,
+ ActorUri = m.ActorUri
+ }).ToList();
+
+ post.RepliesCount = proto.RepliesCount;
+ post.BoostCount = proto.BoostCount;
+ post.LikeCount = proto.LikeCount;
+
+ if (!string.IsNullOrEmpty(proto.ActorId))
+ post.ActorId = Guid.Parse(proto.ActorId);
+
if (!string.IsNullOrEmpty(proto.RepliedPostId))
{
post.RepliedPostId = Guid.Parse(proto.RepliedPostId);
@@ -487,13 +591,17 @@ public class SnPostReaction : ModelBase
public PostReactionAttitude Attitude { get; set; }
public Guid PostId { get; set; }
+ [JsonIgnore] public SnPost Post { get; set; } = null!;
+
+ public Guid? AccountId { get; set; }
+ [NotMapped] public SnAccount? Account { get; set; }
- [JsonIgnore]
- public SnPost Post { get; set; } = null!;
- public Guid AccountId { get; set; }
+ [MaxLength(2048)] public string? FediverseUri { get; set; }
- [NotMapped]
- public SnAccount? Account { get; set; }
+ public Guid? ActorId { get; set; }
+ public SnFediverseActor? Actor { get; set; }
+
+ public bool IsLocal { get; set; } = true;
public PostReaction ToProtoValue()
{
@@ -503,7 +611,10 @@ public class SnPostReaction : ModelBase
Symbol = Symbol,
Attitude = (Proto.PostReactionAttitude)((int)Attitude + 1),
PostId = PostId.ToString(),
- AccountId = AccountId.ToString(),
+ AccountId = AccountId?.ToString() ?? string.Empty,
+ FediverseUri = FediverseUri ?? string.Empty,
+ IsLocal = IsLocal,
+ ActorId = ActorId?.ToString() ?? string.Empty,
CreatedAt = Timestamp.FromDateTimeOffset(CreatedAt.ToDateTimeOffset()),
UpdatedAt = Timestamp.FromDateTimeOffset(UpdatedAt.ToDateTimeOffset()),
};
@@ -515,7 +626,7 @@ public class SnPostReaction : ModelBase
return proto;
}
- public static SnPostReaction FromProtoValue(Proto.PostReaction proto)
+ public static SnPostReaction FromProtoValue(PostReaction proto)
{
return new SnPostReaction
{
@@ -523,8 +634,11 @@ public class SnPostReaction : ModelBase
Symbol = proto.Symbol,
Attitude = (PostReactionAttitude)((int)proto.Attitude - 1),
PostId = Guid.Parse(proto.PostId),
- AccountId = Guid.Parse(proto.AccountId),
+ AccountId = !string.IsNullOrEmpty(proto.AccountId) ? Guid.Parse(proto.AccountId) : null,
Account = proto.Account != null ? SnAccount.FromProtoValue(proto.Account) : null,
+ FediverseUri = !string.IsNullOrEmpty(proto.FediverseUri) ? proto.FediverseUri : null,
+ ActorId = !string.IsNullOrEmpty(proto.ActorId) ? Guid.Parse(proto.ActorId) : null,
+ IsLocal = proto.IsLocal,
CreatedAt = Instant.FromDateTimeOffset(proto.CreatedAt.ToDateTimeOffset()),
UpdatedAt = Instant.FromDateTimeOffset(proto.UpdatedAt.ToDateTimeOffset()),
};
diff --git a/DysonNetwork.Shared/Proto/file.proto b/DysonNetwork.Shared/Proto/file.proto
index 2651850..c97f977 100644
--- a/DysonNetwork.Shared/Proto/file.proto
+++ b/DysonNetwork.Shared/Proto/file.proto
@@ -45,6 +45,15 @@ message CloudFile {
// When the file was uploaded
google.protobuf.Timestamp uploaded_at = 11;
+
+ // Image/Video width (optional, for media files)
+ optional int32 width = 13;
+
+ // Image/Video height (optional, for media files)
+ optional int32 height = 14;
+
+ // Blurhash for placeholder (optional, for images)
+ optional string blurhash = 15;
}
// Service for file operations
diff --git a/DysonNetwork.Shared/Proto/post.proto b/DysonNetwork.Shared/Proto/post.proto
index a937b8d..60895c1 100644
--- a/DysonNetwork.Shared/Proto/post.proto
+++ b/DysonNetwork.Shared/Proto/post.proto
@@ -61,8 +61,33 @@ enum PostEmbedViewRenderer {
WEBVIEW = 1;
}
+enum PostContentType {
+ POST_CONTENT_TYPE_UNSPECIFIED = 0;
+ MARKDOWN = 1;
+ HTML = 2;
+}
+
+enum FediverseContentType {
+ FEDIVERSE_CONTENT_TYPE_UNSPECIFIED = 0;
+ FEDIVERSE_NOTE = 1;
+ FEDIVERSE_ARTICLE = 2;
+ FEDIVERSE_IMAGE = 3;
+ FEDIVERSE_VIDEO = 4;
+ FEDIVERSE_AUDIO = 5;
+ FEDIVERSE_PAGE = 6;
+ FEDIVERSE_QUESTION = 7;
+ FEDIVERSE_EVENT = 8;
+ FEDIVERSE_DOCUMENT = 9;
+}
+
// Messages
+message ContentMention {
+ optional string username = 1;
+ optional string url = 2;
+ optional string actor_uri = 3;
+}
+
message PostEmbedView {
string uri = 1;
optional double aspect_ratio = 2;
@@ -110,7 +135,16 @@ message Post {
repeated CloudFile attachments = 30; // List
string publisher_id = 31;
- Publisher publisher = 32;
+ optional Publisher publisher = 32;
+
+ optional string fediverse_uri = 41;
+ optional FediverseContentType fediverse_type = 42;
+ optional string language = 43;
+ optional PostContentType content_type = 44;
+ repeated ContentMention mentions = 48;
+ int32 boost_count = 50;
+ int32 like_count = 51;
+ optional string actor_id = 53;
repeated PostAward awards = 33;
repeated PostReaction reactions = 34;
@@ -189,6 +223,10 @@ message PostReaction {
string account_id = 5;
optional Account account = 6; // optional full account
+ optional string fediverse_uri = 9;
+ optional string actor_id = 11;
+ bool is_local = 10;
+
google.protobuf.Timestamp created_at = 7;
google.protobuf.Timestamp updated_at = 8;
}
diff --git a/DysonNetwork.Sphere/ActivityPub/ActivityPubActivityProcessor.cs b/DysonNetwork.Sphere/ActivityPub/ActivityPubActivityProcessor.cs
index 3173afb..9364227 100644
--- a/DysonNetwork.Sphere/ActivityPub/ActivityPubActivityProcessor.cs
+++ b/DysonNetwork.Sphere/ActivityPub/ActivityPubActivityProcessor.cs
@@ -2,6 +2,12 @@ using DysonNetwork.Shared.Models;
using Microsoft.EntityFrameworkCore;
using NodaTime;
using System.Text.Json;
+using DysonNetwork.Shared.Proto;
+using ContentMention = DysonNetwork.Shared.Models.ContentMention;
+using PostContentType = DysonNetwork.Shared.Models.PostContentType;
+using PostReactionAttitude = DysonNetwork.Shared.Models.PostReactionAttitude;
+using PostType = DysonNetwork.Shared.Models.PostType;
+using PostVisibility = DysonNetwork.Shared.Models.PostVisibility;
namespace DysonNetwork.Sphere.ActivityPub;
@@ -246,14 +252,13 @@ public class ActivityPubActivityProcessor(
}
var actor = await GetOrCreateActorAsync(actorUri);
- var instance = await GetOrCreateInstanceAsync(actorUri);
var contentUri = objectDict.GetValueOrDefault("id")?.ToString();
if (string.IsNullOrEmpty(contentUri))
return false;
- var existingContent = await db.FediverseContents
- .FirstOrDefaultAsync(c => c.Uri == contentUri);
+ var existingContent = await db.Posts
+ .FirstOrDefaultAsync(c => c.FediverseUri == contentUri);
if (existingContent != null)
{
@@ -261,26 +266,28 @@ public class ActivityPubActivityProcessor(
return true;
}
- var content = new SnFediverseContent
+ var content = new SnPost
{
- Uri = contentUri,
- Type = objectType == "Article" ? FediverseContentType.Article : FediverseContentType.Note,
+ FediverseUri = contentUri,
+ FediverseType = objectType == "Article" ? FediverseContentType.FediverseArticle : FediverseContentType.FediverseNote,
Title = objectDict.GetValueOrDefault("name")?.ToString(),
- Summary = objectDict.GetValueOrDefault("summary")?.ToString(),
+ Description = objectDict.GetValueOrDefault("summary")?.ToString(),
Content = objectDict.GetValueOrDefault("content")?.ToString(),
- ContentHtml = objectDict.GetValueOrDefault("contentMap")?.ToString(),
+ ContentType = objectDict.GetValueOrDefault("contentMap") != null ? PostContentType.Html : PostContentType.Markdown,
PublishedAt = ParseInstant(objectDict.GetValueOrDefault("published")),
EditedAt = ParseInstant(objectDict.GetValueOrDefault("updated")),
- IsSensitive = bool.TryParse(objectDict.GetValueOrDefault("sensitive")?.ToString(), out var sensitive) && sensitive,
ActorId = actor.Id,
- InstanceId = instance.Id,
- Attachments = ParseAttachments(objectDict.GetValueOrDefault("attachment")),
+ Language = objectDict.GetValueOrDefault("language")?.ToString(),
Mentions = ParseMentions(objectDict.GetValueOrDefault("tag")),
- Tags = ParseTags(objectDict.GetValueOrDefault("tag")),
- InReplyTo = objectDict.GetValueOrDefault("inReplyTo")?.ToString()
+ Attachments = ParseAttachments(objectDict.GetValueOrDefault("attachment")) ?? [],
+ Type = objectType == "Article" ? PostType.Article : PostType.Moment,
+ Visibility = PostVisibility.Public,
+ CreatedAt = SystemClock.Instance.GetCurrentInstant(),
+ UpdatedAt = SystemClock.Instance.GetCurrentInstant(),
+ Metadata = BuildMetadataFromActivity(objectDict)
};
- db.FediverseContents.Add(content);
+ db.Posts.Add(content);
await db.SaveChangesAsync();
logger.LogInformation("Created federated content: {Uri}", contentUri);
@@ -294,8 +301,8 @@ public class ActivityPubActivityProcessor(
return false;
var actor = await GetOrCreateActorAsync(actorUri);
- var content = await db.FediverseContents
- .FirstOrDefaultAsync(c => c.Uri == objectUri);
+ var content = await db.Posts
+ .FirstOrDefaultAsync(c => c.FediverseUri == objectUri);
if (content == null)
{
@@ -303,11 +310,11 @@ public class ActivityPubActivityProcessor(
return false;
}
- var existingReaction = await db.FediverseReactions
- .FirstOrDefaultAsync(r =>
- r.ActorId == actor.Id &&
- r.ContentId == content.Id &&
- r.Type == FediverseReactionType.Like);
+ var existingReaction = await db.PostReactions
+ .FirstOrDefaultAsync(r =>
+ r.ActorId == actor.Id &&
+ r.PostId == content.Id &&
+ r.Symbol == "❤️");
if (existingReaction != null)
{
@@ -315,16 +322,20 @@ public class ActivityPubActivityProcessor(
return true;
}
- var reaction = new SnFediverseReaction
+ var reaction = new SnPostReaction
{
- Uri = activity.GetValueOrDefault("id")?.ToString() ?? Guid.NewGuid().ToString(),
- Type = FediverseReactionType.Like,
+ FediverseUri = activity.GetValueOrDefault("id")?.ToString() ?? Guid.NewGuid().ToString(),
+ Symbol = "❤️",
+ Attitude = PostReactionAttitude.Positive,
IsLocal = false,
- ContentId = content.Id,
- ActorId = actor.Id
+ PostId = content.Id,
+ ActorId = actor.Id,
+ Actor = actor,
+ CreatedAt = SystemClock.Instance.GetCurrentInstant(),
+ UpdatedAt = SystemClock.Instance.GetCurrentInstant()
};
- db.FediverseReactions.Add(reaction);
+ db.PostReactions.Add(reaction);
content.LikeCount++;
await db.SaveChangesAsync();
@@ -340,8 +351,8 @@ public class ActivityPubActivityProcessor(
return false;
var actor = await GetOrCreateActorAsync(actorUri);
- var content = await db.FediverseContents
- .FirstOrDefaultAsync(c => c.Uri == objectUri);
+ var content = await db.Posts
+ .FirstOrDefaultAsync(c => c.FediverseUri == objectUri);
if (content != null)
{
@@ -359,8 +370,8 @@ public class ActivityPubActivityProcessor(
if (string.IsNullOrEmpty(objectUri))
return false;
- var content = await db.FediverseContents
- .FirstOrDefaultAsync(c => c.Uri == objectUri);
+ var content = await db.Posts
+ .FirstOrDefaultAsync(c => c.FediverseUri == objectUri);
if (content != null)
{
@@ -378,8 +389,8 @@ public class ActivityPubActivityProcessor(
if (string.IsNullOrEmpty(objectUri))
return false;
- var content = await db.FediverseContents
- .FirstOrDefaultAsync(c => c.Uri == objectUri);
+ var content = await db.Posts
+ .FirstOrDefaultAsync(c => c.FediverseUri == objectUri);
if (content != null)
{
@@ -416,18 +427,18 @@ public class ActivityPubActivityProcessor(
{
var actor = await GetOrCreateActorAsync(actorUri);
- var reactions = await db.FediverseReactions
- .Where(r => r.ActorId == actor.Id && r.Type == FediverseReactionType.Like)
+ var reactions = await db.PostReactions
+ .Where(r => r.ActorId == actor.Id && r.Symbol == "❤️")
.ToListAsync();
foreach (var reaction in reactions)
{
- var content = await db.FediverseContents.FindAsync(reaction.ContentId);
+ var content = await db.Posts.FindAsync(reaction.PostId);
if (content != null)
{
content.LikeCount--;
}
- db.FediverseReactions.Remove(reaction);
+ db.PostReactions.Remove(reaction);
}
await db.SaveChangesAsync();
@@ -436,8 +447,8 @@ public class ActivityPubActivityProcessor(
private async Task UndoAnnounceAsync(string actorUri, string? activityId)
{
- var content = await db.FediverseContents
- .FirstOrDefaultAsync(c => c.Uri == activityId);
+ var content = await db.Posts
+ .FirstOrDefaultAsync(c => c.FediverseUri == activityId);
if (content != null)
{
@@ -518,32 +529,35 @@ public class ActivityPubActivityProcessor(
return null;
}
- private List? ParseAttachments(object? value)
+ private static List? ParseAttachments(object? value)
{
- if (value == null)
- return null;
-
- if (value is JsonElement element && element.ValueKind == JsonValueKind.Array)
+ if (value is JsonElement { ValueKind: JsonValueKind.Array } element)
{
return element.EnumerateArray()
- .Select(attachment => new ContentAttachment
+ .Select(attachment => new SnCloudFileReferenceObject
{
+ Id = Guid.NewGuid().ToString(),
+ Name = attachment.GetProperty("name").GetString() ?? string.Empty,
Url = attachment.GetProperty("url").GetString(),
- MediaType = attachment.GetProperty("mediaType").GetString(),
- Name = attachment.GetProperty("name").GetString()
+ MimeType = attachment.GetProperty("mediaType").GetString(),
+ Width = attachment.GetProperty("width").GetInt32(),
+ Height = attachment.GetProperty("height").GetInt32(),
+ Blurhash = attachment.GetProperty("blurhash").GetString(),
+ FileMeta = new Dictionary(),
+ UserMeta = new Dictionary(),
+ Size = 0,
+ CreatedAt = SystemClock.Instance.GetCurrentInstant(),
+ UpdatedAt = SystemClock.Instance.GetCurrentInstant()
})
.ToList();
}
-
+
return null;
}
- private List? ParseMentions(object? value)
+ private static List? ParseMentions(object? value)
{
- if (value == null)
- return null;
-
- if (value is JsonElement element && element.ValueKind == JsonValueKind.Array)
+ if (value is JsonElement { ValueKind: JsonValueKind.Array } element)
{
return element.EnumerateArray()
.Where(e => e.GetProperty("type").GetString() == "Mention")
@@ -554,27 +568,46 @@ public class ActivityPubActivityProcessor(
})
.ToList();
}
-
+
return null;
}
- private List? ParseTags(object? value)
+ private static Dictionary BuildMetadataFromActivity(Dictionary objectDict)
{
- if (value == null)
- return null;
-
- if (value is JsonElement element && element.ValueKind == JsonValueKind.Array)
+ var metadata = new Dictionary();
+
+ var tagsValue = objectDict.GetValueOrDefault("tag");
+ if (tagsValue is JsonElement { ValueKind: JsonValueKind.Array } tagsElement)
{
- return element.EnumerateArray()
+ var fediverseTags = tagsElement.EnumerateArray()
.Where(e => e.GetProperty("type").GetString() == "Hashtag")
- .Select(tag => new ContentTag
+ .Select(e => e.GetProperty("name").GetString())
+ .ToList();
+
+ if (fediverseTags.Count > 0)
+ {
+ metadata["fediverseTags"] = fediverseTags;
+ }
+ }
+
+ var emojiValue = objectDict.GetValueOrDefault("emoji");
+ if (emojiValue is not JsonElement { ValueKind: JsonValueKind.Array } emojiElement) return metadata;
+ {
+ var emojis = emojiElement.EnumerateArray()
+ .Select(e => new
{
- Name = tag.GetProperty("name").GetString(),
- Url = tag.GetProperty("href").GetString()
+ Shortcode = e.GetProperty("shortcode").GetString(),
+ StaticUrl = e.GetProperty("static_url").GetString(),
+ Url = e.GetProperty("url").GetString()
})
.ToList();
+
+ if (emojis.Count > 0)
+ {
+ metadata["fediverseEmojis"] = emojis;
+ }
}
-
- return null;
+
+ return metadata;
}
}
diff --git a/DysonNetwork.Sphere/AppDatabase.cs b/DysonNetwork.Sphere/AppDatabase.cs
index a9d92be..2582b13 100644
--- a/DysonNetwork.Sphere/AppDatabase.cs
+++ b/DysonNetwork.Sphere/AppDatabase.cs
@@ -50,10 +50,7 @@ public class AppDatabase(
public DbSet FediverseInstances { get; set; } = null!;
public DbSet FediverseActors { get; set; } = null!;
- public DbSet FediverseContents { get; set; } = null!;
- public DbSet FediverseActivities { get; set; } = null!;
public DbSet FediverseRelationships { get; set; } = null!;
- public DbSet FediverseReactions { get; set; } = null!;
public DbSet WebArticles { get; set; } = null!;
public DbSet WebFeeds { get; set; } = null!;
@@ -155,28 +152,6 @@ public class AppDatabase(
.HasForeignKey(a => a.InstanceId)
.OnDelete(DeleteBehavior.Cascade);
- modelBuilder.Entity()
- .HasOne(c => c.Actor)
- .WithMany(a => a.Contents)
- .HasForeignKey(c => c.ActorId)
- .OnDelete(DeleteBehavior.Cascade);
- modelBuilder.Entity()
- .HasOne(c => c.Instance)
- .WithMany(i => i.Contents)
- .HasForeignKey(c => c.InstanceId)
- .OnDelete(DeleteBehavior.Cascade);
-
- modelBuilder.Entity()
- .HasOne(a => a.Actor)
- .WithMany(actor => actor.Activities)
- .HasForeignKey(a => a.ActorId)
- .OnDelete(DeleteBehavior.Cascade);
- modelBuilder.Entity()
- .HasOne(a => a.Content)
- .WithMany(c => c.Activities)
- .HasForeignKey(a => a.ContentId)
- .OnDelete(DeleteBehavior.Cascade);
-
modelBuilder.Entity()
.HasOne(r => r.Actor)
.WithMany(a => a.FollowingRelationships)
@@ -188,17 +163,6 @@ public class AppDatabase(
.HasForeignKey(r => r.TargetActorId)
.OnDelete(DeleteBehavior.Cascade);
- modelBuilder.Entity()
- .HasOne(r => r.Content)
- .WithMany(c => c.Reactions)
- .HasForeignKey(r => r.ContentId)
- .OnDelete(DeleteBehavior.Cascade);
- modelBuilder.Entity()
- .HasOne(r => r.Actor)
- .WithMany()
- .HasForeignKey(r => r.ActorId)
- .OnDelete(DeleteBehavior.Cascade);
-
modelBuilder.ApplySoftDeleteFilters();
}
diff --git a/DysonNetwork.Sphere/Migrations/20251228100758_AddActivityPub.Designer.cs b/DysonNetwork.Sphere/Migrations/20251228100758_AddActivityPub.Designer.cs
index b6f4c59..c411a12 100644
--- a/DysonNetwork.Sphere/Migrations/20251228100758_AddActivityPub.Designer.cs
+++ b/DysonNetwork.Sphere/Migrations/20251228100758_AddActivityPub.Designer.cs
@@ -543,9 +543,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("character varying(2048)")
.HasColumnName("announced_content_uri");
- b.Property>("Attachments")
- .HasColumnType("jsonb")
- .HasColumnName("attachments");
+ // b.Property>("Attachments")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("attachments");
b.Property("BoostCount")
.HasColumnType("integer")
@@ -571,9 +571,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("timestamp with time zone")
.HasColumnName("edited_at");
- b.Property>("Emojis")
- .HasColumnType("jsonb")
- .HasColumnName("emojis");
+ // b.Property>("Emojis")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("emojis");
b.Property("InReplyTo")
.HasMaxLength(2048)
@@ -601,9 +601,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("uuid")
.HasColumnName("local_post_id");
- b.Property>("Mentions")
- .HasColumnType("jsonb")
- .HasColumnName("mentions");
+ // b.Property>("Mentions")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("mentions");
b.Property>("Metadata")
.HasColumnType("jsonb")
@@ -622,9 +622,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("character varying(4096)")
.HasColumnName("summary");
- b.Property>("Tags")
- .HasColumnType("jsonb")
- .HasColumnName("tags");
+ // b.Property>("Tags")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("tags");
b.Property("Title")
.HasMaxLength(1024)
diff --git a/DysonNetwork.Sphere/Migrations/20251228100758_AddActivityPub.cs b/DysonNetwork.Sphere/Migrations/20251228100758_AddActivityPub.cs
index 49e2191..aa55412 100644
--- a/DysonNetwork.Sphere/Migrations/20251228100758_AddActivityPub.cs
+++ b/DysonNetwork.Sphere/Migrations/20251228100758_AddActivityPub.cs
@@ -102,10 +102,10 @@ namespace DysonNetwork.Sphere.Migrations
published_at = table.Column(type: "timestamp with time zone", nullable: true),
edited_at = table.Column(type: "timestamp with time zone", nullable: true),
is_sensitive = table.Column(type: "boolean", nullable: false),
- attachments = table.Column>(type: "jsonb", nullable: true),
- mentions = table.Column>(type: "jsonb", nullable: true),
- tags = table.Column>(type: "jsonb", nullable: true),
- emojis = table.Column>(type: "jsonb", nullable: true),
+ // attachments = table.Column>(type: "jsonb", nullable: true),
+ // mentions = table.Column>(type: "jsonb", nullable: true),
+ // tags = table.Column>(type: "jsonb", nullable: true),
+ // emojis = table.Column>(type: "jsonb", nullable: true),
metadata = table.Column>(type: "jsonb", nullable: true),
actor_id = table.Column(type: "uuid", nullable: false),
instance_id = table.Column(type: "uuid", nullable: false),
diff --git a/DysonNetwork.Sphere/Migrations/20251228165042_AddSeprateActorType.Designer.cs b/DysonNetwork.Sphere/Migrations/20251228165042_AddSeprateActorType.Designer.cs
index a5267f7..e73cb5c 100644
--- a/DysonNetwork.Sphere/Migrations/20251228165042_AddSeprateActorType.Designer.cs
+++ b/DysonNetwork.Sphere/Migrations/20251228165042_AddSeprateActorType.Designer.cs
@@ -549,9 +549,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("character varying(2048)")
.HasColumnName("announced_content_uri");
- b.Property>("Attachments")
- .HasColumnType("jsonb")
- .HasColumnName("attachments");
+ // b.Property>("Attachments")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("attachments");
b.Property("BoostCount")
.HasColumnType("integer")
@@ -577,9 +577,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("timestamp with time zone")
.HasColumnName("edited_at");
- b.Property>("Emojis")
- .HasColumnType("jsonb")
- .HasColumnName("emojis");
+ // b.Property>("Emojis")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("emojis");
b.Property("InReplyTo")
.HasMaxLength(2048)
@@ -607,9 +607,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("uuid")
.HasColumnName("local_post_id");
- b.Property>("Mentions")
- .HasColumnType("jsonb")
- .HasColumnName("mentions");
+ // b.Property>("Mentions")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("mentions");
b.Property>("Metadata")
.HasColumnType("jsonb")
@@ -628,9 +628,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("character varying(4096)")
.HasColumnName("summary");
- b.Property>("Tags")
- .HasColumnType("jsonb")
- .HasColumnName("tags");
+ // b.Property>("Tags")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("tags");
b.Property("Title")
.HasMaxLength(1024)
diff --git a/DysonNetwork.Sphere/Migrations/20251228173217_EnrichFediverseInstance.Designer.cs b/DysonNetwork.Sphere/Migrations/20251228173217_EnrichFediverseInstance.Designer.cs
index e5b92aa..42e28a5 100644
--- a/DysonNetwork.Sphere/Migrations/20251228173217_EnrichFediverseInstance.Designer.cs
+++ b/DysonNetwork.Sphere/Migrations/20251228173217_EnrichFediverseInstance.Designer.cs
@@ -549,9 +549,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("character varying(2048)")
.HasColumnName("announced_content_uri");
- b.Property>("Attachments")
- .HasColumnType("jsonb")
- .HasColumnName("attachments");
+ // b.Property>("Attachments")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("attachments");
b.Property("BoostCount")
.HasColumnType("integer")
@@ -577,9 +577,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("timestamp with time zone")
.HasColumnName("edited_at");
- b.Property>("Emojis")
- .HasColumnType("jsonb")
- .HasColumnName("emojis");
+ // b.Property>("Emojis")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("emojis");
b.Property("InReplyTo")
.HasMaxLength(2048)
@@ -607,9 +607,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("uuid")
.HasColumnName("local_post_id");
- b.Property>("Mentions")
- .HasColumnType("jsonb")
- .HasColumnName("mentions");
+ // b.Property>("Mentions")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("mentions");
b.Property>("Metadata")
.HasColumnType("jsonb")
@@ -628,9 +628,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("character varying(4096)")
.HasColumnName("summary");
- b.Property>("Tags")
- .HasColumnType("jsonb")
- .HasColumnName("tags");
+ // b.Property>("Tags")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("tags");
b.Property("Title")
.HasMaxLength(1024)
diff --git a/DysonNetwork.Sphere/Migrations/20251229163103_BetterLocalActor.Designer.cs b/DysonNetwork.Sphere/Migrations/20251229163103_BetterLocalActor.Designer.cs
index 060ce4e..5457962 100644
--- a/DysonNetwork.Sphere/Migrations/20251229163103_BetterLocalActor.Designer.cs
+++ b/DysonNetwork.Sphere/Migrations/20251229163103_BetterLocalActor.Designer.cs
@@ -553,9 +553,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("character varying(2048)")
.HasColumnName("announced_content_uri");
- b.Property>("Attachments")
- .HasColumnType("jsonb")
- .HasColumnName("attachments");
+ // b.Property>("Attachments")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("attachments");
b.Property("BoostCount")
.HasColumnType("integer")
@@ -581,9 +581,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("timestamp with time zone")
.HasColumnName("edited_at");
- b.Property>("Emojis")
- .HasColumnType("jsonb")
- .HasColumnName("emojis");
+ // b.Property>("Emojis")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("emojis");
b.Property("InReplyTo")
.HasMaxLength(2048)
@@ -611,9 +611,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("uuid")
.HasColumnName("local_post_id");
- b.Property>("Mentions")
- .HasColumnType("jsonb")
- .HasColumnName("mentions");
+ // b.Property>("Mentions")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("mentions");
b.Property>("Metadata")
.HasColumnType("jsonb")
@@ -632,9 +632,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("character varying(4096)")
.HasColumnName("summary");
- b.Property>("Tags")
- .HasColumnType("jsonb")
- .HasColumnName("tags");
+ // b.Property>("Tags")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("tags");
b.Property("Title")
.HasMaxLength(1024)
diff --git a/DysonNetwork.Sphere/Migrations/20251229174336_AddPublisherKeys.Designer.cs b/DysonNetwork.Sphere/Migrations/20251229174336_AddPublisherKeys.Designer.cs
index 0cb3ac4..2237ee8 100644
--- a/DysonNetwork.Sphere/Migrations/20251229174336_AddPublisherKeys.Designer.cs
+++ b/DysonNetwork.Sphere/Migrations/20251229174336_AddPublisherKeys.Designer.cs
@@ -553,9 +553,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("character varying(2048)")
.HasColumnName("announced_content_uri");
- b.Property>("Attachments")
- .HasColumnType("jsonb")
- .HasColumnName("attachments");
+ // b.Property>("Attachments")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("attachments");
b.Property("BoostCount")
.HasColumnType("integer")
@@ -581,9 +581,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("timestamp with time zone")
.HasColumnName("edited_at");
- b.Property>("Emojis")
- .HasColumnType("jsonb")
- .HasColumnName("emojis");
+ // b.Property>("Emojis")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("emojis");
b.Property("InReplyTo")
.HasMaxLength(2048)
@@ -611,9 +611,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("uuid")
.HasColumnName("local_post_id");
- b.Property>("Mentions")
- .HasColumnType("jsonb")
- .HasColumnName("mentions");
+ // b.Property>("Mentions")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("mentions");
b.Property>("Metadata")
.HasColumnType("jsonb")
@@ -632,9 +632,9 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("character varying(4096)")
.HasColumnName("summary");
- b.Property>("Tags")
- .HasColumnType("jsonb")
- .HasColumnName("tags");
+ // b.Property>("Tags")
+ // .HasColumnType("jsonb")
+ // .HasColumnName("tags");
b.Property("Title")
.HasMaxLength(1024)
diff --git a/DysonNetwork.Sphere/Migrations/20251230153545_MergeFediverseDataClass.Designer.cs b/DysonNetwork.Sphere/Migrations/20251230153545_MergeFediverseDataClass.Designer.cs
new file mode 100644
index 0000000..60ce417
--- /dev/null
+++ b/DysonNetwork.Sphere/Migrations/20251230153545_MergeFediverseDataClass.Designer.cs
@@ -0,0 +1,2385 @@
+//
+using System;
+using System.Collections.Generic;
+using System.Text.Json;
+using DysonNetwork.Shared.Models;
+using DysonNetwork.Sphere;
+using DysonNetwork.Sphere.WebReader;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using NodaTime;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace DysonNetwork.Sphere.Migrations
+{
+ [DbContext(typeof(AppDatabase))]
+ [Migration("20251230153545_MergeFediverseDataClass")]
+ partial class MergeFediverseDataClass
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "10.0.1")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("DysonNetwork.Shared.Models.SnChatMember", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("AccountId")
+ .HasColumnType("uuid")
+ .HasColumnName("account_id");
+
+ b.Property("BreakUntil")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("break_until");
+
+ b.Property("ChatRoomId")
+ .HasColumnType("uuid")
+ .HasColumnName("chat_room_id");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property("DeletedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("deleted_at");
+
+ b.Property("InvitedById")
+ .HasColumnType("uuid")
+ .HasColumnName("invited_by_id");
+
+ b.Property("JoinedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("joined_at");
+
+ b.Property("LastReadAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("last_read_at");
+
+ b.Property("LeaveAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("leave_at");
+
+ b.Property("Nick")
+ .HasMaxLength(1024)
+ .HasColumnType("character varying(1024)")
+ .HasColumnName("nick");
+
+ b.Property("Notify")
+ .HasColumnType("integer")
+ .HasColumnName("notify");
+
+ b.Property("TimeoutCause")
+ .HasColumnType("jsonb")
+ .HasColumnName("timeout_cause");
+
+ b.Property("TimeoutUntil")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("timeout_until");
+
+ b.Property("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("InvitedById")
+ .HasDatabaseName("ix_chat_members_invited_by_id");
+
+ b.ToTable("chat_members", (string)null);
+ });
+
+ modelBuilder.Entity("DysonNetwork.Shared.Models.SnChatMessage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property>("Attachments")
+ .IsRequired()
+ .HasColumnType("jsonb")
+ .HasColumnName("attachments");
+
+ b.Property("ChatRoomId")
+ .HasColumnType("uuid")
+ .HasColumnName("chat_room_id");
+
+ b.Property("Content")
+ .HasMaxLength(4096)
+ .HasColumnType("character varying(4096)")
+ .HasColumnName("content");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property("DeletedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("deleted_at");
+
+ b.Property("EditedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("edited_at");
+
+ b.Property("ForwardedMessageId")
+ .HasColumnType("uuid")
+ .HasColumnName("forwarded_message_id");
+
+ b.PrimitiveCollection("MembersMentioned")
+ .HasColumnType("jsonb")
+ .HasColumnName("members_mentioned");
+
+ b.Property>("Meta")
+ .HasColumnType("jsonb")
+ .HasColumnName("meta");
+
+ b.Property("Nonce")
+ .IsRequired()
+ .HasMaxLength(36)
+ .HasColumnType("character varying(36)")
+ .HasColumnName("nonce");
+
+ b.Property("RepliedMessageId")
+ .HasColumnType("uuid")
+ .HasColumnName("replied_message_id");
+
+ b.Property("SenderId")
+ .HasColumnType("uuid")
+ .HasColumnName("sender_id");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasMaxLength(1024)
+ .HasColumnType("character varying(1024)")
+ .HasColumnName("type");
+
+ b.Property("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.Shared.Models.SnChatMessageReaction", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("Attitude")
+ .HasColumnType("integer")
+ .HasColumnName("attitude");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property("DeletedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("deleted_at");
+
+ b.Property("MessageId")
+ .HasColumnType("uuid")
+ .HasColumnName("message_id");
+
+ b.Property("SenderId")
+ .HasColumnType("uuid")
+ .HasColumnName("sender_id");
+
+ b.Property("Symbol")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("symbol");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("updated_at");
+
+ b.HasKey("Id")
+ .HasName("pk_chat_reactions");
+
+ b.HasIndex("MessageId")
+ .HasDatabaseName("ix_chat_reactions_message_id");
+
+ b.HasIndex("SenderId")
+ .HasDatabaseName("ix_chat_reactions_sender_id");
+
+ b.ToTable("chat_reactions", (string)null);
+ });
+
+ modelBuilder.Entity("DysonNetwork.Shared.Models.SnChatRoom", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("AccountId")
+ .HasColumnType("uuid")
+ .HasColumnName("account_id");
+
+ b.Property("Background")
+ .HasColumnType("jsonb")
+ .HasColumnName("background");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property("DeletedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("deleted_at");
+
+ b.Property("Description")
+ .HasMaxLength(4096)
+ .HasColumnType("character varying(4096)")
+ .HasColumnName("description");
+
+ b.Property("IsCommunity")
+ .HasColumnType("boolean")
+ .HasColumnName("is_community");
+
+ b.Property("IsPublic")
+ .HasColumnType("boolean")
+ .HasColumnName("is_public");
+
+ b.Property("Name")
+ .HasMaxLength(1024)
+ .HasColumnType("character varying(1024)")
+ .HasColumnName("name");
+
+ b.Property("Picture")
+ .HasColumnType("jsonb")
+ .HasColumnName("picture");
+
+ b.Property("RealmId")
+ .HasColumnType("uuid")
+ .HasColumnName("realm_id");
+
+ b.Property("Type")
+ .HasColumnType("integer")
+ .HasColumnName("type");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("updated_at");
+
+ b.HasKey("Id")
+ .HasName("pk_chat_rooms");
+
+ b.ToTable("chat_rooms", (string)null);
+ });
+
+ modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseActor", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("AvatarUrl")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("avatar_url");
+
+ b.Property("Bio")
+ .HasMaxLength(4096)
+ .HasColumnType("character varying(4096)")
+ .HasColumnName("bio");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property("DeletedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("deleted_at");
+
+ b.Property("DisplayName")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("display_name");
+
+ b.Property("FeaturedUri")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("featured_uri");
+
+ b.Property("FollowersUri")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("followers_uri");
+
+ b.Property("FollowingUri")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("following_uri");
+
+ b.Property("HeaderUrl")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("header_url");
+
+ b.Property("InboxUri")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("inbox_uri");
+
+ b.Property("InstanceId")
+ .HasColumnType("uuid")
+ .HasColumnName("instance_id");
+
+ b.Property("IsBot")
+ .HasColumnType("boolean")
+ .HasColumnName("is_bot");
+
+ b.Property("IsDiscoverable")
+ .HasColumnType("boolean")
+ .HasColumnName("is_discoverable");
+
+ b.Property("IsLocked")
+ .HasColumnType("boolean")
+ .HasColumnName("is_locked");
+
+ b.Property("LastActivityAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("last_activity_at");
+
+ b.Property("LastFetchedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("last_fetched_at");
+
+ b.Property>("Metadata")
+ .HasColumnType("jsonb")
+ .HasColumnName("metadata");
+
+ b.Property("OutboxUri")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("outbox_uri");
+
+ b.Property("PublicKey")
+ .HasMaxLength(8192)
+ .HasColumnType("character varying(8192)")
+ .HasColumnName("public_key");
+
+ b.Property("PublicKeyId")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("public_key_id");
+
+ b.Property("PublisherId")
+ .HasColumnType("uuid")
+ .HasColumnName("publisher_id");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("type");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("updated_at");
+
+ b.Property("Uri")
+ .IsRequired()
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("uri");
+
+ b.Property("Username")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("username");
+
+ b.HasKey("Id")
+ .HasName("pk_fediverse_actors");
+
+ b.HasIndex("InstanceId")
+ .HasDatabaseName("ix_fediverse_actors_instance_id");
+
+ b.HasIndex("Uri")
+ .IsUnique()
+ .HasDatabaseName("ix_fediverse_actors_uri");
+
+ b.ToTable("fediverse_actors", (string)null);
+ });
+
+ modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseInstance", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("ActiveUsers")
+ .HasColumnType("integer")
+ .HasColumnName("active_users");
+
+ b.Property("BlockReason")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("block_reason");
+
+ b.Property("ContactAccountUsername")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("contact_account_username");
+
+ b.Property("ContactEmail")
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)")
+ .HasColumnName("contact_email");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property("DeletedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("deleted_at");
+
+ b.Property("Description")
+ .HasMaxLength(4096)
+ .HasColumnType("character varying(4096)")
+ .HasColumnName("description");
+
+ b.Property("Domain")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("domain");
+
+ b.Property("IconUrl")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("icon_url");
+
+ b.Property("IsBlocked")
+ .HasColumnType("boolean")
+ .HasColumnName("is_blocked");
+
+ b.Property("IsSilenced")
+ .HasColumnType("boolean")
+ .HasColumnName("is_silenced");
+
+ b.Property("LastActivityAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("last_activity_at");
+
+ b.Property("LastFetchedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("last_fetched_at");
+
+ b.Property>("Metadata")
+ .HasColumnType("jsonb")
+ .HasColumnName("metadata");
+
+ b.Property("MetadataFetchedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("metadata_fetched_at");
+
+ b.Property("Name")
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)")
+ .HasColumnName("name");
+
+ b.Property("Software")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("software");
+
+ b.Property("ThumbnailUrl")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("thumbnail_url");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("updated_at");
+
+ b.Property("Version")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)")
+ .HasColumnName("version");
+
+ b.HasKey("Id")
+ .HasName("pk_fediverse_instances");
+
+ b.HasIndex("Domain")
+ .IsUnique()
+ .HasDatabaseName("ix_fediverse_instances_domain");
+
+ b.ToTable("fediverse_instances", (string)null);
+ });
+
+ modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseRelationship", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("ActorId")
+ .HasColumnType("uuid")
+ .HasColumnName("actor_id");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property("DeletedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("deleted_at");
+
+ b.Property("FollowedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("followed_at");
+
+ b.Property("FollowedBackAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("followed_back_at");
+
+ b.Property("IsBlocking")
+ .HasColumnType("boolean")
+ .HasColumnName("is_blocking");
+
+ b.Property("IsFollowedBy")
+ .HasColumnType("boolean")
+ .HasColumnName("is_followed_by");
+
+ b.Property("IsFollowing")
+ .HasColumnType("boolean")
+ .HasColumnName("is_following");
+
+ b.Property("IsMuting")
+ .HasColumnType("boolean")
+ .HasColumnName("is_muting");
+
+ b.Property("RejectReason")
+ .HasMaxLength(4096)
+ .HasColumnType("character varying(4096)")
+ .HasColumnName("reject_reason");
+
+ b.Property("State")
+ .HasColumnType("integer")
+ .HasColumnName("state");
+
+ b.Property("TargetActorId")
+ .HasColumnType("uuid")
+ .HasColumnName("target_actor_id");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("updated_at");
+
+ b.HasKey("Id")
+ .HasName("pk_fediverse_relationships");
+
+ b.HasIndex("ActorId")
+ .HasDatabaseName("ix_fediverse_relationships_actor_id");
+
+ b.HasIndex("TargetActorId")
+ .HasDatabaseName("ix_fediverse_relationships_target_actor_id");
+
+ b.ToTable("fediverse_relationships", (string)null);
+ });
+
+ modelBuilder.Entity("DysonNetwork.Shared.Models.SnPoll", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property("DeletedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("deleted_at");
+
+ b.Property("Description")
+ .HasMaxLength(4096)
+ .HasColumnType("character varying(4096)")
+ .HasColumnName("description");
+
+ b.Property("EndedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("ended_at");
+
+ b.Property("IsAnonymous")
+ .HasColumnType("boolean")
+ .HasColumnName("is_anonymous");
+
+ b.Property("PublisherId")
+ .HasColumnType("uuid")
+ .HasColumnName("publisher_id");
+
+ b.Property("Title")
+ .HasMaxLength(1024)
+ .HasColumnType("character varying(1024)")
+ .HasColumnName("title");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("updated_at");
+
+ b.HasKey("Id")
+ .HasName("pk_polls");
+
+ b.HasIndex("PublisherId")
+ .HasDatabaseName("ix_polls_publisher_id");
+
+ b.ToTable("polls", (string)null);
+ });
+
+ modelBuilder.Entity("DysonNetwork.Shared.Models.SnPollAnswer", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("AccountId")
+ .HasColumnType("uuid")
+ .HasColumnName("account_id");
+
+ b.Property>("Answer")
+ .IsRequired()
+ .HasColumnType("jsonb")
+ .HasColumnName("answer");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property("DeletedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("deleted_at");
+
+ b.Property("PollId")
+ .HasColumnType("uuid")
+ .HasColumnName("poll_id");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("updated_at");
+
+ b.HasKey("Id")
+ .HasName("pk_poll_answers");
+
+ b.HasIndex("PollId")
+ .HasDatabaseName("ix_poll_answers_poll_id");
+
+ b.ToTable("poll_answers", (string)null);
+ });
+
+ modelBuilder.Entity("DysonNetwork.Shared.Models.SnPollQuestion", b =>
+ {
+ b.Property