mirror of
https://github.com/Govor-team/Govor.git
synced 2026-07-21 11:44:56 +00:00
Refactor: migrate Core -> Domain and reorganize projects
Large refactor that renames/moves core types into a new Govor.Domain surface and reorganizes the Application layer. Models, configurations, migrations and many files moved from Govor.Core/Govor.Data to Govor.Domain; numerous Application services, interfaces and implementations were relocated or added (authentication, friends, messages, medias, push notifications, user sessions, storage, synching, private chats, etc.). Tests updated to use Govor.Domain namespaces and adjusted project references (removed Govor.Data reference from API tests). Also updated API, Hub and mapping code and project files to reflect the new structure and naming. This is primarily a codebase-wide namespace and module reorganization to establish a Domain project and restructure application services.
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
namespace Govor.Domain.Common.Constants;
|
||||
|
||||
public class InvitationConstants
|
||||
{
|
||||
public const int MIN_INVITATION_LENGTH = 5;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Govor.Domain.Common.Constants;
|
||||
|
||||
public class UserConstants
|
||||
{
|
||||
public const int MAX_LENGHT_OF_NAME = 44;
|
||||
public const int MIN_LENGHT_OF_NAME = 4;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Govor.Domain.Common;
|
||||
|
||||
|
||||
public record Error(string Code, string Message)
|
||||
{
|
||||
public static readonly Error None = new(string.Empty, string.Empty);
|
||||
public static readonly Error Null = new("NULL", "Value cannot be null.");
|
||||
public override string ToString() => $"{Code}: {Message}";
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Govor.Domain.Common.Extensions;
|
||||
|
||||
public static class QueryableExtensions
|
||||
{
|
||||
public static async Task<List<T>> ToListOrThrowIfEmpty<T>(this IQueryable<T> query, Exception ex)
|
||||
{
|
||||
var list = await query.ToListAsync();
|
||||
if (list.Count == 0) throw ex;
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
namespace Govor.Domain.Common;
|
||||
|
||||
public class Result
|
||||
{
|
||||
protected Result(bool isSuccess, Error error)
|
||||
{
|
||||
if (isSuccess && error != Error.None || !isSuccess && error == Error.None)
|
||||
{
|
||||
throw new ArgumentException("Invalid error state", nameof(error));
|
||||
}
|
||||
|
||||
IsSuccess = isSuccess;
|
||||
Error = error;
|
||||
}
|
||||
|
||||
public bool IsSuccess { get; }
|
||||
public bool IsFailure => !IsSuccess;
|
||||
public Error Error { get; }
|
||||
|
||||
public static Result Success() => new(true, Error.None);
|
||||
public static Result Failure(Error error) => new(false, error);
|
||||
|
||||
public static Result Failure(Exception ex) => new(false, new Error(ex.GetType().Name, ex.Message));
|
||||
|
||||
public static implicit operator Result(Error error) => Failure(error);
|
||||
}
|
||||
|
||||
public class Result<T> : Result
|
||||
{
|
||||
private readonly T? _value;
|
||||
|
||||
private Result(T? value, bool isSuccess, Error error) : base(isSuccess, error)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public T Value => IsSuccess
|
||||
? _value!
|
||||
: throw new InvalidOperationException("The value of a failure result cannot be accessed.");
|
||||
|
||||
public static Result<T> Success(T value) => new(value, true, Error.None);
|
||||
public static new Result<T> Failure(Error error) => new(default, false, error);
|
||||
public static new Result<T> Failure(Exception ex) => new(default, false, new Error(ex.GetType().Name, ex.Message));
|
||||
|
||||
public static implicit operator Result<T>(T value) => Success(value);
|
||||
|
||||
public static implicit operator Result<T>(Error error) => Failure(error);
|
||||
public static implicit operator T(Result<T> result) => result.Value;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Govor.Domain.Models.Users;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class AdminConfiguration : IEntityTypeConfiguration<Admin>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Admin> builder)
|
||||
{
|
||||
builder.HasKey(a => a.UserId);
|
||||
|
||||
builder.HasOne(a => a.User)
|
||||
.WithOne()
|
||||
.HasForeignKey<Admin>(a => a.UserId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Govor.Domain.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class ChatGroupConfigurator : IEntityTypeConfiguration<ChatGroup>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ChatGroup> builder)
|
||||
{
|
||||
builder.HasKey(e => e.Id);
|
||||
|
||||
builder.Property(e => e.Name).IsRequired().HasMaxLength(100);
|
||||
builder.Property(e => e.Description).HasMaxLength(500);
|
||||
|
||||
builder.HasMany(e => e.Members)
|
||||
.WithOne()
|
||||
.HasForeignKey(e => e.GroupId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(e => e.Admins)
|
||||
.WithOne()
|
||||
.HasForeignKey(e => e.GroupId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(e => e.InviteCodes)
|
||||
.WithOne()
|
||||
.HasForeignKey(e => e.GroupId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Govor.Domain.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class FriendshipConfiguration : IEntityTypeConfiguration<Friendship>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Friendship> builder)
|
||||
{
|
||||
builder.HasKey(f => f.Id);
|
||||
|
||||
builder.HasOne(f => f.Requester)
|
||||
.WithMany(u => u.SentFriendRequests)
|
||||
.HasForeignKey(f => f.RequesterId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
builder.HasOne(f => f.Addressee)
|
||||
.WithMany(u => u.ReceivedFriendRequests)
|
||||
.HasForeignKey(f => f.AddresseeId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
builder.Property(f => f.Status)
|
||||
.IsRequired();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Govor.Domain.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class GroupAdminsConfiguration : IEntityTypeConfiguration<GroupAdmins>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<GroupAdmins> builder)
|
||||
{
|
||||
builder.HasKey(e => e.Id);
|
||||
|
||||
builder.Property(e => e.UserId).IsRequired();
|
||||
builder.Property(e => e.GroupId).IsRequired();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Govor.Domain.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class GroupInvitationConfiguration : IEntityTypeConfiguration<GroupInvitation>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<GroupInvitation> builder)
|
||||
{
|
||||
builder.HasKey(e => e.Id);
|
||||
|
||||
builder.Property(e => e.InvitationCode).IsRequired().HasMaxLength(200);
|
||||
builder.Property(e => e.Description).HasMaxLength(500);
|
||||
builder.Property(e => e.EndDate).IsRequired();
|
||||
builder.Property(e => e.CreatedAt).IsRequired();
|
||||
|
||||
builder.HasOne(e => e.UserMaker)
|
||||
.WithMany()
|
||||
.HasForeignKey(e => e.UserMakerId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
|
||||
builder.Ignore(e => e.GroupMemberships);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Govor.Domain.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class GroupMembershipConfiguration : IEntityTypeConfiguration<GroupMembership>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<GroupMembership> builder)
|
||||
{
|
||||
builder.HasKey(e => e.Id);
|
||||
|
||||
builder.Property(e => e.UserId).IsRequired();
|
||||
builder.Property(e => e.GroupId).IsRequired();
|
||||
builder.Property(e => e.InvitationId).IsRequired(false);
|
||||
|
||||
builder.HasOne(e => e.ChatGroup)
|
||||
.WithMany()
|
||||
.HasForeignKey(e => e.GroupId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
// Optional: настройка связи с GroupInvitation
|
||||
builder.HasOne<GroupInvitation>()
|
||||
.WithMany()
|
||||
.HasForeignKey(e => e.InvitationId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Govor.Domain.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class InvitationConfiguration : IEntityTypeConfiguration<Invitation>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Invitation> builder)
|
||||
{
|
||||
builder.HasKey(i => i.Id);
|
||||
|
||||
builder.HasMany(i => i.Users)
|
||||
.WithOne(u => u.Invite)
|
||||
.HasForeignKey(u => u.InviteId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Govor.Domain.Models.Messages;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class MediaAttachmentsConfiguration : IEntityTypeConfiguration<MediaAttachments>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<MediaAttachments> builder)
|
||||
{
|
||||
builder.HasKey(ma => ma.Id);
|
||||
|
||||
builder.HasOne(ma => ma.Message)
|
||||
.WithMany(m => m.MediaAttachments)
|
||||
.HasForeignKey(ma => ma.MessageId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasOne(ma => ma.MediaFile)
|
||||
.WithMany()
|
||||
.HasForeignKey(ma => ma.MediaFileId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Govor.Domain.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class MediaFileConfiguration : IEntityTypeConfiguration<MediaFile>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<MediaFile> builder)
|
||||
{
|
||||
builder.HasKey(ma => ma.Id);
|
||||
|
||||
builder.Property(mf => mf.Url)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(mf => mf.MediaType)
|
||||
.HasConversion<string>() // enum as string (e.g., "Image")
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(ma => ma.MineType)
|
||||
.HasMaxLength(128)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(mf => mf.DateCreated)
|
||||
.IsRequired();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using Govor.Domain.Models.Messages;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class MessageReactionConfiguration : IEntityTypeConfiguration<MessageReaction>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<MessageReaction> builder)
|
||||
{
|
||||
builder.HasKey(r => r.Id);
|
||||
|
||||
builder.HasIndex(r => new { r.MessageId, r.UserId }).IsUnique(); // Одна реакция от одного юзера
|
||||
|
||||
builder.Property(r => r.ReactionCode)
|
||||
.IsRequired()
|
||||
.HasMaxLength(64); // можно увеличить для кастомных эмодзи
|
||||
|
||||
builder.HasOne(r => r.User)
|
||||
.WithMany()
|
||||
.HasForeignKey(r => r.UserId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Govor.Domain.Models.Messages;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class MessageViewConfiguration : IEntityTypeConfiguration<MessageView>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<MessageView> builder)
|
||||
{
|
||||
builder.HasKey(mv => mv.Id);
|
||||
|
||||
builder.HasIndex(mv => new { mv.MessageId, mv.UserId }).IsUnique();
|
||||
|
||||
builder.Property(mv => mv.ViewedAt)
|
||||
.IsRequired();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using Govor.Domain.Models.Messages;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class MessagesConfiguration : IEntityTypeConfiguration<Message>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Message> builder)
|
||||
{
|
||||
builder.HasKey(m => m.Id);
|
||||
|
||||
// Просто индекс, без unique
|
||||
builder.HasIndex(m => m.RecipientId);
|
||||
|
||||
builder.HasMany(m => m.Reactions)
|
||||
.WithOne(r => r.Message)
|
||||
.HasForeignKey(r => r.MessageId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(m => m.MediaAttachments)
|
||||
.WithOne(ma => ma.Message)
|
||||
.HasForeignKey(ma => ma.MessageId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(m => m.MessageViews)
|
||||
.WithOne()
|
||||
.HasForeignKey(mv => mv.MessageId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.Property(m => m.EncryptedContent)
|
||||
.IsRequired();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using Govor.Domain.Models.Users.Crypto;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class OneTimePreKeyConfiguration : IEntityTypeConfiguration<OneTimePreKey>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<OneTimePreKey> builder)
|
||||
{
|
||||
// Первичный ключ
|
||||
builder.HasKey(otpk => otpk.Id);
|
||||
|
||||
builder.HasOne(otpk => otpk.UserCryptoSession)
|
||||
.WithMany(ucs => ucs.OneTimePreKeys)
|
||||
.HasForeignKey(otpk => otpk.UserCryptoSessionId)
|
||||
.IsRequired()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.Property(otpk => otpk.PublicKey)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(otpk => otpk.IsUsed)
|
||||
.IsRequired()
|
||||
.HasDefaultValue(false);
|
||||
|
||||
builder.Property(otpk => otpk.UploadedAt)
|
||||
.IsRequired();
|
||||
|
||||
builder.HasIndex(otpk => new { otpk.UserCryptoSessionId, otpk.IsUsed });
|
||||
builder.HasIndex(otpk => otpk.UploadedAt);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Govor.Domain.Models.Users;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class PrivacyRuleEntityConfiguration : IEntityTypeConfiguration<PrivacyRuleEntity>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<PrivacyRuleEntity> builder)
|
||||
{
|
||||
builder.HasKey(r => r.Id);
|
||||
|
||||
builder.Property(r => r.OwnerId).IsRequired();
|
||||
builder.Property(r => r.Area).IsRequired().HasConversion<string>();
|
||||
builder.Property(r => r.AccessType).IsRequired().HasConversion<string>();
|
||||
|
||||
builder.Property(r => r.Whitelist).HasColumnType("jsonb");
|
||||
builder.Property(r => r.Blacklist).HasColumnType("jsonb");
|
||||
|
||||
builder.HasIndex(r => r.OwnerId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Govor.Domain.Models.Users;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class PrivacyUserSettingsConfiguration : IEntityTypeConfiguration<PrivacyUserSettings>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<PrivacyUserSettings> builder)
|
||||
{
|
||||
// Primary Key
|
||||
builder.HasKey(p => p.UserId);
|
||||
|
||||
builder.Property(p => p.DeletingVia)
|
||||
.IsRequired()
|
||||
.HasConversion<string>()
|
||||
.HasDefaultValue(DeletingMessagesVia.None); // Adjust default as needed
|
||||
|
||||
builder.Property(p => p.DeletingIn)
|
||||
.IsRequired()
|
||||
.HasDefaultValue(0);
|
||||
|
||||
// Relationship Configuration
|
||||
builder.HasMany(p => p.Rules)
|
||||
.WithOne(r => r.OwnerSettings)
|
||||
.HasForeignKey(r => r.OwnerId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Govor.Domain.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class PrivateChatsConfiguration : IEntityTypeConfiguration<PrivateChat>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<PrivateChat> builder)
|
||||
{
|
||||
builder.HasKey(us => us.Id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Govor.Domain.Models.Users.Crypto;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class SignedPreKeyConfiguration : IEntityTypeConfiguration<SignedPreKey>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<SignedPreKey> builder)
|
||||
{
|
||||
builder.HasKey(spk => spk.Id);
|
||||
|
||||
builder.HasOne(spk => spk.UserCryptoSession)
|
||||
.WithOne(ucs => ucs.SignedPreKey)
|
||||
.HasForeignKey<SignedPreKey>(spk => spk.UserCryptoSessionId)
|
||||
.IsRequired()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.Property(spk => spk.PublicSignedPreKey)
|
||||
.IsRequired();
|
||||
builder.Property(spk => spk.SignedPreKeySignature)
|
||||
.IsRequired();
|
||||
|
||||
builder.HasIndex(spk => spk.UserCryptoSessionId)
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Govor.Domain.Models.Users;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class UserConfiguration : IEntityTypeConfiguration<User>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<User> builder)
|
||||
{
|
||||
builder.HasKey(x => x.Id);
|
||||
|
||||
builder.HasIndex(u => u.Username).IsUnique();
|
||||
builder.HasIndex(u => u.CreatedOn);
|
||||
builder.HasIndex(u => u.WasOnline);
|
||||
|
||||
builder.HasOne(u => u.Invite)
|
||||
.WithMany(i => i.Users)
|
||||
.HasForeignKey(u => u.InviteId);
|
||||
|
||||
builder.Property(u => u.Username)
|
||||
.IsRequired()
|
||||
.HasMaxLength(50);
|
||||
|
||||
builder.HasIndex(u => u.Username).IsUnique();
|
||||
|
||||
builder.Property(u => u.Description)
|
||||
.HasMaxLength(500)
|
||||
.IsRequired(false);
|
||||
|
||||
builder.Property(u => u.PasswordHash)
|
||||
.IsRequired()
|
||||
.HasMaxLength(128);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using Govor.Domain.Models.Users.Crypto;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class UserCryptoSessionConfiguration : IEntityTypeConfiguration<UserCryptoSession>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<UserCryptoSession> builder)
|
||||
{
|
||||
builder.HasKey(ucs => ucs.Id);
|
||||
|
||||
builder.HasOne(ucs => ucs.UserSession)
|
||||
.WithOne(us => us.CryptoSession)
|
||||
.HasForeignKey<UserCryptoSession>(ucs => ucs.UserSessionId)
|
||||
.IsRequired()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasOne(ucs => ucs.SignedPreKey)
|
||||
.WithOne(spk => spk.UserCryptoSession)
|
||||
.HasForeignKey<SignedPreKey>(spk => spk.UserCryptoSessionId)
|
||||
.IsRequired()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(ucs => ucs.OneTimePreKeys)
|
||||
.WithOne(otpk => otpk.UserCryptoSession)
|
||||
.HasForeignKey(otpk => otpk.UserCryptoSessionId)
|
||||
.IsRequired()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasIndex(ucs => ucs.UserSessionId)
|
||||
.IsUnique();
|
||||
|
||||
builder.Property(ucs => ucs.PublicIdentityKey)
|
||||
.IsRequired();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using Govor.Domain.Models.Users;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class UserPushTokenConfiguration : IEntityTypeConfiguration<UserPushToken>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<UserPushToken> builder)
|
||||
{
|
||||
builder.HasKey(t => t.Id);
|
||||
|
||||
builder.HasIndex(x => x.Token)
|
||||
.IsUnique();
|
||||
|
||||
builder.HasIndex(x => x.UserSessionId)
|
||||
.IsUnique();
|
||||
|
||||
builder.HasIndex(x => new { x.UserId, x.IsActive });
|
||||
|
||||
builder.Property(x => x.Token)
|
||||
.IsRequired()
|
||||
.HasMaxLength(512);
|
||||
|
||||
builder.Property(x => x.Platform)
|
||||
.IsRequired()
|
||||
.HasMaxLength(50);
|
||||
|
||||
builder.Property(x => x.Provider)
|
||||
.IsRequired()
|
||||
.HasMaxLength(50);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using Govor.Domain.Models.Users;
|
||||
using Govor.Domain.Models.Users.Crypto;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Govor.Domain.Configurations;
|
||||
|
||||
public class UserSessionConfiguration : IEntityTypeConfiguration<UserSession>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<UserSession> builder)
|
||||
{
|
||||
builder.HasKey(us => us.Id);
|
||||
|
||||
builder.HasIndex(us => us.UserId);
|
||||
|
||||
builder.HasIndex(s => s.RefreshTokenHash)
|
||||
.IsUnique();
|
||||
|
||||
builder.Property(us => us.RefreshTokenHash)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(us => us.DeviceInfo)
|
||||
.HasMaxLength(256);
|
||||
|
||||
builder.HasOne(us => us.User)
|
||||
.WithMany()
|
||||
.HasForeignKey(us => us.UserId)
|
||||
.IsRequired()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasOne(e => e.CryptoSession)
|
||||
.WithOne(e => e.UserSession)
|
||||
.HasForeignKey<UserCryptoSession>(e => e.UserSessionId)
|
||||
.IsRequired()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.6" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace Govor.Domain;
|
||||
|
||||
/// <summary>
|
||||
/// Base exception class for Govor solutions
|
||||
/// </summary>
|
||||
public class GovorCoreException : Exception
|
||||
{
|
||||
public GovorCoreException() { }
|
||||
|
||||
public GovorCoreException(string message)
|
||||
: base(message) { }
|
||||
|
||||
public GovorCoreException(string message, Exception innerException)
|
||||
: base(message, innerException) { }
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using Govor.Domain.Models;
|
||||
using Govor.Domain.Models.Messages;
|
||||
using Govor.Domain.Models.Users;
|
||||
using Govor.Domain.Models.Users.Crypto;
|
||||
using Govor.Domain.Configurations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Govor.Domain;
|
||||
|
||||
public class GovorDbContext(DbContextOptions<GovorDbContext> options) : DbContext(options)
|
||||
{
|
||||
public virtual DbSet<User> Users { get; set; }
|
||||
public virtual DbSet<UserSession> UserSessions { get; set; }
|
||||
public virtual DbSet<UserPushToken> UserPushTokens { get; set; }
|
||||
public virtual DbSet<UserCryptoSession> UserCryptoSessions { get; set; }
|
||||
public virtual DbSet<SignedPreKey> SignedPreKeys { get; set; }
|
||||
public virtual DbSet<OneTimePreKey> OneTimePreKeys { get; set; }
|
||||
public virtual DbSet<Friendship> Friendships { get; set; }
|
||||
public virtual DbSet<PrivateChat> PrivateChats { get; set; }
|
||||
public virtual DbSet<Admin> Admins { get; set; }
|
||||
|
||||
public virtual DbSet<Invitation> Invitations { get; set; }
|
||||
|
||||
public virtual DbSet<Message> Messages { get; set; }
|
||||
public virtual DbSet<MessageView> MessageViews { get; set; }
|
||||
public virtual DbSet<MessageReaction> MessageReactions { get; set; }
|
||||
public virtual DbSet<MediaAttachments> MediaAttachments { get; set; }
|
||||
public virtual DbSet<MediaFile> MediaFiles { get; set; }
|
||||
|
||||
public virtual DbSet<ChatGroup> ChatGroups { get; set; }
|
||||
public virtual DbSet<GroupInvitation> GroupInvitations { get; set; }
|
||||
public virtual DbSet<GroupMembership> GroupMemberships { get; set; }
|
||||
public virtual DbSet<GroupAdmins> GroupAdmins { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.ApplyConfiguration(new UserSessionConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new FriendshipConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new UserConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new InvitationConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new AdminConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new MessagesConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new MessageReactionConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new MediaAttachmentsConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new MessageViewConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new MediaFileConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new ChatGroupConfigurator());
|
||||
modelBuilder.ApplyConfiguration(new GroupInvitationConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new GroupMembershipConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new GroupAdminsConfiguration());
|
||||
|
||||
modelBuilder.ApplyConfiguration(new OneTimePreKeyConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new UserCryptoSessionConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new SignedPreKeyConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new PrivateChatsConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new UserPushTokenConfiguration());
|
||||
base.OnModelCreating(modelBuilder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,848 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Govor.Domain;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Govor.Domain.Migrations
|
||||
{
|
||||
[DbContext(typeof(GovorDbContext))]
|
||||
[Migration("20260716110338_InitialCreate")]
|
||||
partial class InitialCreate
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.6")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.ChatGroup", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<Guid>("ImageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsChannel")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsPrivate")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ChatGroups");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Friendship", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("AddresseeId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("RequesterId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AddresseeId");
|
||||
|
||||
b.HasIndex("RequesterId");
|
||||
|
||||
b.ToTable("Friendships");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.GroupAdmins", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("GroupId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GroupId");
|
||||
|
||||
b.ToTable("GroupAdmins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.GroupInvitation", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<DateTime>("EndDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("GroupId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("InvitationCode")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<int>("MaxParticipants")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid>("UserMakerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GroupId");
|
||||
|
||||
b.HasIndex("UserMakerId");
|
||||
|
||||
b.ToTable("GroupInvitations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.GroupMembership", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("ChatGroupId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("GroupId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("InvitationId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsBanned")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTime>("MemberSince")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChatGroupId");
|
||||
|
||||
b.HasIndex("GroupId");
|
||||
|
||||
b.HasIndex("InvitationId");
|
||||
|
||||
b.ToTable("GroupMemberships");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Invitation", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("DateCreated")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("EndDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAdmin")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<int>("MaxParticipants")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Invitations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.MediaFile", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("DateCreated")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("MediaType")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("MineType")
|
||||
.IsRequired()
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("character varying(128)");
|
||||
|
||||
b.Property<Guid?>("OwnerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("OwnerType")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid>("UploaderId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("MediaFiles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.MediaAttachments", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("MediaFileId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("MessageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MediaFileId");
|
||||
|
||||
b.HasIndex("MessageId");
|
||||
|
||||
b.ToTable("MediaAttachments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.Message", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("ChatGroupId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime?>("EditedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("EncryptedContent")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsEdited")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<Guid?>("PrivateChatId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("RecipientId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("RecipientType")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid?>("ReplyToMessageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("SenderId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("SentAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChatGroupId");
|
||||
|
||||
b.HasIndex("PrivateChatId");
|
||||
|
||||
b.HasIndex("RecipientId");
|
||||
|
||||
b.ToTable("Messages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.MessageReaction", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("MessageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("ReactedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("ReactionCode")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.HasIndex("MessageId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("MessageReactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.MessageView", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("MessageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("ViewedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MessageId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("MessageViews");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.PrivateChat", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("UserAId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("UserBId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PrivateChats");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Admin", b =>
|
||||
{
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("UserId");
|
||||
|
||||
b.ToTable("Admins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Crypto.OneTimePreKey", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsUsed")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(false);
|
||||
|
||||
b.Property<byte[]>("PublicKey")
|
||||
.IsRequired()
|
||||
.HasColumnType("bytea");
|
||||
|
||||
b.Property<DateTime>("UploadedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("UserCryptoSessionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UploadedAt");
|
||||
|
||||
b.HasIndex("UserCryptoSessionId", "IsUsed");
|
||||
|
||||
b.ToTable("OneTimePreKeys");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Crypto.SignedPreKey", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<byte[]>("PublicSignedPreKey")
|
||||
.IsRequired()
|
||||
.HasColumnType("bytea");
|
||||
|
||||
b.Property<byte[]>("SignedPreKeySignature")
|
||||
.IsRequired()
|
||||
.HasColumnType("bytea");
|
||||
|
||||
b.Property<Guid>("UserCryptoSessionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserCryptoSessionId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("SignedPreKeys");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Crypto.UserCryptoSession", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<byte[]>("PublicIdentityKey")
|
||||
.IsRequired()
|
||||
.HasColumnType("bytea");
|
||||
|
||||
b.Property<Guid>("UserSessionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserSessionId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("UserCryptoSessions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.User", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateOnly>("CreatedOn")
|
||||
.HasColumnType("date");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<Guid>("IconId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("InviteId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.IsRequired()
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("character varying(128)");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<DateTime>("WasOnline")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedOn");
|
||||
|
||||
b.HasIndex("InviteId");
|
||||
|
||||
b.HasIndex("Username")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("WasOnline");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.UserPushToken", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTime?>("LastUsedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Platform")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("Provider")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("Token")
|
||||
.IsRequired()
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("character varying(512)");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("UserSessionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Token")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("UserSessionId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("UserId", "IsActive");
|
||||
|
||||
b.ToTable("UserPushTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.UserSession", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("DeviceInfo")
|
||||
.IsRequired()
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<DateTime>("ExpiresAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("IsRevoked")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("RefreshTokenHash")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RefreshTokenHash")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserSessions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Friendship", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Users.User", "Addressee")
|
||||
.WithMany("ReceivedFriendRequests")
|
||||
.HasForeignKey("AddresseeId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Govor.Domain.Models.Users.User", "Requester")
|
||||
.WithMany("SentFriendRequests")
|
||||
.HasForeignKey("RequesterId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Addressee");
|
||||
|
||||
b.Navigation("Requester");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.GroupAdmins", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.ChatGroup", null)
|
||||
.WithMany("Admins")
|
||||
.HasForeignKey("GroupId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.GroupInvitation", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.ChatGroup", null)
|
||||
.WithMany("InviteCodes")
|
||||
.HasForeignKey("GroupId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Govor.Domain.Models.Users.User", "UserMaker")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserMakerId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("UserMaker");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.GroupMembership", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.ChatGroup", null)
|
||||
.WithMany("Members")
|
||||
.HasForeignKey("ChatGroupId");
|
||||
|
||||
b.HasOne("Govor.Domain.Models.ChatGroup", "ChatGroup")
|
||||
.WithMany()
|
||||
.HasForeignKey("GroupId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Govor.Domain.Models.GroupInvitation", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("InvitationId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.Navigation("ChatGroup");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.MediaAttachments", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.MediaFile", "MediaFile")
|
||||
.WithMany()
|
||||
.HasForeignKey("MediaFileId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Govor.Domain.Models.Messages.Message", "Message")
|
||||
.WithMany("MediaAttachments")
|
||||
.HasForeignKey("MessageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("MediaFile");
|
||||
|
||||
b.Navigation("Message");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.Message", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.ChatGroup", null)
|
||||
.WithMany("Messages")
|
||||
.HasForeignKey("ChatGroupId");
|
||||
|
||||
b.HasOne("Govor.Domain.Models.PrivateChat", null)
|
||||
.WithMany("Messages")
|
||||
.HasForeignKey("PrivateChatId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.MessageReaction", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Messages.Message", "Message")
|
||||
.WithMany("Reactions")
|
||||
.HasForeignKey("MessageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Govor.Domain.Models.Users.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Message");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.MessageView", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Messages.Message", null)
|
||||
.WithMany("MessageViews")
|
||||
.HasForeignKey("MessageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Admin", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Users.User", "User")
|
||||
.WithOne()
|
||||
.HasForeignKey("Govor.Domain.Models.Users.Admin", "UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Crypto.OneTimePreKey", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Users.Crypto.UserCryptoSession", "UserCryptoSession")
|
||||
.WithMany("OneTimePreKeys")
|
||||
.HasForeignKey("UserCryptoSessionId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("UserCryptoSession");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Crypto.SignedPreKey", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Users.Crypto.UserCryptoSession", "UserCryptoSession")
|
||||
.WithOne("SignedPreKey")
|
||||
.HasForeignKey("Govor.Domain.Models.Users.Crypto.SignedPreKey", "UserCryptoSessionId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("UserCryptoSession");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Crypto.UserCryptoSession", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Users.UserSession", "UserSession")
|
||||
.WithOne("CryptoSession")
|
||||
.HasForeignKey("Govor.Domain.Models.Users.Crypto.UserCryptoSession", "UserSessionId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("UserSession");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.User", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Invitation", "Invite")
|
||||
.WithMany("Users")
|
||||
.HasForeignKey("InviteId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Invite");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.UserSession", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Users.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.ChatGroup", b =>
|
||||
{
|
||||
b.Navigation("Admins");
|
||||
|
||||
b.Navigation("InviteCodes");
|
||||
|
||||
b.Navigation("Members");
|
||||
|
||||
b.Navigation("Messages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Invitation", b =>
|
||||
{
|
||||
b.Navigation("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.Message", b =>
|
||||
{
|
||||
b.Navigation("MediaAttachments");
|
||||
|
||||
b.Navigation("MessageViews");
|
||||
|
||||
b.Navigation("Reactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.PrivateChat", b =>
|
||||
{
|
||||
b.Navigation("Messages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Crypto.UserCryptoSession", b =>
|
||||
{
|
||||
b.Navigation("OneTimePreKeys");
|
||||
|
||||
b.Navigation("SignedPreKey")
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.User", b =>
|
||||
{
|
||||
b.Navigation("ReceivedFriendRequests");
|
||||
|
||||
b.Navigation("SentFriendRequests");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.UserSession", b =>
|
||||
{
|
||||
b.Navigation("CryptoSession")
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,650 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Govor.Domain.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialCreate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChatGroups",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||
Description = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: false),
|
||||
ImageId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
IsChannel = table.Column<bool>(type: "boolean", nullable: false),
|
||||
IsPrivate = table.Column<bool>(type: "boolean", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChatGroups", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Invitations",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
IsAdmin = table.Column<bool>(type: "boolean", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "boolean", nullable: false),
|
||||
Code = table.Column<string>(type: "text", nullable: false),
|
||||
Description = table.Column<string>(type: "text", nullable: false),
|
||||
DateCreated = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
EndDate = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
MaxParticipants = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Invitations", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "MediaFiles",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UploaderId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Url = table.Column<string>(type: "text", nullable: false),
|
||||
MediaType = table.Column<string>(type: "text", nullable: false),
|
||||
MineType = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: false),
|
||||
DateCreated = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
OwnerType = table.Column<int>(type: "integer", nullable: false),
|
||||
OwnerId = table.Column<Guid>(type: "uuid", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_MediaFiles", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PrivateChats",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserAId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserBId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_PrivateChats", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserPushTokens",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserSessionId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
Token = table.Column<string>(type: "character varying(512)", maxLength: 512, nullable: false),
|
||||
Provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
||||
Platform = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
LastUsedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
IsActive = table.Column<bool>(type: "boolean", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UserPushTokens", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GroupAdmins",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
GroupId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GroupAdmins", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_GroupAdmins_ChatGroups_GroupId",
|
||||
column: x => x.GroupId,
|
||||
principalTable: "ChatGroups",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Users",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Username = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
||||
Description = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
|
||||
PasswordHash = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: false),
|
||||
IconId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
CreatedOn = table.Column<DateOnly>(type: "date", nullable: false),
|
||||
WasOnline = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
InviteId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Users", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Users_Invitations_InviteId",
|
||||
column: x => x.InviteId,
|
||||
principalTable: "Invitations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Messages",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
SenderId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
RecipientId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
RecipientType = table.Column<int>(type: "integer", nullable: false),
|
||||
EncryptedContent = table.Column<string>(type: "text", nullable: false),
|
||||
SentAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
IsEdited = table.Column<bool>(type: "boolean", nullable: false),
|
||||
EditedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
ReplyToMessageId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
ChatGroupId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
PrivateChatId = table.Column<Guid>(type: "uuid", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Messages", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Messages_ChatGroups_ChatGroupId",
|
||||
column: x => x.ChatGroupId,
|
||||
principalTable: "ChatGroups",
|
||||
principalColumn: "Id");
|
||||
table.ForeignKey(
|
||||
name: "FK_Messages_PrivateChats_PrivateChatId",
|
||||
column: x => x.PrivateChatId,
|
||||
principalTable: "PrivateChats",
|
||||
principalColumn: "Id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Admins",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Admins", x => x.UserId);
|
||||
table.ForeignKey(
|
||||
name: "FK_Admins_Users_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Friendships",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
RequesterId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
AddresseeId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Status = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Friendships", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Friendships_Users_AddresseeId",
|
||||
column: x => x.AddresseeId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_Friendships_Users_RequesterId",
|
||||
column: x => x.RequesterId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GroupInvitations",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
GroupId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserMakerId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
InvitationCode = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||
Description = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: false),
|
||||
EndDate = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
MaxParticipants = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GroupInvitations", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_GroupInvitations_ChatGroups_GroupId",
|
||||
column: x => x.GroupId,
|
||||
principalTable: "ChatGroups",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_GroupInvitations_Users_UserMakerId",
|
||||
column: x => x.UserMakerId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserSessions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
RefreshTokenHash = table.Column<string>(type: "text", nullable: false),
|
||||
DeviceInfo = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
ExpiresAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
IsRevoked = table.Column<bool>(type: "boolean", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UserSessions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_UserSessions_Users_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "MediaAttachments",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MessageId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MediaFileId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_MediaAttachments", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_MediaAttachments_MediaFiles_MediaFileId",
|
||||
column: x => x.MediaFileId,
|
||||
principalTable: "MediaFiles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_MediaAttachments_Messages_MessageId",
|
||||
column: x => x.MessageId,
|
||||
principalTable: "Messages",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "MessageReactions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MessageId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ReactionCode = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
|
||||
ReactedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_MessageReactions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_MessageReactions_Messages_MessageId",
|
||||
column: x => x.MessageId,
|
||||
principalTable: "Messages",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_MessageReactions_Users_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "MessageViews",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MessageId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ViewedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_MessageViews", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_MessageViews_Messages_MessageId",
|
||||
column: x => x.MessageId,
|
||||
principalTable: "Messages",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GroupMemberships",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
GroupId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
InvitationId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
IsBanned = table.Column<bool>(type: "boolean", nullable: false),
|
||||
MemberSince = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
ChatGroupId = table.Column<Guid>(type: "uuid", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GroupMemberships", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_GroupMemberships_ChatGroups_ChatGroupId",
|
||||
column: x => x.ChatGroupId,
|
||||
principalTable: "ChatGroups",
|
||||
principalColumn: "Id");
|
||||
table.ForeignKey(
|
||||
name: "FK_GroupMemberships_ChatGroups_GroupId",
|
||||
column: x => x.GroupId,
|
||||
principalTable: "ChatGroups",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_GroupMemberships_GroupInvitations_InvitationId",
|
||||
column: x => x.InvitationId,
|
||||
principalTable: "GroupInvitations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.SetNull);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserCryptoSessions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserSessionId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
PublicIdentityKey = table.Column<byte[]>(type: "bytea", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UserCryptoSessions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_UserCryptoSessions_UserSessions_UserSessionId",
|
||||
column: x => x.UserSessionId,
|
||||
principalTable: "UserSessions",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "OneTimePreKeys",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserCryptoSessionId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
PublicKey = table.Column<byte[]>(type: "bytea", nullable: false),
|
||||
IsUsed = table.Column<bool>(type: "boolean", nullable: false, defaultValue: false),
|
||||
UploadedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_OneTimePreKeys", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_OneTimePreKeys_UserCryptoSessions_UserCryptoSessionId",
|
||||
column: x => x.UserCryptoSessionId,
|
||||
principalTable: "UserCryptoSessions",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SignedPreKeys",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserCryptoSessionId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
PublicSignedPreKey = table.Column<byte[]>(type: "bytea", nullable: false),
|
||||
SignedPreKeySignature = table.Column<byte[]>(type: "bytea", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SignedPreKeys", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_SignedPreKeys_UserCryptoSessions_UserCryptoSessionId",
|
||||
column: x => x.UserCryptoSessionId,
|
||||
principalTable: "UserCryptoSessions",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Friendships_AddresseeId",
|
||||
table: "Friendships",
|
||||
column: "AddresseeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Friendships_RequesterId",
|
||||
table: "Friendships",
|
||||
column: "RequesterId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GroupAdmins_GroupId",
|
||||
table: "GroupAdmins",
|
||||
column: "GroupId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GroupInvitations_GroupId",
|
||||
table: "GroupInvitations",
|
||||
column: "GroupId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GroupInvitations_UserMakerId",
|
||||
table: "GroupInvitations",
|
||||
column: "UserMakerId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GroupMemberships_ChatGroupId",
|
||||
table: "GroupMemberships",
|
||||
column: "ChatGroupId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GroupMemberships_GroupId",
|
||||
table: "GroupMemberships",
|
||||
column: "GroupId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GroupMemberships_InvitationId",
|
||||
table: "GroupMemberships",
|
||||
column: "InvitationId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MediaAttachments_MediaFileId",
|
||||
table: "MediaAttachments",
|
||||
column: "MediaFileId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MediaAttachments_MessageId",
|
||||
table: "MediaAttachments",
|
||||
column: "MessageId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MessageReactions_MessageId_UserId",
|
||||
table: "MessageReactions",
|
||||
columns: new[] { "MessageId", "UserId" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MessageReactions_UserId",
|
||||
table: "MessageReactions",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Messages_ChatGroupId",
|
||||
table: "Messages",
|
||||
column: "ChatGroupId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Messages_PrivateChatId",
|
||||
table: "Messages",
|
||||
column: "PrivateChatId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Messages_RecipientId",
|
||||
table: "Messages",
|
||||
column: "RecipientId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MessageViews_MessageId_UserId",
|
||||
table: "MessageViews",
|
||||
columns: new[] { "MessageId", "UserId" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_OneTimePreKeys_UploadedAt",
|
||||
table: "OneTimePreKeys",
|
||||
column: "UploadedAt");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_OneTimePreKeys_UserCryptoSessionId_IsUsed",
|
||||
table: "OneTimePreKeys",
|
||||
columns: new[] { "UserCryptoSessionId", "IsUsed" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SignedPreKeys_UserCryptoSessionId",
|
||||
table: "SignedPreKeys",
|
||||
column: "UserCryptoSessionId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserCryptoSessions_UserSessionId",
|
||||
table: "UserCryptoSessions",
|
||||
column: "UserSessionId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserPushTokens_Token",
|
||||
table: "UserPushTokens",
|
||||
column: "Token",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserPushTokens_UserId_IsActive",
|
||||
table: "UserPushTokens",
|
||||
columns: new[] { "UserId", "IsActive" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserPushTokens_UserSessionId",
|
||||
table: "UserPushTokens",
|
||||
column: "UserSessionId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Users_CreatedOn",
|
||||
table: "Users",
|
||||
column: "CreatedOn");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Users_InviteId",
|
||||
table: "Users",
|
||||
column: "InviteId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Users_Username",
|
||||
table: "Users",
|
||||
column: "Username",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Users_WasOnline",
|
||||
table: "Users",
|
||||
column: "WasOnline");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserSessions_RefreshTokenHash",
|
||||
table: "UserSessions",
|
||||
column: "RefreshTokenHash",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserSessions_UserId",
|
||||
table: "UserSessions",
|
||||
column: "UserId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Admins");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Friendships");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "GroupAdmins");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "GroupMemberships");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "MediaAttachments");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "MessageReactions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "MessageViews");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "OneTimePreKeys");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "SignedPreKeys");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserPushTokens");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "GroupInvitations");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "MediaFiles");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Messages");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserCryptoSessions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ChatGroups");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "PrivateChats");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserSessions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Users");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Invitations");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,845 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Govor.Domain;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Govor.Domain.Migrations
|
||||
{
|
||||
[DbContext(typeof(GovorDbContext))]
|
||||
partial class GovorDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.6")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.ChatGroup", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<Guid>("ImageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsChannel")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsPrivate")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ChatGroups");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Friendship", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("AddresseeId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("RequesterId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AddresseeId");
|
||||
|
||||
b.HasIndex("RequesterId");
|
||||
|
||||
b.ToTable("Friendships");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.GroupAdmins", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("GroupId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GroupId");
|
||||
|
||||
b.ToTable("GroupAdmins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.GroupInvitation", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<DateTime>("EndDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("GroupId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("InvitationCode")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<int>("MaxParticipants")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid>("UserMakerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GroupId");
|
||||
|
||||
b.HasIndex("UserMakerId");
|
||||
|
||||
b.ToTable("GroupInvitations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.GroupMembership", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("ChatGroupId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("GroupId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("InvitationId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsBanned")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTime>("MemberSince")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChatGroupId");
|
||||
|
||||
b.HasIndex("GroupId");
|
||||
|
||||
b.HasIndex("InvitationId");
|
||||
|
||||
b.ToTable("GroupMemberships");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Invitation", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("DateCreated")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("EndDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAdmin")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<int>("MaxParticipants")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Invitations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.MediaFile", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("DateCreated")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("MediaType")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("MineType")
|
||||
.IsRequired()
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("character varying(128)");
|
||||
|
||||
b.Property<Guid?>("OwnerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("OwnerType")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid>("UploaderId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("MediaFiles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.MediaAttachments", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("MediaFileId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("MessageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MediaFileId");
|
||||
|
||||
b.HasIndex("MessageId");
|
||||
|
||||
b.ToTable("MediaAttachments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.Message", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("ChatGroupId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime?>("EditedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("EncryptedContent")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsEdited")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<Guid?>("PrivateChatId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("RecipientId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("RecipientType")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid?>("ReplyToMessageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("SenderId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("SentAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChatGroupId");
|
||||
|
||||
b.HasIndex("PrivateChatId");
|
||||
|
||||
b.HasIndex("RecipientId");
|
||||
|
||||
b.ToTable("Messages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.MessageReaction", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("MessageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("ReactedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("ReactionCode")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.HasIndex("MessageId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("MessageReactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.MessageView", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("MessageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("ViewedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MessageId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("MessageViews");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.PrivateChat", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("UserAId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("UserBId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PrivateChats");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Admin", b =>
|
||||
{
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("UserId");
|
||||
|
||||
b.ToTable("Admins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Crypto.OneTimePreKey", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsUsed")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(false);
|
||||
|
||||
b.Property<byte[]>("PublicKey")
|
||||
.IsRequired()
|
||||
.HasColumnType("bytea");
|
||||
|
||||
b.Property<DateTime>("UploadedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("UserCryptoSessionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UploadedAt");
|
||||
|
||||
b.HasIndex("UserCryptoSessionId", "IsUsed");
|
||||
|
||||
b.ToTable("OneTimePreKeys");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Crypto.SignedPreKey", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<byte[]>("PublicSignedPreKey")
|
||||
.IsRequired()
|
||||
.HasColumnType("bytea");
|
||||
|
||||
b.Property<byte[]>("SignedPreKeySignature")
|
||||
.IsRequired()
|
||||
.HasColumnType("bytea");
|
||||
|
||||
b.Property<Guid>("UserCryptoSessionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserCryptoSessionId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("SignedPreKeys");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Crypto.UserCryptoSession", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<byte[]>("PublicIdentityKey")
|
||||
.IsRequired()
|
||||
.HasColumnType("bytea");
|
||||
|
||||
b.Property<Guid>("UserSessionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserSessionId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("UserCryptoSessions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.User", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateOnly>("CreatedOn")
|
||||
.HasColumnType("date");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<Guid>("IconId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("InviteId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.IsRequired()
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("character varying(128)");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<DateTime>("WasOnline")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedOn");
|
||||
|
||||
b.HasIndex("InviteId");
|
||||
|
||||
b.HasIndex("Username")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("WasOnline");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.UserPushToken", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTime?>("LastUsedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Platform")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("Provider")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("Token")
|
||||
.IsRequired()
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("character varying(512)");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("UserSessionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Token")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("UserSessionId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("UserId", "IsActive");
|
||||
|
||||
b.ToTable("UserPushTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.UserSession", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("DeviceInfo")
|
||||
.IsRequired()
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<DateTime>("ExpiresAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("IsRevoked")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("RefreshTokenHash")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RefreshTokenHash")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserSessions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Friendship", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Users.User", "Addressee")
|
||||
.WithMany("ReceivedFriendRequests")
|
||||
.HasForeignKey("AddresseeId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Govor.Domain.Models.Users.User", "Requester")
|
||||
.WithMany("SentFriendRequests")
|
||||
.HasForeignKey("RequesterId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Addressee");
|
||||
|
||||
b.Navigation("Requester");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.GroupAdmins", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.ChatGroup", null)
|
||||
.WithMany("Admins")
|
||||
.HasForeignKey("GroupId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.GroupInvitation", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.ChatGroup", null)
|
||||
.WithMany("InviteCodes")
|
||||
.HasForeignKey("GroupId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Govor.Domain.Models.Users.User", "UserMaker")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserMakerId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("UserMaker");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.GroupMembership", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.ChatGroup", null)
|
||||
.WithMany("Members")
|
||||
.HasForeignKey("ChatGroupId");
|
||||
|
||||
b.HasOne("Govor.Domain.Models.ChatGroup", "ChatGroup")
|
||||
.WithMany()
|
||||
.HasForeignKey("GroupId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Govor.Domain.Models.GroupInvitation", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("InvitationId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.Navigation("ChatGroup");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.MediaAttachments", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.MediaFile", "MediaFile")
|
||||
.WithMany()
|
||||
.HasForeignKey("MediaFileId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Govor.Domain.Models.Messages.Message", "Message")
|
||||
.WithMany("MediaAttachments")
|
||||
.HasForeignKey("MessageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("MediaFile");
|
||||
|
||||
b.Navigation("Message");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.Message", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.ChatGroup", null)
|
||||
.WithMany("Messages")
|
||||
.HasForeignKey("ChatGroupId");
|
||||
|
||||
b.HasOne("Govor.Domain.Models.PrivateChat", null)
|
||||
.WithMany("Messages")
|
||||
.HasForeignKey("PrivateChatId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.MessageReaction", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Messages.Message", "Message")
|
||||
.WithMany("Reactions")
|
||||
.HasForeignKey("MessageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Govor.Domain.Models.Users.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Message");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.MessageView", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Messages.Message", null)
|
||||
.WithMany("MessageViews")
|
||||
.HasForeignKey("MessageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Admin", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Users.User", "User")
|
||||
.WithOne()
|
||||
.HasForeignKey("Govor.Domain.Models.Users.Admin", "UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Crypto.OneTimePreKey", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Users.Crypto.UserCryptoSession", "UserCryptoSession")
|
||||
.WithMany("OneTimePreKeys")
|
||||
.HasForeignKey("UserCryptoSessionId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("UserCryptoSession");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Crypto.SignedPreKey", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Users.Crypto.UserCryptoSession", "UserCryptoSession")
|
||||
.WithOne("SignedPreKey")
|
||||
.HasForeignKey("Govor.Domain.Models.Users.Crypto.SignedPreKey", "UserCryptoSessionId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("UserCryptoSession");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Crypto.UserCryptoSession", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Users.UserSession", "UserSession")
|
||||
.WithOne("CryptoSession")
|
||||
.HasForeignKey("Govor.Domain.Models.Users.Crypto.UserCryptoSession", "UserSessionId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("UserSession");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.User", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Invitation", "Invite")
|
||||
.WithMany("Users")
|
||||
.HasForeignKey("InviteId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Invite");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.UserSession", b =>
|
||||
{
|
||||
b.HasOne("Govor.Domain.Models.Users.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.ChatGroup", b =>
|
||||
{
|
||||
b.Navigation("Admins");
|
||||
|
||||
b.Navigation("InviteCodes");
|
||||
|
||||
b.Navigation("Members");
|
||||
|
||||
b.Navigation("Messages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Invitation", b =>
|
||||
{
|
||||
b.Navigation("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Messages.Message", b =>
|
||||
{
|
||||
b.Navigation("MediaAttachments");
|
||||
|
||||
b.Navigation("MessageViews");
|
||||
|
||||
b.Navigation("Reactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.PrivateChat", b =>
|
||||
{
|
||||
b.Navigation("Messages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.Crypto.UserCryptoSession", b =>
|
||||
{
|
||||
b.Navigation("OneTimePreKeys");
|
||||
|
||||
b.Navigation("SignedPreKey")
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.User", b =>
|
||||
{
|
||||
b.Navigation("ReceivedFriendRequests");
|
||||
|
||||
b.Navigation("SentFriendRequests");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Domain.Models.Users.UserSession", b =>
|
||||
{
|
||||
b.Navigation("CryptoSession")
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Govor.Domain.Models.Messages;
|
||||
|
||||
namespace Govor.Domain.Models;
|
||||
|
||||
public class ChatGroup
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public Guid ImageId { get; set; }
|
||||
public bool IsChannel { get; set; }
|
||||
public bool IsPrivate { get; set; }
|
||||
public List<GroupAdmins> Admins { get; set; } = new();
|
||||
public List<GroupMembership> Members { get; set; } = new();
|
||||
public List<GroupInvitation> InviteCodes { get; set; } = new();
|
||||
public List<Message> Messages { get; set; } = new();
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
ChatGroup chatGroup = obj as ChatGroup;
|
||||
|
||||
return Id == chatGroup.Id &&
|
||||
Name == chatGroup.Name &&
|
||||
Description == chatGroup.Description &&
|
||||
ImageId == chatGroup.ImageId &&
|
||||
IsChannel == chatGroup.IsChannel &&
|
||||
IsPrivate == chatGroup.IsPrivate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Govor.Domain.Models.Users;
|
||||
|
||||
namespace Govor.Domain.Models;
|
||||
|
||||
public class Friendship
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid RequesterId { get; set; }
|
||||
public Guid AddresseeId { get; set; }
|
||||
public FriendshipStatus Status { get; set; }
|
||||
|
||||
public User Requester { get; set; }
|
||||
public User Addressee { get; set; }
|
||||
}
|
||||
|
||||
public enum FriendshipStatus
|
||||
{
|
||||
Pending,
|
||||
Accepted,
|
||||
Rejected,
|
||||
Blocked
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Govor.Domain.Models;
|
||||
|
||||
public class GroupAdmins
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid GroupId { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Govor.Domain.Models.Users;
|
||||
|
||||
namespace Govor.Domain.Models;
|
||||
|
||||
public class GroupInvitation
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid GroupId { get; set; }
|
||||
public Guid UserMakerId { get; set; }
|
||||
public string InvitationCode { get; set; }
|
||||
public string Description {get; set;}
|
||||
public DateTime EndDate { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public int MaxParticipants { get; set; }
|
||||
public List<Guid> GroupMemberships { get; set; } = new();
|
||||
public User? UserMaker { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Govor.Domain.Models;
|
||||
|
||||
public class GroupMembership
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid GroupId { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public Guid? InvitationId { get; set; }
|
||||
public bool IsBanned { get; set; }
|
||||
public DateTime MemberSince { get; set; }
|
||||
public ChatGroup ChatGroup { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using Govor.Domain.Models.Users;
|
||||
|
||||
namespace Govor.Domain.Models;
|
||||
|
||||
public class Invitation
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public bool IsAdmin { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public string Code { get; set; }
|
||||
public string Description { get; set; }
|
||||
public DateTime DateCreated { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
public int MaxParticipants { get; set; }
|
||||
public List<User> Users { get; set; } = new List<User>();
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
var invitation = obj as Invitation ?? throw new InvalidCastException();
|
||||
|
||||
return Id == invitation.Id &&
|
||||
IsAdmin == invitation.IsAdmin &&
|
||||
Description == invitation.Description &&
|
||||
DateCreated == invitation.DateCreated &&
|
||||
EndDate == invitation.EndDate &&
|
||||
MaxParticipants == invitation.MaxParticipants;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using Govor.Domain.Models.Messages;
|
||||
|
||||
namespace Govor.Domain.Models;
|
||||
|
||||
public class MediaFile
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid UploaderId { get; set; }
|
||||
public string Url { get; set; }
|
||||
public MediaType MediaType { get; set; }
|
||||
public string MineType { get; set; }
|
||||
public DateTime DateCreated { get; set; }
|
||||
|
||||
public MediaOwnerType OwnerType { get; set; } = MediaOwnerType.Message;
|
||||
public Guid? OwnerId { get; set; }
|
||||
}
|
||||
|
||||
public enum MediaOwnerType
|
||||
{
|
||||
Message = 0,
|
||||
Avatar = 1,
|
||||
GroupAvatar = 2,
|
||||
System = 3 // (Emoge, icons � e.t.c)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
namespace Govor.Domain.Models.Messages;
|
||||
|
||||
public class MediaAttachments
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid MessageId { get; set; }
|
||||
public Guid MediaFileId { get; set; }
|
||||
public Message Message { get; set; }
|
||||
public MediaFile MediaFile { get; set; }
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is not MediaAttachments other) return false;
|
||||
|
||||
return Id == other.Id &&
|
||||
MessageId == other.MessageId &&
|
||||
MediaFileId == other.MediaFileId;
|
||||
}
|
||||
}
|
||||
|
||||
public enum MediaType
|
||||
{
|
||||
Image,
|
||||
Video,
|
||||
Audio,
|
||||
File,
|
||||
Voice
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
namespace Govor.Domain.Models.Messages;
|
||||
|
||||
public class Message
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid SenderId { get; set; }
|
||||
public Guid RecipientId { get; set; } // or GroupId
|
||||
public RecipientType RecipientType { get; set; }
|
||||
public string EncryptedContent { get; set; } = string.Empty;
|
||||
public DateTime SentAt { get; set; }
|
||||
public bool IsEdited { get; set; } = false;
|
||||
public DateTime? EditedAt { get; set; }
|
||||
public List<MessageReaction> Reactions { get; set; } = new List<MessageReaction>();
|
||||
public List<MediaAttachments> MediaAttachments { get; set; } = new List<MediaAttachments>();
|
||||
public List<MessageView> MessageViews { get; set; } = new List<MessageView>();
|
||||
|
||||
public Guid? ReplyToMessageId { get; set; }
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is not Message other) return false;
|
||||
|
||||
return Id == other.Id &&
|
||||
SenderId == other.SenderId &&
|
||||
RecipientId == other.RecipientId &&
|
||||
RecipientType == other.RecipientType &&
|
||||
EncryptedContent == other.EncryptedContent &&
|
||||
SentAt == other.SentAt &&
|
||||
IsEdited == other.IsEdited &&
|
||||
EditedAt == other.EditedAt &&
|
||||
ReplyToMessageId == other.ReplyToMessageId;
|
||||
}
|
||||
}
|
||||
|
||||
public enum RecipientType
|
||||
{
|
||||
User,
|
||||
Group
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Govor.Domain.Models.Users;
|
||||
|
||||
namespace Govor.Domain.Models.Messages;
|
||||
|
||||
public class MessageReaction
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public Guid MessageId { get; set; }
|
||||
public Message Message { get; set; }
|
||||
|
||||
public Guid UserId { get; set; }
|
||||
public User User { get; set; }
|
||||
|
||||
public string ReactionCode { get; set; } // "❤️", "🔥", "👍", ":custom_emoji:"
|
||||
public DateTime ReactedAt { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Govor.Domain.Models.Messages;
|
||||
|
||||
public class MessageView
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid MessageId { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public DateTime ViewedAt { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Govor.Domain.Models.Messages;
|
||||
|
||||
namespace Govor.Domain.Models;
|
||||
|
||||
public class PrivateChat
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid UserAId { get; set; }
|
||||
public Guid UserBId { get; set; }
|
||||
public List<Message> Messages { get; set; } = new();
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
PrivateChat other = obj as PrivateChat;
|
||||
return Id == other.Id &&
|
||||
UserAId == other.UserAId &&
|
||||
UserBId == other.UserBId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Govor.Domain.Models.Users;
|
||||
|
||||
public class Admin
|
||||
{
|
||||
[Key]
|
||||
public Guid UserId { get; set; }
|
||||
public User User { get; set; } = null!;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Govor.Domain.Models.Users.Crypto;
|
||||
|
||||
public class OneTimePreKey
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid UserCryptoSessionId { get; set; }
|
||||
public UserCryptoSession UserCryptoSession { get; set; }
|
||||
|
||||
public byte[] PublicKey { get; set; }
|
||||
public bool IsUsed { get; set; }
|
||||
public DateTime UploadedAt { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Govor.Domain.Models.Users.Crypto;
|
||||
|
||||
public class SignedPreKey
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid UserCryptoSessionId { get; set; }
|
||||
public UserCryptoSession UserCryptoSession { get; set; }
|
||||
public byte[] PublicSignedPreKey { get; set; }
|
||||
public byte[] SignedPreKeySignature { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Govor.Domain.Models.Users.Crypto;
|
||||
|
||||
public class UserCryptoSession
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public Guid UserSessionId { get; set; }
|
||||
public UserSession UserSession { get; set; }
|
||||
|
||||
public byte[] PublicIdentityKey { get; set; }
|
||||
|
||||
public SignedPreKey SignedPreKey { get; set; }
|
||||
public ICollection<OneTimePreKey> OneTimePreKeys { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace Govor.Domain.Models.Users;
|
||||
|
||||
public class PrivacyRuleEntity
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid OwnerId { get; set; }
|
||||
|
||||
public PrivacyTargetArea Area { get; set; }
|
||||
public WhoCan AccessType { get; set; } // Everyone, Friends, None
|
||||
|
||||
public List<Guid> Whitelist { get; set; } = new();
|
||||
public List<Guid> Blacklist { get; set; } = new();
|
||||
|
||||
public PrivacyUserSettings OwnerSettings { get; set; } = null!;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
namespace Govor.Domain.Models.Users;
|
||||
|
||||
public class PrivacyUserSettings
|
||||
{
|
||||
public Guid UserId { get; set; }
|
||||
|
||||
public bool IsGlobalAccount { get; set; }
|
||||
|
||||
public DeletingMessagesVia DeletingVia { get; set; }
|
||||
public int DeletingIn { get; set; }
|
||||
|
||||
public bool IsInvisibleMode { get; set; }
|
||||
|
||||
public List<PrivacyRuleEntity> Rules { get; set; } = new();
|
||||
}
|
||||
|
||||
public enum WhoCan
|
||||
{
|
||||
None = 0,
|
||||
OnlyFriends = 1,
|
||||
Everyone = 2,
|
||||
}
|
||||
|
||||
public enum DeletingMessagesVia
|
||||
{
|
||||
None = 0,
|
||||
Hours = 1,
|
||||
Days = 2,
|
||||
Months = 3,
|
||||
Years = 4
|
||||
}
|
||||
|
||||
public enum PrivacyTargetArea
|
||||
{
|
||||
CanSend = 0,
|
||||
CanSeeTimeWas = 1,
|
||||
CanSeeImage = 2,
|
||||
CanSendImage = 3,
|
||||
}
|
||||
|
||||
public enum PrivacyRuleType
|
||||
{
|
||||
Allow = 0,
|
||||
Deny = 1
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Govor.Domain.Models.Users;
|
||||
|
||||
public class User
|
||||
{
|
||||
public Guid Id {get; set;}
|
||||
public string Username {get; set;}
|
||||
public string Description {get; set;}
|
||||
public string PasswordHash {get; set;}
|
||||
public Guid IconId {get; set;}
|
||||
public DateOnly CreatedOn {get; set;}
|
||||
public DateTime WasOnline {get; set;}
|
||||
public Guid InviteId {get; set;}
|
||||
public Invitation? Invite { get; set; }
|
||||
public List<Friendship> SentFriendRequests { get; set; } = new();
|
||||
public List<Friendship> ReceivedFriendRequests { get; set; } = new();
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
var user = obj as User;
|
||||
|
||||
return Id == user.Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Govor.Domain.Models.Users;
|
||||
public class UserPushToken
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
public Guid UserId { get; set; }
|
||||
public Guid? UserSessionId { get; set; }
|
||||
|
||||
public string Token { get; set; } = string.Empty; // FCM/APNs
|
||||
public string Provider { get; set; } = "FCM"; // FCM | APNs | Web | Huawei
|
||||
public string Platform { get; set; } = string.Empty; // android | ios | web
|
||||
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime? LastUsedAt { get; set; }
|
||||
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using Govor.Domain.Models.Users.Crypto;
|
||||
|
||||
namespace Govor.Domain.Models.Users;
|
||||
|
||||
public class UserSession
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public Guid UserId { get; set; }
|
||||
public string RefreshTokenHash { get; set; } = string.Empty;
|
||||
public string DeviceInfo { get; set; } = string.Empty;
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime ExpiresAt { get; set; }
|
||||
public bool IsRevoked { get; set; } = false;
|
||||
|
||||
public User User { get; set; } = null!;
|
||||
public UserCryptoSession CryptoSession { get; set; } = null!;
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is not UserSession userSession)
|
||||
return false;
|
||||
|
||||
return Id == userSession.Id &&
|
||||
UserId == userSession.UserId &&
|
||||
RefreshTokenHash == userSession.RefreshTokenHash &&
|
||||
DeviceInfo == userSession.DeviceInfo &&
|
||||
CreatedAt == userSession.CreatedAt &&
|
||||
ExpiresAt == userSession.ExpiresAt &&
|
||||
IsRevoked == userSession.IsRevoked;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(Id, UserId, RefreshTokenHash, DeviceInfo, CreatedAt, ExpiresAt, IsRevoked);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user