🧱 Relationship query supports isRelated
This commit is contained in:
@@ -53,7 +53,8 @@ public class AccountServiceGrpc(
|
||||
.FirstOrDefaultAsync(a => a.AutomatedId == automatedId);
|
||||
|
||||
if (account == null)
|
||||
throw new RpcException(new Grpc.Core.Status(StatusCode.NotFound, $"Account with automated ID {request.AutomatedId} not found"));
|
||||
throw new RpcException(new Grpc.Core.Status(StatusCode.NotFound,
|
||||
$"Account with automated ID {request.AutomatedId} not found"));
|
||||
|
||||
var perk = await subscriptions.GetPerkSubscriptionAsync(account.Id);
|
||||
account.PerkSubscription = perk?.ToReference();
|
||||
@@ -159,7 +160,8 @@ public class AccountServiceGrpc(
|
||||
return response;
|
||||
}
|
||||
|
||||
public override async Task<GetAccountBatchResponse> SearchAccount(SearchAccountRequest request, ServerCallContext context)
|
||||
public override async Task<GetAccountBatchResponse> SearchAccount(SearchAccountRequest request,
|
||||
ServerCallContext context)
|
||||
{
|
||||
var accounts = await _db.Accounts
|
||||
.AsNoTracking()
|
||||
@@ -232,21 +234,48 @@ public class AccountServiceGrpc(
|
||||
public override async Task<ListRelationshipSimpleResponse> ListFriends(
|
||||
ListRelationshipSimpleRequest request, ServerCallContext context)
|
||||
{
|
||||
var resp = new ListRelationshipSimpleResponse();
|
||||
switch (request.RelationIdentifierCase)
|
||||
{
|
||||
case ListRelationshipSimpleRequest.RelationIdentifierOneofCase.AccountId:
|
||||
var accountId = Guid.Parse(request.AccountId);
|
||||
var relationship = await relationships.ListAccountFriends(accountId);
|
||||
var resp = new ListRelationshipSimpleResponse();
|
||||
resp.AccountsId.AddRange(relationship.Select(x => x.ToString()));
|
||||
return resp;
|
||||
case ListRelationshipSimpleRequest.RelationIdentifierOneofCase.RelatedId:
|
||||
var relatedId = Guid.Parse(request.RelatedId);
|
||||
var relatedRelationship = await relationships.ListAccountFriends(relatedId, true);
|
||||
resp.AccountsId.AddRange(relatedRelationship.Select(x => x.ToString()));
|
||||
return resp;
|
||||
break;
|
||||
case ListRelationshipSimpleRequest.RelationIdentifierOneofCase.None:
|
||||
default:
|
||||
throw new RpcException(new Status(StatusCode.InvalidArgument,
|
||||
$"The relationship identifier must be provided."));
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<ListRelationshipSimpleResponse> ListBlocked(
|
||||
ListRelationshipSimpleRequest request, ServerCallContext context)
|
||||
{
|
||||
var resp = new ListRelationshipSimpleResponse();
|
||||
switch (request.RelationIdentifierCase)
|
||||
{
|
||||
case ListRelationshipSimpleRequest.RelationIdentifierOneofCase.AccountId:
|
||||
var accountId = Guid.Parse(request.AccountId);
|
||||
var relationship = await relationships.ListAccountBlocked(accountId);
|
||||
var resp = new ListRelationshipSimpleResponse();
|
||||
resp.AccountsId.AddRange(relationship.Select(x => x.ToString()));
|
||||
return resp;
|
||||
case ListRelationshipSimpleRequest.RelationIdentifierOneofCase.RelatedId:
|
||||
var relatedId = Guid.Parse(request.RelatedId);
|
||||
var relatedRelationship = await relationships.ListAccountBlocked(relatedId, true);
|
||||
resp.AccountsId.AddRange(relatedRelationship.Select(x => x.ToString()));
|
||||
return resp;
|
||||
case ListRelationshipSimpleRequest.RelationIdentifierOneofCase.None:
|
||||
default:
|
||||
throw new RpcException(new Status(StatusCode.InvalidArgument,
|
||||
$"The relationship identifier must be provided."));
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<GetRelationshipResponse> GetRelationship(GetRelationshipRequest request,
|
||||
|
||||
@@ -52,7 +52,8 @@ public class RelationshipService(
|
||||
return relationship;
|
||||
}
|
||||
|
||||
public async Task<SnAccountRelationship> CreateRelationship(SnAccount sender, SnAccount target, RelationshipStatus status)
|
||||
public async Task<SnAccountRelationship> CreateRelationship(SnAccount sender, SnAccount target,
|
||||
RelationshipStatus status)
|
||||
{
|
||||
if (status == RelationshipStatus.Pending)
|
||||
throw new InvalidOperationException(
|
||||
@@ -169,12 +170,14 @@ public class RelationshipService(
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
await PurgeRelationshipCache(relationship.AccountId, relationship.RelatedId, RelationshipStatus.Friends, status);
|
||||
await PurgeRelationshipCache(relationship.AccountId, relationship.RelatedId, RelationshipStatus.Friends,
|
||||
status);
|
||||
|
||||
return relationshipBackward;
|
||||
}
|
||||
|
||||
public async Task<SnAccountRelationship> UpdateRelationship(Guid accountId, Guid relatedId, RelationshipStatus status)
|
||||
public async Task<SnAccountRelationship> UpdateRelationship(Guid accountId, Guid relatedId,
|
||||
RelationshipStatus status)
|
||||
{
|
||||
var relationship = await GetRelationship(accountId, relatedId);
|
||||
if (relationship is null) throw new ArgumentException("There is no relationship between you and the user.");
|
||||
@@ -189,24 +192,26 @@ public class RelationshipService(
|
||||
return relationship;
|
||||
}
|
||||
|
||||
public async Task<List<Guid>> ListAccountFriends(SnAccount account)
|
||||
public async Task<List<Guid>> ListAccountFriends(SnAccount account, bool isRelated = false)
|
||||
{
|
||||
return await ListAccountFriends(account.Id);
|
||||
return await ListAccountFriends(account.Id, isRelated);
|
||||
}
|
||||
|
||||
public async Task<List<Guid>> ListAccountFriends(Guid accountId)
|
||||
public async Task<List<Guid>> ListAccountFriends(Guid accountId, bool isRelated = false)
|
||||
{
|
||||
return await GetCachedRelationships(accountId, RelationshipStatus.Friends, UserFriendsCacheKeyPrefix);
|
||||
return await GetCachedRelationships(accountId, RelationshipStatus.Friends, UserFriendsCacheKeyPrefix,
|
||||
isRelated);
|
||||
}
|
||||
|
||||
public async Task<List<Guid>> ListAccountBlocked(SnAccount account)
|
||||
public async Task<List<Guid>> ListAccountBlocked(SnAccount account, bool isRelated = false)
|
||||
{
|
||||
return await ListAccountBlocked(account.Id);
|
||||
return await ListAccountBlocked(account.Id, isRelated);
|
||||
}
|
||||
|
||||
public async Task<List<Guid>> ListAccountBlocked(Guid accountId)
|
||||
public async Task<List<Guid>> ListAccountBlocked(Guid accountId, bool isRelated = false)
|
||||
{
|
||||
return await GetCachedRelationships(accountId, RelationshipStatus.Blocked, UserBlockedCacheKeyPrefix);
|
||||
return await GetCachedRelationships(accountId, RelationshipStatus.Blocked, UserBlockedCacheKeyPrefix,
|
||||
isRelated);
|
||||
}
|
||||
|
||||
public async Task<bool> HasRelationshipWithStatus(Guid accountId, Guid relatedId,
|
||||
@@ -216,29 +221,26 @@ public class RelationshipService(
|
||||
return relationship is not null;
|
||||
}
|
||||
|
||||
private async Task<List<Guid>> GetCachedRelationships(Guid accountId, RelationshipStatus status, string cachePrefix)
|
||||
private async Task<List<Guid>> GetCachedRelationships(
|
||||
Guid accountId,
|
||||
RelationshipStatus status,
|
||||
string cachePrefix,
|
||||
bool isRelated = false
|
||||
)
|
||||
{
|
||||
if (accountId == Guid.Empty)
|
||||
throw new ArgumentException("Account ID cannot be empty.");
|
||||
|
||||
var cacheKey = $"{cachePrefix}{accountId}";
|
||||
var cacheKey = $"{cachePrefix}{accountId}:{isRelated}";
|
||||
var relationships = await cache.GetAsync<List<Guid>>(cacheKey);
|
||||
|
||||
if (relationships != null) return relationships;
|
||||
var now = Instant.FromDateTimeUtc(DateTime.UtcNow);
|
||||
var query = db.AccountRelationships
|
||||
.Where(r => r.RelatedId == accountId)
|
||||
.Where(r => isRelated ? r.RelatedId == accountId : r.AccountId == accountId)
|
||||
.Where(r => r.Status == status)
|
||||
.Where(r => r.ExpiredAt == null || r.ExpiredAt > now)
|
||||
.Select(r => r.AccountId);
|
||||
|
||||
if (status == RelationshipStatus.Friends)
|
||||
{
|
||||
var usersBlockedByMe = db.AccountRelationships
|
||||
.Where(r => r.AccountId == accountId && r.Status == RelationshipStatus.Blocked)
|
||||
.Select(r => r.RelatedId);
|
||||
query = query.Except(usersBlockedByMe);
|
||||
}
|
||||
.Select(r => isRelated ? r.AccountId : r.RelatedId);
|
||||
|
||||
relationships = await query.ToListAsync();
|
||||
|
||||
|
||||
@@ -290,8 +290,6 @@ service AccountService {
|
||||
rpc ListConnections(ListConnectionsRequest) returns (ListConnectionsResponse) {}
|
||||
|
||||
// Relationship Operations
|
||||
rpc ListRelationships(ListRelationshipsRequest) returns (ListRelationshipsResponse) {}
|
||||
|
||||
rpc GetRelationship(GetRelationshipRequest) returns (GetRelationshipResponse) {}
|
||||
rpc HasRelationship(GetRelationshipRequest) returns (google.protobuf.BoolValue) {}
|
||||
rpc ListFriends(ListRelationshipSimpleRequest) returns (ListRelationshipSimpleResponse) {}
|
||||
@@ -489,7 +487,10 @@ message GetRelationshipResponse {
|
||||
}
|
||||
|
||||
message ListRelationshipSimpleRequest {
|
||||
oneof relation_identifier {
|
||||
string account_id = 1;
|
||||
string related_id = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message ListRelationshipSimpleResponse {
|
||||
|
||||
Reference in New Issue
Block a user