♻️ Move most of models to the Shared package

This commit is contained in:
2025-07-06 22:34:52 +08:00
parent cb4acbb3fc
commit 65450e8511
170 changed files with 679 additions and 101121 deletions

View File

@ -1,5 +1,6 @@
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using DysonNetwork.Shared.Models;
using DysonNetwork.Sphere.Permission;
using DysonNetwork.Sphere.Storage;
using Microsoft.AspNetCore.Authorization;
@ -32,7 +33,7 @@ public partial class ChatController(AppDatabase db, ChatService cs, ChatRoomServ
[Authorize]
public async Task<ActionResult<Dictionary<Guid, ChatSummaryResponse>>> GetChatSummary()
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var unreadMessages = await cs.CountUnreadMessageForUser(currentUser.Id);
var lastMessages = await cs.ListLastMessageForUser(currentUser.Id);
@ -65,7 +66,7 @@ public partial class ChatController(AppDatabase db, ChatService cs, ChatRoomServ
public async Task<ActionResult<List<Message>>> ListMessages(Guid roomId, [FromQuery] int offset,
[FromQuery] int take = 20)
{
var currentUser = HttpContext.Items["CurrentUser"] as Account.Account;
var currentUser = HttpContext.Items["CurrentUser"] as Shared.Models.Account;
var room = await db.ChatRooms.FirstOrDefaultAsync(r => r.Id == roomId);
if (room is null) return NotFound();
@ -102,7 +103,7 @@ public partial class ChatController(AppDatabase db, ChatService cs, ChatRoomServ
[HttpGet("{roomId:guid}/messages/{messageId:guid}")]
public async Task<ActionResult<Message>> GetMessage(Guid roomId, Guid messageId)
{
var currentUser = HttpContext.Items["CurrentUser"] as Account.Account;
var currentUser = HttpContext.Items["CurrentUser"] as Shared.Models.Account;
var room = await db.ChatRooms.FirstOrDefaultAsync(r => r.Id == roomId);
if (room is null) return NotFound();
@ -139,7 +140,7 @@ public partial class ChatController(AppDatabase db, ChatService cs, ChatRoomServ
[RequiredPermission("global", "chat.messages.create")]
public async Task<ActionResult> SendMessage([FromBody] SendMessageRequest request, Guid roomId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
request.Content = TextSanitizer.Sanitize(request.Content);
if (string.IsNullOrWhiteSpace(request.Content) &&
@ -216,7 +217,7 @@ public partial class ChatController(AppDatabase db, ChatService cs, ChatRoomServ
[Authorize]
public async Task<ActionResult> UpdateMessage([FromBody] SendMessageRequest request, Guid roomId, Guid messageId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
request.Content = TextSanitizer.Sanitize(request.Content);
@ -269,7 +270,7 @@ public partial class ChatController(AppDatabase db, ChatService cs, ChatRoomServ
[Authorize]
public async Task<ActionResult> DeleteMessage(Guid roomId, Guid messageId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var message = await db.ChatMessages
.Include(m => m.Sender)
@ -295,7 +296,7 @@ public partial class ChatController(AppDatabase db, ChatService cs, ChatRoomServ
[HttpPost("{roomId:guid}/sync")]
public async Task<ActionResult<SyncResponse>> GetSyncData([FromBody] SyncRequest request, Guid roomId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser)
return Unauthorized();
var isMember = await db.ChatMembers

View File

@ -1,144 +0,0 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
using DysonNetwork.Sphere.Storage;
using NodaTime;
namespace DysonNetwork.Sphere.Chat;
public enum ChatRoomType
{
Group,
DirectMessage
}
public class ChatRoom : ModelBase, IIdentifiedResource
{
public Guid Id { get; set; }
[MaxLength(1024)] public string? Name { get; set; }
[MaxLength(4096)] public string? Description { get; set; }
public ChatRoomType Type { get; set; }
public bool IsCommunity { get; set; }
public bool IsPublic { get; set; }
// Outdated fields, for backward compability
[MaxLength(32)] public string? PictureId { get; set; }
[MaxLength(32)] public string? BackgroundId { get; set; }
[Column(TypeName = "jsonb")] public CloudFileReferenceObject? Picture { get; set; }
[Column(TypeName = "jsonb")] public CloudFileReferenceObject? Background { get; set; }
[JsonIgnore] public ICollection<ChatMember> Members { get; set; } = new List<ChatMember>();
public Guid? RealmId { get; set; }
public Realm.Realm? Realm { get; set; }
[NotMapped]
[JsonPropertyName("members")]
public ICollection<ChatMemberTransmissionObject> DirectMembers { get; set; } =
new List<ChatMemberTransmissionObject>();
public string ResourceIdentifier => $"chatroom/{Id}";
}
public abstract class ChatMemberRole
{
public const int Owner = 100;
public const int Moderator = 50;
public const int Member = 0;
}
public enum ChatMemberNotify
{
All,
Mentions,
None
}
public enum ChatTimeoutCauseType
{
ByModerator = 0,
BySlowMode = 1,
}
public class ChatTimeoutCause
{
public ChatTimeoutCauseType Type { get; set; }
public Guid? SenderId { get; set; }
}
public class ChatMember : ModelBase
{
public Guid Id { get; set; }
public Guid ChatRoomId { get; set; }
public ChatRoom ChatRoom { get; set; } = null!;
public Guid AccountId { get; set; }
public Account.Account Account { get; set; } = null!;
[MaxLength(1024)] public string? Nick { get; set; }
public int Role { get; set; } = ChatMemberRole.Member;
public ChatMemberNotify Notify { get; set; } = ChatMemberNotify.All;
public Instant? LastReadAt { get; set; }
public Instant? JoinedAt { get; set; }
public Instant? LeaveAt { get; set; }
public bool IsBot { get; set; } = false;
/// <summary>
/// The break time is the user doesn't receive any message from this member for a while.
/// Expect mentioned him or her.
/// </summary>
public Instant? BreakUntil { get; set; }
/// <summary>
/// The timeout is the user can't send any message.
/// Set by the moderator of the chat room.
/// </summary>
public Instant? TimeoutUntil { get; set; }
/// <summary>
/// The timeout cause is the reason why the user is timeout.
/// </summary>
[Column(TypeName = "jsonb")] public ChatTimeoutCause? TimeoutCause { get; set; }
}
public class ChatMemberTransmissionObject : ModelBase
{
public Guid Id { get; set; }
public Guid ChatRoomId { get; set; }
public Guid AccountId { get; set; }
public Account.Account Account { get; set; } = null!;
[MaxLength(1024)] public string? Nick { get; set; }
public int Role { get; set; } = ChatMemberRole.Member;
public ChatMemberNotify Notify { get; set; } = ChatMemberNotify.All;
public Instant? JoinedAt { get; set; }
public Instant? LeaveAt { get; set; }
public bool IsBot { get; set; } = false;
public Instant? BreakUntil { get; set; }
public Instant? TimeoutUntil { get; set; }
public ChatTimeoutCause? TimeoutCause { get; set; }
public static ChatMemberTransmissionObject FromEntity(ChatMember member)
{
return new ChatMemberTransmissionObject
{
Id = member.Id,
ChatRoomId = member.ChatRoomId,
AccountId = member.AccountId,
Account = member.Account,
Nick = member.Nick,
Role = member.Role,
Notify = member.Notify,
JoinedAt = member.JoinedAt,
LeaveAt = member.LeaveAt,
IsBot = member.IsBot,
BreakUntil = member.BreakUntil,
TimeoutUntil = member.TimeoutUntil,
TimeoutCause = member.TimeoutCause,
CreatedAt = member.CreatedAt,
UpdatedAt = member.UpdatedAt,
DeletedAt = member.DeletedAt
};
}
}

View File

@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using DysonNetwork.Shared.Models;
using DysonNetwork.Sphere.Account;
using DysonNetwork.Sphere.Localization;
using DysonNetwork.Sphere.Permission;
@ -36,7 +37,7 @@ public class ChatRoomController(
if (chatRoom is null) return NotFound();
if (chatRoom.Type != ChatRoomType.DirectMessage) return Ok(chatRoom);
if (HttpContext.Items["CurrentUser"] is Account.Account currentUser)
if (HttpContext.Items["CurrentUser"] is Shared.Models.Account currentUser)
chatRoom = await crs.LoadDirectMessageMembers(chatRoom, currentUser.Id);
return Ok(chatRoom);
@ -46,7 +47,7 @@ public class ChatRoomController(
[Authorize]
public async Task<ActionResult<List<ChatRoom>>> ListJoinedChatRooms()
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser)
return Unauthorized();
var userId = currentUser.Id;
@ -72,7 +73,7 @@ public class ChatRoomController(
[Authorize]
public async Task<ActionResult<ChatRoom>> CreateDirectMessage([FromBody] DirectMessageRequest request)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser)
return Unauthorized();
var relatedUser = await db.Accounts.FindAsync(request.RelatedUserId);
@ -134,7 +135,7 @@ public class ChatRoomController(
[Authorize]
public async Task<ActionResult<ChatRoom>> GetDirectChatRoom(Guid userId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser)
return Unauthorized();
var room = await db.ChatRooms
@ -164,7 +165,7 @@ public class ChatRoomController(
[RequiredPermission("global", "chat.create")]
public async Task<ActionResult<ChatRoom>> CreateChatRoom(ChatRoomRequest request)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
if (request.Name is null) return BadRequest("You cannot create a chat room without a name.");
var chatRoom = new ChatRoom
@ -236,7 +237,7 @@ public class ChatRoomController(
[HttpPatch("{id:guid}")]
public async Task<ActionResult<ChatRoom>> UpdateChatRoom(Guid id, [FromBody] ChatRoomRequest request)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var chatRoom = await db.ChatRooms
.Where(e => e.Id == id)
@ -321,7 +322,7 @@ public class ChatRoomController(
[HttpDelete("{id:guid}")]
public async Task<ActionResult> DeleteChatRoom(Guid id)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var chatRoom = await db.ChatRooms
.Where(e => e.Id == id)
@ -356,7 +357,7 @@ public class ChatRoomController(
[Authorize]
public async Task<ActionResult<ChatMember>> GetRoomIdentity(Guid roomId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser)
return Unauthorized();
var member = await db.ChatMembers
@ -375,7 +376,7 @@ public class ChatRoomController(
public async Task<ActionResult<List<ChatMember>>> ListMembers(Guid roomId, [FromQuery] int take = 20,
[FromQuery] int skip = 0, [FromQuery] bool withStatus = false, [FromQuery] string? status = null)
{
var currentUser = HttpContext.Items["CurrentUser"] as Account.Account;
var currentUser = HttpContext.Items["CurrentUser"] as Shared.Models.Account;
var room = await db.ChatRooms
.FirstOrDefaultAsync(r => r.Id == roomId);
@ -448,7 +449,7 @@ public class ChatRoomController(
public async Task<ActionResult<ChatMember>> InviteMember(Guid roomId,
[FromBody] ChatMemberRequest request)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var userId = currentUser.Id;
var relatedUser = await db.Accounts.FindAsync(request.RelatedUserId);
@ -519,7 +520,7 @@ public class ChatRoomController(
[Authorize]
public async Task<ActionResult<List<ChatMember>>> ListChatInvites()
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var userId = currentUser.Id;
var members = await db.ChatMembers
@ -544,7 +545,7 @@ public class ChatRoomController(
[Authorize]
public async Task<ActionResult<ChatRoom>> AcceptChatInvite(Guid roomId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var userId = currentUser.Id;
var member = await db.ChatMembers
@ -571,7 +572,7 @@ public class ChatRoomController(
[Authorize]
public async Task<ActionResult> DeclineChatInvite(Guid roomId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var userId = currentUser.Id;
var member = await db.ChatMembers
@ -600,7 +601,7 @@ public class ChatRoomController(
[FromBody] ChatMemberNotifyRequest request
)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var chatRoom = await db.ChatRooms
.Where(r => r.Id == roomId)
@ -629,7 +630,7 @@ public class ChatRoomController(
public async Task<ActionResult<ChatMember>> UpdateChatMemberRole(Guid roomId, Guid memberId, [FromBody] int newRole)
{
if (newRole >= ChatMemberRole.Owner) return BadRequest("Unable to set chat member to owner or greater role.");
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var chatRoom = await db.ChatRooms
.Where(r => r.Id == roomId)
@ -688,7 +689,7 @@ public class ChatRoomController(
[Authorize]
public async Task<ActionResult> RemoveChatMember(Guid roomId, Guid memberId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var chatRoom = await db.ChatRooms
.Where(r => r.Id == roomId)
@ -736,7 +737,7 @@ public class ChatRoomController(
[Authorize]
public async Task<ActionResult<ChatRoom>> JoinChatRoom(Guid roomId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var chatRoom = await db.ChatRooms
.Where(r => r.Id == roomId)
@ -774,7 +775,7 @@ public class ChatRoomController(
[Authorize]
public async Task<ActionResult> LeaveChat(Guid roomId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var member = await db.ChatMembers
.Where(m => m.AccountId == currentUser.Id)
@ -807,7 +808,7 @@ public class ChatRoomController(
return NoContent();
}
private async Task _SendInviteNotify(ChatMember member, Account.Account sender)
private async Task _SendInviteNotify(ChatMember member, Shared.Models.Account sender)
{
string title = localizer["ChatInviteTitle"];

View File

@ -1,3 +1,4 @@
using DysonNetwork.Shared.Models;
using DysonNetwork.Sphere.Storage;
using Microsoft.EntityFrameworkCore;
using NodaTime;

View File

@ -1,4 +1,5 @@
using System.Text.RegularExpressions;
using DysonNetwork.Shared.Models;
using DysonNetwork.Sphere.Account;
using DysonNetwork.Sphere.Chat.Realtime;
using DysonNetwork.Sphere.Connection;
@ -241,7 +242,7 @@ public partial class ChatService(
Priority = 10,
};
List<Account.Account> accountsToNotify = [];
List<Shared.Models.Account> accountsToNotify = [];
foreach (var member in members)
{
scopedWs.SendPacketToAccount(member.AccountId, new WebSocketPacket

View File

@ -1,67 +0,0 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
using DysonNetwork.Sphere.Storage;
using Microsoft.EntityFrameworkCore;
using NodaTime;
namespace DysonNetwork.Sphere.Chat;
public class Message : ModelBase, IIdentifiedResource
{
public Guid Id { get; set; } = Guid.NewGuid();
[MaxLength(1024)] public string Type { get; set; } = null!;
[MaxLength(4096)] public string? Content { get; set; }
[Column(TypeName = "jsonb")] public Dictionary<string, object>? Meta { get; set; }
[Column(TypeName = "jsonb")] public List<Guid>? MembersMentioned { get; set; }
[MaxLength(36)] public string Nonce { get; set; } = null!;
public Instant? EditedAt { get; set; }
[Column(TypeName = "jsonb")] public List<CloudFileReferenceObject> Attachments { get; set; } = [];
// Outdated fields, keep for backward compability
public ICollection<CloudFile> OutdatedAttachments { get; set; } = new List<CloudFile>();
public ICollection<MessageReaction> Reactions { get; set; } = new List<MessageReaction>();
public Guid? RepliedMessageId { get; set; }
public Message? RepliedMessage { get; set; }
public Guid? ForwardedMessageId { get; set; }
public Message? ForwardedMessage { get; set; }
public Guid SenderId { get; set; }
public ChatMember Sender { get; set; } = null!;
public Guid ChatRoomId { get; set; }
[JsonIgnore] public ChatRoom ChatRoom { get; set; } = null!;
public string ResourceIdentifier => $"message/{Id}";
}
public enum MessageReactionAttitude
{
Positive,
Neutral,
Negative,
}
public class MessageReaction : ModelBase
{
public Guid Id { get; set; } = Guid.NewGuid();
public Guid MessageId { get; set; }
[JsonIgnore] public Message Message { get; set; } = null!;
public Guid SenderId { get; set; }
public ChatMember Sender { get; set; } = null!;
[MaxLength(256)] public string Symbol { get; set; } = null!;
public MessageReactionAttitude Attitude { get; set; }
}
/// <summary>
/// The data model for updating the last read at field for chat member,
/// after the refactor of the unread system, this no longer stored in the database.
/// Not only used for the data transmission object
/// </summary>
[NotMapped]
public class MessageReadReceipt
{
public Guid SenderId { get; set; }
}

View File

@ -36,7 +36,7 @@ public interface IRealtimeService
/// <param name="sessionId">The session identifier</param>
/// <param name="isAdmin">The user is the admin of session</param>
/// <returns>User-specific token for the session</returns>
string GetUserToken(Account.Account account, string sessionId, bool isAdmin = false);
string GetUserToken(Shared.Models.Account account, string sessionId, bool isAdmin = false);
/// <summary>
/// Processes incoming webhook requests from the realtime service provider

View File

@ -4,6 +4,7 @@ using Livekit.Server.Sdk.Dotnet;
using Microsoft.EntityFrameworkCore;
using NodaTime;
using System.Text.Json;
using DysonNetwork.Shared.Models;
namespace DysonNetwork.Sphere.Chat.Realtime;
@ -111,7 +112,7 @@ public class LivekitRealtimeService : IRealtimeService
}
/// <inheritdoc />
public string GetUserToken(Account.Account account, string sessionId, bool isAdmin = false)
public string GetUserToken(Shared.Models.Account account, string sessionId, bool isAdmin = false)
{
var token = _accessToken.WithIdentity(account.Name)
.WithName(account.Nick)

View File

@ -1,50 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;
using System.Text.Json.Serialization;
using DysonNetwork.Sphere.Chat.Realtime;
using NodaTime;
namespace DysonNetwork.Sphere.Chat;
public class RealtimeCall : ModelBase
{
public Guid Id { get; set; } = Guid.NewGuid();
public Instant? EndedAt { get; set; }
public Guid SenderId { get; set; }
public ChatMember Sender { get; set; } = null!;
public Guid RoomId { get; set; }
public ChatRoom Room { get; set; } = null!;
/// <summary>
/// Provider name (e.g., "cloudflare", "agora", "twilio")
/// </summary>
public string? ProviderName { get; set; }
/// <summary>
/// Service provider's session identifier
/// </summary>
public string? SessionId { get; set; }
/// <summary>
/// JSONB column containing provider-specific configuration
/// </summary>
[Column(name: "upstream", TypeName = "jsonb")]
public string? UpstreamConfigJson { get; set; }
/// <summary>
/// Deserialized upstream configuration
/// </summary>
[NotMapped]
public Dictionary<string, object> UpstreamConfig
{
get => string.IsNullOrEmpty(UpstreamConfigJson)
? new Dictionary<string, object>()
: JsonSerializer.Deserialize<Dictionary<string, object>>(UpstreamConfigJson) ?? new Dictionary<string, object>();
set => UpstreamConfigJson = value.Count > 0
? JsonSerializer.Serialize(value)
: null;
}
}

View File

@ -1,3 +1,4 @@
using DysonNetwork.Shared.Models;
using DysonNetwork.Sphere.Chat.Realtime;
using Livekit.Server.Sdk.Dotnet;
using Microsoft.AspNetCore.Authorization;
@ -46,7 +47,7 @@ public class RealtimeCallController(
[Authorize]
public async Task<ActionResult<RealtimeCall>> GetOngoingCall(Guid roomId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var member = await db.ChatMembers
.Where(m => m.AccountId == currentUser.Id && m.ChatRoomId == roomId)
@ -71,7 +72,7 @@ public class RealtimeCallController(
[Authorize]
public async Task<ActionResult<JoinCallResponse>> JoinCall(Guid roomId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
// Check if the user is a member of the chat room
var member = await db.ChatMembers
@ -144,7 +145,7 @@ public class RealtimeCallController(
[Authorize]
public async Task<ActionResult<RealtimeCall>> StartCall(Guid roomId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var member = await db.ChatMembers
.Where(m => m.AccountId == currentUser.Id && m.ChatRoomId == roomId)
@ -163,7 +164,7 @@ public class RealtimeCallController(
[Authorize]
public async Task<ActionResult<RealtimeCall>> EndCall(Guid roomId)
{
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser) return Unauthorized();
var member = await db.ChatMembers
.Where(m => m.AccountId == currentUser.Id && m.ChatRoomId == roomId)