namespace DorkNet.Server.Data.Entities; /// /// Join row marking that is on the invite list /// for . Created when the owner sends an /// invite via POST /invite (handled in MessagesController); /// checked on POST /goto/instance/{id} by /// PrivateInstanceService.CanJoin. /// /// Composite PK on (PrivateInstanceId, PlayerId) — naturally unique; /// repeat-invite calls become idempotent no-ops. /// public class PrivateInstanceInviteeEntity { public long PrivateInstanceId { get; set; } public long PlayerId { get; set; } public DateTime InvitedAt { get; set; } = DateTime.UtcNow; /// The MessageEntity.Id of the latest invite for this /// (instance, player). Lets GoToInvite resolve the /// roomInstanceId even when the watch's accept flow has already /// raced through POST /api/messages/v3/delete and removed /// the underlying message row. Without this column the server /// returned ErrorCode 40 ("invite expired") for any successful /// accept where DELETE landed first — which was the common case /// because the 2020 watch fires DELETE and POST /goto/invite/{id} /// in parallel. public long? LatestInviteMessageId { get; set; } }