♻️ Finish centerlizing the data models

This commit is contained in:
2025-09-27 15:14:05 +08:00
parent e70d8371f8
commit 9ce31c4dd8
167 changed files with 780 additions and 42880 deletions

View File

@@ -23,18 +23,18 @@ public class SnAccount : ModelBase
public Guid? AutomatedId { get; set; }
public SnAccountProfile Profile { get; set; } = null!;
public ICollection<AccountContact> Contacts { get; set; } = [];
public ICollection<SnAccountContact> Contacts { get; set; } = [];
public ICollection<SnAccountBadge> Badges { get; set; } = [];
[JsonIgnore] public ICollection<AccountAuthFactor> AuthFactors { get; set; } = [];
[JsonIgnore] public ICollection<AccountConnection> Connections { get; set; } = [];
[JsonIgnore] public ICollection<SnAccountAuthFactor> AuthFactors { get; set; } = [];
[JsonIgnore] public ICollection<SnAccountConnection> Connections { get; set; } = [];
[JsonIgnore] public ICollection<SnAuthSession> Sessions { get; set; } = [];
[JsonIgnore] public ICollection<SnAuthChallenge> Challenges { get; set; } = [];
[JsonIgnore] public ICollection<SnAccountRelationship> OutgoingRelationships { get; set; } = [];
[JsonIgnore] public ICollection<SnAccountRelationship> IncomingRelationships { get; set; } = [];
[NotMapped] public SubscriptionReferenceObject? PerkSubscription { get; set; }
[NotMapped] public SnSubscriptionReferenceObject? PerkSubscription { get; set; }
public Proto.Account ToProtoValue()
{
@@ -78,7 +78,7 @@ public class SnAccount : ModelBase
ActivatedAt = proto.ActivatedAt?.ToInstant(),
IsSuperuser = proto.IsSuperuser,
PerkSubscription = proto.PerkSubscription is not null
? SubscriptionReferenceObject.FromProtoValue(proto.PerkSubscription)
? SnSubscriptionReferenceObject.FromProtoValue(proto.PerkSubscription)
: null,
CreatedAt = proto.CreatedAt.ToInstant(),
UpdatedAt = proto.UpdatedAt.ToInstant(),
@@ -87,7 +87,7 @@ public class SnAccount : ModelBase
};
foreach (var contactProto in proto.Contacts)
account.Contacts.Add(AccountContact.FromProtoValue(contactProto));
account.Contacts.Add(SnAccountContact.FromProtoValue(contactProto));
foreach (var badgeProto in proto.Badges)
account.Badges.Add(SnAccountBadge.FromProtoValue(badgeProto));
@@ -254,7 +254,7 @@ public class ProfileLink
public string Url { get; set; } = string.Empty;
}
public class AccountContact : ModelBase
public class SnAccountContact : ModelBase
{
public Guid Id { get; set; }
public AccountContactType Type { get; set; }
@@ -289,9 +289,9 @@ public class AccountContact : ModelBase
return proto;
}
public static AccountContact FromProtoValue(Proto.AccountContact proto)
public static SnAccountContact FromProtoValue(Proto.AccountContact proto)
{
var contact = new AccountContact
var contact = new SnAccountContact
{
Id = Guid.Parse(proto.Id),
AccountId = Guid.Parse(proto.AccountId),
@@ -320,7 +320,7 @@ public enum AccountContactType
Address
}
public class AccountAuthFactor : ModelBase
public class SnAccountAuthFactor : ModelBase
{
public Guid Id { get; set; }
public AccountAuthFactorType Type { get; set; }
@@ -343,7 +343,7 @@ public class AccountAuthFactor : ModelBase
public Guid AccountId { get; set; }
[JsonIgnore] public SnAccount Account { get; set; } = null!;
public AccountAuthFactor HashSecret(int cost = 12)
public SnAccountAuthFactor HashSecret(int cost = 12)
{
if (Secret == null) return this;
Secret = BCrypt.Net.BCrypt.HashPassword(Secret, workFactor: cost);
@@ -386,7 +386,7 @@ public enum AccountAuthFactorType
PinCode,
}
public class AccountConnection : ModelBase
public class SnAccountConnection : ModelBase
{
public Guid Id { get; set; } = Guid.NewGuid();
[MaxLength(4096)] public string Provider { get; set; } = null!;

View File

@@ -40,4 +40,44 @@ public class SnActionLog : ModelBase
return protoLog;
}
}
public abstract class ActionLogType
{
public const string NewLogin = "login";
public const string ChallengeAttempt = "challenges.attempt";
public const string ChallengeSuccess = "challenges.success";
public const string ChallengeFailure = "challenges.failure";
public const string PostCreate = "posts.create";
public const string PostUpdate = "posts.update";
public const string PostDelete = "posts.delete";
public const string PostReact = "posts.react";
public const string PostPin = "posts.pin";
public const string PostUnpin = "posts.unpin";
public const string MessageCreate = "messages.create";
public const string MessageUpdate = "messages.update";
public const string MessageDelete = "messages.delete";
public const string MessageReact = "messages.react";
public const string PublisherCreate = "publishers.create";
public const string PublisherUpdate = "publishers.update";
public const string PublisherDelete = "publishers.delete";
public const string PublisherMemberInvite = "publishers.members.invite";
public const string PublisherMemberJoin = "publishers.members.join";
public const string PublisherMemberLeave = "publishers.members.leave";
public const string PublisherMemberKick = "publishers.members.kick";
public const string RealmCreate = "realms.create";
public const string RealmUpdate = "realms.update";
public const string RealmDelete = "realms.delete";
public const string RealmInvite = "realms.invite";
public const string RealmJoin = "realms.join";
public const string RealmLeave = "realms.leave";
public const string RealmKick = "realms.kick";
public const string RealmAdjustRole = "realms.role.edit";
public const string ChatroomCreate = "chatrooms.create";
public const string ChatroomUpdate = "chatrooms.update";
public const string ChatroomDelete = "chatrooms.delete";
public const string ChatroomInvite = "chatrooms.invite";
public const string ChatroomJoin = "chatrooms.join";
public const string ChatroomLeave = "chatrooms.leave";
public const string ChatroomKick = "chatrooms.kick";
public const string ChatroomAdjustRole = "chatrooms.role.edit";
}

View File

@@ -1,6 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using DysonNetwork.Shared.Data;
using NodaTime.Serialization.Protobuf;
namespace DysonNetwork.Shared.Models;

View File

@@ -5,8 +5,6 @@ using Google.Protobuf.WellKnownTypes;
using NodaTime.Serialization.Protobuf;
using NodaTime;
using SnVerificationMark = DysonNetwork.Shared.Models.SnVerificationMark;
namespace DysonNetwork.Shared.Models;
public enum CustomAppStatus
@@ -29,8 +27,8 @@ public class SnCustomApp : ModelBase, IIdentifiedResource
[Column(TypeName = "jsonb")] public SnCloudFileReferenceObject? Background { get; set; }
[Column(TypeName = "jsonb")] public SnVerificationMark? Verification { get; set; }
[Column(TypeName = "jsonb")] public CustomAppOauthConfig? OauthConfig { get; set; }
[Column(TypeName = "jsonb")] public CustomAppLinks? Links { get; set; }
[Column(TypeName = "jsonb")] public SnCustomAppOauthConfig? OauthConfig { get; set; }
[Column(TypeName = "jsonb")] public SnCustomAppLinks? Links { get; set; }
[JsonIgnore] public ICollection<SnCustomAppSecret> Secrets { get; set; } = new List<SnCustomAppSecret>();
@@ -105,7 +103,7 @@ public class SnCustomApp : ModelBase, IIdentifiedResource
if (p.Verification is not null) Verification = SnVerificationMark.FromProtoValue(p.Verification);
if (p.Links is not null)
{
Links = new CustomAppLinks
Links = new SnCustomAppLinks
{
HomePage = string.IsNullOrEmpty(p.Links.HomePage) ? null : p.Links.HomePage,
PrivacyPolicy = string.IsNullOrEmpty(p.Links.PrivacyPolicy) ? null : p.Links.PrivacyPolicy,
@@ -116,14 +114,14 @@ public class SnCustomApp : ModelBase, IIdentifiedResource
}
}
public class CustomAppLinks
public class SnCustomAppLinks
{
[MaxLength(8192)] public string? HomePage { get; set; }
[MaxLength(8192)] public string? PrivacyPolicy { get; set; }
[MaxLength(8192)] public string? TermsOfService { get; set; }
}
public class CustomAppOauthConfig
public class SnCustomAppOauthConfig
{
[MaxLength(1024)] public string? ClientUri { get; set; }
[MaxLength(4096)] public string[] RedirectUris { get; set; } = [];

View File

@@ -3,7 +3,7 @@ using NodaTime.Serialization.Protobuf;
namespace DysonNetwork.Shared.Models;
public class ExperienceRecord : ModelBase
public class SnExperienceRecord : ModelBase
{
public Guid Id { get; set; } = Guid.NewGuid();
[MaxLength(1024)] public string ReasonType { get; set; } = string.Empty;

View File

@@ -1,7 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
using DysonNetwork.Shared.Data;
using NodaTime;
namespace DysonNetwork.Shared.Models;

View File

@@ -4,6 +4,7 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.EntityFrameworkCore;
using NodaTime;
using NodaTime.Serialization.Protobuf;
namespace DysonNetwork.Shared.Models;
@@ -32,6 +33,21 @@ public class SnPermissionNode : ModelBase, IDisposable
public Guid? GroupId { get; set; } = null;
[JsonIgnore] public SnPermissionGroup? Group { get; set; } = null;
public Proto.PermissionNode ToProtoValue()
{
return new Proto.PermissionNode
{
Id = Id.ToString(),
Actor = Actor,
Area = Area,
Key = Key,
Value = Google.Protobuf.WellKnownTypes.Value.Parser.ParseJson(Value.RootElement.GetRawText()),
ExpiredAt = ExpiredAt?.ToTimestamp(),
AffectedAt = AffectedAt?.ToTimestamp(),
GroupId = GroupId?.ToString() ?? string.Empty
};
}
public void Dispose()
{
Value.Dispose();

View File

@@ -2,7 +2,6 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;
using System.Text.Json.Serialization;
using DysonNetwork.Shared.Data;
using NodaTime;
namespace DysonNetwork.Shared.Models;

View File

@@ -1,7 +1,6 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
using DysonNetwork.Shared.Proto;
using Microsoft.EntityFrameworkCore;
using NodaTime;
using NodaTime.Serialization.Protobuf;
@@ -36,18 +35,60 @@ public class SnPublisher : ModelBase, IIdentifiedResource
[JsonIgnore] public ICollection<SnPoll> Polls { get; set; } = [];
[JsonIgnore] public ICollection<SnPostCollection> Collections { get; set; } = [];
[JsonIgnore] public ICollection<SnPublisherMember> Members { get; set; } = [];
[JsonIgnore] public ICollection<PublisherFeature> Features { get; set; } = [];
[JsonIgnore] public ICollection<SnPublisherFeature> Features { get; set; } = [];
[JsonIgnore]
public ICollection<PublisherSubscription> Subscriptions { get; set; } = [];
public ICollection<SnPublisherSubscription> Subscriptions { get; set; } = [];
public Guid? AccountId { get; set; }
public Guid? RealmId { get; set; }
[JsonIgnore] public SnRealm? Realm { get; set; }
[NotMapped] public Account? Account { get; set; }
[NotMapped] public SnAccount? Account { get; set; }
public string ResourceIdentifier => $"publisher:{Id}";
public static SnPublisher FromProto(Proto.Publisher proto)
{
var publisher = new SnPublisher
{
Id = Guid.TryParse(proto.Id, out var id) ? id : Guid.NewGuid(),
Type = proto.Type == Shared.Proto.PublisherType.PubIndividual
? PublisherType.Individual
: PublisherType.Organizational,
Name = proto.Name,
Nick = proto.Nick,
Bio = proto.Bio,
AccountId = Guid.TryParse(proto.AccountId, out var accountId) ? accountId : null,
RealmId = Guid.TryParse(proto.RealmId, out var realmId) ? realmId : null,
};
if (proto.Picture != null)
{
publisher.Picture = new SnCloudFileReferenceObject
{
Id = proto.Picture.Id,
Name = proto.Picture.Name,
MimeType = proto.Picture.MimeType,
Hash = proto.Picture.Hash,
Size = proto.Picture.Size,
};
}
if (proto.Background != null)
{
publisher.Background = new SnCloudFileReferenceObject
{
Id = proto.Background.Id,
Name = proto.Background.Name,
MimeType = proto.Background.MimeType,
Hash = proto.Background.Hash,
Size = proto.Background.Size,
};
}
return publisher;
}
public Proto.Publisher ToProto()
{
var p = new Proto.Publisher()
@@ -105,7 +146,7 @@ public class SnPublisherMember : ModelBase
public Guid PublisherId { get; set; }
[JsonIgnore] public SnPublisher Publisher { get; set; } = null!;
public Guid AccountId { get; set; }
[NotMapped] public Account? Account { get; set; }
[NotMapped] public SnAccount? Account { get; set; }
public PublisherMemberRole Role { get; set; } = PublisherMemberRole.Viewer;
public Instant? JoinedAt { get; set; }
@@ -137,7 +178,7 @@ public enum PublisherSubscriptionStatus
Cancelled
}
public class PublisherSubscription : ModelBase
public class SnPublisherSubscription : ModelBase
{
public Guid Id { get; set; }
@@ -149,7 +190,7 @@ public class PublisherSubscription : ModelBase
public int Tier { get; set; } = 0;
}
public class PublisherFeature : ModelBase
public class SnPublisherFeature : ModelBase
{
public Guid Id { get; set; }
[MaxLength(1024)] public string Flag { get; set; } = null!;

View File

@@ -4,7 +4,7 @@ using NodaTime.Serialization.Protobuf;
namespace DysonNetwork.Shared.Models;
public class SocialCreditRecord : ModelBase
public class SnSocialCreditRecord : ModelBase
{
public Guid Id { get; set; }
[MaxLength(1024)] public string ReasonType { get; set; } = string.Empty;

View File

@@ -104,7 +104,7 @@ public enum SubscriptionStatus
/// The paid subscription in another word.
/// </summary>
[Index(nameof(Identifier))]
public class SnSubscription : ModelBase
public class SnWalletSubscription : ModelBase
{
public Guid Id { get; set; } = Guid.NewGuid();
public Instant BegunAt { get; set; }
@@ -133,10 +133,10 @@ public class SnSubscription : ModelBase
public SubscriptionStatus Status { get; set; } = SubscriptionStatus.Unpaid;
[MaxLength(4096)] public string PaymentMethod { get; set; } = null!;
[Column(TypeName = "jsonb")] public PaymentDetails PaymentDetails { get; set; } = null!;
[Column(TypeName = "jsonb")] public SnPaymentDetails PaymentDetails { get; set; } = null!;
public decimal BasePrice { get; set; }
public Guid? CouponId { get; set; }
public Coupon? Coupon { get; set; }
public SnWalletCoupon? Coupon { get; set; }
public Instant? RenewalAt { get; set; }
public Guid AccountId { get; set; }
@@ -182,9 +182,9 @@ public class SnSubscription : ModelBase
/// Returns a reference object that contains a subset of subscription data
/// suitable for client-side use, with sensitive information removed.
/// </summary>
public SubscriptionReferenceObject ToReference()
public SnSubscriptionReferenceObject ToReference()
{
return new SubscriptionReferenceObject
return new SnSubscriptionReferenceObject
{
Id = Id,
Identifier = Identifier,
@@ -223,7 +223,7 @@ public class SnSubscription : ModelBase
UpdatedAt = UpdatedAt.ToTimestamp()
};
public static SnSubscription FromProtoValue(Proto.Subscription proto) => new()
public static SnWalletSubscription FromProtoValue(Proto.Subscription proto) => new()
{
Id = Guid.Parse(proto.Id),
BegunAt = proto.BegunAt.ToInstant(),
@@ -233,10 +233,10 @@ public class SnSubscription : ModelBase
IsFreeTrial = proto.IsFreeTrial,
Status = (SubscriptionStatus)proto.Status,
PaymentMethod = proto.PaymentMethod,
PaymentDetails = PaymentDetails.FromProtoValue(proto.PaymentDetails),
PaymentDetails = SnPaymentDetails.FromProtoValue(proto.PaymentDetails),
BasePrice = decimal.Parse(proto.BasePrice),
CouponId = proto.HasCouponId ? Guid.Parse(proto.CouponId) : null,
Coupon = proto.Coupon is not null ? Coupon.FromProtoValue(proto.Coupon) : null,
Coupon = proto.Coupon is not null ? SnWalletCoupon.FromProtoValue(proto.Coupon) : null,
RenewalAt = proto.RenewalAt?.ToInstant(),
AccountId = Guid.Parse(proto.AccountId),
CreatedAt = proto.CreatedAt.ToInstant(),
@@ -248,7 +248,7 @@ public class SnSubscription : ModelBase
/// A reference object for Subscription that contains only non-sensitive information
/// suitable for client-side use.
/// </summary>
public class SubscriptionReferenceObject : ModelBase
public class SnSubscriptionReferenceObject : ModelBase
{
public Guid Id { get; set; }
public string Identifier { get; set; } = null!;
@@ -290,7 +290,7 @@ public class SubscriptionReferenceObject : ModelBase
UpdatedAt = UpdatedAt.ToTimestamp()
};
public static SubscriptionReferenceObject FromProtoValue(Proto.SubscriptionReferenceObject proto) => new()
public static SnSubscriptionReferenceObject FromProtoValue(Proto.SubscriptionReferenceObject proto) => new()
{
Id = Guid.Parse(proto.Id),
Identifier = proto.Identifier,
@@ -309,7 +309,7 @@ public class SubscriptionReferenceObject : ModelBase
};
}
public class PaymentDetails
public class SnPaymentDetails
{
public string Currency { get; set; } = null!;
public string? OrderId { get; set; }
@@ -320,7 +320,7 @@ public class PaymentDetails
OrderId = OrderId,
};
public static PaymentDetails FromProtoValue(Proto.PaymentDetails proto) => new()
public static SnPaymentDetails FromProtoValue(Proto.PaymentDetails proto) => new()
{
Currency = proto.Currency,
OrderId = proto.OrderId,
@@ -331,7 +331,7 @@ public class PaymentDetails
/// A discount that can applies in purchases among the Solar Network.
/// For now, it can be used in the subscription purchase.
/// </summary>
public class Coupon : ModelBase
public class SnWalletCoupon : ModelBase
{
public Guid Id { get; set; } = Guid.NewGuid();
@@ -388,7 +388,7 @@ public class Coupon : ModelBase
UpdatedAt = UpdatedAt.ToTimestamp()
};
public static Coupon FromProtoValue(Proto.Coupon proto) => new()
public static SnWalletCoupon FromProtoValue(Proto.Coupon proto) => new()
{
Id = Guid.Parse(proto.Id),
Identifier = proto.Identifier,