diff --git a/DysonNetwork.Pass/Migrations/20251116153151_OpenableFunds.Designer.cs b/DysonNetwork.Pass/Migrations/20251116153151_OpenableFunds.Designer.cs new file mode 100644 index 0000000..c43fd62 --- /dev/null +++ b/DysonNetwork.Pass/Migrations/20251116153151_OpenableFunds.Designer.cs @@ -0,0 +1,2722 @@ +// +using System; +using System.Collections.Generic; +using System.Text.Json; +using DysonNetwork.Pass; +using DysonNetwork.Shared.GeoIp; +using DysonNetwork.Shared.Models; +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.Pass.Migrations +{ + [DbContext(typeof(AppDatabase))] + [Migration("20251116153151_OpenableFunds")] + partial class OpenableFunds + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.11") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAbuseReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_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("Reason") + .IsRequired() + .HasMaxLength(8192) + .HasColumnType("character varying(8192)") + .HasColumnName("reason"); + + b.Property("Resolution") + .HasMaxLength(8192) + .HasColumnType("character varying(8192)") + .HasColumnName("resolution"); + + b.Property("ResolvedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("resolved_at"); + + b.Property("ResourceIdentifier") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("resource_identifier"); + + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_abuse_reports"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_abuse_reports_account_id"); + + b.ToTable("abuse_reports", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("ActivatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("activated_at"); + + b.Property("AutomatedId") + .HasColumnType("uuid") + .HasColumnName("automated_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("IsSuperuser") + .HasColumnType("boolean") + .HasColumnName("is_superuser"); + + b.Property("Language") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("language"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("name"); + + b.Property("Nick") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("nick"); + + b.Property("Region") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("region"); + + b.Property("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.Shared.Models.SnAccountAuthFactor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property>("Config") + .HasColumnType("jsonb") + .HasColumnName("config"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("EnabledAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("enabled_at"); + + b.Property("ExpiredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expired_at"); + + b.Property("Secret") + .HasMaxLength(8196) + .HasColumnType("character varying(8196)") + .HasColumnName("secret"); + + b.Property("Trustworthy") + .HasColumnType("integer") + .HasColumnName("trustworthy"); + + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.Property("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.Shared.Models.SnAccountBadge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property("ActivatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("activated_at"); + + b.Property("Caption") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("caption"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("ExpiredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expired_at"); + + b.Property("Label") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("label"); + + b.Property>("Meta") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("meta"); + + 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_badges"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_badges_account_id"); + + b.ToTable("badges", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAccountConnection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccessToken") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("access_token"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_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("LastUsedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_used_at"); + + b.Property>("Meta") + .HasColumnType("jsonb") + .HasColumnName("meta"); + + b.Property("ProvidedIdentifier") + .IsRequired() + .HasMaxLength(8192) + .HasColumnType("character varying(8192)") + .HasColumnName("provided_identifier"); + + b.Property("Provider") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("provider"); + + b.Property("RefreshToken") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("refresh_token"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_account_connections"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_account_connections_account_id"); + + b.ToTable("account_connections", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAccountContact", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .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("IsPrimary") + .HasColumnType("boolean") + .HasColumnName("is_primary"); + + b.Property("IsPublic") + .HasColumnType("boolean") + .HasColumnName("is_public"); + + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.Property("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.Shared.Models.SnAccountProfile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property("ActiveBadge") + .HasColumnType("jsonb") + .HasColumnName("active_badge"); + + b.Property("Background") + .HasColumnType("jsonb") + .HasColumnName("background"); + + b.Property("Bio") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("bio"); + + b.Property("Birthday") + .HasColumnType("timestamp with time zone") + .HasColumnName("birthday"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("Experience") + .HasColumnType("integer") + .HasColumnName("experience"); + + b.Property("FirstName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("first_name"); + + b.Property("Gender") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("gender"); + + b.Property("LastName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("last_name"); + + b.Property("LastSeenAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_seen_at"); + + b.Property>("Links") + .HasColumnType("jsonb") + .HasColumnName("links"); + + b.Property("Location") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("location"); + + b.Property("MiddleName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("middle_name"); + + b.Property("Picture") + .HasColumnType("jsonb") + .HasColumnName("picture"); + + b.Property("Pronouns") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("pronouns"); + + b.Property("SocialCredits") + .HasColumnType("double precision") + .HasColumnName("social_credits"); + + b.Property("TimeZone") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("time_zone"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.Property("UsernameColor") + .HasColumnType("jsonb") + .HasColumnName("username_color"); + + b.Property("Verification") + .HasColumnType("jsonb") + .HasColumnName("verification"); + + b.HasKey("Id") + .HasName("pk_account_profiles"); + + b.HasIndex("AccountId") + .IsUnique() + .HasDatabaseName("ix_account_profiles_account_id"); + + b.ToTable("account_profiles", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAccountPunishment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property>("BlockedPermissions") + .HasColumnType("jsonb") + .HasColumnName("blocked_permissions"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("ExpiredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expired_at"); + + b.Property("Reason") + .IsRequired() + .HasMaxLength(8192) + .HasColumnType("character varying(8192)") + .HasColumnName("reason"); + + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_punishments"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_punishments_account_id"); + + b.ToTable("punishments", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAccountRelationship", b => + { + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property("RelatedId") + .HasColumnType("uuid") + .HasColumnName("related_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("ExpiredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expired_at"); + + b.Property("Status") + .HasColumnType("smallint") + .HasColumnName("status"); + + b.Property("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.Shared.Models.SnAccountStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property("AppIdentifier") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("app_identifier"); + + b.Property("Attitude") + .HasColumnType("integer") + .HasColumnName("attitude"); + + b.Property("ClearedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("cleared_at"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("IsAutomated") + .HasColumnType("boolean") + .HasColumnName("is_automated"); + + b.Property("IsInvisible") + .HasColumnType("boolean") + .HasColumnName("is_invisible"); + + b.Property("IsNotDisturb") + .HasColumnType("boolean") + .HasColumnName("is_not_disturb"); + + b.Property("Label") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("label"); + + b.Property>("Meta") + .HasColumnType("jsonb") + .HasColumnName("meta"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_account_statuses"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_account_statuses_account_id"); + + b.ToTable("account_statuses", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnActionLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property("Action") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("action"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("IpAddress") + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("ip_address"); + + b.Property("Location") + .HasColumnType("jsonb") + .HasColumnName("location"); + + b.Property>("Meta") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("meta"); + + b.Property("SessionId") + .HasColumnType("uuid") + .HasColumnName("session_id"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.Property("UserAgent") + .HasMaxLength(512) + .HasColumnType("character varying(512)") + .HasColumnName("user_agent"); + + b.HasKey("Id") + .HasName("pk_action_logs"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_action_logs_account_id"); + + b.ToTable("action_logs", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_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("Label") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("label"); + + b.Property("SessionId") + .HasColumnType("uuid") + .HasColumnName("session_id"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_api_keys"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_api_keys_account_id"); + + b.HasIndex("SessionId") + .HasDatabaseName("ix_api_keys_session_id"); + + b.ToTable("api_keys", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAuthChallenge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property>("Audiences") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("audiences"); + + b.Property>("BlacklistFactors") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("blacklist_factors"); + + b.Property("ClientId") + .HasColumnType("uuid") + .HasColumnName("client_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("ExpiredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expired_at"); + + b.Property("FailedAttempts") + .HasColumnType("integer") + .HasColumnName("failed_attempts"); + + b.Property("IpAddress") + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("ip_address"); + + b.Property("Location") + .HasColumnType("jsonb") + .HasColumnName("location"); + + b.Property("Nonce") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("nonce"); + + b.Property>("Scopes") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("scopes"); + + b.Property("StepRemain") + .HasColumnType("integer") + .HasColumnName("step_remain"); + + b.Property("StepTotal") + .HasColumnType("integer") + .HasColumnName("step_total"); + + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.Property("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.HasIndex("ClientId") + .HasDatabaseName("ix_auth_challenges_client_id"); + + b.ToTable("auth_challenges", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAuthClient", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_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("DeviceId") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("device_id"); + + b.Property("DeviceLabel") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("device_label"); + + b.Property("DeviceName") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("device_name"); + + b.Property("Platform") + .HasColumnType("integer") + .HasColumnName("platform"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_auth_clients"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_auth_clients_account_id"); + + b.ToTable("auth_clients", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAuthSession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property("AppId") + .HasColumnType("uuid") + .HasColumnName("app_id"); + + b.Property("ChallengeId") + .HasColumnType("uuid") + .HasColumnName("challenge_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("ExpiredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expired_at"); + + b.Property("LastGrantedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_granted_at"); + + b.Property("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.Shared.Models.SnCheckInResult", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property("BackdatedFrom") + .HasColumnType("timestamp with time zone") + .HasColumnName("backdated_from"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("Level") + .HasColumnType("integer") + .HasColumnName("level"); + + b.Property("RewardExperience") + .HasColumnType("integer") + .HasColumnName("reward_experience"); + + b.Property("RewardPoints") + .HasColumnType("numeric") + .HasColumnName("reward_points"); + + b.Property>("Tips") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("tips"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_account_check_in_results"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_account_check_in_results_account_id"); + + b.ToTable("account_check_in_results", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnExperienceRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property("BonusMultiplier") + .HasColumnType("double precision") + .HasColumnName("bonus_multiplier"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("Delta") + .HasColumnType("bigint") + .HasColumnName("delta"); + + b.Property("Reason") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("reason"); + + b.Property("ReasonType") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("reason_type"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_experience_records"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_experience_records_account_id"); + + b.ToTable("experience_records", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnLottery", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_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("DrawDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("draw_date"); + + b.Property("DrawStatus") + .HasColumnType("integer") + .HasColumnName("draw_status"); + + b.Property>("MatchedRegionOneNumbers") + .HasColumnType("jsonb") + .HasColumnName("matched_region_one_numbers"); + + b.Property("MatchedRegionTwoNumber") + .HasColumnType("integer") + .HasColumnName("matched_region_two_number"); + + b.Property("Multiplier") + .HasColumnType("integer") + .HasColumnName("multiplier"); + + b.Property>("RegionOneNumbers") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("region_one_numbers"); + + b.Property("RegionTwoNumber") + .HasColumnType("integer") + .HasColumnName("region_two_number"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_lotteries"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_lotteries_account_id"); + + b.ToTable("lotteries", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnLotteryRecord", 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("DrawDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("draw_date"); + + b.Property("TotalPrizeAmount") + .HasColumnType("bigint") + .HasColumnName("total_prize_amount"); + + b.Property("TotalPrizesAwarded") + .HasColumnType("integer") + .HasColumnName("total_prizes_awarded"); + + b.Property("TotalTickets") + .HasColumnType("integer") + .HasColumnName("total_tickets"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.Property>("WinningRegionOneNumbers") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("winning_region_one_numbers"); + + b.Property("WinningRegionTwoNumber") + .HasColumnType("integer") + .HasColumnName("winning_region_two_number"); + + b.HasKey("Id") + .HasName("pk_lottery_records"); + + b.ToTable("lottery_records", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnMagicSpell", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property("AffectedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("affected_at"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expires_at"); + + b.Property>("Meta") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("meta"); + + b.Property("Spell") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("spell"); + + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.Property("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.Shared.Models.SnPermissionGroup", 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("Key") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("key"); + + b.Property("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.Shared.Models.SnPermissionGroupMember", b => + { + b.Property("GroupId") + .HasColumnType("uuid") + .HasColumnName("group_id"); + + b.Property("Actor") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("actor"); + + b.Property("AffectedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("affected_at"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("ExpiredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expired_at"); + + b.Property("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.Shared.Models.SnPermissionNode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Actor") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("actor"); + + b.Property("AffectedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("affected_at"); + + b.Property("Area") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("area"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("ExpiredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expired_at"); + + b.Property("GroupId") + .HasColumnType("uuid") + .HasColumnName("group_id"); + + b.Property("Key") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("key"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.Property("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.Shared.Models.SnPresenceActivity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property("Caption") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("caption"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("LargeImage") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("large_image"); + + b.Property("LeaseExpiresAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("lease_expires_at"); + + b.Property("LeaseMinutes") + .HasColumnType("integer") + .HasColumnName("lease_minutes"); + + b.Property("ManualId") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("manual_id"); + + b.Property>("Meta") + .HasColumnType("jsonb") + .HasColumnName("meta"); + + b.Property("SmallImage") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("small_image"); + + b.Property("Subtitle") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("subtitle"); + + b.Property("SubtitleUrl") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("subtitle_url"); + + b.Property("Title") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("title"); + + b.Property("TitleUrl") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("title_url"); + + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_presence_activities"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_presence_activities_account_id"); + + b.ToTable("presence_activities", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnRealm", 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") + .IsRequired() + .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") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("name"); + + b.Property("Picture") + .HasColumnType("jsonb") + .HasColumnName("picture"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("slug"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.Property("Verification") + .HasColumnType("jsonb") + .HasColumnName("verification"); + + b.HasKey("Id") + .HasName("pk_realms"); + + b.HasIndex("Slug") + .IsUnique() + .HasDatabaseName("ix_realms_slug"); + + b.ToTable("realms", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnRealmMember", b => + { + b.Property("RealmId") + .HasColumnType("uuid") + .HasColumnName("realm_id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_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("JoinedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("joined_at"); + + b.Property("LeaveAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("leave_at"); + + b.Property("Role") + .HasColumnType("integer") + .HasColumnName("role"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("RealmId", "AccountId") + .HasName("pk_realm_members"); + + b.ToTable("realm_members", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnSocialCreditRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_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("Delta") + .HasColumnType("double precision") + .HasColumnName("delta"); + + b.Property("ExpiredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expired_at"); + + b.Property("Reason") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("reason"); + + b.Property("ReasonType") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("reason_type"); + + b.Property("Status") + .HasColumnType("integer") + .HasColumnName("status"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_social_credit_records"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_social_credit_records_account_id"); + + b.ToTable("social_credit_records", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWallet", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_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("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_wallets"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_wallets_account_id"); + + b.ToTable("wallets", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletCoupon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AffectedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("affected_at"); + + b.Property("Code") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("code"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("DiscountAmount") + .HasColumnType("numeric") + .HasColumnName("discount_amount"); + + b.Property("DiscountRate") + .HasColumnType("double precision") + .HasColumnName("discount_rate"); + + b.Property("ExpiredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expired_at"); + + b.Property("Identifier") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("identifier"); + + b.Property("MaxUsage") + .HasColumnType("integer") + .HasColumnName("max_usage"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_wallet_coupons"); + + b.ToTable("wallet_coupons", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletFund", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("CreatorAccountId") + .HasColumnType("uuid") + .HasColumnName("creator_account_id"); + + b.Property("Currency") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("currency"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("ExpiredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expired_at"); + + b.Property("IsOpen") + .HasColumnType("boolean") + .HasColumnName("is_open"); + + b.Property("Message") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("message"); + + b.Property("RemainingAmount") + .HasColumnType("numeric") + .HasColumnName("remaining_amount"); + + b.Property("SplitType") + .HasColumnType("integer") + .HasColumnName("split_type"); + + b.Property("Status") + .HasColumnType("integer") + .HasColumnName("status"); + + b.Property("TotalAmount") + .HasColumnType("numeric") + .HasColumnName("total_amount"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_wallet_funds"); + + b.HasIndex("CreatorAccountId") + .HasDatabaseName("ix_wallet_funds_creator_account_id"); + + b.ToTable("wallet_funds", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletFundRecipient", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Amount") + .HasColumnType("numeric") + .HasColumnName("amount"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("FundId") + .HasColumnType("uuid") + .HasColumnName("fund_id"); + + b.Property("IsReceived") + .HasColumnType("boolean") + .HasColumnName("is_received"); + + b.Property("ReceivedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("received_at"); + + b.Property("RecipientAccountId") + .HasColumnType("uuid") + .HasColumnName("recipient_account_id"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_wallet_fund_recipients"); + + b.HasIndex("FundId") + .HasDatabaseName("ix_wallet_fund_recipients_fund_id"); + + b.HasIndex("RecipientAccountId") + .HasDatabaseName("ix_wallet_fund_recipients_recipient_account_id"); + + b.ToTable("wallet_fund_recipients", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletGift", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("BasePrice") + .HasColumnType("numeric") + .HasColumnName("base_price"); + + b.Property("CouponId") + .HasColumnType("uuid") + .HasColumnName("coupon_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("ExpiresAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expires_at"); + + b.Property("FinalPrice") + .HasColumnType("numeric") + .HasColumnName("final_price"); + + b.Property("GiftCode") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("gift_code"); + + b.Property("GifterId") + .HasColumnType("uuid") + .HasColumnName("gifter_id"); + + b.Property("IsOpenGift") + .HasColumnType("boolean") + .HasColumnName("is_open_gift"); + + b.Property("Message") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)") + .HasColumnName("message"); + + b.Property("PaymentDetails") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("payment_details"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("payment_method"); + + b.Property("RecipientId") + .HasColumnType("uuid") + .HasColumnName("recipient_id"); + + b.Property("RedeemedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("redeemed_at"); + + b.Property("RedeemerId") + .HasColumnType("uuid") + .HasColumnName("redeemer_id"); + + b.Property("Status") + .HasColumnType("integer") + .HasColumnName("status"); + + b.Property("SubscriptionId") + .HasColumnType("uuid") + .HasColumnName("subscription_id"); + + b.Property("SubscriptionIdentifier") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("subscription_identifier"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_wallet_gifts"); + + b.HasIndex("CouponId") + .HasDatabaseName("ix_wallet_gifts_coupon_id"); + + b.HasIndex("GiftCode") + .HasDatabaseName("ix_wallet_gifts_gift_code"); + + b.HasIndex("GifterId") + .HasDatabaseName("ix_wallet_gifts_gifter_id"); + + b.HasIndex("RecipientId") + .HasDatabaseName("ix_wallet_gifts_recipient_id"); + + b.HasIndex("RedeemerId") + .HasDatabaseName("ix_wallet_gifts_redeemer_id"); + + b.HasIndex("SubscriptionId") + .IsUnique() + .HasDatabaseName("ix_wallet_gifts_subscription_id"); + + b.ToTable("wallet_gifts", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletOrder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Amount") + .HasColumnType("numeric") + .HasColumnName("amount"); + + b.Property("AppIdentifier") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("app_identifier"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("Currency") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("currency"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("ExpiredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expired_at"); + + b.Property>("Meta") + .HasColumnType("jsonb") + .HasColumnName("meta"); + + b.Property("PayeeWalletId") + .HasColumnType("uuid") + .HasColumnName("payee_wallet_id"); + + b.Property("ProductIdentifier") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("product_identifier"); + + b.Property("Remarks") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("remarks"); + + b.Property("Status") + .HasColumnType("integer") + .HasColumnName("status"); + + b.Property("TransactionId") + .HasColumnType("uuid") + .HasColumnName("transaction_id"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_payment_orders"); + + b.HasIndex("PayeeWalletId") + .HasDatabaseName("ix_payment_orders_payee_wallet_id"); + + b.HasIndex("TransactionId") + .HasDatabaseName("ix_payment_orders_transaction_id"); + + b.ToTable("payment_orders", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletPocket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Amount") + .HasColumnType("numeric") + .HasColumnName("amount"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("Currency") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("currency"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.Property("WalletId") + .HasColumnType("uuid") + .HasColumnName("wallet_id"); + + b.HasKey("Id") + .HasName("pk_wallet_pockets"); + + b.HasIndex("WalletId") + .HasDatabaseName("ix_wallet_pockets_wallet_id"); + + b.ToTable("wallet_pockets", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccountId") + .HasColumnType("uuid") + .HasColumnName("account_id"); + + b.Property("BasePrice") + .HasColumnType("numeric") + .HasColumnName("base_price"); + + b.Property("BegunAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("begun_at"); + + b.Property("CouponId") + .HasColumnType("uuid") + .HasColumnName("coupon_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("EndedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("ended_at"); + + b.Property("Identifier") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("identifier"); + + b.Property("IsActive") + .HasColumnType("boolean") + .HasColumnName("is_active"); + + b.Property("IsFreeTrial") + .HasColumnType("boolean") + .HasColumnName("is_free_trial"); + + b.Property("PaymentDetails") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("payment_details"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("payment_method"); + + b.Property("RenewalAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("renewal_at"); + + b.Property("Status") + .HasColumnType("integer") + .HasColumnName("status"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_wallet_subscriptions"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_wallet_subscriptions_account_id"); + + b.HasIndex("CouponId") + .HasDatabaseName("ix_wallet_subscriptions_coupon_id"); + + b.HasIndex("Identifier") + .HasDatabaseName("ix_wallet_subscriptions_identifier"); + + b.HasIndex("Status") + .HasDatabaseName("ix_wallet_subscriptions_status"); + + b.HasIndex("AccountId", "Identifier") + .HasDatabaseName("ix_wallet_subscriptions_account_id_identifier"); + + b.HasIndex("AccountId", "IsActive") + .HasDatabaseName("ix_wallet_subscriptions_account_id_is_active"); + + b.ToTable("wallet_subscriptions", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletTransaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Amount") + .HasColumnType("numeric") + .HasColumnName("amount"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("Currency") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("currency"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("PayeeWalletId") + .HasColumnType("uuid") + .HasColumnName("payee_wallet_id"); + + b.Property("PayerWalletId") + .HasColumnType("uuid") + .HasColumnName("payer_wallet_id"); + + b.Property("Remarks") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("remarks"); + + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("Id") + .HasName("pk_payment_transactions"); + + b.HasIndex("PayeeWalletId") + .HasDatabaseName("ix_payment_transactions_payee_wallet_id"); + + b.HasIndex("PayerWalletId") + .HasDatabaseName("ix_payment_transactions_payer_wallet_id"); + + b.ToTable("payment_transactions", (string)null); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAbuseReport", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_abuse_reports_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAccountAuthFactor", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany("AuthFactors") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_account_auth_factors_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAccountBadge", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany("Badges") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_badges_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAccountConnection", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany("Connections") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_account_connections_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAccountContact", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany("Contacts") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_account_contacts_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAccountProfile", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithOne("Profile") + .HasForeignKey("DysonNetwork.Shared.Models.SnAccountProfile", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_account_profiles_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAccountPunishment", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_punishments_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAccountRelationship", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany("OutgoingRelationships") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_account_relationships_accounts_account_id"); + + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "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.Shared.Models.SnAccountStatus", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_account_statuses_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnActionLog", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_action_logs_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnApiKey", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_api_keys_accounts_account_id"); + + b.HasOne("DysonNetwork.Shared.Models.SnAuthSession", "Session") + .WithMany() + .HasForeignKey("SessionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_api_keys_auth_sessions_session_id"); + + b.Navigation("Account"); + + b.Navigation("Session"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAuthChallenge", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany("Challenges") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_auth_challenges_accounts_account_id"); + + b.HasOne("DysonNetwork.Shared.Models.SnAuthClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .HasConstraintName("fk_auth_challenges_auth_clients_client_id"); + + b.Navigation("Account"); + + b.Navigation("Client"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAuthClient", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_auth_clients_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAuthSession", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany("Sessions") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_auth_sessions_accounts_account_id"); + + b.HasOne("DysonNetwork.Shared.Models.SnAuthChallenge", "Challenge") + .WithMany() + .HasForeignKey("ChallengeId") + .HasConstraintName("fk_auth_sessions_auth_challenges_challenge_id"); + + b.Navigation("Account"); + + b.Navigation("Challenge"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnCheckInResult", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_account_check_in_results_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnExperienceRecord", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_experience_records_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnLottery", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_lotteries_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnMagicSpell", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .HasConstraintName("fk_magic_spells_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnPermissionGroupMember", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnPermissionGroup", "Group") + .WithMany("Members") + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_permission_group_members_permission_groups_group_id"); + + b.Navigation("Group"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnPermissionNode", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnPermissionGroup", "Group") + .WithMany("Nodes") + .HasForeignKey("GroupId") + .HasConstraintName("fk_permission_nodes_permission_groups_group_id"); + + b.Navigation("Group"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnPresenceActivity", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_presence_activities_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnRealmMember", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnRealm", "Realm") + .WithMany("Members") + .HasForeignKey("RealmId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_realm_members_realms_realm_id"); + + b.Navigation("Realm"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnSocialCreditRecord", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_social_credit_records_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWallet", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_wallets_accounts_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletFund", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "CreatorAccount") + .WithMany() + .HasForeignKey("CreatorAccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_wallet_funds_accounts_creator_account_id"); + + b.Navigation("CreatorAccount"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletFundRecipient", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnWalletFund", "Fund") + .WithMany("Recipients") + .HasForeignKey("FundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_wallet_fund_recipients_wallet_funds_fund_id"); + + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "RecipientAccount") + .WithMany() + .HasForeignKey("RecipientAccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_wallet_fund_recipients_accounts_recipient_account_id"); + + b.Navigation("Fund"); + + b.Navigation("RecipientAccount"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletGift", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnWalletCoupon", "Coupon") + .WithMany() + .HasForeignKey("CouponId") + .HasConstraintName("fk_wallet_gifts_wallet_coupons_coupon_id"); + + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Gifter") + .WithMany() + .HasForeignKey("GifterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_wallet_gifts_accounts_gifter_id"); + + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Recipient") + .WithMany() + .HasForeignKey("RecipientId") + .HasConstraintName("fk_wallet_gifts_accounts_recipient_id"); + + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Redeemer") + .WithMany() + .HasForeignKey("RedeemerId") + .HasConstraintName("fk_wallet_gifts_accounts_redeemer_id"); + + b.HasOne("DysonNetwork.Shared.Models.SnWalletSubscription", "Subscription") + .WithOne("Gift") + .HasForeignKey("DysonNetwork.Shared.Models.SnWalletGift", "SubscriptionId") + .HasConstraintName("fk_wallet_gifts_wallet_subscriptions_subscription_id"); + + b.Navigation("Coupon"); + + b.Navigation("Gifter"); + + b.Navigation("Recipient"); + + b.Navigation("Redeemer"); + + b.Navigation("Subscription"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletOrder", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnWallet", "PayeeWallet") + .WithMany() + .HasForeignKey("PayeeWalletId") + .HasConstraintName("fk_payment_orders_wallets_payee_wallet_id"); + + b.HasOne("DysonNetwork.Shared.Models.SnWalletTransaction", "Transaction") + .WithMany() + .HasForeignKey("TransactionId") + .HasConstraintName("fk_payment_orders_payment_transactions_transaction_id"); + + b.Navigation("PayeeWallet"); + + b.Navigation("Transaction"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletPocket", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnWallet", "Wallet") + .WithMany("Pockets") + .HasForeignKey("WalletId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_wallet_pockets_wallets_wallet_id"); + + b.Navigation("Wallet"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletSubscription", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_wallet_subscriptions_accounts_account_id"); + + b.HasOne("DysonNetwork.Shared.Models.SnWalletCoupon", "Coupon") + .WithMany() + .HasForeignKey("CouponId") + .HasConstraintName("fk_wallet_subscriptions_wallet_coupons_coupon_id"); + + b.Navigation("Account"); + + b.Navigation("Coupon"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletTransaction", b => + { + b.HasOne("DysonNetwork.Shared.Models.SnWallet", "PayeeWallet") + .WithMany() + .HasForeignKey("PayeeWalletId") + .HasConstraintName("fk_payment_transactions_wallets_payee_wallet_id"); + + b.HasOne("DysonNetwork.Shared.Models.SnWallet", "PayerWallet") + .WithMany() + .HasForeignKey("PayerWalletId") + .HasConstraintName("fk_payment_transactions_wallets_payer_wallet_id"); + + b.Navigation("PayeeWallet"); + + b.Navigation("PayerWallet"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnAccount", b => + { + b.Navigation("AuthFactors"); + + b.Navigation("Badges"); + + b.Navigation("Challenges"); + + b.Navigation("Connections"); + + b.Navigation("Contacts"); + + b.Navigation("IncomingRelationships"); + + b.Navigation("OutgoingRelationships"); + + b.Navigation("Profile") + .IsRequired(); + + b.Navigation("Sessions"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnPermissionGroup", b => + { + b.Navigation("Members"); + + b.Navigation("Nodes"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnRealm", b => + { + b.Navigation("Members"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWallet", b => + { + b.Navigation("Pockets"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletFund", b => + { + b.Navigation("Recipients"); + }); + + modelBuilder.Entity("DysonNetwork.Shared.Models.SnWalletSubscription", b => + { + b.Navigation("Gift"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DysonNetwork.Pass/Migrations/20251116153151_OpenableFunds.cs b/DysonNetwork.Pass/Migrations/20251116153151_OpenableFunds.cs new file mode 100644 index 0000000..90d7714 --- /dev/null +++ b/DysonNetwork.Pass/Migrations/20251116153151_OpenableFunds.cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DysonNetwork.Pass.Migrations +{ + /// + public partial class OpenableFunds : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "is_open", + table: "wallet_funds", + type: "boolean", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "remaining_amount", + table: "wallet_funds", + type: "numeric", + nullable: false, + defaultValue: 0m); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "is_open", + table: "wallet_funds"); + + migrationBuilder.DropColumn( + name: "remaining_amount", + table: "wallet_funds"); + } + } +} diff --git a/DysonNetwork.Pass/Migrations/AppDatabaseModelSnapshot.cs b/DysonNetwork.Pass/Migrations/AppDatabaseModelSnapshot.cs index 8706209..3a02cde 100644 --- a/DysonNetwork.Pass/Migrations/AppDatabaseModelSnapshot.cs +++ b/DysonNetwork.Pass/Migrations/AppDatabaseModelSnapshot.cs @@ -22,7 +22,7 @@ namespace DysonNetwork.Pass.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "9.0.10") + .HasAnnotation("ProductVersion", "9.0.11") .HasAnnotation("Relational:MaxIdentifierLength", 63); NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); @@ -1734,11 +1734,19 @@ namespace DysonNetwork.Pass.Migrations .HasColumnType("timestamp with time zone") .HasColumnName("expired_at"); + b.Property("IsOpen") + .HasColumnType("boolean") + .HasColumnName("is_open"); + b.Property("Message") .HasMaxLength(4096) .HasColumnType("character varying(4096)") .HasColumnName("message"); + b.Property("RemainingAmount") + .HasColumnType("numeric") + .HasColumnName("remaining_amount"); + b.Property("SplitType") .HasColumnType("integer") .HasColumnName("split_type"); diff --git a/DysonNetwork.Pass/Wallet/PaymentService.cs b/DysonNetwork.Pass/Wallet/PaymentService.cs index f214f08..34ef8d2 100644 --- a/DysonNetwork.Pass/Wallet/PaymentService.cs +++ b/DysonNetwork.Pass/Wallet/PaymentService.cs @@ -465,8 +465,7 @@ public class PaymentService( null, currency, fee, - $"Transfer fee for transaction #{transaction.Id}", - Shared.Models.TransactionType.System); + $"Transfer fee for transaction #{transaction.Id}"); return transaction; } @@ -480,52 +479,41 @@ public class PaymentService( string? message = null, Duration? expiration = null) { - if (recipientAccountIds.Count == 0) - throw new ArgumentException("At least one recipient is required"); - if (totalAmount <= 0) throw new ArgumentException("Total amount must be positive"); - - // Validate all recipient accounts exist and have wallets - var recipientWallets = new List(); - foreach (var accountId in recipientAccountIds) - { - var wallet = await wat.GetWalletAsync(accountId); - if (wallet == null) - throw new InvalidOperationException($"Wallet not found for recipient account {accountId}"); - recipientWallets.Add(wallet); - } - + // Check creator has sufficient funds var creatorWallet = await wat.GetWalletAsync(creatorAccountId); if (creatorWallet == null) throw new InvalidOperationException($"Creator wallet not found for account {creatorAccountId}"); + // Validate all recipient accounts exist and have wallets + foreach (var accountId in recipientAccountIds) + { + var wallet = await wat.GetWalletAsync(accountId); + if (wallet == null) + throw new InvalidOperationException($"Wallet not found for recipient account {accountId}"); + } + var (creatorPocket, _) = await wat.GetOrCreateWalletPocketAsync(creatorWallet.Id, currency); if (creatorPocket.Amount < totalAmount) throw new InvalidOperationException("Insufficient funds"); - // Calculate amounts for each recipient - var recipientAmounts = splitType switch - { - Shared.Models.FundSplitType.Even => SplitEvenly(totalAmount, recipientAccountIds.Count), - Shared.Models.FundSplitType.Random => SplitRandomly(totalAmount, recipientAccountIds.Count), - _ => throw new ArgumentException("Invalid split type") - }; - var now = SystemClock.Instance.GetCurrentInstant(); var fund = new SnWalletFund { CreatorAccountId = creatorAccountId, Currency = currency, TotalAmount = totalAmount, + RemainingAmount = totalAmount, SplitType = splitType, Message = message, ExpiredAt = now.Plus(expiration ?? Duration.FromHours(24)), - Recipients = recipientAccountIds.Select((accountId, index) => new SnWalletFundRecipient + IsOpen = recipientAccountIds.Count == 0, + Recipients = recipientAccountIds.Select(accountId => new SnWalletFundRecipient { RecipientAccountId = accountId, - Amount = recipientAmounts[index] + Amount = 0 // Amount will be calculated dynamically when claimed }).ToList() }; @@ -589,6 +577,36 @@ public class PaymentService( return amounts; } + private decimal CalculateDynamicAmount(SnWalletFund fund) + { + if (fund.RemainingAmount <= 0) + return 0; + + // For open mode funds: use percentage-based calculation + if (fund.IsOpen) + { + const decimal percentagePerClaim = 0.1m; // 10% of remaining amount per claim + const decimal minimumAmount = 0.01m; // Minimum 0.01 per claim + + var calculatedAmount = Math.Max(fund.RemainingAmount * percentagePerClaim, minimumAmount); + return Math.Min(calculatedAmount, fund.RemainingAmount); + } + // For closed mode funds: use split type calculation + else + { + var unclaimedRecipients = fund.Recipients.Count(r => !r.IsReceived); + if (unclaimedRecipients == 0) + return 0; + + return fund.SplitType switch + { + Shared.Models.FundSplitType.Even => SplitEvenly(fund.RemainingAmount, unclaimedRecipients)[0], + Shared.Models.FundSplitType.Random => SplitRandomly(fund.RemainingAmount, unclaimedRecipients)[0], + _ => throw new ArgumentException("Invalid split type") + }; + } + } + public async Task ReceiveFundAsync(Guid recipientAccountId, Guid fundId) { var fund = await db.WalletFunds @@ -598,12 +616,49 @@ public class PaymentService( if (fund == null) throw new InvalidOperationException("Fund not found"); - if (fund.Status == Shared.Models.FundStatus.Expired || fund.Status == Shared.Models.FundStatus.Refunded) + if (fund.Status is Shared.Models.FundStatus.Expired or Shared.Models.FundStatus.Refunded) throw new InvalidOperationException("Fund is no longer available"); var recipient = fund.Recipients.FirstOrDefault(r => r.RecipientAccountId == recipientAccountId); - if (recipient == null) + + // Handle open mode fund - create recipient if not exists + if (recipient is null && fund.IsOpen) + { + // Check if recipient has already claimed from this fund + var existingClaim = fund.Recipients.FirstOrDefault(r => r.RecipientAccountId == recipientAccountId); + if (existingClaim != null) + throw new InvalidOperationException("You have already claimed from this fund"); + + // Calculate amount for new recipient + var amount = CalculateDynamicAmount(fund); + if (amount <= 0) + throw new InvalidOperationException("No funds remaining to claim"); + + // Create new recipient + recipient = new SnWalletFundRecipient + { + RecipientAccountId = recipientAccountId, + Amount = amount, + IsReceived = false + }; + fund.Recipients.Add(recipient); + fund.RemainingAmount -= amount; + } + else if (recipient is null) + { throw new InvalidOperationException("You are not a recipient of this fund"); + } + + // For closed mode funds, calculate amount dynamically if not already set + if (!fund.IsOpen && recipient.Amount == 0) + { + var amount = CalculateDynamicAmount(fund); + if (amount <= 0) + throw new InvalidOperationException("No funds remaining to claim"); + + recipient.Amount = amount; + fund.RemainingAmount -= amount; + } if (recipient.IsReceived) throw new InvalidOperationException("You have already received this fund"); @@ -628,11 +683,21 @@ public class PaymentService( recipient.ReceivedAt = SystemClock.Instance.GetCurrentInstant(); // Update fund status - var allReceived = fund.Recipients.All(r => r.IsReceived); - if (allReceived) - fund.Status = Shared.Models.FundStatus.FullyReceived; + if (fund.IsOpen) + { + if (fund.RemainingAmount <= 0) + fund.Status = Shared.Models.FundStatus.FullyReceived; + else + fund.Status = Shared.Models.FundStatus.PartiallyReceived; + } else - fund.Status = Shared.Models.FundStatus.PartiallyReceived; + { + var allReceived = fund.Recipients.All(r => r.IsReceived); + if (allReceived) + fund.Status = Shared.Models.FundStatus.FullyReceived; + else + fund.Status = Shared.Models.FundStatus.PartiallyReceived; + } await db.SaveChangesAsync(); diff --git a/DysonNetwork.Pass/Wallet/WalletController.cs b/DysonNetwork.Pass/Wallet/WalletController.cs index 70467f8..ed1a309 100644 --- a/DysonNetwork.Pass/Wallet/WalletController.cs +++ b/DysonNetwork.Pass/Wallet/WalletController.cs @@ -334,11 +334,8 @@ public class WalletController( } [HttpGet("funds/{id:guid}")] - [Authorize] public async Task> GetFund(Guid id) { - if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized(); - var fund = await db.WalletFunds .Include(f => f.Recipients) .ThenInclude(r => r.RecipientAccount) diff --git a/DysonNetwork.Shared/Models/Wallet.cs b/DysonNetwork.Shared/Models/Wallet.cs index 2b5690f..ed73e5e 100644 --- a/DysonNetwork.Shared/Models/Wallet.cs +++ b/DysonNetwork.Shared/Models/Wallet.cs @@ -85,9 +85,11 @@ public class SnWalletFund : ModelBase public Guid Id { get; set; } = Guid.NewGuid(); [MaxLength(128)] public string Currency { get; set; } = null!; public decimal TotalAmount { get; set; } + public decimal RemainingAmount { get; set; } public FundSplitType SplitType { get; set; } public FundStatus Status { get; set; } = FundStatus.Created; [MaxLength(4096)] public string? Message { get; set; } + public bool IsOpen { get; set; } = false; // Creator public Guid CreatorAccountId { get; set; } @@ -104,6 +106,7 @@ public class SnWalletFund : ModelBase Id = Id.ToString(), Currency = Currency, TotalAmount = TotalAmount.ToString(CultureInfo.InvariantCulture), + RemainingAmount = RemainingAmount.ToString(CultureInfo.InvariantCulture), SplitType = (Proto.FundSplitType)SplitType, Status = (Proto.FundStatus)Status, Message = Message, @@ -116,6 +119,7 @@ public class SnWalletFund : ModelBase Id = Guid.Parse(proto.Id), Currency = proto.Currency, TotalAmount = decimal.Parse(proto.TotalAmount), + RemainingAmount = proto.RemainingAmount is not null ? decimal.Parse(proto.RemainingAmount) : decimal.Parse(proto.TotalAmount), SplitType = (FundSplitType)proto.SplitType, Status = (FundStatus)proto.Status, Message = proto.Message, diff --git a/DysonNetwork.Shared/Proto/wallet.proto b/DysonNetwork.Shared/Proto/wallet.proto index 8090d53..b0f93ab 100644 --- a/DysonNetwork.Shared/Proto/wallet.proto +++ b/DysonNetwork.Shared/Proto/wallet.proto @@ -41,6 +41,7 @@ message WalletFund { string id = 1; string currency = 2; string total_amount = 3; + string remaining_amount = 10; FundSplitType split_type = 4; FundStatus status = 5; optional string message = 6;