✨ Full featured auto complete
This commit is contained in:
@@ -160,6 +160,26 @@ public class AccountServiceGrpc(
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override async Task<GetAccountBatchResponse> SearchAccount(SearchAccountRequest request, ServerCallContext context)
|
||||||
|
{
|
||||||
|
var accounts = await _db.Accounts
|
||||||
|
.AsNoTracking()
|
||||||
|
.Where(a => EF.Functions.ILike(a.Name, $"%{request.Query}%"))
|
||||||
|
.Include(a => a.Profile)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var perks = await subscriptions.GetPerkSubscriptionsAsync(
|
||||||
|
accounts.Select(x => x.Id).ToList()
|
||||||
|
);
|
||||||
|
foreach (var account in accounts)
|
||||||
|
if (perks.TryGetValue(account.Id, out var perk))
|
||||||
|
account.PerkSubscription = perk?.ToReference();
|
||||||
|
|
||||||
|
var response = new GetAccountBatchResponse();
|
||||||
|
response.Accounts.AddRange(accounts.Select(a => a.ToProtoValue()));
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
public override async Task<ListAccountsResponse> ListAccounts(ListAccountsRequest request,
|
public override async Task<ListAccountsResponse> ListAccounts(ListAccountsRequest request,
|
||||||
ServerCallContext context)
|
ServerCallContext context)
|
||||||
{
|
{
|
||||||
|
@@ -14,232 +14,232 @@ import 'wallet.proto';
|
|||||||
|
|
||||||
// Account represents a user account in the system
|
// Account represents a user account in the system
|
||||||
message Account {
|
message Account {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
string name = 2;
|
string name = 2;
|
||||||
string nick = 3;
|
string nick = 3;
|
||||||
string language = 4;
|
string language = 4;
|
||||||
string region = 18;
|
string region = 18;
|
||||||
google.protobuf.Timestamp activated_at = 5;
|
google.protobuf.Timestamp activated_at = 5;
|
||||||
bool is_superuser = 6;
|
bool is_superuser = 6;
|
||||||
|
|
||||||
AccountProfile profile = 7;
|
AccountProfile profile = 7;
|
||||||
optional SubscriptionReferenceObject perk_subscription = 16;
|
optional SubscriptionReferenceObject perk_subscription = 16;
|
||||||
repeated AccountContact contacts = 8;
|
repeated AccountContact contacts = 8;
|
||||||
repeated AccountBadge badges = 9;
|
repeated AccountBadge badges = 9;
|
||||||
repeated AccountAuthFactor auth_factors = 10;
|
repeated AccountAuthFactor auth_factors = 10;
|
||||||
repeated AccountConnection connections = 11;
|
repeated AccountConnection connections = 11;
|
||||||
repeated Relationship outgoing_relationships = 12;
|
repeated Relationship outgoing_relationships = 12;
|
||||||
repeated Relationship incoming_relationships = 13;
|
repeated Relationship incoming_relationships = 13;
|
||||||
|
|
||||||
google.protobuf.Timestamp created_at = 14;
|
google.protobuf.Timestamp created_at = 14;
|
||||||
google.protobuf.Timestamp updated_at = 15;
|
google.protobuf.Timestamp updated_at = 15;
|
||||||
|
|
||||||
google.protobuf.StringValue automated_id = 17;
|
google.protobuf.StringValue automated_id = 17;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enum for status attitude
|
// Enum for status attitude
|
||||||
enum StatusAttitude {
|
enum StatusAttitude {
|
||||||
STATUS_ATTITUDE_UNSPECIFIED = 0;
|
STATUS_ATTITUDE_UNSPECIFIED = 0;
|
||||||
POSITIVE = 1;
|
POSITIVE = 1;
|
||||||
NEGATIVE = 2;
|
NEGATIVE = 2;
|
||||||
NEUTRAL = 3;
|
NEUTRAL = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountStatus represents the status of an account
|
// AccountStatus represents the status of an account
|
||||||
message AccountStatus {
|
message AccountStatus {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
StatusAttitude attitude = 2;
|
StatusAttitude attitude = 2;
|
||||||
bool is_online = 3;
|
bool is_online = 3;
|
||||||
bool is_customized = 4;
|
bool is_customized = 4;
|
||||||
bool is_invisible = 5;
|
bool is_invisible = 5;
|
||||||
bool is_not_disturb = 6;
|
bool is_not_disturb = 6;
|
||||||
google.protobuf.StringValue label = 7;
|
google.protobuf.StringValue label = 7;
|
||||||
google.protobuf.Timestamp cleared_at = 8;
|
google.protobuf.Timestamp cleared_at = 8;
|
||||||
string account_id = 9;
|
string account_id = 9;
|
||||||
bytes meta = 10;
|
bytes meta = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Profile contains detailed information about a user
|
// Profile contains detailed information about a user
|
||||||
message AccountProfile {
|
message AccountProfile {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
google.protobuf.StringValue first_name = 2;
|
google.protobuf.StringValue first_name = 2;
|
||||||
google.protobuf.StringValue middle_name = 3;
|
google.protobuf.StringValue middle_name = 3;
|
||||||
google.protobuf.StringValue last_name = 4;
|
google.protobuf.StringValue last_name = 4;
|
||||||
google.protobuf.StringValue bio = 5;
|
google.protobuf.StringValue bio = 5;
|
||||||
google.protobuf.StringValue gender = 6;
|
google.protobuf.StringValue gender = 6;
|
||||||
google.protobuf.StringValue pronouns = 7;
|
google.protobuf.StringValue pronouns = 7;
|
||||||
google.protobuf.StringValue time_zone = 8;
|
google.protobuf.StringValue time_zone = 8;
|
||||||
google.protobuf.StringValue location = 9;
|
google.protobuf.StringValue location = 9;
|
||||||
google.protobuf.Timestamp birthday = 10;
|
google.protobuf.Timestamp birthday = 10;
|
||||||
google.protobuf.Timestamp last_seen_at = 11;
|
google.protobuf.Timestamp last_seen_at = 11;
|
||||||
|
|
||||||
VerificationMark verification = 12;
|
VerificationMark verification = 12;
|
||||||
BadgeReferenceObject active_badge = 13;
|
BadgeReferenceObject active_badge = 13;
|
||||||
|
|
||||||
int32 experience = 14;
|
int32 experience = 14;
|
||||||
int32 level = 15;
|
int32 level = 15;
|
||||||
double leveling_progress = 16;
|
double leveling_progress = 16;
|
||||||
double social_credits = 17;
|
double social_credits = 17;
|
||||||
int32 social_credits_level = 18;
|
int32 social_credits_level = 18;
|
||||||
|
|
||||||
CloudFile picture = 19;
|
CloudFile picture = 19;
|
||||||
CloudFile background = 20;
|
CloudFile background = 20;
|
||||||
|
|
||||||
string account_id = 21;
|
string account_id = 21;
|
||||||
|
|
||||||
google.protobuf.Timestamp created_at = 22;
|
google.protobuf.Timestamp created_at = 22;
|
||||||
google.protobuf.Timestamp updated_at = 23;
|
google.protobuf.Timestamp updated_at = 23;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountContact represents a contact method for an account
|
// AccountContact represents a contact method for an account
|
||||||
message AccountContact {
|
message AccountContact {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
AccountContactType type = 2;
|
AccountContactType type = 2;
|
||||||
google.protobuf.Timestamp verified_at = 3;
|
google.protobuf.Timestamp verified_at = 3;
|
||||||
bool is_primary = 4;
|
bool is_primary = 4;
|
||||||
string content = 5;
|
string content = 5;
|
||||||
string account_id = 6;
|
string account_id = 6;
|
||||||
|
|
||||||
google.protobuf.Timestamp created_at = 7;
|
google.protobuf.Timestamp created_at = 7;
|
||||||
google.protobuf.Timestamp updated_at = 8;
|
google.protobuf.Timestamp updated_at = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enum for contact types
|
// Enum for contact types
|
||||||
enum AccountContactType {
|
enum AccountContactType {
|
||||||
ACCOUNT_CONTACT_TYPE_UNSPECIFIED = 0;
|
ACCOUNT_CONTACT_TYPE_UNSPECIFIED = 0;
|
||||||
EMAIL = 1;
|
EMAIL = 1;
|
||||||
PHONE_NUMBER = 2;
|
PHONE_NUMBER = 2;
|
||||||
ADDRESS = 3;
|
ADDRESS = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountAuthFactor represents an authentication factor for an account
|
// AccountAuthFactor represents an authentication factor for an account
|
||||||
message AccountAuthFactor {
|
message AccountAuthFactor {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
AccountAuthFactorType type = 2;
|
AccountAuthFactorType type = 2;
|
||||||
google.protobuf.StringValue secret = 3; // Omitted from JSON serialization in original
|
google.protobuf.StringValue secret = 3; // Omitted from JSON serialization in original
|
||||||
map<string, google.protobuf.Value> config = 4; // Omitted from JSON serialization in original
|
map<string, google.protobuf.Value> config = 4; // Omitted from JSON serialization in original
|
||||||
int32 trustworthy = 5;
|
int32 trustworthy = 5;
|
||||||
google.protobuf.Timestamp enabled_at = 6;
|
google.protobuf.Timestamp enabled_at = 6;
|
||||||
google.protobuf.Timestamp expired_at = 7;
|
google.protobuf.Timestamp expired_at = 7;
|
||||||
string account_id = 8;
|
string account_id = 8;
|
||||||
map<string, google.protobuf.Value> created_response = 9; // For initial setup
|
map<string, google.protobuf.Value> created_response = 9; // For initial setup
|
||||||
|
|
||||||
google.protobuf.Timestamp created_at = 10;
|
google.protobuf.Timestamp created_at = 10;
|
||||||
google.protobuf.Timestamp updated_at = 11;
|
google.protobuf.Timestamp updated_at = 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enum for authentication factor types
|
// Enum for authentication factor types
|
||||||
enum AccountAuthFactorType {
|
enum AccountAuthFactorType {
|
||||||
AUTH_FACTOR_TYPE_UNSPECIFIED = 0;
|
AUTH_FACTOR_TYPE_UNSPECIFIED = 0;
|
||||||
PASSWORD = 1;
|
PASSWORD = 1;
|
||||||
EMAIL_CODE = 2;
|
EMAIL_CODE = 2;
|
||||||
IN_APP_CODE = 3;
|
IN_APP_CODE = 3;
|
||||||
TIMED_CODE = 4;
|
TIMED_CODE = 4;
|
||||||
PIN_CODE = 5;
|
PIN_CODE = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountBadge represents a badge associated with an account
|
// AccountBadge represents a badge associated with an account
|
||||||
message AccountBadge {
|
message AccountBadge {
|
||||||
string id = 1; // Unique identifier for the badge
|
string id = 1; // Unique identifier for the badge
|
||||||
string type = 2; // Type/category of the badge
|
string type = 2; // Type/category of the badge
|
||||||
google.protobuf.StringValue label = 3; // Display name of the badge
|
google.protobuf.StringValue label = 3; // Display name of the badge
|
||||||
google.protobuf.StringValue caption = 4; // Optional description of the badge
|
google.protobuf.StringValue caption = 4; // Optional description of the badge
|
||||||
map<string, google.protobuf.Value> meta = 5; // Additional metadata for the badge
|
map<string, google.protobuf.Value> meta = 5; // Additional metadata for the badge
|
||||||
google.protobuf.Timestamp activated_at = 6; // When the badge was activated
|
google.protobuf.Timestamp activated_at = 6; // When the badge was activated
|
||||||
google.protobuf.Timestamp expired_at = 7; // Optional expiration time
|
google.protobuf.Timestamp expired_at = 7; // Optional expiration time
|
||||||
string account_id = 8; // ID of the account this badge belongs to
|
string account_id = 8; // ID of the account this badge belongs to
|
||||||
|
|
||||||
google.protobuf.Timestamp created_at = 9;
|
google.protobuf.Timestamp created_at = 9;
|
||||||
google.protobuf.Timestamp updated_at = 10;
|
google.protobuf.Timestamp updated_at = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountConnection represents a third-party connection for an account
|
// AccountConnection represents a third-party connection for an account
|
||||||
message AccountConnection {
|
message AccountConnection {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
string provider = 2;
|
string provider = 2;
|
||||||
string provided_identifier = 3;
|
string provided_identifier = 3;
|
||||||
map<string, google.protobuf.Value> meta = 4;
|
map<string, google.protobuf.Value> meta = 4;
|
||||||
google.protobuf.StringValue access_token = 5; // Omitted from JSON serialization
|
google.protobuf.StringValue access_token = 5; // Omitted from JSON serialization
|
||||||
google.protobuf.StringValue refresh_token = 6; // Omitted from JSON serialization
|
google.protobuf.StringValue refresh_token = 6; // Omitted from JSON serialization
|
||||||
google.protobuf.Timestamp last_used_at = 7;
|
google.protobuf.Timestamp last_used_at = 7;
|
||||||
string account_id = 8;
|
string account_id = 8;
|
||||||
|
|
||||||
google.protobuf.Timestamp created_at = 9;
|
google.protobuf.Timestamp created_at = 9;
|
||||||
google.protobuf.Timestamp updated_at = 10;
|
google.protobuf.Timestamp updated_at = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerificationMark represents verification status
|
// VerificationMark represents verification status
|
||||||
message VerificationMark {
|
message VerificationMark {
|
||||||
VerificationMarkType type = 1;
|
VerificationMarkType type = 1;
|
||||||
string title = 2;
|
string title = 2;
|
||||||
string description = 3;
|
string description = 3;
|
||||||
string verified_by = 4;
|
string verified_by = 4;
|
||||||
|
|
||||||
google.protobuf.Timestamp created_at = 5;
|
google.protobuf.Timestamp created_at = 5;
|
||||||
google.protobuf.Timestamp updated_at = 6;
|
google.protobuf.Timestamp updated_at = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum VerificationMarkType {
|
enum VerificationMarkType {
|
||||||
VERIFICATION_MARK_TYPE_UNSPECIFIED = 0;
|
VERIFICATION_MARK_TYPE_UNSPECIFIED = 0;
|
||||||
OFFICIAL = 1;
|
OFFICIAL = 1;
|
||||||
INDIVIDUAL = 2;
|
INDIVIDUAL = 2;
|
||||||
ORGANIZATION = 3;
|
ORGANIZATION = 3;
|
||||||
GOVERNMENT = 4;
|
GOVERNMENT = 4;
|
||||||
CREATOR = 5;
|
CREATOR = 5;
|
||||||
DEVELOPER = 6;
|
DEVELOPER = 6;
|
||||||
PARODY = 7;
|
PARODY = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BadgeReferenceObject represents a reference to a badge with minimal information
|
// BadgeReferenceObject represents a reference to a badge with minimal information
|
||||||
message BadgeReferenceObject {
|
message BadgeReferenceObject {
|
||||||
string id = 1; // Unique identifier for the badge
|
string id = 1; // Unique identifier for the badge
|
||||||
string type = 2; // Type/category of the badge
|
string type = 2; // Type/category of the badge
|
||||||
google.protobuf.StringValue label = 3; // Display name of the badge
|
google.protobuf.StringValue label = 3; // Display name of the badge
|
||||||
google.protobuf.StringValue caption = 4; // Optional description of the badge
|
google.protobuf.StringValue caption = 4; // Optional description of the badge
|
||||||
map<string, google.protobuf.Value> meta = 5; // Additional metadata for the badge
|
map<string, google.protobuf.Value> meta = 5; // Additional metadata for the badge
|
||||||
google.protobuf.Timestamp activated_at = 6; // When the badge was activated
|
google.protobuf.Timestamp activated_at = 6; // When the badge was activated
|
||||||
google.protobuf.Timestamp expired_at = 7; // Optional expiration time
|
google.protobuf.Timestamp expired_at = 7; // Optional expiration time
|
||||||
string account_id = 8; // ID of the account this badge belongs to
|
string account_id = 8; // ID of the account this badge belongs to
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relationship represents a connection between two accounts
|
// Relationship represents a connection between two accounts
|
||||||
message Relationship {
|
message Relationship {
|
||||||
string account_id = 1;
|
string account_id = 1;
|
||||||
string related_id = 2;
|
string related_id = 2;
|
||||||
optional Account account = 3;
|
optional Account account = 3;
|
||||||
optional Account related = 4;
|
optional Account related = 4;
|
||||||
int32 status = 5;
|
int32 status = 5;
|
||||||
|
|
||||||
google.protobuf.Timestamp created_at = 6;
|
google.protobuf.Timestamp created_at = 6;
|
||||||
google.protobuf.Timestamp updated_at = 7;
|
google.protobuf.Timestamp updated_at = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leveling information
|
// Leveling information
|
||||||
message LevelingInfo {
|
message LevelingInfo {
|
||||||
int32 current_level = 1;
|
int32 current_level = 1;
|
||||||
int32 current_experience = 2;
|
int32 current_experience = 2;
|
||||||
int32 next_level_experience = 3;
|
int32 next_level_experience = 3;
|
||||||
int32 previous_level_experience = 4;
|
int32 previous_level_experience = 4;
|
||||||
double level_progress = 5;
|
double level_progress = 5;
|
||||||
repeated int32 experience_per_level = 6;
|
repeated int32 experience_per_level = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionLog represents a record of an action taken by a user
|
// ActionLog represents a record of an action taken by a user
|
||||||
message ActionLog {
|
message ActionLog {
|
||||||
string id = 1; // Unique identifier for the log entry
|
string id = 1; // Unique identifier for the log entry
|
||||||
string action = 2; // The action that was performed, e.g., "user.login"
|
string action = 2; // The action that was performed, e.g., "user.login"
|
||||||
map<string, google.protobuf.Value> meta = 3; // Metadata associated with the action
|
map<string, google.protobuf.Value> meta = 3; // Metadata associated with the action
|
||||||
google.protobuf.StringValue user_agent = 4; // User agent of the client
|
google.protobuf.StringValue user_agent = 4; // User agent of the client
|
||||||
google.protobuf.StringValue ip_address = 5; // IP address of the client
|
google.protobuf.StringValue ip_address = 5; // IP address of the client
|
||||||
google.protobuf.StringValue location = 6; // Geographic location of the client, derived from IP
|
google.protobuf.StringValue location = 6; // Geographic location of the client, derived from IP
|
||||||
string account_id = 7; // The account that performed the action
|
string account_id = 7; // The account that performed the action
|
||||||
google.protobuf.StringValue session_id = 8; // The session in which the action was performed
|
google.protobuf.StringValue session_id = 8; // The session in which the action was performed
|
||||||
|
|
||||||
google.protobuf.Timestamp created_at = 9; // When the action log was created
|
google.protobuf.Timestamp created_at = 9; // When the action log was created
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetAccountStatusBatchResponse {
|
message GetAccountStatusBatchResponse {
|
||||||
repeated AccountStatus statuses = 1;
|
repeated AccountStatus statuses = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====================================
|
// ====================================
|
||||||
@@ -248,45 +248,46 @@ message GetAccountStatusBatchResponse {
|
|||||||
|
|
||||||
// AccountService provides CRUD operations for user accounts and related entities
|
// AccountService provides CRUD operations for user accounts and related entities
|
||||||
service AccountService {
|
service AccountService {
|
||||||
// Account Operations
|
// Account Operations
|
||||||
rpc GetAccount(GetAccountRequest) returns (Account) {}
|
rpc GetAccount(GetAccountRequest) returns (Account) {}
|
||||||
rpc GetBotAccount(GetBotAccountRequest) returns (Account) {}
|
rpc GetBotAccount(GetBotAccountRequest) returns (Account) {}
|
||||||
rpc GetAccountBatch(GetAccountBatchRequest) returns (GetAccountBatchResponse) {}
|
rpc GetAccountBatch(GetAccountBatchRequest) returns (GetAccountBatchResponse) {}
|
||||||
rpc GetBotAccountBatch(GetBotAccountBatchRequest) returns (GetAccountBatchResponse) {}
|
rpc GetBotAccountBatch(GetBotAccountBatchRequest) returns (GetAccountBatchResponse) {}
|
||||||
rpc LookupAccountBatch(LookupAccountBatchRequest) returns (GetAccountBatchResponse) {}
|
rpc LookupAccountBatch(LookupAccountBatchRequest) returns (GetAccountBatchResponse) {}
|
||||||
rpc ListAccounts(ListAccountsRequest) returns (ListAccountsResponse) {}
|
rpc SearchAccount(SearchAccountRequest) returns (GetAccountBatchResponse) {}
|
||||||
|
rpc ListAccounts(ListAccountsRequest) returns (ListAccountsResponse) {}
|
||||||
|
|
||||||
rpc GetAccountStatus(GetAccountRequest) returns (AccountStatus) {}
|
rpc GetAccountStatus(GetAccountRequest) returns (AccountStatus) {}
|
||||||
rpc GetAccountStatusBatch(GetAccountBatchRequest) returns (GetAccountStatusBatchResponse) {}
|
rpc GetAccountStatusBatch(GetAccountBatchRequest) returns (GetAccountStatusBatchResponse) {}
|
||||||
|
|
||||||
// Profile Operations
|
// Profile Operations
|
||||||
rpc GetProfile(GetProfileRequest) returns (AccountProfile) {}
|
rpc GetProfile(GetProfileRequest) returns (AccountProfile) {}
|
||||||
|
|
||||||
// Contact Operations
|
// Contact Operations
|
||||||
rpc ListContacts(ListContactsRequest) returns (ListContactsResponse) {}
|
rpc ListContacts(ListContactsRequest) returns (ListContactsResponse) {}
|
||||||
|
|
||||||
// Badge Operations
|
// Badge Operations
|
||||||
rpc ListBadges(ListBadgesRequest) returns (ListBadgesResponse) {}
|
rpc ListBadges(ListBadgesRequest) returns (ListBadgesResponse) {}
|
||||||
|
|
||||||
// Authentication Factor Operations
|
// Authentication Factor Operations
|
||||||
rpc ListAuthFactors(ListAuthFactorsRequest) returns (ListAuthFactorsResponse) {}
|
rpc ListAuthFactors(ListAuthFactorsRequest) returns (ListAuthFactorsResponse) {}
|
||||||
|
|
||||||
// Connection Operations
|
// Connection Operations
|
||||||
rpc ListConnections(ListConnectionsRequest) returns (ListConnectionsResponse) {}
|
rpc ListConnections(ListConnectionsRequest) returns (ListConnectionsResponse) {}
|
||||||
|
|
||||||
// Relationship Operations
|
// Relationship Operations
|
||||||
rpc ListRelationships(ListRelationshipsRequest) returns (ListRelationshipsResponse) {}
|
rpc ListRelationships(ListRelationshipsRequest) returns (ListRelationshipsResponse) {}
|
||||||
|
|
||||||
rpc GetRelationship(GetRelationshipRequest) returns (GetRelationshipResponse) {}
|
rpc GetRelationship(GetRelationshipRequest) returns (GetRelationshipResponse) {}
|
||||||
rpc HasRelationship(GetRelationshipRequest) returns (google.protobuf.BoolValue) {}
|
rpc HasRelationship(GetRelationshipRequest) returns (google.protobuf.BoolValue) {}
|
||||||
rpc ListFriends(ListRelationshipSimpleRequest) returns (ListRelationshipSimpleResponse) {}
|
rpc ListFriends(ListRelationshipSimpleRequest) returns (ListRelationshipSimpleResponse) {}
|
||||||
rpc ListBlocked(ListRelationshipSimpleRequest) returns (ListRelationshipSimpleResponse) {}
|
rpc ListBlocked(ListRelationshipSimpleRequest) returns (ListRelationshipSimpleResponse) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionLogService provides operations for action logs
|
// ActionLogService provides operations for action logs
|
||||||
service ActionLogService {
|
service ActionLogService {
|
||||||
rpc CreateActionLog(CreateActionLogRequest) returns (CreateActionLogResponse) {}
|
rpc CreateActionLog(CreateActionLogRequest) returns (CreateActionLogResponse) {}
|
||||||
rpc ListActionLogs(ListActionLogsRequest) returns (ListActionLogsResponse) {}
|
rpc ListActionLogs(ListActionLogsRequest) returns (ListActionLogsResponse) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====================================
|
// ====================================
|
||||||
@@ -295,184 +296,188 @@ service ActionLogService {
|
|||||||
|
|
||||||
// ActionLog Requests/Responses
|
// ActionLog Requests/Responses
|
||||||
message CreateActionLogRequest {
|
message CreateActionLogRequest {
|
||||||
string action = 1;
|
string action = 1;
|
||||||
map<string, google.protobuf.Value> meta = 2;
|
map<string, google.protobuf.Value> meta = 2;
|
||||||
google.protobuf.StringValue user_agent = 3;
|
google.protobuf.StringValue user_agent = 3;
|
||||||
google.protobuf.StringValue ip_address = 4;
|
google.protobuf.StringValue ip_address = 4;
|
||||||
google.protobuf.StringValue location = 5;
|
google.protobuf.StringValue location = 5;
|
||||||
string account_id = 6;
|
string account_id = 6;
|
||||||
google.protobuf.StringValue session_id = 7;
|
google.protobuf.StringValue session_id = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateActionLogResponse {
|
message CreateActionLogResponse {
|
||||||
ActionLog action_log = 1;
|
ActionLog action_log = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListActionLogsRequest {
|
message ListActionLogsRequest {
|
||||||
string account_id = 1;
|
string account_id = 1;
|
||||||
string action = 2;
|
string action = 2;
|
||||||
int32 page_size = 3;
|
int32 page_size = 3;
|
||||||
string page_token = 4;
|
string page_token = 4;
|
||||||
string order_by = 5;
|
string order_by = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListActionLogsResponse {
|
message ListActionLogsResponse {
|
||||||
repeated ActionLog action_logs = 1;
|
repeated ActionLog action_logs = 1;
|
||||||
string next_page_token = 2;
|
string next_page_token = 2;
|
||||||
int32 total_size = 3;
|
int32 total_size = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Account Requests/Responses
|
// Account Requests/Responses
|
||||||
message GetAccountRequest {
|
message GetAccountRequest {
|
||||||
string id = 1; // Account ID to retrieve
|
string id = 1; // Account ID to retrieve
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetBotAccountRequest {
|
message GetBotAccountRequest {
|
||||||
string automated_id = 1;
|
string automated_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetAccountBatchRequest {
|
message GetAccountBatchRequest {
|
||||||
repeated string id = 1; // Account ID to retrieve
|
repeated string id = 1; // Account ID to retrieve
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetBotAccountBatchRequest {
|
message GetBotAccountBatchRequest {
|
||||||
repeated string automated_id = 1;
|
repeated string automated_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message LookupAccountBatchRequest {
|
message LookupAccountBatchRequest {
|
||||||
repeated string names = 1;
|
repeated string names = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SearchAccountRequest {
|
||||||
|
string query = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetAccountBatchResponse {
|
message GetAccountBatchResponse {
|
||||||
repeated Account accounts = 1; // List of accounts
|
repeated Account accounts = 1; // List of accounts
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateAccountRequest {
|
message CreateAccountRequest {
|
||||||
string name = 1; // Required: Unique username
|
string name = 1; // Required: Unique username
|
||||||
string nick = 2; // Optional: Display name
|
string nick = 2; // Optional: Display name
|
||||||
string language = 3; // Default language
|
string language = 3; // Default language
|
||||||
bool is_superuser = 4; // Admin flag
|
bool is_superuser = 4; // Admin flag
|
||||||
AccountProfile profile = 5; // Initial profile data
|
AccountProfile profile = 5; // Initial profile data
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateAccountRequest {
|
message UpdateAccountRequest {
|
||||||
string id = 1; // Account ID to update
|
string id = 1; // Account ID to update
|
||||||
google.protobuf.StringValue name = 2; // New username if changing
|
google.protobuf.StringValue name = 2; // New username if changing
|
||||||
google.protobuf.StringValue nick = 3; // New display name
|
google.protobuf.StringValue nick = 3; // New display name
|
||||||
google.protobuf.StringValue language = 4; // New language
|
google.protobuf.StringValue language = 4; // New language
|
||||||
google.protobuf.BoolValue is_superuser = 5; // Admin status
|
google.protobuf.BoolValue is_superuser = 5; // Admin status
|
||||||
}
|
}
|
||||||
|
|
||||||
message DeleteAccountRequest {
|
message DeleteAccountRequest {
|
||||||
string id = 1; // Account ID to delete
|
string id = 1; // Account ID to delete
|
||||||
bool purge = 2; // If true, permanently delete instead of soft delete
|
bool purge = 2; // If true, permanently delete instead of soft delete
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListAccountsRequest {
|
message ListAccountsRequest {
|
||||||
int32 page_size = 1; // Number of results per page
|
int32 page_size = 1; // Number of results per page
|
||||||
string page_token = 2; // Token for pagination
|
string page_token = 2; // Token for pagination
|
||||||
string filter = 3; // Filter expression
|
string filter = 3; // Filter expression
|
||||||
string order_by = 4; // Sort order
|
string order_by = 4; // Sort order
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListAccountsResponse {
|
message ListAccountsResponse {
|
||||||
repeated Account accounts = 1; // List of accounts
|
repeated Account accounts = 1; // List of accounts
|
||||||
string next_page_token = 2; // Token for next page
|
string next_page_token = 2; // Token for next page
|
||||||
int32 total_size = 3; // Total number of accounts
|
int32 total_size = 3; // Total number of accounts
|
||||||
}
|
}
|
||||||
|
|
||||||
// Profile Requests/Responses
|
// Profile Requests/Responses
|
||||||
message GetProfileRequest {
|
message GetProfileRequest {
|
||||||
string account_id = 1; // Account ID to get profile for
|
string account_id = 1; // Account ID to get profile for
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateProfileRequest {
|
message UpdateProfileRequest {
|
||||||
string account_id = 1; // Account ID to update profile for
|
string account_id = 1; // Account ID to update profile for
|
||||||
AccountProfile profile = 2; // Profile data to update
|
AccountProfile profile = 2; // Profile data to update
|
||||||
google.protobuf.FieldMask update_mask = 3; // Fields to update
|
google.protobuf.FieldMask update_mask = 3; // Fields to update
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contact Requests/Responses
|
// Contact Requests/Responses
|
||||||
message AddContactRequest {
|
message AddContactRequest {
|
||||||
string account_id = 1; // Account to add contact to
|
string account_id = 1; // Account to add contact to
|
||||||
AccountContactType type = 2; // Type of contact
|
AccountContactType type = 2; // Type of contact
|
||||||
string content = 3; // Contact content (email, phone, etc.)
|
string content = 3; // Contact content (email, phone, etc.)
|
||||||
bool is_primary = 4; // If this should be the primary contact
|
bool is_primary = 4; // If this should be the primary contact
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListContactsRequest {
|
message ListContactsRequest {
|
||||||
string account_id = 1; // Account ID to list contacts for
|
string account_id = 1; // Account ID to list contacts for
|
||||||
AccountContactType type = 2; // Optional: filter by type
|
AccountContactType type = 2; // Optional: filter by type
|
||||||
bool verified_only = 3; // Only return verified contacts
|
bool verified_only = 3; // Only return verified contacts
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListContactsResponse {
|
message ListContactsResponse {
|
||||||
repeated AccountContact contacts = 1; // List of contacts
|
repeated AccountContact contacts = 1; // List of contacts
|
||||||
}
|
}
|
||||||
|
|
||||||
message VerifyContactRequest {
|
message VerifyContactRequest {
|
||||||
string id = 1; // Contact ID to verify
|
string id = 1; // Contact ID to verify
|
||||||
string account_id = 2; // Account ID (for validation)
|
string account_id = 2; // Account ID (for validation)
|
||||||
string code = 3; // Verification code
|
string code = 3; // Verification code
|
||||||
}
|
}
|
||||||
|
|
||||||
// Badge Requests/Responses
|
// Badge Requests/Responses
|
||||||
message ListBadgesRequest {
|
message ListBadgesRequest {
|
||||||
string account_id = 1; // Account to list badges for
|
string account_id = 1; // Account to list badges for
|
||||||
string type = 2; // Optional: filter by type
|
string type = 2; // Optional: filter by type
|
||||||
bool active_only = 3; // Only return active (non-expired) badges
|
bool active_only = 3; // Only return active (non-expired) badges
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListBadgesResponse {
|
message ListBadgesResponse {
|
||||||
repeated AccountBadge badges = 1; // List of badges
|
repeated AccountBadge badges = 1; // List of badges
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListAuthFactorsRequest {
|
message ListAuthFactorsRequest {
|
||||||
string account_id = 1; // Account to list factors for
|
string account_id = 1; // Account to list factors for
|
||||||
bool active_only = 2; // Only return active (non-expired) factors
|
bool active_only = 2; // Only return active (non-expired) factors
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListAuthFactorsResponse {
|
message ListAuthFactorsResponse {
|
||||||
repeated AccountAuthFactor factors = 1; // List of auth factors
|
repeated AccountAuthFactor factors = 1; // List of auth factors
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListConnectionsRequest {
|
message ListConnectionsRequest {
|
||||||
string account_id = 1; // Account to list connections for
|
string account_id = 1; // Account to list connections for
|
||||||
string provider = 2; // Optional: filter by provider
|
string provider = 2; // Optional: filter by provider
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListConnectionsResponse {
|
message ListConnectionsResponse {
|
||||||
repeated AccountConnection connections = 1; // List of connections
|
repeated AccountConnection connections = 1; // List of connections
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relationship Requests/Responses
|
// Relationship Requests/Responses
|
||||||
message ListRelationshipsRequest {
|
message ListRelationshipsRequest {
|
||||||
string account_id = 1; // Account to list relationships for
|
string account_id = 1; // Account to list relationships for
|
||||||
optional int32 status = 2; // Filter by status
|
optional int32 status = 2; // Filter by status
|
||||||
int32 page_size = 5; // Number of results per page
|
int32 page_size = 5; // Number of results per page
|
||||||
string page_token = 6; // Token for pagination
|
string page_token = 6; // Token for pagination
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListRelationshipsResponse {
|
message ListRelationshipsResponse {
|
||||||
repeated Relationship relationships = 1; // List of relationships
|
repeated Relationship relationships = 1; // List of relationships
|
||||||
string next_page_token = 2; // Token for next page
|
string next_page_token = 2; // Token for next page
|
||||||
int32 total_size = 3; // Total number of relationships
|
int32 total_size = 3; // Total number of relationships
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetRelationshipRequest {
|
message GetRelationshipRequest {
|
||||||
string account_id = 1;
|
string account_id = 1;
|
||||||
string related_id = 2;
|
string related_id = 2;
|
||||||
optional int32 status = 3;
|
optional int32 status = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetRelationshipResponse {
|
message GetRelationshipResponse {
|
||||||
optional Relationship relationship = 1;
|
optional Relationship relationship = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListRelationshipSimpleRequest {
|
message ListRelationshipSimpleRequest {
|
||||||
string account_id = 1;
|
string account_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListRelationshipSimpleResponse {
|
message ListRelationshipSimpleResponse {
|
||||||
repeated string accounts_id = 1;
|
repeated string accounts_id = 1;
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,7 @@ public class AccountClientHelper(AccountService.AccountServiceClient accounts)
|
|||||||
var response = await accounts.GetAccountAsync(request);
|
var response = await accounts.GetAccountAsync(request);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Account> GetBotAccount(Guid automatedId)
|
public async Task<Account> GetBotAccount(Guid automatedId)
|
||||||
{
|
{
|
||||||
var request = new GetBotAccountRequest { AutomatedId = automatedId.ToString() };
|
var request = new GetBotAccountRequest { AutomatedId = automatedId.ToString() };
|
||||||
@@ -26,7 +26,14 @@ public class AccountClientHelper(AccountService.AccountServiceClient accounts)
|
|||||||
var response = await accounts.GetAccountBatchAsync(request);
|
var response = await accounts.GetAccountBatchAsync(request);
|
||||||
return response.Accounts.ToList();
|
return response.Accounts.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<List<Account>> SearchAccounts(string query)
|
||||||
|
{
|
||||||
|
var request = new SearchAccountRequest { Query = query };
|
||||||
|
var response = await accounts.SearchAccountAsync(request);
|
||||||
|
return response.Accounts.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<List<Account>> GetBotAccountBatch(List<Guid> automatedIds)
|
public async Task<List<Account>> GetBotAccountBatch(List<Guid> automatedIds)
|
||||||
{
|
{
|
||||||
var request = new GetBotAccountBatchRequest();
|
var request = new GetBotAccountBatchRequest();
|
||||||
|
@@ -1,10 +1,12 @@
|
|||||||
|
using DysonNetwork.Shared.Models;
|
||||||
|
using DysonNetwork.Shared.Registry;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace DysonNetwork.Sphere.Autocompletion;
|
namespace DysonNetwork.Sphere.Autocompletion;
|
||||||
|
|
||||||
public class AutocompletionService(AppDatabase db)
|
public class AutocompletionService(AppDatabase db, AccountClientHelper accountsHelper)
|
||||||
{
|
{
|
||||||
public async Task<List<DysonNetwork.Shared.Models.Autocompletion>> GetAutocompletion(string content, int limit = 10)
|
public async Task<List<DysonNetwork.Shared.Models.Autocompletion>> GetAutocompletion(string content, Guid? chatId = null, Guid? realmId = null, int limit = 10)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(content))
|
if (string.IsNullOrWhiteSpace(content))
|
||||||
return [];
|
return [];
|
||||||
@@ -14,7 +16,8 @@ public class AutocompletionService(AppDatabase db)
|
|||||||
var afterAt = content[1..];
|
var afterAt = content[1..];
|
||||||
string type;
|
string type;
|
||||||
string query;
|
string query;
|
||||||
if (afterAt.Contains('/'))
|
bool hadSlash = afterAt.Contains('/');
|
||||||
|
if (hadSlash)
|
||||||
{
|
{
|
||||||
var parts = afterAt.Split('/', 2);
|
var parts = afterAt.Split('/', 2);
|
||||||
type = parts[0];
|
type = parts[0];
|
||||||
@@ -25,7 +28,8 @@ public class AutocompletionService(AppDatabase db)
|
|||||||
type = "u";
|
type = "u";
|
||||||
query = afterAt;
|
query = afterAt;
|
||||||
}
|
}
|
||||||
return await AutocompleteAt(type, query, limit);
|
|
||||||
|
return await AutocompleteAt(type, query, chatId, realmId, hadSlash, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!content.StartsWith(':')) return [];
|
if (!content.StartsWith(':')) return [];
|
||||||
@@ -33,15 +37,49 @@ public class AutocompletionService(AppDatabase db)
|
|||||||
var query = content[1..];
|
var query = content[1..];
|
||||||
return await AutocompleteSticker(query, limit);
|
return await AutocompleteSticker(query, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<List<DysonNetwork.Shared.Models.Autocompletion>> AutocompleteAt(string type, string query, int limit)
|
private async Task<List<DysonNetwork.Shared.Models.Autocompletion>> AutocompleteAt(string type, string query, Guid? chatId, Guid? realmId, bool hadSlash,
|
||||||
|
int limit)
|
||||||
{
|
{
|
||||||
var results = new List<DysonNetwork.Shared.Models.Autocompletion>();
|
var results = new List<DysonNetwork.Shared.Models.Autocompletion>();
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
case "u":
|
||||||
|
var allAccounts = await accountsHelper.SearchAccounts(query);
|
||||||
|
var filteredAccounts = allAccounts;
|
||||||
|
|
||||||
|
if (chatId.HasValue)
|
||||||
|
{
|
||||||
|
var chatMemberIds = await db.ChatMembers
|
||||||
|
.Where(m => m.ChatRoomId == chatId.Value && m.JoinedAt != null && m.LeaveAt == null)
|
||||||
|
.Select(m => m.AccountId)
|
||||||
|
.ToListAsync();
|
||||||
|
var chatMemberIdStrings = chatMemberIds.Select(id => id.ToString()).ToHashSet();
|
||||||
|
filteredAccounts = allAccounts.Where(a => chatMemberIdStrings.Contains(a.Id)).ToList();
|
||||||
|
}
|
||||||
|
else if (realmId.HasValue)
|
||||||
|
{
|
||||||
|
var realmMemberIds = await db.RealmMembers
|
||||||
|
.Where(m => m.RealmId == realmId.Value && m.LeaveAt == null)
|
||||||
|
.Select(m => m.AccountId)
|
||||||
|
.ToListAsync();
|
||||||
|
var realmMemberIdStrings = realmMemberIds.Select(id => id.ToString()).ToHashSet();
|
||||||
|
filteredAccounts = allAccounts.Where(a => realmMemberIdStrings.Contains(a.Id)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
var users = filteredAccounts
|
||||||
|
.Take(limit)
|
||||||
|
.Select(a => new DysonNetwork.Shared.Models.Autocompletion
|
||||||
|
{
|
||||||
|
Type = "user",
|
||||||
|
Keyword = "@" + (hadSlash ? "u/" : "") + a.Name,
|
||||||
|
Data = SnAccount.FromProtoValue(a)
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
results.AddRange(users);
|
||||||
|
break;
|
||||||
case "p":
|
case "p":
|
||||||
var publishers = await db.Publishers
|
var publishers = await db.Publishers
|
||||||
.Where(p => EF.Functions.Like(p.Name, $"{query}%") || EF.Functions.Like(p.Nick, $"{query}%"))
|
.Where(p => EF.Functions.Like(p.Name, $"{query}%") || EF.Functions.Like(p.Nick, $"{query}%"))
|
||||||
@@ -49,7 +87,7 @@ public class AutocompletionService(AppDatabase db)
|
|||||||
.Select(p => new DysonNetwork.Shared.Models.Autocompletion
|
.Select(p => new DysonNetwork.Shared.Models.Autocompletion
|
||||||
{
|
{
|
||||||
Type = "publisher",
|
Type = "publisher",
|
||||||
Keyword = p.Name,
|
Keyword = "@p/" + p.Name,
|
||||||
Data = p
|
Data = p
|
||||||
})
|
})
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
@@ -63,7 +101,7 @@ public class AutocompletionService(AppDatabase db)
|
|||||||
.Select(r => new DysonNetwork.Shared.Models.Autocompletion
|
.Select(r => new DysonNetwork.Shared.Models.Autocompletion
|
||||||
{
|
{
|
||||||
Type = "realm",
|
Type = "realm",
|
||||||
Keyword = r.Slug,
|
Keyword = "@r/" + r.Slug,
|
||||||
Data = r
|
Data = r
|
||||||
})
|
})
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
@@ -77,7 +115,7 @@ public class AutocompletionService(AppDatabase db)
|
|||||||
.Select(c => new DysonNetwork.Shared.Models.Autocompletion
|
.Select(c => new DysonNetwork.Shared.Models.Autocompletion
|
||||||
{
|
{
|
||||||
Type = "chat",
|
Type = "chat",
|
||||||
Keyword = c.Name!,
|
Keyword = "@c/" + c.Name,
|
||||||
Data = c
|
Data = c
|
||||||
})
|
})
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
@@ -332,7 +332,7 @@ public partial class ChatController(
|
|||||||
return Ok(response);
|
return Ok(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{roomId:guid}/autocomplete")]
|
[HttpPost("{roomId:guid}/autocomplete")]
|
||||||
public async Task<ActionResult<List<DysonNetwork.Shared.Models.Autocompletion>>> ChatAutoComplete([FromBody] AutocompletionRequest request, Guid roomId)
|
public async Task<ActionResult<List<DysonNetwork.Shared.Models.Autocompletion>>> ChatAutoComplete([FromBody] AutocompletionRequest request, Guid roomId)
|
||||||
{
|
{
|
||||||
if (HttpContext.Items["CurrentUser"] is not Account currentUser)
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser)
|
||||||
@@ -344,7 +344,7 @@ public partial class ChatController(
|
|||||||
if (!isMember)
|
if (!isMember)
|
||||||
return StatusCode(403, "You are not a member of this chat room.");
|
return StatusCode(403, "You are not a member of this chat room.");
|
||||||
|
|
||||||
var result = await aus.GetAutocompletion(request.Content, limit: 10);
|
var result = await aus.GetAutocompletion(request.Content, chatId: roomId, limit: 10);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@ builder.ConfigureAppKestrel(builder.Configuration);
|
|||||||
|
|
||||||
// Add application services
|
// Add application services
|
||||||
|
|
||||||
builder.Services.AddAppServices(builder.Configuration);
|
builder.Services.AddAppServices();
|
||||||
builder.Services.AddAppRateLimiting();
|
builder.Services.AddAppRateLimiting();
|
||||||
builder.Services.AddAppAuthentication();
|
builder.Services.AddAppAuthentication();
|
||||||
builder.Services.AddDysonAuth();
|
builder.Services.AddDysonAuth();
|
||||||
|
@@ -282,9 +282,9 @@ public class PublisherService(
|
|||||||
public int SubscribersCount { get; set; }
|
public int SubscribersCount { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private const string PublisherStatsCacheKey = "PublisherStats_{0}";
|
private const string PublisherStatsCacheKey = "publisher:{0}:stats";
|
||||||
private const string PublisherHeatmapCacheKey = "PublisherHeatmap_{0}";
|
private const string PublisherHeatmapCacheKey = "publisher:{0}:heatmap";
|
||||||
private const string PublisherFeatureCacheKey = "PublisherFeature_{0}_{1}";
|
private const string PublisherFeatureCacheKey = "publisher:{0}:feature:{1}";
|
||||||
|
|
||||||
public async Task<PublisherStats?> GetPublisherStats(string name)
|
public async Task<PublisherStats?> GetPublisherStats(string name)
|
||||||
{
|
{
|
||||||
@@ -329,7 +329,7 @@ public class PublisherService(
|
|||||||
public async Task<ActivityHeatmap?> GetPublisherHeatmap(string name)
|
public async Task<ActivityHeatmap?> GetPublisherHeatmap(string name)
|
||||||
{
|
{
|
||||||
var cacheKey = string.Format(PublisherHeatmapCacheKey, name);
|
var cacheKey = string.Format(PublisherHeatmapCacheKey, name);
|
||||||
var heatmap = await cache.GetAsync<ActivityHeatmap>(cacheKey);
|
var heatmap = await cache.GetAsync<ActivityHeatmap?>(cacheKey);
|
||||||
if (heatmap is not null)
|
if (heatmap is not null)
|
||||||
return heatmap;
|
return heatmap;
|
||||||
|
|
||||||
|
@@ -15,6 +15,7 @@ using System.Text.Json.Serialization;
|
|||||||
using System.Threading.RateLimiting;
|
using System.Threading.RateLimiting;
|
||||||
using DysonNetwork.Shared.Cache;
|
using DysonNetwork.Shared.Cache;
|
||||||
using DysonNetwork.Shared.GeoIp;
|
using DysonNetwork.Shared.GeoIp;
|
||||||
|
using DysonNetwork.Shared.Registry;
|
||||||
using DysonNetwork.Sphere.Autocompletion;
|
using DysonNetwork.Sphere.Autocompletion;
|
||||||
using DysonNetwork.Sphere.WebReader;
|
using DysonNetwork.Sphere.WebReader;
|
||||||
using DysonNetwork.Sphere.Discovery;
|
using DysonNetwork.Sphere.Discovery;
|
||||||
@@ -25,7 +26,7 @@ namespace DysonNetwork.Sphere.Startup;
|
|||||||
|
|
||||||
public static class ServiceCollectionExtensions
|
public static class ServiceCollectionExtensions
|
||||||
{
|
{
|
||||||
public static IServiceCollection AddAppServices(this IServiceCollection services, IConfiguration configuration)
|
public static IServiceCollection AddAppServices(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddLocalization(options => options.ResourcesPath = "Resources");
|
services.AddLocalization(options => options.ResourcesPath = "Resources");
|
||||||
|
|
||||||
@@ -119,6 +120,7 @@ public static class ServiceCollectionExtensions
|
|||||||
services.AddScoped<WebFeedService>();
|
services.AddScoped<WebFeedService>();
|
||||||
services.AddScoped<DiscoveryService>();
|
services.AddScoped<DiscoveryService>();
|
||||||
services.AddScoped<PollService>();
|
services.AddScoped<PollService>();
|
||||||
|
services.AddScoped<AccountClientHelper>();
|
||||||
services.AddScoped<AutocompletionService>();
|
services.AddScoped<AutocompletionService>();
|
||||||
|
|
||||||
var translationProvider = configuration["Translation:Provider"]?.ToLower();
|
var translationProvider = configuration["Translation:Provider"]?.ToLower();
|
||||||
|
Reference in New Issue
Block a user