diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 11bb4802f8..99cb27f931 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -183,7 +183,7 @@ dependencies = [ [[package]] name = "appflowy-cloud-billing-client" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud-Billing-Client?rev=c608c4ec97bae19bad212742eeb4e3475845742a#c608c4ec97bae19bad212742eeb4e3475845742a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud-Billing-Client?rev=f14a7964d27c87ea21c5f361a92fc11a5a4f88f8#f14a7964d27c87ea21c5f361a92fc11a5a4f88f8" dependencies = [ "client-api", "reqwest", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 667ccaddd1..9f944ba7ab 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -91,7 +91,7 @@ yrs = "0.18.7" # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ef8e6f3" } -appflowy-cloud-billing-client = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud-Billing-Client", rev = "c608c4ec97bae19bad212742eeb4e3475845742a" } +appflowy-cloud-billing-client = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud-Billing-Client", rev = "f14a7964d27c87ea21c5f361a92fc11a5a4f88f8" } [profile.dev] opt-level = 1 diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs index 5b66485b1b..6b406ba2a3 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs @@ -24,7 +24,7 @@ use flowy_user_pub::cloud::{UserCloudService, UserCollabParams, UserUpdate, User use flowy_user_pub::entities::{ AFCloudOAuthParams, AuthResponse, Role, UpdateUserProfileParams, UserCredentials, UserProfile, UserWorkspace, WorkspaceInvitation, WorkspaceInvitationStatus, WorkspaceMember, - WorkspaceSubscription, + WorkspaceSubscription, WorkspaceUsage, }; use lib_infra::box_any::BoxAny; use lib_infra::future::FutureResult; @@ -526,6 +526,21 @@ where Ok(()) }) } + + fn get_workspace_usage(&self, workspace_id: String) -> FutureResult { + let try_get_client = self.server.try_get_client(); + FutureResult::new(async move { + let client = try_get_client?; + let usage = + WorkspaceSubscriptionClient::get_workspace_usage(client.as_ref(), &workspace_id).await?; + Ok(WorkspaceUsage { + member_count: usage.member_count, + member_count_limit: usage.member_count_limit, + total_blob_bytes: usage.total_blob_bytes, + total_blob_bytes_limit: usage.total_blob_bytes_limit, + }) + }) + } } async fn get_admin_client(client: &Arc) -> FlowyResult { diff --git a/frontend/rust-lib/flowy-user-pub/src/cloud.rs b/frontend/rust-lib/flowy-user-pub/src/cloud.rs index cde3e32187..7d56bd4d16 100644 --- a/frontend/rust-lib/flowy-user-pub/src/cloud.rs +++ b/frontend/rust-lib/flowy-user-pub/src/cloud.rs @@ -15,7 +15,7 @@ use uuid::Uuid; use crate::entities::{ AuthResponse, Authenticator, RecurringInterval, Role, SubscriptionPlan, UpdateUserProfileParams, UserCredentials, UserProfile, UserTokenState, UserWorkspace, WorkspaceInvitation, - WorkspaceInvitationStatus, WorkspaceMember, WorkspaceSubscription, + WorkspaceInvitationStatus, WorkspaceMember, WorkspaceSubscription, WorkspaceUsage, }; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -285,6 +285,10 @@ pub trait UserCloudService: Send + Sync + 'static { fn cancel_workspace_subscription(&self, workspace_id: String) -> FutureResult<(), FlowyError> { FutureResult::new(async { Err(FlowyError::not_support()) }) } + + fn get_workspace_usage(&self, workspace_id: String) -> FutureResult { + FutureResult::new(async { Err(FlowyError::not_support()) }) + } } pub type UserUpdateReceiver = tokio::sync::mpsc::Receiver; diff --git a/frontend/rust-lib/flowy-user-pub/src/entities.rs b/frontend/rust-lib/flowy-user-pub/src/entities.rs index e63eae7255..0d01f47eb5 100644 --- a/frontend/rust-lib/flowy-user-pub/src/entities.rs +++ b/frontend/rust-lib/flowy-user-pub/src/entities.rs @@ -439,3 +439,10 @@ pub struct WorkspaceSubscription { pub recurring_interval: RecurringInterval, pub is_active: bool, } + +pub struct WorkspaceUsage { + pub member_count: usize, + pub member_count_limit: usize, + pub total_blob_bytes: usize, + pub total_blob_bytes_limit: usize, +} diff --git a/frontend/rust-lib/flowy-user/src/entities/workspace.rs b/frontend/rust-lib/flowy-user/src/entities/workspace.rs index 0c9ec1a6da..c723c04c71 100644 --- a/frontend/rust-lib/flowy-user/src/entities/workspace.rs +++ b/frontend/rust-lib/flowy-user/src/entities/workspace.rs @@ -306,3 +306,15 @@ impl From for WorkspaceSubscriptionPB { } } } + +#[derive(Debug, ProtoBuf, Default, Clone)] +pub struct WorkspaceUsagePB { + #[pb(index = 1)] + pub member_count: u64, + #[pb(index = 2)] + pub member_count_limit: u64, + #[pb(index = 3)] + pub total_blob_bytes: u64, + #[pb(index = 4)] + pub total_blob_bytes_limit: u64, +} diff --git a/frontend/rust-lib/flowy-user/src/event_handler.rs b/frontend/rust-lib/flowy-user/src/event_handler.rs index 78afee11fc..c8c90afaa1 100644 --- a/frontend/rust-lib/flowy-user/src/event_handler.rs +++ b/frontend/rust-lib/flowy-user/src/event_handler.rs @@ -810,3 +810,19 @@ pub async fn cancel_workspace_subscription_handler( manager.cancel_workspace_subscription(workspace_id).await?; Ok(()) } + +#[tracing::instrument(level = "debug", skip_all, err)] +pub async fn get_workspace_usage_handler( + param: AFPluginData, + manager: AFPluginState>, +) -> DataResult { + let workspace_id = param.into_inner().workspace_id; + let manager = upgrade_manager(manager)?; + let workspace_usage = manager.get_workspace_usage(workspace_id).await?; + data_result_ok(WorkspaceUsagePB { + member_count: workspace_usage.member_count as u64, + member_count_limit: workspace_usage.member_count_limit as u64, + total_blob_bytes: workspace_usage.total_blob_bytes as u64, + total_blob_bytes_limit: workspace_usage.total_blob_bytes_limit as u64, + }) +} diff --git a/frontend/rust-lib/flowy-user/src/event_map.rs b/frontend/rust-lib/flowy-user/src/event_map.rs index f1e62e2894..7f17bc54f9 100644 --- a/frontend/rust-lib/flowy-user/src/event_map.rs +++ b/frontend/rust-lib/flowy-user/src/event_map.rs @@ -75,6 +75,7 @@ pub fn init(user_manager: Weak) -> AFPlugin { .event(UserEvent::SubscribeWorkspace, subscribe_workspace_handler) .event(UserEvent::GetWorkspaceSubscriptions, get_workspace_subscriptions_handler) .event(UserEvent::CancelWorkspaceSubscription, cancel_workspace_subscription_handler) + .event(UserEvent::GetWorkspaceUsage, get_workspace_usage_handler) } #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] @@ -241,8 +242,11 @@ pub enum UserEvent { #[event(output = "RepeatedWorkspaceSubscriptionPB")] GetWorkspaceSubscriptions = 52, - #[event(output = "UserWorkspaceIdPB")] + #[event(input = "UserWorkspaceIdPB")] CancelWorkspaceSubscription = 53, + + #[event(input = "UserWorkspaceIdPB", output = "WorkspaceUsagePB")] + GetWorkspaceUsage = 54, } pub trait UserStatusCallback: Send + Sync + 'static { diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs index 54f6794cb6..fc067b4abc 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs @@ -11,7 +11,7 @@ use flowy_sqlite::schema::user_workspace_table; use flowy_sqlite::{query_dsl::*, DBConnection, ExpressionMethods}; use flowy_user_pub::entities::{ Role, UserWorkspace, WorkspaceInvitation, WorkspaceInvitationStatus, WorkspaceMember, - WorkspaceSubscription, + WorkspaceSubscription, WorkspaceUsage, }; use lib_dispatch::prelude::af_spawn; @@ -450,6 +450,16 @@ impl UserManager { .await?; Ok(()) } + + #[instrument(level = "info", skip(self), err)] + pub async fn get_workspace_usage(&self, workspace_id: String) -> FlowyResult { + let workspace_usage = self + .cloud_services + .get_user_service()? + .get_workspace_usage(workspace_id) + .await?; + Ok(workspace_usage) + } } /// This method is used to save one user workspace to the SQLite database