using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Microsoft.EntityFrameworkCore; using NpgsqlTypes; using J = System.Text.Json.Serialization.JsonPropertyNameAttribute; namespace Iceshrimp.Backend.Core.Database.Tables; [Table("user_profile")] [Index("EnableWordMute")] [Index("UserHost")] [Index("PinnedPageId", IsUnique = true)] public class UserProfile { [Key] [Column("userId")] [StringLength(32)] public string UserId { get; set; } = null!; /// /// The location of the User. /// [Column("location")] [StringLength(128)] public string? Location { get; set; } /// /// The birthday (YYYY-MM-DD) of the User. /// [Column("birthday")] [StringLength(10)] public string? Birthday { get; set; } /// /// The description (bio) of the User. /// [Column("description")] [StringLength(2048)] public string? Description { get; set; } [Column("fields", TypeName = "jsonb")] public Field[] Fields { get; set; } = null!; /// /// Remote URL of the user. /// [Column("url")] [StringLength(512)] public string? Url { get; set; } [Column("ffVisibility")] public UserProfileFFVisibility FFVisibility { get; set; } [Column("mutingNotificationTypes")] public List MutingNotificationTypes { get; set; } = []; /// /// The email address of the User. /// [Column("email")] [StringLength(128)] public string? Email { get; set; } [Column("emailVerifyCode")] [StringLength(128)] public string? EmailVerifyCode { get; set; } [Column("emailVerified")] public bool EmailVerified { get; set; } [Column("twoFactorTempSecret")] [StringLength(128)] public string? TwoFactorTempSecret { get; set; } [Column("twoFactorSecret")] [StringLength(128)] public string? TwoFactorSecret { get; set; } [Column("twoFactorEnabled")] public bool TwoFactorEnabled { get; set; } /// /// The password hash of the User. It will be null if the origin of the user is local. /// [Column("password")] [StringLength(128)] public string? Password { get; set; } /// /// The client-specific data of the User. /// //TODO: refactor this column (it's currently a Dictionary, which is terrible) [Column("clientData", TypeName = "jsonb")] public string ClientData { get; set; } = null!; [Column("autoAcceptFollowed")] public bool AutoAcceptFollowed { get; set; } [Column("alwaysMarkNsfw")] public bool AlwaysMarkNsfw { get; set; } [Column("carefulBot")] public bool CarefulBot { get; set; } /// /// [Denormalized] /// [Column("userHost")] [StringLength(512)] public string? UserHost { get; set; } [Column("securityKeysAvailable")] public bool SecurityKeysAvailable { get; set; } [Column("usePasswordLessLogin")] public bool UsePasswordLessLogin { get; set; } [Column("pinnedPageId")] [StringLength(32)] public string? PinnedPageId { get; set; } /// /// The room data of the User. /// //TODO: refactor this column (it's currently a Dictionary, which is terrible) [Column("room", TypeName = "jsonb")] public string Room { get; set; } = null!; //TODO: refactor this column (it's currently a Dictionary, which is terrible) [Column("integrations", TypeName = "jsonb")] public string Integrations { get; set; } = null!; [Column("injectFeaturedNote")] public bool InjectFeaturedNote { get; set; } [Column("enableWordMute")] public bool EnableWordMute { get; set; } [Column("mutedWords", TypeName = "jsonb")] public List> MutedWords { get; set; } = null!; /// /// Whether reject index by crawler. /// [Column("noCrawle")] public bool NoCrawle { get; set; } [Column("receiveAnnouncementEmail")] public bool ReceiveAnnouncementEmail { get; set; } //TODO: refactor this column (this should have been NotificationTypeEnum[]) [Column("emailNotificationTypes", TypeName = "jsonb")] public List EmailNotificationTypes { get; set; } = null!; [Column("lang")] [StringLength(32)] public string? Lang { get; set; } /// /// List of instances muted by the user. /// //TODO: refactor this column (this should have been a varchar[]) [Column("mutedInstances", TypeName = "jsonb")] public List MutedInstances { get; set; } = null!; [Column("publicReactions")] public bool PublicReactions { get; set; } [Column("moderationNote")] [StringLength(8192)] public string ModerationNote { get; set; } = null!; [Column("preventAiLearning")] public bool PreventAiLearning { get; set; } [Column("mentions", TypeName = "jsonb")] public List Mentions { get; set; } = null!; [ForeignKey("PinnedPageId")] [InverseProperty(nameof(Page.UserProfile))] public virtual Page? PinnedPage { get; set; } [ForeignKey("UserId")] [InverseProperty(nameof(Tables.User.UserProfile))] public virtual User User { get; set; } = null!; [PgName("user_profile_ffvisibility_enum")] public enum UserProfileFFVisibility { [PgName("public")] Public, [PgName("followers")] Followers, [PgName("private")] Private, } public class Field { [J("name")] public required string Name { get; set; } [J("value")] public required string Value { get; set; } [J("verified")] public bool? IsVerified { get; set; } } public class MentionedRemoteUsers { [J("uri")] public required string Uri { get; set; } [J("url")] public string? Url { get; set; } [J("username")] public required string Username { get; set; } [J("host")] public required string Host { get; set; } } }