♻️ I have no idea what I have done
This commit is contained in:
@@ -5,11 +5,13 @@ using DysonNetwork.Pass.Email;
|
||||
using DysonNetwork.Pass.Localization;
|
||||
using DysonNetwork.Pass.Permission;
|
||||
using DysonNetwork.Shared.Cache;
|
||||
using DysonNetwork.Shared.Proto;
|
||||
using EFCore.BulkExtensions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using NodaTime;
|
||||
using OtpNet;
|
||||
using AuthSession = DysonNetwork.Pass.Auth.AuthSession;
|
||||
|
||||
namespace DysonNetwork.Pass.Account;
|
||||
|
||||
@@ -17,8 +19,8 @@ public class AccountService(
|
||||
AppDatabase db,
|
||||
MagicSpellService spells,
|
||||
AccountUsernameService uname,
|
||||
NotificationService nty,
|
||||
EmailService mailer,
|
||||
PusherService.PusherServiceClient pusher,
|
||||
IStringLocalizer<NotificationResource> localizer,
|
||||
ICacheService cache,
|
||||
ILogger<AccountService> logger
|
||||
@@ -353,13 +355,18 @@ public class AccountService(
|
||||
if (await _GetFactorCode(factor) is not null)
|
||||
throw new InvalidOperationException("A factor code has been sent and in active duration.");
|
||||
|
||||
await nty.SendNotification(
|
||||
account,
|
||||
"auth.verification",
|
||||
localizer["AuthCodeTitle"],
|
||||
null,
|
||||
localizer["AuthCodeBody", code],
|
||||
save: true
|
||||
await pusher.SendPushNotificationToUserAsync(
|
||||
new SendPushNotificationToUserRequest
|
||||
{
|
||||
UserId = account.Id.ToString(),
|
||||
Notification = new PushNotification
|
||||
{
|
||||
Topic = "auth.verification",
|
||||
Title = localizer["AuthCodeTitle"],
|
||||
Body = localizer["AuthCodeBody", code],
|
||||
IsSavable = false
|
||||
}
|
||||
}
|
||||
);
|
||||
await _SetFactorCode(factor, code, TimeSpan.FromMinutes(5));
|
||||
break;
|
||||
@@ -489,7 +496,7 @@ public class AccountService(
|
||||
.ToListAsync();
|
||||
|
||||
if (session.Challenge.DeviceId is not null)
|
||||
await nty.UnsubscribePushNotifications(session.Challenge.DeviceId);
|
||||
await pusher.UnsubscribePushNotifications(session.Challenge.DeviceId);
|
||||
|
||||
// The current session should be included in the sessions' list
|
||||
await db.AuthSessions
|
||||
|
@@ -1,167 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using DysonNetwork.Pass;
|
||||
using DysonNetwork.Pass.Auth;
|
||||
using DysonNetwork.Pass.Permission;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
|
||||
namespace DysonNetwork.Pass.Account;
|
||||
|
||||
[ApiController]
|
||||
[Route("/api/notifications")]
|
||||
public class NotificationController(AppDatabase db, NotificationService nty) : ControllerBase
|
||||
{
|
||||
[HttpGet("count")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult<int>> CountUnreadNotifications()
|
||||
{
|
||||
HttpContext.Items.TryGetValue("CurrentUser", out var currentUserValue);
|
||||
if (currentUserValue is not Account currentUser) return Unauthorized();
|
||||
|
||||
var count = await db.Notifications
|
||||
.Where(s => s.AccountId == currentUser.Id && s.ViewedAt == null)
|
||||
.CountAsync();
|
||||
return Ok(count);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Authorize]
|
||||
public async Task<ActionResult<List<Notification>>> ListNotifications(
|
||||
[FromQuery] int offset = 0,
|
||||
// The page size set to 5 is to avoid the client pulled the notification
|
||||
// but didn't render it in the screen-viewable region.
|
||||
[FromQuery] int take = 5
|
||||
)
|
||||
{
|
||||
HttpContext.Items.TryGetValue("CurrentUser", out var currentUserValue);
|
||||
if (currentUserValue is not Account currentUser) return Unauthorized();
|
||||
|
||||
var totalCount = await db.Notifications
|
||||
.Where(s => s.AccountId == currentUser.Id)
|
||||
.CountAsync();
|
||||
var notifications = await db.Notifications
|
||||
.Where(s => s.AccountId == currentUser.Id)
|
||||
.OrderByDescending(e => e.CreatedAt)
|
||||
.Skip(offset)
|
||||
.Take(take)
|
||||
.ToListAsync();
|
||||
|
||||
Response.Headers["X-Total"] = totalCount.ToString();
|
||||
await nty.MarkNotificationsViewed(notifications);
|
||||
|
||||
return Ok(notifications);
|
||||
}
|
||||
|
||||
public class PushNotificationSubscribeRequest
|
||||
{
|
||||
[MaxLength(4096)] public string DeviceToken { get; set; } = null!;
|
||||
public NotificationPushProvider Provider { get; set; }
|
||||
}
|
||||
|
||||
[HttpPut("subscription")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult<NotificationPushSubscription>> SubscribeToPushNotification(
|
||||
[FromBody] PushNotificationSubscribeRequest request
|
||||
)
|
||||
{
|
||||
HttpContext.Items.TryGetValue("CurrentSession", out var currentSessionValue);
|
||||
HttpContext.Items.TryGetValue("CurrentUser", out var currentUserValue);
|
||||
var currentUser = currentUserValue as Account;
|
||||
if (currentUser == null) return Unauthorized();
|
||||
var currentSession = currentSessionValue as AuthSession;
|
||||
if (currentSession == null) return Unauthorized();
|
||||
|
||||
var result =
|
||||
await nty.SubscribePushNotification(currentUser, request.Provider, currentSession.Challenge.DeviceId!,
|
||||
request.DeviceToken);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpDelete("subscription")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult<int>> UnsubscribeFromPushNotification()
|
||||
{
|
||||
HttpContext.Items.TryGetValue("CurrentSession", out var currentSessionValue);
|
||||
HttpContext.Items.TryGetValue("CurrentUser", out var currentUserValue);
|
||||
var currentUser = currentUserValue as Account;
|
||||
if (currentUser == null) return Unauthorized();
|
||||
var currentSession = currentSessionValue as AuthSession;
|
||||
if (currentSession == null) return Unauthorized();
|
||||
|
||||
var affectedRows = await db.NotificationPushSubscriptions
|
||||
.Where(s =>
|
||||
s.AccountId == currentUser.Id &&
|
||||
s.DeviceId == currentSession.Challenge.DeviceId
|
||||
).ExecuteDeleteAsync();
|
||||
return Ok(affectedRows);
|
||||
}
|
||||
|
||||
public class NotificationRequest
|
||||
{
|
||||
[Required] [MaxLength(1024)] public string Topic { get; set; } = null!;
|
||||
[Required] [MaxLength(1024)] public string Title { get; set; } = null!;
|
||||
[MaxLength(2048)] public string? Subtitle { get; set; }
|
||||
[Required] [MaxLength(4096)] public string Content { get; set; } = null!;
|
||||
public Dictionary<string, object>? Meta { get; set; }
|
||||
public int Priority { get; set; } = 10;
|
||||
}
|
||||
|
||||
[HttpPost("broadcast")]
|
||||
[Authorize]
|
||||
[RequiredPermission("global", "notifications.broadcast")]
|
||||
public async Task<ActionResult> BroadcastNotification(
|
||||
[FromBody] NotificationRequest request,
|
||||
[FromQuery] bool save = false
|
||||
)
|
||||
{
|
||||
await nty.BroadcastNotification(
|
||||
new Notification
|
||||
{
|
||||
CreatedAt = SystemClock.Instance.GetCurrentInstant(),
|
||||
UpdatedAt = SystemClock.Instance.GetCurrentInstant(),
|
||||
Topic = request.Topic,
|
||||
Title = request.Title,
|
||||
Subtitle = request.Subtitle,
|
||||
Content = request.Content,
|
||||
Meta = request.Meta,
|
||||
Priority = request.Priority,
|
||||
},
|
||||
save
|
||||
);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
public class NotificationWithAimRequest : NotificationRequest
|
||||
{
|
||||
[Required] public List<Guid> AccountId { get; set; } = null!;
|
||||
}
|
||||
|
||||
[HttpPost("send")]
|
||||
[Authorize]
|
||||
[RequiredPermission("global", "notifications.send")]
|
||||
public async Task<ActionResult> SendNotification(
|
||||
[FromBody] NotificationWithAimRequest request,
|
||||
[FromQuery] bool save = false
|
||||
)
|
||||
{
|
||||
var accounts = await db.Accounts.Where(a => request.AccountId.Contains(a.Id)).ToListAsync();
|
||||
await nty.SendNotificationBatch(
|
||||
new Notification
|
||||
{
|
||||
CreatedAt = SystemClock.Instance.GetCurrentInstant(),
|
||||
UpdatedAt = SystemClock.Instance.GetCurrentInstant(),
|
||||
Topic = request.Topic,
|
||||
Title = request.Title,
|
||||
Subtitle = request.Subtitle,
|
||||
Content = request.Content,
|
||||
Meta = request.Meta,
|
||||
},
|
||||
accounts,
|
||||
save
|
||||
);
|
||||
return Ok();
|
||||
}
|
||||
}
|
@@ -1,292 +0,0 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using DysonNetwork.Pass;
|
||||
using EFCore.BulkExtensions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
|
||||
namespace DysonNetwork.Pass.Account;
|
||||
|
||||
public class NotificationService(
|
||||
AppDatabase db,
|
||||
IHttpClientFactory httpFactory,
|
||||
IConfiguration config
|
||||
)
|
||||
{
|
||||
private readonly string _notifyTopic = config["Notifications:Topic"]!;
|
||||
private readonly Uri _notifyEndpoint = new(config["Notifications:Endpoint"]!);
|
||||
|
||||
public async Task UnsubscribePushNotifications(string deviceId)
|
||||
{
|
||||
await db.NotificationPushSubscriptions
|
||||
.Where(s => s.DeviceId == deviceId)
|
||||
.ExecuteDeleteAsync();
|
||||
}
|
||||
|
||||
public async Task<NotificationPushSubscription> SubscribePushNotification(
|
||||
Account account,
|
||||
NotificationPushProvider provider,
|
||||
string deviceId,
|
||||
string deviceToken
|
||||
)
|
||||
{
|
||||
var now = SystemClock.Instance.GetCurrentInstant();
|
||||
|
||||
// First check if a matching subscription exists
|
||||
var existingSubscription = await db.NotificationPushSubscriptions
|
||||
.Where(s => s.AccountId == account.Id)
|
||||
.Where(s => s.DeviceId == deviceId || s.DeviceToken == deviceToken)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (existingSubscription is not null)
|
||||
{
|
||||
// Update the existing subscription directly in the database
|
||||
await db.NotificationPushSubscriptions
|
||||
.Where(s => s.Id == existingSubscription.Id)
|
||||
.ExecuteUpdateAsync(setters => setters
|
||||
.SetProperty(s => s.DeviceId, deviceId)
|
||||
.SetProperty(s => s.DeviceToken, deviceToken)
|
||||
.SetProperty(s => s.UpdatedAt, now));
|
||||
|
||||
// Return the updated subscription
|
||||
existingSubscription.DeviceId = deviceId;
|
||||
existingSubscription.DeviceToken = deviceToken;
|
||||
existingSubscription.UpdatedAt = now;
|
||||
return existingSubscription;
|
||||
}
|
||||
|
||||
var subscription = new NotificationPushSubscription
|
||||
{
|
||||
DeviceId = deviceId,
|
||||
DeviceToken = deviceToken,
|
||||
Provider = provider,
|
||||
AccountId = account.Id,
|
||||
};
|
||||
|
||||
db.NotificationPushSubscriptions.Add(subscription);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
return subscription;
|
||||
}
|
||||
|
||||
public async Task<Notification> SendNotification(
|
||||
Account account,
|
||||
string topic,
|
||||
string? title = null,
|
||||
string? subtitle = null,
|
||||
string? content = null,
|
||||
Dictionary<string, object>? meta = null,
|
||||
string? actionUri = null,
|
||||
bool isSilent = false,
|
||||
bool save = true
|
||||
)
|
||||
{
|
||||
if (title is null && subtitle is null && content is null)
|
||||
throw new ArgumentException("Unable to send notification that completely empty.");
|
||||
|
||||
meta ??= new Dictionary<string, object>();
|
||||
if (actionUri is not null) meta["action_uri"] = actionUri;
|
||||
|
||||
var notification = new Notification
|
||||
{
|
||||
Topic = topic,
|
||||
Title = title,
|
||||
Subtitle = subtitle,
|
||||
Content = content,
|
||||
Meta = meta,
|
||||
AccountId = account.Id,
|
||||
};
|
||||
|
||||
if (save)
|
||||
{
|
||||
db.Add(notification);
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (!isSilent) _ = DeliveryNotification(notification);
|
||||
|
||||
return notification;
|
||||
}
|
||||
|
||||
public async Task DeliveryNotification(Notification notification)
|
||||
{
|
||||
// Pushing the notification
|
||||
var subscribers = await db.NotificationPushSubscriptions
|
||||
.Where(s => s.AccountId == notification.AccountId)
|
||||
.ToListAsync();
|
||||
|
||||
await _PushNotification(notification, subscribers);
|
||||
}
|
||||
|
||||
public async Task MarkNotificationsViewed(ICollection<Notification> notifications)
|
||||
{
|
||||
var now = SystemClock.Instance.GetCurrentInstant();
|
||||
var id = notifications.Where(n => n.ViewedAt == null).Select(n => n.Id).ToList();
|
||||
if (id.Count == 0) return;
|
||||
|
||||
await db.Notifications
|
||||
.Where(n => id.Contains(n.Id))
|
||||
.ExecuteUpdateAsync(s => s.SetProperty(n => n.ViewedAt, now)
|
||||
);
|
||||
}
|
||||
|
||||
public async Task BroadcastNotification(Notification notification, bool save = false)
|
||||
{
|
||||
var accounts = await db.Accounts.ToListAsync();
|
||||
|
||||
if (save)
|
||||
{
|
||||
var notifications = accounts.Select(x =>
|
||||
{
|
||||
var newNotification = new Notification
|
||||
{
|
||||
Topic = notification.Topic,
|
||||
Title = notification.Title,
|
||||
Subtitle = notification.Subtitle,
|
||||
Content = notification.Content,
|
||||
Meta = notification.Meta,
|
||||
Priority = notification.Priority,
|
||||
Account = x,
|
||||
AccountId = x.Id
|
||||
};
|
||||
return newNotification;
|
||||
}).ToList();
|
||||
await db.BulkInsertAsync(notifications);
|
||||
}
|
||||
|
||||
foreach (var account in accounts)
|
||||
{
|
||||
notification.Account = account;
|
||||
notification.AccountId = account.Id;
|
||||
}
|
||||
|
||||
var subscribers = await db.NotificationPushSubscriptions
|
||||
.ToListAsync();
|
||||
await _PushNotification(notification, subscribers);
|
||||
}
|
||||
|
||||
public async Task SendNotificationBatch(Notification notification, List<Account> accounts, bool save = false)
|
||||
{
|
||||
if (save)
|
||||
{
|
||||
var notifications = accounts.Select(x =>
|
||||
{
|
||||
var newNotification = new Notification
|
||||
{
|
||||
Topic = notification.Topic,
|
||||
Title = notification.Title,
|
||||
Subtitle = notification.Subtitle,
|
||||
Content = notification.Content,
|
||||
Meta = notification.Meta,
|
||||
Priority = notification.Priority,
|
||||
Account = x,
|
||||
AccountId = x.Id
|
||||
};
|
||||
return newNotification;
|
||||
}).ToList();
|
||||
await db.BulkInsertAsync(notifications);
|
||||
}
|
||||
|
||||
foreach (var account in accounts)
|
||||
{
|
||||
notification.Account = account;
|
||||
notification.AccountId = account.Id;
|
||||
}
|
||||
|
||||
var accountsId = accounts.Select(x => x.Id).ToList();
|
||||
var subscribers = await db.NotificationPushSubscriptions
|
||||
.Where(s => accountsId.Contains(s.AccountId))
|
||||
.ToListAsync();
|
||||
await _PushNotification(notification, subscribers);
|
||||
}
|
||||
|
||||
private List<Dictionary<string, object>> _BuildNotificationPayload(Notification notification,
|
||||
IEnumerable<NotificationPushSubscription> subscriptions)
|
||||
{
|
||||
var subDict = subscriptions
|
||||
.GroupBy(x => x.Provider)
|
||||
.ToDictionary(x => x.Key, x => x.ToList());
|
||||
|
||||
var notifications = subDict.Select(value =>
|
||||
{
|
||||
var platformCode = value.Key switch
|
||||
{
|
||||
NotificationPushProvider.Apple => 1,
|
||||
NotificationPushProvider.Google => 2,
|
||||
_ => throw new InvalidOperationException($"Unknown push provider: {value.Key}")
|
||||
};
|
||||
|
||||
var tokens = value.Value.Select(x => x.DeviceToken).ToList();
|
||||
return _BuildNotificationPayload(notification, platformCode, tokens);
|
||||
}).ToList();
|
||||
|
||||
return notifications.ToList();
|
||||
}
|
||||
|
||||
private Dictionary<string, object> _BuildNotificationPayload(Notification notification, int platformCode,
|
||||
IEnumerable<string> deviceTokens)
|
||||
{
|
||||
var alertDict = new Dictionary<string, object>();
|
||||
var dict = new Dictionary<string, object>
|
||||
{
|
||||
["notif_id"] = notification.Id.ToString(),
|
||||
["apns_id"] = notification.Id.ToString(),
|
||||
["topic"] = _notifyTopic,
|
||||
["tokens"] = deviceTokens,
|
||||
["data"] = new Dictionary<string, object>
|
||||
{
|
||||
["type"] = notification.Topic,
|
||||
["meta"] = notification.Meta ?? new Dictionary<string, object>(),
|
||||
},
|
||||
["mutable_content"] = true,
|
||||
["priority"] = notification.Priority >= 5 ? "high" : "normal",
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(notification.Title))
|
||||
{
|
||||
dict["title"] = notification.Title;
|
||||
alertDict["title"] = notification.Title;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(notification.Content))
|
||||
{
|
||||
dict["message"] = notification.Content;
|
||||
alertDict["body"] = notification.Content;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(notification.Subtitle))
|
||||
{
|
||||
dict["message"] = $"{notification.Subtitle}\n{dict["message"]}";
|
||||
alertDict["subtitle"] = notification.Subtitle;
|
||||
}
|
||||
|
||||
if (notification.Priority >= 5)
|
||||
dict["name"] = "default";
|
||||
|
||||
dict["platform"] = platformCode;
|
||||
dict["alert"] = alertDict;
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
private async Task _PushNotification(Notification notification,
|
||||
IEnumerable<NotificationPushSubscription> subscriptions)
|
||||
{
|
||||
var subList = subscriptions.ToList();
|
||||
if (subList.Count == 0) return;
|
||||
|
||||
var requestDict = new Dictionary<string, object>
|
||||
{
|
||||
["notifications"] = _BuildNotificationPayload(notification, subList)
|
||||
};
|
||||
|
||||
var client = httpFactory.CreateClient();
|
||||
client.BaseAddress = _notifyEndpoint;
|
||||
var request = await client.PostAsync("/push", new StringContent(
|
||||
JsonSerializer.Serialize(requestDict),
|
||||
Encoding.UTF8,
|
||||
"application/json"
|
||||
));
|
||||
request.EnsureSuccessStatusCode();
|
||||
}
|
||||
}
|
@@ -9,6 +9,10 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Grpc.AspNetCore.Server" Version="2.71.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.7">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NodaTime" Version="3.2.2" />
|
||||
<PackageReference Include="NodaTime.Serialization.JsonNet" Version="3.2.0" />
|
||||
<PackageReference Include="NodaTime.Serialization.Protobuf" Version="2.0.2" />
|
||||
|
@@ -1,33 +1,23 @@
|
||||
using dotnet_etcd;
|
||||
using dotnet_etcd.interfaces;
|
||||
using DysonNetwork.Shared.Proto;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace DysonNetwork.Pass.Email;
|
||||
|
||||
public class EmailService
|
||||
public class EmailService(
|
||||
IEtcdClient etcd,
|
||||
RazorViewRenderer viewRenderer,
|
||||
IConfiguration configuration,
|
||||
ILogger<EmailService> logger
|
||||
)
|
||||
{
|
||||
private readonly PusherService.PusherServiceClient _client;
|
||||
private readonly RazorViewRenderer _viewRenderer;
|
||||
private readonly ILogger<EmailService> _logger;
|
||||
private readonly PusherService.PusherServiceClient _client = GrpcClientHelper.CreatePusherServiceClient(
|
||||
etcd,
|
||||
configuration["Service:CertPath"]!,
|
||||
configuration["Service:KeyPath"]!
|
||||
).GetAwaiter().GetResult();
|
||||
|
||||
public EmailService(
|
||||
EtcdClient etcd,
|
||||
RazorViewRenderer viewRenderer,
|
||||
IConfiguration configuration,
|
||||
ILogger<EmailService> logger,
|
||||
PusherService.PusherServiceClient client
|
||||
)
|
||||
{
|
||||
_client = GrpcClientHelper.CreatePusherServiceClient(
|
||||
etcd,
|
||||
configuration["Service:CertPath"]!,
|
||||
configuration["Service:KeyPath"]!
|
||||
).GetAwaiter().GetResult();
|
||||
_viewRenderer = viewRenderer;
|
||||
_logger = logger;
|
||||
_client = client;
|
||||
}
|
||||
|
||||
public async Task SendEmailAsync(
|
||||
string? recipientName,
|
||||
string recipientEmail,
|
||||
@@ -57,12 +47,12 @@ public class EmailService
|
||||
{
|
||||
try
|
||||
{
|
||||
var htmlBody = await _viewRenderer.RenderComponentToStringAsync<TComponent, TModel>(model);
|
||||
var htmlBody = await viewRenderer.RenderComponentToStringAsync<TComponent, TModel>(model);
|
||||
await SendEmailAsync(recipientName, recipientEmail, subject, htmlBody);
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.LogError(err, "Failed to render email template...");
|
||||
logger.LogError(err, "Failed to render email template...");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
1977
DysonNetwork.Pass/Migrations/20250713121237_InitialMigration.Designer.cs
generated
Normal file
1977
DysonNetwork.Pass/Migrations/20250713121237_InitialMigration.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
998
DysonNetwork.Pass/Migrations/20250713121237_InitialMigration.cs
Normal file
998
DysonNetwork.Pass/Migrations/20250713121237_InitialMigration.cs
Normal file
@@ -0,0 +1,998 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using DysonNetwork.Pass.Account;
|
||||
using DysonNetwork.Pass.Developer;
|
||||
using DysonNetwork.Pass.Wallet;
|
||||
using DysonNetwork.Shared.Data;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using NetTopologySuite.Geometries;
|
||||
using NodaTime;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace DysonNetwork.Pass.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialMigration : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterDatabase()
|
||||
.Annotation("Npgsql:PostgresExtension:postgis", ",,");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "accounts",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
|
||||
nick = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
|
||||
language = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
||||
activated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
is_superuser = table.Column<bool>(type: "boolean", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_accounts", x => x.id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "custom_apps",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
slug = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: false),
|
||||
name = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: false),
|
||||
description = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
||||
status = table.Column<int>(type: "integer", nullable: false),
|
||||
picture = table.Column<CloudFileReferenceObject>(type: "jsonb", nullable: true),
|
||||
background = table.Column<CloudFileReferenceObject>(type: "jsonb", nullable: true),
|
||||
verification = table.Column<VerificationMark>(type: "jsonb", nullable: true),
|
||||
oauth_config = table.Column<CustomAppOauthConfig>(type: "jsonb", nullable: true),
|
||||
links = table.Column<CustomAppLinks>(type: "jsonb", nullable: true),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_custom_apps", x => x.id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "permission_groups",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
key = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_permission_groups", x => x.id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "wallet_coupons",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
identifier = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
||||
code = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
||||
affected_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
expired_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
discount_amount = table.Column<decimal>(type: "numeric", nullable: true),
|
||||
discount_rate = table.Column<double>(type: "double precision", nullable: true),
|
||||
max_usage = table.Column<int>(type: "integer", nullable: true),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_wallet_coupons", x => x.id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "abuse_reports",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
resource_identifier = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: false),
|
||||
type = table.Column<int>(type: "integer", nullable: false),
|
||||
reason = table.Column<string>(type: "character varying(8192)", maxLength: 8192, nullable: false),
|
||||
resolved_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
resolution = table.Column<string>(type: "character varying(8192)", maxLength: 8192, nullable: true),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_abuse_reports", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_abuse_reports_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "account_auth_factors",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
type = table.Column<int>(type: "integer", nullable: false),
|
||||
secret = table.Column<string>(type: "character varying(8196)", maxLength: 8196, nullable: true),
|
||||
config = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: true),
|
||||
trustworthy = table.Column<int>(type: "integer", nullable: false),
|
||||
enabled_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
expired_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_account_auth_factors", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_account_auth_factors_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "account_check_in_results",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
level = table.Column<int>(type: "integer", nullable: false),
|
||||
reward_points = table.Column<decimal>(type: "numeric", nullable: true),
|
||||
reward_experience = table.Column<int>(type: "integer", nullable: true),
|
||||
tips = table.Column<ICollection<FortuneTip>>(type: "jsonb", nullable: false),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_account_check_in_results", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_account_check_in_results_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "account_connections",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
provider = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: false),
|
||||
provided_identifier = table.Column<string>(type: "character varying(8192)", maxLength: 8192, nullable: false),
|
||||
meta = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: true),
|
||||
access_token = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
||||
refresh_token = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
||||
last_used_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_account_connections", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_account_connections_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "account_contacts",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
type = table.Column<int>(type: "integer", nullable: false),
|
||||
verified_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
is_primary = table.Column<bool>(type: "boolean", nullable: false),
|
||||
content = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: false),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_account_contacts", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_account_contacts_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "account_profiles",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
first_name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
middle_name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
last_name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
bio = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
||||
gender = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
||||
pronouns = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
||||
time_zone = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
||||
location = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
||||
birthday = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
last_seen_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
verification = table.Column<VerificationMark>(type: "jsonb", nullable: true),
|
||||
active_badge = table.Column<BadgeReferenceObject>(type: "jsonb", nullable: true),
|
||||
experience = table.Column<int>(type: "integer", nullable: false),
|
||||
picture_id = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||
background_id = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||
picture = table.Column<CloudFileReferenceObject>(type: "jsonb", nullable: true),
|
||||
background = table.Column<CloudFileReferenceObject>(type: "jsonb", nullable: true),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_account_profiles", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_account_profiles_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "account_relationships",
|
||||
columns: table => new
|
||||
{
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
related_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
expired_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
status = table.Column<short>(type: "smallint", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_account_relationships", x => new { x.account_id, x.related_id });
|
||||
table.ForeignKey(
|
||||
name: "fk_account_relationships_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "fk_account_relationships_accounts_related_id",
|
||||
column: x => x.related_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "account_statuses",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
attitude = table.Column<int>(type: "integer", nullable: false),
|
||||
is_invisible = table.Column<bool>(type: "boolean", nullable: false),
|
||||
is_not_disturb = table.Column<bool>(type: "boolean", nullable: false),
|
||||
label = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
||||
cleared_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_account_statuses", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_account_statuses_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "action_logs",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
action = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: false),
|
||||
meta = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: false),
|
||||
user_agent = table.Column<string>(type: "character varying(512)", maxLength: 512, nullable: true),
|
||||
ip_address = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
||||
location = table.Column<Point>(type: "geometry", nullable: true),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
session_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_action_logs", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_action_logs_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "auth_challenges",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
expired_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
step_remain = table.Column<int>(type: "integer", nullable: false),
|
||||
step_total = table.Column<int>(type: "integer", nullable: false),
|
||||
failed_attempts = table.Column<int>(type: "integer", nullable: false),
|
||||
platform = table.Column<int>(type: "integer", nullable: false),
|
||||
type = table.Column<int>(type: "integer", nullable: false),
|
||||
blacklist_factors = table.Column<List<Guid>>(type: "jsonb", nullable: false),
|
||||
audiences = table.Column<List<string>>(type: "jsonb", nullable: false),
|
||||
scopes = table.Column<List<string>>(type: "jsonb", nullable: false),
|
||||
ip_address = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
||||
user_agent = table.Column<string>(type: "character varying(512)", maxLength: 512, nullable: true),
|
||||
device_id = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
nonce = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
||||
location = table.Column<Point>(type: "geometry", nullable: true),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_auth_challenges", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_auth_challenges_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "badges",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
type = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: false),
|
||||
label = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
||||
caption = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
||||
meta = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: false),
|
||||
activated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
expired_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_badges", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_badges_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "magic_spells",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
spell = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: false),
|
||||
type = table.Column<int>(type: "integer", nullable: false),
|
||||
expires_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
affected_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
meta = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: false),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_magic_spells", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_magic_spells_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "notification_push_subscriptions",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
device_id = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: false),
|
||||
device_token = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: false),
|
||||
provider = table.Column<int>(type: "integer", nullable: false),
|
||||
last_used_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_notification_push_subscriptions", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_notification_push_subscriptions_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "notifications",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
topic = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: false),
|
||||
title = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
||||
subtitle = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
||||
content = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
||||
meta = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: true),
|
||||
priority = table.Column<int>(type: "integer", nullable: false),
|
||||
viewed_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_notifications", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_notifications_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "wallets",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_wallets", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_wallets_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "custom_app_secrets",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
secret = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: false),
|
||||
description = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
||||
expired_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
is_oidc = table.Column<bool>(type: "boolean", nullable: false),
|
||||
app_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_custom_app_secrets", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_custom_app_secrets_custom_apps_app_id",
|
||||
column: x => x.app_id,
|
||||
principalTable: "custom_apps",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "permission_group_members",
|
||||
columns: table => new
|
||||
{
|
||||
group_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
actor = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: false),
|
||||
expired_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
affected_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_permission_group_members", x => new { x.group_id, x.actor });
|
||||
table.ForeignKey(
|
||||
name: "fk_permission_group_members_permission_groups_group_id",
|
||||
column: x => x.group_id,
|
||||
principalTable: "permission_groups",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "permission_nodes",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
actor = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: false),
|
||||
area = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: false),
|
||||
key = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: false),
|
||||
value = table.Column<JsonDocument>(type: "jsonb", nullable: false),
|
||||
expired_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
affected_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
group_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_permission_nodes", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_permission_nodes_permission_groups_group_id",
|
||||
column: x => x.group_id,
|
||||
principalTable: "permission_groups",
|
||||
principalColumn: "id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "wallet_subscriptions",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
begun_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
ended_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
identifier = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: false),
|
||||
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
||||
is_free_trial = table.Column<bool>(type: "boolean", nullable: false),
|
||||
status = table.Column<int>(type: "integer", nullable: false),
|
||||
payment_method = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: false),
|
||||
payment_details = table.Column<PaymentDetails>(type: "jsonb", nullable: false),
|
||||
base_price = table.Column<decimal>(type: "numeric", nullable: false),
|
||||
coupon_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
renewal_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_wallet_subscriptions", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_wallet_subscriptions_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "fk_wallet_subscriptions_wallet_coupons_coupon_id",
|
||||
column: x => x.coupon_id,
|
||||
principalTable: "wallet_coupons",
|
||||
principalColumn: "id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "auth_sessions",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
label = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
||||
last_granted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
expired_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
challenge_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
app_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_auth_sessions", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_auth_sessions_accounts_account_id",
|
||||
column: x => x.account_id,
|
||||
principalTable: "accounts",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "fk_auth_sessions_auth_challenges_challenge_id",
|
||||
column: x => x.challenge_id,
|
||||
principalTable: "auth_challenges",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "fk_auth_sessions_custom_apps_app_id",
|
||||
column: x => x.app_id,
|
||||
principalTable: "custom_apps",
|
||||
principalColumn: "id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "payment_transactions",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
currency = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: false),
|
||||
amount = table.Column<decimal>(type: "numeric", nullable: false),
|
||||
remarks = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
||||
type = table.Column<int>(type: "integer", nullable: false),
|
||||
payer_wallet_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
payee_wallet_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_payment_transactions", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_payment_transactions_wallets_payee_wallet_id",
|
||||
column: x => x.payee_wallet_id,
|
||||
principalTable: "wallets",
|
||||
principalColumn: "id");
|
||||
table.ForeignKey(
|
||||
name: "fk_payment_transactions_wallets_payer_wallet_id",
|
||||
column: x => x.payer_wallet_id,
|
||||
principalTable: "wallets",
|
||||
principalColumn: "id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "wallet_pockets",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
currency = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: false),
|
||||
amount = table.Column<decimal>(type: "numeric", nullable: false),
|
||||
wallet_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_wallet_pockets", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_wallet_pockets_wallets_wallet_id",
|
||||
column: x => x.wallet_id,
|
||||
principalTable: "wallets",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "payment_orders",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
status = table.Column<int>(type: "integer", nullable: false),
|
||||
currency = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: false),
|
||||
remarks = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
||||
app_identifier = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
||||
meta = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: true),
|
||||
amount = table.Column<decimal>(type: "numeric", nullable: false),
|
||||
expired_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
payee_wallet_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
transaction_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_payment_orders", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_payment_orders_payment_transactions_transaction_id",
|
||||
column: x => x.transaction_id,
|
||||
principalTable: "payment_transactions",
|
||||
principalColumn: "id");
|
||||
table.ForeignKey(
|
||||
name: "fk_payment_orders_wallets_payee_wallet_id",
|
||||
column: x => x.payee_wallet_id,
|
||||
principalTable: "wallets",
|
||||
principalColumn: "id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_abuse_reports_account_id",
|
||||
table: "abuse_reports",
|
||||
column: "account_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_account_auth_factors_account_id",
|
||||
table: "account_auth_factors",
|
||||
column: "account_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_account_check_in_results_account_id",
|
||||
table: "account_check_in_results",
|
||||
column: "account_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_account_connections_account_id",
|
||||
table: "account_connections",
|
||||
column: "account_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_account_contacts_account_id",
|
||||
table: "account_contacts",
|
||||
column: "account_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_account_profiles_account_id",
|
||||
table: "account_profiles",
|
||||
column: "account_id",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_account_relationships_related_id",
|
||||
table: "account_relationships",
|
||||
column: "related_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_account_statuses_account_id",
|
||||
table: "account_statuses",
|
||||
column: "account_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_accounts_name",
|
||||
table: "accounts",
|
||||
column: "name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_action_logs_account_id",
|
||||
table: "action_logs",
|
||||
column: "account_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_auth_challenges_account_id",
|
||||
table: "auth_challenges",
|
||||
column: "account_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_auth_sessions_account_id",
|
||||
table: "auth_sessions",
|
||||
column: "account_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_auth_sessions_app_id",
|
||||
table: "auth_sessions",
|
||||
column: "app_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_auth_sessions_challenge_id",
|
||||
table: "auth_sessions",
|
||||
column: "challenge_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_badges_account_id",
|
||||
table: "badges",
|
||||
column: "account_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_custom_app_secrets_app_id",
|
||||
table: "custom_app_secrets",
|
||||
column: "app_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_magic_spells_account_id",
|
||||
table: "magic_spells",
|
||||
column: "account_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_magic_spells_spell",
|
||||
table: "magic_spells",
|
||||
column: "spell",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_notification_push_subscriptions_account_id",
|
||||
table: "notification_push_subscriptions",
|
||||
column: "account_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_notification_push_subscriptions_device_token_device_id_acco",
|
||||
table: "notification_push_subscriptions",
|
||||
columns: new[] { "device_token", "device_id", "account_id" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_notifications_account_id",
|
||||
table: "notifications",
|
||||
column: "account_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_payment_orders_payee_wallet_id",
|
||||
table: "payment_orders",
|
||||
column: "payee_wallet_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_payment_orders_transaction_id",
|
||||
table: "payment_orders",
|
||||
column: "transaction_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_payment_transactions_payee_wallet_id",
|
||||
table: "payment_transactions",
|
||||
column: "payee_wallet_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_payment_transactions_payer_wallet_id",
|
||||
table: "payment_transactions",
|
||||
column: "payer_wallet_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_permission_nodes_group_id",
|
||||
table: "permission_nodes",
|
||||
column: "group_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_permission_nodes_key_area_actor",
|
||||
table: "permission_nodes",
|
||||
columns: new[] { "key", "area", "actor" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_wallet_pockets_wallet_id",
|
||||
table: "wallet_pockets",
|
||||
column: "wallet_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_wallet_subscriptions_account_id",
|
||||
table: "wallet_subscriptions",
|
||||
column: "account_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_wallet_subscriptions_coupon_id",
|
||||
table: "wallet_subscriptions",
|
||||
column: "coupon_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_wallet_subscriptions_identifier",
|
||||
table: "wallet_subscriptions",
|
||||
column: "identifier");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_wallets_account_id",
|
||||
table: "wallets",
|
||||
column: "account_id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "abuse_reports");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "account_auth_factors");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "account_check_in_results");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "account_connections");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "account_contacts");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "account_profiles");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "account_relationships");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "account_statuses");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "action_logs");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "auth_sessions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "badges");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "custom_app_secrets");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "magic_spells");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "notification_push_subscriptions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "notifications");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "payment_orders");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "permission_group_members");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "permission_nodes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "wallet_pockets");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "wallet_subscriptions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "auth_challenges");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "custom_apps");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "payment_transactions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "permission_groups");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "wallet_coupons");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "wallets");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "accounts");
|
||||
}
|
||||
}
|
||||
}
|
1974
DysonNetwork.Pass/Migrations/AppDatabaseModelSnapshot.cs
Normal file
1974
DysonNetwork.Pass/Migrations/AppDatabaseModelSnapshot.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -28,8 +28,6 @@ builder.Services.AddAppBusinessServices(builder.Configuration);
|
||||
// Add scheduled jobs
|
||||
builder.Services.AddAppScheduledJobs();
|
||||
|
||||
builder.Services.AddHostedService<ServiceRegistrationHostedService>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Run database migrations
|
||||
|
@@ -1,56 +0,0 @@
|
||||
using DysonNetwork.Shared.Registry;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DysonNetwork.Pass.Startup;
|
||||
|
||||
public class ServiceRegistrationHostedService : IHostedService
|
||||
{
|
||||
private readonly ServiceRegistry _serviceRegistry;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly ILogger<ServiceRegistrationHostedService> _logger;
|
||||
|
||||
public ServiceRegistrationHostedService(
|
||||
ServiceRegistry serviceRegistry,
|
||||
IConfiguration configuration,
|
||||
ILogger<ServiceRegistrationHostedService> logger)
|
||||
{
|
||||
_serviceRegistry = serviceRegistry;
|
||||
_configuration = configuration;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var serviceName = "DysonNetwork.Pass"; // Preset service name
|
||||
var serviceUrl = _configuration["Service:Url"];
|
||||
|
||||
if (string.IsNullOrEmpty(serviceName) || string.IsNullOrEmpty(serviceUrl))
|
||||
{
|
||||
_logger.LogWarning("Service name or URL not configured. Skipping Etcd registration.");
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Registering service {ServiceName} at {ServiceUrl} with Etcd.", serviceName, serviceUrl);
|
||||
try
|
||||
{
|
||||
await _serviceRegistry.RegisterService(serviceName, serviceUrl);
|
||||
_logger.LogInformation("Service {ServiceName} registered successfully.", serviceName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to register service {ServiceName} with Etcd.", serviceName);
|
||||
}
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
// The lease will expire automatically if the service stops.
|
||||
// For explicit unregistration, you would implement it here.
|
||||
_logger.LogInformation("Service registration hosted service is stopping.");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
@@ -9,8 +9,9 @@
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"App": "Host=localhost;Port=5432;Database=dyson_network;Username=postgres;Password=postgres;Include Error Detail=True;Maximum Pool Size=20;Connection Idle Lifetime=60",
|
||||
"FastRetrieve": "localhost:6379"
|
||||
"App": "Host=localhost;Port=5432;Database=dyson_pass;Username=postgres;Password=postgres;Include Error Detail=True;Maximum Pool Size=20;Connection Idle Lifetime=60",
|
||||
"FastRetrieve": "localhost:6379",
|
||||
"Etcd": "etcd.orb.local:2379"
|
||||
},
|
||||
"Authentication": {
|
||||
"Schemes": {
|
||||
@@ -36,60 +37,11 @@
|
||||
"AuthorizationCodeLifetime": "00:30:00",
|
||||
"RequireHttpsMetadata": true
|
||||
},
|
||||
"Tus": {
|
||||
"StorePath": "Uploads"
|
||||
},
|
||||
"Storage": {
|
||||
"PreferredRemote": "minio",
|
||||
"Remote": [
|
||||
{
|
||||
"Id": "minio",
|
||||
"Label": "Minio",
|
||||
"Region": "auto",
|
||||
"Bucket": "solar-network-development",
|
||||
"Endpoint": "localhost:9000",
|
||||
"SecretId": "littlesheep",
|
||||
"SecretKey": "password",
|
||||
"EnabledSigned": true,
|
||||
"EnableSsl": false
|
||||
},
|
||||
{
|
||||
"Id": "cloudflare",
|
||||
"Label": "Cloudflare R2",
|
||||
"Region": "auto",
|
||||
"Bucket": "solar-network",
|
||||
"Endpoint": "0a70a6d1b7128888c823359d0008f4e1.r2.cloudflarestorage.com",
|
||||
"SecretId": "8ff5d06c7b1639829d60bc6838a542e6",
|
||||
"SecretKey": "fd58158c5201be16d1872c9209d9cf199421dae3c2f9972f94b2305976580d67",
|
||||
"EnableSigned": true,
|
||||
"EnableSsl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"Captcha": {
|
||||
"Provider": "cloudflare",
|
||||
"ApiKey": "0x4AAAAAABCDUdOujj4feOb_",
|
||||
"ApiSecret": "0x4AAAAAABCDUWABiJQweqlB7tYq-IqIm8U"
|
||||
},
|
||||
"Notifications": {
|
||||
"Topic": "dev.solsynth.solian",
|
||||
"Endpoint": "http://localhost:8088"
|
||||
},
|
||||
"Email": {
|
||||
"Server": "smtp4dev.orb.local",
|
||||
"Port": 25,
|
||||
"UseSsl": false,
|
||||
"Username": "no-reply@mail.solsynth.dev",
|
||||
"Password": "password",
|
||||
"FromAddress": "no-reply@mail.solsynth.dev",
|
||||
"FromName": "Alphabot",
|
||||
"SubjectPrefix": "Solar Network"
|
||||
},
|
||||
"RealtimeChat": {
|
||||
"Endpoint": "https://solar-network-im44o8gq.livekit.cloud",
|
||||
"ApiKey": "APIs6TiL8wj3A4j",
|
||||
"ApiSecret": "SffxRneIwTnlHPtEf3zicmmv3LUEl7xXael4PvWZrEhE"
|
||||
},
|
||||
"GeoIp": {
|
||||
"DatabasePath": "./Keys/GeoLite2-City.mmdb"
|
||||
},
|
||||
@@ -125,5 +77,14 @@
|
||||
"KnownProxies": [
|
||||
"127.0.0.1",
|
||||
"::1"
|
||||
]
|
||||
],
|
||||
"Service": {
|
||||
"Name": "DysonNetwork.Pass",
|
||||
"Url": "http://localhost:5216",
|
||||
"ClientCert": "../Certificates/client.crt",
|
||||
"ClientKey": "../Certificates/client.key"
|
||||
},
|
||||
"Etcd": {
|
||||
"Insecure": true
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user