diff --git a/libs/database/src/workspace.rs b/libs/database/src/workspace.rs index ce30fbd3..2f6d9629 100644 --- a/libs/database/src/workspace.rs +++ b/libs/database/src/workspace.rs @@ -845,6 +845,25 @@ pub async fn update_workspace_publish_namespace<'a, E: Executor<'a, Database = P Ok(()) } +#[inline] +pub async fn select_workspace_id_by_namespace<'a, E: Executor<'a, Database = Postgres>>( + executor: E, + publish_namespace: &str, +) -> Result { + let res = sqlx::query_scalar!( + r#" + SELECT workspace_id + FROM af_workspace + WHERE publish_namespace = $1 + "#, + publish_namespace, + ) + .fetch_one(executor) + .await?; + + Ok(res) +} + #[inline] pub async fn insert_or_replace_publish_collab_meta<'a, E: Executor<'a, Database = Postgres>>( executor: E, diff --git a/migrations/20240613112820_publish_collab.sql b/migrations/20240613112820_publish_collab.sql index e5106b72..3f6dd26f 100644 --- a/migrations/20240613112820_publish_collab.sql +++ b/migrations/20240613112820_publish_collab.sql @@ -27,3 +27,4 @@ EXECUTE FUNCTION update_updated_at(); -- every workspace have a prefix for published view ALTER TABLE af_workspace ADD COLUMN publish_namespace TEXT UNIQUE; +CREATE INDEX IF NOT EXISTS publish_namespace_idx ON af_workspace(publish_namespace); diff --git a/src/api/workspace.rs b/src/api/workspace.rs index 0ac45aa9..5eac8388 100644 --- a/src/api/workspace.rs +++ b/src/api/workspace.rs @@ -128,6 +128,14 @@ pub fn workspace_scope() -> Scope { .route(web::put().to(update_collab_member_handler)) .route(web::delete().to(remove_collab_member_handler)), ) + .service( + web::resource("/published/{publish_namespace}/{doc_name}") + .route(web::get().to(get_published_collab_handler)) + ) + .service( + web::resource("/published/{publish_namespace}/{doc_name}/blob") + .route(web::get().to(get_published_collab_blob_handler)) + ) .service( web::resource("/{workspace_id}/publish-namespace") .route(web::put().to(put_publish_namespace_handler)) @@ -970,6 +978,34 @@ async fn put_publish_namespace_handler( Ok(Json(AppResponse::Ok())) } +async fn get_published_collab_handler( + path_param: web::Path<(String, String)>, + state: Data, +) -> Result>> { + let (workspace_namespace, doc_name) = path_param.into_inner(); + let metadata = biz::workspace::ops::get_published_collab_using_publish_namespace( + &state.pg_pool, + &workspace_namespace, + &doc_name, + ) + .await?; + Ok(Json(AppResponse::Ok().with_data(metadata))) +} + +async fn get_published_collab_blob_handler( + path_param: web::Path<(String, String)>, + state: Data, +) -> Result> { + let (publish_namespace, doc_name) = path_param.into_inner(); + let collab_data = biz::workspace::ops::get_published_collab_blob_with_publish_namespace( + &state.pg_pool, + &publish_namespace, + &doc_name, + ) + .await?; + Ok(collab_data) +} + async fn put_publish_collab_handler( path_param: web::Path<(Uuid, String)>, user_uuid: UserUuid, @@ -995,7 +1031,7 @@ async fn get_publish_collab_handler( ) -> Result>> { let (workspace_id, doc_name) = path_param.into_inner(); let metadata = - biz::workspace::ops::get_publish_collab(&state.pg_pool, &workspace_id, &doc_name).await?; + biz::workspace::ops::get_published_collab(&state.pg_pool, &workspace_id, &doc_name).await?; Ok(Json(AppResponse::Ok().with_data(metadata))) } diff --git a/src/biz/workspace/ops.rs b/src/biz/workspace/ops.rs index 31b5ae80..48cf55f6 100644 --- a/src/biz/workspace/ops.rs +++ b/src/biz/workspace/ops.rs @@ -22,11 +22,11 @@ use database::workspace::{ insert_or_replace_published_collab_blob, insert_user_workspace, insert_workspace_invitation, rename_workspace, select_all_user_workspaces, select_publish_collab_meta, select_published_collab_blob, select_user_is_collab_publisher, select_user_is_workspace_owner, - select_workspace, select_workspace_invitations_for_user, select_workspace_member, - select_workspace_member_list, select_workspace_settings, select_workspace_total_collab_bytes, - update_updated_at_of_workspace, update_workspace_invitation_set_status_accepted, - update_workspace_publish_namespace, upsert_workspace_member, upsert_workspace_member_with_txn, - upsert_workspace_settings, + select_workspace, select_workspace_id_by_namespace, select_workspace_invitations_for_user, + select_workspace_member, select_workspace_member_list, select_workspace_settings, + select_workspace_total_collab_bytes, update_updated_at_of_workspace, + update_workspace_invitation_set_status_accepted, update_workspace_publish_namespace, + upsert_workspace_member, upsert_workspace_member_with_txn, upsert_workspace_settings, }; use database_entity::dto::{ AFAccessLevel, AFRole, AFWorkspace, AFWorkspaceInvitation, AFWorkspaceInvitationStatus, @@ -153,7 +153,7 @@ pub async fn put_published_collab_blob( Ok(()) } -pub async fn get_publish_collab( +pub async fn get_published_collab( pg_pool: &PgPool, workspace_id: &Uuid, doc_name: &str, @@ -162,6 +162,15 @@ pub async fn get_publish_collab( Ok(metadata) } +pub async fn get_published_collab_using_publish_namespace( + pg_pool: &PgPool, + publish_namespace: &str, + doc_name: &str, +) -> Result { + let workspace_id = select_workspace_id_by_namespace(pg_pool, publish_namespace).await?; + get_published_collab(pg_pool, &workspace_id, doc_name).await +} + pub async fn get_published_collab_blob( pg_pool: &PgPool, workspace_id: &Uuid, @@ -170,6 +179,15 @@ pub async fn get_published_collab_blob( select_published_collab_blob(pg_pool, workspace_id, doc_name).await } +pub async fn get_published_collab_blob_with_publish_namespace( + pg_pool: &PgPool, + publish_namespace: &str, + doc_name: &str, +) -> Result, AppError> { + let workspace_id = select_workspace_id_by_namespace(pg_pool, publish_namespace).await?; + select_published_collab_blob(pg_pool, &workspace_id, doc_name).await +} + pub async fn delete_published_workspace_collab( pg_pool: &PgPool, workspace_id: &Uuid,