Переглянути джерело

refactor backend directory

appflowy 3 роки тому
батько
коміт
d9421f70a0
93 змінених файлів з 699 додано та 627 видалено
  1. 9 12
      backend/src/application.rs
  2. 12 12
      backend/src/context.rs
  3. 0 0
      backend/src/entities/logged_user.rs
  4. 1 1
      backend/src/entities/mod.rs
  5. 7 7
      backend/src/entities/token.rs
  6. 0 120
      backend/src/entities/workspace.rs
  7. 2 3
      backend/src/lib.rs
  8. 4 2
      backend/src/middleware/auth_middleware.rs
  9. 5 5
      backend/src/services/core/app/controller.rs
  10. 2 2
      backend/src/services/core/app/mod.rs
  11. 31 5
      backend/src/services/core/app/persistence.rs
  12. 17 14
      backend/src/services/core/app/router.rs
  13. 0 0
      backend/src/services/core/log.rs
  14. 5 0
      backend/src/services/core/mod.rs
  15. 1 0
      backend/src/services/core/trash/mod.rs
  16. 39 0
      backend/src/services/core/trash/persistence.rs
  17. 4 4
      backend/src/services/core/trash/router.rs
  18. 5 5
      backend/src/services/core/trash/trash.rs
  19. 5 8
      backend/src/services/core/view/controller.rs
  20. 6 0
      backend/src/services/core/view/mod.rs
  21. 33 5
      backend/src/services/core/view/persistence.rs
  22. 8 6
      backend/src/services/core/view/router.rs
  23. 7 4
      backend/src/services/core/workspace/controller.rs
  24. 6 0
      backend/src/services/core/workspace/mod.rs
  25. 24 4
      backend/src/services/core/workspace/persistence.rs
  26. 5 5
      backend/src/services/core/workspace/router.rs
  27. 0 65
      backend/src/services/doc/editor.rs
  28. 7 8
      backend/src/services/document/crud.rs
  29. 14 20
      backend/src/services/document/manager.rs
  30. 0 1
      backend/src/services/document/mod.rs
  31. 2 4
      backend/src/services/document/router.rs
  32. 66 18
      backend/src/services/document/ws_actor.rs
  33. 3 7
      backend/src/services/mod.rs
  34. 9 5
      backend/src/services/user/controller.rs
  35. 2 7
      backend/src/services/user/mod.rs
  36. 6 10
      backend/src/services/user/router.rs
  37. 0 49
      backend/src/services/user/user_default.rs
  38. 0 6
      backend/src/services/view/mod.rs
  39. 2 2
      backend/src/services/web_socket/entities/connect.rs
  40. 4 4
      backend/src/services/web_socket/entities/message.rs
  41. 0 0
      backend/src/services/web_socket/entities/mod.rs
  42. 0 2
      backend/src/services/web_socket/mod.rs
  43. 16 16
      backend/src/services/web_socket/router.rs
  44. 44 25
      backend/src/services/web_socket/ws_client.rs
  45. 14 14
      backend/src/services/web_socket/ws_server.rs
  46. 0 6
      backend/src/services/workspace/mod.rs
  47. 3 0
      backend/src/util/mod.rs
  48. 0 0
      backend/src/util/serde_ext.rs
  49. 0 0
      backend/src/util/sqlx_ext/mod.rs
  50. 0 0
      backend/src/util/sqlx_ext/query.rs
  51. 0 0
      backend/src/util/sqlx_ext/utils.rs
  52. 0 0
      backend/src/util/user_ext.rs
  53. 0 24
      backend/src/web_socket/biz_handler.rs
  54. 3 3
      backend/tests/document/edit_test.rs
  55. 1 1
      backend/tests/util/helper.rs
  56. 4 0
      frontend/rust-lib/dart-ffi/src/protobuf/document
  57. 8 0
      frontend/rust-lib/dart-ffi/src/protobuf/model/document
  58. 4 0
      frontend/rust-lib/dart-notify/src/protobuf/document
  59. 5 0
      frontend/rust-lib/dart-notify/src/protobuf/model/document
  60. 4 0
      frontend/rust-lib/flowy-core/src/protobuf/document
  61. 8 0
      frontend/rust-lib/flowy-core/src/protobuf/model/document
  62. 4 0
      frontend/rust-lib/flowy-document/src/protobuf/document
  63. 5 0
      frontend/rust-lib/flowy-document/src/protobuf/model/document
  64. 2 2
      frontend/rust-lib/flowy-document/src/services/controller.rs
  65. 4 4
      frontend/rust-lib/flowy-document/src/services/doc/web_socket/web_socket.rs
  66. 1 1
      frontend/rust-lib/flowy-document/src/services/file/manager.rs
  67. 1 1
      frontend/rust-lib/flowy-document/src/services/server/middleware.rs
  68. 4 0
      frontend/rust-lib/flowy-error/src/protobuf/document
  69. 5 0
      frontend/rust-lib/flowy-error/src/protobuf/model/document
  70. 4 0
      frontend/rust-lib/flowy-net/src/protobuf/document
  71. 8 0
      frontend/rust-lib/flowy-net/src/protobuf/model/document
  72. 1 1
      frontend/rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs
  73. 4 0
      frontend/rust-lib/flowy-user/src/protobuf/document
  74. 8 0
      frontend/rust-lib/flowy-user/src/protobuf/model/document
  75. 2 2
      frontend/scripts/flowy-tool/src/proto/proto_info.rs
  76. 1 1
      shared-lib/backend-service/src/configuration.rs
  77. 4 0
      shared-lib/error-code/src/protobuf/document
  78. 5 0
      shared-lib/error-code/src/protobuf/model/document
  79. 2 5
      shared-lib/flowy-collaboration/src/core/sync/server_editor.rs
  80. 2 3
      shared-lib/flowy-collaboration/src/entities/doc/doc.rs
  81. 2 2
      shared-lib/flowy-collaboration/src/entities/ws/ws.rs
  82. 50 50
      shared-lib/flowy-collaboration/src/protobuf/model/doc.rs
  83. 32 32
      shared-lib/flowy-collaboration/src/protobuf/model/ws.rs
  84. 0 1
      shared-lib/flowy-collaboration/src/protobuf/proto/doc.proto
  85. 0 1
      shared-lib/flowy-collaboration/src/protobuf/proto/ws.proto
  86. 4 0
      shared-lib/flowy-core-data-model/src/protobuf/document
  87. 41 0
      shared-lib/flowy-core-data-model/src/protobuf/model/document
  88. 4 0
      shared-lib/flowy-user-data-model/src/protobuf/document
  89. 11 0
      shared-lib/flowy-user-data-model/src/protobuf/model/document
  90. 4 0
      shared-lib/lib-ot/src/protobuf/document
  91. 5 0
      shared-lib/lib-ot/src/protobuf/model/document
  92. 4 0
      shared-lib/lib-ws/src/protobuf/document
  93. 8 0
      shared-lib/lib-ws/src/protobuf/model/document

+ 9 - 12
backend/src/application.rs

@@ -13,14 +13,11 @@ use crate::{
     },
     context::AppContext,
     services::{
-        app::router as app,
-        doc::router as doc,
-        trash::router as trash,
+        core::{app::router as app, trash::router as trash, view::router as view, workspace::router as workspace},
+        document::router as doc,
         user::router as user,
-        view::router as view,
-        workspace::router as workspace,
+        web_socket::WSServer,
     },
-    web_socket::WsServer,
 };
 
 pub struct Application {
@@ -58,8 +55,8 @@ pub fn run(listener: TcpListener, app_ctx: AppContext) -> Result<Server, std::io
             .service(user_scope())
             .app_data(app_ctx.ws_server.clone())
             .app_data(app_ctx.pg_pool.clone())
-            .app_data(app_ctx.ws_bizs.clone())
-            .app_data(app_ctx.document_core.clone())
+            .app_data(app_ctx.ws_receivers.clone())
+            .app_data(app_ctx.document_mng.clone())
     })
     .listen(listener)?
     .run();
@@ -73,7 +70,7 @@ async fn period_check(_pool: Data<PgPool>) {
     }
 }
 
-fn ws_scope() -> Scope { web::scope("/ws").service(crate::web_socket::router::establish_ws_connection) }
+fn ws_scope() -> Scope { web::scope("/ws").service(crate::services::web_socket::router::establish_ws_connection) }
 
 fn user_scope() -> Scope {
     // https://developer.mozilla.org/en-US/docs/Web/HTTP
@@ -112,7 +109,7 @@ fn user_scope() -> Scope {
             .route(web::get().to(view::read_handler))
             .route(web::patch().to(view::update_handler))
         )
-        .service(web::resource("/doc")
+        .service(web::resource("/document")
             .route(web::post().to(doc::create_handler))
             .route(web::get().to(doc::read_handler))
             .route(web::patch().to(doc::update_handler))
@@ -132,14 +129,14 @@ fn user_scope() -> Scope {
 }
 
 pub async fn init_app_context(configuration: &Settings) -> AppContext {
-    let _ = crate::services::log::Builder::new("flowy-server")
+    let _ = crate::services::core::log::Builder::new("flowy-server")
         .env_filter("Trace")
         .build();
     let pg_pool = get_connection_pool(&configuration.database)
         .await
         .unwrap_or_else(|_| panic!("Failed to connect to Postgres at {:?}.", configuration.database));
 
-    let ws_server = WsServer::new().start();
+    let ws_server = WSServer::new().start();
     AppContext::new(ws_server, pg_pool)
 }
 

+ 12 - 12
backend/src/context.rs

@@ -1,6 +1,6 @@
-use crate::{
-    services::doc::manager::DocumentCore,
-    web_socket::{WsBizHandlers, WsServer},
+use crate::services::{
+    document::manager::DocumentManager,
+    web_socket::{WSServer, WebSocketReceivers},
 };
 use actix::Addr;
 use actix_web::web::Data;
@@ -10,26 +10,26 @@ use std::sync::Arc;
 
 #[derive(Clone)]
 pub struct AppContext {
-    pub ws_server: Data<Addr<WsServer>>,
+    pub ws_server: Data<Addr<WSServer>>,
     pub pg_pool: Data<PgPool>,
-    pub ws_bizs: Data<WsBizHandlers>,
-    pub document_core: Data<Arc<DocumentCore>>,
+    pub ws_receivers: Data<WebSocketReceivers>,
+    pub document_mng: Data<Arc<DocumentManager>>,
 }
 
 impl AppContext {
-    pub fn new(ws_server: Addr<WsServer>, db_pool: PgPool) -> Self {
+    pub fn new(ws_server: Addr<WSServer>, db_pool: PgPool) -> Self {
         let ws_server = Data::new(ws_server);
         let pg_pool = Data::new(db_pool);
 
-        let mut ws_bizs = WsBizHandlers::new();
-        let document_core = Arc::new(DocumentCore::new(pg_pool.clone()));
-        ws_bizs.register(WSModule::Doc, document_core.clone());
+        let mut ws_receivers = WebSocketReceivers::new();
+        let document_mng = Arc::new(DocumentManager::new(pg_pool.clone()));
+        ws_receivers.set(WSModule::Doc, document_mng.clone());
 
         AppContext {
             ws_server,
             pg_pool,
-            ws_bizs: Data::new(ws_bizs),
-            document_core: Data::new(document_core),
+            ws_receivers: Data::new(ws_receivers),
+            document_mng: Data::new(document_mng),
         }
     }
 }

+ 0 - 0
backend/src/services/user/logged_user.rs → backend/src/entities/logged_user.rs


+ 1 - 1
backend/src/entities/mod.rs

@@ -1,4 +1,4 @@
 pub mod doc;
+pub mod logged_user;
 pub mod token;
 pub mod user;
-pub mod workspace;

+ 7 - 7
backend/src/entities/token.rs

@@ -1,7 +1,12 @@
-use crate::config::env::{domain, jwt_secret};
-use backend_service::errors::ServerError;
+use crate::{
+    config::env::{domain, jwt_secret},
+    entities::logged_user::EXPIRED_DURATION_DAYS,
+};
+use actix_web::{dev::Payload, FromRequest, HttpRequest};
+use backend_service::{configuration::HEADER_TOKEN, errors::ServerError};
 use chrono::{Duration, Local};
 use derive_more::{From, Into};
+use futures::future::{ready, Ready};
 use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};
 use serde::{Deserialize, Serialize};
 
@@ -74,11 +79,6 @@ impl Token {
     }
 }
 
-use crate::services::user::EXPIRED_DURATION_DAYS;
-use actix_web::{dev::Payload, FromRequest, HttpRequest};
-use backend_service::configuration::HEADER_TOKEN;
-use futures::future::{ready, Ready};
-
 impl FromRequest for Token {
     type Error = ServerError;
     type Future = Ready<Result<Self, Self::Error>>;

+ 0 - 120
backend/src/entities/workspace.rs

@@ -1,120 +0,0 @@
-use chrono::Utc;
-use flowy_core_data_model::protobuf::{App, RepeatedView, Trash, TrashType, View, ViewType, Workspace};
-use protobuf::ProtobufEnum;
-
-pub(crate) const WORKSPACE_TABLE: &str = "workspace_table";
-pub(crate) const APP_TABLE: &str = "app_table";
-pub(crate) const VIEW_TABLE: &str = "view_table";
-pub(crate) const TRASH_TABLE: &str = "trash_table";
-
-#[derive(Debug, Clone, sqlx::FromRow)]
-pub struct WorkspaceTable {
-    pub(crate) id: uuid::Uuid,
-    pub(crate) name: String,
-    pub(crate) description: String,
-    pub(crate) modified_time: chrono::DateTime<Utc>,
-    pub(crate) create_time: chrono::DateTime<Utc>,
-    pub(crate) user_id: String,
-}
-impl std::convert::From<WorkspaceTable> for Workspace {
-    fn from(table: WorkspaceTable) -> Self {
-        let mut workspace = Workspace::default();
-        workspace.set_id(table.id.to_string());
-        workspace.set_name(table.name.clone());
-        workspace.set_desc(table.description.clone());
-        workspace.set_modified_time(table.modified_time.timestamp());
-        workspace.set_create_time(table.create_time.timestamp());
-        workspace
-    }
-}
-
-#[derive(Debug, Clone, sqlx::FromRow)]
-pub struct AppTable {
-    pub(crate) id: uuid::Uuid,
-    pub(crate) workspace_id: String,
-    pub(crate) name: String,
-    pub(crate) description: String,
-    pub(crate) color_style: Vec<u8>,
-    pub(crate) last_view_id: String,
-    pub(crate) modified_time: chrono::DateTime<Utc>,
-    pub(crate) create_time: chrono::DateTime<Utc>,
-    pub(crate) user_id: String,
-}
-impl std::convert::From<AppTable> for App {
-    fn from(table: AppTable) -> Self {
-        let mut app = App::default();
-        app.set_id(table.id.to_string());
-        app.set_workspace_id(table.workspace_id.to_string());
-        app.set_name(table.name.clone());
-        app.set_desc(table.description.clone());
-        app.set_belongings(RepeatedView::default());
-        app.set_modified_time(table.modified_time.timestamp());
-        app.set_create_time(table.create_time.timestamp());
-
-        app
-    }
-}
-
-impl std::convert::From<AppTable> for Trash {
-    fn from(table: AppTable) -> Self {
-        Trash {
-            id: table.id.to_string(),
-            name: table.name,
-            modified_time: table.modified_time.timestamp(),
-            create_time: table.create_time.timestamp(),
-            ty: TrashType::App,
-            unknown_fields: Default::default(),
-            cached_size: Default::default(),
-        }
-    }
-}
-
-#[derive(Debug, Clone, sqlx::FromRow)]
-pub struct ViewTable {
-    pub(crate) id: uuid::Uuid,
-    pub(crate) belong_to_id: String,
-    pub(crate) name: String,
-    pub(crate) description: String,
-    pub(crate) modified_time: chrono::DateTime<Utc>,
-    pub(crate) create_time: chrono::DateTime<Utc>,
-    pub(crate) thumbnail: String,
-    pub(crate) view_type: i32,
-}
-impl std::convert::From<ViewTable> for View {
-    fn from(table: ViewTable) -> Self {
-        let view_type = ViewType::from_i32(table.view_type).unwrap_or(ViewType::Doc);
-
-        let mut view = View::default();
-        view.set_id(table.id.to_string());
-        view.set_belong_to_id(table.belong_to_id);
-        view.set_name(table.name);
-        view.set_desc(table.description);
-        view.set_view_type(view_type);
-        view.set_belongings(RepeatedView::default());
-        view.set_create_time(table.create_time.timestamp());
-        view.set_modified_time(table.modified_time.timestamp());
-
-        view
-    }
-}
-
-impl std::convert::From<ViewTable> for Trash {
-    fn from(table: ViewTable) -> Self {
-        Trash {
-            id: table.id.to_string(),
-            name: table.name,
-            modified_time: table.modified_time.timestamp(),
-            create_time: table.create_time.timestamp(),
-            ty: TrashType::View,
-            unknown_fields: Default::default(),
-            cached_size: Default::default(),
-        }
-    }
-}
-
-#[derive(Debug, Clone, sqlx::FromRow)]
-pub struct TrashTable {
-    pub(crate) id: uuid::Uuid,
-    pub(crate) user_id: String,
-    pub(crate) ty: i32,
-}

+ 2 - 3
backend/src/lib.rs

@@ -2,7 +2,6 @@ pub mod application;
 pub mod config;
 pub mod context;
 mod entities;
-mod middleware;
+pub mod middleware;
 pub mod services;
-mod sqlx_ext;
-pub mod web_socket;
+pub mod util;

+ 4 - 2
backend/src/middleware/auth_middleware.rs

@@ -1,4 +1,3 @@
-use crate::services::user::{LoggedUser, AUTHORIZED_USERS};
 use actix_service::{Service, Transform};
 use actix_web::{
     dev::{ServiceRequest, ServiceResponse},
@@ -7,7 +6,10 @@ use actix_web::{
     ResponseError,
 };
 
-use crate::config::IGNORE_ROUTES;
+use crate::{
+    config::IGNORE_ROUTES,
+    entities::logged_user::{LoggedUser, AUTHORIZED_USERS},
+};
 use actix_web::{body::AnyBody, dev::MessageBody};
 use backend_service::{configuration::HEADER_TOKEN, errors::ServerError};
 use futures::future::{ok, LocalBoxFuture, Ready};

+ 5 - 5
backend/src/services/app/app.rs → backend/src/services/core/app/controller.rs

@@ -1,10 +1,10 @@
+use crate::services::core::view::read_view_belong_to_id;
+
 use crate::{
-    entities::workspace::{AppTable, APP_TABLE},
-    services::{app::sql_builder::*, user::LoggedUser, view::read_view_belong_to_id},
-    sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
+    entities::logged_user::LoggedUser,
+    services::core::{app::persistence::*, trash::read_trash_ids},
+    util::sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
 };
-
-use crate::services::trash::read_trash_ids;
 use backend_service::errors::{invalid_params, ServerError};
 use chrono::Utc;
 use flowy_core_data_model::{

+ 2 - 2
backend/src/services/app/mod.rs → backend/src/services/core/app/mod.rs

@@ -1,5 +1,5 @@
 #![allow(clippy::module_inception)]
-pub mod app;
+pub mod controller;
 pub mod router;
 
-pub mod sql_builder;
+pub mod persistence;

+ 31 - 5
backend/src/services/app/sql_builder.rs → backend/src/services/core/app/persistence.rs

@@ -1,17 +1,16 @@
-use crate::{
-    entities::workspace::{AppTable, APP_TABLE},
-    sqlx_ext::SqlBuilder,
-};
+use crate::util::sqlx_ext::SqlBuilder;
 use backend_service::errors::{invalid_params, ServerError};
 use chrono::{DateTime, NaiveDateTime, Utc};
 use flowy_core_data_model::{
     parser::app::AppId,
-    protobuf::{App, ColorStyle},
+    protobuf::{App, ColorStyle, RepeatedView},
 };
 use protobuf::Message;
 use sqlx::postgres::PgArguments;
 use uuid::Uuid;
 
+pub(crate) const APP_TABLE: &str = "app_table";
+
 pub struct NewAppSqlBuilder {
     table: AppTable,
 }
@@ -111,3 +110,30 @@ pub(crate) fn check_app_id(id: String) -> Result<Uuid, ServerError> {
     let app_id = Uuid::parse_str(app_id.as_ref())?;
     Ok(app_id)
 }
+
+#[derive(Debug, Clone, sqlx::FromRow)]
+pub struct AppTable {
+    pub(crate) id: uuid::Uuid,
+    pub(crate) workspace_id: String,
+    pub(crate) name: String,
+    pub(crate) description: String,
+    pub(crate) color_style: Vec<u8>,
+    pub(crate) last_view_id: String,
+    pub(crate) modified_time: chrono::DateTime<Utc>,
+    pub(crate) create_time: chrono::DateTime<Utc>,
+    pub(crate) user_id: String,
+}
+impl std::convert::From<AppTable> for App {
+    fn from(table: AppTable) -> Self {
+        let mut app = App::default();
+        app.set_id(table.id.to_string());
+        app.set_workspace_id(table.workspace_id.to_string());
+        app.set_name(table.name.clone());
+        app.set_desc(table.description.clone());
+        app.set_belongings(RepeatedView::default());
+        app.set_modified_time(table.modified_time.timestamp());
+        app.set_create_time(table.create_time.timestamp());
+
+        app
+    }
+}

+ 17 - 14
backend/src/services/app/router.rs → backend/src/services/core/app/router.rs

@@ -1,24 +1,27 @@
+use crate::{
+    entities::logged_user::LoggedUser,
+    services::core::app::{
+        controller::{create_app, delete_app, read_app, update_app},
+        persistence::check_app_id,
+    },
+    util::serde_ext::parse_from_payload,
+};
 use actix_web::{
     web::{Data, Payload},
     HttpResponse,
 };
-use backend_service::errors::{invalid_params, ServerError};
-use flowy_core_data_model::protobuf::{AppIdentifier, CreateAppParams, UpdateAppParams};
+use anyhow::Context;
+use backend_service::{
+    errors::{invalid_params, ServerError},
+    response::FlowyResponse,
+};
+use flowy_core_data_model::{
+    parser::app::{AppDesc, AppName},
+    protobuf::{AppIdentifier, CreateAppParams, UpdateAppParams},
+};
 use protobuf::Message;
 use sqlx::PgPool;
 
-use crate::services::{
-    app::{
-        app::{create_app, delete_app, read_app, update_app},
-        sql_builder::check_app_id,
-    },
-    user::LoggedUser,
-    util::parse_from_payload,
-};
-use anyhow::Context;
-use backend_service::response::FlowyResponse;
-use flowy_core_data_model::parser::app::{AppDesc, AppName};
-
 pub async fn create_handler(
     payload: Payload,
     pool: Data<PgPool>,

+ 0 - 0
backend/src/services/log.rs → backend/src/services/core/log.rs


+ 5 - 0
backend/src/services/core/mod.rs

@@ -0,0 +1,5 @@
+pub mod app;
+pub(crate) mod log;
+pub mod trash;
+pub mod view;
+pub mod workspace;

+ 1 - 0
backend/src/services/trash/mod.rs → backend/src/services/core/trash/mod.rs

@@ -1,4 +1,5 @@
 #![allow(clippy::module_inception)]
+mod persistence;
 pub mod router;
 mod trash;
 

+ 39 - 0
backend/src/services/core/trash/persistence.rs

@@ -0,0 +1,39 @@
+use crate::services::core::{app::persistence::AppTable, view::persistence::ViewTable};
+use flowy_core_data_model::protobuf::{Trash, TrashType};
+
+pub(crate) const TRASH_TABLE: &str = "trash_table";
+
+#[derive(Debug, Clone, sqlx::FromRow)]
+pub struct TrashTable {
+    pub(crate) id: uuid::Uuid,
+    pub(crate) user_id: String,
+    pub(crate) ty: i32,
+}
+
+impl std::convert::From<AppTable> for Trash {
+    fn from(table: AppTable) -> Self {
+        Trash {
+            id: table.id.to_string(),
+            name: table.name,
+            modified_time: table.modified_time.timestamp(),
+            create_time: table.create_time.timestamp(),
+            ty: TrashType::App,
+            unknown_fields: Default::default(),
+            cached_size: Default::default(),
+        }
+    }
+}
+
+impl std::convert::From<ViewTable> for Trash {
+    fn from(table: ViewTable) -> Self {
+        Trash {
+            id: table.id.to_string(),
+            name: table.name,
+            modified_time: table.modified_time.timestamp(),
+            create_time: table.create_time.timestamp(),
+            ty: TrashType::View,
+            unknown_fields: Default::default(),
+            cached_size: Default::default(),
+        }
+    }
+}

+ 4 - 4
backend/src/services/trash/router.rs → backend/src/services/core/trash/router.rs

@@ -1,7 +1,7 @@
-use crate::services::{
-    trash::{create_trash, delete_all_trash, delete_trash, read_trash},
-    user::LoggedUser,
-    util::parse_from_payload,
+use crate::{
+    entities::logged_user::LoggedUser,
+    services::core::trash::{create_trash, delete_all_trash, delete_trash, read_trash},
+    util::serde_ext::parse_from_payload,
 };
 use ::protobuf::ProtobufEnum;
 use actix_web::{

+ 5 - 5
backend/src/services/trash/trash.rs → backend/src/services/core/trash/trash.rs

@@ -1,11 +1,11 @@
 use crate::{
-    entities::workspace::{TrashTable, TRASH_TABLE},
-    services::{
-        app::app::{delete_app, read_app_table},
-        user::LoggedUser,
+    entities::logged_user::LoggedUser,
+    services::core::{
+        app::controller::{delete_app, read_app_table},
+        trash::persistence::{TrashTable, TRASH_TABLE},
         view::{delete_view, read_view_table},
     },
-    sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
+    util::sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
 };
 use ::protobuf::ProtobufEnum;
 use backend_service::errors::ServerError;

+ 5 - 8
backend/src/services/view/view.rs → backend/src/services/core/view/controller.rs

@@ -1,12 +1,9 @@
+use crate::services::document::{create_doc_with_transaction, delete_doc};
+
 use crate::{
-    entities::workspace::{ViewTable, VIEW_TABLE},
-    services::{
-        doc::{create_doc_with_transaction, delete_doc},
-        trash::read_trash_ids,
-        user::LoggedUser,
-        view::sql_builder::*,
-    },
-    sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
+    entities::logged_user::LoggedUser,
+    services::core::{trash::read_trash_ids, view::persistence::*},
+    util::sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
 };
 use backend_service::errors::{invalid_params, ServerError};
 use chrono::Utc;

+ 6 - 0
backend/src/services/core/view/mod.rs

@@ -0,0 +1,6 @@
+#![allow(clippy::module_inception)]
+mod controller;
+pub mod persistence;
+pub mod router;
+
+pub(crate) use controller::*;

+ 33 - 5
backend/src/services/view/sql_builder.rs → backend/src/services/core/view/persistence.rs

@@ -1,17 +1,16 @@
-use crate::{
-    entities::workspace::{ViewTable, VIEW_TABLE},
-    sqlx_ext::SqlBuilder,
-};
+use crate::util::sqlx_ext::SqlBuilder;
 use backend_service::errors::{invalid_params, ServerError};
 use chrono::{DateTime, NaiveDateTime, Utc};
 use flowy_core_data_model::{
     parser::view::ViewId,
-    protobuf::{View, ViewType},
+    protobuf::{RepeatedView, View, ViewType},
 };
 use protobuf::ProtobufEnum;
 use sqlx::postgres::PgArguments;
 use uuid::Uuid;
 
+pub(crate) const VIEW_TABLE: &str = "view_table";
+
 pub struct NewViewSqlBuilder {
     table: ViewTable,
 }
@@ -101,3 +100,32 @@ pub(crate) fn check_view_ids(ids: Vec<String>) -> Result<Vec<Uuid>, ServerError>
     }
     Ok(view_ids)
 }
+
+#[derive(Debug, Clone, sqlx::FromRow)]
+pub struct ViewTable {
+    pub(crate) id: uuid::Uuid,
+    pub(crate) belong_to_id: String,
+    pub(crate) name: String,
+    pub(crate) description: String,
+    pub(crate) modified_time: chrono::DateTime<Utc>,
+    pub(crate) create_time: chrono::DateTime<Utc>,
+    pub(crate) thumbnail: String,
+    pub(crate) view_type: i32,
+}
+impl std::convert::From<ViewTable> for View {
+    fn from(table: ViewTable) -> Self {
+        let view_type = ViewType::from_i32(table.view_type).unwrap_or(ViewType::Doc);
+
+        let mut view = View::default();
+        view.set_id(table.id.to_string());
+        view.set_belong_to_id(table.belong_to_id);
+        view.set_name(table.name);
+        view.set_desc(table.description);
+        view.set_view_type(view_type);
+        view.set_belongings(RepeatedView::default());
+        view.set_create_time(table.create_time.timestamp());
+        view.set_modified_time(table.modified_time.timestamp());
+
+        view
+    }
+}

+ 8 - 6
backend/src/services/view/router.rs → backend/src/services/core/view/router.rs

@@ -1,8 +1,10 @@
-use crate::services::{
-    doc::manager::DocumentCore,
-    user::LoggedUser,
-    util::parse_from_payload,
-    view::{create_view, delete_view, read_view, sql_builder::check_view_ids, update_view},
+use crate::{
+    entities::logged_user::LoggedUser,
+    services::{
+        core::view::{create_view, delete_view, persistence::check_view_ids, read_view, update_view},
+        document::manager::DocumentManager,
+    },
+    util::serde_ext::parse_from_payload,
 };
 use actix_web::{
     web::{Data, Payload},
@@ -23,7 +25,7 @@ use std::sync::Arc;
 pub async fn create_handler(
     payload: Payload,
     pool: Data<PgPool>,
-    _doc_biz: Data<Arc<DocumentCore>>,
+    _doc_biz: Data<Arc<DocumentManager>>,
 ) -> Result<HttpResponse, ServerError> {
     let params: CreateViewParams = parse_from_payload(payload).await?;
     let mut transaction = pool

+ 7 - 4
backend/src/services/workspace/workspace.rs → backend/src/services/core/workspace/controller.rs

@@ -1,8 +1,11 @@
-use super::sql_builder::NewWorkspaceBuilder;
+use super::persistence::NewWorkspaceBuilder;
 use crate::{
-    entities::workspace::{AppTable, WorkspaceTable, WORKSPACE_TABLE},
-    services::{app::app::read_app, user::LoggedUser, workspace::sql_builder::*},
-    sqlx_ext::*,
+    entities::logged_user::LoggedUser,
+    services::core::{
+        app::{controller::read_app, persistence::AppTable},
+        workspace::persistence::*,
+    },
+    util::sqlx_ext::*,
 };
 use anyhow::Context;
 use backend_service::errors::{invalid_params, ServerError};

+ 6 - 0
backend/src/services/core/workspace/mod.rs

@@ -0,0 +1,6 @@
+#![allow(clippy::module_inception)]
+mod controller;
+pub mod persistence;
+pub mod router;
+
+pub use controller::*;

+ 24 - 4
backend/src/services/workspace/sql_builder.rs → backend/src/services/core/workspace/persistence.rs

@@ -1,7 +1,4 @@
-use crate::{
-    entities::workspace::{WorkspaceTable, WORKSPACE_TABLE},
-    sqlx_ext::SqlBuilder,
-};
+use crate::util::sqlx_ext::SqlBuilder;
 use backend_service::errors::{invalid_params, ServerError};
 use chrono::{DateTime, NaiveDateTime, Utc};
 use flowy_core_data_model::{parser::workspace::WorkspaceId, protobuf::Workspace};
@@ -76,3 +73,26 @@ pub(crate) fn check_workspace_id(id: String) -> Result<Uuid, ServerError> {
     let workspace_id = Uuid::parse_str(workspace_id.as_ref())?;
     Ok(workspace_id)
 }
+
+pub(crate) const WORKSPACE_TABLE: &str = "workspace_table";
+
+#[derive(Debug, Clone, sqlx::FromRow)]
+pub struct WorkspaceTable {
+    pub(crate) id: uuid::Uuid,
+    pub(crate) name: String,
+    pub(crate) description: String,
+    pub(crate) modified_time: chrono::DateTime<Utc>,
+    pub(crate) create_time: chrono::DateTime<Utc>,
+    pub(crate) user_id: String,
+}
+impl std::convert::From<WorkspaceTable> for Workspace {
+    fn from(table: WorkspaceTable) -> Self {
+        let mut workspace = Workspace::default();
+        workspace.set_id(table.id.to_string());
+        workspace.set_name(table.name.clone());
+        workspace.set_desc(table.description.clone());
+        workspace.set_modified_time(table.modified_time.timestamp());
+        workspace.set_create_time(table.create_time.timestamp());
+        workspace
+    }
+}

+ 5 - 5
backend/src/services/workspace/router.rs → backend/src/services/core/workspace/router.rs

@@ -1,13 +1,13 @@
-use crate::services::{
-    user::LoggedUser,
-    util::parse_from_payload,
-    workspace::{
+use crate::{
+    entities::logged_user::LoggedUser,
+    services::core::workspace::{
         create_workspace,
         delete_workspace,
+        persistence::check_workspace_id,
         read_workspaces,
-        sql_builder::check_workspace_id,
         update_workspace,
     },
+    util::serde_ext::parse_from_payload,
 };
 use actix_web::{
     web::{Data, Payload},

+ 0 - 65
backend/src/services/doc/editor.rs

@@ -1,65 +0,0 @@
-use crate::{
-    services::doc::update_doc,
-    web_socket::{entities::Socket, WsMessageAdaptor, WsUser},
-};
-use actix_web::web::Data;
-use backend_service::errors::internal_error;
-
-use flowy_collaboration::{
-    core::sync::{RevisionUser, SyncResponse},
-    protobuf::UpdateDocParams,
-};
-
-use sqlx::PgPool;
-use std::sync::Arc;
-
-#[derive(Clone, Debug)]
-pub struct ServerDocUser {
-    pub user: Arc<WsUser>,
-    pub(crate) socket: Socket,
-    pub pg_pool: Data<PgPool>,
-}
-
-impl RevisionUser for ServerDocUser {
-    fn user_id(&self) -> String { self.user.id().to_string() }
-
-    fn receive(&self, resp: SyncResponse) {
-        let result = match resp {
-            SyncResponse::Pull(data) => {
-                let msg: WsMessageAdaptor = data.into();
-                self.socket.try_send(msg).map_err(internal_error)
-            },
-            SyncResponse::Push(data) => {
-                let msg: WsMessageAdaptor = data.into();
-                self.socket.try_send(msg).map_err(internal_error)
-            },
-            SyncResponse::Ack(data) => {
-                let msg: WsMessageAdaptor = data.into();
-                self.socket.try_send(msg).map_err(internal_error)
-            },
-            SyncResponse::NewRevision {
-                rev_id,
-                doc_id,
-                doc_json,
-            } => {
-                let pg_pool = self.pg_pool.clone();
-                tokio::task::spawn(async move {
-                    let mut params = UpdateDocParams::new();
-                    params.set_doc_id(doc_id);
-                    params.set_data(doc_json);
-                    params.set_rev_id(rev_id);
-                    match update_doc(pg_pool.get_ref(), params).await {
-                        Ok(_) => {},
-                        Err(e) => log::error!("{}", e),
-                    }
-                });
-                Ok(())
-            },
-        };
-
-        match result {
-            Ok(_) => {},
-            Err(e) => log::error!("[ServerDocUser]: {}", e),
-        }
-    }
-}

+ 7 - 8
backend/src/services/doc/crud.rs → backend/src/services/document/crud.rs

@@ -1,6 +1,6 @@
 use crate::{
     entities::doc::{DocTable, DOC_TABLE},
-    sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
+    util::sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
 };
 use anyhow::Context;
 use backend_service::errors::ServerError;
@@ -27,14 +27,14 @@ pub(crate) async fn create_doc(pool: &PgPool, params: CreateDocParams) -> Result
     let mut transaction = pool
         .begin()
         .await
-        .context("Failed to acquire a Postgres connection to create doc")?;
+        .context("Failed to acquire a Postgres connection to create document")?;
 
     let _ = create_doc_with_transaction(&mut transaction, params).await?;
 
     transaction
         .commit()
         .await
-        .context("Failed to commit SQL transaction to create doc.")?;
+        .context("Failed to commit SQL transaction to create document.")?;
 
     Ok(())
 }
@@ -45,7 +45,7 @@ pub(crate) async fn read_doc(pool: &PgPool, params: DocIdentifier) -> Result<Doc
     let mut transaction = pool
         .begin()
         .await
-        .context("Failed to acquire a Postgres connection to read doc")?;
+        .context("Failed to acquire a Postgres connection to read document")?;
 
     let builder = SqlBuilder::select(DOC_TABLE).add_field("*").and_where_eq("id", &doc_id);
 
@@ -60,7 +60,7 @@ pub(crate) async fn read_doc(pool: &PgPool, params: DocIdentifier) -> Result<Doc
     transaction
         .commit()
         .await
-        .context("Failed to commit SQL transaction to read doc.")?;
+        .context("Failed to commit SQL transaction to read document.")?;
 
     Ok(doc)
 }
@@ -71,7 +71,7 @@ pub async fn update_doc(pool: &PgPool, mut params: UpdateDocParams) -> Result<()
     let mut transaction = pool
         .begin()
         .await
-        .context("Failed to acquire a Postgres connection to update doc")?;
+        .context("Failed to acquire a Postgres connection to update document")?;
 
     let data = Some(params.take_data());
 
@@ -91,7 +91,7 @@ pub async fn update_doc(pool: &PgPool, mut params: UpdateDocParams) -> Result<()
     transaction
         .commit()
         .await
-        .context("Failed to commit SQL transaction to update doc.")?;
+        .context("Failed to commit SQL transaction to update document.")?;
 
     Ok(())
 }
@@ -99,7 +99,6 @@ pub async fn update_doc(pool: &PgPool, mut params: UpdateDocParams) -> Result<()
 #[tracing::instrument(level = "debug", skip(transaction), err)]
 pub(crate) async fn delete_doc(transaction: &mut DBTransaction<'_>, doc_id: Uuid) -> Result<(), ServerError> {
     let (sql, args) = SqlBuilder::delete(DOC_TABLE).and_where_eq("id", doc_id).build()?;
-
     let _ = sqlx::query_with(&sql, args)
         .execute(transaction)
         .await

+ 14 - 20
backend/src/services/doc/manager.rs → backend/src/services/document/manager.rs

@@ -1,14 +1,13 @@
-use crate::{
-    services::doc::{
+use crate::services::{
+    document::{
+        create_doc,
         read_doc,
         update_doc,
-        ws_actor::{DocWsActor, DocWsMsg},
+        ws_actor::{DocumentWebSocketActor, WSActorMessage},
     },
-    web_socket::{WsBizHandler, WsClientData},
+    web_socket::{WSClientData, WebSocketReceiver},
 };
 use actix_web::web::Data;
-
-use crate::services::doc::create_doc;
 use backend_service::errors::ServerError;
 use flowy_collaboration::{
     core::sync::{ServerDocManager, ServerDocPersistence},
@@ -22,34 +21,29 @@ use sqlx::PgPool;
 use std::{convert::TryInto, sync::Arc};
 use tokio::sync::{mpsc, oneshot};
 
-pub struct DocumentCore {
-    pub manager: Arc<ServerDocManager>,
-    ws_sender: mpsc::Sender<DocWsMsg>,
+pub struct DocumentManager {
+    ws_sender: mpsc::Sender<WSActorMessage>,
     pg_pool: Data<PgPool>,
 }
 
-impl DocumentCore {
+impl DocumentManager {
     pub fn new(pg_pool: Data<PgPool>) -> Self {
-        let manager = Arc::new(ServerDocManager::new(Arc::new(DocPersistenceImpl(pg_pool.clone()))));
+        let inner = Arc::new(ServerDocManager::new(Arc::new(DocPersistenceImpl(pg_pool.clone()))));
         let (ws_sender, rx) = mpsc::channel(100);
-        let actor = DocWsActor::new(rx, manager.clone());
+        let actor = DocumentWebSocketActor::new(rx, inner);
         tokio::task::spawn(actor.run());
-        Self {
-            manager,
-            ws_sender,
-            pg_pool,
-        }
+        Self { ws_sender, pg_pool }
     }
 }
 
-impl WsBizHandler for DocumentCore {
-    fn receive(&self, data: WsClientData) {
+impl WebSocketReceiver for DocumentManager {
+    fn receive(&self, data: WSClientData) {
         let (ret, rx) = oneshot::channel();
         let sender = self.ws_sender.clone();
         let pool = self.pg_pool.clone();
 
         actix_rt::spawn(async move {
-            let msg = DocWsMsg::ClientData {
+            let msg = WSActorMessage::ClientData {
                 client_data: data,
                 ret,
                 pool,

+ 0 - 1
backend/src/services/doc/mod.rs → backend/src/services/document/mod.rs

@@ -4,7 +4,6 @@ pub(crate) use crud::*;
 pub use router::*;
 
 pub mod crud;
-mod editor;
 pub mod manager;
 pub mod router;
 mod ws_actor;

+ 2 - 4
backend/src/services/doc/router.rs → backend/src/services/document/router.rs

@@ -1,12 +1,10 @@
-use crate::services::{
-    doc::{create_doc, read_doc, update_doc},
-    util::parse_from_payload,
-};
+use crate::services::document::{create_doc, read_doc, update_doc};
 use actix_web::{
     web::{Data, Payload},
     HttpResponse,
 };
 
+use crate::util::serde_ext::parse_from_payload;
 use backend_service::{errors::ServerError, response::FlowyResponse};
 use flowy_collaboration::protobuf::{CreateDocParams, DocIdentifier, UpdateDocParams};
 use sqlx::PgPool;

+ 66 - 18
backend/src/services/doc/ws_actor.rs → backend/src/services/document/ws_actor.rs

@@ -1,9 +1,9 @@
 use crate::{
     services::{
-        doc::editor::ServerDocUser,
-        util::{md5, parse_from_bytes},
+        document::update_doc,
+        web_socket::{entities::Socket, WSClientData, WSMessageAdaptor, WSUser},
     },
-    web_socket::WsClientData,
+    util::serde_ext::{md5, parse_from_bytes},
 };
 use actix_rt::task::spawn_blocking;
 use actix_web::web::Data;
@@ -11,32 +11,29 @@ use async_stream::stream;
 use backend_service::errors::{internal_error, Result, ServerError};
 use flowy_collaboration::{
     core::sync::{RevisionUser, ServerDocManager, SyncResponse},
-    entities::ws::DocumentWSDataBuilder,
-    protobuf::{DocumentWSData, DocumentWSDataType},
+    protobuf::{DocumentWSData, DocumentWSDataType, NewDocumentUser, UpdateDocParams},
 };
-
-use flowy_collaboration::protobuf::NewDocumentUser;
 use futures::stream::StreamExt;
 use lib_ot::protobuf::Revision;
 use sqlx::PgPool;
 use std::{convert::TryInto, sync::Arc};
 use tokio::sync::{mpsc, oneshot};
 
-pub enum DocWsMsg {
+pub enum WSActorMessage {
     ClientData {
-        client_data: WsClientData,
+        client_data: WSClientData,
         pool: Data<PgPool>,
         ret: oneshot::Sender<Result<()>>,
     },
 }
 
-pub struct DocWsActor {
-    receiver: Option<mpsc::Receiver<DocWsMsg>>,
+pub struct DocumentWebSocketActor {
+    receiver: Option<mpsc::Receiver<WSActorMessage>>,
     doc_manager: Arc<ServerDocManager>,
 }
 
-impl DocWsActor {
-    pub fn new(receiver: mpsc::Receiver<DocWsMsg>, manager: Arc<ServerDocManager>) -> Self {
+impl DocumentWebSocketActor {
+    pub fn new(receiver: mpsc::Receiver<WSActorMessage>, manager: Arc<ServerDocManager>) -> Self {
         Self {
             receiver: Some(receiver),
             doc_manager: manager,
@@ -61,16 +58,16 @@ impl DocWsActor {
         stream.for_each(|msg| self.handle_message(msg)).await;
     }
 
-    async fn handle_message(&self, msg: DocWsMsg) {
+    async fn handle_message(&self, msg: WSActorMessage) {
         match msg {
-            DocWsMsg::ClientData { client_data, pool, ret } => {
+            WSActorMessage::ClientData { client_data, pool, ret } => {
                 let _ = ret.send(self.handle_client_data(client_data, pool).await);
             },
         }
     }
 
-    async fn handle_client_data(&self, client_data: WsClientData, pg_pool: Data<PgPool>) -> Result<()> {
-        let WsClientData { user, socket, data } = client_data;
+    async fn handle_client_data(&self, client_data: WSClientData, pg_pool: Data<PgPool>) -> Result<()> {
+        let WSClientData { user, socket, data } = client_data;
         let document_data = spawn_blocking(move || {
             let document_data: DocumentWSData = parse_from_bytes(&data)?;
             Result::Ok(document_data)
@@ -127,7 +124,7 @@ impl DocWsActor {
 
     async fn handle_revision(&self, user: Arc<ServerDocUser>, mut revision: Revision) -> Result<()> {
         let revision: lib_ot::revision::Revision = (&mut revision).try_into().map_err(internal_error)?;
-        // Create the doc if it doesn't exist
+        // Create the document if it doesn't exist
         let handler = match self.doc_manager.get(&revision.doc_id).await {
             None => self
                 .doc_manager
@@ -149,3 +146,54 @@ fn verify_md5(revision: &Revision) -> Result<()> {
     }
     Ok(())
 }
+
+#[derive(Clone, Debug)]
+pub struct ServerDocUser {
+    pub user: Arc<WSUser>,
+    pub(crate) socket: Socket,
+    pub pg_pool: Data<PgPool>,
+}
+
+impl RevisionUser for ServerDocUser {
+    fn user_id(&self) -> String { self.user.id().to_string() }
+
+    fn receive(&self, resp: SyncResponse) {
+        let result = match resp {
+            SyncResponse::Pull(data) => {
+                let msg: WSMessageAdaptor = data.into();
+                self.socket.try_send(msg).map_err(internal_error)
+            },
+            SyncResponse::Push(data) => {
+                let msg: WSMessageAdaptor = data.into();
+                self.socket.try_send(msg).map_err(internal_error)
+            },
+            SyncResponse::Ack(data) => {
+                let msg: WSMessageAdaptor = data.into();
+                self.socket.try_send(msg).map_err(internal_error)
+            },
+            SyncResponse::NewRevision {
+                rev_id,
+                doc_id,
+                doc_json,
+            } => {
+                let pg_pool = self.pg_pool.clone();
+                tokio::task::spawn(async move {
+                    let mut params = UpdateDocParams::new();
+                    params.set_doc_id(doc_id);
+                    params.set_data(doc_json);
+                    params.set_rev_id(rev_id);
+                    match update_doc(pg_pool.get_ref(), params).await {
+                        Ok(_) => {},
+                        Err(e) => log::error!("{}", e),
+                    }
+                });
+                Ok(())
+            },
+        };
+
+        match result {
+            Ok(_) => {},
+            Err(e) => log::error!("[ServerDocUser]: {}", e),
+        }
+    }
+}

+ 3 - 7
backend/src/services/mod.rs

@@ -1,8 +1,4 @@
-pub mod app;
-pub mod doc;
-pub(crate) mod log;
-pub mod trash;
+pub mod core;
+pub mod document;
 pub mod user;
-pub(crate) mod util;
-pub mod view;
-pub mod workspace;
+pub mod web_socket;

+ 9 - 5
backend/src/services/user/auth.rs → backend/src/services/user/controller.rs

@@ -1,7 +1,13 @@
 use crate::{
-    entities::{token::Token, user::UserTable},
-    services::user::{hash_password, verify_password, LoggedUser},
-    sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
+    entities::{
+        logged_user::{LoggedUser, AUTHORIZED_USERS},
+        token::Token,
+        user::UserTable,
+    },
+    util::{
+        sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
+        user_ext::{hash_password, verify_password},
+    },
 };
 use anyhow::Context;
 use backend_service::{
@@ -15,8 +21,6 @@ use flowy_user_data_model::{
 };
 use sqlx::{PgPool, Postgres};
 
-use super::AUTHORIZED_USERS;
-
 pub async fn sign_in(pool: &PgPool, params: SignInParams) -> Result<SignInResponse, ServerError> {
     let email = UserEmail::parse(params.email).map_err(|e| ServerError::params_invalid().context(e))?;
     let password = UserPassword::parse(params.password).map_err(|e| ServerError::params_invalid().context(e))?;

+ 2 - 7
backend/src/services/user/mod.rs

@@ -1,9 +1,4 @@
-pub use auth::*;
-pub use logged_user::*;
-pub use utils::*;
+pub use controller::*;
 
-mod auth;
-mod logged_user;
+mod controller;
 pub mod router;
-pub mod user_default;
-mod utils;

+ 6 - 10
backend/src/services/user/router.rs

@@ -1,21 +1,17 @@
+use crate::{
+    entities::{logged_user::LoggedUser, token::Token},
+    services::user::{get_user_profile, register_user, set_user_profile, sign_in, sign_out},
+    util::serde_ext::parse_from_payload,
+};
 use actix_identity::Identity;
 use actix_web::{
     web::{Data, Payload},
     HttpRequest,
     HttpResponse,
 };
-use sqlx::PgPool;
-
 use backend_service::{errors::ServerError, response::FlowyResponse};
 use flowy_user_data_model::protobuf::{SignInParams, SignUpParams, UpdateUserParams};
-
-use crate::{
-    entities::token::Token,
-    services::{
-        user::{get_user_profile, register_user, set_user_profile, sign_in, sign_out, LoggedUser},
-        util::parse_from_payload,
-    },
-};
+use sqlx::PgPool;
 
 pub async fn sign_in_handler(payload: Payload, id: Identity, pool: Data<PgPool>) -> Result<HttpResponse, ServerError> {
     let params: SignInParams = parse_from_payload(payload).await?;

+ 0 - 49
backend/src/services/user/user_default.rs

@@ -1,49 +0,0 @@
-use crate::{
-    services::{
-        app::sql_builder::NewAppSqlBuilder as AppBuilder,
-        workspace::sql_builder::NewWorkspaceBuilder as WorkspaceBuilder,
-    },
-    sqlx_ext::{map_sqlx_error, DBTransaction},
-};
-
-use crate::services::view::{create_view_with_args, sql_builder::NewViewSqlBuilder};
-use backend_service::errors::ServerError;
-use chrono::Utc;
-use flowy_collaboration::core::document::default::initial_string;
-use flowy_core_data_model::protobuf::Workspace;
-use std::convert::TryInto;
-
-#[allow(dead_code)]
-pub async fn create_default_workspace(
-    transaction: &mut DBTransaction<'_>,
-    user_id: &str,
-) -> Result<Workspace, ServerError> {
-    let time = Utc::now();
-    let workspace: Workspace = flowy_core_data_model::user_default::create_default_workspace(time)
-        .try_into()
-        .unwrap();
-
-    let mut cloned_workspace = workspace.clone();
-    let mut apps = cloned_workspace.take_apps();
-
-    let (sql, args, _) = WorkspaceBuilder::from_workspace(user_id, cloned_workspace)?.build()?;
-    let _ = sqlx::query_with(&sql, args)
-        .execute(transaction as &mut DBTransaction<'_>)
-        .await
-        .map_err(map_sqlx_error)?;
-
-    for mut app in apps.take_items() {
-        let mut views = app.take_belongings();
-        let (sql, args, _) = AppBuilder::from_app(user_id, app)?.build()?;
-        let _ = sqlx::query_with(&sql, args)
-            .execute(transaction as &mut DBTransaction<'_>)
-            .await
-            .map_err(map_sqlx_error)?;
-
-        for view in views.take_items() {
-            let (sql, args, view) = NewViewSqlBuilder::from_view(view)?.build()?;
-            let _ = create_view_with_args(transaction, sql, args, view, initial_string()).await?;
-        }
-    }
-    Ok(workspace)
-}

+ 0 - 6
backend/src/services/view/mod.rs

@@ -1,6 +0,0 @@
-#![allow(clippy::module_inception)]
-pub mod router;
-pub mod sql_builder;
-mod view;
-
-pub(crate) use view::*;

+ 2 - 2
backend/src/web_socket/entities/connect.rs → backend/src/services/web_socket/entities/connect.rs

@@ -1,10 +1,10 @@
-use crate::web_socket::WsMessageAdaptor;
+use crate::services::web_socket::WSMessageAdaptor;
 use actix::{Message, Recipient};
 use backend_service::errors::ServerError;
 use serde::{Deserialize, Serialize};
 use std::fmt::Formatter;
 
-pub type Socket = Recipient<WsMessageAdaptor>;
+pub type Socket = Recipient<WSMessageAdaptor>;
 
 #[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq)]
 pub struct SessionId(pub String);

+ 4 - 4
backend/src/web_socket/entities/message.rs → backend/src/services/web_socket/entities/message.rs

@@ -6,15 +6,15 @@ use std::convert::TryInto;
 
 #[derive(Debug, Message, Clone)]
 #[rtype(result = "()")]
-pub struct WsMessageAdaptor(pub Bytes);
+pub struct WSMessageAdaptor(pub Bytes);
 
-impl std::ops::Deref for WsMessageAdaptor {
+impl std::ops::Deref for WSMessageAdaptor {
     type Target = Bytes;
 
     fn deref(&self) -> &Self::Target { &self.0 }
 }
 
-impl std::convert::From<DocumentWSData> for WsMessageAdaptor {
+impl std::convert::From<DocumentWSData> for WSMessageAdaptor {
     fn from(data: DocumentWSData) -> Self {
         let bytes: Bytes = data.try_into().unwrap();
         let msg = WSMessage {
@@ -23,6 +23,6 @@ impl std::convert::From<DocumentWSData> for WsMessageAdaptor {
         };
 
         let bytes: Bytes = msg.try_into().unwrap();
-        WsMessageAdaptor(bytes)
+        WSMessageAdaptor(bytes)
     }
 }

+ 0 - 0
backend/src/web_socket/entities/mod.rs → backend/src/services/web_socket/entities/mod.rs


+ 0 - 2
backend/src/web_socket/mod.rs → backend/src/services/web_socket/mod.rs

@@ -1,9 +1,7 @@
-pub use biz_handler::*;
 pub use entities::message::*;
 pub use ws_client::*;
 pub use ws_server::*;
 
-mod biz_handler;
 pub(crate) mod entities;
 pub mod router;
 mod ws_client;

+ 16 - 16
backend/src/web_socket/router.rs → backend/src/services/web_socket/router.rs

@@ -1,6 +1,6 @@
 use crate::{
-    services::user::LoggedUser,
-    web_socket::{WsBizHandlers, WsClient, WsServer, WsUser},
+    entities::logged_user::LoggedUser,
+    services::web_socket::{WSClient, WSServer, WSUser, WebSocketReceivers},
 };
 use actix::Addr;
 use actix_web::{
@@ -20,29 +20,29 @@ use actix_web_actors::ws;
 //                  │ └────────┘  │   │
 //                  └─────────────┘   │
 //                                    │
-//                                    │    ┌───────────────┐   ┌─────────────┐    ┌────────────────┐
-//                                    ├───▶│ WsBizHandlers │──▶│WsBizHandler │───▶│  WsClientData 
-//                                    │    └───────────────┘   └─────────────┘    └────────────────┘
-//                   WsClient         │                               △
-//                  ┌─────────────┐   │                               │
-//                  │ ┌────────┐  │   │                               │
-//  wss://xxx ─────▶│ │ WsUser │  │───┘                       ┌───────────────┐
-//                  │ └────────┘  │                           │ DocumentCore  │
-//                  └─────────────┘                           └───────────────┘
-
+//                                    │    ┌──────────────────┐ 1 n ┌──────────────────┐
+//                                    ├───▶│WebSocketReceivers│◆────│WebSocketReceiver
+//                                    │    └──────────────────┘ ──────────────────┘
+//                   WsClient         │                                       
+//                  ┌─────────────┐   │                                       
+//                  │ ┌────────┐  │   │                                       
+//  wss://xxx ─────▶│ │ WsUser │  │───┘                       
+//                  │ └────────┘  │                                   ┌───────────────┐
+//                  └─────────────┘                                   │DocumentManager│
+//                                                                    └───────────────┘
 #[get("/{token}")]
 pub async fn establish_ws_connection(
     request: HttpRequest,
     payload: Payload,
     token: Path<String>,
-    server: Data<Addr<WsServer>>,
-    biz_handlers: Data<WsBizHandlers>,
+    server: Data<Addr<WSServer>>,
+    ws_receivers: Data<WebSocketReceivers>,
 ) -> Result<HttpResponse, Error> {
     tracing::info!("establish_ws_connection");
     match LoggedUser::from_token(token.clone()) {
         Ok(user) => {
-            let ws_user = WsUser::new(user);
-            let client = WsClient::new(ws_user, server.get_ref().clone(), biz_handlers);
+            let ws_user = WSUser::new(user);
+            let client = WSClient::new(ws_user, server.get_ref().clone(), ws_receivers);
             let result = ws::start(client, &request, payload);
             match result {
                 Ok(response) => Ok(response),

+ 44 - 25
backend/src/web_socket/ws_client.rs → backend/src/services/web_socket/ws_client.rs

@@ -1,50 +1,69 @@
 use crate::{
     config::{HEARTBEAT_INTERVAL, PING_TIMEOUT},
-    services::user::LoggedUser,
-    web_socket::{
+    entities::logged_user::LoggedUser,
+    services::web_socket::{
         entities::{Connect, Disconnect, Socket},
-        WsBizHandlers,
-        WsMessageAdaptor,
-        WsServer,
+        WSMessageAdaptor,
+        WSServer,
     },
 };
 use actix::*;
 use actix_web::web::Data;
 use actix_web_actors::{ws, ws::Message::Text};
 use bytes::Bytes;
-use lib_ws::WSMessage;
-use std::{convert::TryFrom, sync::Arc, time::Instant};
+use lib_ws::{WSMessage, WSModule};
+use std::{collections::HashMap, convert::TryFrom, sync::Arc, time::Instant};
+
+pub trait WebSocketReceiver: Send + Sync {
+    fn receive(&self, data: WSClientData);
+}
+
+pub struct WebSocketReceivers {
+    inner: HashMap<WSModule, Arc<dyn WebSocketReceiver>>,
+}
+
+impl std::default::Default for WebSocketReceivers {
+    fn default() -> Self { Self { inner: HashMap::new() } }
+}
+
+impl WebSocketReceivers {
+    pub fn new() -> Self { WebSocketReceivers::default() }
+
+    pub fn set(&mut self, source: WSModule, handler: Arc<dyn WebSocketReceiver>) { self.inner.insert(source, handler); }
+
+    pub fn get(&self, source: &WSModule) -> Option<Arc<dyn WebSocketReceiver>> { self.inner.get(source).cloned() }
+}
 
 #[derive(Debug)]
-pub struct WsUser {
+pub struct WSUser {
     inner: LoggedUser,
 }
 
-impl WsUser {
+impl WSUser {
     pub fn new(inner: LoggedUser) -> Self { Self { inner } }
 
     pub fn id(&self) -> &str { &self.inner.user_id }
 }
 
-pub struct WsClientData {
-    pub(crate) user: Arc<WsUser>,
+pub struct WSClientData {
+    pub(crate) user: Arc<WSUser>,
     pub(crate) socket: Socket,
     pub(crate) data: Bytes,
 }
 
-pub struct WsClient {
-    user: Arc<WsUser>,
-    server: Addr<WsServer>,
-    biz_handlers: Data<WsBizHandlers>,
+pub struct WSClient {
+    user: Arc<WSUser>,
+    server: Addr<WSServer>,
+    ws_receivers: Data<WebSocketReceivers>,
     hb: Instant,
 }
 
-impl WsClient {
-    pub fn new(user: WsUser, server: Addr<WsServer>, biz_handlers: Data<WsBizHandlers>) -> Self {
+impl WSClient {
+    pub fn new(user: WSUser, server: Addr<WSServer>, ws_receivers: Data<WebSocketReceivers>) -> Self {
         Self {
             user: Arc::new(user),
             server,
-            biz_handlers,
+            ws_receivers,
             hb: Instant::now(),
         }
     }
@@ -65,12 +84,12 @@ impl WsClient {
     fn handle_binary_message(&self, bytes: Bytes, socket: Socket) {
         // TODO: ok to unwrap?
         let message: WSMessage = WSMessage::try_from(bytes).unwrap();
-        match self.biz_handlers.get(&message.module) {
+        match self.ws_receivers.get(&message.module) {
             None => {
-                log::error!("Can't find the handler for {:?}", message.module);
+                log::error!("Can't find the receiver for {:?}", message.module);
             },
             Some(handler) => {
-                let client_data = WsClientData {
+                let client_data = WSClientData {
                     user: self.user.clone(),
                     socket,
                     data: Bytes::from(message.data),
@@ -81,7 +100,7 @@ impl WsClient {
     }
 }
 
-impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WsClient {
+impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WSClient {
     fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) {
         match msg {
             Ok(ws::Message::Ping(msg)) => {
@@ -113,13 +132,13 @@ impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WsClient {
     }
 }
 
-impl Handler<WsMessageAdaptor> for WsClient {
+impl Handler<WSMessageAdaptor> for WSClient {
     type Result = ();
 
-    fn handle(&mut self, msg: WsMessageAdaptor, ctx: &mut Self::Context) { ctx.binary(msg.0); }
+    fn handle(&mut self, msg: WSMessageAdaptor, ctx: &mut Self::Context) { ctx.binary(msg.0); }
 }
 
-impl Actor for WsClient {
+impl Actor for WSClient {
     type Context = ws::WebsocketContext<Self>;
 
     fn started(&mut self, ctx: &mut Self::Context) {

+ 14 - 14
backend/src/web_socket/ws_server.rs → backend/src/services/web_socket/ws_server.rs

@@ -1,34 +1,34 @@
-use crate::web_socket::{
+use crate::services::web_socket::{
     entities::{Connect, Disconnect, Session, SessionId},
-    WsMessageAdaptor,
+    WSMessageAdaptor,
 };
 use actix::{Actor, Context, Handler};
 use backend_service::errors::ServerError;
 use dashmap::DashMap;
 
-pub struct WsServer {
+pub struct WSServer {
     sessions: DashMap<SessionId, Session>,
 }
 
-impl std::default::Default for WsServer {
+impl std::default::Default for WSServer {
     fn default() -> Self {
         Self {
             sessions: DashMap::new(),
         }
     }
 }
-impl WsServer {
-    pub fn new() -> Self { WsServer::default() }
+impl WSServer {
+    pub fn new() -> Self { WSServer::default() }
 
-    pub fn send(&self, _msg: WsMessageAdaptor) { unimplemented!() }
+    pub fn send(&self, _msg: WSMessageAdaptor) { unimplemented!() }
 }
 
-impl Actor for WsServer {
+impl Actor for WSServer {
     type Context = Context<Self>;
     fn started(&mut self, _ctx: &mut Self::Context) {}
 }
 
-impl Handler<Connect> for WsServer {
+impl Handler<Connect> for WSServer {
     type Result = Result<(), ServerError>;
     fn handle(&mut self, msg: Connect, _ctx: &mut Context<Self>) -> Self::Result {
         let session: Session = msg.into();
@@ -38,7 +38,7 @@ impl Handler<Connect> for WsServer {
     }
 }
 
-impl Handler<Disconnect> for WsServer {
+impl Handler<Disconnect> for WSServer {
     type Result = Result<(), ServerError>;
     fn handle(&mut self, msg: Disconnect, _: &mut Context<Self>) -> Self::Result {
         self.sessions.remove(&msg.sid);
@@ -46,14 +46,14 @@ impl Handler<Disconnect> for WsServer {
     }
 }
 
-impl Handler<WsMessageAdaptor> for WsServer {
+impl Handler<WSMessageAdaptor> for WSServer {
     type Result = ();
 
-    fn handle(&mut self, _msg: WsMessageAdaptor, _ctx: &mut Context<Self>) -> Self::Result { unimplemented!() }
+    fn handle(&mut self, _msg: WSMessageAdaptor, _ctx: &mut Context<Self>) -> Self::Result { unimplemented!() }
 }
 
-impl actix::Supervised for WsServer {
-    fn restarting(&mut self, _ctx: &mut Context<WsServer>) {
+impl actix::Supervised for WSServer {
+    fn restarting(&mut self, _ctx: &mut Context<WSServer>) {
         log::warn!("restarting");
     }
 }

+ 0 - 6
backend/src/services/workspace/mod.rs

@@ -1,6 +0,0 @@
-#![allow(clippy::module_inception)]
-pub mod router;
-pub mod sql_builder;
-mod workspace;
-
-pub use workspace::*;

+ 3 - 0
backend/src/util/mod.rs

@@ -0,0 +1,3 @@
+pub mod serde_ext;
+pub mod sqlx_ext;
+pub mod user_ext;

+ 0 - 0
backend/src/services/util.rs → backend/src/util/serde_ext.rs


+ 0 - 0
backend/src/sqlx_ext/mod.rs → backend/src/util/sqlx_ext/mod.rs


+ 0 - 0
backend/src/sqlx_ext/query.rs → backend/src/util/sqlx_ext/query.rs


+ 0 - 0
backend/src/sqlx_ext/utils.rs → backend/src/util/sqlx_ext/utils.rs


+ 0 - 0
backend/src/services/user/utils.rs → backend/src/util/user_ext.rs


+ 0 - 24
backend/src/web_socket/biz_handler.rs

@@ -1,24 +0,0 @@
-use crate::web_socket::WsClientData;
-use lib_ws::WSModule;
-use std::{collections::HashMap, sync::Arc};
-
-pub trait WsBizHandler: Send + Sync {
-    fn receive(&self, data: WsClientData);
-}
-
-pub type BizHandler = Arc<dyn WsBizHandler>;
-pub struct WsBizHandlers {
-    inner: HashMap<WSModule, BizHandler>,
-}
-
-impl std::default::Default for WsBizHandlers {
-    fn default() -> Self { Self { inner: HashMap::new() } }
-}
-
-impl WsBizHandlers {
-    pub fn new() -> Self { WsBizHandlers::default() }
-
-    pub fn register(&mut self, source: WSModule, handler: BizHandler) { self.inner.insert(source, handler); }
-
-    pub fn get(&self, source: &WSModule) -> Option<BizHandler> { self.inner.get(source).cloned() }
-}

+ 3 - 3
backend/tests/document/edit_test.rs

@@ -70,7 +70,7 @@ async fn delta_sync_while_editing_with_attribute() {
 // │ops: ["123", "456"] rev: 2│ │                 │
 // └──────────────────────────┘ │                 │
 //                              │                 │
-//                              ◀── http request ─┤ Open doc
+//                              ◀── http request ─┤ Open document
 //                              │                 │
 //                              │                 │  ┌──────────────────────────┐
 //                              ├──http response──┼─▶│ops: ["123", "456"] rev: 2│
@@ -115,7 +115,7 @@ async fn delta_sync_with_server_push_delta() {
 //                         └─────────┘       └─────────┘
 //                              │                 │
 //                              │                 │
-//                              ◀── http request ─┤ Open doc
+//                              ◀── http request ─┤ Open document
 //                              │                 │
 //                              │                 │  ┌───────────────┐
 //                              ├──http response──┼─▶│ops: [] rev: 0 │
@@ -165,7 +165,7 @@ async fn delta_sync_while_local_rev_less_than_server_rev() {
 //               ┌───────────────────┐ │                 │
 //               │ops: ["123"] rev: 1│ │                 │
 //               └───────────────────┘ │                 │
-//                                     ◀── http request ─┤  Open doc
+//                                     ◀── http request ─┤  Open document
 //                                     │                 │
 //                                     │                 │   ┌───────────────┐
 //                                     ├──http response──┼──▶│ops: [123] rev:│

+ 1 - 1
backend/tests/util/helper.rs

@@ -150,7 +150,7 @@ impl TestUserServer {
     }
 
     pub async fn read_doc(&self, params: DocIdentifier) -> Option<Doc> {
-        let url = format!("{}/api/doc", self.http_addr());
+        let url = format!("{}/api/document", self.http_addr());
         let doc = read_doc_request(self.user_token(), params, &url).await.unwrap();
         doc
     }

+ 4 - 0
frontend/rust-lib/dart-ffi/src/protobuf/document

@@ -0,0 +1,4 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+mod model;
+pub use model::*;

+ 8 - 0
frontend/rust-lib/dart-ffi/src/protobuf/model/document

@@ -0,0 +1,8 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+
+mod ffi_response;
+pub use ffi_response::*;
+
+mod ffi_request;
+pub use ffi_request::*;

+ 4 - 0
frontend/rust-lib/dart-notify/src/protobuf/document

@@ -0,0 +1,4 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+mod model;
+pub use model::*;

+ 5 - 0
frontend/rust-lib/dart-notify/src/protobuf/model/document

@@ -0,0 +1,5 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+
+mod subject;
+pub use subject::*;

+ 4 - 0
frontend/rust-lib/flowy-core/src/protobuf/document

@@ -0,0 +1,4 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+mod model;
+pub use model::*;

+ 8 - 0
frontend/rust-lib/flowy-core/src/protobuf/model/document

@@ -0,0 +1,8 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+
+mod observable;
+pub use observable::*;
+
+mod event;
+pub use event::*;

+ 4 - 0
frontend/rust-lib/flowy-document/src/protobuf/document

@@ -0,0 +1,4 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+mod model;
+pub use model::*;

+ 5 - 0
frontend/rust-lib/flowy-document/src/protobuf/model/document

@@ -0,0 +1,5 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+
+mod observable;
+pub use observable::*;

+ 2 - 2
frontend/rust-lib/flowy-document/src/services/controller.rs

@@ -56,7 +56,7 @@ impl DocController {
     }
 
     pub(crate) fn close(&self, doc_id: &str) -> Result<(), FlowyError> {
-        tracing::debug!("Close doc {}", doc_id);
+        tracing::debug!("Close document {}", doc_id);
         self.open_cache.remove(doc_id);
         self.ws_handlers.remove_handler(doc_id);
         Ok(())
@@ -114,7 +114,7 @@ impl DocController {
     fn make_rev_manager(&self, doc_id: &str, pool: Arc<ConnectionPool>) -> Result<RevisionManager, FlowyError> {
         // Opti: require upgradable_read lock and then upgrade to write lock using
         // RwLockUpgradableReadGuard::upgrade(xx) of ws
-        // let doc = self.read_doc(doc_id, pool.clone()).await?;
+        // let document = self.read_doc(doc_id, pool.clone()).await?;
         let user_id = self.user.user_id()?;
         let cache = Arc::new(RevisionCache::new(&user_id, doc_id, pool));
         Ok(RevisionManager::new(&user_id, doc_id, cache))

+ 4 - 4
frontend/rust-lib/flowy-document/src/services/doc/web_socket/web_socket.rs

@@ -20,7 +20,7 @@ use flowy_collaboration::{
 use flowy_error::{internal_error, FlowyError, FlowyResult};
 use lib_infra::future::FutureResult;
 use lib_ot::{
-    revision::{RevType, Revision, RevisionRange},
+    revision::{Revision, RevisionRange},
     rich_text::RichTextDelta,
 };
 use lib_ws::WSConnectState;
@@ -194,7 +194,7 @@ pub(crate) async fn handle_push_rev(
     bytes: Bytes,
 ) -> FlowyResult<Option<Revision>> {
     // Transform the revision
-    let (ret, rx) = oneshot::channel::<CollaborateResult<TransformDeltas>>();
+    let (_ret, _rx) = oneshot::channel::<CollaborateResult<TransformDeltas>>();
     let revision = Revision::try_from(bytes)?;
     let delta = RichTextDelta::from_bytes(&revision.delta_data)?;
     let server_rev_id = revision.rev_id;
@@ -217,10 +217,10 @@ pub(crate) async fn handle_push_rev(
         ret,
     };
     let _ = edit_cmd_tx.send(msg);
-    let md5 = rx.await.map_err(internal_error)??;
+    let _md5 = rx.await.map_err(internal_error)??;
 
     // update rev id
-    rev_manager.update_rev_id_counter_value(server_rev_id.clone().into());
+    rev_manager.update_rev_id_counter_value(server_rev_id);
     // let (local_base_rev_id, local_rev_id) = rev_manager.next_rev_id();
     // let delta_data = client_prime.to_bytes();
     // // save the revision

+ 1 - 1
frontend/rust-lib/flowy-document/src/services/file/manager.rs

@@ -64,7 +64,7 @@ impl FileManager {
     pub(crate) fn create_file(&mut self, id: &str, dir: &str, text: &str) -> Result<PathBuf, FileError> {
         let path = PathBuf::from(format!("{}/{}", dir, id));
         let file_id: FileId = id.to_owned().into();
-        tracing::info!("Create doc at: {:?}", path);
+        tracing::info!("Create document at: {:?}", path);
         let _ = self.save_new(&path, text, &file_id)?;
         Ok(path)
     }

+ 1 - 1
frontend/rust-lib/flowy-document/src/services/server/middleware.rs

@@ -11,7 +11,7 @@ impl ResponseMiddleware for DocMiddleware {
     fn receive_response(&self, token: &Option<String>, response: &FlowyResponse) {
         if let Some(error) = &response.error {
             if error.is_unauthorized() {
-                log::error!("doc user is unauthorized");
+                log::error!("document user is unauthorized");
 
                 match token {
                     None => {},

+ 4 - 0
frontend/rust-lib/flowy-error/src/protobuf/document

@@ -0,0 +1,4 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+mod model;
+pub use model::*;

+ 5 - 0
frontend/rust-lib/flowy-error/src/protobuf/model/document

@@ -0,0 +1,5 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+
+mod errors;
+pub use errors::*;

+ 4 - 0
frontend/rust-lib/flowy-net/src/protobuf/document

@@ -0,0 +1,4 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+mod model;
+pub use model::*;

+ 8 - 0
frontend/rust-lib/flowy-net/src/protobuf/model/document

@@ -0,0 +1,8 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+
+mod network_state;
+pub use network_state::*;
+
+mod event;
+pub use event::*;

+ 1 - 1
frontend/rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs

@@ -42,7 +42,7 @@ impl DocumentUser for DocumentUserImpl {
             .user_dir()
             .map_err(|e| FlowyError::unauthorized().context(e))?;
 
-        let doc_dir = format!("{}/doc", dir);
+        let doc_dir = format!("{}/document", dir);
         if !Path::new(&doc_dir).exists() {
             let _ = std::fs::create_dir_all(&doc_dir)?;
         }

+ 4 - 0
frontend/rust-lib/flowy-user/src/protobuf/document

@@ -0,0 +1,4 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+mod model;
+pub use model::*;

+ 8 - 0
frontend/rust-lib/flowy-user/src/protobuf/model/document

@@ -0,0 +1,8 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+
+mod observable;
+pub use observable::*;
+
+mod event;
+pub use event::*;

+ 2 - 2
frontend/scripts/flowy-tool/src/proto/proto_info.rs

@@ -16,7 +16,7 @@ impl CrateProtoInfo {
     pub fn create_crate_mod_file(&self) {
         // mod model;
         // pub use model::*;
-        let mod_file_path = format!("{}/mod.rs", self.inner.protobuf_crate_name());
+        let mod_file_path = format!("{}/document", self.inner.protobuf_crate_name());
         let mut content = "#![cfg_attr(rustfmt, rustfmt::skip)]\n".to_owned();
         content.push_str("// Auto-generated, do not edit\n");
         content.push_str("mod model;\npub use model::*;");
@@ -81,7 +81,7 @@ impl ProtobufCrate {
     }
 
     pub fn proto_model_mod_file(&self) -> String {
-        format!("{}/mod.rs", self.proto_struct_output_dir())
+        format!("{}/document", self.proto_struct_output_dir())
     }
 }
 

+ 1 - 1
shared-lib/backend-service/src/configuration.rs

@@ -54,7 +54,7 @@ impl ClientServerConfiguration {
 
     pub fn view_url(&self) -> String { format!("{}/api/view", self.base_url()) }
 
-    pub fn doc_url(&self) -> String { format!("{}/api/doc", self.base_url()) }
+    pub fn doc_url(&self) -> String { format!("{}/api/document", self.base_url()) }
 
     pub fn trash_url(&self) -> String { format!("{}/api/trash", self.base_url()) }
 

+ 4 - 0
shared-lib/error-code/src/protobuf/document

@@ -0,0 +1,4 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+mod model;
+pub use model::*;

+ 5 - 0
shared-lib/error-code/src/protobuf/model/document

@@ -0,0 +1,5 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+
+mod error_code;
+pub use error_code::*;

+ 2 - 5
shared-lib/flowy-collaboration/src/core/sync/server_editor.rs

@@ -235,7 +235,7 @@ impl ServerDocEditor {
         ));
 
         Ok(Self {
-            doc_id: doc.id.clone(),
+            doc_id: doc.id,
             synchronizer,
             users,
         })
@@ -247,10 +247,7 @@ impl ServerDocEditor {
         Ok(())
     }
 
-    pub fn document_json(&self) -> String {
-        let json = self.synchronizer.doc_json();
-        json
-    }
+    pub fn document_json(&self) -> String { self.synchronizer.doc_json() }
 
     pub fn rev_id(&self) -> i64 { self.synchronizer.rev_id.load(SeqCst) }
 }

+ 2 - 3
shared-lib/flowy-collaboration/src/entities/doc/doc.rs

@@ -47,9 +47,8 @@ impl std::convert::TryFrom<Revision> for Doc {
 
     fn try_from(revision: Revision) -> Result<Self, Self::Error> {
         if !revision.is_initial() {
-            return Err(
-                CollaborateError::revision_conflict().context("Revision's rev_id should be 0 when creating the doc")
-            );
+            return Err(CollaborateError::revision_conflict()
+                .context("Revision's rev_id should be 0 when creating the document"));
         }
 
         let delta = RichTextDelta::from_bytes(&revision.delta_data)?;

+ 2 - 2
shared-lib/flowy-collaboration/src/entities/ws/ws.rs

@@ -1,7 +1,7 @@
 use crate::errors::CollaborateError;
 use bytes::Bytes;
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
-use lib_infra::uuid;
+
 use lib_ot::revision::{Revision, RevisionRange};
 use std::convert::{TryFrom, TryInto};
 
@@ -62,7 +62,7 @@ pub struct DocumentWSDataBuilder();
 impl DocumentWSDataBuilder {
     // DocumentWSDataType::PushRev -> Revision
     pub fn build_push_message(doc_id: &str, revision: Revision, id: &str) -> DocumentWSData {
-        let rev_id = revision.rev_id;
+        let _rev_id = revision.rev_id;
         let bytes: Bytes = revision.try_into().unwrap();
         DocumentWSData {
             doc_id: doc_id.to_string(),

+ 50 - 50
shared-lib/flowy-collaboration/src/protobuf/model/doc.rs

@@ -1340,56 +1340,56 @@ static file_descriptor_proto_data: &'static [u8] = b"\
     \x17\n\x07user_id\x18\x01\x20\x01(\tR\x06userId\x12\x15\n\x06rev_id\x18\
     \x02\x20\x01(\x03R\x05revId\x12\x15\n\x06doc_id\x18\x03\x20\x01(\tR\x05d\
     ocId\"&\n\rDocIdentifier\x12\x15\n\x06doc_id\x18\x01\x20\x01(\tR\x05docI\
-    dJ\xdb\x07\n\x06\x12\x04\0\0\x1c\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\
-    \n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\
-    \x17\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x12\n\x0c\n\x05\x04\0\x02\0\
-    \x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0b\r\n\
-    \x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x10\x11\n\x0b\n\x04\x04\0\x02\x01\
-    \x12\x03\x04\x04\x14\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\
-    \x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\x0f\n\x0c\n\x05\x04\0\x02\
-    \x01\x03\x12\x03\x04\x12\x13\n\n\n\x02\x04\x01\x12\x04\x06\0\x0b\x01\n\n\
-    \n\x03\x04\x01\x01\x12\x03\x06\x08\x0b\n\x0b\n\x04\x04\x01\x02\0\x12\x03\
-    \x07\x04\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x07\x04\n\n\x0c\n\x05\
-    \x04\x01\x02\0\x01\x12\x03\x07\x0b\r\n\x0c\n\x05\x04\x01\x02\0\x03\x12\
-    \x03\x07\x10\x11\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\x08\x04\x14\n\x0c\n\
-    \x05\x04\x01\x02\x01\x05\x12\x03\x08\x04\n\n\x0c\n\x05\x04\x01\x02\x01\
-    \x01\x12\x03\x08\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\x08\x12\
-    \x13\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\t\x04\x15\n\x0c\n\x05\x04\x01\
-    \x02\x02\x05\x12\x03\t\x04\t\n\x0c\n\x05\x04\x01\x02\x02\x01\x12\x03\t\n\
-    \x10\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\t\x13\x14\n\x0b\n\x04\x04\
-    \x01\x02\x03\x12\x03\n\x04\x1a\n\x0c\n\x05\x04\x01\x02\x03\x05\x12\x03\n\
-    \x04\t\n\x0c\n\x05\x04\x01\x02\x03\x01\x12\x03\n\n\x15\n\x0c\n\x05\x04\
-    \x01\x02\x03\x03\x12\x03\n\x18\x19\n\n\n\x02\x04\x02\x12\x04\x0c\0\x10\
-    \x01\n\n\n\x03\x04\x02\x01\x12\x03\x0c\x08\x17\n\x0b\n\x04\x04\x02\x02\0\
-    \x12\x03\r\x04\x16\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\r\x04\n\n\x0c\n\
-    \x05\x04\x02\x02\0\x01\x12\x03\r\x0b\x11\n\x0c\n\x05\x04\x02\x02\0\x03\
-    \x12\x03\r\x14\x15\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0e\x04\x14\n\x0c\
-    \n\x05\x04\x02\x02\x01\x05\x12\x03\x0e\x04\n\n\x0c\n\x05\x04\x02\x02\x01\
-    \x01\x12\x03\x0e\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\x0e\x12\
-    \x13\n\x0b\n\x04\x04\x02\x02\x02\x12\x03\x0f\x04\x15\n\x0c\n\x05\x04\x02\
-    \x02\x02\x05\x12\x03\x0f\x04\t\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\x03\
-    \x0f\n\x10\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x0f\x13\x14\n\n\n\x02\
-    \x04\x03\x12\x04\x11\0\x14\x01\n\n\n\x03\x04\x03\x01\x12\x03\x11\x08\x10\
-    \n\x0b\n\x04\x04\x03\x02\0\x12\x03\x12\x04\x16\n\x0c\n\x05\x04\x03\x02\0\
-    \x05\x12\x03\x12\x04\n\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x12\x0b\x11\
-    \n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x12\x14\x15\n\x0b\n\x04\x04\x03\
-    \x02\x01\x12\x03\x13\x04\x14\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\x03\x13\
-    \x04\n\n\x0c\n\x05\x04\x03\x02\x01\x01\x12\x03\x13\x0b\x0f\n\x0c\n\x05\
-    \x04\x03\x02\x01\x03\x12\x03\x13\x12\x13\n\n\n\x02\x04\x04\x12\x04\x15\0\
-    \x19\x01\n\n\n\x03\x04\x04\x01\x12\x03\x15\x08\x12\n\x0b\n\x04\x04\x04\
-    \x02\0\x12\x03\x16\x04\x17\n\x0c\n\x05\x04\x04\x02\0\x05\x12\x03\x16\x04\
-    \n\n\x0c\n\x05\x04\x04\x02\0\x01\x12\x03\x16\x0b\x12\n\x0c\n\x05\x04\x04\
-    \x02\0\x03\x12\x03\x16\x15\x16\n\x0b\n\x04\x04\x04\x02\x01\x12\x03\x17\
-    \x04\x15\n\x0c\n\x05\x04\x04\x02\x01\x05\x12\x03\x17\x04\t\n\x0c\n\x05\
-    \x04\x04\x02\x01\x01\x12\x03\x17\n\x10\n\x0c\n\x05\x04\x04\x02\x01\x03\
-    \x12\x03\x17\x13\x14\n\x0b\n\x04\x04\x04\x02\x02\x12\x03\x18\x04\x16\n\
-    \x0c\n\x05\x04\x04\x02\x02\x05\x12\x03\x18\x04\n\n\x0c\n\x05\x04\x04\x02\
-    \x02\x01\x12\x03\x18\x0b\x11\n\x0c\n\x05\x04\x04\x02\x02\x03\x12\x03\x18\
-    \x14\x15\n\n\n\x02\x04\x05\x12\x04\x1a\0\x1c\x01\n\n\n\x03\x04\x05\x01\
-    \x12\x03\x1a\x08\x15\n\x0b\n\x04\x04\x05\x02\0\x12\x03\x1b\x04\x16\n\x0c\
-    \n\x05\x04\x05\x02\0\x05\x12\x03\x1b\x04\n\n\x0c\n\x05\x04\x05\x02\0\x01\
-    \x12\x03\x1b\x0b\x11\n\x0c\n\x05\x04\x05\x02\0\x03\x12\x03\x1b\x14\x15b\
-    \x06proto3\
+    dJ\xdb\x07\n\x06\x12\x04\0\0\x1b\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\
+    \n\x02\x04\0\x12\x04\x01\0\x04\x01\n\n\n\x03\x04\0\x01\x12\x03\x01\x08\
+    \x17\n\x0b\n\x04\x04\0\x02\0\x12\x03\x02\x04\x12\n\x0c\n\x05\x04\0\x02\0\
+    \x05\x12\x03\x02\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x02\x0b\r\n\
+    \x0c\n\x05\x04\0\x02\0\x03\x12\x03\x02\x10\x11\n\x0b\n\x04\x04\0\x02\x01\
+    \x12\x03\x03\x04\x14\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x03\x04\n\n\
+    \x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x03\x0b\x0f\n\x0c\n\x05\x04\0\x02\
+    \x01\x03\x12\x03\x03\x12\x13\n\n\n\x02\x04\x01\x12\x04\x05\0\n\x01\n\n\n\
+    \x03\x04\x01\x01\x12\x03\x05\x08\x0b\n\x0b\n\x04\x04\x01\x02\0\x12\x03\
+    \x06\x04\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x06\x04\n\n\x0c\n\x05\
+    \x04\x01\x02\0\x01\x12\x03\x06\x0b\r\n\x0c\n\x05\x04\x01\x02\0\x03\x12\
+    \x03\x06\x10\x11\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\x07\x04\x14\n\x0c\n\
+    \x05\x04\x01\x02\x01\x05\x12\x03\x07\x04\n\n\x0c\n\x05\x04\x01\x02\x01\
+    \x01\x12\x03\x07\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\x07\x12\
+    \x13\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\x08\x04\x15\n\x0c\n\x05\x04\x01\
+    \x02\x02\x05\x12\x03\x08\x04\t\n\x0c\n\x05\x04\x01\x02\x02\x01\x12\x03\
+    \x08\n\x10\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\x08\x13\x14\n\x0b\n\
+    \x04\x04\x01\x02\x03\x12\x03\t\x04\x1a\n\x0c\n\x05\x04\x01\x02\x03\x05\
+    \x12\x03\t\x04\t\n\x0c\n\x05\x04\x01\x02\x03\x01\x12\x03\t\n\x15\n\x0c\n\
+    \x05\x04\x01\x02\x03\x03\x12\x03\t\x18\x19\n\n\n\x02\x04\x02\x12\x04\x0b\
+    \0\x0f\x01\n\n\n\x03\x04\x02\x01\x12\x03\x0b\x08\x17\n\x0b\n\x04\x04\x02\
+    \x02\0\x12\x03\x0c\x04\x16\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\x0c\x04\
+    \n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\x0c\x0b\x11\n\x0c\n\x05\x04\x02\
+    \x02\0\x03\x12\x03\x0c\x14\x15\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\r\x04\
+    \x14\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\x03\r\x04\n\n\x0c\n\x05\x04\x02\
+    \x02\x01\x01\x12\x03\r\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\r\
+    \x12\x13\n\x0b\n\x04\x04\x02\x02\x02\x12\x03\x0e\x04\x15\n\x0c\n\x05\x04\
+    \x02\x02\x02\x05\x12\x03\x0e\x04\t\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\
+    \x03\x0e\n\x10\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x0e\x13\x14\n\n\n\
+    \x02\x04\x03\x12\x04\x10\0\x13\x01\n\n\n\x03\x04\x03\x01\x12\x03\x10\x08\
+    \x10\n\x0b\n\x04\x04\x03\x02\0\x12\x03\x11\x04\x16\n\x0c\n\x05\x04\x03\
+    \x02\0\x05\x12\x03\x11\x04\n\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x11\
+    \x0b\x11\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x11\x14\x15\n\x0b\n\x04\
+    \x04\x03\x02\x01\x12\x03\x12\x04\x14\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\
+    \x03\x12\x04\n\n\x0c\n\x05\x04\x03\x02\x01\x01\x12\x03\x12\x0b\x0f\n\x0c\
+    \n\x05\x04\x03\x02\x01\x03\x12\x03\x12\x12\x13\n\n\n\x02\x04\x04\x12\x04\
+    \x14\0\x18\x01\n\n\n\x03\x04\x04\x01\x12\x03\x14\x08\x12\n\x0b\n\x04\x04\
+    \x04\x02\0\x12\x03\x15\x04\x17\n\x0c\n\x05\x04\x04\x02\0\x05\x12\x03\x15\
+    \x04\n\n\x0c\n\x05\x04\x04\x02\0\x01\x12\x03\x15\x0b\x12\n\x0c\n\x05\x04\
+    \x04\x02\0\x03\x12\x03\x15\x15\x16\n\x0b\n\x04\x04\x04\x02\x01\x12\x03\
+    \x16\x04\x15\n\x0c\n\x05\x04\x04\x02\x01\x05\x12\x03\x16\x04\t\n\x0c\n\
+    \x05\x04\x04\x02\x01\x01\x12\x03\x16\n\x10\n\x0c\n\x05\x04\x04\x02\x01\
+    \x03\x12\x03\x16\x13\x14\n\x0b\n\x04\x04\x04\x02\x02\x12\x03\x17\x04\x16\
+    \n\x0c\n\x05\x04\x04\x02\x02\x05\x12\x03\x17\x04\n\n\x0c\n\x05\x04\x04\
+    \x02\x02\x01\x12\x03\x17\x0b\x11\n\x0c\n\x05\x04\x04\x02\x02\x03\x12\x03\
+    \x17\x14\x15\n\n\n\x02\x04\x05\x12\x04\x19\0\x1b\x01\n\n\n\x03\x04\x05\
+    \x01\x12\x03\x19\x08\x15\n\x0b\n\x04\x04\x05\x02\0\x12\x03\x1a\x04\x16\n\
+    \x0c\n\x05\x04\x05\x02\0\x05\x12\x03\x1a\x04\n\n\x0c\n\x05\x04\x05\x02\0\
+    \x01\x12\x03\x1a\x0b\x11\n\x0c\n\x05\x04\x05\x02\0\x03\x12\x03\x1a\x14\
+    \x15b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 32 - 32
shared-lib/flowy-collaboration/src/protobuf/model/ws.rs

@@ -605,38 +605,38 @@ static file_descriptor_proto_data: &'static [u8] = b"\
     \x05docId\x12#\n\rrevision_data\x18\x03\x20\x01(\x0cR\x0crevisionData*H\
     \n\x12DocumentWSDataType\x12\x07\n\x03Ack\x10\0\x12\x0b\n\x07PushRev\x10\
     \x01\x12\x0b\n\x07PullRev\x10\x02\x12\x0f\n\x0bUserConnect\x10\x03J\xff\
-    \x04\n\x06\x12\x04\0\0\x12\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\
-    \x04\0\x12\x04\x02\0\x07\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x16\n\
-    \x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x16\n\x0c\n\x05\x04\0\x02\0\x05\
-    \x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0b\x11\n\x0c\
-    \n\x05\x04\0\x02\0\x03\x12\x03\x03\x14\x15\n\x0b\n\x04\x04\0\x02\x01\x12\
-    \x03\x04\x04\x1e\n\x0c\n\x05\x04\0\x02\x01\x06\x12\x03\x04\x04\x16\n\x0c\
-    \n\x05\x04\0\x02\x01\x01\x12\x03\x04\x17\x19\n\x0c\n\x05\x04\0\x02\x01\
-    \x03\x12\x03\x04\x1c\x1d\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x05\x04\x13\n\
-    \x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x05\x04\t\n\x0c\n\x05\x04\0\x02\x02\
-    \x01\x12\x03\x05\n\x0e\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\x05\x11\x12\
-    \n\x0b\n\x04\x04\0\x02\x03\x12\x03\x06\x04\x12\n\x0c\n\x05\x04\0\x02\x03\
-    \x05\x12\x03\x06\x04\n\n\x0c\n\x05\x04\0\x02\x03\x01\x12\x03\x06\x0b\r\n\
-    \x0c\n\x05\x04\0\x02\x03\x03\x12\x03\x06\x10\x11\n\n\n\x02\x04\x01\x12\
-    \x04\x08\0\x0c\x01\n\n\n\x03\x04\x01\x01\x12\x03\x08\x08\x17\n\x0b\n\x04\
-    \x04\x01\x02\0\x12\x03\t\x04\x17\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\t\
-    \x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\t\x0b\x12\n\x0c\n\x05\x04\
-    \x01\x02\0\x03\x12\x03\t\x15\x16\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\n\
-    \x04\x16\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\n\x04\n\n\x0c\n\x05\x04\
-    \x01\x02\x01\x01\x12\x03\n\x0b\x11\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\
-    \x03\n\x14\x15\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\x0b\x04\x1c\n\x0c\n\
-    \x05\x04\x01\x02\x02\x05\x12\x03\x0b\x04\t\n\x0c\n\x05\x04\x01\x02\x02\
-    \x01\x12\x03\x0b\n\x17\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\x0b\x1a\
-    \x1b\n\n\n\x02\x05\0\x12\x04\r\0\x12\x01\n\n\n\x03\x05\0\x01\x12\x03\r\
-    \x05\x17\n\x0b\n\x04\x05\0\x02\0\x12\x03\x0e\x04\x0c\n\x0c\n\x05\x05\0\
-    \x02\0\x01\x12\x03\x0e\x04\x07\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x0e\n\
-    \x0b\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x0f\x04\x10\n\x0c\n\x05\x05\0\x02\
-    \x01\x01\x12\x03\x0f\x04\x0b\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x0f\
-    \x0e\x0f\n\x0b\n\x04\x05\0\x02\x02\x12\x03\x10\x04\x10\n\x0c\n\x05\x05\0\
-    \x02\x02\x01\x12\x03\x10\x04\x0b\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\
-    \x10\x0e\x0f\n\x0b\n\x04\x05\0\x02\x03\x12\x03\x11\x04\x14\n\x0c\n\x05\
-    \x05\0\x02\x03\x01\x12\x03\x11\x04\x0f\n\x0c\n\x05\x05\0\x02\x03\x02\x12\
-    \x03\x11\x12\x13b\x06proto3\
+    \x04\n\x06\x12\x04\0\0\x11\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\
+    \x04\0\x12\x04\x01\0\x06\x01\n\n\n\x03\x04\0\x01\x12\x03\x01\x08\x16\n\
+    \x0b\n\x04\x04\0\x02\0\x12\x03\x02\x04\x16\n\x0c\n\x05\x04\0\x02\0\x05\
+    \x12\x03\x02\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x02\x0b\x11\n\x0c\
+    \n\x05\x04\0\x02\0\x03\x12\x03\x02\x14\x15\n\x0b\n\x04\x04\0\x02\x01\x12\
+    \x03\x03\x04\x1e\n\x0c\n\x05\x04\0\x02\x01\x06\x12\x03\x03\x04\x16\n\x0c\
+    \n\x05\x04\0\x02\x01\x01\x12\x03\x03\x17\x19\n\x0c\n\x05\x04\0\x02\x01\
+    \x03\x12\x03\x03\x1c\x1d\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x04\x04\x13\n\
+    \x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x04\x04\t\n\x0c\n\x05\x04\0\x02\x02\
+    \x01\x12\x03\x04\n\x0e\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\x04\x11\x12\
+    \n\x0b\n\x04\x04\0\x02\x03\x12\x03\x05\x04\x12\n\x0c\n\x05\x04\0\x02\x03\
+    \x05\x12\x03\x05\x04\n\n\x0c\n\x05\x04\0\x02\x03\x01\x12\x03\x05\x0b\r\n\
+    \x0c\n\x05\x04\0\x02\x03\x03\x12\x03\x05\x10\x11\n\n\n\x02\x04\x01\x12\
+    \x04\x07\0\x0b\x01\n\n\n\x03\x04\x01\x01\x12\x03\x07\x08\x17\n\x0b\n\x04\
+    \x04\x01\x02\0\x12\x03\x08\x04\x17\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\
+    \x08\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x08\x0b\x12\n\x0c\n\x05\
+    \x04\x01\x02\0\x03\x12\x03\x08\x15\x16\n\x0b\n\x04\x04\x01\x02\x01\x12\
+    \x03\t\x04\x16\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\t\x04\n\n\x0c\n\
+    \x05\x04\x01\x02\x01\x01\x12\x03\t\x0b\x11\n\x0c\n\x05\x04\x01\x02\x01\
+    \x03\x12\x03\t\x14\x15\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\n\x04\x1c\n\
+    \x0c\n\x05\x04\x01\x02\x02\x05\x12\x03\n\x04\t\n\x0c\n\x05\x04\x01\x02\
+    \x02\x01\x12\x03\n\n\x17\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\n\x1a\
+    \x1b\n\n\n\x02\x05\0\x12\x04\x0c\0\x11\x01\n\n\n\x03\x05\0\x01\x12\x03\
+    \x0c\x05\x17\n\x0b\n\x04\x05\0\x02\0\x12\x03\r\x04\x0c\n\x0c\n\x05\x05\0\
+    \x02\0\x01\x12\x03\r\x04\x07\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\r\n\x0b\
+    \n\x0b\n\x04\x05\0\x02\x01\x12\x03\x0e\x04\x10\n\x0c\n\x05\x05\0\x02\x01\
+    \x01\x12\x03\x0e\x04\x0b\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x0e\x0e\
+    \x0f\n\x0b\n\x04\x05\0\x02\x02\x12\x03\x0f\x04\x10\n\x0c\n\x05\x05\0\x02\
+    \x02\x01\x12\x03\x0f\x04\x0b\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\x0f\
+    \x0e\x0f\n\x0b\n\x04\x05\0\x02\x03\x12\x03\x10\x04\x14\n\x0c\n\x05\x05\0\
+    \x02\x03\x01\x12\x03\x10\x04\x0f\n\x0c\n\x05\x05\0\x02\x03\x02\x12\x03\
+    \x10\x12\x13b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 0 - 1
shared-lib/flowy-collaboration/src/protobuf/proto/doc.proto

@@ -1,5 +1,4 @@
 syntax = "proto3";
-
 message CreateDocParams {
     string id = 1;
     string data = 2;

+ 0 - 1
shared-lib/flowy-collaboration/src/protobuf/proto/ws.proto

@@ -1,5 +1,4 @@
 syntax = "proto3";
-
 message DocumentWSData {
     string doc_id = 1;
     DocumentWSDataType ty = 2;

+ 4 - 0
shared-lib/flowy-core-data-model/src/protobuf/document

@@ -0,0 +1,4 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+mod model;
+pub use model::*;

+ 41 - 0
shared-lib/flowy-core-data-model/src/protobuf/model/document

@@ -0,0 +1,41 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+
+mod view_update;
+pub use view_update::*;
+
+mod workspace_setting;
+pub use workspace_setting::*;
+
+mod app_query;
+pub use app_query::*;
+
+mod errors;
+pub use errors::*;
+
+mod workspace_update;
+pub use workspace_update::*;
+
+mod app_create;
+pub use app_create::*;
+
+mod workspace_query;
+pub use workspace_query::*;
+
+mod view_create;
+pub use view_create::*;
+
+mod workspace_create;
+pub use workspace_create::*;
+
+mod app_update;
+pub use app_update::*;
+
+mod view_query;
+pub use view_query::*;
+
+mod trash_create;
+pub use trash_create::*;
+
+mod export;
+pub use export::*;

+ 4 - 0
shared-lib/flowy-user-data-model/src/protobuf/document

@@ -0,0 +1,4 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+mod model;
+pub use model::*;

+ 11 - 0
shared-lib/flowy-user-data-model/src/protobuf/model/document

@@ -0,0 +1,11 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+
+mod errors;
+pub use errors::*;
+
+mod user_profile;
+pub use user_profile::*;
+
+mod auth;
+pub use auth::*;

+ 4 - 0
shared-lib/lib-ot/src/protobuf/document

@@ -0,0 +1,4 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+mod model;
+pub use model::*;

+ 5 - 0
shared-lib/lib-ot/src/protobuf/model/document

@@ -0,0 +1,5 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+
+mod model;
+pub use model::*;

+ 4 - 0
shared-lib/lib-ws/src/protobuf/document

@@ -0,0 +1,4 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+mod model;
+pub use model::*;

+ 8 - 0
shared-lib/lib-ws/src/protobuf/model/document

@@ -0,0 +1,8 @@
+#![cfg_attr(rustfmt, rustfmt::skip)]
+// Auto-generated, do not edit
+
+mod errors;
+pub use errors::*;
+
+mod msg;
+pub use msg::*;