♻️ Finish centerlizing the data models

This commit is contained in:
2025-09-27 15:14:05 +08:00
parent e70d8371f8
commit 9ce31c4dd8
167 changed files with 780 additions and 42880 deletions

View File

@@ -1,6 +1,5 @@
using System.ComponentModel.DataAnnotations;
using DysonNetwork.Develop.Project;
using DysonNetwork.Shared.Data;
using DysonNetwork.Shared.Models;
using DysonNetwork.Shared.Proto;
using DysonNetwork.Shared.Registry;
@@ -89,7 +88,7 @@ public class BotAccountController(
return NotFound("Developer not found");
if (!await developerService.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id),
PublisherMemberRole.Viewer))
Shared.Proto.PublisherMemberRole.Viewer))
return StatusCode(403, "You must be an viewer of the developer to list bots");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -114,7 +113,7 @@ public class BotAccountController(
return NotFound("Developer not found");
if (!await developerService.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id),
PublisherMemberRole.Viewer))
Shared.Proto.PublisherMemberRole.Viewer))
return StatusCode(403, "You must be an viewer of the developer to view bot details");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -143,7 +142,7 @@ public class BotAccountController(
return NotFound("Developer not found");
if (!await developerService.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id),
PublisherMemberRole.Editor))
Shared.Proto.PublisherMemberRole.Editor))
return StatusCode(403, "You must be an editor of the developer to create a bot");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -212,7 +211,7 @@ public class BotAccountController(
return NotFound("Developer not found");
if (!await developerService.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id),
PublisherMemberRole.Editor))
Shared.Proto.PublisherMemberRole.Editor))
return StatusCode(403, "You must be an editor of the developer to update a bot");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -273,7 +272,7 @@ public class BotAccountController(
return NotFound("Developer not found");
if (!await developerService.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id),
PublisherMemberRole.Editor))
Shared.Proto.PublisherMemberRole.Editor))
return StatusCode(403, "You must be an editor of the developer to delete a bot");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -297,7 +296,7 @@ public class BotAccountController(
}
[HttpGet("{botId:guid}/keys")]
public async Task<ActionResult<List<ApiKeyReference>>> ListBotKeys(
public async Task<ActionResult<List<SnApiKey>>> ListBotKeys(
[FromRoute] string pubName,
[FromRoute] Guid projectId,
[FromRoute] Guid botId
@@ -306,7 +305,7 @@ public class BotAccountController(
if (HttpContext.Items["CurrentUser"] is not Account currentUser)
return Unauthorized();
var (developer, project, bot) = await ValidateBotAccess(pubName, projectId, botId, currentUser, PublisherMemberRole.Viewer);
var (developer, project, bot) = await ValidateBotAccess(pubName, projectId, botId, currentUser, Shared.Proto.PublisherMemberRole.Viewer);
if (developer == null) return NotFound("Developer not found");
if (project == null) return NotFound("Project not found or you don't have access");
if (bot == null) return NotFound("Bot not found");
@@ -315,13 +314,13 @@ public class BotAccountController(
{
AutomatedId = bot.Id.ToString()
});
var data = keys.Data.Select(ApiKeyReference.FromProtoValue).ToList();
var data = keys.Data.Select(SnApiKey.FromProtoValue).ToList();
return Ok(data);
}
[HttpGet("{botId:guid}/keys/{keyId:guid}")]
public async Task<ActionResult<ApiKeyReference>> GetBotKey(
public async Task<ActionResult<SnApiKey>> GetBotKey(
[FromRoute] string pubName,
[FromRoute] Guid projectId,
[FromRoute] Guid botId,
@@ -330,7 +329,7 @@ public class BotAccountController(
if (HttpContext.Items["CurrentUser"] is not Account currentUser)
return Unauthorized();
var (developer, project, bot) = await ValidateBotAccess(pubName, projectId, botId, currentUser, PublisherMemberRole.Viewer);
var (developer, project, bot) = await ValidateBotAccess(pubName, projectId, botId, currentUser, Shared.Proto.PublisherMemberRole.Viewer);
if (developer == null) return NotFound("Developer not found");
if (project == null) return NotFound("Project not found or you don't have access");
if (bot == null) return NotFound("Bot not found");
@@ -339,7 +338,7 @@ public class BotAccountController(
{
var key = await accountsReceiver.GetApiKeyAsync(new GetApiKeyRequest { Id = keyId.ToString() });
if (key == null) return NotFound("API key not found");
return Ok(ApiKeyReference.FromProtoValue(key));
return Ok(SnApiKey.FromProtoValue(key));
}
catch (RpcException ex) when (ex.StatusCode == Grpc.Core.StatusCode.NotFound)
{
@@ -354,7 +353,7 @@ public class BotAccountController(
}
[HttpPost("{botId:guid}/keys")]
public async Task<ActionResult<ApiKeyReference>> CreateBotKey(
public async Task<ActionResult<SnApiKey>> CreateBotKey(
[FromRoute] string pubName,
[FromRoute] Guid projectId,
[FromRoute] Guid botId,
@@ -363,7 +362,7 @@ public class BotAccountController(
if (HttpContext.Items["CurrentUser"] is not Account currentUser)
return Unauthorized();
var (developer, project, bot) = await ValidateBotAccess(pubName, projectId, botId, currentUser, PublisherMemberRole.Editor);
var (developer, project, bot) = await ValidateBotAccess(pubName, projectId, botId, currentUser, Shared.Proto.PublisherMemberRole.Editor);
if (developer == null) return NotFound("Developer not found");
if (project == null) return NotFound("Project not found or you don't have access");
if (bot == null) return NotFound("Bot not found");
@@ -377,7 +376,7 @@ public class BotAccountController(
};
var createdKey = await accountsReceiver.CreateApiKeyAsync(newKey);
return Ok(ApiKeyReference.FromProtoValue(createdKey));
return Ok(SnApiKey.FromProtoValue(createdKey));
}
catch (RpcException ex) when (ex.StatusCode == Grpc.Core.StatusCode.InvalidArgument)
{
@@ -386,7 +385,7 @@ public class BotAccountController(
}
[HttpPost("{botId:guid}/keys/{keyId:guid}/rotate")]
public async Task<ActionResult<ApiKeyReference>> RotateBotKey(
public async Task<ActionResult<SnApiKey>> RotateBotKey(
[FromRoute] string pubName,
[FromRoute] Guid projectId,
[FromRoute] Guid botId,
@@ -395,7 +394,7 @@ public class BotAccountController(
if (HttpContext.Items["CurrentUser"] is not Account currentUser)
return Unauthorized();
var (developer, project, bot) = await ValidateBotAccess(pubName, projectId, botId, currentUser, PublisherMemberRole.Editor);
var (developer, project, bot) = await ValidateBotAccess(pubName, projectId, botId, currentUser, Shared.Proto.PublisherMemberRole.Editor);
if (developer == null) return NotFound("Developer not found");
if (project == null) return NotFound("Project not found or you don't have access");
if (bot == null) return NotFound("Bot not found");
@@ -403,7 +402,7 @@ public class BotAccountController(
try
{
var rotatedKey = await accountsReceiver.RotateApiKeyAsync(new GetApiKeyRequest { Id = keyId.ToString() });
return Ok(ApiKeyReference.FromProtoValue(rotatedKey));
return Ok(SnApiKey.FromProtoValue(rotatedKey));
}
catch (RpcException ex) when (ex.StatusCode == Grpc.Core.StatusCode.NotFound)
{
@@ -421,7 +420,7 @@ public class BotAccountController(
if (HttpContext.Items["CurrentUser"] is not Account currentUser)
return Unauthorized();
var (developer, project, bot) = await ValidateBotAccess(pubName, projectId, botId, currentUser, PublisherMemberRole.Editor);
var (developer, project, bot) = await ValidateBotAccess(pubName, projectId, botId, currentUser, Shared.Proto.PublisherMemberRole.Editor);
if (developer == null) return NotFound("Developer not found");
if (project == null) return NotFound("Project not found or you don't have access");
if (bot == null) return NotFound("Bot not found");
@@ -437,12 +436,12 @@ public class BotAccountController(
}
}
private async Task<(SnDeveloper?, SnDevProject?, BotAccount?)> ValidateBotAccess(
private async Task<(SnDeveloper?, SnDevProject?, SnBotAccount?)> ValidateBotAccess(
string pubName,
Guid projectId,
Guid botId,
Account currentUser,
PublisherMemberRole requiredRole)
Shared.Proto.PublisherMemberRole requiredRole)
{
var developer = await developerService.GetDeveloperByName(pubName);
if (developer == null) return (null, null, null);

View File

@@ -1,4 +1,3 @@
using DysonNetwork.Shared.Data;
using DysonNetwork.Shared.Models;
using DysonNetwork.Shared.Proto;
using DysonNetwork.Shared.Registry;
@@ -14,21 +13,21 @@ public class BotAccountService(
AccountClientHelper accounts
)
{
public async Task<BotAccount?> GetBotByIdAsync(Guid id)
public async Task<SnBotAccount?> GetBotByIdAsync(Guid id)
{
return await db.BotAccounts
.Include(b => b.Project)
.FirstOrDefaultAsync(b => b.Id == id);
}
public async Task<IEnumerable<BotAccount>> GetBotsByProjectAsync(Guid projectId)
public async Task<IEnumerable<SnBotAccount>> GetBotsByProjectAsync(Guid projectId)
{
return await db.BotAccounts
.Where(b => b.ProjectId == projectId)
.ToListAsync();
}
public async Task<BotAccount> CreateBotAsync(
public async Task<SnBotAccount> CreateBotAsync(
SnDevProject project,
string slug,
Account account,
@@ -58,7 +57,7 @@ public class BotAccountService(
var botAccount = createResponse.Bot;
// Then create the local bot account
var bot = new BotAccount
var bot = new SnBotAccount
{
Id = automatedId,
Slug = slug,
@@ -89,8 +88,8 @@ public class BotAccountService(
}
}
public async Task<BotAccount> UpdateBotAsync(
BotAccount bot,
public async Task<SnBotAccount> UpdateBotAsync(
SnBotAccount bot,
Account account,
string? pictureId,
string? backgroundId
@@ -130,7 +129,7 @@ public class BotAccountService(
return bot;
}
public async Task DeleteBotAsync(BotAccount bot)
public async Task DeleteBotAsync(SnBotAccount bot)
{
try
{
@@ -153,12 +152,12 @@ public class BotAccountService(
await db.SaveChangesAsync();
}
public async Task<BotAccount?> LoadBotAccountAsync(BotAccount bot) =>
public async Task<SnBotAccount?> LoadBotAccountAsync(SnBotAccount bot) =>
(await LoadBotsAccountAsync([bot])).FirstOrDefault();
public async Task<List<BotAccount>> LoadBotsAccountAsync(IEnumerable<BotAccount> bots)
public async Task<List<SnBotAccount>> LoadBotsAccountAsync(IEnumerable<SnBotAccount> bots)
{
bots = bots.ToList();
bots = [.. bots];
var automatedIds = bots.Select(b => b.Id).ToList();
var data = await accounts.GetBotAccountBatch(automatedIds);
@@ -169,6 +168,6 @@ public class BotAccountService(
.FirstOrDefault(e => e.AutomatedId == bot.Id);
}
return bots as List<BotAccount> ?? [];
return bots as List<SnBotAccount> ?? [];
}
}

View File

@@ -19,9 +19,9 @@ public class CustomAppController(CustomAppService customApps, DeveloperService d
[MaxLength(4096)] string? Description,
string? PictureId,
string? BackgroundId,
CustomAppStatus? Status,
CustomAppLinks? Links,
CustomAppOauthConfig? OauthConfig
Shared.Models.CustomAppStatus? Status,
SnCustomAppLinks? Links,
SnCustomAppOauthConfig? OauthConfig
);
public record CreateSecretRequest(
@@ -51,7 +51,7 @@ public class CustomAppController(CustomAppService customApps, DeveloperService d
if (developer is null) return NotFound();
var accountId = Guid.Parse(currentUser.Id);
if (!await ds.IsMemberWithRole(developer.PublisherId, accountId, PublisherMemberRole.Viewer))
if (!await ds.IsMemberWithRole(developer.PublisherId, accountId, Shared.Proto.PublisherMemberRole.Viewer))
return StatusCode(403, "You must be a viewer of the developer to list custom apps");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -73,7 +73,7 @@ public class CustomAppController(CustomAppService customApps, DeveloperService d
if (developer is null) return NotFound();
var accountId = Guid.Parse(currentUser.Id);
if (!await ds.IsMemberWithRole(developer.PublisherId, accountId, PublisherMemberRole.Viewer))
if (!await ds.IsMemberWithRole(developer.PublisherId, accountId, Shared.Proto.PublisherMemberRole.Viewer))
return StatusCode(403, "You must be a viewer of the developer to list custom apps");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -100,7 +100,7 @@ public class CustomAppController(CustomAppService customApps, DeveloperService d
if (developer is null)
return NotFound("Developer not found");
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), PublisherMemberRole.Editor))
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), Shared.Proto.PublisherMemberRole.Editor))
return StatusCode(403, "You must be an editor of the developer to create a custom app");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -144,7 +144,7 @@ public class CustomAppController(CustomAppService customApps, DeveloperService d
if (developer is null)
return NotFound("Developer not found");
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), PublisherMemberRole.Editor))
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), Shared.Proto.PublisherMemberRole.Editor))
return StatusCode(403, "You must be an editor of the developer to update a custom app");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -181,7 +181,7 @@ public class CustomAppController(CustomAppService customApps, DeveloperService d
if (developer is null)
return NotFound("Developer not found");
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), PublisherMemberRole.Editor))
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), Shared.Proto.PublisherMemberRole.Editor))
return StatusCode(403, "You must be an editor of the developer to delete a custom app");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -213,7 +213,7 @@ public class CustomAppController(CustomAppService customApps, DeveloperService d
if (developer is null)
return NotFound("Developer not found");
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), PublisherMemberRole.Editor))
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), Shared.Proto.PublisherMemberRole.Editor))
return StatusCode(403, "You must be an editor of the developer to view app secrets");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -251,7 +251,7 @@ public class CustomAppController(CustomAppService customApps, DeveloperService d
if (developer is null)
return NotFound("Developer not found");
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), PublisherMemberRole.Editor))
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), Shared.Proto.PublisherMemberRole.Editor))
return StatusCode(403, "You must be an editor of the developer to create app secrets");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -264,7 +264,7 @@ public class CustomAppController(CustomAppService customApps, DeveloperService d
try
{
var secret = await customApps.CreateAppSecretAsync(new CustomAppSecret
var secret = await customApps.CreateAppSecretAsync(new SnCustomAppSecret
{
AppId = appId,
Description = request.Description,
@@ -310,7 +310,7 @@ public class CustomAppController(CustomAppService customApps, DeveloperService d
if (developer is null)
return NotFound("Developer not found");
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), PublisherMemberRole.Editor))
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), Shared.Proto.PublisherMemberRole.Editor))
return StatusCode(403, "You must be an editor of the developer to view app secrets");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -351,7 +351,7 @@ public class CustomAppController(CustomAppService customApps, DeveloperService d
if (developer is null)
return NotFound("Developer not found");
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), PublisherMemberRole.Editor))
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), Shared.Proto.PublisherMemberRole.Editor))
return StatusCode(403, "You must be an editor of the developer to delete app secrets");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -389,7 +389,7 @@ public class CustomAppController(CustomAppService customApps, DeveloperService d
if (developer is null)
return NotFound("Developer not found");
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), PublisherMemberRole.Editor))
if (!await ds.IsMemberWithRole(developer.PublisherId, Guid.Parse(currentUser.Id), Shared.Proto.PublisherMemberRole.Editor))
return StatusCode(403, "You must be an editor of the developer to rotate app secrets");
var project = await projectService.GetProjectAsync(projectId, developer.Id);
@@ -402,7 +402,7 @@ public class CustomAppController(CustomAppService customApps, DeveloperService d
try
{
var secret = await customApps.RotateAppSecretAsync(new CustomAppSecret
var secret = await customApps.RotateAppSecretAsync(new SnCustomAppSecret
{
Id = secretId,
AppId = appId,

View File

@@ -1,4 +1,3 @@
using DysonNetwork.Develop.Project;
using DysonNetwork.Shared.Models;
using DysonNetwork.Shared.Proto;
using Microsoft.EntityFrameworkCore;
@@ -13,7 +12,7 @@ public class CustomAppService(
FileService.FileServiceClient files
)
{
public async Task<CustomApp?> CreateAppAsync(
public async Task<SnCustomApp?> CreateAppAsync(
Guid projectId,
CustomAppController.CustomAppRequest request
)
@@ -25,12 +24,12 @@ public class CustomAppService(
if (project == null)
return null;
var app = new CustomApp
var app = new SnCustomApp
{
Slug = request.Slug!,
Name = request.Name!,
Description = request.Description,
Status = request.Status ?? CustomAppStatus.Developing,
Status = request.Status ?? Shared.Models.CustomAppStatus.Developing,
Links = request.Links,
OauthConfig = request.OauthConfig,
ProjectId = projectId
@@ -84,7 +83,7 @@ public class CustomAppService(
return app;
}
public async Task<CustomApp?> GetAppAsync(Guid id, Guid? projectId = null)
public async Task<SnCustomApp?> GetAppAsync(Guid id, Guid? projectId = null)
{
var query = db.CustomApps.AsQueryable();
@@ -96,7 +95,7 @@ public class CustomAppService(
return await query.FirstOrDefaultAsync(a => a.Id == id);
}
public async Task<List<CustomAppSecret>> GetAppSecretsAsync(Guid appId)
public async Task<List<SnCustomAppSecret>> GetAppSecretsAsync(Guid appId)
{
return await db.CustomAppSecrets
.Where(s => s.AppId == appId)
@@ -104,13 +103,13 @@ public class CustomAppService(
.ToListAsync();
}
public async Task<CustomAppSecret?> GetAppSecretAsync(Guid secretId, Guid appId)
public async Task<SnCustomAppSecret?> GetAppSecretAsync(Guid secretId, Guid appId)
{
return await db.CustomAppSecrets
.FirstOrDefaultAsync(s => s.Id == secretId && s.AppId == appId);
}
public async Task<CustomAppSecret> CreateAppSecretAsync(CustomAppSecret secret)
public async Task<SnCustomAppSecret> CreateAppSecretAsync(SnCustomAppSecret secret)
{
if (string.IsNullOrWhiteSpace(secret.Secret))
{
@@ -141,7 +140,7 @@ public class CustomAppService(
return true;
}
public async Task<CustomAppSecret> RotateAppSecretAsync(CustomAppSecret secretUpdate)
public async Task<SnCustomAppSecret> RotateAppSecretAsync(SnCustomAppSecret secretUpdate)
{
var existingSecret = await db.CustomAppSecrets
.FirstOrDefaultAsync(s => s.Id == secretUpdate.Id && s.AppId == secretUpdate.AppId);
@@ -177,14 +176,14 @@ public class CustomAppService(
return res.ToString();
}
public async Task<List<CustomApp>> GetAppsByProjectAsync(Guid projectId)
public async Task<List<SnCustomApp>> GetAppsByProjectAsync(Guid projectId)
{
return await db.CustomApps
.Where(a => a.ProjectId == projectId)
.ToListAsync();
}
public async Task<CustomApp?> UpdateAppAsync(CustomApp app, CustomAppController.CustomAppRequest request)
public async Task<SnCustomApp?> UpdateAppAsync(SnCustomApp app, CustomAppController.CustomAppRequest request)
{
if (request.Slug is not null)
app.Slug = request.Slug;

View File

@@ -38,7 +38,7 @@ public class CustomAppServiceGrpc(AppDatabase db) : Shared.Proto.CustomAppServic
if (string.IsNullOrEmpty(request.Secret))
throw new RpcException(new Status(StatusCode.InvalidArgument, "secret required"));
IQueryable<CustomAppSecret> q = db.CustomAppSecrets;
IQueryable<SnCustomAppSecret> q = db.CustomAppSecrets;
switch (request.SecretIdentifierCase)
{
case CheckCustomAppSecretRequest.SecretIdentifierOneofCase.SecretId:

View File

@@ -75,11 +75,11 @@ public class DeveloperController(
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
var accountId = Guid.Parse(currentUser.Id);
PublisherInfo? pub;
SnPublisher? pub;
try
{
var pubResponse = await ps.GetPublisherAsync(new GetPublisherRequest { Name = name });
pub = PublisherInfo.FromProto(pubResponse.Publisher);
pub = SnPublisher.FromProto(pubResponse.Publisher);
} catch (RpcException ex)
{
return NotFound(ex.Status.Detail);
@@ -90,7 +90,7 @@ public class DeveloperController(
{
PublisherId = pub.Id.ToString(),
AccountId = currentUser.Id,
Role = PublisherMemberRole.Owner
Role = Shared.Proto.PublisherMemberRole.Owner
});
if (!permResponse.Valid) return StatusCode(403, "You must be the owner of the publisher to join the developer program");

View File

@@ -13,7 +13,7 @@ public class DeveloperService(
public async Task<SnDeveloper> LoadDeveloperPublisher(SnDeveloper developer)
{
var pubResponse = await ps.GetPublisherAsync(new GetPublisherRequest { Id = developer.PublisherId.ToString() });
developer.Publisher = PublisherInfo.FromProto(pubResponse.Publisher);
developer.Publisher = SnPublisher.FromProto(pubResponse.Publisher);
return developer;
}
@@ -25,7 +25,7 @@ public class DeveloperService(
var pubRequest = new GetPublisherBatchRequest();
pubIds.ForEach(x => pubRequest.Ids.Add(x.ToString()));
var pubResponse = await ps.GetPublisherBatchAsync(pubRequest);
var pubs = pubResponse.Publishers.ToDictionary(p => Guid.Parse(p.Id), PublisherInfo.FromProto);
var pubs = pubResponse.Publishers.ToDictionary(p => Guid.Parse(p.Id), SnPublisher.FromProto);
return enumerable.Select(d =>
{
@@ -56,7 +56,7 @@ public class DeveloperService(
return await db.Developers.FirstOrDefaultAsync(d => d.Id == id);
}
public async Task<bool> IsMemberWithRole(Guid pubId, Guid accountId, PublisherMemberRole role)
public async Task<bool> IsMemberWithRole(Guid pubId, Guid accountId, Shared.Proto.PublisherMemberRole role)
{
try
{